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 void SetPowerstate(PCIDev *device, uint8 state); 119 120 void RefreshDeviceInfo(); 121 122 status_t UpdateInterruptLine(uint8 domain, uint8 bus, 123 uint8 device, uint8 function, 124 uint8 newInterruptLineValue); 125 126 private: 127 void _EnumerateBus(uint8 domain, uint8 bus, 128 uint8 *subordinateBus = NULL); 129 130 void _FixupDevices(uint8 domain, uint8 bus); 131 132 void _DiscoverBus(PCIBus *bus); 133 void _DiscoverDevice(PCIBus *bus, uint8 dev, 134 uint8 function); 135 136 PCIDev * _CreateDevice(PCIBus *parent, uint8 dev, 137 uint8 function); 138 PCIBus * _CreateBus(PCIDev *parent, uint8 domain, 139 uint8 bus); 140 141 status_t _GetNthInfo(PCIBus *bus, long *currentIndex, 142 long wantIndex, pci_info *outInfo); 143 void _ReadBasicInfo(PCIDev *dev); 144 void _ReadHeaderInfo(PCIDev *dev); 145 146 void _ConfigureBridges(PCIBus *bus); 147 void _RefreshDeviceInfo(PCIBus *bus); 148 149 uint64 _BarSize(uint64 bits); 150 size_t _GetBarInfo(PCIDev *dev, uint8 offset, 151 uint32 &ramAddress, uint32 &pciAddress, 152 uint32 &size, uint8 &flags, 153 uint32 *highRAMAddress = NULL, 154 uint32 *highPCIAddress = NULL, 155 uint32 *highSize = NULL); 156 void _GetRomBarInfo(PCIDev *dev, uint8 offset, 157 uint32 &address, uint32 *size = NULL, 158 uint8 *flags = NULL); 159 160 domain_data * _GetDomainData(uint8 domain); 161 162 status_t _CreateVirtualBus(uint8 domain, uint8 bus, 163 uint8 *virtualBus); 164 165 int _NumFunctions(uint8 domain, uint8 bus, 166 uint8 device); 167 PCIDev * _FindDevice(PCIBus *current, uint8 domain, 168 uint8 bus, uint8 device, uint8 function); 169 170 private: 171 PCIBus * fRootBus; 172 173 enum { MAX_PCI_DOMAINS = 8 }; 174 175 domain_data fDomainData[MAX_PCI_DOMAINS]; 176 uint8 fDomainCount; 177 bool fBusEnumeration; 178 179 typedef VectorMap<uint8, uint16> VirtualBusMap; 180 181 VirtualBusMap fVirtualBusMap; 182 int fNextVirtualBus; 183 }; 184 185 extern PCI *gPCI; 186 187 #endif // __cplusplus 188 189 190 #ifdef __cplusplus 191 extern "C" { 192 #endif 193 194 status_t pci_init(void); 195 void pci_uninit(void); 196 197 long pci_get_nth_pci_info(long index, pci_info *outInfo); 198 199 uint32 pci_read_config(uint8 virtualBus, uint8 device, uint8 function, 200 uint16 offset, uint8 size); 201 void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, 202 uint16 offset, uint8 size, uint32 value); 203 204 void __pci_resolve_virtual_bus(uint8 virtualBus, uint8 *domain, uint8 *bus); 205 206 #ifdef __cplusplus 207 } 208 #endif 209 210 #endif /* __PCI_H__ */ 211