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(__INTEL__) || 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(__INTEL__) || 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, uint8 offset, uint8 size, 81 uint32 *value); 82 uint32 ReadConfig(uint8 domain, uint8 bus, uint8 device, 83 uint8 function, uint8 offset, uint8 size); 84 uint32 ReadConfig(PCIDev *device, uint8 offset, 85 uint8 size); 86 87 status_t WriteConfig(uint8 domain, uint8 bus, uint8 device, 88 uint8 function, uint8 offset, uint8 size, 89 uint32 value); 90 status_t WriteConfig(PCIDev *device, uint8 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); 96 status_t FindCapability(PCIDev *device, uint8 capID, 97 uint8 *offset); 98 99 status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain, 100 uint8 *bus); 101 102 PCIDev * FindDevice(uint8 domain, uint8 bus, uint8 device, 103 uint8 function); 104 105 void ClearDeviceStatus(PCIBus *bus, bool dumpStatus); 106 107 void RefreshDeviceInfo(); 108 109 status_t UpdateInterruptLine(uint8 domain, uint8 bus, 110 uint8 device, uint8 function, 111 uint8 newInterruptLineValue); 112 113 private: 114 void _EnumerateBus(uint8 domain, uint8 bus, 115 uint8 *subordinateBus = NULL); 116 117 void _FixupDevices(uint8 domain, uint8 bus); 118 119 void _DiscoverBus(PCIBus *bus); 120 void _DiscoverDevice(PCIBus *bus, uint8 dev, 121 uint8 function); 122 123 PCIDev * _CreateDevice(PCIBus *parent, uint8 dev, 124 uint8 function); 125 PCIBus * _CreateBus(PCIDev *parent, uint8 domain, 126 uint8 bus); 127 128 status_t _GetNthInfo(PCIBus *bus, long *currentIndex, 129 long wantIndex, pci_info *outInfo); 130 void _ReadBasicInfo(PCIDev *dev); 131 void _ReadHeaderInfo(PCIDev *dev); 132 133 void _ConfigureBridges(PCIBus *bus); 134 void _RefreshDeviceInfo(PCIBus *bus); 135 136 uint32 _BarSize(uint32 bits, uint32 mask); 137 void _GetBarInfo(PCIDev *dev, uint8 offset, 138 uint32 *address, uint32 *size = 0, 139 uint8 *flags = 0); 140 void _GetRomBarInfo(PCIDev *dev, uint8 offset, 141 uint32 *address, uint32 *size = 0, 142 uint8 *flags = 0); 143 144 domain_data * _GetDomainData(uint8 domain); 145 146 status_t _CreateVirtualBus(uint8 domain, uint8 bus, 147 uint8 *virtualBus); 148 149 int _NumFunctions(uint8 domain, uint8 bus, 150 uint8 device); 151 PCIDev * _FindDevice(PCIBus *current, uint8 domain, 152 uint8 bus, uint8 device, uint8 function); 153 154 private: 155 PCIBus * fRootBus; 156 157 enum { MAX_PCI_DOMAINS = 8 }; 158 159 domain_data fDomainData[MAX_PCI_DOMAINS]; 160 uint8 fDomainCount; 161 bool fBusEnumeration; 162 163 typedef VectorMap<uint8, uint16> VirtualBusMap; 164 165 VirtualBusMap fVirtualBusMap; 166 int fNextVirtualBus; 167 }; 168 169 extern PCI *gPCI; 170 171 #endif // __cplusplus 172 173 174 #ifdef __cplusplus 175 extern "C" { 176 #endif 177 178 status_t pci_init(void); 179 void pci_uninit(void); 180 181 long pci_get_nth_pci_info(long index, pci_info *outInfo); 182 183 uint32 pci_read_config(uint8 virtualBus, uint8 device, uint8 function, 184 uint8 offset, uint8 size); 185 void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, 186 uint8 offset, uint8 size, uint32 value); 187 188 void __pci_resolve_virtual_bus(uint8 virtualBus, uint8 *domain, uint8 *bus); 189 190 #ifdef __cplusplus 191 } 192 #endif 193 194 #endif /* __PCI_H__ */ 195