VirtualBox

Changeset 83377 in vbox for trunk


Ignore:
Timestamp:
Mar 24, 2020 7:56:05 AM (5 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Bits.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r83263 r83377  
    192192RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_MISCINFO_1_, UINT32_C(0), UINT32_MAX,
    193193                            (MSI_NUM_GA, RSVD_5_31));
     194/** @} */
     195
     196/**
     197 * @name MSI Capability Header Register.
     198 * In accordance with the AMD spec.
     199 * @{
     200 */
     201/** MsiCapId: Capability ID. */
     202#define IOMMU_BF_MSI_CAPHDR_CAP_ID_SHIFT            0
     203#define IOMMU_BF_MSI_CAPHDR_CAP_ID_MASK             UINT32_C(0x000000ff)
     204/** MsiCapPtr: Pointer (PCI config offset) to the next capability register. */
     205#define IOMMU_BF_MSI_CAPHDR_CAP_PTR_SHIFT           8
     206#define IOMMU_BF_MSI_CAPHDR_CAP_PTR_MASK            UINT32_C(0x0000ff00)
     207/** MsiEn: Message Signal Interrupt enable. */
     208#define IOMMU_BF_MSI_CAPHDR_EN_SHIFT                16
     209#define IOMMU_BF_MSI_CAPHDR_EN_MASK                 UINT32_C(0x00010000)
     210/** MsiMultMessCap: MSI Multi-Message Capability. */
     211#define IOMMU_BF_MSI_CAPHDR_MULTMESS_CAP_SHIFT      17
     212#define IOMMU_BF_MSI_CAPHDR_MULTMESS_CAP_MASK       UINT32_C(0x000e0000)
     213/** MsiMultMessEn: MSI Mult-Message Enable. */
     214#define IOMMU_BF_MSI_CAPHDR_MULTMESS_EN_SHIFT       20
     215#define IOMMU_BF_MSI_CAPHDR_MULTMESS_EN_MASK        UINT32_C(0x00700000)
     216/** Msi64BitEn: MSI 64-bit Enabled. */
     217#define IOMMU_BF_MSI_CAPHDR_64BIT_EN_SHIFT          23
     218#define IOMMU_BF_MSI_CAPHDR_64BIT_EN_MASK           UINT32_C(0x00800000)
     219/** Bits 31:24 reserved. */
     220#define IOMMU_BF_MSI_CAPHDR_RSVD_24_31_SHIFT        24
     221#define IOMMU_BF_MSI_CAPHDR_RSVD_24_31_MASK         UINT32_C(0xff000000)
     222RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_MSI_CAPHDR_, UINT32_C(0), UINT32_MAX,
     223                            (CAP_ID, CAP_PTR, EN, MULTMESS_CAP, MULTMESS_EN, 64BIT_EN, RSVD_24_31));
     224/** @} */
     225
     226/**
     227 * @name MSI Mapping Capability Header Register.
     228 * In accordance with the AMD spec.
     229 * @{
     230 */
     231/** MsiMapCapId: Capability ID. */
     232#define IOMMU_BF_MSI_MAP_CAPHDR_CAP_ID_SHIFT        0
     233#define IOMMU_BF_MSI_MAP_CAPHDR_CAP_ID_MASK         UINT32_C(0x000000ff)
     234/** MsiMapCapPtr: Pointer (PCI config offset) to the next capability register. */
     235#define IOMMU_BF_MSI_MAP_CAPHDR_CAP_PTR_SHIFT       8
     236#define IOMMU_BF_MSI_MAP_CAPHDR_CAP_PTR_MASK        UINT32_C(0x0000ff00)
     237/** MsiMapEn: MSI mapping capability enable. */
     238#define IOMMU_BF_MSI_MAP_CAPHDR_EN_SHIFT            16
     239#define IOMMU_BF_MSI_MAP_CAPHDR_EN_MASK             UINT32_C(0x00010000)
     240/** MsiMapFixd: MSI interrupt mapping range is not programmable. */
     241#define IOMMU_BF_MSI_MAP_CAPHDR_FIXED_SHIFT         17
     242#define IOMMU_BF_MSI_MAP_CAPHDR_FIXED_MASK          UINT32_C(0x00020000)
     243/** Bits 18:28 reserved. */
     244#define IOMMU_BF_MSI_MAP_CAPHDR_RSVD_18_28_SHIFT    18
     245#define IOMMU_BF_MSI_MAP_CAPHDR_RSVD_18_28_MASK     UINT32_C(0x07fc0000)
     246/** MsiMapCapType: MSI mapping capability. */
     247#define IOMMU_BF_MSI_MAP_CAPHDR_CAP_TYPE_SHIFT      27
     248#define IOMMU_BF_MSI_MAP_CAPHDR_CAP_TYPE_MASK       UINT32_C(0xf8000000)
     249RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_MSI_MAP_CAPHDR_, UINT32_C(0), UINT32_MAX,
     250                            (CAP_ID, CAP_PTR, EN, FIXED, RSVD_18_28, CAP_TYPE));
     251/** @} */
     252
     253/** @name Miscellaneous IOMMU defines.
     254 * @{ */
     255#define IOMMU_LOG_PFX                               "AMD_IOMMU"     /**< Log prefix string. */
     256#define IOMMU_PCI_VENDOR_ID                         0x1022          /**< AMD's vendor ID. */
     257#define IOMMU_PCI_DEVICE_ID                         0xc0de          /**< VirtualBox IOMMU Device ID. */
     258#define IOMMU_PCI_REVISION_ID                       0x01            /**< VirtualBox IOMMU Device Revision ID. */
    194259/** @} */
    195260
     
    774839typedef struct IOMMU
    775840{
    776 
     841    bool                fRootComplex;
    777842} IOMMU;
    778843/** Pointer to the IOMMU device state. */
     
    784849typedef struct IOMMUR3
    785850{
     851    /** The IOMMU helpers. */
     852    PCPDMIOMMUHLPR3     pIommuHlp;
    786853} IOMMUR3;
    787854/** Pointer to the ring-3 IOMMU device state. */
     
    793860typedef struct IOMMUR0
    794861{
    795     uint64_t        uUnused;
     862    /** The IOMMU helpers. */
     863    PCPDMIOMMUHLPR0     pIommuHlp;
    796864} IOMMUR0;
    797865/** Pointer to the ring-0 IOMMU device state. */
     
    803871typedef struct IOMMURC
    804872{
    805     uint64_t        uUnused;
     873    /** The IOMMU helpers. */
     874    PCPDMIOMMUHLPRC     pIommuHlp;
    806875} IOMMURC;
    807876/** Pointer to the raw-mode IOMMU device state. */
     
    845914
    846915    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    847 #if 0
    848916    PIOMMU          pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    849917    PIOMMUCC        pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     
    852920    LogFlowFunc(("\n"));
    853921
     922    NOREF(pThisCC); /** @todo IOMMU: populate CC data. */
     923
    854924    /*
    855925     * Validate and read the configuration.
    856926     */
    857     //PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "", "");
    858 #endif
     927    PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "RootComplex", "");
     928
     929    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "RootComplex", &pThis->fRootComplex, true);
     930    AssertLogRelRCReturn(rc, rc);
     931
     932    /*
     933     * Initialize the PCI configuration space.
     934     */
     935    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     936    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
     937
     938    uint8_t const offCapHdr       = 0x40;
     939    uint8_t const offBaseAddrLo   = offCapHdr + 0x4;
     940    uint8_t const offBaseAddrHi   = offCapHdr + 0x8;
     941    uint8_t const offRange        = offCapHdr + 0xc;
     942    uint8_t const offMiscInfo0    = offCapHdr + 0x10;
     943    uint8_t const offMiscInfo1    = offCapHdr + 0x14;
     944    uint8_t const offMsiCapHdr    = offCapHdr + 0x24;
     945    uint8_t const offMsiMapCapHdr = offCapHdr + 0x34;
     946
     947    /* Header. */
     948    PDMPciDevSetVendorId(pPciDev,           IOMMU_PCI_VENDOR_ID);   /* RO - AMD */
     949    PDMPciDevSetDeviceId(pPciDev,           IOMMU_PCI_DEVICE_ID);   /* RO - VirtualBox IOMMU device */
     950    PDMPciDevSetCommand(pPciDev,            0);                     /* RW - Command */
     951    PDMPciDevSetStatus(pPciDev,             0x5);                   /* RW - Status - CapList supported */
     952    PDMPciDevSetRevisionId(pPciDev,         IOMMU_PCI_REVISION_ID); /* RO - VirtualBox specific device implementation revision */
     953    PDMPciDevSetClassBase(pPciDev,          0x08);                  /* RO - System Base Peripheral */
     954    PDMPciDevSetClassSub(pPciDev,           0x06);                  /* RO - IOMMU */
     955    PDMPciDevSetClassProg(pPciDev,          0x00);                  /* RO - IOMMU Programming interface */
     956    PDMPciDevSetHeaderType(pPciDev,         0x00);                  /* RO - Single function, type 0. */
     957    PDMPciDevSetSubSystemId(pPciDev,        IOMMU_PCI_DEVICE_ID);   /* RO - AMD */
     958    PDMPciDevSetSubSystemVendorId(pPciDev,  IOMMU_PCI_VENDOR_ID);   /* RO - VirtualBox IOMMU device */
     959    PDMPciDevSetCapabilityList(pPciDev,     offCapHdr);             /* RO - Offset into capability registers. */
     960    PDMPciDevSetInterruptPin(pPciDev,       0x01);                  /* RO - INTA#. */
     961    PDMPciDevSetInterruptLine(pPciDev,      0x00);                  /* RW - For software compatibility; no effect on hardware. */
     962
     963    /* Capability Header. */
     964    PDMPciDevSetDWord(pPciDev, offCapHdr,
     965                        RT_BF_MAKE(IOMMU_BF_CAPHDR_CAP_ID,     0xf)             /* RO - Secure Device capability block */
     966                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_CAP_PTR,    offMsiCapHdr)    /* RO - Offset to next capability block */
     967                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_CAP_TYPE,   0x3)             /* RO - IOMMU capability block */
     968                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_CAP_REV,    0x1)             /* RO - IOMMU interface revision */
     969                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_IOTLB_SUP,  0x0)             /* RO - Remote IOTLB support */
     970                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_HT_TUNNEL,  0x0)             /* RO - HyperTransport Tunnel support */
     971                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_NP_CACHE,   0x0)             /* RO - Cache Not-present page table entries */
     972                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_EFR_SUP,    0x1)             /* RO - Extended Feature Register support */
     973                      | RT_BF_MAKE(IOMMU_BF_CAPHDR_CAP_EXT,    0x1));           /* RO - Misc. Information Register support */
     974
     975    /* Base Address Low Register. */
     976    PDMPciDevSetDWord(pPciDev, offBaseAddrLo,
     977                        RT_BF_MAKE(IOMMU_BF_BASEADDR_LO_ENABLE,  0x0)       /* RW - Enable */
     978                      | RT_BF_MAKE(IOMMU_BF_BASEADDR_LO_ADDR_LO, 0x0)       /* RW - Base address low (lo) */
     979                      | RT_BF_MAKE(IOMMU_BF_BASEADDR_LO_ADDR_HI, 0x0));     /* RW - Base address low (hi) */
     980
     981    /* Base Address High Register. */
     982    PDMPciDevSetDWord(pPciDev, offBaseAddrHi, 0);   /* RW - Base address high */
     983
     984    /* IOMMU Range Register. */
     985    PDMPciDevSetDWord(pPciDev, offRange,
     986                        RT_BF_MAKE(IOMMU_BF_RANGE_UNIT_ID,      0x0)        /* RO - HyperTransport Unit ID */
     987                      | RT_BF_MAKE(IOMMU_BF_RANGE_VALID,        0x0)        /* RW - Range Valid */
     988                      | RT_BF_MAKE(IOMMU_BF_RANGE_BUS_NUMBER,   0x0)        /* RO - Bus number */
     989                      | RT_BF_MAKE(IOMMU_BF_RANGE_FIRST_DEVICE, 0x0)        /* RO - First device */
     990                      | RT_BF_MAKE(IOMMU_BF_RANGE_LAST_DEVICE,  0x0));      /* RO - Last device */
     991
     992    /* Misc. Information Register 0. */
     993    PDMPciDevSetDWord(pPciDev, offMiscInfo0,
     994                        RT_BF_MAKE(IOMMU_BF_MISCINFO_0_MSI_NUM,     0x0)    /* RO - MSI number */
     995                      | RT_BF_MAKE(IOMMU_BF_MISCINFO_0_GVA_SIZE,    0x2)    /* RO - Guest Virt. Addr size (2=48 bits) */
     996                      | RT_BF_MAKE(IOMMU_BF_MISCINFO_0_PA_SIZE,     0x30)   /* RO - Physical Addr size (48 bits) */
     997                      | RT_BF_MAKE(IOMMU_BF_MISCINFO_0_VA_SIZE,     0x40)   /* RO - Virt. Addr size (64 bits) */
     998                      | RT_BF_MAKE(IOMMU_BF_MISCINFO_0_HT_ATS_RESV, 0x0)    /* RW - HT ATS reserved */
     999                      | RT_BF_MAKE(IOMMU_BF_MISCINFO_0_MSI_NUM_PPR, 0x0));  /* RW - PPR interrupt number */
     1000
     1001    /* Misc. Information Register 1. */
     1002    PDMPciDevSetDWord(pPciDev, offMiscInfo1, 0);
     1003
     1004    /* MSI Capability Header register. */
     1005    PDMPciDevSetDWord(pPciDev, offMsiCapHdr,
     1006                        RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_CAP_ID,       0x5)             /* RO - Capability ID. */
     1007                      | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_CAP_PTR,      offMsiMapCapHdr) /* RO - Offset to mapping capability block */
     1008                      | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_EN,           0x0)             /* RW - MSI capability enable */
     1009                      | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_MULTMESS_CAP, 0x0)             /* RO - MSI multi-message capability */
     1010                      | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_MULTMESS_EN,  0x0)             /* RW - MSI multi-message enable */
     1011                      | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_64BIT_EN,     0x1));           /* RO - MSI 64-bit enable */
     1012
     1013    /* MSI Mapping Capability header register. */
     1014    PDMPciDevSetDWord(pPciDev, offMsiMapCapHdr,
     1015                        RT_BF_MAKE(IOMMU_BF_MSI_MAP_CAPHDR_CAP_ID,   0x8)       /* RO - Capability ID */
     1016                      | RT_BF_MAKE(IOMMU_BF_MSI_MAP_CAPHDR_CAP_PTR,  0x0)       /* RO - Offset to next capability (NULL) */
     1017                      | RT_BF_MAKE(IOMMU_BF_MSI_MAP_CAPHDR_EN,       0x1)       /* RO - MSI mapping capability enable */
     1018                      | RT_BF_MAKE(IOMMU_BF_MSI_MAP_CAPHDR_FIXED,    0x1)       /* RO - MSI mapping range is fixed */
     1019                      | RT_BF_MAKE(IOMMU_BF_MSI_MAP_CAPHDR_CAP_TYPE, 0x15));    /* RO - MSI mapping capability */
     1020
    8591021    return VINF_SUCCESS;
    8601022}
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