Changeset 68423 in vbox
- Timestamp:
- Aug 15, 2017 11:28:57 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
include/VBox/vmm/pdmpcidevint.h (modified) (2 diffs)
-
src/VBox/Devices/Bus/DevPciIch9.cpp (modified) (1 diff)
-
src/VBox/Devices/Bus/MsixCommon.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmpcidevint.h
r66645 r68423 203 203 * @todo fix non-standard naming. */ 204 204 uint8_t u8MsixCapSize; 205 #if HC_ARCH_BITS == 64 206 /** Explicit alignment padding. */207 uint8_t abPadding1[HC_ARCH_BITS == 32 ? 0 : 4];208 #endif 205 /** Size of the MSI-X region. */ 206 uint16_t cbMsixRegion; 207 /** Offset to the PBA for MSI-X. */ 208 uint16_t offMsixPba; 209 209 210 210 /** Pointer to bus specific data. (R3 ptr) */ … … 216 216 } PDMPCIDEVINT; 217 217 AssertCompileMemberAlignment(PDMPCIDEVINT, aIORegions, 8); 218 AssertCompileSize(PDMPCIDEVINT, HC_ARCH_BITS == 32 ? 26 4: 384);218 AssertCompileSize(PDMPCIDEVINT, HC_ARCH_BITS == 32 ? 268 : 384); 219 219 220 220 /** Indicate that PDMPCIDEV::Int.s can be declared. */ -
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r68090 r68423 1440 1440 { 1441 1441 Assert(pDev->Int.s.pMsixPageR3 != NULL); 1442 memcpy(pDev->Int.s.pMsixPageR3, pvMsixPage, 0x1000); 1442 Assert(pDev->Int.s.cbMsixRegion != 0); 1443 memcpy(pDev->Int.s.pMsixPageR3, pvMsixPage, pDev->Int.s.cbMsixRegion); 1443 1444 } 1444 1445 } -
trunk/src/VBox/Devices/Bus/MsixCommon.cpp
r64454 r68423 5 5 6 6 /* 7 * Copyright (C) 2010-201 6Oracle Corporation7 * Copyright (C) 2010-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 88 88 DECLINLINE(uint8_t*) msixPendingByte(PPDMPCIDEV pDev, uint32_t iVector) 89 89 { 90 return msixGetPageOffset(pDev, 0x800+ iVector / 8);90 return msixGetPageOffset(pDev, pDev->Int.s.offMsixPba + iVector / 8); 91 91 } 92 92 … … 116 116 PDMBOTHCBDECL(int) msixMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 117 117 { 118 LogFlowFunc(("\n")); 119 120 uint32_t off = (uint32_t)(GCPhysAddr & 0xffff); 121 PPDMPCIDEV pPciDev = (PPDMPCIDEV)pvUser; 122 118 123 /// @todo qword accesses? 119 NOREF(pDevIns);124 RT_NOREF(pDevIns); 120 125 AssertMsgReturn(cb == 4, 121 126 ("MSI-X must be accessed with 4-byte reads"), 122 127 VERR_INTERNAL_ERROR); 123 124 uint32_t off = (uint32_t)(GCPhysAddr & 0xfff); 128 AssertMsgReturn(off < pPciDev->Int.s.cbMsixRegion, 129 ("Out of bounds access for the MSI-X region\n"), 130 VINF_IOM_MMIO_UNUSED_FF); 131 132 *(uint32_t*)pv = *(uint32_t*)msixGetPageOffset(pPciDev, off); 133 return VINF_SUCCESS; 134 } 135 136 PDMBOTHCBDECL(int) msixMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 137 { 138 LogFlowFunc(("\n")); 139 125 140 PPDMPCIDEV pPciDev = (PPDMPCIDEV)pvUser; 126 127 *(uint32_t*)pv = *(uint32_t*)msixGetPageOffset(pPciDev, off); 128 129 return VINF_SUCCESS; 130 } 131 132 PDMBOTHCBDECL(int) msixMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 133 { 141 uint32_t off = (uint32_t)(GCPhysAddr & 0xffff); 142 134 143 /// @todo qword accesses? 135 144 AssertMsgReturn(cb == 4, 136 145 ("MSI-X must be accessed with 4-byte reads"), 137 146 VERR_INTERNAL_ERROR); 138 PPDMPCIDEV pPciDev = (PPDMPCIDEV)pvUser; 139 140 uint32_t off = (uint32_t)(GCPhysAddr & 0xfff); 141 142 AssertMsgReturn(off < 0x800, ("Trying to write to PBA\n"), VINF_SUCCESS); 147 AssertMsgReturn(off < pPciDev->Int.s.offMsixPba, 148 ("Trying to write to PBA\n"), 149 VINF_IOM_MMIO_UNUSED_FF); 143 150 144 151 *(uint32_t*)msixGetPageOffset(pPciDev, off) = *(uint32_t*)pv; 145 152 146 153 msixCheckPendingVector(pDevIns, (PCPDMPCIHLP)pPciDev->Int.s.pPciBusPtrR3, pPciDev, off / VBOX_MSIX_ENTRY_SIZE); 147 148 154 return VINF_SUCCESS; 149 155 } … … 181 187 uint8_t iBar = pMsiReg->iMsixBar; 182 188 183 if (cVectors > VBOX_MSIX_MAX_ENTRIES) 184 { 185 AssertMsgFailed(("Too many MSI-X vectors: %d\n", cVectors)); 186 return VERR_TOO_MUCH_DATA; 187 } 188 189 if (iBar > 5) 190 { 191 AssertMsgFailed(("Using wrong BAR for MSI-X: %d\n", iBar)); 192 return VERR_INVALID_PARAMETER; 193 } 189 AssertMsgReturn(cVectors <= VBOX_MSIX_MAX_ENTRIES, 190 ("Too many MSI-X vectors: %d\n", cVectors), 191 VERR_TOO_MUCH_DATA); 192 AssertMsgReturn(iBar <= 5, 193 ("Using wrong BAR for MSI-X: %d\n", iBar), 194 VERR_INVALID_PARAMETER); 194 195 195 196 Assert(iCapOffset != 0 && iCapOffset < 0xff && iNextOffset < 0xff); 196 197 197 198 int rc = VINF_SUCCESS; 199 uint16_t cbPba = cVectors / 8; 200 if (cVectors % 8) 201 cbPba++; 202 uint16_t cbMsixRegion = RT_ALIGN_T(cVectors * sizeof(MsixTableRecord) + cbPba, _4K, uint16_t); 198 203 199 204 /* If device is passthrough, BAR is registered using common mechanism. */ 200 205 if (!pciDevIsPassthrough(pDev)) 201 206 { 202 rc = PDMDevHlpPCIIORegionRegister(pDev->Int.s.CTX_SUFF(pDevIns), iBar, 0x1000, PCI_ADDRESS_SPACE_MEM, msixMap);207 rc = PDMDevHlpPCIIORegionRegister(pDev->Int.s.CTX_SUFF(pDevIns), iBar, cbMsixRegion, PCI_ADDRESS_SPACE_MEM, msixMap); 203 208 if (RT_FAILURE (rc)) 204 209 return rc; 205 210 } 206 211 212 uint16_t offTable = 0; 213 uint16_t offPBA = cVectors * sizeof(MsixTableRecord); 214 207 215 pDev->Int.s.u8MsixCapOffset = iCapOffset; 208 216 pDev->Int.s.u8MsixCapSize = VBOX_MSIX_CAP_SIZE; 217 pDev->Int.s.cbMsixRegion = cbMsixRegion; 218 pDev->Int.s.offMsixPba = offPBA; 209 219 PVM pVM = PDMDevHlpGetVM(pDev->Int.s.CTX_SUFF(pDevIns)); 210 220 211 221 pDev->Int.s.pMsixPageR3 = NULL; 212 222 213 rc = MMHyperAlloc(pVM, 0x1000, 1, MM_TAG_PDM_DEVICE_USER, (void **)&pDev->Int.s.pMsixPageR3);223 rc = MMHyperAlloc(pVM, cbMsixRegion, 1, MM_TAG_PDM_DEVICE_USER, (void **)&pDev->Int.s.pMsixPageR3); 214 224 if (RT_FAILURE(rc) || (pDev->Int.s.pMsixPageR3 == NULL)) 215 225 return VERR_NO_VM_MEMORY; 216 RT_BZERO(pDev->Int.s.pMsixPageR3, 0x1000);226 RT_BZERO(pDev->Int.s.pMsixPageR3, cbMsixRegion); 217 227 pDev->Int.s.pMsixPageR0 = MMHyperR3ToR0(pVM, pDev->Int.s.pMsixPageR3); 218 228 pDev->Int.s.pMsixPageRC = MMHyperR3ToRC(pVM, pDev->Int.s.pMsixPageR3); … … 224 234 PCIDevSetByte(pDev, iCapOffset + 1, iNextOffset); /* next */ 225 235 PCIDevSetWord(pDev, iCapOffset + VBOX_MSIX_CAP_MESSAGE_CONTROL, cVectors - 1); 226 227 uint32_t offTable = 0, offPBA = 0x800;228 236 229 237 PCIDevSetDWord(pDev, iCapOffset + VBOX_MSIX_TABLE_BIROFFSET, offTable | iBar);
Note:
See TracChangeset
for help on using the changeset viewer.

