Changeset 42127 in vbox for trunk/src/VBox/Devices/PC/BIOS/pcibios.c
- Timestamp:
- Jul 12, 2012 3:21:46 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/pcibios.c
r42030 r42127 63 63 #define BP r.gr.u.r16.bp 64 64 #define SP r.gr.u.r16.sp 65 #define FLAGS r.ra.flags.u.r16.flags66 65 #define EAX r.gr.u.r32.eax 67 66 #define EBX r.gr.u.r32.ebx … … 90 89 #define PCI_CFG_ADDR 0xCF8 91 90 #define PCI_CFG_DATA 0xCFC 91 92 #ifdef __386__ 93 94 #define PCIxx(x) pci32_##x 95 96 /* The stack layout is different in 32-bit mode. */ 97 typedef struct { 98 pushad_regs_t gr; 99 uint32_t flags; 100 } pci_regs_t; 101 102 #define FLAGS r.flags 103 104 /* In 32-bit mode, don't do any output; not technically impossible but needs 105 * a lot of extra code. 106 */ 107 #undef BX_INFO 108 #define BX_INFO(...) 109 #undef BX_DEBUG_PCI 110 #define BX_DEBUG_PCI(...) 111 112 #else 113 114 #define PCIxx(x) pci16_##x 115 116 typedef struct { 117 pushad_regs_t gr; 118 uint16_t es; 119 uint16_t ds; 120 iret_addr_t ra; 121 } pci_regs_t; 122 123 #define FLAGS r.ra.flags.u.r16.flags 124 125 #endif 126 127 #ifdef __386__ 128 129 /* 32-bit code can just use the compiler intrinsics. */ 130 extern unsigned inpd(unsigned port); 131 extern unsigned outpd(unsigned port, unsigned value); 132 #pragma intrinsic(inpd,outpd) 133 134 #else 92 135 93 136 //@todo: merge with AHCI code … … 113 156 parm [dx] [cx ax] modify nomemory; 114 157 158 #endif 159 115 160 /* Write the CONFIG_ADDRESS register to prepare for data access. Requires 116 161 * the register offset to be DWORD aligned (low two bits clear). Warning: … … 131 176 * This is largely a wrapper to avoid excessive inlining. 132 177 */ 133 void pci16_select_reg(uint16_t bus_dev_fn, uint16_t ofs)178 void PCIxx(select_reg)(uint16_t bus_dev_fn, uint16_t ofs) 134 179 { 135 180 pci16_w_addr(bus_dev_fn, ofs & ~3, PCI_CFG_ADDR); 136 181 } 137 182 183 /* Selected configuration space offsets. */ 138 184 #define PCI_VEN_ID 0x00 139 185 #define PCI_DEV_ID 0x02 … … 141 187 #define PCI_CLASS_CODE 0x09 142 188 #define PCI_HEADER_TYPE 0x0E 143 189 #define PCI_BRIDGE_SUBORD 0x1A 190 191 /* To avoid problems with 16-bit code, we reserve the last possible 192 * bus/dev/fn combination (65,535). Upon reaching this location, the 193 * probing will end. 194 */ 195 #define INDEX_NOT_FOUND 0xFFFF 144 196 145 197 /* Find a specified PCI device, either by vendor+device ID or class. … … 151 203 * non-present devices. 152 204 */ 153 uint16_t pci16_find_device(uint32_t search_item, uint16_t index, int search_class)205 uint16_t PCIxx(find_device)(uint32_t search_item, uint16_t index, int search_class) 154 206 { 155 207 uint32_t data; … … 157 209 uint8_t max_bus; 158 210 uint8_t hdr_type; 211 uint8_t subordinate; 159 212 int step; 160 213 int found; … … 179 232 */ 180 233 if ((bus_dev_fn & 7) == 0) { 181 pci16_select_reg(bus_dev_fn, PCI_HEADER_TYPE);234 PCIxx(select_reg)(bus_dev_fn, PCI_HEADER_TYPE); 182 235 hdr_type = inp(PCI_CFG_DATA + (PCI_HEADER_TYPE & 3)); 183 236 if (hdr_type == 0xFF) { … … 196 249 * there will be only the primary bus (i.e. bus 0) and we can avoid 197 250 * looking at the remaining 255 theoretically present buses. This check 198 * only needs to be done on the primary bus (bridges must report all199 * bridges behind them).251 * only needs to be done on the primary bus, since bridges must report 252 * all bridges potentially behind them. 200 253 */ 201 254 if ((hdr_type & 7) == 1 && (bus_dev_fn >> 8) == 0) { 255 /* Read the subordinate (last) bridge number. */ 256 PCIxx(select_reg)(bus_dev_fn, PCI_BRIDGE_SUBORD); 257 subordinate = inp(PCI_CFG_DATA + (PCI_BRIDGE_SUBORD & 3)); 258 if (subordinate > max_bus) 259 max_bus = subordinate; 202 260 } 203 261 204 262 /* Select the appropriate register. */ 205 pci16_select_reg(bus_dev_fn, search_class ? PCI_REV_ID : PCI_VEN_ID);263 PCIxx(select_reg)(bus_dev_fn, search_class ? PCI_REV_ID : PCI_VEN_ID); 206 264 data = inpd(PCI_CFG_DATA); 207 265 found = 0; … … 226 284 } while ((bus_dev_fn >> 8) <= max_bus); 227 285 228 if (index == ~0)286 if (index == INDEX_NOT_FOUND) 229 287 BX_DEBUG_PCI("PCI: Device found (%02X:%%02X:%01X)\n", bus_dev_fn >> 8, 230 288 bus_dev_fn >> 3 & 31, bus_dev_fn & 7); 231 289 232 return index == ~0 ? bus_dev_fn : ~0;290 return index == INDEX_NOT_FOUND ? bus_dev_fn : INDEX_NOT_FOUND; 233 291 } 234 292 235 void BIOSCALL pci16_function(volatile pci_regs_t r)293 void BIOSCALL PCIxx(function)(volatile pci_regs_t r) 236 294 { 237 295 uint16_t device; … … 254 312 * be easily detected. 255 313 */ 256 if (DX == ~0) {314 if (DX == 0xFFFF) { 257 315 SET_AH(BAD_VENDOR_ID); 258 316 SET_CF(); 259 317 } else { 260 device = pci16_find_device(DX | (uint32_t)CX << 16, SI, 0);261 if (device == ~0) {318 device = PCIxx(find_device)(DX | (uint32_t)CX << 16, SI, 0); 319 if (device == INDEX_NOT_FOUND) { 262 320 SET_AH(DEVICE_NOT_FOUND); 263 321 SET_CF(); … … 268 326 break; 269 327 case FIND_PCI_CLASS_CODE: 270 device = pci16_find_device(ECX, SI, 1);271 if (device == ~0) {328 device = PCIxx(find_device)(ECX, SI, 1); 329 if (device == INDEX_NOT_FOUND) { 272 330 SET_AH(DEVICE_NOT_FOUND); 273 331 SET_CF(); … … 286 344 SET_CF(); 287 345 } else { 288 pci16_select_reg(BX, DI);346 PCIxx(select_reg)(BX, DI); 289 347 switch (GET_AL()) { 290 348 case READ_CONFIG_BYTE:
Note:
See TracChangeset
for help on using the changeset viewer.