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 <zircon/compiler.h>
11 #include <zircon/errors.h>
12 #include <dev/pcie_bus_driver.h>
13 #include <dev/pcie_device.h>
14 #include <dev/pcie_ref_counted.h>
15 #include <dev/pcie_upstream_node.h>
16 
17 #include <region-alloc/region-alloc.h>
18 #include <fbl/macros.h>
19 #include <fbl/ref_ptr.h>
20 #include <sys/types.h>
21 
22 class PciConfig;
23 class PcieBridge : public PcieDevice,
24                    public PcieUpstreamNode {
25 public:
26     static fbl::RefPtr<PcieDevice> Create(PcieUpstreamNode& upstream,
27                                            uint dev_id,
28                                            uint func_id,
29                                            uint managed_bus_id);
30 
31     // Disallow copying, assigning and moving.
32     DISALLOW_COPY_ASSIGN_AND_MOVE(PcieBridge);
33 
34     // Implement ref counting, do not let derived classes override.
35     PCIE_IMPLEMENT_REFCOUNTED;
36 
37     // Device overrides
38     void Unplug() override;
39 
40     // UpstreamNode overrides
pf_mmio_regions()41     RegionAllocator& pf_mmio_regions() final { return pf_mmio_regions_; }
mmio_lo_regions()42     RegionAllocator& mmio_lo_regions() final { return mmio_lo_regions_; }
mmio_hi_regions()43     RegionAllocator& mmio_hi_regions() final { return mmio_hi_regions_; }
pio_regions()44     RegionAllocator& pio_regions()     final { return pio_regions_; }
45 
46     // Properties
driver()47     PcieBusDriver& driver() { return PcieDevice::driver(); }
48 
pf_mem_base()49     uint64_t pf_mem_base()        const { return pf_mem_base_; }
pf_mem_limit()50     uint64_t pf_mem_limit()       const { return pf_mem_limit_; }
mem_base()51     uint32_t mem_base()           const { return mem_base_; }
mem_limit()52     uint32_t mem_limit()          const { return mem_limit_; }
io_base()53     uint32_t io_base()            const { return io_base_; }
io_limit()54     uint32_t io_limit()           const { return io_limit_; }
supports_32bit_pio()55     bool     supports_32bit_pio() const { return supports_32bit_pio_; }
56 
57     // print some info about the bridge
58     void Dump() const override;
59 
60 protected:
61     zx_status_t AllocateBars() override;
62     zx_status_t AllocateBridgeWindowsLocked();
63     void        Disable() override;
64 
65 private:
66     friend class PcieBusDriver;
67 
68     PcieBridge(PcieBusDriver& bus_drv, uint bus_id, uint dev_id, uint func_id, uint mbus_id);
69 
70     zx_status_t ParseBusWindowsLocked();
71     zx_status_t Init(PcieUpstreamNode& upstream);
72 
73     RegionAllocator pf_mmio_regions_;
74     RegionAllocator mmio_lo_regions_;
75     RegionAllocator mmio_hi_regions_;
76     RegionAllocator pio_regions_;
77 
78     RegionAllocator::Region::UPtr pf_mmio_window_;
79     RegionAllocator::Region::UPtr mmio_window_;
80     RegionAllocator::Region::UPtr pio_window_;
81 
82     uint64_t pf_mem_base_;
83     uint64_t pf_mem_limit_;
84     uint32_t mem_base_;
85     uint32_t mem_limit_;
86     uint32_t io_base_;
87     uint32_t io_limit_;
88     bool     supports_32bit_pio_;
89     fbl::RefPtr<PcieDevice> ScanDevice(const PciConfig* cfg, uint dev_id, uint func_id);
90 };
91