Changeset 84651 in vbox
- Timestamp:
- Jun 3, 2020 8:30:21 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
include/VBox/msi.h (modified) (1 diff)
-
src/VBox/Devices/Bus/DevIommuAmd.cpp (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/msi.h
r84515 r84651 135 135 /** @} */ 136 136 137 /** 138 * MSI Address Register. 139 * In accordance to the Intel spec. 140 * See Intel spec. 10.11.1 "Message Address Register Format". 141 * 142 * This also conforms to the AMD IOMMU spec. which omits specifying individual 143 * fields but specifies reserved bits. 144 */ 145 typedef union 146 { 147 struct 148 { 149 uint32_t u2Ign0 : 2; /**< Bits 1:0 - Ignored (read as 0, writes ignored). */ 150 uint32_t u1DestMode : 1; /**< Bit 2 - DM: Destination Mode. */ 151 uint32_t u1RedirHint : 1; /**< Bit 3 - RH: Redirection Hint. */ 152 uint32_t u8Rsvd0 : 8; /**< Bits 11:4 - Reserved. */ 153 uint32_t u8DestId : 8; /**< Bits 19:12 - Destination Id. */ 154 uint32_t u12Addr : 12; /**< Bits 31:20 - Address. */ 155 uint32_t u32Rsvd0; /**< Bits 63:32 - Reserved. */ 156 } n; 157 /** The 32-bit unsigned integer view. */ 158 uint32_t au32[2]; 159 /** The 64-bit unsigned integer view. */ 160 uint64_t u64; 161 } MSIADDR; 162 AssertCompileSize(MSIADDR, 8); 163 /** Pointer to an MSI address register. */ 164 typedef MSIADDR *PMSIADDR; 165 /** Pointer to a const MSI address register. */ 166 typedef MSIADDR const *PCMSIADDR; 167 168 /** Mask of valid bits in the MSI address register. According to the AMD IOMMU spec. 169 * and presumably the PCI spec., the top 32-bits are not reserved. From a PCI/IOMMU 170 * standpoint this makes sense. However, when dealing with the CPU side of things 171 * we might want to ensure the upper bits are reserved. Does x86/x64 really 172 * support a 64-bit MSI address? */ 173 #define VBOX_MSI_ADDR_VALID_MASK UINT64_C(0xfffffffffffffffc) 174 #define VBOX_MSI_ADDR_ADDR_MASK UINT64_C(0x00000000fff00000) 175 176 /** 177 * MSI Data Register (PCI + MMIO). 178 * In accordance to the Intel spec. 179 * See Intel spec. 10.11.2 "Message Data Register Format". 180 * 181 * This also conforms to the AMD IOMMU spec. which omits specifying individual 182 * fields but specifies reserved bits. 183 */ 184 typedef union 185 { 186 struct 187 { 188 uint32_t u8Vector : 8; /**< Bits 7:0 - Vector. */ 189 uint32_t u3DeliveryMode : 3; /**< Bits 10:8 - Delivery Mode. */ 190 uint32_t u3Rsvd0 : 3; /**< Bits 13:11 - Reserved. */ 191 uint32_t u1Level : 1; /**< Bit 14 - Level. */ 192 uint32_t u1TriggerMode : 1; /**< Bit 15 - Trigger Mode (0=edge, 1=level). */ 193 uint32_t u16Rsvd0 : 16; /**< Bits 31:16 - Reserved. */ 194 } n; 195 /** The 32-bit unsigned integer view. */ 196 uint32_t u32; 197 } MSIDATA; 198 AssertCompileSize(MSIDATA, 4); 199 /** Pointer to an MSI data register. */ 200 typedef MSIDATA *PMSIDATA; 201 /** Pointer to a const MSI data register. */ 202 typedef MSIDATA const *PCMSIDATA; 203 204 /** Mask of valid bits in the MSI data register. */ 205 #define VBOX_MSI_DATA_VALID_MASK UINT64_C(0x000000000000ffff) 206 207 /** 208 * MSI Message (Address and Data Register Pair). 209 */ 210 typedef struct 211 { 212 /** The MSI Address Register. */ 213 MSIADDR MsiAddr; 214 /** The MSI Data Register. */ 215 MSIDATA MsiData; 216 } MSIMSG; 217 /** Pointer to an MSI message struct. */ 218 typedef MSIMSG *PMSIMSG; 219 /** Pointer to a const MSI message struct. */ 220 typedef MSIMSG const *PCMSIMSG; 137 221 138 222 #endif /* !VBOX_INCLUDED_msi_h */ -
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r84638 r84651 765 765 typedef IRTE_T const *PCIRTE_T; 766 766 767 /** The IRTE offset corresponds directly to bits 10:0 of the originating MSI 768 * interrupt message. See AMD IOMMU spec. 2.2.5 "Interrupt Remapping Tables". */ 769 #define IOMMU_MSI_DATA_IRTE_OFFSET_MASK UINT32_C(0x000007ff) 770 767 771 /** 768 772 * Command: Generic Command Buffer Entry. … … 1736 1740 1737 1741 /** 1738 * MSI Address Register (PCI + MMIO).1739 * In accordance to the Intel spec.1740 * See Intel spec. 10.11.1 "Message Address Register Format".1741 *1742 * This also conforms to the AMD IOMMU spec. which omits specifying individual1743 * fields but specifies reserved bits.1744 */1745 typedef union1746 {1747 struct1748 {1749 uint32_t u2Ign0 : 2; /**< Bits 1:0 - Ignored (read as 0, writes ignored). */1750 uint32_t u1DestMode : 1; /**< Bit 2 - DM: Destination Mode. */1751 uint32_t u1RedirHint : 1; /**< Bit 3 - RH: Redirection Hint. */1752 uint32_t u8Rsvd0 : 8; /**< Bits 11:4 - Reserved. */1753 uint32_t u8DestId : 8; /**< Bits 19:12 - Destination Id. */1754 uint32_t u12Addr : 12; /**< Bits 31:20 - Address. */1755 uint32_t u32Rsvd0; /**< Bits 63:32 - Reserved. */1756 } n;1757 /** The 32-bit unsigned integer view. */1758 uint32_t au32[2];1759 /** The 64-bit unsigned integer view. */1760 uint64_t u64;1761 } MSI_ADDR_T;1762 AssertCompileSize(MSI_ADDR_T, 8);1763 /** According to the AMD IOMMU spec. the top 32-bits are not reserved. From a1764 * PCI/IOMMU standpoint this makes sense. However, when dealing with the CPU side1765 * of things we might want to ensure the upper bits are reserved. Does x86/x641766 * really support a 64-bit MSI address? */1767 #define IOMMU_MSI_ADDR_VALID_MASK UINT64_C(0xfffffffffffffffc)1768 #define IOMMU_MSI_ADDR_ADDR_MASK UINT64_C(0x00000000fff00000)1769 /** Pointer to an MSI address register. */1770 typedef MSI_ADDR_T *PMSI_ADDR_T;1771 /** Pointer to a const MSI address register. */1772 typedef MSI_ADDR_T const *PCMSI_ADDR_T;1773 1774 /**1775 * MSI Data Register (PCI + MMIO).1776 * In accordance to the Intel spec.1777 * See Intel spec. 10.11.2 "Message Data Register Format".1778 *1779 * This also conforms to the AMD IOMMU spec. which omits specifying individual1780 * fields but specifies reserved bits.1781 */1782 typedef union1783 {1784 struct1785 {1786 uint32_t u8Vector : 8; /**< Bits 7:0 - Vector. */1787 uint32_t u3DeliveryMode : 3; /**< Bits 10:8 - Delivery Mode. */1788 uint32_t u3Rsvd0 : 3; /**< Bits 13:11 - Reserved. */1789 uint32_t u1Level : 1; /**< Bit 14 - Level. */1790 uint32_t u1TriggerMode : 1; /**< Bit 15 - Trigger Mode (0=edge, 1=level). */1791 uint32_t u16Rsvd0 : 16; /**< Bits 31:16 - Reserved. */1792 } n;1793 /** The 32-bit unsigned integer view. */1794 uint32_t u32;1795 } MSI_DATA_T;1796 AssertCompileSize(MSI_DATA_T, 4);1797 #define IOMMU_MSI_DATA_VALID_MASK UINT64_C(0x000000000000ffff)1798 /** The IRTE offset corresponds directly to bits 10:0 of the originating MSI1799 * interrupt message. See AMD IOMMU spec. 2.2.5 "Interrupt Remapping Tables". */1800 #define IOMMU_MSI_DATA_IRTE_OFFSET_MASK UINT32_C(0x000007ff)1801 1802 /** Pointer to an MSI data register. */1803 typedef MSI_DATA_T *PMSI_DATA_T;1804 /** Pointer to a const MSI data register. */1805 typedef MSI_DATA_T const *PCMSI_DATA_T;1806 1807 /**1808 1742 * MSI Mapping Capability Header Register (PCI + MMIO). 1809 1743 * In accordance with the AMD spec. … … 2311 2245 2312 2246 /** 2313 * MSI Message (Address and Data Register Pair).2314 */2315 typedef struct2316 {2317 /** The MSI Address Register. */2318 MSI_ADDR_T MsiAddr;2319 /** The MSI Data Register. */2320 MSI_DATA_T MsiData;2321 } MSI_MSG_T;2322 /** Pointer to an MSI message struct. */2323 typedef MSI_MSG_T *PMSI_MSG_T;2324 /** Pointer to a const MSI message struct. */2325 typedef MSI_MSG_T const *PCMSI_MSG_T;2326 2327 /**2328 2247 * The shared IOMMU device state. 2329 2248 */ … … 2983 2902 PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0]; 2984 2903 PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev); 2985 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO, u64Value & IOMMU_MSI_ADDR_VALID_MASK);2904 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO, u64Value & VBOX_MSI_ADDR_VALID_MASK); 2986 2905 return VINF_SUCCESS; 2987 2906 } … … 3010 2929 PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0]; 3011 2930 PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev); 3012 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA, u64Value & IOMMU_MSI_DATA_VALID_MASK);2931 PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA, u64Value & VBOX_MSI_DATA_VALID_MASK); 3013 2932 return VINF_SUCCESS; 3014 2933 } … … 4640 4559 IOMMUOP enmOp, PRTGCPHYS pGCPhysOut, uint32_t *puDataOut) 4641 4560 { 4561 /** @todo Replace GCPhys[Out|In], uData[Out|In] with MSIMSG. */ 4642 4562 Assert(pDte->n.u2IntrCtrl == IOMMU_INTR_CTRL_REMAP); 4643 4563 … … 4652 4572 if (Irte.n.u3IntrType < VBOX_MSI_DELIVERY_MODE_LOWEST_PRIO) 4653 4573 { 4654 MSI _ADDR_TMsiAddrIn;4574 MSIADDR MsiAddrIn; 4655 4575 MsiAddrIn.u64 = GCPhysIn; 4656 4576 4657 MSI _DATA_TMsiDataIn;4577 MSIDATA MsiDataIn; 4658 4578 MsiDataIn.u32 = uDataIn; 4659 4579 4660 PMSI _ADDR_T pMsiAddrOut = (PMSI_ADDR_T)pGCPhysOut;4661 PMSI _DATA_T pMsiDataOut = (PMSI_DATA_T)puDataOut;4580 PMSIADDR pMsiAddrOut = (PMSIADDR)pGCPhysOut; 4581 PMSIDATA pMsiDataOut = (PMSIDATA)puDataOut; 4662 4582 4663 4583 /* Preserve all bits from the source MSI address that don't map 1:1 from the IRTE. */ … … 4760 4680 * See Intel spec. 10.11.1 "Message Address Register Format". 4761 4681 */ 4762 MSI _ADDR_TMsiAddrIn;4682 MSIADDR MsiAddrIn; 4763 4683 MsiAddrIn.u64 = GCPhysIn; 4764 if ((MsiAddrIn.u64 & IOMMU_MSI_ADDR_ADDR_MASK) == VBOX_MSI_ADDR_BASE)4684 if ((MsiAddrIn.u64 & VBOX_MSI_ADDR_ADDR_MASK) == VBOX_MSI_ADDR_BASE) 4765 4685 { 4766 MSI _DATA_TMsiDataIn;4686 MSIDATA MsiDataIn; 4767 4687 MsiDataIn.u32 = uDataIn; 4768 4688 … … 5610 5530 uint32_t const uMsiAddrLo = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO); 5611 5531 uint32_t const uMsiAddrHi = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI); 5612 MSI _ADDR_TMsiAddr;5532 MSIADDR MsiAddr; 5613 5533 MsiAddr.u64 = RT_MAKE_U64(uMsiAddrLo, uMsiAddrHi); 5614 5534 pHlp->pfnPrintf(pHlp, " MSI Address = %#RX64\n", MsiAddr.u64); … … 5624 5544 /* MSI Data. */ 5625 5545 { 5626 MSI _DATA_TMsiData;5546 MSIDATA MsiData; 5627 5547 MsiData.u32 = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA); 5628 5548 pHlp->pfnPrintf(pHlp, " MSI Data = %#RX32\n", MsiData.u32);
Note:
See TracChangeset
for help on using the changeset viewer.

