- Timestamp:
- Nov 26, 2019 11:16:13 AM (5 years ago)
- Location:
- trunk/src/VBox/Devices/Bus
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r82073 r82218 980 980 pPciDev->Int.s.pfnConfigRead = NULL; 981 981 pPciDev->Int.s.pfnConfigWrite = NULL; 982 pPciDev->Int.s.hMmioMsix = NIL_IOMMMIOHANDLE; 982 983 if (pBus->fTypePiix3 && pPciDev->cbConfig > 256) 983 984 pPciDev->cbConfig = 256; -
trunk/src/VBox/Devices/Bus/MsixCommon.cpp
r81035 r82218 24 24 #include <VBox/log.h> 25 25 #include <VBox/vmm/mm.h> 26 #include <VBox/AssertGuest.h> 26 27 27 28 #include <iprt/assert.h> … … 117 118 } 118 119 119 120 PDMBOTHCBDECL(int) msixR3MMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 120 /** 121 * @callback_method_impl{FNIOMMMIONEWREAD} 122 */ 123 static DECLCALLBACK(VBOXSTRICTRC) msixR3MMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb) 121 124 { 122 125 PPDMPCIDEV pPciDev = (PPDMPCIDEV)pvUser; 123 uint32_t off = (uint32_t)(GCPhysAddr & 0xffff);124 LogFlowFunc(("GCPhysAddr=%RGp cb=%d\n", GCPhysAddr, cb));125 126 /// @todo qword accesses?127 126 RT_NOREF(pDevIns); 128 AssertMsgReturn(cb == 4, ("MSI-X must be accessed with 4-byte reads\n"), VERR_INTERNAL_ERROR); 129 AssertMsgReturn(off + cb <= pPciDev->Int.s.cbMsixRegion, ("Out of bounds access for the MSI-X region\n"), VINF_IOM_MMIO_UNUSED_FF); 127 128 /* Validate IOM behaviour. */ 129 Assert(cb == 4); 130 Assert((off & 3) == 0); 131 132 /* Do the read if it's within the MSI state. */ 133 ASSERT_GUEST_MSG_RETURN(off + cb <= pPciDev->Int.s.cbMsixRegion, ("Out of bounds access for the MSI-X region\n"), 134 VINF_IOM_MMIO_UNUSED_FF); 130 135 *(uint32_t *)pv = *(uint32_t *)&pPciDev->abMsixState[off]; 131 136 137 LogFlowFunc(("off=%RGp cb=%d -> %#010RX32\n", off, cb, *(uint32_t *)pv)); 132 138 return VINF_SUCCESS; 133 139 } 134 140 135 PDMBOTHCBDECL(int) msixR3MMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 141 /** 142 * @callback_method_impl{FNIOMMMIONEWWRITE} 143 */ 144 static DECLCALLBACK(VBOXSTRICTRC) msixR3MMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb) 136 145 { 137 146 PPDMPCIDEV pPciDev = (PPDMPCIDEV)pvUser; 138 uint32_t off = (uint32_t)(GCPhysAddr & 0xffff); 139 LogFlowFunc(("GCPhysAddr=%RGp cb=%d\n", GCPhysAddr, cb)); 140 141 /// @todo qword accesses? 142 AssertMsgReturn(cb == 4, ("MSI-X must be accessed with 4-byte reads\n"), VERR_INTERNAL_ERROR); 143 AssertMsgReturn(off + cb <= pPciDev->Int.s.offMsixPba, ("Trying to write to PBA\n"), VINF_SUCCESS); 147 LogFlowFunc(("off=%RGp cb=%d %#010RX32\n", off, cb, *(uint32_t *)pv)); 148 149 /* Validate IOM behaviour. */ 150 Assert(cb == 4); 151 Assert((off & 3) == 0); 152 153 /* Do the write if it's within the MSI state. */ 154 ASSERT_GUEST_MSG_RETURN(off + cb <= pPciDev->Int.s.offMsixPba, ("Trying to write to PBA\n"), 155 VINF_SUCCESS); 144 156 *(uint32_t *)&pPciDev->abMsixState[off] = *(uint32_t *)pv; 145 157 … … 147 159 msixR3CheckPendingVector(pDevIns, (PCPDMPCIHLP)pPciDev->Int.s.pvPciBusPtrR3, pPciDev, off / VBOX_MSIX_ENTRY_SIZE); 148 160 return VINF_SUCCESS; 149 }150 151 /**152 * @callback_method_impl{FNPCIIOREGIONMAP}153 */154 static DECLCALLBACK(int) msixR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,155 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)156 {157 Assert(enmType == PCI_ADDRESS_SPACE_MEM);158 NOREF(iRegion); NOREF(enmType);159 160 return PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, pPciDev,161 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,162 msixR3MMIOWrite, msixR3MMIORead, "MSI-X tables");163 161 } 164 162 … … 179 177 uint8_t iBar = pMsiReg->iMsixBar; 180 178 181 AssertMsgReturn(cVectors <= VBOX_MSIX_MAX_ENTRIES, 182 ("Too many MSI-X vectors: %d\n", cVectors), 183 VERR_TOO_MUCH_DATA); 184 AssertMsgReturn(iBar <= 5, 185 ("Using wrong BAR for MSI-X: %d\n", iBar), 186 VERR_INVALID_PARAMETER); 187 179 AssertMsgReturn(cVectors <= VBOX_MSIX_MAX_ENTRIES, ("Too many MSI-X vectors: %d\n", cVectors), VERR_TOO_MUCH_DATA); 180 AssertMsgReturn(iBar <= 5, ("Using wrong BAR for MSI-X: %d\n", iBar), VERR_INVALID_PARAMETER); 188 181 Assert(iCapOffset != 0 && iCapOffset < 0xff && iNextOffset < 0xff); 189 182 190 int rc = VINF_SUCCESS;191 183 uint16_t cbPba = cVectors / 8; 192 184 if (cVectors % 8) … … 200 192 if (!pciDevIsPassthrough(pDev)) 201 193 { 202 rc = PDMDevHlpPCIIORegionRegister(pDev->Int.s.CTX_SUFF(pDevIns), iBar, cbMsixRegion, PCI_ADDRESS_SPACE_MEM, msixR3Map); 203 if (RT_FAILURE (rc)) 204 return rc; 194 /** @todo r=bird: This used to be IOMMMIO_FLAGS_READ_PASSTHRU | 195 * IOMMMIO_FLAGS_WRITE_PASSTHRU with the callbacks asserting and 196 * returning VERR_INTERNAL_ERROR on non-dword reads. That is of 197 * course certifiable insane behaviour. So, instead I've changed it 198 * so the callbacks only see dword reads and writes. I'm not at all 199 * sure about the read-missing behaviour, but it seems like a good 200 * idea for now. */ 201 int rc = PDMDevHlpPCIIORegionCreateMmio(pDev->Int.s.CTX_SUFF(pDevIns), iBar, cbMsixRegion, PCI_ADDRESS_SPACE_MEM, 202 msixR3MMIOWrite, msixR3MMIORead, pDev, 203 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING, 204 "MSI-X tables", &pDev->Int.s.hMmioMsix); 205 AssertRCReturn(rc, rc); 205 206 } 206 207
Note:
See TracChangeset
for help on using the changeset viewer.