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 #if defined(__i386__) || defined(__x86_64__) 19 #include "pci_arch_info.h" 20 #endif 21 22 #define TRACE_PCI 23 #ifndef TRACE_PCI 24 # define TRACE(x) 25 #else 26 # define TRACE(x) dprintf x 27 #endif 28 29 #ifdef __cplusplus 30 31 struct PCIDev; 32 33 struct PCIBus { 34 PCIBus * next; 35 PCIDev * parent; 36 PCIDev * child; 37 uint8 domain; 38 uint8 bus; 39 }; 40 41 struct PCIDev { 42 PCIDev * next; 43 PCIBus * parent; 44 PCIBus * child; 45 uint8 domain; 46 uint8 bus; 47 uint8 device; 48 uint8 function; 49 pci_info info; 50 #if defined(__i386__) || defined(__x86_64__) 51 pci_arch_info arch_info; 52 #endif 53 }; 54 55 56 struct domain_data { 57 // These two are set in PCI::AddController: 58 pci_controller * controller; 59 void * controller_cookie; 60 61 // All the rest is set in PCI::InitDomainData 62 int max_bus_devices; 63 }; 64 65 66 class PCI { 67 public: 68 PCI(); 69 ~PCI(); 70 71 void InitDomainData(); 72 void InitBus(); 73 74 status_t AddController(pci_controller *controller, 75 void *controller_cookie); 76 77 status_t GetNthInfo(long index, pci_info *outInfo); 78 79 status_t ReadConfig(uint8 domain, uint8 bus, uint8 device, 80 uint8 function, uint16 offset, uint8 size, 81 uint32 *value); 82 uint32 ReadConfig(uint8 domain, uint8 bus, uint8 device, 83 uint8 function, uint16 offset, uint8 size); 84 uint32 ReadConfig(PCIDev *device, uint16 offset, 85 uint8 size); 86 87 status_t WriteConfig(uint8 domain, uint8 bus, uint8 device, 88 uint8 function, uint16 offset, uint8 size, 89 uint32 value); 90 status_t WriteConfig(PCIDev *device, uint16 offset, 91 uint8 size, uint32 value); 92 93 status_t FindCapability(uint8 domain, uint8 bus, 94 uint8 device, uint8 function, uint8 capID, 95 uint8 *offset = NULL); 96 status_t FindCapability(PCIDev *device, uint8 capID, 97 uint8 *offset = NULL); 98 status_t FindExtendedCapability(uint8 domain, uint8 bus, 99 uint8 device, uint8 function, uint16 capID, 100 uint16 *offset = NULL); 101 status_t FindExtendedCapability(PCIDev *device, 102 uint16 capID, uint16 *offset = NULL); 103 status_t FindHTCapability(uint8 domain, uint8 bus, 104 uint8 device, uint8 function, uint16 capID, 105 uint8 *offset); 106 status_t FindHTCapability(PCIDev *device, 107 uint16 capID, uint8 *offset = NULL); 108 109 status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain, 110 uint8 *bus); 111 112 PCIDev * FindDevice(uint8 domain, uint8 bus, uint8 device, 113 uint8 function); 114 115 void ClearDeviceStatus(PCIBus *bus, bool dumpStatus); 116 117 uint8 GetPowerstate(PCIDev *device); 118 status_t GetPowerstate(uint8 domain, uint8 bus, uint8 device, 119 uint8 function, uint8* state); 120 void SetPowerstate(PCIDev *device, uint8 state); 121 status_t SetPowerstate(uint8 domain, uint8 bus, uint8 device, 122 uint8 function, uint8 newState); 123 124 void RefreshDeviceInfo(); 125 126 status_t UpdateInterruptLine(uint8 domain, uint8 bus, 127 uint8 device, uint8 function, 128 uint8 newInterruptLineValue); 129 130 private: 131 void _EnumerateBus(uint8 domain, uint8 bus, 132 uint8 *subordinateBus = NULL); 133 134 void _FixupDevices(uint8 domain, uint8 bus); 135 136 void _DiscoverBus(PCIBus *bus); 137 void _DiscoverDevice(PCIBus *bus, uint8 dev, 138 uint8 function); 139 140 PCIDev * _CreateDevice(PCIBus *parent, uint8 dev, 141 uint8 function); 142 PCIBus * _CreateBus(PCIDev *parent, uint8 domain, 143 uint8 bus); 144 145 status_t _GetNthInfo(PCIBus *bus, long *currentIndex, 146 long wantIndex, pci_info *outInfo); 147 void _ReadBasicInfo(PCIDev *dev); 148 void _ReadHeaderInfo(PCIDev *dev); 149 150 void _ConfigureBridges(PCIBus *bus); 151 void _RefreshDeviceInfo(PCIBus *bus); 152 153 uint64 _BarSize(uint64 bits); 154 size_t _GetBarInfo(PCIDev *dev, uint8 offset, 155 uint32 &ramAddress, uint32 &pciAddress, 156 uint32 &size, uint8 &flags, 157 uint32 *highRAMAddress = NULL, 158 uint32 *highPCIAddress = NULL, 159 uint32 *highSize = NULL); 160 void _GetRomBarInfo(PCIDev *dev, uint8 offset, 161 uint32 &address, uint32 *size = NULL, 162 uint8 *flags = NULL); 163 164 domain_data * _GetDomainData(uint8 domain); 165 166 status_t _CreateVirtualBus(uint8 domain, uint8 bus, 167 uint8 *virtualBus); 168 169 int _NumFunctions(uint8 domain, uint8 bus, 170 uint8 device); 171 PCIDev * _FindDevice(PCIBus *current, uint8 domain, 172 uint8 bus, uint8 device, uint8 function); 173 174 private: 175 PCIBus * fRootBus; 176 177 enum { MAX_PCI_DOMAINS = 8 }; 178 179 domain_data fDomainData[MAX_PCI_DOMAINS]; 180 uint8 fDomainCount; 181 bool fBusEnumeration; 182 183 typedef VectorMap<uint8, uint16> VirtualBusMap; 184 185 VirtualBusMap fVirtualBusMap; 186 int fNextVirtualBus; 187 }; 188 189 extern PCI *gPCI; 190 191 #endif // __cplusplus 192 193 194 #ifdef __cplusplus 195 extern "C" { 196 #endif 197 198 status_t pci_init(void); 199 status_t pci_init_deferred(void); 200 void pci_uninit(void); 201 202 long pci_get_nth_pci_info(long index, pci_info *outInfo); 203 204 uint32 pci_read_config(uint8 virtualBus, uint8 device, uint8 function, 205 uint16 offset, uint8 size); 206 void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, 207 uint16 offset, uint8 size, uint32 value); 208 209 void __pci_resolve_virtual_bus(uint8 virtualBus, uint8 *domain, uint8 *bus); 210 211 #ifdef __cplusplus 212 } 213 #endif 214 215 #endif /* __PCI_H__ */ 216