1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2016, Google, Inc. All rights reserved
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 
8 #pragma once
9 
10 #include <dev/pcie_bus_driver.h>
11 #include <dev/pcie_device.h>
12 #include <dev/pcie_ref_counted.h>
13 #include <fbl/macros.h>
14 #include <fbl/ref_ptr.h>
15 #include <sys/types.h>
16 
17 struct pcie_config_t;
18 class  RegionAllocator;
19 class  PciConfig;
20 
21 // PcieUpstreamNode
22 //
23 // A class responsible for maintaining the state of a node in the graph of
24 // PCI/PCIe devices which can have downstream children.  PcieUpstreamNodes are
25 // not instantiated directly, instead they serve as the base class of
26 // PcieBridges and PcieRoots.
27 class PcieUpstreamNode {
28 public:
29     enum class Type { ROOT, BRIDGE };
30     virtual ~PcieUpstreamNode();
31 
32     // Disallow copying, assigning and moving.
33     DISALLOW_COPY_ASSIGN_AND_MOVE(PcieUpstreamNode);
34 
35     // Require that derived classes implement ref counting.
36     PCIE_REQUIRE_REFCOUNTED;
37 
GetDownstream(uint ndx)38     fbl::RefPtr<PcieDevice> GetDownstream(uint ndx) { return bus_drv_.GetDownstream(*this, ndx); }
driver()39     PcieBusDriver& driver() { return bus_drv_; }
40 
type()41     Type type()           const { return type_; }
managed_bus_id()42     uint managed_bus_id() const { return managed_bus_id_; }
43 
44     virtual RegionAllocator& pf_mmio_regions() = 0;
45     virtual RegionAllocator& mmio_lo_regions() = 0;
46     virtual RegionAllocator& mmio_hi_regions() = 0;
47     virtual RegionAllocator& pio_regions() = 0;
48 
49 protected:
50     friend class PcieBusDriver;
PcieUpstreamNode(PcieBusDriver & bus_drv,Type type,uint mbus_id)51     PcieUpstreamNode(PcieBusDriver& bus_drv, Type type, uint mbus_id)
52         : bus_drv_(bus_drv),
53           type_(type),
54           managed_bus_id_(mbus_id) { }
55 
56     void AllocateDownstreamBars();
57     void DisableDownstream();
58     void ScanDownstream();
59     void UnplugDownstream();
60 
61     fbl::RefPtr<PcieDevice> ScanDevice(const PciConfig* cfg, uint dev_id, uint func_id);
62 
63 private:
64 
65     PcieBusDriver& bus_drv_;         // TODO(johngro) : Eliminate this, see ZX-325
66     const Type     type_;
67     const uint     managed_bus_id_;  // The ID of the downstream bus which this node manages.
68 
69     // An array of pointers for all the possible functions which exist on the
70     // downstream bus of this node.
71     //
72     // TODO(johngro): Consider making this into a WAVLTree, indexed by the
73     // concatenation of device and function ID instead of an array.
74     fbl::RefPtr<PcieDevice> downstream_[PCIE_MAX_FUNCTIONS_PER_BUS];
75 };
76