- Timestamp:
- Oct 15, 2008 8:27:33 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPCI.cpp
r13233 r13302 55 55 #include <iprt/assert.h> 56 56 #include <iprt/string.h> 57 #ifdef IN_RING3 58 # include <iprt/mem.h> 59 #endif 57 60 58 61 #include "../Builtins.h" … … 79 82 /** Start device number. */ 80 83 int32_t iDevSearch; 81 82 uint32_t Alignment0[2]; 84 /** Number of bridges attached to the bus. */ 85 uint32_t cBridges; 86 87 uint32_t Alignment0; 83 88 84 89 /** Array of PCI devices. */ 85 90 R3PTRTYPE(PPCIDEVICE) devices[256]; 91 /** Array of bridges attached to the bus. */ 92 R3PTRTYPE(PPCIDEVICE) apBridgesR3[256]; /* @todo: Waste of precious hypervisor space. */ 86 93 87 94 /** R3 pointer to the device instance. */ … … 212 219 PDMBOTHCBDECL(void) pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel); 213 220 PDMBOTHCBDECL(void) pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel); 221 222 #ifdef IN_RING3 223 static PPCIDEVICE pciFindBridge(PPCIBUS pBus, uint8_t iBus); 224 #endif 214 225 215 226 __END_DECLS … … 482 493 if (iBus != 0) 483 494 { 484 /** @todo r=bird: Guess you should cache the pci-bridges instead of searching 485 * the full array, that way we don't need to make assumptions about 486 * multi function devices. */ 487 /* 488 * Search for a fitting bridge. Because we don't support multi function devices at the moment 489 * we only search all devices with function 0 to speed things up. 490 * If no bridge is found the write will be ignored. 491 */ 492 for (uint32_t iDev = pGlobals->PciBus.iDevSearch; iDev < RT_ELEMENTS(pGlobals->PciBus.devices); iDev += 8) 493 { 494 /* 495 * Examine secondary and subordinate bus number. 496 * If the target bus is in the range we pass the request on to the bridge. 497 */ 498 PPCIDEVICE pBridgeDevice = pGlobals->PciBus.devices[iDev]; 499 if (!pBridgeDevice) 500 continue; 501 if (!pBridgeDevice->Int.s.fPciToPciBridge) 502 continue; 503 504 if ( iBus >= pBridgeDevice->config[VBOX_PCI_SECONDARY_BUS] 505 && iBus <= pBridgeDevice->config[VBOX_PCI_SUBORDINATE_BUS]) 506 { 507 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite); 508 509 /* Start the journey... */ 510 pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, val, len); 511 } 495 PPCIDEVICE pBridgeDevice = pciFindBridge(&pGlobals->PciBus, iBus); 496 497 if (pBridgeDevice) 498 { 499 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite); 500 501 pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, val, len); 512 502 } 513 503 } … … 537 527 if (iBus != 0) 538 528 { 539 /* 540 * Search for a fitting bridge. Because we don't support multi function devices at the moment 541 * we only search all devices with function 0 to speed things up. 542 * If no bridge is found the read will be ignored. 543 */ 544 for (uint32_t iDev = pGlobals->PciBus.iDevSearch; iDev < RT_ELEMENTS(pGlobals->PciBus.devices); iDev += 8) 545 { 546 /* 547 * Examine secondary and subordinate bus number. 548 * If the target bus is in the range we pass the request on to the bridge. 549 */ 550 PPCIDEVICE pBridgeDevice = pGlobals->PciBus.devices[iDev]; 551 if (!pBridgeDevice) 552 continue; 553 if (!pBridgeDevice->Int.s.fPciToPciBridge) 554 continue; 555 556 if ( iBus >= pBridgeDevice->config[VBOX_PCI_SECONDARY_BUS] 557 && iBus <= pBridgeDevice->config[VBOX_PCI_SUBORDINATE_BUS]) 558 { 559 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead); 560 561 val = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, len); 562 } 529 PPCIDEVICE pBridgeDevice = pciFindBridge(&pGlobals->PciBus, iBus); 530 531 if (pBridgeDevice) 532 { 533 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead); 534 535 val = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, len); 563 536 } 564 537 } … … 754 727 755 728 #ifdef IN_RING3 729 730 /** 731 * Finds a bridge on the bus which contains the destination bus. 732 * 733 * @return Pointer to the device instance data of the bus or 734 * NULL if no bridge was found. 735 * @param pBus Pointer to the bus to search on. 736 * @param iBus Destination bus number. 737 */ 738 static PPCIDEVICE pciFindBridge(PPCIBUS pBus, uint8_t iBus) 739 { 740 /* Search for a fitting bridge. */ 741 for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++) 742 { 743 /* 744 * Examine secondary and subordinate bus number. 745 * If the target bus is in the range we pass the request on to the bridge. 746 */ 747 PPCIDEVICE pBridgeTemp = pBus->apBridgesR3[iBridge]; 748 AssertMsg(pBridgeTemp && pBridgeTemp->Int.s.fPciToPciBridge, 749 ("Device is not a PCI bridge but on the list of PCi bridges\n")); 750 751 if ( iBus >= pBridgeTemp->config[VBOX_PCI_SECONDARY_BUS] 752 && iBus <= pBridgeTemp->config[VBOX_PCI_SUBORDINATE_BUS]) 753 return pBridgeTemp; 754 } 755 756 /* Nothing found. */ 757 return NULL; 758 } 756 759 757 760 static void piix3_reset(PIIX3State *d) … … 1003 1006 /* default memory mappings */ 1004 1007 /* 1005 * PCI_NUM_REGIONS is 7 b cause of the rom region but there are only 6 base address register defined by the PCispec.1008 * PCI_NUM_REGIONS is 7 because of the rom region but there are only 6 base address register defined by the PCI spec. 1006 1009 * Leaving only PCI_NUM_REGIONS would cause reading another and enabling a memory region which does not exist. 1007 1010 */ … … 1397 1400 1398 1401 /* -=-=-=-=-=- real code -=-=-=-=-=- */ 1399 1400 1402 1401 1403 /** … … 1518 1520 pPciDev->Int.s.pfnConfigWrite = pci_default_write_config; 1519 1521 pBus->devices[iDev] = pPciDev; 1522 if (pPciDev->Int.s.fPciToPciBridge) 1523 { 1524 AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus->apBridgesR3), ("Number of bridges exceeds the number of possible bridges on the bus\n")); 1525 AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite, 1526 ("device is a bridge but does not implement read/write functions\n")); 1527 pBus->apBridgesR3[pBus->cBridges] = pPciDev; 1528 pBus->cBridges++; 1529 } 1530 1520 1531 Log(("PCI: Registered device %d function %d (%#x) '%s'.\n", 1521 1532 iDev >> 3, iDev & 7, 0x80000000 | (iDev << 8), pszName)); … … 1930 1941 if (iBus != pBus->PciDev.config[VBOX_PCI_SECONDARY_BUS]) 1931 1942 { 1932 /* 1933 * Search for a fitting bridge. Because we don't support multi function devices at the moment 1934 * we only search all devices with function 0 to speed things up. 1935 * If no bridge is found the write will be ignored. 1936 */ 1937 for (uint32_t iDev = pBus->iDevSearch; iDev < RT_ELEMENTS(pBus->devices); iDev += 8) 1938 { 1939 /* 1940 * Examine secondary and subordinate bus number. 1941 * If the target bus is in the range we pass the request on to the bridge. 1942 */ 1943 PPCIDEVICE pBridgeDevice = pBus->devices[iDev]; 1944 if (!pBridgeDevice) 1945 continue; 1946 if (!pBridgeDevice->Int.s.fPciToPciBridge) 1947 continue; 1948 1949 if ( iBus >= pBridgeDevice->config[VBOX_PCI_SECONDARY_BUS] 1950 && iBus <= pBridgeDevice->config[VBOX_PCI_SUBORDINATE_BUS]) 1951 { 1952 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite); 1953 1954 pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, u32Address, u32Value, cb); 1955 } 1943 PPCIDEVICE pBridgeDevice = pciFindBridge(pBus, iBus); 1944 1945 if (pBridgeDevice) 1946 { 1947 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite); 1948 1949 pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, u32Address, u32Value, cb); 1956 1950 } 1957 1951 } … … 1978 1972 if (iBus != pBus->PciDev.config[VBOX_PCI_SECONDARY_BUS]) 1979 1973 { 1980 /* 1981 * Search for a fitting bridge. Because we don't support multi function devices at the moment 1982 * we only search all devices with function 0 to speed things up. 1983 * If no bridge is found the read will return 0xffffffff. 1984 */ 1985 for (uint32_t iDev = pBus->iDevSearch; iDev < RT_ELEMENTS(pBus->devices); iDev += 8) 1986 { 1987 /* 1988 * Examine secondary and subordinate bus number. 1989 * If the target bus is in the range we pass the request on to the bridge. 1990 */ 1991 PPCIDEVICE pBridgeDevice = pBus->devices[iDev]; 1992 if (!pBridgeDevice) 1993 continue; 1994 if (!pBridgeDevice->Int.s.fPciToPciBridge) 1995 continue; 1996 1997 if ( iBus >= pBridgeDevice->config[VBOX_PCI_SECONDARY_BUS] 1998 && iBus <= pBridgeDevice->config[VBOX_PCI_SUBORDINATE_BUS]) 1999 { 2000 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead); 2001 2002 u32Value = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, u32Address, cb); 2003 } 1974 PPCIDEVICE pBridgeDevice = pciFindBridge(pBus, iBus); 1975 1976 if (pBridgeDevice) 1977 { 1978 AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead); 1979 1980 u32Value = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, u32Address, cb); 2004 1981 } 2005 1982 }
Note:
See TracChangeset
for help on using the changeset viewer.