Changeset 32714 in vbox
- Timestamp:
- Sep 23, 2010 12:28:55 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pci.h
r32589 r32714 187 187 * @returns The register value. 188 188 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance. 189 * @param Address The configuration space register address. [0.. 255]189 * @param Address The configuration space register address. [0..4096] 190 190 * @param cb The register size. [1,2,4] 191 191 */ … … 200 200 * 201 201 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance. 202 * @param Address The configuration space register address. [0.. 255]202 * @param Address The configuration space register address. [0..4096] 203 203 * @param u32Value The value that's being written. The number of bits actually used from 204 204 * this value is determined by the cb parameter. -
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r32637 r32714 106 106 uint64_t u64PciConfigMMioAddress; 107 107 /* Length of PCI config space MMIO region */ 108 uint64_t u64PciConfigMMioLength;108 uint64_t u64PciConfigMMioLength; 109 109 110 110 … … 117 117 } PCIGLOBALS, *PPCIGLOBALS; 118 118 119 120 typedef struct { 121 uint8_t iBus; 122 uint8_t iDeviceFunc; 123 uint16_t iRegister; 124 } PciAddress; 119 125 120 126 /******************************************************************************* … … 176 182 #endif 177 183 184 // See 7.2.2. PCI Express Enhanced Configuration Mechanism for details of address 185 // mapping, we take n=8 approach 186 DECLINLINE(void) ich9pciPhysToPciAddr(RTGCPHYS GCPhysAddr, PciAddress* pPciAddr) 187 { 188 pPciAddr->iBus = (GCPhysAddr >> 20) & ((1<<8) - 1); 189 pPciAddr->iDeviceFunc = (GCPhysAddr >> 15) & ((1<<(5+3)) - 1); // 5 bits - device, 3 bits - function 190 pPciAddr->iRegister = (GCPhysAddr >> 0) & ((1<<(6+4+2)) - 1); // 6 bits - register, 4 bits - extended register, 2 bits -Byte Enable 191 } 192 193 DECLINLINE(void) ich9pciStateToPciAddr(PPCIGLOBALS pGlobals, RTGCPHYS addr, PciAddress* pPciAddr) 194 { 195 pPciAddr->iBus = (pGlobals->uConfigReg >> 16) & 0xff; 196 pPciAddr->iDeviceFunc = (pGlobals->uConfigReg >> 8) & 0xff; 197 pPciAddr->iRegister = (pGlobals->uConfigReg & 0xfc) | (addr & 3); 198 } 199 178 200 PDMBOTHCBDECL(void) ich9pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel) 179 201 { … … 264 286 } 265 287 266 static int ich9pciDataWrite(PPCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len) 267 { 268 uint8_t iBus, iDevice; 269 uint32_t uConfigReg; 270 271 Log(("ich9pciDataWrite: addr=%08x val=%08x len=%d\n", pGlobals->uConfigReg, val, len)); 272 273 if (!(pGlobals->uConfigReg & (1 << 31))) 274 return VINF_SUCCESS; 275 276 if ((pGlobals->uConfigReg & 0x3) != 0) 277 return VINF_SUCCESS; 278 279 /* Compute destination device */ 280 iBus = (pGlobals->uConfigReg >> 16) & 0xff; 281 iDevice = (pGlobals->uConfigReg >> 8) & 0xff; 282 /* And config register */ 283 uConfigReg = (pGlobals->uConfigReg & 0xfc) | (addr & 3); 284 if (iBus != 0) 288 static int ich9pciDataWriteAddr(PPCIGLOBALS pGlobals, PciAddress* pAddr, uint32_t val, int len) 289 { 290 if (pAddr->iBus != 0) 285 291 { 286 292 if (pGlobals->aPciBus.cBridges) 287 293 { 288 294 #ifdef IN_RING3 /** @todo do lookup in R0/RC too! */ 289 PPCIDEVICE pBridgeDevice = ich9pciFindBridge(&pGlobals->aPciBus, iBus);295 PPCIDEVICE pBridgeDevice = ich9pciFindBridge(&pGlobals->aPciBus, pAddr->iBus); 290 296 if (pBridgeDevice) 291 297 { 292 298 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite); 293 pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, uConfigReg, val, len);299 pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, pAddr->iBus, pAddr->iDeviceFunc, pAddr->iRegister, val, len); 294 300 } 295 301 #else … … 300 306 else 301 307 { 302 if (pGlobals->aPciBus.apDevices[ iDevice])308 if (pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc]) 303 309 { 304 310 #ifdef IN_RING3 305 R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[ iDevice];306 Log(("ich9pciConfigWrite: %s: addr=%02x val=%08x len=%d\n", aDev->name, uConfigReg, val, len));307 aDev->Int.s.pfnConfigWrite(aDev, uConfigReg, val, len);311 R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc]; 312 Log(("ich9pciConfigWrite: %s: addr=%02x val=%08x len=%d\n", aDev->name, pAddr->iRegister, val, len)); 313 aDev->Int.s.pfnConfigWrite(aDev, pAddr->iRegister, val, len); 308 314 #else 309 315 return VINF_IOM_HC_IOPORT_WRITE; … … 312 318 } 313 319 return VINF_SUCCESS; 320 } 321 322 static int ich9pciDataWrite(PPCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len) 323 { 324 PciAddress aPciAddr; 325 uint32_t uConfigReg; 326 327 Log(("ich9pciDataWrite: addr=%08x val=%08x len=%d\n", pGlobals->uConfigReg, val, len)); 328 329 if (!(pGlobals->uConfigReg & (1 << 31))) 330 return VINF_SUCCESS; 331 332 if ((pGlobals->uConfigReg & 0x3) != 0) 333 return VINF_SUCCESS; 334 335 /* Compute destination device */ 336 ich9pciStateToPciAddr(pGlobals, addr, &aPciAddr); 337 338 return ich9pciDataWriteAddr(pGlobals, &aPciAddr, val, len); 314 339 } 315 340 … … 341 366 } 342 367 343 static int ich9pciDataRead(PPCIGLOBALS pGlobals, uint32_t addr, int len, uint32_t *pu32) 344 { 345 uint8_t iBus, iDevice; 346 uint32_t uConfigReg; 347 348 *pu32 = 0xffffffff; 349 350 if (!(pGlobals->uConfigReg & (1 << 31))) 351 return VINF_SUCCESS; 352 353 if ((pGlobals->uConfigReg & 0x3) != 0) 354 return VINF_SUCCESS; 355 356 /* Compute destination device */ 357 iBus = (pGlobals->uConfigReg >> 16) & 0xff; 358 iDevice = (pGlobals->uConfigReg >> 8) & 0xff; 359 /* And config register */ 360 uConfigReg = (pGlobals->uConfigReg & 0xfc) | (addr & 3); 361 if (iBus != 0) 368 static int ich9pciDataReadAddr(PPCIGLOBALS pGlobals, PciAddress* pPciAddr, int len, uint32_t *pu32) 369 { 370 if (pPciAddr->iBus != 0) 362 371 { 363 372 if (pGlobals->aPciBus.cBridges) 364 373 { 365 374 #ifdef IN_RING3 /** @todo do lookup in R0/RC too! */ 366 PPCIDEVICE pBridgeDevice = ich9pciFindBridge(&pGlobals->aPciBus, iBus);375 PPCIDEVICE pBridgeDevice = ich9pciFindBridge(&pGlobals->aPciBus, pPciAddr->iBus); 367 376 if (pBridgeDevice) 368 377 { 369 378 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead); 370 *pu32 = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, uConfigReg, len);379 *pu32 = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, pPciAddr->iBus, pPciAddr->iDeviceFunc, pPciAddr->iRegister, len); 371 380 } 372 381 #else … … 377 386 else 378 387 { 379 if (pGlobals->aPciBus.apDevices[ iDevice])388 if (pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc]) 380 389 { 381 390 #ifdef IN_RING3 382 R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[ iDevice];383 *pu32 = aDev->Int.s.pfnConfigRead(aDev, uConfigReg, len);384 Log(("ich9pciConfigRead: %s: addr=%02x val=%08x len=%d\n", aDev->name, uConfigReg, *pu32, len));391 R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc]; 392 *pu32 = aDev->Int.s.pfnConfigRead(aDev, pPciAddr->iRegister, len); 393 Log(("ich9pciConfigRead: %s: addr=%02x val=%08x len=%d\n", aDev->name, pPciAddr->iRegister, *pu32, len)); 385 394 #else 386 395 return VINF_IOM_HC_IOPORT_READ; … … 390 399 391 400 return VINF_SUCCESS; 401 } 402 403 404 static int ich9pciDataRead(PPCIGLOBALS pGlobals, uint32_t addr, int len, uint32_t *pu32) 405 { 406 PciAddress aPciAddr; 407 uint32_t uConfigReg; 408 409 *pu32 = 0xffffffff; 410 411 if (!(pGlobals->uConfigReg & (1 << 31))) 412 return VINF_SUCCESS; 413 414 if ((pGlobals->uConfigReg & 0x3) != 0) 415 return VINF_SUCCESS; 416 417 /* Compute destination device */ 418 ich9pciStateToPciAddr(pGlobals, addr, &aPciAddr); 419 420 return ich9pciDataReadAddr(pGlobals, &aPciAddr, len, pu32); 392 421 } 393 422 … … 503 532 } 504 533 534 PDMBOTHCBDECL(int) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 535 { 536 PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS); 537 PciAddress aDest; 538 uint32_t u32 = 0; 539 540 ich9pciPhysToPciAddr(GCPhysAddr, &aDest); 541 542 PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE); 543 switch (cb) 544 { 545 case 1: 546 u32 = *(uint8_t*)pv; 547 break; 548 case 2: 549 u32 = *(uint16_t*)pv; 550 break; 551 case 4: 552 u32 = *(uint32_t*)pv; 553 break; 554 default: 555 Assert(false); 556 break; 557 } 558 int rc = ich9pciDataWriteAddr(pGlobals, &aDest, u32, cb); 559 PCI_UNLOCK(pDevIns); 560 Assert(false); 561 562 return rc; 563 } 564 565 PDMBOTHCBDECL(int) ich9pciMcfgMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 566 { 567 PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS); 568 PciAddress aDest; 569 uint32_t rv = 0; 570 571 ich9pciPhysToPciAddr(GCPhysAddr, &aDest); 572 573 PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE); 574 int rc = ich9pciDataReadAddr(pGlobals, &aDest, cb, &rv); 575 if (rc == VINF_SUCCESS) 576 { 577 switch (cb) 578 { 579 case 1: 580 *(uint8_t*)pv = (uint8_t)rv; 581 break; 582 case 2: 583 *(uint16_t*)pv = (uint16_t)rv; 584 break; 585 case 4: 586 *(uint32_t*)pv = (uint32_t)rv; 587 break; 588 default: 589 Assert(false); 590 break; 591 } 592 } 593 PCI_UNLOCK(pDevIns); 594 595 Assert(false); 596 return rc; 597 } 598 505 599 #ifdef IN_RING3 506 507 PDMBOTHCBDECL(int) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)508 {509 //PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);510 Assert(false);511 return VINF_IOM_MMIO_UNUSED_FF;512 }513 514 PDMBOTHCBDECL(int) ich9pciMcfgMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)515 {516 //PPCIGLOBALS pGlobals = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);517 Assert(false);518 return VINF_IOM_MMIO_UNUSED_FF;519 }520 600 521 601 DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus) … … 597 677 mappings, we handle specific values as invalid 598 678 mappings. */ 599 if (uLast <= uNew || uNew == 0 || uLast == ~0U)679 if (uLast <= uNew || uNew == 0 || uLast == INVALID_PCI_ADDRESS) 600 680 uNew = INVALID_PCI_ADDRESS; 601 681 } … … 705 785 */ 706 786 PPCIIOREGION pRegion = &pPciDev->Int.s.aIORegions[iRegion]; 707 pRegion->addr = ~0U;787 pRegion->addr = INVALID_PCI_ADDRESS; 708 788 pRegion->size = cbRegion; 709 789 pRegion->type = enmType; … … 1400 1480 static DECLCALLBACK(uint32_t) ich9pciConfigRead(PCIDevice *aDev, uint32_t u32Address, unsigned len) 1401 1481 { 1482 if ((u32Address + len) > 256 && (u32Address + len) < 4096) 1483 { 1484 AssertMsgReturn(false, ("Read from extended registers falled back to generic code\n"), 0); 1485 } 1486 1402 1487 AssertMsgReturn(u32Address + len <= 256, ("Read after end of PCI config space\n"), 1403 1488 0); … … 1422 1507 uint32_t val, unsigned len) 1423 1508 { 1509 if ((u32Address + len) > 256 && (u32Address + len) < 4096) 1510 { 1511 AssertMsgReturnVoid(false, ("Write to extended registers falled back to generic code\n")); 1512 } 1513 1514 AssertMsgReturnVoid(u32Address + len <= 256, ("Write after end of PCI config space\n")); 1515 1424 1516 /* Fast case - update one of BARs or ROM address, 'while' only for 'break' */ 1425 1517 while ( len == 4 … … 1744 1836 * Validate and read configuration. 1745 1837 */ 1746 if (!CFGMR3AreValuesValid(pCfg, 1747 "IOAPIC\0" 1748 "GCEnabled\0" 1838 if (!CFGMR3AreValuesValid(pCfg, 1839 "IOAPIC\0" 1840 "GCEnabled\0" 1749 1841 "R0Enabled\0" 1750 1842 "McfgBase\0" … … 1891 1983 return rc; 1892 1984 } 1985 1986 if (fGCEnabled) 1987 { 1988 1989 rc = PDMDevHlpMMIORegisterRC(pDevIns, 1990 pGlobals->u64PciConfigMMioAddress, 1991 pGlobals->u64PciConfigMMioLength, 1992 0, 1993 "ich9pciMcfgMMIOWrite", 1994 "ich9pciMcfgMMIORead", 1995 NULL); 1996 if (RT_FAILURE(rc)) 1997 { 1998 AssertMsgRC(rc, ("Cannot register MCFG MMIO (GC): %Rrc\n", rc)); 1999 return rc; 2000 } 2001 } 2002 2003 2004 if (fR0Enabled) 2005 { 2006 2007 rc = PDMDevHlpMMIORegisterR0(pDevIns, 2008 pGlobals->u64PciConfigMMioAddress, 2009 pGlobals->u64PciConfigMMioLength, 2010 0, 2011 "ich9pciMcfgMMIOWrite", 2012 "ich9pciMcfgMMIORead", 2013 NULL); 2014 if (RT_FAILURE(rc)) 2015 { 2016 AssertMsgRC(rc, ("Cannot register MCFG MMIO (R0): %Rrc\n", rc)); 2017 return rc; 2018 } 2019 } 1893 2020 } 1894 2021 -
trunk/src/VBox/Devices/PC/vbox.dsl
r32637 r32714 565 565 { 566 566 Memory32Fixed (ReadOnly, 567 0x E0000000, // Address Base567 0xD0000000, // Address Base 568 568 0x10000000, // Address Length 569 569 _Y13)
Note:
See TracChangeset
for help on using the changeset viewer.