Changeset 83959 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Apr 24, 2020 8:49:48 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 137523
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r83945 r83959 78 78 79 79 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST 0x100 80 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_1 0x100 81 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_2 0x108 82 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_3 0x110 83 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_4 0x118 84 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_5 0x120 85 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_6 0x128 86 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_7 0x130 80 87 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_LAST 0x130 81 88 … … 372 379 /** @name Miscellaneous IOMMU defines. 373 380 * @{ */ 374 #define IOMMU_LOG_PFX "AMD_IOMMU" /**< Log prefix string. */ 375 #define IOMMU_SAVED_STATE_VERSION 1 /**< The current saved state version. */ 376 #define IOMMU_PCI_VENDOR_ID 0x1022 /**< AMD's vendor ID. */ 377 #define IOMMU_PCI_DEVICE_ID 0xc0de /**< VirtualBox IOMMU device ID. */ 378 #define IOMMU_PCI_REVISION_ID 0x01 /**< VirtualBox IOMMU device revision ID. */ 379 #define IOMMU_MMIO_REGION_SIZE _16K /**< Size of the MMIO region in bytes. */ 381 /** Log prefix string. */ 382 #define IOMMU_LOG_PFX "AMD_IOMMU" 383 /** The current saved state version. */ 384 #define IOMMU_SAVED_STATE_VERSION 1 385 /** AMD's vendor ID. */ 386 #define IOMMU_PCI_VENDOR_ID 0x1022 387 /** VirtualBox IOMMU device ID. */ 388 #define IOMMU_PCI_DEVICE_ID 0xc0de 389 /** VirtualBox IOMMU device revision ID. */ 390 #define IOMMU_PCI_REVISION_ID 0x01 391 /** Size of the MMIO region in bytes. */ 392 #define IOMMU_MMIO_REGION_SIZE _16K 393 /** Number of device table segments supported (power of 2). */ 394 #define IOMMU_MAX_DEV_TAB_SEGMENTS 3 380 395 /** @} */ 381 396 … … 1057 1072 } DEV_TAB_BAR_T; 1058 1073 AssertCompileSize(DEV_TAB_BAR_T, 8); 1059 #define IOMMU_DEV_TAB_BAR_VALID_MASK UINT64_C(0x000ffffffffff 3ff)1074 #define IOMMU_DEV_TAB_BAR_VALID_MASK UINT64_C(0x000ffffffffff1ff) 1060 1075 1061 1076 /** … … 1376 1391 } DEV_TAB_SEG_BAR_T; 1377 1392 AssertCompileSize(DEV_TAB_SEG_BAR_T, 8); 1393 #define IOMMU_DEV_TAB_SEG_BAR_VALID_MASK UINT64_C(0x000ffffffffff0ff) 1378 1394 1379 1395 /** … … 2085 2101 2086 2102 2103 /********************************************************************************************************************************* 2104 * Global Variables * 2105 *********************************************************************************************************************************/ 2106 /** 2107 * An array of the number of device table segments supported. 2108 * Indexed by u2DevTabSegSup. 2109 */ 2110 static uint8_t const g_aDevTabSegments[] = { 0, 2, 4, 8 }; 2111 2112 /** 2113 * The maximum size (inclusive) of each device table segment (0 to 7). 2114 * Indexed by the device table segment index. 2115 */ 2116 static uint16_t const g_aDevTabSegmentSizes[] = { 0x1ff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x3f, 0x3f }; 2117 2118 2087 2119 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 2088 2120 … … 2299 2331 RT_NOREF(pDevIns, iReg); 2300 2332 2301 /* Ignoreall unrecognized bits. */2333 /* Mask out all unrecognized bits. */ 2302 2334 u64Value &= IOMMU_HW_EVT_STATUS_VALID_MASK; 2303 2335 … … 2320 2352 2321 2353 /** 2354 * Writes the Device Table Segment Base Address Register. 2355 */ 2356 static VBOXSTRICTRC iommuAmdDevTabSegBar_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value) 2357 { 2358 RT_NOREF(pDevIns); 2359 2360 /* Figure out which segment is being written. */ 2361 uint8_t const idxDevTabSeg = (iReg - IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST) >> 3; 2362 Assert(idxDevTabSeg < RT_ELEMENTS(pThis->DevTabSeg)); 2363 2364 /* Mask out all unrecognized bits. */ 2365 u64Value &= IOMMU_DEV_TAB_SEG_BAR_VALID_MASK; 2366 uint8_t const cbSegSize = u64Value & UINT64_C(0xff); 2367 2368 /* Validate the size and write the register. */ 2369 uint8_t const idxSegment = idxDevTabSeg + 1; 2370 uint16_t const cbMaxSegSize = g_aDevTabSegmentSizes[idxSegment]; 2371 if (cbSegSize <= cbMaxSegSize) 2372 pThis->DevTabSeg[idxDevTabSeg].u64 = u64Value; 2373 else 2374 Log((IOMMU_LOG_PFX ": Setting device table segment %u with invalid size (%#RX32) -> Ignored\n", idxSegment, cbSegSize)); 2375 2376 return VINF_SUCCESS; 2377 } 2378 2379 2380 /** 2322 2381 * Writes the MSI Address (Lo) Register (32-bit). 2323 2382 */ … … 2527 2586 case IOMMU_MMIO_OFF_PPR_EVT_B_BAR: return iommuAmdIgnore_w(pDevIns, pThis, off, uValue); 2528 2587 2529 case IOMMU_MMIO_OFF_DEV_TAB_SEG_ FIRST:2530 case IOMMU_MMIO_OFF_DEV_TAB_SEG_ LAST:2531 {2532 uint8_t const idxDevTabSeg = (off - IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST) >> 3;2533 Assert(idxDevTabSeg < RT_ELEMENTS(pThis->DevTabSeg));2534 return iommuAmdIgnore_w(pDevIns, pThis, off, uValue);2535 }2588 case IOMMU_MMIO_OFF_DEV_TAB_SEG_1: 2589 case IOMMU_MMIO_OFF_DEV_TAB_SEG_2: 2590 case IOMMU_MMIO_OFF_DEV_TAB_SEG_3: 2591 case IOMMU_MMIO_OFF_DEV_TAB_SEG_4: 2592 case IOMMU_MMIO_OFF_DEV_TAB_SEG_5: 2593 case IOMMU_MMIO_OFF_DEV_TAB_SEG_6: 2594 case IOMMU_MMIO_OFF_DEV_TAB_SEG_7: return iommuAmdDevTabSegBar_w(pDevIns, pThis, off, uValue); 2536 2595 2537 2596 case IOMMU_MMIO_OFF_DEV_SPECIFIC_FEAT: … … 2789 2848 *puResult = uReg; 2790 2849 return VINF_SUCCESS; 2850 } 2851 2852 2853 /** 2854 * Reads a device table segment (0-7) from guest memory. 2855 * 2856 * @returns VBox status code. 2857 * @param pDevIns The IOMMU device instance. 2858 * @param idxSeg The device table segment index. 2859 * @param pvBuf Where to store the device table segment. 2860 * @param cbBuf The size of the buffer in bytes. 2861 */ 2862 static int iommuAmdReadDeviceTableSegment(PPDMDEVINS pDevIns, uint8_t idxSeg, void *pvBuf, uint32_t cbBuf) 2863 { 2864 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 2865 Assert(pThis); 2866 2867 /* Validate. */ 2868 Assert(pvBuf); 2869 Assert(cbBuf <= _2M); 2870 Assert(!idxSeg || pThis->ExtFeat.n.u2DevTabSegSup); 2871 Assert(!idxSeg || idxSeg < g_aDevTabSegments[pThis->ExtFeat.n.u2DevTabSegSup]); 2872 2873 /* Get the base address and size of the segment. */ 2874 RTGCPHYS GCPhysDevTab; 2875 uint32_t cbDevTab; 2876 if (!idxSeg) 2877 { 2878 GCPhysDevTab = pThis->DevTabBaseAddr.n.u40DevTabBase; 2879 cbDevTab = pThis->DevTabBaseAddr.n.u9Size; 2880 } 2881 else 2882 { 2883 GCPhysDevTab = pThis->DevTabSeg[idxSeg].n.u40DevTabBase; 2884 cbDevTab = pThis->DevTabSeg[idxSeg].n.u8Size; 2885 } 2886 2887 /* Validate that the destination buffer is large enough to hold the segment. */ 2888 Assert(cbBuf >= cbDevTab); 2889 2890 /* Copy the device table to the buffer. */ 2891 int rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhysDevTab, pvBuf, cbDevTab); 2892 if (RT_FAILURE(rc)) 2893 { 2894 Log((IOMMU_LOG_PFX ": iommuAmdFetchDeviceTable: Failed to read device table segment. idxSeg=%u GCPhys=%#RGp rc=%Rrc", 2895 idxSeg, GCPhysDevTab, rc)); 2896 } 2897 2898 return rc; 2791 2899 } 2792 2900 … … 3090 3198 if (fVerbose) 3091 3199 { 3092 pHlp->pfnPrintf(pHlp, " PPR support = %RTbool\n", ExtFeat.n.u1PprSup); 3093 pHlp->pfnPrintf(pHlp, " x2APIC support = %RTbool\n", ExtFeat.n.u1X2ApicSup); 3094 pHlp->pfnPrintf(pHlp, " NX and privilege level support = %RTbool\n", ExtFeat.n.u1NoExecuteSup); 3095 pHlp->pfnPrintf(pHlp, " Guest translation support = %RTbool\n", ExtFeat.n.u1GstTranslateSup); 3096 pHlp->pfnPrintf(pHlp, " Invalidate-All command support = %RTbool\n", ExtFeat.n.u1InvAllSup); 3097 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC support = %RTbool\n", ExtFeat.n.u1GstVirtApicSup); 3098 pHlp->pfnPrintf(pHlp, " Hardware error register support = %RTbool\n", ExtFeat.n.u1HwErrorSup); 3099 pHlp->pfnPrintf(pHlp, " Performance counters support = %RTbool\n", ExtFeat.n.u1PerfCounterSup); 3100 pHlp->pfnPrintf(pHlp, " Host address translation size = %#x\n", ExtFeat.n.u2HostAddrTranslateSize); 3101 pHlp->pfnPrintf(pHlp, " Guest address translation size = %#x\n", ExtFeat.n.u2GstAddrTranslateSize); 3102 pHlp->pfnPrintf(pHlp, " Guest CR3 root table level support = %#x\n", ExtFeat.n.u2GstCr3RootTblLevel); 3103 pHlp->pfnPrintf(pHlp, " SMI filter register support = %#x\n", ExtFeat.n.u2SmiFilterSup); 3104 pHlp->pfnPrintf(pHlp, " SMI filter register count = %#x\n", ExtFeat.n.u3SmiFilterCount); 3105 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC modes support = %#x\n", ExtFeat.n.u3GstVirtApicModeSup); 3106 pHlp->pfnPrintf(pHlp, " Dual PPR log support = %#x\n", ExtFeat.n.u2DualPprLogSup); 3107 pHlp->pfnPrintf(pHlp, " Dual event log support = %#x\n", ExtFeat.n.u2DualEvtLogSup); 3108 pHlp->pfnPrintf(pHlp, " Maximum PASID = %#x\n", ExtFeat.n.u5MaxPasidSup); 3109 pHlp->pfnPrintf(pHlp, " User/supervisor page protection support = %RTbool\n", ExtFeat.n.u1UserSupervisorSup); 3110 pHlp->pfnPrintf(pHlp, " Device table segments supported = %u\n", (ExtFeat.n.u2DevTabSegSup << 1)); 3111 pHlp->pfnPrintf(pHlp, " PPR log overflow early warning support = %RTbool\n", ExtFeat.n.u1PprLogOverflowWarn); 3112 pHlp->pfnPrintf(pHlp, " PPR auto response support = %RTbool\n", ExtFeat.n.u1PprAutoRespSup); 3113 pHlp->pfnPrintf(pHlp, " MARC support = %#x\n", ExtFeat.n.u2MarcSup); 3114 pHlp->pfnPrintf(pHlp, " Block StopMark message support = %RTbool\n", ExtFeat.n.u1BlockStopMarkSup); 3115 pHlp->pfnPrintf(pHlp, " Performance optimization support = %RTbool\n", ExtFeat.n.u1PerfOptSup); 3116 pHlp->pfnPrintf(pHlp, " MSI capability MMIO access support = %RTbool\n", ExtFeat.n.u1MsiCapMmioSup); 3117 pHlp->pfnPrintf(pHlp, " Guest I/O protection support = %RTbool\n", ExtFeat.n.u1GstIoSup); 3118 pHlp->pfnPrintf(pHlp, " Host access support = %RTbool\n", ExtFeat.n.u1HostAccessSup); 3119 pHlp->pfnPrintf(pHlp, " Enhanced PPR handling support = %RTbool\n", ExtFeat.n.u1EnhancedPprSup); 3120 pHlp->pfnPrintf(pHlp, " Attribute forward supported = %RTbool\n", ExtFeat.n.u1AttrForwardSup); 3121 pHlp->pfnPrintf(pHlp, " Host dirty support = %RTbool\n", ExtFeat.n.u1HostDirtySup); 3122 pHlp->pfnPrintf(pHlp, " Invalidate IOTLB type support = %RTbool\n", ExtFeat.n.u1InvIoTlbTypeSup); 3123 pHlp->pfnPrintf(pHlp, " Guest page table access bit hw disable = %RTbool\n", ExtFeat.n.u1GstUpdateDisSup); 3124 pHlp->pfnPrintf(pHlp, " Force physical dest for remapped intr. = %RTbool\n", ExtFeat.n.u1ForcePhysDstSup); 3200 pHlp->pfnPrintf(pHlp, " PPR support = %RTbool\n", ExtFeat.n.u1PprSup); 3201 pHlp->pfnPrintf(pHlp, " x2APIC support = %RTbool\n", ExtFeat.n.u1X2ApicSup); 3202 pHlp->pfnPrintf(pHlp, " NX and privilege level support = %RTbool\n", ExtFeat.n.u1NoExecuteSup); 3203 pHlp->pfnPrintf(pHlp, " Guest translation support = %RTbool\n", ExtFeat.n.u1GstTranslateSup); 3204 pHlp->pfnPrintf(pHlp, " Invalidate-All command support = %RTbool\n", ExtFeat.n.u1InvAllSup); 3205 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC support = %RTbool\n", ExtFeat.n.u1GstVirtApicSup); 3206 pHlp->pfnPrintf(pHlp, " Hardware error register support = %RTbool\n", ExtFeat.n.u1HwErrorSup); 3207 pHlp->pfnPrintf(pHlp, " Performance counters support = %RTbool\n", ExtFeat.n.u1PerfCounterSup); 3208 pHlp->pfnPrintf(pHlp, " Host address translation size = %#x\n", ExtFeat.n.u2HostAddrTranslateSize); 3209 pHlp->pfnPrintf(pHlp, " Guest address translation size = %#x\n", ExtFeat.n.u2GstAddrTranslateSize); 3210 pHlp->pfnPrintf(pHlp, " Guest CR3 root table level support = %#x\n", ExtFeat.n.u2GstCr3RootTblLevel); 3211 pHlp->pfnPrintf(pHlp, " SMI filter register support = %#x\n", ExtFeat.n.u2SmiFilterSup); 3212 pHlp->pfnPrintf(pHlp, " SMI filter register count = %#x\n", ExtFeat.n.u3SmiFilterCount); 3213 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC modes support = %#x\n", ExtFeat.n.u3GstVirtApicModeSup); 3214 pHlp->pfnPrintf(pHlp, " Dual PPR log support = %#x\n", ExtFeat.n.u2DualPprLogSup); 3215 pHlp->pfnPrintf(pHlp, " Dual event log support = %#x\n", ExtFeat.n.u2DualEvtLogSup); 3216 pHlp->pfnPrintf(pHlp, " Maximum PASID = %#x\n", ExtFeat.n.u5MaxPasidSup); 3217 pHlp->pfnPrintf(pHlp, " User/supervisor page protection support = %RTbool\n", ExtFeat.n.u1UserSupervisorSup); 3218 pHlp->pfnPrintf(pHlp, " Device table segments supported = %#x (%u)\n", ExtFeat.n.u2DevTabSegSup, 3219 g_aDevTabSegments[ExtFeat.n.u2DevTabSegSup]); 3220 pHlp->pfnPrintf(pHlp, " PPR log overflow early warning support = %RTbool\n", ExtFeat.n.u1PprLogOverflowWarn); 3221 pHlp->pfnPrintf(pHlp, " PPR auto response support = %RTbool\n", ExtFeat.n.u1PprAutoRespSup); 3222 pHlp->pfnPrintf(pHlp, " MARC support = %#x\n", ExtFeat.n.u2MarcSup); 3223 pHlp->pfnPrintf(pHlp, " Block StopMark message support = %RTbool\n", ExtFeat.n.u1BlockStopMarkSup); 3224 pHlp->pfnPrintf(pHlp, " Performance optimization support = %RTbool\n", ExtFeat.n.u1PerfOptSup); 3225 pHlp->pfnPrintf(pHlp, " MSI capability MMIO access support = %RTbool\n", ExtFeat.n.u1MsiCapMmioSup); 3226 pHlp->pfnPrintf(pHlp, " Guest I/O protection support = %RTbool\n", ExtFeat.n.u1GstIoSup); 3227 pHlp->pfnPrintf(pHlp, " Host access support = %RTbool\n", ExtFeat.n.u1HostAccessSup); 3228 pHlp->pfnPrintf(pHlp, " Enhanced PPR handling support = %RTbool\n", ExtFeat.n.u1EnhancedPprSup); 3229 pHlp->pfnPrintf(pHlp, " Attribute forward supported = %RTbool\n", ExtFeat.n.u1AttrForwardSup); 3230 pHlp->pfnPrintf(pHlp, " Host dirty support = %RTbool\n", ExtFeat.n.u1HostDirtySup); 3231 pHlp->pfnPrintf(pHlp, " Invalidate IOTLB type support = %RTbool\n", ExtFeat.n.u1InvIoTlbTypeSup); 3232 pHlp->pfnPrintf(pHlp, " Guest page table access bit hw disable = %RTbool\n", ExtFeat.n.u1GstUpdateDisSup); 3233 pHlp->pfnPrintf(pHlp, " Force physical dest for remapped intr. = %RTbool\n", ExtFeat.n.u1ForcePhysDstSup); 3125 3234 } 3126 3235 } … … 3585 3694 pThis->ExtFeat.n.u5MaxPasidSup = 0; /* Requires GstTranslateSup. */ 3586 3695 pThis->ExtFeat.n.u1UserSupervisorSup = 0; 3587 pThis->ExtFeat.n.u2DevTabSegSup = 0; 3696 AssertCompile(IOMMU_MAX_DEV_TAB_SEGMENTS < RT_ELEMENTS(g_aDevTabSegments)); 3697 pThis->ExtFeat.n.u2DevTabSegSup = IOMMU_MAX_DEV_TAB_SEGMENTS; 3588 3698 pThis->ExtFeat.n.u1PprLogOverflowWarn = 0; 3589 3699 pThis->ExtFeat.n.u1PprAutoRespSup = 0;
Note:
See TracChangeset
for help on using the changeset viewer.