1 /* 2 * Copyright 2003-2008, Marcus Overhagen. All rights reserved. 3 * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 #ifndef __PCI_H__ 8 #define __PCI_H__ 9 10 #include <PCI.h> 11 12 #ifdef __cplusplus 13 #include <VectorMap.h> 14 #endif 15 16 #include "pci_controller.h" 17 18 19 #define TRACE_PCI 20 #ifndef TRACE_PCI 21 # define TRACE(x) 22 #else 23 # define TRACE(x) dprintf x 24 #endif 25 26 27 #ifdef __cplusplus 28 29 struct PCIDev; 30 31 struct PCIBus { 32 PCIBus * next; 33 PCIDev * parent; 34 PCIDev * child; 35 int domain; 36 uint8 bus; 37 }; 38 39 struct PCIDev { 40 PCIDev * next; 41 PCIBus * parent; 42 PCIBus * child; 43 int domain; 44 uint8 bus; 45 uint8 device; 46 uint8 function; 47 pci_info info; 48 }; 49 50 51 struct domain_data { 52 // These two are set in PCI::AddController: 53 pci_controller * controller; 54 void * controller_cookie; 55 56 // All the rest is set in PCI::InitDomainData 57 int max_bus_devices; 58 }; 59 60 61 class PCI { 62 public: 63 PCI(); 64 ~PCI(); 65 66 void InitDomainData(); 67 void InitBus(); 68 69 status_t AddController(pci_controller *controller, 70 void *controller_cookie); 71 72 status_t GetNthInfo(long index, pci_info *outInfo); 73 74 status_t ReadConfig(int domain, uint8 bus, uint8 device, 75 uint8 function, uint8 offset, uint8 size, 76 uint32 *value); 77 uint32 ReadConfig(int domain, uint8 bus, uint8 device, 78 uint8 function, uint8 offset, uint8 size); 79 uint32 ReadConfig(PCIDev *device, uint8 offset, 80 uint8 size); 81 82 status_t WriteConfig(int domain, uint8 bus, uint8 device, 83 uint8 function, uint8 offset, uint8 size, 84 uint32 value); 85 status_t WriteConfig(PCIDev *device, uint8 offset, 86 uint8 size, uint32 value); 87 88 status_t FindCapability(int domain, uint8 bus, uint8 device, 89 uint8 function, uint8 capID, uint8 *offset); 90 status_t FindCapability(PCIDev *device, uint8 capID, 91 uint8 *offset); 92 93 status_t ResolveVirtualBus(uint8 virtualBus, int *domain, 94 uint8 *bus); 95 96 PCIDev * FindDevice(int domain, uint8 bus, uint8 device, 97 uint8 function); 98 99 void ClearDeviceStatus(PCIBus *bus, bool dumpStatus); 100 101 private: 102 void _EnumerateBus(int domain, uint8 bus, 103 uint8 *subordinateBus = NULL); 104 105 void _FixupDevices(int domain, uint8 bus); 106 107 void _DiscoverBus(PCIBus *bus); 108 void _DiscoverDevice(PCIBus *bus, uint8 dev, 109 uint8 function); 110 111 PCIDev * _CreateDevice(PCIBus *parent, uint8 dev, 112 uint8 function); 113 PCIBus * _CreateBus(PCIDev *parent, int domain, uint8 bus); 114 115 status_t _GetNthInfo(PCIBus *bus, long *currentIndex, 116 long wantIndex, pci_info *outInfo); 117 void _ReadBasicInfo(PCIDev *dev); 118 void _ReadHeaderInfo(PCIDev *dev); 119 120 void _ConfigureBridges(PCIBus *bus); 121 void _RefreshDeviceInfo(PCIBus *bus); 122 123 uint32 _BarSize(uint32 bits, uint32 mask); 124 void _GetBarInfo(PCIDev *dev, uint8 offset, 125 uint32 *address, uint32 *size = 0, 126 uint8 *flags = 0); 127 void _GetRomBarInfo(PCIDev *dev, uint8 offset, 128 uint32 *address, uint32 *size = 0, 129 uint8 *flags = 0); 130 131 domain_data * _GetDomainData(int domain); 132 133 status_t _CreateVirtualBus(int domain, uint8 bus, 134 uint8 *virtualBus); 135 136 int _NumFunctions(int domain, uint8 bus, uint8 device); 137 PCIDev * _FindDevice(PCIBus *current, int domain, uint8 bus, 138 uint8 device, uint8 function); 139 140 private: 141 PCIBus * fRootBus; 142 143 enum { MAX_PCI_DOMAINS = 8 }; 144 145 domain_data fDomainData[MAX_PCI_DOMAINS]; 146 int fDomainCount; 147 bool fBusEnumeration; 148 149 typedef VectorMap<uint8, uint16> VirtualBusMap; 150 151 VirtualBusMap fVirtualBusMap; 152 int fNextVirtualBus; 153 }; 154 155 extern PCI *gPCI; 156 157 #endif // __cplusplus 158 159 160 #ifdef __cplusplus 161 extern "C" { 162 #endif 163 164 status_t pci_init(void); 165 void pci_uninit(void); 166 167 long pci_get_nth_pci_info(long index, pci_info *outInfo); 168 169 uint32 pci_read_config(uint8 virtualBus, uint8 device, uint8 function, 170 uint8 offset, uint8 size); 171 void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, 172 uint8 offset, uint8 size, uint32 value); 173 174 void __pci_resolve_virtual_bus(uint8 virtualBus, int *domain, uint8 *bus); 175 176 #ifdef __cplusplus 177 } 178 #endif 179 180 #endif /* __PCI_H__ */ 181