Changeset 83681 in vbox for trunk/src/VBox
- Timestamp:
- Apr 13, 2020 4:38:52 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 137176
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r83669 r83681 1658 1658 } CMD_BUF_HEAD_PTR_T; 1659 1659 AssertCompileSize(CMD_BUF_HEAD_PTR_T, 8); 1660 #define IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK UINT64_C(0x000000000007fff0) 1660 1661 1661 1662 /** … … 1665 1666 */ 1666 1667 typedef CMD_BUF_HEAD_PTR_T CMD_BUF_TAIL_PTR_T; 1668 #define IOMMU_CMD_BUF_TAIL_PTR_VALID_MASK UINT64_C(0x000000000007fff0) 1669 1667 1670 1668 1671 /** … … 1845 1848 /** The MMIO handle. */ 1846 1849 IOMMMIOHANDLE hMmio; 1850 /** The event semaphore the command thread waits on. */ 1851 SUPSEMEVENT hEvtCmdThread; 1847 1852 1848 1853 /** @name MMIO: Control and status registers. … … 1981 1986 { 1982 1987 /** The IOMMU helpers. */ 1983 PCPDMIOMMUHLPR3 pIommuHlp; 1988 PCPDMIOMMUHLPR3 pIommuHlp; 1989 /** The command thread handle. */ 1990 R3PTRTYPE(PPDMTHREAD) pCmdThread; 1984 1991 } IOMMUR3; 1985 1992 /** Pointer to the ring-3 IOMMU device state. */ … … 1992 1999 { 1993 2000 /** The IOMMU helpers. */ 1994 PCPDMIOMMUHLPR0 pIommuHlp;2001 PCPDMIOMMUHLPR0 pIommuHlp; 1995 2002 } IOMMUR0; 1996 2003 /** Pointer to the ring-0 IOMMU device state. */ … … 2003 2010 { 2004 2011 /** The IOMMU helpers. */ 2005 PCPDMIOMMUHLPRC pIommuHlp;2012 PCPDMIOMMUHLPRC pIommuHlp; 2006 2013 } IOMMURC; 2007 2014 /** Pointer to the raw-mode IOMMU device state. */ … … 2188 2195 pThis->MsiData.u32 = u64Value & IOMMU_MSI_DATA_VALID_MASK; 2189 2196 return VINF_SUCCESS; 2197 } 2198 2199 2200 /** 2201 * Writes the Command Buffer Head Pointer Register (32-bit). 2202 */ 2203 static VBOXSTRICTRC iommuAmdCmdBufHeadPtr_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value) 2204 { 2205 RT_NOREF(pDevIns, iReg); 2206 2207 /* 2208 * IOMMU behavior is undefined when software writes this register when the command buffer is running. 2209 * In our emulation, we ignore the write entirely. 2210 * See AMD IOMMU spec. 3.3.13 "Command and Event Log Pointer Registers". 2211 */ 2212 IOMMU_STATUS_T const Status = pThis->Status; 2213 if (Status.n.u1CmdBufRunning) 2214 { 2215 Log((IOMMU_LOG_PFX ": Setting CmdBufHeadPtr (%#RX64) when command buffer is running -> Ignored\n", u64Value)); 2216 return VINF_SUCCESS; 2217 } 2218 2219 /* 2220 * IOMMU behavior is undefined when software writes a value value outside the buffer length. 2221 * In our emtulation, we ignore the write entirely. 2222 */ 2223 uint32_t const offBuf = u64Value & IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK; 2224 CMD_BUF_BAR_T const CmdBufBar = pThis->CmdBufBaseAddr; 2225 uint32_t cbBuf; 2226 iommuAmdDecodeBufferLength(CmdBufBar.n.u4CmdLen, NULL, &cbBuf); 2227 if (offBuf >= cbBuf) 2228 { 2229 Log((IOMMU_LOG_PFX ": Setting CmdBufHeadPtr (%#RX32) to a value that exceeds buffer length -> Ignored\n", offBuf, cbBuf)); 2230 return VINF_SUCCESS; 2231 } 2232 2233 pThis->CmdBufHeadPtr.u64 = offBuf; 2234 LogFlow((IOMMU_LOG_PFX ": Set CmdBufHeadPtr to %#RX32\n", offBuf)); 2235 return VINF_SUCCESS; 2236 } 2237 2238 2239 /** 2240 * Writes the Command Buffer Tail Pointer Register (32-bit). 2241 */ 2242 static VBOXSTRICTRC iommuAmdCmdBufTailPtr_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value) 2243 { 2244 RT_NOREF(pDevIns, iReg); 2245 2246 /* 2247 * IOMMU behavior is undefined when software advances this register equal or beyond its head pointer. 2248 * In our emulation, we ignore the write entirely. 2249 * See AMD IOMMU spec. 3.3.13 "Command and Event Log Pointer Registers". 2250 */ 2251 uint32_t const offBufTail = u64Value & IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK; 2252 NOREF(offBufTail); 2253 NOREF(pThis); 2254 return VINF_SUCCESS; 2255 } 2256 2257 2258 /** 2259 * Writes the Event Log Head Pointer Register (32-bit). 2260 */ 2261 static VBOXSTRICTRC iommuAmdEvtLogHeadPtr_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value) 2262 { 2263 RT_NOREF(pDevIns, iReg); 2264 NOREF(pThis); 2265 NOREF(u64Value); 2266 return VINF_SUCCESS; 2267 } 2268 2269 2270 /** 2271 * Writes the Event Log Tail Pointer Register (32-bit). 2272 */ 2273 static VBOXSTRICTRC iommuAmdEvtLogTailPtr_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value) 2274 { 2275 RT_NOREF(pDevIns, iReg); 2276 NOREF(pThis); 2277 NOREF(u64Value); 2278 return VINF_SUCCESS; 2279 } 2280 2281 2282 /** 2283 * The IOMMU command thread. 2284 * 2285 * @returns VBox status code. 2286 * @param pDevIns The device instance. 2287 * @param pThread The command thread. 2288 */ 2289 static DECLCALLBACK(int) iommuAmdR3CmdThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 2290 { 2291 RT_NOREF(pDevIns, pThread); 2292 } 2293 2294 2295 /** 2296 * Unblocks the command thread so it can respond to a state change. 2297 * 2298 * @returns VBox status code. 2299 * @param pDevIns The device instance. 2300 * @param pThread The command thread. 2301 */ 2302 static DECLCALLBACK(int) iommuAmdR3CmdThreadWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 2303 { 2304 RT_NOREF(pDevIns, pThread); 2190 2305 } 2191 2306 … … 2302 2417 case IOMMU_MMIO_OFF_RSVD_REG: return iommuAmdIgnore_w(pDevIns, pThis, off, uValue); 2303 2418 2304 case IOMMU_MMIO_CMD_BUF_HEAD_PTR: 2305 case IOMMU_MMIO_CMD_BUF_TAIL_PTR: 2306 case IOMMU_MMIO_EVT_LOG_HEAD_PTR: 2307 case IOMMU_MMIO_EVT_LOG_TAIL_PTR: 2419 case IOMMU_MMIO_CMD_BUF_HEAD_PTR: return iommuAmdCmdBufHeadPtr_w(pDevIns, pThis, off, uValue); 2420 case IOMMU_MMIO_CMD_BUF_TAIL_PTR: return iommuAmdCmdBufTailPtr_w(pDevIns, pThis, off, uValue); 2421 case IOMMU_MMIO_EVT_LOG_HEAD_PTR: return iommuAmdEvtLogHeadPtr_w(pDevIns, pThis, off, uValue); 2422 case IOMMU_MMIO_EVT_LOG_TAIL_PTR: return iommuAmdEvtLogTailPtr_w(pDevIns, pThis, off, uValue); 2308 2423 2309 2424 case IOMMU_MMIO_OFF_STATUS: … … 2319 2434 2320 2435 case IOMMU_MMIO_OFF_EVT_LOG_B_HEAD_PTR: 2321 case IOMMU_MMIO_OFF_EVT_LOG_B_TAIL_PTR: 2436 case IOMMU_MMIO_OFF_EVT_LOG_B_TAIL_PTR: return iommuAmdIgnore_w(pDevIns, pThis, off, uValue); 2322 2437 2323 2438 case IOMMU_MMIO_OFF_PPR_LOG_AUTO_RESP: … … 2513 2628 2514 2629 # ifdef IN_RING3 2515 2516 /** 2517 * Resets read-write portions of the IOMMU state. 2518 * 2519 * State data not initialized here is expected to be initialized in the construct 2520 * callback and remain read-only through the lifetime of the VM. 2521 * 2522 * @param pDevIns The device instance. 2523 */ 2524 static void iommuAmdR3Init(PPDMDEVINS pDevIns) 2525 { 2630 /** 2631 * @callback_method_impl{FNPCICONFIGREAD} 2632 */ 2633 static DECLCALLBACK(VBOXSTRICTRC) iommuAmdR3PciConfigRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress, 2634 unsigned cb, uint32_t *pu32Value) 2635 { 2636 /** @todo IOMMU: PCI config read stat counter. */ 2637 VBOXSTRICTRC rcStrict = PDMDevHlpPCIConfigRead(pDevIns, pPciDev, uAddress, cb, pu32Value); 2638 Log3((IOMMU_LOG_PFX ": PCI config read: At %#x (%u) -> %#x %Rrc\n", uAddress, cb, *pu32Value, VBOXSTRICTRC_VAL(rcStrict))); 2639 return rcStrict; 2640 } 2641 2642 2643 /** 2644 * @callback_method_impl{FNPCICONFIGWRITE} 2645 */ 2646 static DECLCALLBACK(VBOXSTRICTRC) iommuAmdR3PciConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress, 2647 unsigned cb, uint32_t u32Value) 2648 { 2649 /** @todo IOMMU: PCI config write. */ 2650 VBOXSTRICTRC rcStrict = PDMDevHlpPCIConfigWrite(pDevIns, pPciDev, uAddress, cb, u32Value); 2651 Log3((IOMMU_LOG_PFX ": PCI config write: %#x -> To %#x (%u) %Rrc\n", u32Value, uAddress, cb, VBOXSTRICTRC_VAL(rcStrict))); 2652 return rcStrict; 2653 } 2654 2655 2656 /** 2657 * @callback_method_impl{FNDBGFHANDLERDEV} 2658 */ 2659 static DECLCALLBACK(void) iommuAmdR3DbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 2660 { 2661 PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 2662 Assert(pThis); 2663 2664 LogFlow((IOMMU_LOG_PFX ": iommuAmdR3DbgInfo: pThis=%p pszArgs=%s\n", pThis, pszArgs)); 2665 bool const fVerbose = !strncmp(pszArgs, RT_STR_TUPLE("verbose")) ? true : false; 2666 2667 pHlp->pfnPrintf(pHlp, "AMD-IOMMU:\n"); 2668 /* Device Table Base Address. */ 2669 { 2670 DEV_TAB_BAR_T const DevTabBar = pThis->DevTabBaseAddr; 2671 pHlp->pfnPrintf(pHlp, " Device Table BAR = %#RX64\n", DevTabBar.u64); 2672 if (fVerbose) 2673 { 2674 pHlp->pfnPrintf(pHlp, " Size = %u (%u bytes)\n", DevTabBar.n.u9Size, 2675 (DevTabBar.n.u9Size + 1) * _4K); 2676 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", DevTabBar.n.u40DevTabBase); 2677 } 2678 } 2679 /* Command Buffer Base Address Register. */ 2680 { 2681 CMD_BUF_BAR_T const CmdBufBar = pThis->CmdBufBaseAddr; 2682 uint32_t cEntries; 2683 uint32_t cbBuffer; 2684 uint8_t const uEncodedLen = CmdBufBar.n.u4CmdLen; 2685 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2686 pHlp->pfnPrintf(pHlp, " Command buffer BAR = %#RX64\n", CmdBufBar.u64); 2687 if (fVerbose) 2688 { 2689 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", CmdBufBar.n.u40CmdBase); 2690 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen, 2691 cEntries, cbBuffer); 2692 } 2693 } 2694 /* Event Log Base Address Register. */ 2695 { 2696 EVT_LOG_BAR_T const EvtLogBar = pThis->EvtLogBaseAddr; 2697 uint32_t cEntries; 2698 uint32_t cbBuffer; 2699 uint8_t const uEncodedLen = EvtLogBar.n.u4EvtLen; 2700 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2701 pHlp->pfnPrintf(pHlp, " Event log BAR = %#RX64\n", EvtLogBar.u64); 2702 if (fVerbose) 2703 { 2704 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", EvtLogBar.n.u40EvtBase); 2705 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen, 2706 cEntries, cbBuffer); 2707 } 2708 } 2709 /* IOMMU Control Register. */ 2710 { 2711 IOMMU_CTRL_T const Ctrl = pThis->Ctrl; 2712 pHlp->pfnPrintf(pHlp, " Control = %#RX64\n", Ctrl.u64); 2713 if (fVerbose) 2714 { 2715 pHlp->pfnPrintf(pHlp, " IOMMU enable = %RTbool\n", Ctrl.n.u1IommuEn); 2716 pHlp->pfnPrintf(pHlp, " HT Tunnel translation enable = %RTbool\n", Ctrl.n.u1HtTunEn); 2717 pHlp->pfnPrintf(pHlp, " Event log enable = %RTbool\n", Ctrl.n.u1EvtLogEn); 2718 pHlp->pfnPrintf(pHlp, " Event log interrupt enable = %RTbool\n", Ctrl.n.u1EvtIntrEn); 2719 pHlp->pfnPrintf(pHlp, " Completion wait interrupt enable = %RTbool\n", Ctrl.n.u1EvtIntrEn); 2720 pHlp->pfnPrintf(pHlp, " Invalidation timeout = %u\n", Ctrl.n.u3InvTimeOut); 2721 pHlp->pfnPrintf(pHlp, " Pass posted write = %RTbool\n", Ctrl.n.u1PassPW); 2722 pHlp->pfnPrintf(pHlp, " Respose Pass posted write = %RTbool\n", Ctrl.n.u1ResPassPW); 2723 pHlp->pfnPrintf(pHlp, " Coherent = %RTbool\n", Ctrl.n.u1Coherent); 2724 pHlp->pfnPrintf(pHlp, " Isochronous = %RTbool\n", Ctrl.n.u1Isoc); 2725 pHlp->pfnPrintf(pHlp, " Command buffer enable = %RTbool\n", Ctrl.n.u1CmdBufEn); 2726 pHlp->pfnPrintf(pHlp, " PPR log enable = %RTbool\n", Ctrl.n.u1PprLogEn); 2727 pHlp->pfnPrintf(pHlp, " PPR interrupt enable = %RTbool\n", Ctrl.n.u1PprIntrEn); 2728 pHlp->pfnPrintf(pHlp, " PPR enable = %RTbool\n", Ctrl.n.u1PprEn); 2729 pHlp->pfnPrintf(pHlp, " Guest translation eanble = %RTbool\n", Ctrl.n.u1GstTranslateEn); 2730 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC enable = %RTbool\n", Ctrl.n.u1GstVirtApicEn); 2731 pHlp->pfnPrintf(pHlp, " CRW = %#x\n", Ctrl.n.u4Crw); 2732 pHlp->pfnPrintf(pHlp, " SMI filter enable = %RTbool\n", Ctrl.n.u1SmiFilterEn); 2733 pHlp->pfnPrintf(pHlp, " Self-writeback disable = %RTbool\n", Ctrl.n.u1SelfWriteBackDis); 2734 pHlp->pfnPrintf(pHlp, " SMI filter log enable = %RTbool\n", Ctrl.n.u1SmiFilterLogEn); 2735 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC mode enable = %#x\n", Ctrl.n.u3GstVirtApicModeEn); 2736 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC GA log enable = %RTbool\n", Ctrl.n.u1GstLogEn); 2737 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC interrupt enable = %RTbool\n", Ctrl.n.u1GstIntrEn); 2738 pHlp->pfnPrintf(pHlp, " Dual PPR log enable = %#x\n", Ctrl.n.u2DualPprLogEn); 2739 pHlp->pfnPrintf(pHlp, " Dual event log enable = %#x\n", Ctrl.n.u2DualEvtLogEn); 2740 pHlp->pfnPrintf(pHlp, " Device table segmentation enable = %#x\n", Ctrl.n.u3DevTabSegEn); 2741 pHlp->pfnPrintf(pHlp, " Privilege abort enable = %#x\n", Ctrl.n.u2PrivAbortEn); 2742 pHlp->pfnPrintf(pHlp, " PPR auto response enable = %RTbool\n", Ctrl.n.u1PprAutoRespEn); 2743 pHlp->pfnPrintf(pHlp, " MARC enable = %RTbool\n", Ctrl.n.u1MarcEn); 2744 pHlp->pfnPrintf(pHlp, " Block StopMark enable = %RTbool\n", Ctrl.n.u1BlockStopMarkEn); 2745 pHlp->pfnPrintf(pHlp, " PPR auto response always-on enable = %RTbool\n", Ctrl.n.u1PprAutoRespAlwaysOnEn); 2746 pHlp->pfnPrintf(pHlp, " Domain IDPNE = %RTbool\n", Ctrl.n.u1DomainIDPNE); 2747 pHlp->pfnPrintf(pHlp, " Enhanced PPR handling = %RTbool\n", Ctrl.n.u1EnhancedPpr); 2748 pHlp->pfnPrintf(pHlp, " Host page table access/dirty bit update = %#x\n", Ctrl.n.u2HstAccDirtyBitUpdate); 2749 pHlp->pfnPrintf(pHlp, " Guest page table dirty bit disable = %RTbool\n", Ctrl.n.u1GstDirtyUpdateDis); 2750 pHlp->pfnPrintf(pHlp, " x2APIC enable = %RTbool\n", Ctrl.n.u1X2ApicEn); 2751 pHlp->pfnPrintf(pHlp, " x2APIC interrupt enable = %RTbool\n", Ctrl.n.u1X2ApicIntrGenEn); 2752 pHlp->pfnPrintf(pHlp, " Guest page table access bit update = %RTbool\n", Ctrl.n.u1GstAccessUpdateDis); 2753 } 2754 } 2755 /* Exclusion Base Address Register. */ 2756 { 2757 IOMMU_EXCL_RANGE_BAR_T const ExclRangeBar = pThis->ExclRangeBaseAddr; 2758 pHlp->pfnPrintf(pHlp, " Exclusion BAR = %#RX64\n", ExclRangeBar.u64); 2759 if (fVerbose) 2760 { 2761 pHlp->pfnPrintf(pHlp, " Exclusion enable = %RTbool\n", ExclRangeBar.n.u1ExclEnable); 2762 pHlp->pfnPrintf(pHlp, " Allow all devices = %RTbool\n", ExclRangeBar.n.u1AllowAll); 2763 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", ExclRangeBar.n.u40ExclRangeBase); 2764 } 2765 } 2766 /* Exclusion Range Limit Register. */ 2767 { 2768 IOMMU_EXCL_RANGE_LIMIT_T const ExclRangeLimit = pThis->ExclRangeLimit; 2769 pHlp->pfnPrintf(pHlp, " Exclusion Range Limit = %#RX64\n", ExclRangeLimit.u64); 2770 if (fVerbose) 2771 pHlp->pfnPrintf(pHlp, " Range limit = %#RX64\n", ExclRangeLimit.n.u40ExclLimit); 2772 } 2773 /* Extended Feature Register. */ 2774 { 2775 IOMMU_EXT_FEAT_T ExtFeat = pThis->ExtFeat; 2776 pHlp->pfnPrintf(pHlp, " Extended Feature Register = %#RX64\n", ExtFeat.u64); 2777 pHlp->pfnPrintf(pHlp, " Prefetch support = %RTbool\n", ExtFeat.n.u1PrefetchSup); 2778 if (fVerbose) 2779 { 2780 pHlp->pfnPrintf(pHlp, " PPR support = %RTbool\n", ExtFeat.n.u1PprSup); 2781 pHlp->pfnPrintf(pHlp, " x2APIC support = %RTbool\n", ExtFeat.n.u1X2ApicSup); 2782 pHlp->pfnPrintf(pHlp, " NX and privilege level support = %RTbool\n", ExtFeat.n.u1NoExecuteSup); 2783 pHlp->pfnPrintf(pHlp, " Guest translation support = %RTbool\n", ExtFeat.n.u1GstTranslateSup); 2784 pHlp->pfnPrintf(pHlp, " Invalidate-All command support = %RTbool\n", ExtFeat.n.u1InvAllSup); 2785 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC support = %RTbool\n", ExtFeat.n.u1GstVirtApicSup); 2786 pHlp->pfnPrintf(pHlp, " Hardware error register support = %RTbool\n", ExtFeat.n.u1HwErrorSup); 2787 pHlp->pfnPrintf(pHlp, " Performance counters support = %RTbool\n", ExtFeat.n.u1PerfCounterSup); 2788 pHlp->pfnPrintf(pHlp, " Host address translation size = %#x\n", ExtFeat.n.u2HostAddrTranslateSize); 2789 pHlp->pfnPrintf(pHlp, " Guest address translation size = %#x\n", ExtFeat.n.u2GstAddrTranslateSize); 2790 pHlp->pfnPrintf(pHlp, " Guest CR3 root table level support = %#x\n", ExtFeat.n.u2GstCr3RootTblLevel); 2791 pHlp->pfnPrintf(pHlp, " SMI filter register support = %#x\n", ExtFeat.n.u2SmiFilterSup); 2792 pHlp->pfnPrintf(pHlp, " SMI filter register count = %#x\n", ExtFeat.n.u3SmiFilterCount); 2793 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC modes support = %#x\n", ExtFeat.n.u3GstVirtApicModeSup); 2794 pHlp->pfnPrintf(pHlp, " Dual PPR log support = %#x\n", ExtFeat.n.u2DualPprLogSup); 2795 pHlp->pfnPrintf(pHlp, " Dual event log support = %#x\n", ExtFeat.n.u2DualEvtLogSup); 2796 pHlp->pfnPrintf(pHlp, " Maximum PASID = %#x\n", ExtFeat.n.u5MaxPasidSup); 2797 pHlp->pfnPrintf(pHlp, " User/supervisor page protection support = %RTbool\n", ExtFeat.n.u1UserSupervisorSup); 2798 pHlp->pfnPrintf(pHlp, " Device table segments supported = %u\n", (ExtFeat.n.u2DevTabSegSup << 1)); 2799 pHlp->pfnPrintf(pHlp, " PPR log overflow early warning support = %RTbool\n", ExtFeat.n.u1PprLogOverflowWarn); 2800 pHlp->pfnPrintf(pHlp, " PPR auto response support = %RTbool\n", ExtFeat.n.u1PprAutoRespSup); 2801 pHlp->pfnPrintf(pHlp, " MARC support = %#x\n", ExtFeat.n.u2MarcSup); 2802 pHlp->pfnPrintf(pHlp, " Block StopMark message support = %RTbool\n", ExtFeat.n.u1BlockStopMarkSup); 2803 pHlp->pfnPrintf(pHlp, " Performance optimization support = %RTbool\n", ExtFeat.n.u1PerfOptSup); 2804 pHlp->pfnPrintf(pHlp, " MSI capability MMIO access support = %RTbool\n", ExtFeat.n.u1MsiCapMmioSup); 2805 pHlp->pfnPrintf(pHlp, " Guest I/O protection support = %RTbool\n", ExtFeat.n.u1GstIoSup); 2806 pHlp->pfnPrintf(pHlp, " Host access support = %RTbool\n", ExtFeat.n.u1HostAccessSup); 2807 pHlp->pfnPrintf(pHlp, " Enhanced PPR handling support = %RTbool\n", ExtFeat.n.u1EnhancedPprSup); 2808 pHlp->pfnPrintf(pHlp, " Attribute forward supported = %RTbool\n", ExtFeat.n.u1AttrForwardSup); 2809 pHlp->pfnPrintf(pHlp, " Host dirty support = %RTbool\n", ExtFeat.n.u1HostDirtySup); 2810 pHlp->pfnPrintf(pHlp, " Invalidate IOTLB type support = %RTbool\n", ExtFeat.n.u1InvIoTlbTypeSup); 2811 pHlp->pfnPrintf(pHlp, " Guest page table access bit hw disable = %RTbool\n", ExtFeat.n.u1GstUpdateDisSup); 2812 pHlp->pfnPrintf(pHlp, " Force physical dest for remapped intr. = %RTbool\n", ExtFeat.n.u1ForcePhysDstSup); 2813 } 2814 } 2815 /* PPR Log Base Address Register. */ 2816 { 2817 PPR_LOG_BAR_T PprLogBar = pThis->PprLogBaseAddr; 2818 uint32_t cEntries; 2819 uint32_t cbBuffer; 2820 uint8_t const uEncodedLen = PprLogBar.n.u4PprLogLen; 2821 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2822 pHlp->pfnPrintf(pHlp, " PPR Log BAR = %#RX64\n", PprLogBar.u64); 2823 if (fVerbose) 2824 { 2825 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", PprLogBar.n.u40PprLogBase); 2826 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen, 2827 cEntries, cbBuffer); 2828 } 2829 } 2830 /* Hardware Event (Hi) Register. */ 2831 { 2832 IOMMU_HW_EVT_HI_T HwEvtHi = pThis->HwEvtHi; 2833 pHlp->pfnPrintf(pHlp, " Hardware Event (Hi) = %#RX64\n", HwEvtHi.u64); 2834 if (fVerbose) 2835 { 2836 pHlp->pfnPrintf(pHlp, " First operand = %#RX64\n", HwEvtHi.n.u60FirstOperand); 2837 pHlp->pfnPrintf(pHlp, " Event code = %#RX8\n", HwEvtHi.n.u4EvtCode); 2838 } 2839 } 2840 /* Hardware Event (Lo) Register. */ 2841 pHlp->pfnPrintf(pHlp, " Hardware Event (Lo) = %#RX64\n", pThis->HwEvtLo); 2842 /* Hardware Event Status. */ 2843 { 2844 IOMMU_HW_EVT_STATUS_T HwEvtStatus = pThis->HwEvtStatus; 2845 pHlp->pfnPrintf(pHlp, " Hardware Event Status = %#RX64\n", HwEvtStatus.u64); 2846 if (fVerbose) 2847 { 2848 pHlp->pfnPrintf(pHlp, " Valid = %RTbool\n", HwEvtStatus.n.u1Valid); 2849 pHlp->pfnPrintf(pHlp, " Overflow = %RTbool\n", HwEvtStatus.n.u1Overflow); 2850 } 2851 } 2852 /* Guest Virtual-APIC Log Base Address Register. */ 2853 { 2854 GALOG_BAR_T const GALogBar = pThis->GALogBaseAddr; 2855 uint32_t cEntries; 2856 uint32_t cbBuffer; 2857 uint8_t const uEncodedLen = GALogBar.n.u4GALogLen; 2858 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2859 pHlp->pfnPrintf(pHlp, " Guest Log BAR = %#RX64\n", GALogBar.u64); 2860 if (fVerbose) 2861 { 2862 pHlp->pfnPrintf(pHlp, " Base address = %RTbool\n", GALogBar.n.u40GALogBase); 2863 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen, 2864 cEntries, cbBuffer); 2865 } 2866 } 2867 /* Guest Virtual-APIC Log Tail Address Register. */ 2868 { 2869 GALOG_TAIL_ADDR_T GALogTail = pThis->GALogTailAddr; 2870 pHlp->pfnPrintf(pHlp, " Guest Log Tail Address = %#RX64\n", GALogTail.u64); 2871 if (fVerbose) 2872 pHlp->pfnPrintf(pHlp, " Tail address = %#RX64\n", GALogTail.n.u40GALogTailAddr); 2873 } 2874 /* PPR Log B Base Address Register. */ 2875 { 2876 PPR_LOG_B_BAR_T PprLogBBar = pThis->PprLogBBaseAddr; 2877 uint32_t cEntries; 2878 uint32_t cbBuffer; 2879 uint8_t const uEncodedLen = PprLogBBar.n.u4PprLogLen; 2880 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2881 pHlp->pfnPrintf(pHlp, " PPR Log B BAR = %#RX64\n", PprLogBBar.u64); 2882 if (fVerbose) 2883 { 2884 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", PprLogBBar.n.u40PprLogBase); 2885 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen, 2886 cEntries, cbBuffer); 2887 } 2888 } 2889 /* Event Log B Base Address Register. */ 2890 { 2891 EVT_LOG_B_BAR_T EvtLogBBar = pThis->EvtLogBBaseAddr; 2892 uint32_t cEntries; 2893 uint32_t cbBuffer; 2894 uint8_t const uEncodedLen = EvtLogBBar.n.u4EvtLen; 2895 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer); 2896 pHlp->pfnPrintf(pHlp, " Event Log B BAR = %#RX64\n", EvtLogBBar.u64); 2897 if (fVerbose) 2898 { 2899 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", EvtLogBBar.n.u40EvtBase); 2900 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen, 2901 cEntries, cbBuffer); 2902 } 2903 } 2904 /* Device Table Segment Registers. */ 2905 for (unsigned i = 0; i < RT_ELEMENTS(pThis->DevTabSeg); i++) 2906 { 2907 DEV_TAB_SEG_BAR_T const DevTabSeg = pThis->DevTabSeg[i]; 2908 pHlp->pfnPrintf(pHlp, " Device Table Segment BAR [%u] = %#RX64\n", DevTabSeg.u64); 2909 if (fVerbose) 2910 { 2911 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", DevTabSeg.n.u40DevTabBase); 2912 pHlp->pfnPrintf(pHlp, " Size = %#x (%u bytes)\n", DevTabSeg.n.u8Size, 2913 (DevTabSeg.n.u8Size + 1) << X86_PAGE_4K_SHIFT); 2914 } 2915 } 2916 /* Device-Specific Feature Extension Register. */ 2917 { 2918 DEV_SPECIFIC_FEAT_T const DevSpecificFeat = pThis->DevSpecificFeat; 2919 pHlp->pfnPrintf(pHlp, " Device-specific Feature = %#RX64\n", DevSpecificFeat.u64); 2920 if (fVerbose) 2921 { 2922 pHlp->pfnPrintf(pHlp, " Feature = %#RX32\n", DevSpecificFeat.n.u24DevSpecFeat); 2923 pHlp->pfnPrintf(pHlp, " Minor revision ID = %#x\n", DevSpecificFeat.n.u4RevMinor); 2924 pHlp->pfnPrintf(pHlp, " Major revision ID = %#x\n", DevSpecificFeat.n.u4RevMajor); 2925 } 2926 } 2927 /* Device-Specific Control Extension Register. */ 2928 { 2929 DEV_SPECIFIC_CTRL_T const DevSpecificCtrl = pThis->DevSpecificCtrl; 2930 pHlp->pfnPrintf(pHlp, " Device-specific Control = %#RX64\n", DevSpecificCtrl.u64); 2931 if (fVerbose) 2932 { 2933 pHlp->pfnPrintf(pHlp, " Control = %#RX32\n", DevSpecificCtrl.n.u24DevSpecCtrl); 2934 pHlp->pfnPrintf(pHlp, " Minor revision ID = %#x\n", DevSpecificCtrl.n.u4RevMinor); 2935 pHlp->pfnPrintf(pHlp, " Major revision ID = %#x\n", DevSpecificCtrl.n.u4RevMajor); 2936 } 2937 } 2938 /* Device-Specific Status Extension Register. */ 2939 { 2940 DEV_SPECIFIC_STATUS_T const DevSpecificStatus = pThis->DevSpecificStatus; 2941 pHlp->pfnPrintf(pHlp, " Device-specific Control = %#RX64\n", DevSpecificStatus.u64); 2942 if (fVerbose) 2943 { 2944 pHlp->pfnPrintf(pHlp, " Status = %#RX32\n", DevSpecificStatus.n.u24DevSpecStatus); 2945 pHlp->pfnPrintf(pHlp, " Minor revision ID = %#x\n", DevSpecificStatus.n.u4RevMinor); 2946 pHlp->pfnPrintf(pHlp, " Major revision ID = %#x\n", DevSpecificStatus.n.u4RevMajor); 2947 } 2948 } 2949 /* MSI Miscellaneous Information Register (Lo and Hi). */ 2950 { 2951 MSI_MISC_INFO_T const MsiMiscInfo = pThis->MsiMiscInfo; 2952 pHlp->pfnPrintf(pHlp, " MSI Misc. Info. Register = %#RX64\n", MsiMiscInfo.u64); 2953 if (fVerbose) 2954 { 2955 pHlp->pfnPrintf(pHlp, " Event Log MSI number = %#x\n", MsiMiscInfo.n.u5MsiNumEvtLog); 2956 pHlp->pfnPrintf(pHlp, " Guest Virtual-Address Size = %#x\n", MsiMiscInfo.n.u3GstVirtAddrSize); 2957 pHlp->pfnPrintf(pHlp, " Physical Address Size = %#x\n", MsiMiscInfo.n.u7PhysAddrSize); 2958 pHlp->pfnPrintf(pHlp, " Virtual-Address Size = %#x\n", MsiMiscInfo.n.u7VirtAddrSize); 2959 pHlp->pfnPrintf(pHlp, " HT Transport ATS Range Reserved = %RTbool\n", MsiMiscInfo.n.u1HtAtsResv); 2960 pHlp->pfnPrintf(pHlp, " PPR MSI number = %#x\n", MsiMiscInfo.n.u5MsiNumPpr); 2961 pHlp->pfnPrintf(pHlp, " GA Log MSI number = %#x\n", MsiMiscInfo.n.u5MsiNumGa); 2962 } 2963 } 2964 /* MSI Capability Header. */ 2965 { 2966 MSI_CAP_HDR_T const MsiCapHdr = pThis->MsiCapHdr; 2967 pHlp->pfnPrintf(pHlp, " MSI Capability Header = %#RX32\n", MsiCapHdr.u32); 2968 if (fVerbose) 2969 { 2970 pHlp->pfnPrintf(pHlp, " Capability ID = %#x\n", MsiCapHdr.n.u8MsiCapId); 2971 pHlp->pfnPrintf(pHlp, " Capability Ptr (PCI config offset) = %#x\n", MsiCapHdr.n.u8MsiCapPtr); 2972 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", MsiCapHdr.n.u1MsiEnable); 2973 pHlp->pfnPrintf(pHlp, " Multi-message capability = %#x\n", MsiCapHdr.n.u3MsiMultiMessCap); 2974 pHlp->pfnPrintf(pHlp, " Multi-message enable = %#x\n", MsiCapHdr.n.u3MsiMultiMessEn); 2975 } 2976 } 2977 /* MSI Address Register (Lo and Hi). */ 2978 { 2979 MSI_ADDR_T const MsiAddr = pThis->MsiAddr; 2980 pHlp->pfnPrintf(pHlp, " MSI Address = %#RX64\n", MsiAddr.u64); 2981 if (fVerbose) 2982 pHlp->pfnPrintf(pHlp, " Address = %#RX64\n", MsiAddr.n.u62MsiAddr); 2983 } 2984 /* MSI Data. */ 2985 { 2986 MSI_DATA_T const MsiData = pThis->MsiData; 2987 pHlp->pfnPrintf(pHlp, " MSI Data = %#RX32\n", MsiData.u32); 2988 if (fVerbose) 2989 pHlp->pfnPrintf(pHlp, " Data = %#x\n", MsiData.n.u16MsiData); 2990 } 2991 /* MSI Mapping Capability Header. */ 2992 { 2993 MSI_MAP_CAP_HDR_T const MsiMapCapHdr = pThis->MsiMapCapHdr; 2994 pHlp->pfnPrintf(pHlp, " MSI Mapping Capability Header = %#RX32\n", MsiMapCapHdr.u32); 2995 if (fVerbose) 2996 { 2997 pHlp->pfnPrintf(pHlp, " Capability ID = %#x\n", MsiMapCapHdr.n.u8MsiMapCapId); 2998 pHlp->pfnPrintf(pHlp, " Map enable = %RTbool\n", MsiMapCapHdr.n.u1MsiMapEn); 2999 pHlp->pfnPrintf(pHlp, " Map fixed = %RTbool\n", MsiMapCapHdr.n.u1MsiMapFixed); 3000 pHlp->pfnPrintf(pHlp, " Map capability type = %#x\n", MsiMapCapHdr.n.u5MapCapType); 3001 } 3002 } 3003 /* Performance Optimization Control Register. */ 3004 { 3005 IOMMU_PERF_OPT_CTRL_T const PerfOptCtrl = pThis->PerfOptCtrl; 3006 pHlp->pfnPrintf(pHlp, " Performance Optimization Control = %#RX32\n", PerfOptCtrl.u32); 3007 if (fVerbose) 3008 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", PerfOptCtrl.n.u1PerfOptEn); 3009 } 3010 /* XT (x2APIC) General Interrupt Control Register. */ 3011 { 3012 IOMMU_XT_GEN_INTR_CTRL_T const XtGenIntrCtrl = pThis->XtGenIntrCtrl; 3013 pHlp->pfnPrintf(pHlp, " XT General Interrupt Control = %#RX64\n", XtGenIntrCtrl.u64); 3014 if (fVerbose) 3015 { 3016 pHlp->pfnPrintf(pHlp, " Interrupt destination mode = %s\n", 3017 !XtGenIntrCtrl.n.u1X2ApicIntrDstMode ? "physical" : "logical"); 3018 pHlp->pfnPrintf(pHlp, " Interrupt destination = %#RX64\n", 3019 RT_MAKE_U64(XtGenIntrCtrl.n.u24X2ApicIntrDstLo, XtGenIntrCtrl.n.u7X2ApicIntrDstHi)); 3020 pHlp->pfnPrintf(pHlp, " Interrupt vector = %#x\n", XtGenIntrCtrl.n.u8X2ApicIntrVector); 3021 pHlp->pfnPrintf(pHlp, " Interrupt delivery mode = %#x\n", 3022 !XtGenIntrCtrl.n.u8X2ApicIntrVector ? "fixed" : "arbitrated"); 3023 } 3024 } 3025 /* XT (x2APIC) PPR Interrupt Control Register. */ 3026 { 3027 IOMMU_XT_PPR_INTR_CTRL_T const XtPprIntrCtrl = pThis->XtPprIntrCtrl; 3028 pHlp->pfnPrintf(pHlp, " XT PPR Interrupt Control = %#RX64\n", XtPprIntrCtrl.u64); 3029 if (fVerbose) 3030 { 3031 pHlp->pfnPrintf(pHlp, " Interrupt destination mode = %s\n", 3032 !XtPprIntrCtrl.n.u1X2ApicIntrDstMode ? "physical" : "logical"); 3033 pHlp->pfnPrintf(pHlp, " Interrupt destination = %#RX64\n", 3034 RT_MAKE_U64(XtPprIntrCtrl.n.u24X2ApicIntrDstLo, XtPprIntrCtrl.n.u7X2ApicIntrDstHi)); 3035 pHlp->pfnPrintf(pHlp, " Interrupt vector = %#x\n", XtPprIntrCtrl.n.u8X2ApicIntrVector); 3036 pHlp->pfnPrintf(pHlp, " Interrupt delivery mode = %#x\n", 3037 !XtPprIntrCtrl.n.u8X2ApicIntrVector ? "fixed" : "arbitrated"); 3038 } 3039 } 3040 /* XT (X2APIC) GA Log Interrupt Control Register. */ 3041 { 3042 IOMMU_XT_GALOG_INTR_CTRL_T const XtGALogIntrCtrl = pThis->XtGALogIntrCtrl; 3043 pHlp->pfnPrintf(pHlp, " XT PPR Interrupt Control = %#RX64\n", XtGALogIntrCtrl.u64); 3044 if (fVerbose) 3045 { 3046 pHlp->pfnPrintf(pHlp, " Interrupt destination mode = %s\n", 3047 !XtGALogIntrCtrl.n.u1X2ApicIntrDstMode ? "physical" : "logical"); 3048 pHlp->pfnPrintf(pHlp, " Interrupt destination = %#RX64\n", 3049 RT_MAKE_U64(XtGALogIntrCtrl.n.u24X2ApicIntrDstLo, XtGALogIntrCtrl.n.u7X2ApicIntrDstHi)); 3050 pHlp->pfnPrintf(pHlp, " Interrupt vector = %#x\n", XtGALogIntrCtrl.n.u8X2ApicIntrVector); 3051 pHlp->pfnPrintf(pHlp, " Interrupt delivery mode = %#x\n", 3052 !XtGALogIntrCtrl.n.u8X2ApicIntrVector ? "fixed" : "arbitrated"); 3053 } 3054 } 3055 /* MARC Registers. */ 3056 { 3057 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aMarcApers); i++) 3058 { 3059 pHlp->pfnPrintf(pHlp, " MARC Aperature %u:\n", i); 3060 MARC_APER_BAR_T const MarcAperBar = pThis->aMarcApers[i].Base; 3061 pHlp->pfnPrintf(pHlp, " Base = %#RX64 (addr: %#RX64)\n", MarcAperBar.u64, MarcAperBar.n.u40MarcBaseAddr); 3062 3063 MARC_APER_RELOC_T const MarcAperReloc = pThis->aMarcApers[i].Reloc; 3064 pHlp->pfnPrintf(pHlp, " Reloc = %#RX64 (addr: %#RX64, read-only: %RTbool, enable: %RTbool)\n", 3065 MarcAperReloc.u64, MarcAperReloc.n.u40MarcRelocAddr, MarcAperReloc.n.u1ReadOnly, 3066 MarcAperReloc.n.u1RelocEn); 3067 3068 MARC_APER_LEN_T const MarcAperLen = pThis->aMarcApers[i].Length; 3069 pHlp->pfnPrintf(pHlp, " Length = %u pages\n", MarcAperLen.n.u40MarcLength); 3070 } 3071 } 3072 /* Reserved Register. */ 3073 pHlp->pfnPrintf(pHlp, " Reserved Register = %#RX64\n", pThis->RsvdReg); 3074 /* Command Buffer Head Pointer Register. */ 3075 { 3076 CMD_BUF_HEAD_PTR_T const CmdBufHeadPtr = pThis->CmdBufHeadPtr; 3077 pHlp->pfnPrintf(pHlp, " Command Buffer Head Pointer = %#RX64\n", CmdBufHeadPtr.u64); 3078 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufHeadPtr.n.u15Ptr); 3079 } 3080 /* Command Buffer Tail Pointer Register. */ 3081 { 3082 CMD_BUF_HEAD_PTR_T const CmdBufTailPtr = pThis->CmdBufTailPtr; 3083 pHlp->pfnPrintf(pHlp, " Command Buffer Tail Pointer = %#RX64\n", CmdBufTailPtr.u64); 3084 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufTailPtr.n.u15Ptr); 3085 } 3086 /* Event Log Head Pointer Register. */ 3087 { 3088 EVT_LOG_HEAD_PTR_T const EvtLogHeadPtr = pThis->EvtLogHeadPtr; 3089 pHlp->pfnPrintf(pHlp, " Event Log Head Pointer = %#RX64\n", EvtLogHeadPtr.u64); 3090 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogHeadPtr.n.u15Ptr); 3091 } 3092 /* Event Log Tail Pointer Register. */ 3093 { 3094 EVT_LOG_TAIL_PTR_T const EvtLogTailPtr = pThis->EvtLogTailPtr; 3095 pHlp->pfnPrintf(pHlp, " Event Log Head Pointer = %#RX64\n", EvtLogTailPtr.u64); 3096 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogTailPtr.n.u15Ptr); 3097 } 3098 /* Status Register. */ 3099 { 3100 IOMMU_STATUS_T const Status = pThis->Status; 3101 pHlp->pfnPrintf(pHlp, " Status Register = %#RX64\n", Status.u64); 3102 if (fVerbose) 3103 { 3104 pHlp->pfnPrintf(pHlp, " Event log overflow = %RTbool\n", Status.n.u1EvtOverflow); 3105 pHlp->pfnPrintf(pHlp, " Event log interrupt = %RTbool\n", Status.n.u1EvtLogIntr); 3106 pHlp->pfnPrintf(pHlp, " Completion wait interrupt = %RTbool\n", Status.n.u1CompWaitIntr); 3107 pHlp->pfnPrintf(pHlp, " Event log running = %RTbool\n", Status.n.u1EvtLogRunning); 3108 pHlp->pfnPrintf(pHlp, " Command buffer running = %RTbool\n", Status.n.u1CmdBufRunning); 3109 pHlp->pfnPrintf(pHlp, " PPR overflow = %RTbool\n", Status.n.u1PprOverflow); 3110 pHlp->pfnPrintf(pHlp, " PPR interrupt = %RTbool\n", Status.n.u1PprIntr); 3111 pHlp->pfnPrintf(pHlp, " PPR log running = %RTbool\n", Status.n.u1PprLogRunning); 3112 pHlp->pfnPrintf(pHlp, " Guest log running = %RTbool\n", Status.n.u1GstLogRunning); 3113 pHlp->pfnPrintf(pHlp, " Guest log interrupt = %RTbool\n", Status.n.u1GstLogIntr); 3114 pHlp->pfnPrintf(pHlp, " PPR log B overflow = %RTbool\n", Status.n.u1PprOverflowB); 3115 pHlp->pfnPrintf(pHlp, " PPR log active = %RTbool\n", Status.n.u1PprLogActive); 3116 pHlp->pfnPrintf(pHlp, " Event log B overflow = %RTbool\n", Status.n.u1EvtOverflowB); 3117 pHlp->pfnPrintf(pHlp, " Event log active = %RTbool\n", Status.n.u1EvtLogActive); 3118 pHlp->pfnPrintf(pHlp, " PPR log B overflow early warning = %RTbool\n", Status.n.u1PprOverflowEarlyB); 3119 pHlp->pfnPrintf(pHlp, " PPR log overflow early warning = %RTbool\n", Status.n.u1PprOverflowEarly); 3120 } 3121 } 3122 /* PPR Log Head Pointer. */ 3123 { 3124 PPR_LOG_HEAD_PTR_T const PprLogHeadPtr = pThis->PprLogHeadPtr; 3125 pHlp->pfnPrintf(pHlp, " PPR Log Head Pointer = %#RX64\n", PprLogHeadPtr.u64); 3126 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogHeadPtr.n.u15Ptr); 3127 } 3128 /* PPR Log Tail Pointer. */ 3129 { 3130 PPR_LOG_TAIL_PTR_T const PprLogTailPtr = pThis->PprLogTailPtr; 3131 pHlp->pfnPrintf(pHlp, " PPR Log Tail Pointer = %#RX64\n", PprLogTailPtr.u64); 3132 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogTailPtr.n.u15Ptr); 3133 } 3134 /* Guest Virtual-APIC Log Head Pointer. */ 3135 { 3136 GALOG_HEAD_PTR_T const GALogHeadPtr = pThis->GALogHeadPtr; 3137 pHlp->pfnPrintf(pHlp, " Guest Virtual-APIC Log Head Pointer = %#RX64\n", GALogHeadPtr.u64); 3138 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", GALogHeadPtr.n.u12GALogPtr); 3139 } 3140 /* Guest Virtual-APIC Log Tail Pointer. */ 3141 { 3142 GALOG_HEAD_PTR_T const GALogTailPtr = pThis->GALogTailPtr; 3143 pHlp->pfnPrintf(pHlp, " Guest Virtual-APIC Log Tail Pointer = %#RX64\n", GALogTailPtr.u64); 3144 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", GALogTailPtr.n.u12GALogPtr); 3145 } 3146 /* PPR Log B Head Pointer. */ 3147 { 3148 PPR_LOG_B_HEAD_PTR_T const PprLogBHeadPtr = pThis->PprLogBHeadPtr; 3149 pHlp->pfnPrintf(pHlp, " PPR Log B Head Pointer = %#RX64\n", PprLogBHeadPtr.u64); 3150 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBHeadPtr.n.u15Ptr); 3151 } 3152 /* PPR Log B Tail Pointer. */ 3153 { 3154 PPR_LOG_B_TAIL_PTR_T const PprLogBTailPtr = pThis->PprLogBTailPtr; 3155 pHlp->pfnPrintf(pHlp, " PPR Log B Tail Pointer = %#RX64\n", PprLogBTailPtr.u64); 3156 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBTailPtr.n.u15Ptr); 3157 } 3158 /* Event Log B Head Pointer. */ 3159 { 3160 EVT_LOG_B_HEAD_PTR_T const EvtLogBHeadPtr = pThis->EvtLogBHeadPtr; 3161 pHlp->pfnPrintf(pHlp, " Event Log B Head Pointer = %#RX64\n", EvtLogBHeadPtr.u64); 3162 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBHeadPtr.n.u15Ptr); 3163 } 3164 /* Event Log B Tail Pointer. */ 3165 { 3166 EVT_LOG_B_TAIL_PTR_T const EvtLogBTailPtr = pThis->EvtLogBTailPtr; 3167 pHlp->pfnPrintf(pHlp, " Event Log B Tail Pointer = %#RX64\n", EvtLogBTailPtr.u64); 3168 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBTailPtr.n.u15Ptr); 3169 } 3170 /* PPR Log Auto Response Register. */ 3171 { 3172 PPR_LOG_AUTO_RESP_T const PprLogAutoResp = pThis->PprLogAutoResp; 3173 pHlp->pfnPrintf(pHlp, " PPR Log Auto Response Register = %#RX64\n", PprLogAutoResp.u64); 3174 if (fVerbose) 3175 { 3176 pHlp->pfnPrintf(pHlp, " Code = %#x\n", PprLogAutoResp.n.u4AutoRespCode); 3177 pHlp->pfnPrintf(pHlp, " Mask Gen. = %RTbool\n", PprLogAutoResp.n.u1AutoRespMaskGen); 3178 } 3179 } 3180 /* PPR Log Overflow Early Warning Indicator Register. */ 3181 { 3182 PPR_LOG_OVERFLOW_EARLY_T const PprLogOverflowEarly = pThis->PprLogOverflowEarly; 3183 pHlp->pfnPrintf(pHlp, " PPR Log overflow early warning = %#RX64\n", PprLogOverflowEarly.u64); 3184 if (fVerbose) 3185 { 3186 pHlp->pfnPrintf(pHlp, " Threshold = %#x\n", PprLogOverflowEarly.n.u15Threshold); 3187 pHlp->pfnPrintf(pHlp, " Interrupt enable = %RTbool\n", PprLogOverflowEarly.n.u1IntrEn); 3188 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", PprLogOverflowEarly.n.u1Enable); 3189 } 3190 } 3191 /* PPR Log Overflow Early Warning Indicator Register. */ 3192 { 3193 PPR_LOG_OVERFLOW_EARLY_T const PprLogBOverflowEarly = pThis->PprLogBOverflowEarly; 3194 pHlp->pfnPrintf(pHlp, " PPR Log B overflow early warning = %#RX64\n", PprLogBOverflowEarly.u64); 3195 if (fVerbose) 3196 { 3197 pHlp->pfnPrintf(pHlp, " Threshold = %#x\n", PprLogBOverflowEarly.n.u15Threshold); 3198 pHlp->pfnPrintf(pHlp, " Interrupt enable = %RTbool\n", PprLogBOverflowEarly.n.u1IntrEn); 3199 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", PprLogBOverflowEarly.n.u1Enable); 3200 } 3201 } 3202 } 3203 3204 3205 /** 3206 * @callback_method_impl{FNSSMDEVSAVEEXEC} 3207 */ 3208 static DECLCALLBACK(int) iommuAmdR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 3209 { 3210 /** @todo IOMMU: Save state. */ 3211 RT_NOREF2(pDevIns, pSSM); 3212 return VERR_NOT_IMPLEMENTED; 3213 } 3214 3215 3216 /** 3217 * @callback_method_impl{FNSSMDEVLOADEXEC} 3218 */ 3219 static DECLCALLBACK(int) iommuAmdR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 3220 { 3221 /** @todo IOMMU: Load state. */ 3222 RT_NOREF4(pDevIns, pSSM, uVersion, uPass); 3223 return VERR_NOT_IMPLEMENTED; 3224 } 3225 3226 3227 /** 3228 * @interface_method_impl{PDMDEVREG,pfnReset} 3229 */ 3230 static DECLCALLBACK(void) iommuAmdR3Reset(PPDMDEVINS pDevIns) 3231 { 3232 /* 3233 * Resets read-write portion of the IOMMU state. 3234 * 3235 * State data not initialized here is expected to be initialized during 3236 * device construction and remain read-only through the lifetime of the VM. 3237 */ 2526 3238 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 2527 3239 Assert(pThis); … … 2620 3332 2621 3333 /** 2622 * @callback_method_impl{FNPCICONFIGREAD}2623 */2624 static DECLCALLBACK(VBOXSTRICTRC) iommuAmdR3PciConfigRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress,2625 unsigned cb, uint32_t *pu32Value)2626 {2627 /** @todo IOMMU: PCI config read stat counter. */2628 VBOXSTRICTRC rcStrict = PDMDevHlpPCIConfigRead(pDevIns, pPciDev, uAddress, cb, pu32Value);2629 Log3((IOMMU_LOG_PFX ": PCI config read: At %#x (%u) -> %#x %Rrc\n", uAddress, cb, *pu32Value, VBOXSTRICTRC_VAL(rcStrict)));2630 return rcStrict;2631 }2632 2633 2634 /**2635 * @callback_method_impl{FNPCICONFIGWRITE}2636 */2637 static DECLCALLBACK(VBOXSTRICTRC) iommuAmdR3PciConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress,2638 unsigned cb, uint32_t u32Value)2639 {2640 /** @todo IOMMU: PCI config write. */2641 VBOXSTRICTRC rcStrict = PDMDevHlpPCIConfigWrite(pDevIns, pPciDev, uAddress, cb, u32Value);2642 Log3((IOMMU_LOG_PFX ": PCI config write: %#x -> To %#x (%u) %Rrc\n", u32Value, uAddress, cb, VBOXSTRICTRC_VAL(rcStrict)));2643 return rcStrict;2644 }2645 2646 2647 /**2648 * @callback_method_impl{FNDBGFHANDLERDEV}2649 */2650 static DECLCALLBACK(void) iommuAmdR3DbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)2651 {2652 PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);2653 Assert(pThis);2654 2655 LogFlow((IOMMU_LOG_PFX ": iommuAmdR3DbgInfo: pThis=%p pszArgs=%s\n", pThis, pszArgs));2656 bool const fVerbose = !strncmp(pszArgs, RT_STR_TUPLE("verbose")) ? true : false;2657 2658 pHlp->pfnPrintf(pHlp, "AMD-IOMMU:\n");2659 /* Device Table Base Address. */2660 {2661 DEV_TAB_BAR_T const DevTabBar = pThis->DevTabBaseAddr;2662 pHlp->pfnPrintf(pHlp, " Device Table BAR = %#RX64\n", DevTabBar.u64);2663 if (fVerbose)2664 {2665 pHlp->pfnPrintf(pHlp, " Size = %u (%u bytes)\n", DevTabBar.n.u9Size,2666 (DevTabBar.n.u9Size + 1) * _4K);2667 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", DevTabBar.n.u40DevTabBase);2668 }2669 }2670 /* Command Buffer Base Address Register. */2671 {2672 CMD_BUF_BAR_T const CmdBufBar = pThis->CmdBufBaseAddr;2673 uint32_t cEntries;2674 uint32_t cbBuffer;2675 uint8_t const uEncodedLen = CmdBufBar.n.u4CmdLen;2676 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2677 pHlp->pfnPrintf(pHlp, " Command buffer BAR = %#RX64\n", CmdBufBar.u64);2678 if (fVerbose)2679 {2680 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", CmdBufBar.n.u40CmdBase);2681 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen,2682 cEntries, cbBuffer);2683 }2684 }2685 /* Event Log Base Address Register. */2686 {2687 EVT_LOG_BAR_T const EvtLogBar = pThis->EvtLogBaseAddr;2688 uint32_t cEntries;2689 uint32_t cbBuffer;2690 uint8_t const uEncodedLen = EvtLogBar.n.u4EvtLen;2691 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2692 pHlp->pfnPrintf(pHlp, " Event log BAR = %#RX64\n", EvtLogBar.u64);2693 if (fVerbose)2694 {2695 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", EvtLogBar.n.u40EvtBase);2696 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen,2697 cEntries, cbBuffer);2698 }2699 }2700 /* IOMMU Control Register. */2701 {2702 IOMMU_CTRL_T const Ctrl = pThis->Ctrl;2703 pHlp->pfnPrintf(pHlp, " Control = %#RX64\n", Ctrl.u64);2704 if (fVerbose)2705 {2706 pHlp->pfnPrintf(pHlp, " IOMMU enable = %RTbool\n", Ctrl.n.u1IommuEn);2707 pHlp->pfnPrintf(pHlp, " HT Tunnel translation enable = %RTbool\n", Ctrl.n.u1HtTunEn);2708 pHlp->pfnPrintf(pHlp, " Event log enable = %RTbool\n", Ctrl.n.u1EvtLogEn);2709 pHlp->pfnPrintf(pHlp, " Event log interrupt enable = %RTbool\n", Ctrl.n.u1EvtIntrEn);2710 pHlp->pfnPrintf(pHlp, " Completion wait interrupt enable = %RTbool\n", Ctrl.n.u1EvtIntrEn);2711 pHlp->pfnPrintf(pHlp, " Invalidation timeout = %u\n", Ctrl.n.u3InvTimeOut);2712 pHlp->pfnPrintf(pHlp, " Pass posted write = %RTbool\n", Ctrl.n.u1PassPW);2713 pHlp->pfnPrintf(pHlp, " Respose Pass posted write = %RTbool\n", Ctrl.n.u1ResPassPW);2714 pHlp->pfnPrintf(pHlp, " Coherent = %RTbool\n", Ctrl.n.u1Coherent);2715 pHlp->pfnPrintf(pHlp, " Isochronous = %RTbool\n", Ctrl.n.u1Isoc);2716 pHlp->pfnPrintf(pHlp, " Command buffer enable = %RTbool\n", Ctrl.n.u1CmdBufEn);2717 pHlp->pfnPrintf(pHlp, " PPR log enable = %RTbool\n", Ctrl.n.u1PprLogEn);2718 pHlp->pfnPrintf(pHlp, " PPR interrupt enable = %RTbool\n", Ctrl.n.u1PprIntrEn);2719 pHlp->pfnPrintf(pHlp, " PPR enable = %RTbool\n", Ctrl.n.u1PprEn);2720 pHlp->pfnPrintf(pHlp, " Guest translation eanble = %RTbool\n", Ctrl.n.u1GstTranslateEn);2721 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC enable = %RTbool\n", Ctrl.n.u1GstVirtApicEn);2722 pHlp->pfnPrintf(pHlp, " CRW = %#x\n", Ctrl.n.u4Crw);2723 pHlp->pfnPrintf(pHlp, " SMI filter enable = %RTbool\n", Ctrl.n.u1SmiFilterEn);2724 pHlp->pfnPrintf(pHlp, " Self-writeback disable = %RTbool\n", Ctrl.n.u1SelfWriteBackDis);2725 pHlp->pfnPrintf(pHlp, " SMI filter log enable = %RTbool\n", Ctrl.n.u1SmiFilterLogEn);2726 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC mode enable = %#x\n", Ctrl.n.u3GstVirtApicModeEn);2727 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC GA log enable = %RTbool\n", Ctrl.n.u1GstLogEn);2728 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC interrupt enable = %RTbool\n", Ctrl.n.u1GstIntrEn);2729 pHlp->pfnPrintf(pHlp, " Dual PPR log enable = %#x\n", Ctrl.n.u2DualPprLogEn);2730 pHlp->pfnPrintf(pHlp, " Dual event log enable = %#x\n", Ctrl.n.u2DualEvtLogEn);2731 pHlp->pfnPrintf(pHlp, " Device table segmentation enable = %#x\n", Ctrl.n.u3DevTabSegEn);2732 pHlp->pfnPrintf(pHlp, " Privilege abort enable = %#x\n", Ctrl.n.u2PrivAbortEn);2733 pHlp->pfnPrintf(pHlp, " PPR auto response enable = %RTbool\n", Ctrl.n.u1PprAutoRespEn);2734 pHlp->pfnPrintf(pHlp, " MARC enable = %RTbool\n", Ctrl.n.u1MarcEn);2735 pHlp->pfnPrintf(pHlp, " Block StopMark enable = %RTbool\n", Ctrl.n.u1BlockStopMarkEn);2736 pHlp->pfnPrintf(pHlp, " PPR auto response always-on enable = %RTbool\n", Ctrl.n.u1PprAutoRespAlwaysOnEn);2737 pHlp->pfnPrintf(pHlp, " Domain IDPNE = %RTbool\n", Ctrl.n.u1DomainIDPNE);2738 pHlp->pfnPrintf(pHlp, " Enhanced PPR handling = %RTbool\n", Ctrl.n.u1EnhancedPpr);2739 pHlp->pfnPrintf(pHlp, " Host page table access/dirty bit update = %#x\n", Ctrl.n.u2HstAccDirtyBitUpdate);2740 pHlp->pfnPrintf(pHlp, " Guest page table dirty bit disable = %RTbool\n", Ctrl.n.u1GstDirtyUpdateDis);2741 pHlp->pfnPrintf(pHlp, " x2APIC enable = %RTbool\n", Ctrl.n.u1X2ApicEn);2742 pHlp->pfnPrintf(pHlp, " x2APIC interrupt enable = %RTbool\n", Ctrl.n.u1X2ApicIntrGenEn);2743 pHlp->pfnPrintf(pHlp, " Guest page table access bit update = %RTbool\n", Ctrl.n.u1GstAccessUpdateDis);2744 }2745 }2746 /* Exclusion Base Address Register. */2747 {2748 IOMMU_EXCL_RANGE_BAR_T const ExclRangeBar = pThis->ExclRangeBaseAddr;2749 pHlp->pfnPrintf(pHlp, " Exclusion BAR = %#RX64\n", ExclRangeBar.u64);2750 if (fVerbose)2751 {2752 pHlp->pfnPrintf(pHlp, " Exclusion enable = %RTbool\n", ExclRangeBar.n.u1ExclEnable);2753 pHlp->pfnPrintf(pHlp, " Allow all devices = %RTbool\n", ExclRangeBar.n.u1AllowAll);2754 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", ExclRangeBar.n.u40ExclRangeBase);2755 }2756 }2757 /* Exclusion Range Limit Register. */2758 {2759 IOMMU_EXCL_RANGE_LIMIT_T const ExclRangeLimit = pThis->ExclRangeLimit;2760 pHlp->pfnPrintf(pHlp, " Exclusion Range Limit = %#RX64\n", ExclRangeLimit.u64);2761 if (fVerbose)2762 pHlp->pfnPrintf(pHlp, " Range limit = %#RX64\n", ExclRangeLimit.n.u40ExclLimit);2763 }2764 /* Extended Feature Register. */2765 {2766 IOMMU_EXT_FEAT_T ExtFeat = pThis->ExtFeat;2767 pHlp->pfnPrintf(pHlp, " Extended Feature Register = %#RX64\n", ExtFeat.u64);2768 pHlp->pfnPrintf(pHlp, " Prefetch support = %RTbool\n", ExtFeat.n.u1PrefetchSup);2769 if (fVerbose)2770 {2771 pHlp->pfnPrintf(pHlp, " PPR support = %RTbool\n", ExtFeat.n.u1PprSup);2772 pHlp->pfnPrintf(pHlp, " x2APIC support = %RTbool\n", ExtFeat.n.u1X2ApicSup);2773 pHlp->pfnPrintf(pHlp, " NX and privilege level support = %RTbool\n", ExtFeat.n.u1NoExecuteSup);2774 pHlp->pfnPrintf(pHlp, " Guest translation support = %RTbool\n", ExtFeat.n.u1GstTranslateSup);2775 pHlp->pfnPrintf(pHlp, " Invalidate-All command support = %RTbool\n", ExtFeat.n.u1InvAllSup);2776 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC support = %RTbool\n", ExtFeat.n.u1GstVirtApicSup);2777 pHlp->pfnPrintf(pHlp, " Hardware error register support = %RTbool\n", ExtFeat.n.u1HwErrorSup);2778 pHlp->pfnPrintf(pHlp, " Performance counters support = %RTbool\n", ExtFeat.n.u1PerfCounterSup);2779 pHlp->pfnPrintf(pHlp, " Host address translation size = %#x\n", ExtFeat.n.u2HostAddrTranslateSize);2780 pHlp->pfnPrintf(pHlp, " Guest address translation size = %#x\n", ExtFeat.n.u2GstAddrTranslateSize);2781 pHlp->pfnPrintf(pHlp, " Guest CR3 root table level support = %#x\n", ExtFeat.n.u2GstCr3RootTblLevel);2782 pHlp->pfnPrintf(pHlp, " SMI filter register support = %#x\n", ExtFeat.n.u2SmiFilterSup);2783 pHlp->pfnPrintf(pHlp, " SMI filter register count = %#x\n", ExtFeat.n.u3SmiFilterCount);2784 pHlp->pfnPrintf(pHlp, " Guest virtual-APIC modes support = %#x\n", ExtFeat.n.u3GstVirtApicModeSup);2785 pHlp->pfnPrintf(pHlp, " Dual PPR log support = %#x\n", ExtFeat.n.u2DualPprLogSup);2786 pHlp->pfnPrintf(pHlp, " Dual event log support = %#x\n", ExtFeat.n.u2DualEvtLogSup);2787 pHlp->pfnPrintf(pHlp, " Maximum PASID = %#x\n", ExtFeat.n.u5MaxPasidSup);2788 pHlp->pfnPrintf(pHlp, " User/supervisor page protection support = %RTbool\n", ExtFeat.n.u1UserSupervisorSup);2789 pHlp->pfnPrintf(pHlp, " Device table segments supported = %u\n", (ExtFeat.n.u2DevTabSegSup << 1));2790 pHlp->pfnPrintf(pHlp, " PPR log overflow early warning support = %RTbool\n", ExtFeat.n.u1PprLogOverflowWarn);2791 pHlp->pfnPrintf(pHlp, " PPR auto response support = %RTbool\n", ExtFeat.n.u1PprAutoRespSup);2792 pHlp->pfnPrintf(pHlp, " MARC support = %#x\n", ExtFeat.n.u2MarcSup);2793 pHlp->pfnPrintf(pHlp, " Block StopMark message support = %RTbool\n", ExtFeat.n.u1BlockStopMarkSup);2794 pHlp->pfnPrintf(pHlp, " Performance optimization support = %RTbool\n", ExtFeat.n.u1PerfOptSup);2795 pHlp->pfnPrintf(pHlp, " MSI capability MMIO access support = %RTbool\n", ExtFeat.n.u1MsiCapMmioSup);2796 pHlp->pfnPrintf(pHlp, " Guest I/O protection support = %RTbool\n", ExtFeat.n.u1GstIoSup);2797 pHlp->pfnPrintf(pHlp, " Host access support = %RTbool\n", ExtFeat.n.u1HostAccessSup);2798 pHlp->pfnPrintf(pHlp, " Enhanced PPR handling support = %RTbool\n", ExtFeat.n.u1EnhancedPprSup);2799 pHlp->pfnPrintf(pHlp, " Attribute forward supported = %RTbool\n", ExtFeat.n.u1AttrForwardSup);2800 pHlp->pfnPrintf(pHlp, " Host dirty support = %RTbool\n", ExtFeat.n.u1HostDirtySup);2801 pHlp->pfnPrintf(pHlp, " Invalidate IOTLB type support = %RTbool\n", ExtFeat.n.u1InvIoTlbTypeSup);2802 pHlp->pfnPrintf(pHlp, " Guest page table access bit hw disable = %RTbool\n", ExtFeat.n.u1GstUpdateDisSup);2803 pHlp->pfnPrintf(pHlp, " Force physical dest for remapped intr. = %RTbool\n", ExtFeat.n.u1ForcePhysDstSup);2804 }2805 }2806 /* PPR Log Base Address Register. */2807 {2808 PPR_LOG_BAR_T PprLogBar = pThis->PprLogBaseAddr;2809 uint32_t cEntries;2810 uint32_t cbBuffer;2811 uint8_t const uEncodedLen = PprLogBar.n.u4PprLogLen;2812 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2813 pHlp->pfnPrintf(pHlp, " PPR Log BAR = %#RX64\n", PprLogBar.u64);2814 if (fVerbose)2815 {2816 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", PprLogBar.n.u40PprLogBase);2817 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen,2818 cEntries, cbBuffer);2819 }2820 }2821 /* Hardware Event (Hi) Register. */2822 {2823 IOMMU_HW_EVT_HI_T HwEvtHi = pThis->HwEvtHi;2824 pHlp->pfnPrintf(pHlp, " Hardware Event (Hi) = %#RX64\n", HwEvtHi.u64);2825 if (fVerbose)2826 {2827 pHlp->pfnPrintf(pHlp, " First operand = %#RX64\n", HwEvtHi.n.u60FirstOperand);2828 pHlp->pfnPrintf(pHlp, " Event code = %#RX8\n", HwEvtHi.n.u4EvtCode);2829 }2830 }2831 /* Hardware Event (Lo) Register. */2832 pHlp->pfnPrintf(pHlp, " Hardware Event (Lo) = %#RX64\n", pThis->HwEvtLo);2833 /* Hardware Event Status. */2834 {2835 IOMMU_HW_EVT_STATUS_T HwEvtStatus = pThis->HwEvtStatus;2836 pHlp->pfnPrintf(pHlp, " Hardware Event Status = %#RX64\n", HwEvtStatus.u64);2837 if (fVerbose)2838 {2839 pHlp->pfnPrintf(pHlp, " Valid = %RTbool\n", HwEvtStatus.n.u1Valid);2840 pHlp->pfnPrintf(pHlp, " Overflow = %RTbool\n", HwEvtStatus.n.u1Overflow);2841 }2842 }2843 /* Guest Virtual-APIC Log Base Address Register. */2844 {2845 GALOG_BAR_T const GALogBar = pThis->GALogBaseAddr;2846 uint32_t cEntries;2847 uint32_t cbBuffer;2848 uint8_t const uEncodedLen = GALogBar.n.u4GALogLen;2849 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2850 pHlp->pfnPrintf(pHlp, " Guest Log BAR = %#RX64\n", GALogBar.u64);2851 if (fVerbose)2852 {2853 pHlp->pfnPrintf(pHlp, " Base address = %RTbool\n", GALogBar.n.u40GALogBase);2854 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen,2855 cEntries, cbBuffer);2856 }2857 }2858 /* Guest Virtual-APIC Log Tail Address Register. */2859 {2860 GALOG_TAIL_ADDR_T GALogTail = pThis->GALogTailAddr;2861 pHlp->pfnPrintf(pHlp, " Guest Log Tail Address = %#RX64\n", GALogTail.u64);2862 if (fVerbose)2863 pHlp->pfnPrintf(pHlp, " Tail address = %#RX64\n", GALogTail.n.u40GALogTailAddr);2864 }2865 /* PPR Log B Base Address Register. */2866 {2867 PPR_LOG_B_BAR_T PprLogBBar = pThis->PprLogBBaseAddr;2868 uint32_t cEntries;2869 uint32_t cbBuffer;2870 uint8_t const uEncodedLen = PprLogBBar.n.u4PprLogLen;2871 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2872 pHlp->pfnPrintf(pHlp, " PPR Log B BAR = %#RX64\n", PprLogBBar.u64);2873 if (fVerbose)2874 {2875 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", PprLogBBar.n.u40PprLogBase);2876 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen,2877 cEntries, cbBuffer);2878 }2879 }2880 /* Event Log B Base Address Register. */2881 {2882 EVT_LOG_B_BAR_T EvtLogBBar = pThis->EvtLogBBaseAddr;2883 uint32_t cEntries;2884 uint32_t cbBuffer;2885 uint8_t const uEncodedLen = EvtLogBBar.n.u4EvtLen;2886 iommuAmdDecodeBufferLength(uEncodedLen, &cEntries, &cbBuffer);2887 pHlp->pfnPrintf(pHlp, " Event Log B BAR = %#RX64\n", EvtLogBBar.u64);2888 if (fVerbose)2889 {2890 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", EvtLogBBar.n.u40EvtBase);2891 pHlp->pfnPrintf(pHlp, " Length = %u (%u entries, %u bytes)\n", uEncodedLen,2892 cEntries, cbBuffer);2893 }2894 }2895 /* Device Table Segment Registers. */2896 for (unsigned i = 0; i < RT_ELEMENTS(pThis->DevTabSeg); i++)2897 {2898 DEV_TAB_SEG_BAR_T const DevTabSeg = pThis->DevTabSeg[i];2899 pHlp->pfnPrintf(pHlp, " Device Table Segment BAR [%u] = %#RX64\n", DevTabSeg.u64);2900 if (fVerbose)2901 {2902 pHlp->pfnPrintf(pHlp, " Base address = %#RX64\n", DevTabSeg.n.u40DevTabBase);2903 pHlp->pfnPrintf(pHlp, " Size = %#x (%u bytes)\n", DevTabSeg.n.u8Size,2904 (DevTabSeg.n.u8Size + 1) << X86_PAGE_4K_SHIFT);2905 }2906 }2907 /* Device-Specific Feature Extension Register. */2908 {2909 DEV_SPECIFIC_FEAT_T const DevSpecificFeat = pThis->DevSpecificFeat;2910 pHlp->pfnPrintf(pHlp, " Device-specific Feature = %#RX64\n", DevSpecificFeat.u64);2911 if (fVerbose)2912 {2913 pHlp->pfnPrintf(pHlp, " Feature = %#RX32\n", DevSpecificFeat.n.u24DevSpecFeat);2914 pHlp->pfnPrintf(pHlp, " Minor revision ID = %#x\n", DevSpecificFeat.n.u4RevMinor);2915 pHlp->pfnPrintf(pHlp, " Major revision ID = %#x\n", DevSpecificFeat.n.u4RevMajor);2916 }2917 }2918 /* Device-Specific Control Extension Register. */2919 {2920 DEV_SPECIFIC_CTRL_T const DevSpecificCtrl = pThis->DevSpecificCtrl;2921 pHlp->pfnPrintf(pHlp, " Device-specific Control = %#RX64\n", DevSpecificCtrl.u64);2922 if (fVerbose)2923 {2924 pHlp->pfnPrintf(pHlp, " Control = %#RX32\n", DevSpecificCtrl.n.u24DevSpecCtrl);2925 pHlp->pfnPrintf(pHlp, " Minor revision ID = %#x\n", DevSpecificCtrl.n.u4RevMinor);2926 pHlp->pfnPrintf(pHlp, " Major revision ID = %#x\n", DevSpecificCtrl.n.u4RevMajor);2927 }2928 }2929 /* Device-Specific Status Extension Register. */2930 {2931 DEV_SPECIFIC_STATUS_T const DevSpecificStatus = pThis->DevSpecificStatus;2932 pHlp->pfnPrintf(pHlp, " Device-specific Control = %#RX64\n", DevSpecificStatus.u64);2933 if (fVerbose)2934 {2935 pHlp->pfnPrintf(pHlp, " Status = %#RX32\n", DevSpecificStatus.n.u24DevSpecStatus);2936 pHlp->pfnPrintf(pHlp, " Minor revision ID = %#x\n", DevSpecificStatus.n.u4RevMinor);2937 pHlp->pfnPrintf(pHlp, " Major revision ID = %#x\n", DevSpecificStatus.n.u4RevMajor);2938 }2939 }2940 /* MSI Miscellaneous Information Register (Lo and Hi). */2941 {2942 MSI_MISC_INFO_T const MsiMiscInfo = pThis->MsiMiscInfo;2943 pHlp->pfnPrintf(pHlp, " MSI Misc. Info. Register = %#RX64\n", MsiMiscInfo.u64);2944 if (fVerbose)2945 {2946 pHlp->pfnPrintf(pHlp, " Event Log MSI number = %#x\n", MsiMiscInfo.n.u5MsiNumEvtLog);2947 pHlp->pfnPrintf(pHlp, " Guest Virtual-Address Size = %#x\n", MsiMiscInfo.n.u3GstVirtAddrSize);2948 pHlp->pfnPrintf(pHlp, " Physical Address Size = %#x\n", MsiMiscInfo.n.u7PhysAddrSize);2949 pHlp->pfnPrintf(pHlp, " Virtual-Address Size = %#x\n", MsiMiscInfo.n.u7VirtAddrSize);2950 pHlp->pfnPrintf(pHlp, " HT Transport ATS Range Reserved = %RTbool\n", MsiMiscInfo.n.u1HtAtsResv);2951 pHlp->pfnPrintf(pHlp, " PPR MSI number = %#x\n", MsiMiscInfo.n.u5MsiNumPpr);2952 pHlp->pfnPrintf(pHlp, " GA Log MSI number = %#x\n", MsiMiscInfo.n.u5MsiNumGa);2953 }2954 }2955 /* MSI Capability Header. */2956 {2957 MSI_CAP_HDR_T const MsiCapHdr = pThis->MsiCapHdr;2958 pHlp->pfnPrintf(pHlp, " MSI Capability Header = %#RX32\n", MsiCapHdr.u32);2959 if (fVerbose)2960 {2961 pHlp->pfnPrintf(pHlp, " Capability ID = %#x\n", MsiCapHdr.n.u8MsiCapId);2962 pHlp->pfnPrintf(pHlp, " Capability Ptr (PCI config offset) = %#x\n", MsiCapHdr.n.u8MsiCapPtr);2963 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", MsiCapHdr.n.u1MsiEnable);2964 pHlp->pfnPrintf(pHlp, " Multi-message capability = %#x\n", MsiCapHdr.n.u3MsiMultiMessCap);2965 pHlp->pfnPrintf(pHlp, " Multi-message enable = %#x\n", MsiCapHdr.n.u3MsiMultiMessEn);2966 }2967 }2968 /* MSI Address Register (Lo and Hi). */2969 {2970 MSI_ADDR_T const MsiAddr = pThis->MsiAddr;2971 pHlp->pfnPrintf(pHlp, " MSI Address = %#RX64\n", MsiAddr.u64);2972 if (fVerbose)2973 pHlp->pfnPrintf(pHlp, " Address = %#RX64\n", MsiAddr.n.u62MsiAddr);2974 }2975 /* MSI Data. */2976 {2977 MSI_DATA_T const MsiData = pThis->MsiData;2978 pHlp->pfnPrintf(pHlp, " MSI Data = %#RX32\n", MsiData.u32);2979 if (fVerbose)2980 pHlp->pfnPrintf(pHlp, " Data = %#x\n", MsiData.n.u16MsiData);2981 }2982 /* MSI Mapping Capability Header. */2983 {2984 MSI_MAP_CAP_HDR_T const MsiMapCapHdr = pThis->MsiMapCapHdr;2985 pHlp->pfnPrintf(pHlp, " MSI Mapping Capability Header = %#RX32\n", MsiMapCapHdr.u32);2986 if (fVerbose)2987 {2988 pHlp->pfnPrintf(pHlp, " Capability ID = %#x\n", MsiMapCapHdr.n.u8MsiMapCapId);2989 pHlp->pfnPrintf(pHlp, " Map enable = %RTbool\n", MsiMapCapHdr.n.u1MsiMapEn);2990 pHlp->pfnPrintf(pHlp, " Map fixed = %RTbool\n", MsiMapCapHdr.n.u1MsiMapFixed);2991 pHlp->pfnPrintf(pHlp, " Map capability type = %#x\n", MsiMapCapHdr.n.u5MapCapType);2992 }2993 }2994 /* Performance Optimization Control Register. */2995 {2996 IOMMU_PERF_OPT_CTRL_T const PerfOptCtrl = pThis->PerfOptCtrl;2997 pHlp->pfnPrintf(pHlp, " Performance Optimization Control = %#RX32\n", PerfOptCtrl.u32);2998 if (fVerbose)2999 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", PerfOptCtrl.n.u1PerfOptEn);3000 }3001 /* XT (x2APIC) General Interrupt Control Register. */3002 {3003 IOMMU_XT_GEN_INTR_CTRL_T const XtGenIntrCtrl = pThis->XtGenIntrCtrl;3004 pHlp->pfnPrintf(pHlp, " XT General Interrupt Control = %#RX64\n", XtGenIntrCtrl.u64);3005 if (fVerbose)3006 {3007 pHlp->pfnPrintf(pHlp, " Interrupt destination mode = %s\n",3008 !XtGenIntrCtrl.n.u1X2ApicIntrDstMode ? "physical" : "logical");3009 pHlp->pfnPrintf(pHlp, " Interrupt destination = %#RX64\n",3010 RT_MAKE_U64(XtGenIntrCtrl.n.u24X2ApicIntrDstLo, XtGenIntrCtrl.n.u7X2ApicIntrDstHi));3011 pHlp->pfnPrintf(pHlp, " Interrupt vector = %#x\n", XtGenIntrCtrl.n.u8X2ApicIntrVector);3012 pHlp->pfnPrintf(pHlp, " Interrupt delivery mode = %#x\n",3013 !XtGenIntrCtrl.n.u8X2ApicIntrVector ? "fixed" : "arbitrated");3014 }3015 }3016 /* XT (x2APIC) PPR Interrupt Control Register. */3017 {3018 IOMMU_XT_PPR_INTR_CTRL_T const XtPprIntrCtrl = pThis->XtPprIntrCtrl;3019 pHlp->pfnPrintf(pHlp, " XT PPR Interrupt Control = %#RX64\n", XtPprIntrCtrl.u64);3020 if (fVerbose)3021 {3022 pHlp->pfnPrintf(pHlp, " Interrupt destination mode = %s\n",3023 !XtPprIntrCtrl.n.u1X2ApicIntrDstMode ? "physical" : "logical");3024 pHlp->pfnPrintf(pHlp, " Interrupt destination = %#RX64\n",3025 RT_MAKE_U64(XtPprIntrCtrl.n.u24X2ApicIntrDstLo, XtPprIntrCtrl.n.u7X2ApicIntrDstHi));3026 pHlp->pfnPrintf(pHlp, " Interrupt vector = %#x\n", XtPprIntrCtrl.n.u8X2ApicIntrVector);3027 pHlp->pfnPrintf(pHlp, " Interrupt delivery mode = %#x\n",3028 !XtPprIntrCtrl.n.u8X2ApicIntrVector ? "fixed" : "arbitrated");3029 }3030 }3031 /* XT (X2APIC) GA Log Interrupt Control Register. */3032 {3033 IOMMU_XT_GALOG_INTR_CTRL_T const XtGALogIntrCtrl = pThis->XtGALogIntrCtrl;3034 pHlp->pfnPrintf(pHlp, " XT PPR Interrupt Control = %#RX64\n", XtGALogIntrCtrl.u64);3035 if (fVerbose)3036 {3037 pHlp->pfnPrintf(pHlp, " Interrupt destination mode = %s\n",3038 !XtGALogIntrCtrl.n.u1X2ApicIntrDstMode ? "physical" : "logical");3039 pHlp->pfnPrintf(pHlp, " Interrupt destination = %#RX64\n",3040 RT_MAKE_U64(XtGALogIntrCtrl.n.u24X2ApicIntrDstLo, XtGALogIntrCtrl.n.u7X2ApicIntrDstHi));3041 pHlp->pfnPrintf(pHlp, " Interrupt vector = %#x\n", XtGALogIntrCtrl.n.u8X2ApicIntrVector);3042 pHlp->pfnPrintf(pHlp, " Interrupt delivery mode = %#x\n",3043 !XtGALogIntrCtrl.n.u8X2ApicIntrVector ? "fixed" : "arbitrated");3044 }3045 }3046 /* MARC Registers. */3047 {3048 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aMarcApers); i++)3049 {3050 pHlp->pfnPrintf(pHlp, " MARC Aperature %u:\n", i);3051 MARC_APER_BAR_T const MarcAperBar = pThis->aMarcApers[i].Base;3052 pHlp->pfnPrintf(pHlp, " Base = %#RX64 (addr: %#RX64)\n", MarcAperBar.u64, MarcAperBar.n.u40MarcBaseAddr);3053 3054 MARC_APER_RELOC_T const MarcAperReloc = pThis->aMarcApers[i].Reloc;3055 pHlp->pfnPrintf(pHlp, " Reloc = %#RX64 (addr: %#RX64, read-only: %RTbool, enable: %RTbool)\n",3056 MarcAperReloc.u64, MarcAperReloc.n.u40MarcRelocAddr, MarcAperReloc.n.u1ReadOnly,3057 MarcAperReloc.n.u1RelocEn);3058 3059 MARC_APER_LEN_T const MarcAperLen = pThis->aMarcApers[i].Length;3060 pHlp->pfnPrintf(pHlp, " Length = %u pages\n", MarcAperLen.n.u40MarcLength);3061 }3062 }3063 /* Reserved Register. */3064 pHlp->pfnPrintf(pHlp, " Reserved Register = %#RX64\n", pThis->RsvdReg);3065 /* Command Buffer Head Pointer Register. */3066 {3067 CMD_BUF_HEAD_PTR_T const CmdBufHeadPtr = pThis->CmdBufHeadPtr;3068 pHlp->pfnPrintf(pHlp, " Command Buffer Head Pointer = %#RX64\n", CmdBufHeadPtr.u64);3069 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufHeadPtr.n.u15Ptr);3070 }3071 /* Command Buffer Tail Pointer Register. */3072 {3073 CMD_BUF_HEAD_PTR_T const CmdBufTailPtr = pThis->CmdBufTailPtr;3074 pHlp->pfnPrintf(pHlp, " Command Buffer Tail Pointer = %#RX64\n", CmdBufTailPtr.u64);3075 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufTailPtr.n.u15Ptr);3076 }3077 /* Event Log Head Pointer Register. */3078 {3079 EVT_LOG_HEAD_PTR_T const EvtLogHeadPtr = pThis->EvtLogHeadPtr;3080 pHlp->pfnPrintf(pHlp, " Event Log Head Pointer = %#RX64\n", EvtLogHeadPtr.u64);3081 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogHeadPtr.n.u15Ptr);3082 }3083 /* Event Log Tail Pointer Register. */3084 {3085 EVT_LOG_TAIL_PTR_T const EvtLogTailPtr = pThis->EvtLogTailPtr;3086 pHlp->pfnPrintf(pHlp, " Event Log Head Pointer = %#RX64\n", EvtLogTailPtr.u64);3087 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogTailPtr.n.u15Ptr);3088 }3089 /* Status Register. */3090 {3091 IOMMU_STATUS_T const Status = pThis->Status;3092 pHlp->pfnPrintf(pHlp, " Status Register = %#RX64\n", Status.u64);3093 if (fVerbose)3094 {3095 pHlp->pfnPrintf(pHlp, " Event log overflow = %RTbool\n", Status.n.u1EvtOverflow);3096 pHlp->pfnPrintf(pHlp, " Event log interrupt = %RTbool\n", Status.n.u1EvtLogIntr);3097 pHlp->pfnPrintf(pHlp, " Completion wait interrupt = %RTbool\n", Status.n.u1CompWaitIntr);3098 pHlp->pfnPrintf(pHlp, " Event log running = %RTbool\n", Status.n.u1EvtLogRunning);3099 pHlp->pfnPrintf(pHlp, " Command buffer running = %RTbool\n", Status.n.u1CmdBufRunning);3100 pHlp->pfnPrintf(pHlp, " PPR overflow = %RTbool\n", Status.n.u1PprOverflow);3101 pHlp->pfnPrintf(pHlp, " PPR interrupt = %RTbool\n", Status.n.u1PprIntr);3102 pHlp->pfnPrintf(pHlp, " PPR log running = %RTbool\n", Status.n.u1PprLogRunning);3103 pHlp->pfnPrintf(pHlp, " Guest log running = %RTbool\n", Status.n.u1GstLogRunning);3104 pHlp->pfnPrintf(pHlp, " Guest log interrupt = %RTbool\n", Status.n.u1GstLogIntr);3105 pHlp->pfnPrintf(pHlp, " PPR log B overflow = %RTbool\n", Status.n.u1PprOverflowB);3106 pHlp->pfnPrintf(pHlp, " PPR log active = %RTbool\n", Status.n.u1PprLogActive);3107 pHlp->pfnPrintf(pHlp, " Event log B overflow = %RTbool\n", Status.n.u1EvtOverflowB);3108 pHlp->pfnPrintf(pHlp, " Event log active = %RTbool\n", Status.n.u1EvtLogActive);3109 pHlp->pfnPrintf(pHlp, " PPR log B overflow early warning = %RTbool\n", Status.n.u1PprOverflowEarlyB);3110 pHlp->pfnPrintf(pHlp, " PPR log overflow early warning = %RTbool\n", Status.n.u1PprOverflowEarly);3111 }3112 }3113 /* PPR Log Head Pointer. */3114 {3115 PPR_LOG_HEAD_PTR_T const PprLogHeadPtr = pThis->PprLogHeadPtr;3116 pHlp->pfnPrintf(pHlp, " PPR Log Head Pointer = %#RX64\n", PprLogHeadPtr.u64);3117 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogHeadPtr.n.u15Ptr);3118 }3119 /* PPR Log Tail Pointer. */3120 {3121 PPR_LOG_TAIL_PTR_T const PprLogTailPtr = pThis->PprLogTailPtr;3122 pHlp->pfnPrintf(pHlp, " PPR Log Tail Pointer = %#RX64\n", PprLogTailPtr.u64);3123 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogTailPtr.n.u15Ptr);3124 }3125 /* Guest Virtual-APIC Log Head Pointer. */3126 {3127 GALOG_HEAD_PTR_T const GALogHeadPtr = pThis->GALogHeadPtr;3128 pHlp->pfnPrintf(pHlp, " Guest Virtual-APIC Log Head Pointer = %#RX64\n", GALogHeadPtr.u64);3129 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", GALogHeadPtr.n.u12GALogPtr);3130 }3131 /* Guest Virtual-APIC Log Tail Pointer. */3132 {3133 GALOG_HEAD_PTR_T const GALogTailPtr = pThis->GALogTailPtr;3134 pHlp->pfnPrintf(pHlp, " Guest Virtual-APIC Log Tail Pointer = %#RX64\n", GALogTailPtr.u64);3135 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", GALogTailPtr.n.u12GALogPtr);3136 }3137 /* PPR Log B Head Pointer. */3138 {3139 PPR_LOG_B_HEAD_PTR_T const PprLogBHeadPtr = pThis->PprLogBHeadPtr;3140 pHlp->pfnPrintf(pHlp, " PPR Log B Head Pointer = %#RX64\n", PprLogBHeadPtr.u64);3141 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBHeadPtr.n.u15Ptr);3142 }3143 /* PPR Log B Tail Pointer. */3144 {3145 PPR_LOG_B_TAIL_PTR_T const PprLogBTailPtr = pThis->PprLogBTailPtr;3146 pHlp->pfnPrintf(pHlp, " PPR Log B Tail Pointer = %#RX64\n", PprLogBTailPtr.u64);3147 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBTailPtr.n.u15Ptr);3148 }3149 /* Event Log B Head Pointer. */3150 {3151 EVT_LOG_B_HEAD_PTR_T const EvtLogBHeadPtr = pThis->EvtLogBHeadPtr;3152 pHlp->pfnPrintf(pHlp, " Event Log B Head Pointer = %#RX64\n", EvtLogBHeadPtr.u64);3153 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBHeadPtr.n.u15Ptr);3154 }3155 /* Event Log B Tail Pointer. */3156 {3157 EVT_LOG_B_TAIL_PTR_T const EvtLogBTailPtr = pThis->EvtLogBTailPtr;3158 pHlp->pfnPrintf(pHlp, " Event Log B Tail Pointer = %#RX64\n", EvtLogBTailPtr.u64);3159 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBTailPtr.n.u15Ptr);3160 }3161 /* PPR Log Auto Response Register. */3162 {3163 PPR_LOG_AUTO_RESP_T const PprLogAutoResp = pThis->PprLogAutoResp;3164 pHlp->pfnPrintf(pHlp, " PPR Log Auto Response Register = %#RX64\n", PprLogAutoResp.u64);3165 if (fVerbose)3166 {3167 pHlp->pfnPrintf(pHlp, " Code = %#x\n", PprLogAutoResp.n.u4AutoRespCode);3168 pHlp->pfnPrintf(pHlp, " Mask Gen. = %RTbool\n", PprLogAutoResp.n.u1AutoRespMaskGen);3169 }3170 }3171 /* PPR Log Overflow Early Warning Indicator Register. */3172 {3173 PPR_LOG_OVERFLOW_EARLY_T const PprLogOverflowEarly = pThis->PprLogOverflowEarly;3174 pHlp->pfnPrintf(pHlp, " PPR Log overflow early warning = %#RX64\n", PprLogOverflowEarly.u64);3175 if (fVerbose)3176 {3177 pHlp->pfnPrintf(pHlp, " Threshold = %#x\n", PprLogOverflowEarly.n.u15Threshold);3178 pHlp->pfnPrintf(pHlp, " Interrupt enable = %RTbool\n", PprLogOverflowEarly.n.u1IntrEn);3179 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", PprLogOverflowEarly.n.u1Enable);3180 }3181 }3182 /* PPR Log Overflow Early Warning Indicator Register. */3183 {3184 PPR_LOG_OVERFLOW_EARLY_T const PprLogBOverflowEarly = pThis->PprLogBOverflowEarly;3185 pHlp->pfnPrintf(pHlp, " PPR Log B overflow early warning = %#RX64\n", PprLogBOverflowEarly.u64);3186 if (fVerbose)3187 {3188 pHlp->pfnPrintf(pHlp, " Threshold = %#x\n", PprLogBOverflowEarly.n.u15Threshold);3189 pHlp->pfnPrintf(pHlp, " Interrupt enable = %RTbool\n", PprLogBOverflowEarly.n.u1IntrEn);3190 pHlp->pfnPrintf(pHlp, " Enable = %RTbool\n", PprLogBOverflowEarly.n.u1Enable);3191 }3192 }3193 }3194 3195 3196 /**3197 * @callback_method_impl{FNSSMDEVSAVEEXEC}3198 */3199 static DECLCALLBACK(int) iommuAmdR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)3200 {3201 /** @todo IOMMU: Save state. */3202 RT_NOREF2(pDevIns, pSSM);3203 return VERR_NOT_IMPLEMENTED;3204 }3205 3206 3207 /**3208 * @callback_method_impl{FNSSMDEVLOADEXEC}3209 */3210 static DECLCALLBACK(int) iommuAmdR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)3211 {3212 /** @todo IOMMU: Load state. */3213 RT_NOREF4(pDevIns, pSSM, uVersion, uPass);3214 return VERR_NOT_IMPLEMENTED;3215 }3216 3217 3218 /**3219 * @interface_method_impl{PDMDEVREG,pfnReset}3220 */3221 static DECLCALLBACK(void) iommuAmdR3Reset(PPDMDEVINS pDevIns)3222 {3223 iommuAmdR3Init(pDevIns);3224 }3225 3226 3227 /**3228 3334 * @interface_method_impl{PDMDEVREG,pfnDestruct} 3229 3335 */ … … 3358 3464 3359 3465 /* 3360 * Initialize parts of the IOMMU state as it would during reset.3361 * Must be called -after- initializing PCI config. space registers.3362 */3363 iommuAmdR3Init(pDevIns);3364 3365 /*3366 3466 * Register the PCI function with PDM. 3367 3467 */ … … 3373 3473 */ 3374 3474 rc = PDMDevHlpPCIInterceptConfigAccesses(pDevIns, pPciDev, iommuAmdR3PciConfigRead, iommuAmdR3PciConfigWrite); 3375 Assert RCReturn(rc, rc);3475 AssertLogRelRCReturn(rc, rc); 3376 3476 3377 3477 /* … … 3381 3481 NULL /* pvUser */, IOMMMIO_FLAGS_READ_DWORD_QWORD | IOMMMIO_FLAGS_WRITE_DWORD_QWORD_ZEROED, 3382 3482 "AMD-IOMMU", &pThis->hMmio); 3383 Assert RCReturn(rc, rc);3483 AssertLogRelRCReturn(rc, rc); 3384 3484 3385 3485 /* … … 3390 3490 NULL, iommuAmdR3SaveExec, NULL, 3391 3491 NULL, iommuAmdR3LoadExec, NULL); 3392 Assert RCReturn(rc, rc);3492 AssertLogRelRCReturn(rc, rc); 3393 3493 3394 3494 /* … … 3396 3496 */ 3397 3497 rc = PDMDevHlpDBGFInfoRegister(pDevIns, "iommu", "Display IOMMU state.", iommuAmdR3DbgInfo); 3398 AssertRCReturn(rc, rc); 3498 AssertLogRelRCReturn(rc, rc); 3499 3500 /* 3501 * Create the command thread and its event semaphore. 3502 */ 3503 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->pCmdThread, pThis, iommuAmdR3CmdThread, iommuAmdR3CmdThreadWakeUp, 3504 0 /* cbStack */, RTTHREADTYPE_IO, "AMD-IOMMU"); 3505 AssertLogRelRCReturn(rc, rc); 3506 3507 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->hEvtCmdThread); 3508 AssertLogRelRCReturn(rc, rc); 3509 3510 /* 3511 * Initialize parts of the IOMMU state as it would during reset. 3512 * Must be called -after- initializing PCI config. space registers. 3513 */ 3514 iommuAmdR3Reset(pDevIns); 3399 3515 3400 3516 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.