Changeset 32216 in vbox for trunk/src/VBox
- Timestamp:
- Sep 2, 2010 3:32:04 PM (14 years ago)
- Location:
- trunk/src/VBox/Devices/Bus
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r32152 r32216 33 33 * PCI Bus instance. 34 34 */ 35 typedef struct 35 typedef struct PCIBus 36 36 { 37 37 /** Bus number. */ … … 40 40 uint32_t cBridges; 41 41 42 /** Array of PCI devices. */42 /** Array of PCI devices. We assume 32 slots, each with 8 functions. */ 43 43 R3PTRTYPE(PPCIDEVICE) devices[256]; 44 44 /** Array of bridges attached to the bus. */ … … 291 291 } 292 292 293 static DECLCALLBACK(uint32_t) ich9pciConfigRead(PCIDevice *aDev, uint32_t u32Address, unsigned len) 294 { 295 if (u32Address + len >= 256) 296 { 297 Assert(false); 298 return 0; 299 } 300 301 switch (len) 302 { 303 case 1: 304 return aDev->config[u32Address]; 305 case 2: 306 return RT_LE2H_U16(*(uint16_t *)(aDev->config + u32Address)); 307 default: 308 case 4: 309 return RT_LE2H_U32(*(uint32_t *)(aDev->config + u32Address)); 310 } 311 } 312 313 314 static DECLCALLBACK(void) ich9pciConfigWrite(PCIDevice *aDev, uint32_t u32Address, uint32_t val, unsigned len) 315 { 316 // @todo: write me 317 } 318 319 /* Slot/functions assignment per table at p. 12 of ICH9 family spec update */ 320 static const struct { 321 const char* pszName; 322 int32_t iSlot; 323 int32_t iFunction; 324 } PciSlotAssignments[] = { 325 { 326 "piix3ide", 1, 1 // do we really need it? 327 }, 328 { 329 "lan", 25, 0 330 }, 331 { 332 "hda", 27, 0 /* High Definition Audio */ 333 }, 334 { 335 "i82801", 30, 0 /* Host Controller */ 336 }, 337 { 338 "lpc", 31, 0 /* Low Pin Count bus */ 339 }, 340 { 341 "ahci", 31, 2 /* SATA controller */ 342 }, 343 { 344 "smbus", 31, 3 /* System Management Bus */ 345 }, 346 { 347 "thermal", 31, 6 /* Thermal controller */ 348 }, 349 }; 350 static int assignPosition(PPCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName) 351 { 352 /* Hardcoded slots/functions, per chipset spec */ 353 for (size_t i = 0; i < RT_ELEMENTS(PciSlotAssignments); i++) 354 { 355 if (!strcmp(pszName, PciSlotAssignments[i].pszName)) 356 { 357 pPciDev->Int.s.fRequestedDevFn = true; 358 return (PciSlotAssignments[i].iSlot << 3) + PciSlotAssignments[i].iFunction; 359 } 360 } 361 362 /* 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]) 372 { 373 pPciDev->Int.s.fRequestedDevFn = false; 374 return iPos; 375 } 376 377 return -1; 378 } 379 380 static bool hasHardAssignedDevsInSlot(PPCIBUS pBus, int iSlot) 381 { 382 PCIDevice** aSlot = &pBus->devices[iSlot << 3]; 383 384 return (aSlot[0] && aSlot[0]->Int.s.fRequestedDevFn) 385 || (aSlot[1] && aSlot[1]->Int.s.fRequestedDevFn) 386 || (aSlot[2] && aSlot[2]->Int.s.fRequestedDevFn) 387 || (aSlot[3] && aSlot[3]->Int.s.fRequestedDevFn) 388 || (aSlot[4] && aSlot[4]->Int.s.fRequestedDevFn) 389 || (aSlot[5] && aSlot[5]->Int.s.fRequestedDevFn) 390 || (aSlot[6] && aSlot[6]->Int.s.fRequestedDevFn) 391 || (aSlot[7] && aSlot[7]->Int.s.fRequestedDevFn) 392 ; 393 } 394 293 395 static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName) 294 396 { 397 /* 398 * Find device position 399 */ 400 if (iDev < 0) 401 { 402 iDev = assignPosition(pBus, pPciDev, pszName); 403 if (iDev < 0) 404 { 405 AssertMsgFailed(("Couldn't find free spot!\n")); 406 return VERR_PDM_TOO_PCI_MANY_DEVICES; 407 } 408 } 409 410 /* 411 * Check if we can really take this slot, possibly by relocating 412 * its current habitant, if it wasn't hard assigned too. 413 */ 414 if (pPciDev->Int.s.fRequestedDevFn && 415 pBus->devices[iDev] && 416 pBus->devices[iDev]->Int.s.fRequestedDevFn) 417 { 418 /* 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 421 * in accordance with the chipset spec. 422 */ 423 AssertReleaseMsgFailed(("Configuration error:'%s' and '%s' are both configured as device %d\n", 424 pszName, pBus->devices[iDev]->name, iDev)); 425 return VERR_INTERNAL_ERROR; 426 } 427 428 if (pBus->devices[iDev]) 429 { 430 /* if we got here, we shall (and usually can) relocate the device */ 431 int iRelDev = assignPosition(pBus, pBus->devices[iDev], pBus->devices[iDev]->name); 432 if (iRelDev < 0 || iRelDev == iDev) 433 { 434 AssertMsgFailed(("Couldn't find free spot!\n")); 435 return VERR_PDM_TOO_PCI_MANY_DEVICES; 436 } 437 /* Copy device function by function to its new position */ 438 for (int i = 0; i < 8; i++) 439 { 440 if (!pBus->devices[iDev + i]) 441 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; 446 } 447 } 448 449 /* 450 * Fill in device information. 451 */ 452 pPciDev->devfn = iDev; 453 pPciDev->name = pszName; 454 pPciDev->Int.s.pBusR3 = pBus; 455 pPciDev->Int.s.pBusR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus); 456 pPciDev->Int.s.pBusRC = MMHyperR3ToRC(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus); 457 pPciDev->Int.s.pfnConfigRead = ich9pciConfigRead; 458 pPciDev->Int.s.pfnConfigWrite = ich9pciConfigWrite; 459 pBus->devices[iDev] = pPciDev; 460 if (pPciDev->Int.s.fPciToPciBridge) 461 { 462 AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus->devices), ("Number of bridges exceeds the number of possible devices on the bus\n")); 463 AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite, 464 ("device is a bridge but does not implement read/write functions\n")); 465 pBus->papBridgesR3[pBus->cBridges] = pPciDev; 466 pBus->cBridges++; 467 } 468 469 Log(("PCI: Registered device %d function %d (%#x) '%s'.\n", 470 iDev >> 3, iDev & 7, 0x80000000 | (iDev << 8), pszName)); 471 295 472 return VINF_SUCCESS; 296 473 } … … 396 573 pBus->PciDev.pDevIns = pDevIns; 397 574 pBus->PciDev.Int.s.fRequestedDevFn= true; 575 /* We register Host<->PCI controller on the bus */ 398 576 ich9pciRegisterInternal(pBus, 0, &pBus->PciDev, "i82801"); 577 578 /** @todo: ther chipset devices shall be registered too */ 579 /** @todo: bridges? */ 399 580 400 581 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Bus/PCIInternal.h
r28800 r32216 69 69 typedef PFNPCIBRIDGECONFIGWRITE *PPFNPCIBRIDGECONFIGWRITE; 70 70 71 /* Forward declaration */ 72 struct PCIBus; 73 71 74 /** 72 75 * PCI Device - Internal data.
Note:
See TracChangeset
for help on using the changeset viewer.