VirtualBox

Changeset 84651 in vbox


Ignore:
Timestamp:
Jun 3, 2020 8:30:21 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Move MSIADDR, MSIDATA and MSIMSG from IOMMU into VBox/msi.h.
These are MSI defs in accordance with the spec. and will be shared in places outside of IOMMU (upcoming changes).

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/msi.h

    r84515 r84651  
    135135/** @} */
    136136
     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 */
     145typedef 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;
     162AssertCompileSize(MSIADDR, 8);
     163/** Pointer to an MSI address register. */
     164typedef MSIADDR *PMSIADDR;
     165/** Pointer to a const MSI address register. */
     166typedef 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 */
     184typedef 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;
     198AssertCompileSize(MSIDATA, 4);
     199/** Pointer to an MSI data register. */
     200typedef MSIDATA *PMSIDATA;
     201/** Pointer to a const MSI data register. */
     202typedef 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 */
     210typedef 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. */
     218typedef MSIMSG *PMSIMSG;
     219/** Pointer to a const MSI message struct. */
     220typedef MSIMSG const *PCMSIMSG;
    137221
    138222#endif /* !VBOX_INCLUDED_msi_h */
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r84638 r84651  
    765765typedef IRTE_T const *PCIRTE_T;
    766766
     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
    767771/**
    768772 * Command: Generic Command Buffer Entry.
     
    17361740
    17371741/**
    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 individual
    1743  * fields but specifies reserved bits.
    1744  */
    1745 typedef union
    1746 {
    1747     struct
    1748     {
    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 a
    1764  *  PCI/IOMMU standpoint this makes sense. However, when dealing with the CPU side
    1765  *  of things we might want to ensure the upper bits are reserved. Does x86/x64
    1766  *  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 individual
    1780  * fields but specifies reserved bits.
    1781  */
    1782 typedef union
    1783 {
    1784     struct
    1785     {
    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 MSI
    1799  *  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 /**
    18081742 * MSI Mapping Capability Header Register (PCI + MMIO).
    18091743 * In accordance with the AMD spec.
     
    23112245
    23122246/**
    2313  * MSI Message (Address and Data Register Pair).
    2314  */
    2315 typedef struct
    2316 {
    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 /**
    23282247 * The shared IOMMU device state.
    23292248 */
     
    29832902    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    29842903    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);
    29862905    return VINF_SUCCESS;
    29872906}
     
    30102929    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    30112930    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);
    30132932    return VINF_SUCCESS;
    30142933}
     
    46404559                             IOMMUOP enmOp, PRTGCPHYS pGCPhysOut, uint32_t *puDataOut)
    46414560{
     4561    /** @todo Replace GCPhys[Out|In], uData[Out|In] with MSIMSG. */
    46424562    Assert(pDte->n.u2IntrCtrl == IOMMU_INTR_CTRL_REMAP);
    46434563
     
    46524572                if (Irte.n.u3IntrType < VBOX_MSI_DELIVERY_MODE_LOWEST_PRIO)
    46534573                {
    4654                     MSI_ADDR_T MsiAddrIn;
     4574                    MSIADDR MsiAddrIn;
    46554575                    MsiAddrIn.u64 = GCPhysIn;
    46564576
    4657                     MSI_DATA_T MsiDataIn;
     4577                    MSIDATA MsiDataIn;
    46584578                    MsiDataIn.u32 = uDataIn;
    46594579
    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;
    46624582
    46634583                    /* Preserve all bits from the source MSI address that don't map 1:1 from the IRTE. */
     
    47604680             * See Intel spec. 10.11.1 "Message Address Register Format".
    47614681             */
    4762             MSI_ADDR_T MsiAddrIn;
     4682            MSIADDR MsiAddrIn;
    47634683            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)
    47654685            {
    4766                 MSI_DATA_T MsiDataIn;
     4686                MSIDATA MsiDataIn;
    47674687                MsiDataIn.u32 = uDataIn;
    47684688
     
    56105530        uint32_t const uMsiAddrLo = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO);
    56115531        uint32_t const uMsiAddrHi = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI);
    5612         MSI_ADDR_T MsiAddr;
     5532        MSIADDR MsiAddr;
    56135533        MsiAddr.u64 = RT_MAKE_U64(uMsiAddrLo, uMsiAddrHi);
    56145534        pHlp->pfnPrintf(pHlp, "  MSI Address                             = %#RX64\n",   MsiAddr.u64);
     
    56245544    /* MSI Data. */
    56255545    {
    5626         MSI_DATA_T MsiData;
     5546        MSIDATA MsiData;
    56275547        MsiData.u32 = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA);
    56285548        pHlp->pfnPrintf(pHlp, "  MSI Data                                = %#RX32\n", MsiData.u32);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette