Changeset 33236 in vbox for trunk/src/VBox/Devices/Bus
- Timestamp:
- Oct 19, 2010 3:14:42 PM (14 years ago)
- Location:
- trunk/src/VBox/Devices/Bus
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r33215 r33236 530 530 PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns); 531 531 MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel); 532 } 533 534 if (MsixIsEnabled(pPciDev)) 535 { 536 Log2(("MSI-X interrupt: %d level=%d\n", iIrq, iLevel)); 537 PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns); 538 MsixNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel); 532 539 } 533 540 return; … … 774 781 static DECLCALLBACK(int) ich9pciRegisterMsi(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg) 775 782 { 776 return MsiInit(pPciDev, pMsiReg); 783 int rc; 784 785 rc = MsiInit(pPciDev, pMsiReg); 786 if (rc != VINF_SUCCESS) 787 return rc; 788 789 rc = MsixInit(pPciDev, pMsiReg); 790 if (rc != VINF_SUCCESS) 791 return rc; 792 793 return rc; 777 794 } 778 795 … … 1675 1692 } 1676 1693 1694 if ( PCIIsMsixCapable(aDev) 1695 && (u32Address >= aDev->Int.s.u8MsixCapOffset) 1696 && (u32Address < aDev->Int.s.u8MsixCapOffset + aDev->Int.s.u8MsixCapSize) 1697 ) 1698 { 1699 return MsixPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len); 1700 } 1701 1677 1702 AssertMsgReturn(u32Address + len <= 256, ("Read after end of PCI config space\n"), 1678 1703 0); … … 1716 1741 aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp), 1717 1742 aDev, u32Address, val, len); 1743 return; 1744 } 1745 1746 if ( PCIIsMsixCapable(aDev) 1747 && (u32Address >= aDev->Int.s.u8MsixCapOffset) 1748 && (u32Address < aDev->Int.s.u8MsixCapOffset + aDev->Int.s.u8MsixCapSize) 1749 ) 1750 { 1751 MsixPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), 1752 aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp), 1753 aDev, u32Address, val, len); 1718 1754 return; 1719 1755 } … … 1896 1932 }; 1897 1933 1898 static int assignPosition(PPCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName, int iDevFn) 1899 { 1934 static bool assignPosition(PPCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName, int iDevFn, PciAddress* aPosition) 1935 { 1936 aPosition->iBus = 0; 1937 aPosition->iDeviceFunc = iDevFn; 1938 aPosition->iRegister = 0; /* N/A */ 1939 1900 1940 /* Hardcoded slots/functions, per chipset spec */ 1901 1941 for (size_t i = 0; i < RT_ELEMENTS(PciSlotAssignments); i++) … … 1904 1944 { 1905 1945 PCISetRequestedDevfunc(pPciDev); 1906 return (PciSlotAssignments[i].iSlot << 3) + PciSlotAssignments[i].iFunction; 1907 } 1908 } 1909 1946 aPosition->iDeviceFunc = 1947 (PciSlotAssignments[i].iSlot << 3) + PciSlotAssignments[i].iFunction; 1948 return true; 1949 } 1950 } 1951 1952 /* Explicit slot request */ 1910 1953 if (iDevFn >=0 && iDevFn < (int)RT_ELEMENTS(pBus->apDevices)) 1911 return iDevFn;1954 return true; 1912 1955 1913 1956 /* Otherwise when assigning a slot, we need to make sure all its functions are available */ … … 1924 1967 { 1925 1968 PCIClearRequestedDevfunc(pPciDev); 1926 return iPos; 1927 } 1928 } 1929 1930 return -1; 1969 aPosition->iDeviceFunc = iPos; 1970 return true; 1971 } 1972 } 1973 1974 return false; 1931 1975 } 1932 1976 … … 1948 1992 static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName) 1949 1993 { 1994 PciAddress aPosition = {0, 0, 0}; 1995 1950 1996 /* 1951 1997 * Find device position 1952 1998 */ 1953 iDev = assignPosition(pBus, pPciDev, pszName, iDev); 1954 if (iDev < 0) 1955 { 1956 AssertMsgFailed(("Couldn't find free spot!\n")); 1999 if (!assignPosition(pBus, pPciDev, pszName, iDev, &aPosition)) 2000 { 2001 AssertMsgFailed(("Couldn't asssign position!\n")); 1957 2002 return VERR_PDM_TOO_PCI_MANY_DEVICES; 1958 2003 } 1959 2004 2005 AssertMsgReturn(aPosition.iBus == 0, 2006 ("Assigning behind the bridge not implemented yet\n"), 2007 VERR_PDM_TOO_PCI_MANY_DEVICES); 2008 2009 2010 iDev = aPosition.iDeviceFunc; 1960 2011 /* 1961 2012 * Check if we can really take this slot, possibly by relocating … … 1974 2025 { 1975 2026 /* if we got here, we shall (and usually can) relocate the device */ 1976 int iRelDev = assignPosition(pBus, pBus->apDevices[iDev], pBus->apDevices[iDev]->name, -1); 1977 if (iRelDev < 0 || iRelDev == iDev) 2027 bool assigned = assignPosition(pBus, pBus->apDevices[iDev], pBus->apDevices[iDev]->name, -1, &aPosition); 2028 AssertMsgReturn(aPosition.iBus == 0, 2029 ("Assigning behind the bridge not implemented yet\n"), 2030 VERR_PDM_TOO_PCI_MANY_DEVICES); 2031 int iRelDev = aPosition.iDeviceFunc; 2032 if (!assigned || iRelDev == iDev) 1978 2033 { 1979 2034 AssertMsgFailed(("Couldn't find free spot!\n")); -
trunk/src/VBox/Devices/Bus/MsiCommon.cpp
r33215 r33236 84 84 } 85 85 86 DECLINLINE(bool) msiBitJustCleared(uint32_t u 32OldValue,87 uint32_t u 32NewValue,88 uint32_t u 32Mask)89 { 90 return (!!(u 32OldValue & u32Mask) && !(u32NewValue & u32Mask));91 } 92 93 DECLINLINE(bool) msiBitJustSet(uint32_t u 64OldValue,94 uint32_t u 64NewValue,95 uint32_t u 64Mask)96 { 97 return (!(u 64OldValue & u64Mask) && !!(u64NewValue & u64Mask));86 DECLINLINE(bool) msiBitJustCleared(uint32_t uOldValue, 87 uint32_t uNewValue, 88 uint32_t uMask) 89 { 90 return (!!(uOldValue & uMask) && !(uNewValue & uMask)); 91 } 92 93 DECLINLINE(bool) msiBitJustSet(uint32_t uOldValue, 94 uint32_t uNewValue, 95 uint32_t uMask) 96 { 97 return (!(uOldValue & uMask) && !!(uNewValue & uMask)); 98 98 } 99 99 … … 104 104 Assert(iOff >= 0 && (PCIIsMsiCapable(pDev) && iOff < pDev->Int.s.u8MsiCapSize)); 105 105 106 Log2(("M SIPciConfigWrite: %d <- %x (%d)\n", iOff, val, len));106 Log2(("MsiPciConfigWrite: %d <- %x (%d)\n", iOff, val, len)); 107 107 108 108 uint32_t uAddr = u32Address; … … 112 112 { 113 113 uint32_t reg = i + iOff; 114 uint8_t u8Val = (uint8_t)val; 114 115 switch (reg) 115 116 { … … 119 120 case VBOX_MSI_CAP_MESSAGE_CONTROL: 120 121 /* don't change read-only bits: 1-3,7 */ 121 val &= UINT32_C(~0x8e);122 pDev->config[uAddr] = val;122 u8Val &= UINT8_C(~0x8e); 123 pDev->config[uAddr] = u8Val | (pDev->config[uAddr] & UINT8_C(0x8e)); 123 124 break; 124 125 case VBOX_MSI_CAP_MESSAGE_CONTROL + 1: … … 126 127 break; 127 128 default: 128 if (pDev->config[uAddr] != val)129 if (pDev->config[uAddr] != u8Val) 129 130 { 130 131 int32_t maskUpdated = -1; … … 155 156 uint32_t uVector = maskUpdated*8 + iBitNum; 156 157 157 if (msiBitJustCleared(pDev->config[uAddr], val, iBit))158 if (msiBitJustCleared(pDev->config[uAddr], u8Val, iBit)) 158 159 { 159 160 Log(("msi: mask updated bit %d@%x (%d)\n", iBitNum, uAddr, maskUpdated)); … … 167 168 } 168 169 } 169 if (msiBitJustSet(pDev->config[uAddr], val, iBit))170 if (msiBitJustSet(pDev->config[uAddr], u8Val, iBit)) 170 171 { 171 172 Log(("msi: mask vector: %d\n", uVector)); … … 174 175 } 175 176 176 pDev->config[uAddr] = val;177 pDev->config[uAddr] = u8Val; 177 178 } 178 179 } … … 204 205 } 205 206 206 Log2(("M SIPciConfigRead: %d (%d) -> %x\n", iOff, len, rv));207 Log2(("MsiPciConfigRead: %d (%d) -> %x\n", iOff, len, rv)); 207 208 208 209 return rv; … … 212 213 int MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg) 213 214 { 214 uint16_t cVectors = pMsiReg->cVectors; 215 uint8_t iCapOffset = pMsiReg->iCapOffset; 216 uint8_t iNextOffset = pMsiReg->iNextOffset; 217 uint16_t iMsiFlags = pMsiReg->iMsiFlags; 218 219 Assert(cVectors > 0); 215 if (pMsiReg->cMsiVectors == 0) 216 return VINF_SUCCESS; 217 218 uint16_t cVectors = pMsiReg->cMsiVectors; 219 uint8_t iCapOffset = pMsiReg->iMsiCapOffset; 220 uint8_t iNextOffset = pMsiReg->iMsiNextOffset; 221 uint16_t iFlags = pMsiReg->iMsiFlags; 220 222 221 223 if (cVectors != 1) … … 228 230 Assert(iCapOffset != 0 && iCapOffset < 0xff && iNextOffset < 0xff); 229 231 230 bool f64bit = (i MsiFlags & VBOX_PCI_MSI_FLAGS_64BIT) != 0;232 bool f64bit = (iFlags & VBOX_PCI_MSI_FLAGS_64BIT) != 0; 231 233 /* We always support per-vector masking */ 232 i MsiFlags |= VBOX_PCI_MSI_FLAGS_MASKBIT;234 iFlags |= VBOX_PCI_MSI_FLAGS_MASKBIT; 233 235 234 236 pDev->Int.s.u8MsiCapOffset = iCapOffset; … … 237 239 PCIDevSetByte(pDev, iCapOffset + 0, VBOX_PCI_CAP_ID_MSI); 238 240 PCIDevSetByte(pDev, iCapOffset + 1, iNextOffset); /* next */ 239 PCIDevSetWord(pDev, iCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL, i MsiFlags);241 PCIDevSetWord(pDev, iCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL, iFlags); 240 242 241 243 *msiGetMaskBits(pDev) = 0; -
trunk/src/VBox/Devices/Bus/MsiCommon.h
r33215 r33236 1 1 /* $Id$ */ 2 2 /** @file 3 * Header for MSI support routines.3 * Header for MSI/MSI-X support routines. 4 4 */ 5 5 /* … … 40 40 void MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len); 41 41 uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len); 42 43 44 /* Init MSI-X support in the device. */ 45 int MsixInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg); 46 47 /* If MSI-X is enabled, so that MSIXNotify() shall be used for notifications. */ 48 bool MsixIsEnabled(PPCIDEVICE pDev); 49 50 /* Device notification (aka interrupt). */ 51 void MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel); 52 53 /* PCI config space accessors for MSI-X */ 54 void MsixPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len); 55 uint32_t MsixPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
Note:
See TracChangeset
for help on using the changeset viewer.