Changeset 88558 in vbox
- Timestamp:
- Apr 16, 2021 7:39:31 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
include/VBox/iommu-intel.h (modified) (1 diff)
-
src/VBox/Devices/Bus/DevIommuIntel.cpp (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/iommu-intel.h
r88521 r88558 1016 1016 /** RW: Read/write mask. */ 1017 1017 #define VTD_RTADDR_REG_RW_MASK UINT64_C(0xfffffffffffffc00) 1018 1019 /** RTADDR_REG.TTM: Legacy mode. */ 1020 #define VTD_TTM_LEGACY_MODE 0 1021 /** RTADDR_REG.TTM: Scalable mode. */ 1022 #define VTD_TTM_SCALABLE_MODE 1 1023 /** RTADDR_REG.TTM: Reserved. */ 1024 #define VTD_TTM_RSVD 2 1025 /** RTADDR_REG.TTM: Abort DMA mode. */ 1026 #define VTD_TTM_ABORT_DMA_MODE 3 1018 1027 /** @} */ 1019 1028 -
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r88549 r88558 110 110 *********************************************************************************************************************************/ 111 111 /** 112 * DMAR error diagnostics. 113 * 114 * @note Members of this enum are used as array indices, so no gaps are allowed. 115 * Please update g_apsz when you add new fields to this enum. 116 */ 117 typedef enum 118 { 119 kDmarDiag_None = 0, 120 kDmarDiag_IqtReg_Qt_NotAligned, 121 /* Last member for determining array index limit. */ 122 kDmarDiag_End 123 } DMARDIAG; 124 AssertCompileSize(DMARDIAG, 4); 125 126 /** DMAR diagnostic enum description expansion. */ 127 #define DMARDIAG_DESC(a_Def, a_Desc) #a_Def " - " #a_Desc 128 129 /** DMAR diagnostics description. */ 130 static const char *const g_apszDmarDiagDesc[] = 131 { 132 DMARDIAG_DESC(kNone, "None" ), 133 DMARDIAG_DESC(kDmarDiag_IqtReg_Qt_NotAligned, "IqtReg_Qt_NotAligned") 134 /* kDmarDiag_End */ 135 }; 136 AssertCompile(RT_ELEMENTS(g_apszDmarDiagDesc) == kDmarDiag_End); 137 #undef DMARDIAG_DESC 138 139 /** 112 140 * The shared DMAR device state. 113 141 */ … … 132 160 uint8_t uVerReg; 133 161 /** Alignment. */ 134 uint8_t abPadding[7]; 162 uint8_t abPadding[3]; 163 /** Error diagnostic. */ 164 DMARDIAG enmDiag; 135 165 /** Copy of CAP_REG. */ 136 166 uint64_t fCap; … … 550 580 * @param uReg The 64-bit value to write. 551 581 */ 552 DECLINLINE(void)dmarRegWriteRaw64(PDMAR pThis, uint16_t offReg, uint64_t uReg)582 static void dmarRegWriteRaw64(PDMAR pThis, uint16_t offReg, uint64_t uReg) 553 583 { 554 584 uint8_t idxGroup; … … 566 596 * @param uReg The 32-bit value to write. 567 597 */ 568 DECLINLINE(void)dmarRegWriteRaw32(PDMAR pThis, uint16_t offReg, uint32_t uReg)598 static void dmarRegWriteRaw32(PDMAR pThis, uint16_t offReg, uint32_t uReg) 569 599 { 570 600 uint8_t idxGroup; … … 584 614 * @param pfRw1cMask Where to store the RW1C mask corresponding to this register. 585 615 */ 586 DECLINLINE(void)dmarRegReadRaw64(PCDMAR pThis, uint16_t offReg, uint64_t *puReg, uint64_t *pfRwMask, uint64_t *pfRw1cMask)616 static void dmarRegReadRaw64(PCDMAR pThis, uint16_t offReg, uint64_t *puReg, uint64_t *pfRwMask, uint64_t *pfRw1cMask) 587 617 { 588 618 uint8_t idxGroup; … … 606 636 * @param pfRw1cMask Where to store the RW1C mask corresponding to this register. 607 637 */ 608 DECLINLINE(void)dmarRegReadRaw32(PCDMAR pThis, uint16_t offReg, uint32_t *puReg, uint32_t *pfRwMask, uint32_t *pfRw1cMask)638 static void dmarRegReadRaw32(PCDMAR pThis, uint16_t offReg, uint32_t *puReg, uint32_t *pfRwMask, uint32_t *pfRw1cMask) 609 639 { 610 640 uint8_t idxGroup; … … 712 742 713 743 /** 744 * Gets the table translation mode from the RTADDR_REG. 745 * 746 * @returns The table translation mode. 747 * @param pThis The shared DMAR device state. 748 */ 749 static uint8_t dmarRtAddrRegGetTtm(PCDMAR pThis) 750 { 751 uint64_t const uRtAddrReg = dmarRegRead64(pThis, VTD_MMIO_OFF_RTADDR_REG); 752 return RT_BF_GET(uRtAddrReg, VTD_BF_RTADDR_REG_TTM); 753 } 754 755 756 /** 757 * Handles writes to CCMD_REG. 758 * 759 * @returns Strict VBox status code. 760 * @param pDevIns The IOMMU device instance. 761 * @param off The MMIO register offset. 762 * @param cb The size of the MMIO access (in bytes). 763 * @param uCcmdReg The value written to CCMD_REG. 764 */ 765 static VBOXSTRICTRC dmarCcmdRegWrite(PPDMDEVINS pDevIns, uint16_t off, uint8_t cb, uint64_t uCcmdReg) 766 { 767 /* We only care about responding to high 32-bits writes, low 32-bits are data. */ 768 if (off + cb > VTD_MMIO_OFF_CCMD_REG + 4) 769 { 770 /* Check if we need to invalidate the context-context. */ 771 bool const fIcc = RT_BF_GET(uCcmdReg, VTD_BF_CCMD_REG_ICC); 772 if (fIcc) 773 { 774 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 775 uint8_t const uMajorVersion = RT_BF_GET(pThis->uVerReg, VTD_BF_VER_REG_MAX); 776 if (uMajorVersion < 6) 777 { 778 /** @todo Verify queued-invalidation is not enabled. 779 * See Intel spec. 6.5.1 "Register-based Invalidation Interface" */ 780 781 /* Verify table translation mode is legacy. */ 782 uint8_t const fTtm = dmarRtAddrRegGetTtm(pThis); 783 if (fTtm == VTD_TTM_LEGACY_MODE) 784 { 785 /** @todo Invalidate. */ 786 return VINF_SUCCESS; 787 } 788 } 789 790 /** @todo Raise error. */ 791 } 792 } 793 return VINF_SUCCESS; 794 } 795 796 797 /** 714 798 * Handles writes to IQT_REG. 715 799 * … … 721 805 static VBOXSTRICTRC dmarIqtRegWrite(PPDMDEVINS pDevIns, uint16_t off, uint64_t uIqtReg) 722 806 { 723 /* We only care about the low 32-bits . */807 /* We only care about the low 32-bits, high 32-bits are reserved. */ 724 808 if (off == VTD_MMIO_OFF_IQT_REG) 725 809 { … … 732 816 || !(offQueueTail & 0x1f)) 733 817 { 734 /** @todo IOMMU:Figure out what to do here, like waking up worker thread or818 /** @todo Figure out what to do here, like waking up worker thread or 735 819 * something. */ 736 820 } … … 738 822 { 739 823 /* Raise invalidation queue error as queue tail not aligned to 256-bits. */ 740 /** @todo IOMMU:Raise error. */824 /** @todo Raise error. */ 741 825 } 742 826 } … … 832 916 { 833 917 rcStrict = dmarIqtRegWrite(pDevIns, offReg, uRegWritten); 918 break; 919 } 920 921 case VTD_MMIO_OFF_CCMD_REG: 922 case VTD_MMIO_OFF_CCMD_REG + 4: 923 { 924 rcStrict = dmarCcmdRegWrite(pDevIns, offReg, cb, uRegWritten); 834 925 break; 835 926 } … … 1094 1185 PDMPciDevSetSubSystemVendorId(pPciDev, DMAR_PCI_VENDOR_ID); /* Intel */ 1095 1186 1096 /** @todo VTD:Chipset spec says PCI Express Capability Id. Relevant for us? */1187 /** @todo Chipset spec says PCI Express Capability Id. Relevant for us? */ 1097 1188 PDMPciDevSetStatus(pPciDev, 0); 1098 1189 PDMPciDevSetCapabilityList(pPciDev, 0); 1099 1190 1100 /** @todo VT D: VTBAR at 0x180? */1191 /** @todo VTBAR at 0x180? */ 1101 1192 1102 1193 /* … … 1106 1197 AssertLogRelRCReturn(rc, rc); 1107 1198 1108 /** @todo VTD:Register MSI but what's the MSI capability offset? */1199 /** @todo Register MSI but what's the MSI capability offset? */ 1109 1200 #if 0 1110 1201 /*
Note:
See TracChangeset
for help on using the changeset viewer.

