Changeset 32263 in vbox
- Timestamp:
- Sep 7, 2010 6:58:20 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pci.h
r30898 r32263 359 359 } 360 360 361 /** 362 * Gets the header type config register. 363 * 364 * @param pPciDev The PCI device. 365 * @returns u8HdrType The header type. 366 */ 367 DECLINLINE(uint8_t) PCIDevGetHeaderType(PPCIDEVICE pPciDev) 368 { 369 return pPciDev->config[VBOX_PCI_HEADER_TYPE]; 370 } 371 361 372 362 373 /** … … 470 481 { 471 482 return pPciDev->config[VBOX_PCI_CAPABILITY_LIST]; 472 } 483 } 473 484 474 485 /** -
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r32216 r32263 41 41 42 42 /** Array of PCI devices. We assume 32 slots, each with 8 functions. */ 43 R3PTRTYPE(PPCIDEVICE) devices[256];43 R3PTRTYPE(PPCIDEVICE) apDevices[256]; 44 44 /** Array of bridges attached to the bus. */ 45 45 R3PTRTYPE(PPCIDEVICE *) papBridgesR3; … … 61 61 62 62 /** The PCI device for the PCI bridge. */ 63 PCIDEVICE PciDev;63 PCIDEVICE aPciDev; 64 64 65 65 } PCIBUS, *PPCIBUS; … … 92 92 #endif 93 93 94 /** PIC irq levels */95 volatile uint32_t uaPicPciIrqLevels[PCI_IRQ_PINS];96 94 /** I/O APIC irq levels */ 97 95 volatile uint32_t uaPciApicIrqLevels[PCI_APIC_IRQ_PINS]; 98 96 99 /** ACPI IRQ level */ 100 uint32_t uAcpiIrqLevel; 101 /** .. and number */ 102 uint32_t uAcpiIrq; 97 #if 1 /* Will be moved into the BIOS soon. */ 98 /** The next I/O port address which the PCI BIOS will use. */ 99 uint32_t uPciBiosIo; 100 /** The next MMIO address which the PCI BIOS will use. */ 101 uint32_t uPciBiosMmio; 102 /** Actual bus number. */ 103 uint8_t uBus; 104 #endif 105 103 106 104 107 /** Config register. */ 105 108 uint32_t uConfigReg; 106 107 /** I/O APIC usage flag */108 bool fUseIoApic;109 110 109 111 110 /** PCI bus which is attached to the host-to-PCI bridge. */ … … 130 129 /** Converts a device instance pointer to a PCIBUS pointer. */ 131 130 #define DEVINS_2_PCIBUS(pDevIns) ((PPCIBUS)(&PDMINS_2_DATA(pDevIns, PPCIGLOBALS)->aPciBus)) 131 /** Converts a pointer to a PCI root bus instance to a PCIGLOBALS pointer. 132 */ 133 #define PCIROOTBUS_2_PCIGLOBALS(pPciBus) ( (PPCIGLOBALS)((uintptr_t)(pPciBus) - RT_OFFSETOF(PCIGLOBALS, aPciBus)) ) 134 135 136 /** @def PCI_LOCK 137 * Acquires the PDM lock. This is a NOP if locking is disabled. */ 138 /** @def PCI_UNLOCK 139 * Releases the PDM lock. This is a NOP if locking is disabled. */ 140 #define PCI_LOCK(pDevIns, rc) \ 141 do { \ 142 int rc2 = DEVINS_2_PCIBUS(pDevIns)->CTX_SUFF(pPciHlp)->pfnLock((pDevIns), rc); \ 143 if (rc2 != VINF_SUCCESS) \ 144 return rc2; \ 145 } while (0) 146 #define PCI_UNLOCK(pDevIns) \ 147 DEVINS_2_PCIBUS(pDevIns)->CTX_SUFF(pPciHlp)->pfnUnlock(pDevIns) 132 148 133 149 #ifndef VBOX_DEVICE_STRUCT_TESTCASE … … 142 158 PDMBOTHCBDECL(int) ich9pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 143 159 160 RT_C_DECLS_END 161 162 /* Prototypes */ 163 static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel); 144 164 #ifdef IN_RING3 165 static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName); 166 static void ich9pciUpdateMappings(PCIDevice *d); 167 static DECLCALLBACK(uint32_t) ich9pciConfigRead(PCIDevice *aDev, uint32_t u32Address, unsigned len); 145 168 DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus); 146 169 #endif 147 170 148 RT_C_DECLS_END149 150 151 171 PDMBOTHCBDECL(void) ich9pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel) 152 172 { 153 return;173 ich9pciSetIrqInternal(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), pPciDev->devfn, pPciDev, iIrq, iLevel); 154 174 } 155 175 156 176 PDMBOTHCBDECL(void) ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel) 157 177 { 158 return; 159 } 160 178 /* 179 * The PCI-to-PCI bridge specification defines how the interrupt pins 180 * are routed from the secondary to the primary bus (see chapter 9). 181 * iIrq gives the interrupt pin the pci device asserted. 182 * We change iIrq here according to the spec and call the SetIrq function 183 * of our parent passing the device which asserted the interrupt instead of the device of the bridge. 184 */ 185 PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS); 186 PPCIDEVICE pPciDevBus = pPciDev; 187 int iIrqPinBridge = iIrq; 188 uint8_t uDevFnBridge = 0; 189 190 /* Walk the chain until we reach the host bus. */ 191 do 192 { 193 uDevFnBridge = pBus->aPciDev.devfn; 194 iIrqPinBridge = ((pPciDevBus->devfn >> 3) + iIrqPinBridge) & 3; 195 196 /* Get the parent. */ 197 pBus = pBus->aPciDev.Int.s.CTX_SUFF(pBus); 198 pPciDevBus = &pBus->aPciDev; 199 } while (pBus->iBus != 0); 200 201 AssertMsgReturnVoid(pBus->iBus == 0, ("This is not the host pci bus iBus=%d\n", pBus->iBus)); 202 ich9pciSetIrqInternal(PCIROOTBUS_2_PCIGLOBALS(pBus), uDevFnBridge, pPciDev, iIrqPinBridge, iLevel); 203 } 204 205 /** 206 * Port I/O Handler for PCI address OUT operations. 207 * 208 * @returns VBox status code. 209 * 210 * @param pDevIns The device instance. 211 * @param pvUser User argument - ignored. 212 * @param uPort Port number used for the OUT operation. 213 * @param u32 The value to output. 214 * @param cb The value size in bytes. 215 */ 161 216 PDMBOTHCBDECL(int) ich9pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 162 217 { 218 Log(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb)); 219 NOREF(pvUser); 220 if (cb == 4) 221 { 222 PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS); 223 PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE); 224 pThis->uConfigReg = u32 & ~3; /* Bits 0-1 are reserved and we silently clear them */ 225 PCI_UNLOCK(pDevIns); 226 } 227 return VINF_SUCCESS; 228 } 229 230 /** 231 * Port I/O Handler for PCI address IN operations. 232 * 233 * @returns VBox status code. 234 * 235 * @param pDevIns The device instance. 236 * @param pvUser User argument - ignored. 237 * @param uPort Port number used for the IN operation. 238 * @param pu32 Where to store the result. 239 * @param cb Number of bytes read. 240 */ 241 PDMBOTHCBDECL(int) ich9pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 242 { 243 NOREF(pvUser); 244 if (cb == 4) 245 { 246 PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS); 247 PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_READ); 248 *pu32 = pThis->uConfigReg; 249 PCI_UNLOCK(pDevIns); 250 Log(("pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32)); 251 return VINF_SUCCESS; 252 } 253 254 Log(("ich9pciIOPortAddressRead: Port=%#x cb=%d VERR_IOM_IOPORT_UNUSED\n", Port, cb)); 255 256 return VERR_IOM_IOPORT_UNUSED; 257 } 258 259 static int ich9pciDataWrite(PPCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len) 260 { 261 uint8_t iBus, iDevice; 262 uint32_t uConfigReg; 263 264 Log(("ich9pciDataWrite: addr=%08x val=%08x len=%d\n", pGlobals->uConfigReg, val, len)); 265 266 if (!(pGlobals->uConfigReg & (1 << 31))) 267 return VINF_SUCCESS; 268 269 if ((pGlobals->uConfigReg & 0x3) != 0) 270 return VINF_SUCCESS; 271 272 /* Compute destination device */ 273 iBus = (pGlobals->uConfigReg >> 16) & 0xff; 274 iDevice = (pGlobals->uConfigReg >> 8) & 0xff; 275 /* And config register */ 276 uConfigReg = (pGlobals->uConfigReg & 0xfc) | (addr & 3); 277 if (iBus != 0) 278 { 279 if (pGlobals->aPciBus.cBridges) 280 { 281 #ifdef IN_RING3 /** @todo do lookup in R0/RC too! */ 282 PPCIDEVICE pBridgeDevice = ich9pciFindBridge(&pGlobals->aPciBus, iBus); 283 if (pBridgeDevice) 284 { 285 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite); 286 pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, uConfigReg, val, len); 287 } 288 #else 289 return VINF_IOM_HC_IOPORT_WRITE; 290 #endif 291 } 292 } 293 else 294 { 295 if (pGlobals->aPciBus.apDevices[iDevice]) 296 { 297 #ifdef IN_RING3 298 R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[iDevice]; 299 Log(("ich9pciConfigWrite: %s: addr=%02x val=%08x len=%d\n", aDev->name, uConfigReg, val, len)); 300 aDev->Int.s.pfnConfigWrite(aDev, uConfigReg, val, len); 301 #else 302 return VINF_IOM_HC_IOPORT_WRITE; 303 #endif 304 } 305 } 306 return VINF_SUCCESS; 307 } 308 309 /** 310 * Port I/O Handler for PCI data OUT operations. 311 * 312 * @returns VBox status code. 313 * 314 * @param pDevIns The device instance. 315 * @param pvUser User argument - ignored. 316 * @param uPort Port number used for the OUT operation. 317 * @param u32 The value to output. 318 * @param cb The value size in bytes. 319 */ 320 PDMBOTHCBDECL(int) ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 321 { 322 Log(("pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb)); 323 NOREF(pvUser); 324 int rc = VINF_SUCCESS; 325 if (!(Port % cb)) 326 { 327 PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE); 328 rc = ich9pciDataWrite(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, u32, cb); 329 PCI_UNLOCK(pDevIns); 330 } 331 else 332 AssertMsgFailed(("Unaligned write to port %#x u32=%#x cb=%d\n", Port, u32, cb)); 333 return rc; 334 } 335 336 static int ich9pciDataRead(PPCIGLOBALS pGlobals, uint32_t addr, int len, uint32_t *pu32) 337 { 338 uint8_t iBus, iDevice; 339 uint32_t uConfigReg; 340 341 *pu32 = 0xffffffff; 342 343 if (!(pGlobals->uConfigReg & (1 << 31))) 344 return VINF_SUCCESS; 345 346 if ((pGlobals->uConfigReg & 0x3) != 0) 347 return VINF_SUCCESS; 348 349 /* Compute destination device */ 350 iBus = (pGlobals->uConfigReg >> 16) & 0xff; 351 iDevice = (pGlobals->uConfigReg >> 8) & 0xff; 352 /* And config register */ 353 uConfigReg = (pGlobals->uConfigReg & 0xfc) | (addr & 3); 354 if (iBus != 0) 355 { 356 if (pGlobals->aPciBus.cBridges) 357 { 358 #ifdef IN_RING3 /** @todo do lookup in R0/RC too! */ 359 PPCIDEVICE pBridgeDevice = ich9pciFindBridge(&pGlobals->aPciBus, iBus); 360 if (pBridgeDevice) 361 { 362 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead); 363 *pu32 = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, uConfigReg, len); 364 } 365 #else 366 return VINF_IOM_HC_IOPORT_READ; 367 #endif 368 } 369 } 370 else 371 { 372 if (pGlobals->aPciBus.apDevices[iDevice]) 373 { 374 #ifdef IN_RING3 375 R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[iDevice]; 376 *pu32 = aDev->Int.s.pfnConfigRead(aDev, uConfigReg, len); 377 Log(("ich9pciConfigRead: %s: addr=%02x val=%08x len=%d\n", aDev->name, uConfigReg, *pu32, len)); 378 #else 379 return VINF_IOM_HC_IOPORT_READ; 380 #endif 381 } 382 } 383 384 return VINF_SUCCESS; 385 } 386 387 /** 388 * Port I/O Handler for PCI data IN operations. 389 * 390 * @returns VBox status code. 391 * 392 * @param pDevIns The device instance. 393 * @param pvUser User argument - ignored. 394 * @param uPort Port number used for the IN operation. 395 * @param pu32 Where to store the result. 396 * @param cb Number of bytes read. 397 */ 398 PDMBOTHCBDECL(int) ich9pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 399 { 400 NOREF(pvUser); 401 if (!(Port % cb)) 402 { 403 PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_READ); 404 int rc = ich9pciDataRead(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, cb, pu32); 405 PCI_UNLOCK(pDevIns); 406 Log(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc)); 407 return rc; 408 } 409 AssertMsgFailed(("Unaligned read from port %#x cb=%d\n", Port, cb)); 410 return VERR_IOM_IOPORT_UNUSED; 411 } 412 413 static inline int ich9pciSlot2ApicIrq(uint8_t uSlot, int irq_num) 414 { 415 return (irq_num + uSlot) & 7; 416 } 417 418 static inline void ich9pciApicLevelUp(PPCIGLOBALS pGlobals, int irq_num) 419 { 420 ASMAtomicIncU32(&pGlobals->uaPciApicIrqLevels[irq_num]); 421 } 422 423 static inline void ich9pciApicLevelDown(PPCIGLOBALS pGlobals, int irq_num) 424 { 425 ASMAtomicDecU32(&pGlobals->uaPciApicIrqLevels[irq_num]); 426 } 427 428 429 static void ich9pciApicSetIrq(PPCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev, int irq_num1, int iLevel, int iForcedIrq) 430 { 431 /* This is only allowed to be called with a pointer to the root bus. */ 432 AssertMsg(pBus->iBus == 0, ("iBus=%u\n", pBus->iBus)); 433 434 if (iForcedIrq == -1) 435 { 436 int apic_irq, apic_level; 437 PPCIGLOBALS pGlobals = PCIROOTBUS_2_PCIGLOBALS(pBus); 438 int irq_num = ich9pciSlot2ApicIrq(uDevFn >> 3, irq_num1); 439 440 if ((iLevel & PDM_IRQ_LEVEL_HIGH) == PDM_IRQ_LEVEL_HIGH) 441 ich9pciApicLevelUp(pGlobals, irq_num); 442 else if ((iLevel & PDM_IRQ_LEVEL_HIGH) == PDM_IRQ_LEVEL_LOW) 443 ich9pciApicLevelDown(pGlobals, irq_num); 444 445 apic_irq = irq_num + 0x10; 446 apic_level = pGlobals->uaPciApicIrqLevels[irq_num] != 0; 447 Log3(("ich9pciApicSetIrq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d\n", 448 R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num)); 449 pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level); 450 451 if ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP) 452 { 453 /** 454 * we raised it few lines above, as PDM_IRQ_LEVEL_FLIP_FLOP has 455 * PDM_IRQ_LEVEL_HIGH bit set 456 */ 457 ich9pciApicLevelDown(pGlobals, irq_num); 458 pPciDev->Int.s.uIrqPinState = PDM_IRQ_LEVEL_LOW; 459 apic_level = pGlobals->uaPciApicIrqLevels[irq_num] != 0; 460 Log3(("ich9pciApicSetIrq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d (flop)\n", 461 R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num)); 462 pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level); 463 } 464 } else { 465 Log3(("ich9pciApicSetIrq: %s: irq_num1=%d level=%d acpi_irq=%d\n", 466 R3STRING(pPciDev->name), irq_num1, iLevel, iForcedIrq)); 467 pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), iForcedIrq, iLevel); 468 } 469 } 470 471 static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel) 472 { 473 PPCIBUS pBus = &pGlobals->aPciBus; 474 const bool fIsAcpiDevice = PCIDevGetDeviceId(pPciDev) == 0x7113; 475 476 /* Check if the state changed. */ 477 if (pPciDev->Int.s.uIrqPinState != iLevel) 478 { 479 pPciDev->Int.s.uIrqPinState = (iLevel & PDM_IRQ_LEVEL_HIGH); 480 481 /* Send interrupt to I/O APIC only now. */ 482 if (fIsAcpiDevice) 483 /* 484 * ACPI needs special treatment since SCI is hardwired and 485 * should not be affected by PCI IRQ routing tables at the 486 * same time SCI IRQ is shared in PCI sense hence this 487 * kludge (i.e. we fetch the hardwired value from ACPIs 488 * PCI device configuration space). 489 */ 490 ich9pciApicSetIrq(pBus, uDevFn, pPciDev, -1, iLevel, PCIDevGetInterruptLine(pPciDev)); 491 else 492 ich9pciApicSetIrq(pBus, uDevFn, pPciDev, iIrq, iLevel, -1); 493 } 494 } 495 496 #ifdef IN_RING3 497 DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus) 498 { 499 /* Search for a fitting bridge. */ 500 for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++) 501 { 502 /* 503 * Examine secondary and subordinate bus number. 504 * If the target bus is in the range we pass the request on to the bridge. 505 */ 506 PPCIDEVICE pBridgeTemp = pBus->papBridgesR3[iBridge]; 507 AssertMsg(pBridgeTemp && pBridgeTemp->Int.s.fPciToPciBridge, 508 ("Device is not a PCI bridge but on the list of PCI bridges\n")); 509 510 if ( iBus >= pBridgeTemp->config[VBOX_PCI_SECONDARY_BUS] 511 && iBus <= pBridgeTemp->config[VBOX_PCI_SUBORDINATE_BUS]) 512 return pBridgeTemp; 513 } 514 515 /* Nothing found. */ 516 return NULL; 517 } 518 519 /// @todo: simplify 520 static void ich9pciUpdateMappings(PCIDevice *d) 521 { 522 PPCIBUS pBus = d->Int.s.CTX_SUFF(pBus); 523 int cmd, i; 524 uint32_t last_addr, new_addr, config_ofs; 525 526 cmd = PCIDevGetCommand(d); 527 for (i = 0; i < PCI_NUM_REGIONS; i++) { 528 PCIIORegion* r = &d->Int.s.aIORegions[i]; 529 if (i == PCI_ROM_SLOT) { 530 config_ofs = 0x30; 531 } else { 532 config_ofs = 0x10 + i * 4; 533 } 534 if (r->size != 0) { 535 if (r->type & PCI_ADDRESS_SPACE_IO) { 536 if (cmd & PCI_COMMAND_IOACCESS) { 537 new_addr = ich9pciConfigRead(d, config_ofs, 4); 538 new_addr = new_addr & ~(r->size - 1); 539 last_addr = new_addr + r->size - 1; 540 /* NOTE: we have only 64K ioports on PC */ 541 if (last_addr <= new_addr || new_addr == 0 || 542 last_addr >= 0x10000) { 543 new_addr = ~0U; 544 } 545 } else { 546 new_addr = ~0U; 547 } 548 } else { 549 if (cmd & PCI_COMMAND_MEMACCESS) { 550 new_addr = ich9pciConfigRead(d, config_ofs, 4); 551 /* the ROM slot has a specific enable bit */ 552 if (i == PCI_ROM_SLOT && !(new_addr & 1)) 553 goto no_mem_map; 554 new_addr = new_addr & ~(r->size - 1); 555 last_addr = new_addr + r->size - 1; 556 /* NOTE: we do not support wrapping */ 557 /* XXX: as we cannot support really dynamic 558 mappings, we handle specific values as invalid 559 mappings. */ 560 if (last_addr <= new_addr || new_addr == 0 || 561 last_addr == ~0U) { 562 new_addr = ~0U; 563 } 564 } else { 565 no_mem_map: 566 new_addr = ~0U; 567 } 568 } 569 /* now do the real mapping */ 570 if (new_addr != r->addr) { 571 if (r->addr != ~0U) { 572 if (r->type & PCI_ADDRESS_SPACE_IO) { 573 int devclass; 574 /* NOTE: specific hack for IDE in PC case: 575 only one byte must be mapped. */ 576 devclass = d->config[0x0a] | (d->config[0x0b] << 8); 577 if (devclass == 0x0101 && r->size == 4) { 578 int rc = PDMDevHlpIOPortDeregister(d->pDevIns, r->addr + 2, 1); 579 AssertRC(rc); 580 } else { 581 int rc = PDMDevHlpIOPortDeregister(d->pDevIns, r->addr, r->size); 582 AssertRC(rc); 583 } 584 } else { 585 RTGCPHYS GCPhysBase = r->addr; 586 int rc; 587 if (pBus->pPciHlpR3->pfnIsMMIO2Base(pBus->pDevInsR3, d->pDevIns, GCPhysBase)) 588 { 589 /* unmap it. */ 590 rc = r->map_func(d, i, NIL_RTGCPHYS, r->size, (PCIADDRESSSPACE)(r->type)); 591 AssertRC(rc); 592 rc = PDMDevHlpMMIO2Unmap(d->pDevIns, i, GCPhysBase); 593 } 594 else 595 rc = PDMDevHlpMMIODeregister(d->pDevIns, GCPhysBase, r->size); 596 AssertMsgRC(rc, ("rc=%Rrc d=%s i=%d GCPhysBase=%RGp size=%#x\n", rc, d->name, i, GCPhysBase, r->size)); 597 } 598 } 599 r->addr = new_addr; 600 if (r->addr != ~0U) { 601 int rc = r->map_func(d, i, 602 r->addr + (r->type & PCI_ADDRESS_SPACE_IO ? 0 : 0), 603 r->size, (PCIADDRESSSPACE)(r->type)); 604 AssertRC(rc); 605 } 606 } 607 } 608 } 609 } 610 611 static DECLCALLBACK(int) ich9pciRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev) 612 { 613 PPCIBUS pBus = DEVINS_2_PCIBUS(pDevIns); 614 615 /* 616 * Check input. 617 */ 618 if ( !pszName 619 || !pPciDev 620 || iDev >= (int)RT_ELEMENTS(pBus->apDevices) 621 ) 622 { 623 AssertMsgFailed(("Invalid argument! pszName=%s pPciDev=%p iDev=%d\n", pszName, pPciDev, iDev)); 624 return VERR_INVALID_PARAMETER; 625 } 626 627 /* 628 * Register the device. 629 */ 630 return ich9pciRegisterInternal(pBus, iDev, pPciDev, pszName); 631 } 632 633 static DECLCALLBACK(int) ich9pcibridgeRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev) 634 { 163 635 return 0; 164 636 } 165 637 166 PDMBOTHCBDECL(int) ich9pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)167 {168 return 0;169 }170 171 PDMBOTHCBDECL(int) ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)172 {173 return 0;174 }175 176 PDMBOTHCBDECL(int) ich9pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)177 {178 return 0;179 }180 181 #ifdef IN_RING3182 DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus);183 #endif184 185 #ifdef IN_RING3186 187 static DECLCALLBACK(int) ich9pciRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)188 {189 return 0;190 }191 192 static DECLCALLBACK(int) ich9pcibridgeRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)193 {194 return 0;195 }196 197 638 static DECLCALLBACK(int) ich9pciIORegionRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback) 198 639 { 199 return 0; 640 /* 641 * Validate. 642 */ 643 AssertMsgReturn( enmType == PCI_ADDRESS_SPACE_MEM 644 || enmType == PCI_ADDRESS_SPACE_IO 645 || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH, 646 ("Invalid enmType=%#x? Or was this a bitmask after all...\n", enmType), 647 VERR_INVALID_PARAMETER); 648 AssertMsgReturn((unsigned)iRegion < PCI_NUM_REGIONS, 649 ("Invalid iRegion=%d PCI_NUM_REGIONS=%d\n", iRegion, PCI_NUM_REGIONS), 650 VERR_INVALID_PARAMETER); 651 int iLastSet = ASMBitLastSetU32(cbRegion); 652 AssertMsgReturn( iLastSet != 0 653 && RT_BIT_32(iLastSet - 1) == cbRegion, 654 ("Invalid cbRegion=%#x iLastSet=%#x (not a power of 2 or 0)\n", cbRegion, iLastSet), 655 VERR_INVALID_PARAMETER); 656 657 /* 658 * Register the I/O region. 659 */ 660 PPCIIOREGION pRegion = &pPciDev->Int.s.aIORegions[iRegion]; 661 pRegion->addr = ~0U; 662 pRegion->size = cbRegion; 663 pRegion->type = enmType; 664 pRegion->map_func = pfnCallback; 665 666 /* Set type in the config space. */ 667 uint32_t u32Address = 0x10 + iRegion * 4; 668 uint32_t u32Value = (enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH ? (1 << 3) : 0) 669 | (enmType == PCI_ADDRESS_SPACE_IO ? 1 : 0); 670 *(uint32_t *)(pPciDev->config + u32Address) = RT_H2LE_U32(u32Value); 671 672 return VINF_SUCCESS; 200 673 } 201 674 … … 203 676 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld) 204 677 { 678 if (ppfnReadOld) 679 *ppfnReadOld = pPciDev->Int.s.pfnConfigRead; 680 pPciDev->Int.s.pfnConfigRead = pfnRead; 681 682 if (ppfnWriteOld) 683 *ppfnWriteOld = pPciDev->Int.s.pfnConfigWrite; 684 pPciDev->Int.s.pfnConfigWrite = pfnWrite; 205 685 } 206 686 … … 223 703 * Iterate thru all the devices. 224 704 */ 225 for (uint32_t i = 0; i < RT_ELEMENTS(pBus-> devices); i++)226 { 227 PPCIDEVICE pDev = pBus-> devices[i];705 for (uint32_t i = 0; i < RT_ELEMENTS(pBus->apDevices); i++) 706 { 707 PPCIDEVICE pDev = pBus->apDevices[i]; 228 708 if (pDev) 229 709 { … … 286 766 } 287 767 768 static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions) 769 { 770 } 771 772 static const uint8_t auPciIrqs[4] = { 11, 9, 11, 9 }; 773 288 774 static DECLCALLBACK(int) ich9pciFakePCIBIOS(PPDMDEVINS pDevIns) 289 775 { 290 return 0; 776 unsigned i; 777 uint8_t elcr[2] = {0, 0}; 778 PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS); 779 PVM pVM = PDMDevHlpGetVM(pDevIns); 780 Assert(pVM); 781 782 /* 783 * Set the start addresses. 784 */ 785 pGlobals->uPciBiosIo = 0xd000; 786 pGlobals->uPciBiosMmio = UINT32_C(0xf0000000); 787 pGlobals->uBus = 0; 788 789 /* 790 * Activate IRQ mappings. 791 */ 792 for (i = 0; i < 4; i++) 793 { 794 uint8_t irq = auPciIrqs[i]; 795 /* Set to trigger level. */ 796 elcr[irq >> 3] |= (1 << (irq & 7)); 797 } 798 799 /* Tell to the PIC. */ 800 VBOXSTRICTRC rcStrict = IOMIOPortWrite(pVM, 0x4d0, elcr[0], sizeof(uint8_t)); 801 if (rcStrict == VINF_SUCCESS) 802 rcStrict = IOMIOPortWrite(pVM, 0x4d1, elcr[1], sizeof(uint8_t)); 803 if (rcStrict != VINF_SUCCESS) 804 { 805 AssertMsgFailed(("Writing to PIC failed! rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 806 return RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR : VBOXSTRICTRC_VAL(rcStrict); 807 } 808 809 /* 810 * Init the devices. 811 */ 812 for (i = 0; i < 256; i++) 813 { 814 uint8_t aBridgePositions[256]; 815 816 memset(aBridgePositions, 0, sizeof(aBridgePositions)); 817 Log2(("PCI: Initializing device %d (%#x)\n", 818 i, 0x80000000 | (i << 8))); 819 ich9pciBiosInitDevice(pGlobals, 0, i, 0, aBridgePositions); 820 } 821 822 return VINF_SUCCESS; 291 823 } 292 824 293 825 static DECLCALLBACK(uint32_t) ich9pciConfigRead(PCIDevice *aDev, uint32_t u32Address, unsigned len) 294 826 { 295 if (u32Address + len >= 256) 296 { 297 Assert(false); 298 return 0; 299 } 300 827 AssertMsgReturn(u32Address + len <= 256, ("Read after end of PCI config space\n"), 828 0); 301 829 switch (len) 302 830 { … … 312 840 313 841 314 static DECLCALLBACK(void) ich9pciConfigWrite(PCIDevice *aDev, uint32_t u32Address, uint32_t val, unsigned len) 315 { 316 // @todo: write me 842 /** 843 * See paragraph 7.5 of PCI Express specification (p. 349) for definition of 844 * registers and their writability policy. 845 */ 846 static DECLCALLBACK(void) ich9pciConfigWrite(PCIDevice *aDev, uint32_t u32Address, 847 uint32_t val, unsigned len) 848 { 849 /* Fast case - update one of BARs or ROM address, 'while' only for 'break' */ 850 while (len == 4 && 851 (u32Address >= VBOX_PCI_BASE_ADDRESS_0 && 852 u32Address < VBOX_PCI_BASE_ADDRESS_0 + 6 * 4) 853 || 854 (u32Address >= VBOX_PCI_ROM_ADDRESS && u32Address < VBOX_PCI_ROM_ADDRESS+4)) 855 { 856 PCIIORegion *region; 857 int reg, regionSize; 858 859 reg = (u32Address >= VBOX_PCI_ROM_ADDRESS) ? PCI_ROM_SLOT : (u32Address - VBOX_PCI_BASE_ADDRESS_0) >> 2; 860 region = &aDev->Int.s.aIORegions[reg]; 861 regionSize = region->size; 862 if (regionSize == 0) 863 break; 864 /* compute the stored value */ 865 if (reg == PCI_ROM_SLOT) { 866 /* keep ROM enable bit */ 867 val &= (~(regionSize - 1)) | 1; 868 } else { 869 val &= ~(regionSize - 1); 870 val |= region->type; 871 } 872 *(uint32_t *)(aDev->config + u32Address) = RT_H2LE_U32(val); 873 ich9pciUpdateMappings(aDev); 874 return; 875 } 876 877 uint32_t addr = u32Address; 878 bool fUpdateMappings = false; 879 for (uint32_t i = 0; i < len; i++) 880 { 881 bool fWritable = false; 882 switch (PCIDevGetHeaderType(aDev)) 883 { 884 case 0x00: /* normal device */ 885 case 0x80: /* multi-function device */ 886 switch (addr) 887 { 888 /* Read-only registers, see */ 889 case VBOX_PCI_VENDOR_ID: case VBOX_PCI_VENDOR_ID+1: 890 case VBOX_PCI_DEVICE_ID: case VBOX_PCI_DEVICE_ID+1: 891 case VBOX_PCI_REVISION_ID: 892 case VBOX_PCI_CLASS_PROG: 893 case VBOX_PCI_CLASS_SUB: 894 case VBOX_PCI_CLASS_BASE: 895 case VBOX_PCI_HEADER_TYPE: 896 case VBOX_PCI_BASE_ADDRESS_0: case VBOX_PCI_BASE_ADDRESS_0+1: case VBOX_PCI_BASE_ADDRESS_0+2: case VBOX_PCI_BASE_ADDRESS_0+3: 897 case VBOX_PCI_BASE_ADDRESS_1: case VBOX_PCI_BASE_ADDRESS_1+1: case VBOX_PCI_BASE_ADDRESS_1+2: case VBOX_PCI_BASE_ADDRESS_1+3: 898 case VBOX_PCI_BASE_ADDRESS_2: case VBOX_PCI_BASE_ADDRESS_2+1: case VBOX_PCI_BASE_ADDRESS_2+2: case VBOX_PCI_BASE_ADDRESS_2+3: 899 case VBOX_PCI_BASE_ADDRESS_3: case VBOX_PCI_BASE_ADDRESS_3+1: case VBOX_PCI_BASE_ADDRESS_3+2: case VBOX_PCI_BASE_ADDRESS_3+3: 900 case VBOX_PCI_BASE_ADDRESS_4: case VBOX_PCI_BASE_ADDRESS_4+1: case VBOX_PCI_BASE_ADDRESS_4+2: case VBOX_PCI_BASE_ADDRESS_4+3: 901 case VBOX_PCI_BASE_ADDRESS_5: case VBOX_PCI_BASE_ADDRESS_5+1: case VBOX_PCI_BASE_ADDRESS_5+2: case VBOX_PCI_BASE_ADDRESS_5+3: 902 case VBOX_PCI_SUBSYSTEM_VENDOR_ID: case VBOX_PCI_SUBSYSTEM_VENDOR_ID+1: 903 case VBOX_PCI_SUBSYSTEM_ID: case VBOX_PCI_SUBSYSTEM_ID+1: 904 case VBOX_PCI_ROM_ADDRESS: case VBOX_PCI_ROM_ADDRESS+1: case VBOX_PCI_ROM_ADDRESS+2: case VBOX_PCI_ROM_ADDRESS+3: 905 case VBOX_PCI_CAPABILITY_LIST: 906 case VBOX_PCI_INTERRUPT_PIN: 907 fWritable = false; 908 break; 909 /* Others can be written */ 910 default: 911 fWritable = true; 912 break; 913 } 914 break; 915 default: 916 case 0x01: /* bridge */ 917 switch (addr) 918 { 919 /* Read-only registers */ 920 case VBOX_PCI_VENDOR_ID: case VBOX_PCI_VENDOR_ID+1: 921 case VBOX_PCI_DEVICE_ID: case VBOX_PCI_DEVICE_ID+1: 922 case VBOX_PCI_REVISION_ID: 923 case VBOX_PCI_CLASS_PROG: 924 case VBOX_PCI_CLASS_SUB: 925 case VBOX_PCI_CLASS_BASE: 926 case VBOX_PCI_HEADER_TYPE: 927 case VBOX_PCI_ROM_ADDRESS_BR: case VBOX_PCI_ROM_ADDRESS_BR+1: case VBOX_PCI_ROM_ADDRESS_BR+2: case VBOX_PCI_ROM_ADDRESS_BR+3: 928 case VBOX_PCI_INTERRUPT_PIN: 929 fWritable = false; 930 break; 931 default: 932 fWritable = true; 933 break; 934 } 935 break; 936 } 937 938 switch (addr) 939 { 940 case VBOX_PCI_COMMAND: /* Command register, bits 0-7. */ 941 fUpdateMappings = true; 942 aDev->config[addr] = val; 943 break; 944 case VBOX_PCI_COMMAND+1: /* Command register, bits 8-15. */ 945 /* don't change reserved bits (11-15) */ 946 val &= UINT32_C(~0xf8); 947 fUpdateMappings = true; 948 aDev->config[addr] = val; 949 break; 950 case VBOX_PCI_STATUS: /* Status register, bits 0-7. */ 951 /* don't change read-only bits => actually all lower bits are read-only */ 952 val &= UINT32_C(~0xff); 953 /* status register, low part: clear bits by writing a '1' to the corresponding bit */ 954 aDev->config[addr] &= ~val; 955 break; 956 case VBOX_PCI_STATUS+1: /* Status register, bits 8-15. */ 957 /* don't change read-only bits */ 958 val &= UINT32_C(~0x06); 959 /* status register, high part: clear bits by writing a '1' to the corresponding bit */ 960 aDev->config[addr] &= ~val; 961 break; 962 default: 963 if (fWritable) 964 aDev->config[addr] = val; 965 } 966 addr++; 967 val >>= 8; 968 } 969 970 if (fUpdateMappings) 971 /* if the command register is modified, we must modify the mappings */ 972 ich9pciUpdateMappings(aDev); 317 973 } 318 974 … … 348 1004 }, 349 1005 }; 1006 350 1007 static int assignPosition(PPCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName) 351 1008 { … … 361 1018 362 1019 /* Otherwise when assigning a slot, we need to make sure all its functions are available */ 363 for (int iPos = 0; iPos < (int)RT_ELEMENTS(pBus-> devices); iPos += 8)364 if ( !pBus-> devices[iPos]365 && !pBus-> devices[iPos + 1]366 && !pBus-> devices[iPos + 2]367 && !pBus-> devices[iPos + 3]368 && !pBus-> devices[iPos + 4]369 && !pBus-> devices[iPos + 5]370 && !pBus-> devices[iPos + 6]371 && !pBus-> devices[iPos + 7])1020 for (int iPos = 0; iPos < (int)RT_ELEMENTS(pBus->apDevices); iPos += 8) 1021 if ( !pBus->apDevices[iPos] 1022 && !pBus->apDevices[iPos + 1] 1023 && !pBus->apDevices[iPos + 2] 1024 && !pBus->apDevices[iPos + 3] 1025 && !pBus->apDevices[iPos + 4] 1026 && !pBus->apDevices[iPos + 5] 1027 && !pBus->apDevices[iPos + 6] 1028 && !pBus->apDevices[iPos + 7]) 372 1029 { 373 1030 pPciDev->Int.s.fRequestedDevFn = false; … … 380 1037 static bool hasHardAssignedDevsInSlot(PPCIBUS pBus, int iSlot) 381 1038 { 382 PCIDevice** aSlot = &pBus-> devices[iSlot << 3];1039 PCIDevice** aSlot = &pBus->apDevices[iSlot << 3]; 383 1040 384 1041 return (aSlot[0] && aSlot[0]->Int.s.fRequestedDevFn) … … 413 1070 */ 414 1071 if (pPciDev->Int.s.fRequestedDevFn && 415 pBus-> devices[iDev] &&416 pBus-> devices[iDev]->Int.s.fRequestedDevFn)1072 pBus->apDevices[iDev] && 1073 pBus->apDevices[iDev]->Int.s.fRequestedDevFn) 417 1074 { 418 1075 /* 419 * Smth like hasHardAssignedDevsInSlot(pBus, iDev >> 3) shall be use to make 420 * it compatible with DevPCI.cpp version, but this way we cannot assign 1076 * Smth like hasHardAssignedDevsInSlot(pBus, iDev >> 3) shall be use to make 1077 * it compatible with DevPCI.cpp version, but this way we cannot assign 421 1078 * in accordance with the chipset spec. 422 1079 */ 423 1080 AssertReleaseMsgFailed(("Configuration error:'%s' and '%s' are both configured as device %d\n", 424 pszName, pBus-> devices[iDev]->name, iDev));1081 pszName, pBus->apDevices[iDev]->name, iDev)); 425 1082 return VERR_INTERNAL_ERROR; 426 1083 } 427 1084 428 if (pBus-> devices[iDev])1085 if (pBus->apDevices[iDev]) 429 1086 { 430 1087 /* if we got here, we shall (and usually can) relocate the device */ 431 int iRelDev = assignPosition(pBus, pBus-> devices[iDev], pBus->devices[iDev]->name);1088 int iRelDev = assignPosition(pBus, pBus->apDevices[iDev], pBus->apDevices[iDev]->name); 432 1089 if (iRelDev < 0 || iRelDev == iDev) 433 1090 { … … 438 1095 for (int i = 0; i < 8; i++) 439 1096 { 440 if (!pBus-> devices[iDev + i])1097 if (!pBus->apDevices[iDev + i]) 441 1098 continue; 442 Log(("PCI: relocating '%s' from slot %#x to %#x\n", pBus-> devices[iDev + i]->name, iDev + i, iRelDev + i));443 pBus-> devices[iRelDev + i] = pBus->devices[iDev + i];444 pBus-> devices[iRelDev + i]->devfn = i;445 pBus-> devices[iDev + i] = NULL;1099 Log(("PCI: relocating '%s' from slot %#x to %#x\n", pBus->apDevices[iDev + i]->name, iDev + i, iRelDev + i)); 1100 pBus->apDevices[iRelDev + i] = pBus->apDevices[iDev + i]; 1101 pBus->apDevices[iRelDev + i]->devfn = i; 1102 pBus->apDevices[iDev + i] = NULL; 446 1103 } 447 1104 } … … 457 1114 pPciDev->Int.s.pfnConfigRead = ich9pciConfigRead; 458 1115 pPciDev->Int.s.pfnConfigWrite = ich9pciConfigWrite; 459 pBus-> devices[iDev]= pPciDev;1116 pBus->apDevices[iDev] = pPciDev; 460 1117 if (pPciDev->Int.s.fPciToPciBridge) 461 1118 { 462 AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus-> devices), ("Number of bridges exceeds the number of possible devices on the bus\n"));1119 AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus->apDevices), ("Number of bridges exceeds the number of possible devices on the bus\n")); 463 1120 AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite, 464 1121 ("device is a bridge but does not implement read/write functions\n")); … … 516 1173 memset(pGlobals, 0, sizeof(*pGlobals)); 517 1174 /* And fill values */ 518 pGlobals->fUseIoApic = fUseIoApic; 1175 if (!fUseIoApic) 1176 return PDMDEV_SET_ERROR(pDevIns, rc, 1177 N_("Must use IO-APIC with ICH9 chipset")); 519 1178 pGlobals->pDevInsR3 = pDevIns; 520 1179 pGlobals->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); … … 524 1183 pGlobals->aPciBus.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 525 1184 pGlobals->aPciBus.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 526 pGlobals->aPciBus.papBridgesR3 = (PPCIDEVICE *)PDMDevHlpMMHeapAllocZ(pDevIns, sizeof(PPCIDEVICE) * RT_ELEMENTS(pGlobals->aPciBus. devices));1185 pGlobals->aPciBus.papBridgesR3 = (PPCIDEVICE *)PDMDevHlpMMHeapAllocZ(pDevIns, sizeof(PPCIDEVICE) * RT_ELEMENTS(pGlobals->aPciBus.apDevices)); 527 1186 528 1187 /* … … 564 1223 * A2 SLA9M NH82801IB 565 1224 */ 566 PCIDevSetVendorId( &pBus-> PciDev, 0x8086); /* Intel */567 PCIDevSetDeviceId( &pBus-> PciDev, 0x244e); /* Desktop */568 PCIDevSetRevisionId(&pBus-> PciDev, 0x92); /* rev. A2 */569 PCIDevSetClassSub( &pBus-> PciDev, 0x00); /* Host/PCI bridge */570 PCIDevSetClassBase( &pBus-> PciDev, 0x06); /* bridge */571 PCIDevSetHeaderType(&pBus-> PciDev, 0x00);572 573 pBus-> PciDev.pDevIns= pDevIns;574 pBus-> PciDev.Int.s.fRequestedDevFn= true;1225 PCIDevSetVendorId( &pBus->aPciDev, 0x8086); /* Intel */ 1226 PCIDevSetDeviceId( &pBus->aPciDev, 0x244e); /* Desktop */ 1227 PCIDevSetRevisionId(&pBus->aPciDev, 0x92); /* rev. A2 */ 1228 PCIDevSetClassSub( &pBus->aPciDev, 0x00); /* Host/PCI bridge */ 1229 PCIDevSetClassBase( &pBus->aPciDev, 0x06); /* bridge */ 1230 PCIDevSetHeaderType(&pBus->aPciDev, 0x00); 1231 1232 pBus->aPciDev.pDevIns = pDevIns; 1233 pBus->aPciDev.Int.s.fRequestedDevFn = true; 575 1234 /* We register Host<->PCI controller on the bus */ 576 ich9pciRegisterInternal(pBus, 0, &pBus-> PciDev, "i82801");1235 ich9pciRegisterInternal(pBus, 0, &pBus->aPciDev, "i82801"); 577 1236 578 1237 /** @todo: ther chipset devices shall be registered too */ … … 587 1246 static DECLCALLBACK(void) ich9pciRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta) 588 1247 { 1248 PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS); 1249 PPCIBUS pBus = &pGlobals->aPciBus; 1250 pGlobals->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1251 1252 pBus->pPciHlpRC = pBus->pPciHlpR3->pfnGetRCHelpers(pDevIns); 1253 pBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1254 1255 /* Relocate RC pointers for the attached pci devices. */ 1256 for (uint32_t i = 0; i < RT_ELEMENTS(pBus->apDevices); i++) 1257 { 1258 if (pBus->apDevices[i]) 1259 pBus->apDevices[i]->Int.s.pBusRC += offDelta; 1260 } 1261 589 1262 } 590 1263
Note:
See TracChangeset
for help on using the changeset viewer.