VirtualBox

Changeset 85639 in vbox for trunk


Ignore:
Timestamp:
Aug 7, 2020 9:34:12 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 ACPI tables for IOMMU. ifdef'd not enabled.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r85347 r85639  
    2727#include <VBox/log.h>
    2828#include <VBox/param.h>
     29#include <VBox/pci.h>
    2930#include <iprt/assert.h>
    3031#include <iprt/asm.h>
     
    384385    /** PCI address of the host bus controller device. */
    385386    uint32_t            u32HbcPciAddress;
     387    /** PCI address of the AMD IOMMU device. */
     388    uint32_t            u32IommuAmdPciAddress;
     389    /** PCI address of the southbridge I/O APIC device. */
     390    uint32_t            u32SbIoApicPciAddress;
    386391
    387392    /** Physical address of PCI config space MMIO region */
     
    502507/** Pointer to the shared ACPI device state. */
    503508typedef ACPISTATE *PACPISTATE;
     509
    504510
    505511
     
    777783AssertCompileSize(ACPITBLHPET, 56);
    778784
     785#ifdef VBOX_WITH_IOMMU_AMD
     786/** @name IVRS format revision field.
     787 * In accordance with the AMD spec.
     788 * @{ */
     789/** Fixed: Supports only pre-assigned device IDs and type 10h and 11h IVHD
     790 *  blocks. */
     791#define ACPI_IVRS_FMT_REV_FIXED                         0x1
     792/** Mixed: Supports pre-assigned and ACPI HID device naming and all IVHD blocks. */
     793#define ACPI_IVRS_FMT_REV_MIXED                         0x2
     794/** @} */
     795
     796/** @name IVHD special device entry variety field.
     797 * In accordance with the AMD spec.
     798 * @{ */
     799/** I/O APIC. */
     800#define ACPI_IVHD_VARIETY_IOAPIC                        0x1
     801/** HPET. */
     802#define ACPI_IVHD_VARIETY_HPET                          0x2
     803/** @} */
     804
     805/** @name IVHD device entry type codes.
     806 * In accordance with the AMD spec.
     807 * @{ */
     808/** Reserved. */
     809#define ACPI_IVHD_DEVENTRY_TYPE_RSVD                    0x0
     810/** All: DTE setting applies to all Device IDs. */
     811#define ACPI_IVHD_DEVENTRY_TYPE_ALL                     0x1
     812/** Select: DTE setting applies to the device specified in DevId field. */
     813#define ACPI_IVHD_DEVENTRY_TYPE_SELECT                  0x2
     814/** Start of range: DTE setting applies to all devices from start of range specified
     815 *  by the DevId field. */
     816#define ACPI_IVHD_DEVENTRY_TYPE_START_RANGE             0x3
     817/** End of range: DTE setting from previous type 3 entry applies to all devices
     818 *  incl. DevId specified by this entry. */
     819#define ACPI_IVHD_DEVENTRY_TYPE_END_RANGE               0x4
     820/** @} */
     821
     822/** @name IVHD DTE (Device Table Entry) Settings.
     823 * In accordance with the AMD spec.
     824 * @{ */
     825/** INITPass: Identifies a device able to assert INIT interrupts. */
     826#define ACPI_IVHD_DTE_INIT_PASS_SHIFT                   0
     827#define ACPI_IVHD_DTE_INIT_PASS_MASK                    UINT8_C(0x01)
     828/** EIntPass: Identifies a device able to assert ExtInt interrupts. */
     829#define ACPI_IVHD_DTE_EXTINT_PASS_SHIFT                 1
     830#define ACPI_IVHD_DTE_EXTINT_PASS_MASK                  UINT8_C(0x02)
     831/** NMIPass: Identifies a device able to assert NMI interrupts. */
     832#define ACPI_IVHD_DTE_NMI_PASS_SHIFT                    2
     833#define ACPI_IVHD_DTE_NMI_PASS_MASK                     UINT8_C(0x04)
     834/** Bit 3 reserved. */
     835#define ACPI_IVHD_DTE_RSVD_3_SHIFT                      3
     836#define ACPI_IVHD_DTE_RSVD_3_MASK                       UINT8_C(0x08)
     837/** SysMgt: Identifies a device able to assert system management messages. */
     838#define ACPI_IVHD_DTE_SYS_MGT_SHIFT                     4
     839#define ACPI_IVHD_DTE_SYS_MGT_MASK                      UINT8_C(0x30)
     840/** Lint0Pass: Identifies a device able to assert LINT0 interrupts. */
     841#define ACPI_IVHD_DTE_LINT0_PASS_SHIFT                  6
     842#define ACPI_IVHD_DTE_LINT0_PASS_MASK                   UINT8_C(0x40)
     843/** Lint0Pass: Identifies a device able to assert LINT1 interrupts. */
     844#define ACPI_IVHD_DTE_LINT1_PASS_SHIFT                  7
     845#define ACPI_IVHD_DTE_LINT1_PASS_MASK                   UINT8_C(0x80)
     846RT_BF_ASSERT_COMPILE_CHECKS(ACPI_IVHD_DTE_, UINT8_C(0), UINT8_MAX,
     847                            (INIT_PASS, EXTINT_PASS, NMI_PASS, RSVD_3, SYS_MGT, LINT0_PASS, LINT1_PASS));
     848/** @} */
     849
     850/** AMD IOMMU: IVHD (I/O Virtualization Hardware Definition) Device Entry
     851 *  (4-byte). In accordance with the AMD spec. */
     852typedef struct ACPIIVHDDEVENTRY4
     853{
     854    uint8_t         u8DevEntryType;     /**< Device entry type. */
     855    uint16_t        u16DevId;           /**< Device ID. */
     856    uint8_t         u8DteSetting;       /**< DTE (Device Table Entry) setting. */
     857} ACPIIVHDDEVENTRY4;
     858AssertCompileSize(ACPIIVHDDEVENTRY4, 4);
     859
     860/** AMD IOMMU: IVHD (I/O Virtualization Hardware Definition) Device Entry
     861 *  (8-byte). In accordance with the AMD spec. */
     862typedef struct ACPIIVHDDEVENTRY8
     863{
     864    uint8_t         u8DevEntryType;     /**< Device entry type. */
     865    union
     866    {
     867        /** Reserved: When u8DevEntryType is 0x40, 0x41, 0x44 or 0x45 (or 0x49-0x7F). */
     868        struct
     869        {
     870            uint8_t     au8Rsvd0[7];        /**< Reserved (MBZ). */
     871        } rsvd;
     872        /** Alias Select: When u8DevEntryType is 0x42 or 0x43. */
     873        struct
     874        {
     875            uint16_t    u16DevIdA;          /**< Device ID A. */
     876            uint8_t     u8DteSetting;       /**< DTE (Device Table Entry) setting. */
     877            uint8_t     u8Rsvd0;            /**< Reserved (MBZ). */
     878            uint16_t    u16DevIdB;          /**< Device ID B. */
     879            uint8_t     u8Rsvd1;            /**< Reserved (MBZ). */
     880        } alias;
     881        /** Extended Select: When u8DevEntryType is 0x46 or 0x47. */
     882        struct
     883        {
     884            uint16_t    u16DevId;           /**< Device ID. */
     885            uint8_t     u8DteSetting;       /**< DTE (Device Table Entry) setting. */
     886            uint32_t    u32ExtDteSetting;   /**< Extended DTE setting. */
     887        } ext;
     888        /** Special Device: When u8DevEntryType is 0x48. */
     889        struct
     890        {
     891            uint16_t    u16Rsvd0;           /**< Reserved (MBZ). */
     892            uint8_t     u8DteSetting;       /**< DTE (Device Table Entry) setting. */
     893            uint8_t     u8Handle;           /**< Handle contains I/O APIC ID or HPET number. */
     894            uint16_t    u16DevIdB;          /**< Device ID B (I/O APIC or HPET). */
     895            uint8_t     u8Variety;          /**< Whether this is the HPET or I/O APIC. */
     896        } special;
     897    } u;
     898} ACPIIVHDDEVENTRY8;
     899AssertCompileSize(ACPIIVHDDEVENTRY8, 8);
     900
     901/** @name IVHD Type 10h Flags.
     902 * In accordance with the AMD spec.
     903 * @{ */
     904/** Peripheral page request support. */
     905#define ACPI_IVHD_10H_F_PPR_SUP                         RT_BIT(7)
     906/** Prefetch IOMMU pages command support. */
     907#define ACPI_IVHD_10H_F_PREF_SUP                        RT_BIT(6)
     908/** Coherent control. */
     909#define ACPI_IVHD_10H_F_COHERENT                        RT_BIT(5)
     910/** Remote IOTLB support. */
     911#define ACPI_IVHD_10H_F_IOTLB_SUP                       RT_BIT(4)
     912/** Isochronous control. */
     913#define ACPI_IVHD_10H_F_ISOC                            RT_BIT(3)
     914/** Response Pass Posted Write. */
     915#define ACPI_IVHD_10H_F_RES_PASS_PW                     RT_BIT(2)
     916/** Pass Posted Write. */
     917#define ACPI_IVHD_10H_F_PASS_PW                         RT_BIT(1)
     918/** HyperTransport Tunnel. */
     919#define ACPI_IVHD_10H_F_HT_TUNNEL                       RT_BIT(0)
     920/** @} */
     921
     922/** @name IVRS IVinfo field.
     923 * In accordance with the AMD spec.
     924 * @{ */
     925/** EFRSup: Extended Feature Support. */
     926#define ACPI_IVINFO_BF_EFR_SUP_SHIFT                    0
     927#define ACPI_IVINFO_BF_EFR_SUP_MASK                     UINT32_C(0x00000001)
     928/** DMA Remap Sup: DMA remapping support (pre-boot DMA protection with
     929 *  mandatory remapping of device accessed memory). */
     930#define ACPI_IVINFO_BF_DMA_REMAP_SUP_SHIFT              1
     931#define ACPI_IVINFO_BF_DMA_REMAP_SUP_MASK               UINT32_C(0x00000002)
     932/** Bits 4:2 reserved. */
     933#define ACPI_IVINFO_BF_RSVD_2_4_SHIFT                   2
     934#define ACPI_IVINFO_BF_RSVD_2_4_MASK                    UINT32_C(0x0000001c)
     935/** GVASize: Guest virtual-address size. */
     936#define ACPI_IVINFO_BF_GVA_SIZE_SHIFT                   5
     937#define ACPI_IVINFO_BF_GVA_SIZE_MASK                    UINT32_C(0x000000e0)
     938/** PASize: System physical address size. */
     939#define ACPI_IVINFO_BF_PA_SIZE_SHIFT                    8
     940#define ACPI_IVINFO_BF_PA_SIZE_MASK                     UINT32_C(0x00007f00)
     941/** VASize: Virtual address size. */
     942#define ACPI_IVINFO_BF_VA_SIZE_SHIFT                    15
     943#define ACPI_IVINFO_BF_VA_SIZE_MASK                     UINT32_C(0x003f8000)
     944/** HTAtsResv: HyperTransport ATS-response address translation range reserved. */
     945#define ACPI_IVINFO_BF_HT_ATS_RESV_SHIFT                22
     946#define ACPI_IVINFO_BF_HT_ATS_RESV_MASK                 UINT32_C(0x00400000)
     947/** Bits 31:23 reserved. */
     948#define ACPI_IVINFO_BF_RSVD_23_31_SHIFT                 23
     949#define ACPI_IVINFO_BF_RSVD_23_31_MASK                  UINT32_C(0xff800000)
     950RT_BF_ASSERT_COMPILE_CHECKS(ACPI_IVINFO_BF_, UINT32_C(0), UINT32_MAX,
     951                            (EFR_SUP, DMA_REMAP_SUP, RSVD_2_4, GVA_SIZE, PA_SIZE, VA_SIZE, HT_ATS_RESV, RSVD_23_31));
     952/** @} */
     953
     954/** @name IVHD IOMMU info flags.
     955 * In accordance with the AMD spec.
     956 * @{ */
     957/** MSI message number for the event log. */
     958#define ACPI_IOMMU_INFO_BF_MSI_NUM_SHIFT                0
     959#define ACPI_IOMMU_INFO_BF_MSI_NUM_MASK                 UINT16_C(0x001f)
     960/** Bits 7:5 reserved. */
     961#define ACPI_IOMMU_INFO_BF_RSVD_5_7_SHIFT               5
     962#define ACPI_IOMMU_INFO_BF_RSVD_5_7_MASK                UINT16_C(0x00e0)
     963/** IOMMU HyperTransport Unit ID number. */
     964#define ACPI_IOMMU_INFO_BF_UNIT_ID_SHIFT                8
     965#define ACPI_IOMMU_INFO_BF_UNIT_ID_MASK                 UINT16_C(0x1f00)
     966/** Bits 15:13 reserved. */
     967#define ACPI_IOMMU_INFO_BF_RSVD_13_15_SHIFT             13
     968#define ACPI_IOMMU_INFO_BF_RSVD_13_15_MASK              UINT16_C(0xe000)
     969RT_BF_ASSERT_COMPILE_CHECKS(ACPI_IOMMU_INFO_BF_, UINT16_C(0), UINT16_MAX,
     970                            (MSI_NUM, RSVD_5_7, UNIT_ID, RSVD_13_15));
     971/** @} */
     972
     973/** @name IVHD IOMMU feature reporting field.
     974 * In accordance with the AMD spec.
     975 * @{ */
     976/** x2APIC supported for peripherals. */
     977#define ACPI_IOMMU_FEAT_BF_XT_SUP_SHIFT                 0
     978#define ACPI_IOMMU_FEAT_BF_XT_SUP_MASK                  UINT32_C(0x00000001)
     979/** NX supported for I/O. */
     980#define ACPI_IOMMU_FEAT_BF_NX_SUP_SHIFT                 1
     981#define ACPI_IOMMU_FEAT_BF_NX_SUP_MASK                  UINT32_C(0x00000002)
     982/** GT (Guest Translation) supported. */
     983#define ACPI_IOMMU_FEAT_BF_GT_SUP_SHIFT                 2
     984#define ACPI_IOMMU_FEAT_BF_GT_SUP_MASK                  UINT32_C(0x00000004)
     985/** GLX (Number of guest CR3 tables) supported. */
     986#define ACPI_IOMMU_FEAT_BF_GLX_SUP_SHIFT                3
     987#define ACPI_IOMMU_FEAT_BF_GLX_SUP_MASK                 UINT32_C(0x00000018)
     988/** IA (INVALIDATE_IOMMU_ALL) command supported. */
     989#define ACPI_IOMMU_FEAT_BF_IA_SUP_SHIFT                 5
     990#define ACPI_IOMMU_FEAT_BF_IA_SUP_MASK                  UINT32_C(0x00000020)
     991/** GA (Guest virtual APIC) supported. */
     992#define ACPI_IOMMU_FEAT_BF_GA_SUP_SHIFT                 6
     993#define ACPI_IOMMU_FEAT_BF_GA_SUP_MASK                  UINT32_C(0x00000040)
     994/** HE (Hardware error) registers supported. */
     995#define ACPI_IOMMU_FEAT_BF_HE_SUP_SHIFT                 7
     996#define ACPI_IOMMU_FEAT_BF_HE_SUP_MASK                  UINT32_C(0x00000080)
     997/** PASMax (maximum PASID) supported. Ignored if PPRSup=0. */
     998#define ACPI_IOMMU_FEAT_BF_PAS_MAX_SHIFT                8
     999#define ACPI_IOMMU_FEAT_BF_PAS_MAX_MASK                 UINT32_C(0x00001f00)
     1000/** PNCounters (Number of performance counters per counter bank) supported. */
     1001#define ACPI_IOMMU_FEAT_BF_PN_COUNTERS_SHIFT            13
     1002#define ACPI_IOMMU_FEAT_BF_PN_COUNTERS_MASK             UINT32_C(0x0001e000)
     1003/** PNBanks (Number of performance counter banks) supported. */
     1004#define ACPI_IOMMU_FEAT_BF_PN_BANKS_SHIFT               17
     1005#define ACPI_IOMMU_FEAT_BF_PN_BANKS_MASK                UINT32_C(0x007e0000)
     1006/** MSINumPPR (MSI number for peripheral page requests). */
     1007#define ACPI_IOMMU_FEAT_BF_MSI_NUM_PPR_SHIFT            23
     1008#define ACPI_IOMMU_FEAT_BF_MSI_NUM_PPR_MASK             UINT32_C(0x0f800000)
     1009/** GATS (Guest address translation size). MBZ when GTSup=0. */
     1010#define ACPI_IOMMU_FEAT_BF_GATS_SHIFT                   28
     1011#define ACPI_IOMMU_FEAT_BF_GATS_MASK                    UINT32_C(0x30000000)
     1012/** HATS (Host address translation size). */
     1013#define ACPI_IOMMU_FEAT_BF_HATS_SHIFT                   30
     1014#define ACPI_IOMMU_FEAT_BF_HATS_MASK                    UINT32_C(0xc0000000)
     1015RT_BF_ASSERT_COMPILE_CHECKS(ACPI_IOMMU_FEAT_BF_, UINT32_C(0), UINT32_MAX,
     1016                            (XT_SUP, NX_SUP, GT_SUP, GLX_SUP, IA_SUP, GA_SUP, HE_SUP, PAS_MAX, PN_COUNTERS, PN_BANKS,
     1017                             MSI_NUM_PPR, GATS, HATS));
     1018/** @} */
     1019
     1020/** @name IOMMU Extended Feature Register (PCI/MMIO/ACPI).
     1021 * In accordance with the AMD spec.
     1022 * @{ */
     1023/** PreFSup: Prefetch support (RO).   */
     1024#define IOMMU_EXT_FEAT_BF_PREF_SUP_SHIFT                0
     1025#define IOMMU_EXT_FEAT_BF_PREF_SUP_MASK                 UINT64_C(0x0000000000000001)
     1026/** PPRSup: Peripheral Page Request (PPR) support (RO). */
     1027#define IOMMU_EXT_FEAT_BF_PPR_SUP_SHIFT                 1
     1028#define IOMMU_EXT_FEAT_BF_PPR_SUP_MASK                  UINT64_C(0x0000000000000002)
     1029/** XTSup: x2APIC support (RO). */
     1030#define IOMMU_EXT_FEAT_BF_X2APIC_SUP_SHIFT              2
     1031#define IOMMU_EXT_FEAT_BF_X2APIC_SUP_MASK               UINT64_C(0x0000000000000004)
     1032/** NXSup: No Execute (PMR and PRIV) support (RO). */
     1033#define IOMMU_EXT_FEAT_BF_NO_EXEC_SUP_SHIFT             3
     1034#define IOMMU_EXT_FEAT_BF_NO_EXEC_SUP_MASK              UINT64_C(0x0000000000000008)
     1035/** GTSup: Guest Translation support (RO). */
     1036#define IOMMU_EXT_FEAT_BF_GT_SUP_SHIFT                  4
     1037#define IOMMU_EXT_FEAT_BF_GT_SUP_MASK                   UINT64_C(0x0000000000000010)
     1038/** Bit 5 reserved. */
     1039#define IOMMU_EXT_FEAT_BF_RSVD_5_SHIFT                  5
     1040#define IOMMU_EXT_FEAT_BF_RSVD_5_MASK                   UINT64_C(0x0000000000000020)
     1041/** IASup: INVALIDATE_IOMMU_ALL command support (RO). */
     1042#define IOMMU_EXT_FEAT_BF_IA_SUP_SHIFT                  6
     1043#define IOMMU_EXT_FEAT_BF_IA_SUP_MASK                   UINT64_C(0x0000000000000040)
     1044/** GASup: Guest virtual-APIC support (RO). */
     1045#define IOMMU_EXT_FEAT_BF_GA_SUP_SHIFT                  7
     1046#define IOMMU_EXT_FEAT_BF_GA_SUP_MASK                   UINT64_C(0x0000000000000080)
     1047/** HESup: Hardware error registers support (RO). */
     1048#define IOMMU_EXT_FEAT_BF_HE_SUP_SHIFT                  8
     1049#define IOMMU_EXT_FEAT_BF_HE_SUP_MASK                   UINT64_C(0x0000000000000100)
     1050/** PCSup: Performance counters support (RO). */
     1051#define IOMMU_EXT_FEAT_BF_PC_SUP_SHIFT                  9
     1052#define IOMMU_EXT_FEAT_BF_PC_SUP_MASK                   UINT64_C(0x0000000000000200)
     1053/** HATS: Host Address Translation Size (RO). */
     1054#define IOMMU_EXT_FEAT_BF_HATS_SHIFT                    10
     1055#define IOMMU_EXT_FEAT_BF_HATS_MASK                     UINT64_C(0x0000000000000c00)
     1056/** GATS: Guest Address Translation Size (RO). */
     1057#define IOMMU_EXT_FEAT_BF_GATS_SHIFT                    12
     1058#define IOMMU_EXT_FEAT_BF_GATS_MASK                     UINT64_C(0x0000000000003000)
     1059/** GLXSup: Guest CR3 root table level support  (RO). */
     1060#define IOMMU_EXT_FEAT_BF_GLX_SUP_SHIFT                 14
     1061#define IOMMU_EXT_FEAT_BF_GLX_SUP_MASK                  UINT64_C(0x000000000000c000)
     1062/** SmiFSup: SMI filter register support  (RO). */
     1063#define IOMMU_EXT_FEAT_BF_SMI_FLT_SUP_SHIFT             16
     1064#define IOMMU_EXT_FEAT_BF_SMI_FLT_SUP_MASK              UINT64_C(0x0000000000030000)
     1065/** SmiFRC: SMI filter register count  (RO). */
     1066#define IOMMU_EXT_FEAT_BF_SMI_FLT_REG_CNT_SHIFT         18
     1067#define IOMMU_EXT_FEAT_BF_SMI_FLT_REG_CNT_MASK          UINT64_C(0x00000000001c0000)
     1068/** GAMSup: Guest virtual-APIC modes support (RO). */
     1069#define IOMMU_EXT_FEAT_BF_GAM_SUP_SHIFT                 21
     1070#define IOMMU_EXT_FEAT_BF_GAM_SUP_MASK                  UINT64_C(0x0000000000e00000)
     1071/** DualPprLogSup: Dual PPR Log support (RO). */
     1072#define IOMMU_EXT_FEAT_BF_DUAL_PPR_LOG_SUP_SHIFT        24
     1073#define IOMMU_EXT_FEAT_BF_DUAL_PPR_LOG_SUP_MASK         UINT64_C(0x0000000003000000)
     1074/** Bits 27:26 reserved. */
     1075#define IOMMU_EXT_FEAT_BF_RSVD_26_27_SHIFT              26
     1076#define IOMMU_EXT_FEAT_BF_RSVD_26_27_MASK               UINT64_C(0x000000000c000000)
     1077/** DualEventLogSup: Dual Event Log support (RO). */
     1078#define IOMMU_EXT_FEAT_BF_DUAL_EVT_LOG_SUP_SHIFT        28
     1079#define IOMMU_EXT_FEAT_BF_DUAL_EVT_LOG_SUP_MASK         UINT64_C(0x0000000030000000)
     1080/** Bits 31:30 reserved. */
     1081#define IOMMU_EXT_FEAT_BF_RSVD_30_31_SHIFT              30
     1082#define IOMMU_EXT_FEAT_BF_RSVD_30_31_MASK               UINT64_C(0x00000000c0000000)
     1083/** PASMax: Maximum PASID support (RO). */
     1084#define IOMMU_EXT_FEAT_BF_PASID_MAX_SHIFT               32
     1085#define IOMMU_EXT_FEAT_BF_PASID_MAX_MASK                UINT64_C(0x0000001f00000000)
     1086/** USSup: User/Supervisor support (RO). */
     1087#define IOMMU_EXT_FEAT_BF_US_SUP_SHIFT                  37
     1088#define IOMMU_EXT_FEAT_BF_US_SUP_MASK                   UINT64_C(0x0000002000000000)
     1089/** DevTblSegSup: Segmented Device Table support (RO). */
     1090#define IOMMU_EXT_FEAT_BF_DEV_TBL_SEG_SUP_SHIFT         38
     1091#define IOMMU_EXT_FEAT_BF_DEV_TBL_SEG_SUP_MASK          UINT64_C(0x000000c000000000)
     1092/** PprOverflwEarlySup: PPR Log Overflow Early warning support (RO). */
     1093#define IOMMU_EXT_FEAT_BF_PPR_OVERFLOW_EARLY_SHIFT      40
     1094#define IOMMU_EXT_FEAT_BF_PPR_OVERFLOW_EARLY_MASK       UINT64_C(0x0000010000000000)
     1095/** PprAutoRspSup: PPR Automatic Response support (RO). */
     1096#define IOMMU_EXT_FEAT_BF_PPR_AUTO_RES_SUP_SHIFT        41
     1097#define IOMMU_EXT_FEAT_BF_PPR_AUTO_RES_SUP_MASK         UINT64_C(0x0000020000000000)
     1098/** MarcSup: Memory Access and Routing (MARC) support (RO). */
     1099#define IOMMU_EXT_FEAT_BF_MARC_SUP_SHIFT                42
     1100#define IOMMU_EXT_FEAT_BF_MARC_SUP_MASK                 UINT64_C(0x00000c0000000000)
     1101/** BlkStopMrkSup: Block StopMark message support (RO). */
     1102#define IOMMU_EXT_FEAT_BF_BLKSTOP_MARK_SUP_SHIFT        44
     1103#define IOMMU_EXT_FEAT_BF_BLKSTOP_MARK_SUP_MASK         UINT64_C(0x0000100000000000)
     1104/** PerfOptSup: IOMMU Performance Optimization support (RO). */
     1105#define IOMMU_EXT_FEAT_BF_PERF_OPT_SUP_SHIFT            45
     1106#define IOMMU_EXT_FEAT_BF_PERF_OPT_SUP_MASK             UINT64_C(0x0000200000000000)
     1107/** MsiCapMmioSup: MSI-Capability Register MMIO access support (RO). */
     1108#define IOMMU_EXT_FEAT_BF_MSI_CAP_MMIO_SUP_SHIFT        46
     1109#define IOMMU_EXT_FEAT_BF_MSI_CAP_MMIO_SUP_MASK         UINT64_C(0x0000400000000000)
     1110/** Bit 47 reserved. */
     1111#define IOMMU_EXT_FEAT_BF_RSVD_47_SHIFT                 47
     1112#define IOMMU_EXT_FEAT_BF_RSVD_47_MASK                  UINT64_C(0x0000800000000000)
     1113/** GIoSup: Guest I/O Protection support (RO). */
     1114#define IOMMU_EXT_FEAT_BF_GST_IO_PROT_SUP_SHIFT         48
     1115#define IOMMU_EXT_FEAT_BF_GST_IO_PROT_SUP_MASK          UINT64_C(0x0001000000000000)
     1116/** HASup: Host Access support (RO). */
     1117#define IOMMU_EXT_FEAT_BF_HST_ACCESS_SUP_SHIFT          49
     1118#define IOMMU_EXT_FEAT_BF_HST_ACCESS_SUP_MASK           UINT64_C(0x0002000000000000)
     1119/** EPHSup: Enhandled PPR Handling support (RO). */
     1120#define IOMMU_EXT_FEAT_BF_ENHANCED_PPR_SUP_SHIFT        50
     1121#define IOMMU_EXT_FEAT_BF_ENHANCED_PPR_SUP_MASK         UINT64_C(0x0004000000000000)
     1122/** AttrFWSup: Attribute Forward support (RO). */
     1123#define IOMMU_EXT_FEAT_BF_ATTR_FW_SUP_SHIFT             51
     1124#define IOMMU_EXT_FEAT_BF_ATTR_FW_SUP_MASK              UINT64_C(0x0008000000000000)
     1125/** HDSup: Host Dirty Support (RO). */
     1126#define IOMMU_EXT_FEAT_BF_HST_DIRTY_SUP_SHIFT           52
     1127#define IOMMU_EXT_FEAT_BF_HST_DIRTY_SUP_MASK            UINT64_C(0x0010000000000000)
     1128/** Bit 53 reserved. */
     1129#define IOMMU_EXT_FEAT_BF_RSVD_53_SHIFT                 53
     1130#define IOMMU_EXT_FEAT_BF_RSVD_53_MASK                  UINT64_C(0x0020000000000000)
     1131/** InvIotlbTypeSup: Invalidate IOTLB type support (RO). */
     1132#define IOMMU_EXT_FEAT_BF_INV_IOTLB_TYPE_SUP_SHIFT      54
     1133#define IOMMU_EXT_FEAT_BF_INV_IOTLB_TYPE_SUP_MASK       UINT64_C(0x0040000000000000)
     1134/** Bits 60:55 reserved. */
     1135#define IOMMU_EXT_FEAT_BF_RSVD_55_60_SHIFT              55
     1136#define IOMMU_EXT_FEAT_BF_RSVD_55_60_MASK               UINT64_C(0x1f80000000000000)
     1137/** GAUpdateDisSup: Support disabling hardware update on guest page table access
     1138 *  (RO). */
     1139#define IOMMU_EXT_FEAT_BF_GA_UPDATE_DIS_SUP_SHIFT       61
     1140#define IOMMU_EXT_FEAT_BF_GA_UPDATE_DIS_SUP_MASK        UINT64_C(0x2000000000000000)
     1141/** ForcePhysDestSup: Force Physical Destination Mode for Remapped Interrupt
     1142 *  support (RO). */
     1143#define IOMMU_EXT_FEAT_BF_FORCE_PHYS_DST_SUP_SHIFT      62
     1144#define IOMMU_EXT_FEAT_BF_FORCE_PHYS_DST_SUP_MASK       UINT64_C(0x4000000000000000)
     1145/** Bit 63 reserved. */
     1146#define IOMMU_EXT_FEAT_BF_RSVD_63_SHIFT                 63
     1147#define IOMMU_EXT_FEAT_BF_RSVD_63_MASK                  UINT64_C(0x8000000000000000)
     1148RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_EXT_FEAT_BF_, UINT64_C(0), UINT64_MAX,
     1149                            (PREF_SUP, PPR_SUP, X2APIC_SUP, NO_EXEC_SUP, GT_SUP, RSVD_5, IA_SUP, GA_SUP, HE_SUP, PC_SUP,
     1150                             HATS, GATS, GLX_SUP, SMI_FLT_SUP, SMI_FLT_REG_CNT, GAM_SUP, DUAL_PPR_LOG_SUP, RSVD_26_27,
     1151                             DUAL_EVT_LOG_SUP, RSVD_30_31, PASID_MAX, US_SUP, DEV_TBL_SEG_SUP, PPR_OVERFLOW_EARLY,
     1152                             PPR_AUTO_RES_SUP, MARC_SUP, BLKSTOP_MARK_SUP, PERF_OPT_SUP, MSI_CAP_MMIO_SUP, RSVD_47,
     1153                             GST_IO_PROT_SUP, HST_ACCESS_SUP, ENHANCED_PPR_SUP, ATTR_FW_SUP, HST_DIRTY_SUP, RSVD_53,
     1154                             INV_IOTLB_TYPE_SUP, RSVD_55_60, GA_UPDATE_DIS_SUP, FORCE_PHYS_DST_SUP, RSVD_63));
     1155/** @} */
     1156
     1157/** IVHD (I/O Virtualization Hardware Definition) Type 10h.
     1158 *  In accordance with the AMD spec. */
     1159typedef struct ACPIIVHDTYPE10
     1160{
     1161    uint8_t         u8Type;                 /**< Type: Must be 0x10. */
     1162    uint8_t         u8Flags;                /**< Flags (see ACPI_IVHD_10H_F_XXX). */
     1163    uint16_t        u16Length;              /**< Length of IVHD including IVHD device entries. */
     1164    uint16_t        u16DeviceId;            /**< Device ID of the IOMMU. */
     1165    uint16_t        u16CapOffset;           /**< Offset in Capability space for control fields of IOMMU. */
     1166    uint64_t        u64BaseAddress;         /**< Base address of IOMMU control registers in MMIO space. */
     1167    uint16_t        u16PciSegmentGroup;     /**< PCI segment group number. */
     1168    uint16_t        u16IommuInfo;           /**< Interrupt number and Unit ID. */
     1169    uint32_t        u32Features;            /**< IOMMU feature reporting. */
     1170    /* IVHD device entry block follows. */
     1171} ACPIIVHDTYPE10;
     1172AssertCompileSize(ACPIIVHDTYPE10, 24);
     1173
     1174/** @name IVHD Type 11h Flags.
     1175 * In accordance with the AMD spec.
     1176 * @{ */
     1177/** Coherent control. */
     1178#define ACPI_IVHD_11H_F_COHERENT                        RT_BIT(5)
     1179/** Remote IOTLB support. */
     1180#define ACPI_IVHD_11H_F_IOTLB_SUP                       RT_BIT(4)
     1181/** Isochronous control. */
     1182#define ACPI_IVHD_11H_F_ISOC                            RT_BIT(3)
     1183/** Response Pass Posted Write. */
     1184#define ACPI_IVHD_11H_F_RES_PASS_PW                     RT_BIT(2)
     1185/** Pass Posted Write. */
     1186#define ACPI_IVHD_11H_F_PASS_PW                         RT_BIT(1)
     1187/** HyperTransport Tunnel. */
     1188#define ACPI_IVHD_11H_F_HT_TUNNEL                       RT_BIT(0)
     1189/** @} */
     1190
     1191/** @name IVHD IOMMU Type 11 Attributes field.
     1192 * In accordance with the AMD spec.
     1193 * @{ */
     1194/** Bits 12:0 reserved. */
     1195#define ACPI_IOMMU_ATTR_BF_RSVD_0_12_SHIFT              0
     1196#define ACPI_IOMMU_ATTR_BF_RSVD_0_12_MASK               UINT32_C(0x00001fff)
     1197/** PNCounters: Number of performance counters per counter bank. */
     1198#define ACPI_IOMMU_ATTR_BF_PN_COUNTERS_SHIFT            13
     1199#define ACPI_IOMMU_ATTR_BF_PN_COUNTERS_MASK             UINT32_C(0x0001e000)
     1200/** PNBanks: Number of performance counter banks. */
     1201#define ACPI_IOMMU_ATTR_BF_PN_BANKS_SHIFT               17
     1202#define ACPI_IOMMU_ATTR_BF_PN_BANKS_MASK                UINT32_C(0x007e0000)
     1203/** MSINumPPR: MSI number for peripheral page requests (PPR). */
     1204#define ACPI_IOMMU_ATTR_BF_MSI_NUM_PPR_SHIFT            23
     1205#define ACPI_IOMMU_ATTR_BF_MSI_NUM_PPR_MASK             UINT32_C(0x0f800000)
     1206/** Bits 31:28 reserved. */
     1207#define ACPI_IOMMU_ATTR_BF_RSVD_28_31_SHIFT             28
     1208#define ACPI_IOMMU_ATTR_BF_RSVD_28_31_MASK              UINT32_C(0xf0000000)
     1209RT_BF_ASSERT_COMPILE_CHECKS(ACPI_IOMMU_ATTR_BF_, UINT32_C(0), UINT32_MAX,
     1210                            (RSVD_0_12, PN_COUNTERS, PN_BANKS, MSI_NUM_PPR, RSVD_28_31));
     1211/** @} */
     1212
     1213/** AMD IOMMU: IVHD (I/O Virtualization Hardware Definition) Type 11h.
     1214 *  In accordance with the AMD spec. */
     1215typedef struct ACPIIVHDTYPE11
     1216{
     1217    uint8_t         u8Type;                 /**< Type: Must be 0x11. */
     1218    uint8_t         u8Flags;                /**< Flags. */
     1219    uint16_t        u16Length;              /**< Length: Size starting from Type fields incl. IVHD device entries. */
     1220    uint16_t        u16DeviceId;            /**< Device ID of the IOMMU. */
     1221    uint16_t        u16CapOffset;           /**< Offset in Capability space for control fields of IOMMU. */
     1222    uint64_t        u64BaseAddress;         /**< Base address of IOMMU control registers in MMIO space. */
     1223    uint16_t        u16PciSegmentGroup;     /**< PCI segment group number. */
     1224    uint16_t        u16IommuInfo;           /**< Interrupt number and unit ID. */
     1225    uint32_t        u32IommuAttr;           /**< IOMMU info. not reported in EFR. */
     1226    uint64_t        u64EfrRegister;         /**< Extended Feature Register (must be identical to its MMIO shadow). */
     1227    uint64_t        u64Rsvd0;               /**< Reserved for future. */
     1228    /* IVHD device entry block follows. */
     1229} ACPIIVHDTYPE11;
     1230AssertCompileSize(ACPIIVHDTYPE11, 40);
     1231
     1232/** AMD IOMMU: IVHD (I/O Virtualization Hardware Definition) Type 40h.
     1233 *  In accordance with the AMD spec. */
     1234typedef struct ACPIIVHDTYPE11 ACPIIVHDTYPE40;
     1235
     1236/** AMD IOMMU: IVRS (I/O Virtualization Reporting Structure).
     1237 *  In accordance with the AMD spec. */
     1238typedef struct ACPIIVRS
     1239{
     1240    ACPITBLHEADER       header;
     1241    uint32_t            u32IvInfo;  /**< IVInfo: I/O virtualization info. common to all IOMMUs in the system. */
     1242    uint64_t            u64Rsvd;    /**< Reserved (MBZ). */
     1243    /* IVHD type block follows. */
     1244} ACPIIVRS;
     1245AssertCompileSize(ACPIIVRS, 48);
     1246AssertCompileMemberOffset(ACPIIVRS, u32IvInfo, 36);
     1247
     1248/**
     1249 * AMD IOMMU: The ACPI table.
     1250 */
     1251typedef struct ACPITBLIOMMU
     1252{
     1253    ACPIIVRS            Hdr;
     1254    ACPIIVHDTYPE10      IvhdType10;
     1255    ACPIIVHDDEVENTRY4   IvhdType10Start;
     1256    ACPIIVHDDEVENTRY4   IvhdType10End;
     1257    ACPIIVHDDEVENTRY4   IvhdType10Rsvd0;
     1258    ACPIIVHDDEVENTRY4   IvhdType10Rsvd1;
     1259    ACPIIVHDDEVENTRY8   IvhdType10IoApic;
     1260    ACPIIVHDDEVENTRY8   IvhdType10Hpet;
     1261
     1262    ACPIIVHDTYPE11      IvhdType11;
     1263    ACPIIVHDDEVENTRY4   IvhdType11Start;
     1264    ACPIIVHDDEVENTRY4   IvhdType11End;
     1265    ACPIIVHDDEVENTRY4   IvhdType11Rsvd0;
     1266    ACPIIVHDDEVENTRY4   IvhdType11Rsvd1;
     1267    ACPIIVHDDEVENTRY8   IvhdType11IoApic;
     1268    ACPIIVHDDEVENTRY8   IvhdType11Hpet;
     1269} ACPITBLIOMMU;
     1270AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType10Start, 4);
     1271AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType10End, 4);
     1272AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType11Start, 4);
     1273AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType11End, 4);
     1274#endif
     1275
    7791276/** MCFG Descriptor Structure */
    7801277typedef struct ACPITBLMCFG
     
    13481845{
    13491846    RT_NOREF(pvUser, offPort);
    1350     Log(("acpiR3SysInfoIndexWrite: %#x (%#x)\n", u32, u32 >> 2));
     1847    LogRel(("acpiR3SysInfoIndexWrite: %#x (%#x)\n", u32, u32 >> 2));
    13511848    if (cb != 4)
    13521849        return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d offPort=%u u32=%#x\n", cb, offPort, u32);
     
    13671864
    13681865        u32 >>= pThis->u8IndexShift;
    1369         Assert(u32 < SYSTEM_INFO_INDEX_END);
     1866        AssertMsg(u32 < SYSTEM_INFO_INDEX_END, ("%u - Max=%u. IndexShift=%u\n", u32, SYSTEM_INFO_INDEX_END, pThis->u8IndexShift));
    13701867        pThis->uSystemInfoIndex = u32;
    13711868    }
     
    15542051        case SYSTEM_INFO_INDEX_PARALLEL1_IRQ:
    15552052            *pu32 = pThis->uParallel1Irq;
     2053            break;
     2054
     2055        case SYSTEM_INFO_INDEX_IOMMU_AMD_ADDRESS:
     2056            *pu32 = pThis->u32IommuAmdPciAddress;
     2057            break;
     2058
     2059        case SYSTEM_INFO_INDEX_SB_IOAPIC_ADDRESS:
     2060            *pu32 = pThis->u32SbIoApicPciAddress;
    15562061            break;
    15572062
     
    31033608
    31043609
     3610#ifdef VBOX_WITH_IOMMU_AMD
     3611/**
     3612 * Plant the AMD IOMMU descriptor.
     3613 */
     3614static void acpiR3SetupIommuAmd(PPDMDEVINS pDevIns, PACPISTATE pThis, RTGCPHYS32 addr)
     3615{
     3616    ACPITBLIOMMU Ivrs;
     3617    RT_ZERO(Ivrs);
     3618
     3619    /* IVRS header. */
     3620    acpiR3PrepareHeader(pThis, &Ivrs.Hdr.header, "IVRS", sizeof(Ivrs), ACPI_IVRS_FMT_REV_FIXED);
     3621    /* NOTE! The values here must match what we expose via MMIO/PCI config. space in the IOMMU device code. */
     3622    Ivrs.Hdr.u32IvInfo = RT_BF_MAKE(ACPI_IVINFO_BF_EFR_SUP,   1)
     3623                       | RT_BF_MAKE(ACPI_IVINFO_BF_GVA_SIZE,  0)
     3624                       | RT_BF_MAKE(ACPI_IVINFO_BF_GVA_SIZE,  2)    /* Guest Virt. Addr size (2=48 bits) */
     3625                       | RT_BF_MAKE(ACPI_IVINFO_BF_PA_SIZE,  48)    /* Physical Addr size (48 bits) */
     3626                       | RT_BF_MAKE(ACPI_IVINFO_BF_VA_SIZE,  64);   /* Virt. Addr size (64 bits) */
     3627
     3628    /* IVHD type 10 definition block. */
     3629    Ivrs.IvhdType10.u8Type             = 0x10;
     3630    Ivrs.IvhdType10.u16Length          = sizeof(Ivrs.IvhdType10)
     3631                                       + sizeof(Ivrs.IvhdType10Start)
     3632                                       + sizeof(Ivrs.IvhdType10End)
     3633                                       + sizeof(Ivrs.IvhdType10Rsvd0)
     3634                                       + sizeof(Ivrs.IvhdType10Rsvd1)
     3635                                       + sizeof(Ivrs.IvhdType10IoApic)
     3636                                       + sizeof(Ivrs.IvhdType10Hpet);
     3637    Ivrs.IvhdType10.u16DeviceId        = pThis->u32IommuAmdPciAddress;
     3638    Ivrs.IvhdType10.u16CapOffset       = 0;             /* 0=No multiple IOMMU functionality. */
     3639    Ivrs.IvhdType10.u64BaseAddress     = 0xfeb80000;    /* MMIO base address: Taken from real hardware ACPI dumps. */
     3640    Ivrs.IvhdType10.u16PciSegmentGroup = 0;
     3641    /* NOTE! Subfields in the following fields must match any corresponding field in PCI/MMIO registers of the IOMMU device. */
     3642    Ivrs.IvhdType10.u8Flags            = 0; /* Remote IOTLB, Prefetch IOMMU pages features etc. - currently none supported. */
     3643    Ivrs.IvhdType10.u16IommuInfo       = RT_BF_MAKE(ACPI_IOMMU_INFO_BF_MSI_NUM, 0)
     3644                                       | RT_BF_MAKE(ACPI_IOMMU_INFO_BF_UNIT_ID, 0);
     3645    Ivrs.IvhdType10.u32Features        = RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_XT_SUP,      0)
     3646                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_NX_SUP,      0)
     3647                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_GT_SUP,      0)
     3648                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_GLX_SUP,     0)
     3649                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_IA_SUP,      1)
     3650                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_GA_SUP,      0)
     3651                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_HE_SUP,      1)
     3652                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_PAS_MAX,     0)
     3653                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_PN_COUNTERS, 0)
     3654                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_PN_BANKS,    0)
     3655                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_PN_COUNTERS, 0)
     3656                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_MSI_NUM_PPR, 0)
     3657                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_GATS,        0)
     3658                                       | RT_BF_MAKE(ACPI_IOMMU_FEAT_BF_HATS,        6 & 3); /* IOMMU_MAX_HOST_PT_LEVEL & 3*/
     3659    /* Start range from BDF (00:01:00). */
     3660    Ivrs.IvhdType10Start.u8DevEntryType = ACPI_IVHD_DEVENTRY_TYPE_START_RANGE;
     3661    Ivrs.IvhdType10Start.u16DevId       = PCIBDF_MAKE(0, VBOX_PCI_DEVFN_MAKE(1, 0));
     3662    Ivrs.IvhdType10Start.u8DteSetting   = 0;
     3663    /* End range at BDF (ff:1f:7). */
     3664    Ivrs.IvhdType10End.u8DevEntryType   = ACPI_IVHD_DEVENTRY_TYPE_END_RANGE;
     3665    Ivrs.IvhdType10End.u16DevId         = PCIBDF_MAKE(0xff, VBOX_PCI_DEVFN_MAKE(0x1f, 7U));
     3666    Ivrs.IvhdType10End.u8DteSetting     = 0;
     3667
     3668    /* Southbridge I/O APIC special device entry. */
     3669    Ivrs.IvhdType10IoApic.u8DevEntryType          = 0x48;
     3670    Ivrs.IvhdType10IoApic.u.special.u16Rsvd0      = 0;
     3671    Ivrs.IvhdType10IoApic.u.special.u8DteSetting  = RT_BF_MAKE(ACPI_IVHD_DTE_INIT_PASS,   1)
     3672                                                  | RT_BF_MAKE(ACPI_IVHD_DTE_EXTINT_PASS, 1)
     3673                                                  | RT_BF_MAKE(ACPI_IVHD_DTE_NMI_PASS,    1)
     3674                                                  | RT_BF_MAKE(ACPI_IVHD_DTE_LINT0_PASS,  1)
     3675                                                  | RT_BF_MAKE(ACPI_IVHD_DTE_LINT1_PASS,  1);
     3676    Ivrs.IvhdType10IoApic.u.special.u8Handle      = pThis->cCpus;   /* The I/O APIC ID, see u8IOApicId in acpiR3SetupMadt(). */
     3677    Ivrs.IvhdType10IoApic.u.special.u16DevIdB     = VBOX_PCI_BDF_SB_IOAPIC;
     3678    Ivrs.IvhdType10IoApic.u.special.u8Variety     = ACPI_IVHD_VARIETY_IOAPIC;
     3679
     3680    /* HPET special device entry. */
     3681    Ivrs.IvhdType10Hpet.u8DevEntryType          = 0x48;
     3682    Ivrs.IvhdType10Hpet.u.special.u16Rsvd0      = 0;
     3683    Ivrs.IvhdType10Hpet.u.special.u8DteSetting  = 0;
     3684    Ivrs.IvhdType10Hpet.u.special.u8Handle      = 0; /* HPET number. ASSUMING it's identical to u32Number in acpiR3SetupHpet(). */
     3685    Ivrs.IvhdType10Hpet.u.special.u16DevIdB     = VBOX_PCI_BDF_SB_IOAPIC;   /* HPET goes through the I/O APIC. */
     3686    Ivrs.IvhdType10Hpet.u.special.u8Variety     = ACPI_IVHD_VARIETY_HPET;
     3687
     3688    /* IVHD type 11 definition block. */
     3689    Ivrs.IvhdType11.u8Type             = 0x11;
     3690    Ivrs.IvhdType11.u16Length          = sizeof(Ivrs.IvhdType11)
     3691                                       + sizeof(Ivrs.IvhdType11Start)
     3692                                       + sizeof(Ivrs.IvhdType11End)
     3693                                       + sizeof(Ivrs.IvhdType11Rsvd0)
     3694                                       + sizeof(Ivrs.IvhdType11Rsvd1)
     3695                                       + sizeof(Ivrs.IvhdType11IoApic)
     3696                                       + sizeof(Ivrs.IvhdType11Hpet);
     3697    Ivrs.IvhdType11.u16DeviceId        = Ivrs.IvhdType10.u16DeviceId;
     3698    Ivrs.IvhdType11.u16CapOffset       = Ivrs.IvhdType10.u16CapOffset;
     3699    Ivrs.IvhdType11.u64BaseAddress     = Ivrs.IvhdType10.u64BaseAddress;
     3700    Ivrs.IvhdType11.u16PciSegmentGroup = Ivrs.IvhdType10.u16PciSegmentGroup;
     3701    Ivrs.IvhdType11.u8Flags            = Ivrs.IvhdType10.u8Flags;
     3702    Ivrs.IvhdType11.u16IommuInfo       = Ivrs.IvhdType10.u16IommuInfo;
     3703    Ivrs.IvhdType11.u32IommuAttr       = RT_BF_MAKE(ACPI_IOMMU_ATTR_BF_PN_COUNTERS, 0)
     3704                                       | RT_BF_MAKE(ACPI_IOMMU_ATTR_BF_PN_BANKS,    0)
     3705                                       | RT_BF_MAKE(ACPI_IOMMU_ATTR_BF_MSI_NUM_PPR, 0);
     3706    /* NOTE! The feature bits below must match the IOMMU device code (MMIO/PCI access of the EFR register). */
     3707    Ivrs.IvhdType11.u64EfrRegister     = RT_BF_MAKE(IOMMU_EXT_FEAT_BF_PREF_SUP,           0)
     3708                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_PPR_SUP,            0)
     3709                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_X2APIC_SUP,         0)
     3710                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_NO_EXEC_SUP,        0)
     3711                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_GT_SUP,             0)
     3712                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_IA_SUP,             0)
     3713                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_GA_SUP,             0)
     3714                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_HE_SUP,             1)
     3715                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_PC_SUP,             0)
     3716                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_HATS,               6 /* IOMMU_MAX_HOST_PT_LEVEL */ & 3)
     3717                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_GATS,               0)
     3718                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_GLX_SUP,            0)
     3719                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_SMI_FLT_SUP,        0)
     3720                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_SMI_FLT_REG_CNT,    0)
     3721                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_GAM_SUP,            0)
     3722                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_DUAL_PPR_LOG_SUP,   0)
     3723                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_DUAL_EVT_LOG_SUP,   0)
     3724                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_PASID_MAX,          0)
     3725                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_US_SUP,             0)
     3726                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_DEV_TBL_SEG_SUP,    3 /* IOMMU_MAX_DEV_TAB_SEGMENTS */)
     3727                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_PPR_OVERFLOW_EARLY, 0)
     3728                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_PPR_AUTO_RES_SUP,   0)
     3729                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_MARC_SUP,           0)
     3730                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_BLKSTOP_MARK_SUP,   0)
     3731                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_PERF_OPT_SUP,       0)
     3732                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_MSI_CAP_MMIO_SUP,   1)
     3733                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_GST_IO_PROT_SUP,    0)
     3734                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_HST_ACCESS_SUP,     0)
     3735                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_ENHANCED_PPR_SUP,   0)
     3736                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_ATTR_FW_SUP,        0)
     3737                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_HST_DIRTY_SUP,      0)
     3738                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_INV_IOTLB_TYPE_SUP, 0)
     3739                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_GA_UPDATE_DIS_SUP,  0)
     3740                                       | RT_BF_MAKE(IOMMU_EXT_FEAT_BF_FORCE_PHYS_DST_SUP, 0);
     3741
     3742    /* The IVHD type 11 entries can be copied from their type 10 counterparts. */
     3743    Ivrs.IvhdType11Start  = Ivrs.IvhdType10Start;
     3744    Ivrs.IvhdType11End    = Ivrs.IvhdType10End;
     3745    Ivrs.IvhdType11Rsvd0  = Ivrs.IvhdType10Rsvd0;
     3746    Ivrs.IvhdType11Rsvd1  = Ivrs.IvhdType10Rsvd1;
     3747    Ivrs.IvhdType11IoApic = Ivrs.IvhdType10IoApic;
     3748    Ivrs.IvhdType11Hpet   = Ivrs.IvhdType10Hpet;
     3749
     3750    /* Finally, Compute checksum. */
     3751    Ivrs.Hdr.header.u8Checksum = acpiR3Checksum(&Ivrs, sizeof(Ivrs));
     3752
     3753    /* Plant the ACPI table. */
     3754    acpiR3PhysCopy(pDevIns, addr, (const uint8_t *)&Ivrs, sizeof(Ivrs));
     3755}
     3756#endif
     3757
     3758
    31053759/**
    31063760 * Used by acpiR3PlantTables to plant a MMCONFIG PCI config space access (MCFG)
     
    32023856    RTGCPHYS32 GCPhysCur, GCPhysRsdt, GCPhysXsdt, GCPhysFadtAcpi1, GCPhysFadtAcpi2, GCPhysFacs, GCPhysDsdt;
    32033857    RTGCPHYS32 GCPhysHpet = 0;
     3858#ifdef VBOX_WITH_IOMMU_AMD
     3859    RTGCPHYS32 GCPhysIommuAmd = 0;
     3860#endif
    32043861    RTGCPHYS32 GCPhysApic = 0;
    32053862    RTGCPHYS32 GCPhysSsdt = 0;
     
    32073864    RTGCPHYS32 aGCPhysCust[MAX_CUST_TABLES] = {0};
    32083865    uint32_t   addend = 0;
     3866#ifdef VBOX_WITH_IOMMU_AMD
     3867    RTGCPHYS32 aGCPhysRsdt[8 + MAX_CUST_TABLES];
     3868    RTGCPHYS32 aGCPhysXsdt[8 + MAX_CUST_TABLES];
     3869#else
    32093870    RTGCPHYS32 aGCPhysRsdt[7 + MAX_CUST_TABLES];
    32103871    RTGCPHYS32 aGCPhysXsdt[7 + MAX_CUST_TABLES];
     3872#endif
    32113873    uint32_t   cAddr;
    32123874    uint32_t   iMadt  = 0;
    32133875    uint32_t   iHpet  = 0;
     3876#ifdef VBOX_WITH_IOMMU_AMD
     3877    uint32_t   iIommuAmd = 0;
     3878#endif
    32143879    uint32_t   iSsdt  = 0;
    32153880    uint32_t   iMcfg  = 0;
     
    32243889    if (pThis->fUseHpet)
    32253890        iHpet = cAddr++;        /* HPET */
     3891
     3892#ifdef VBOX_WITH_IOMMU_AMD
     3893    if (pThis->u32IommuAmdPciAddress)
     3894        iIommuAmd = cAddr++;    /* IOMMU (AMD) */
     3895#endif
    32263896
    32273897    if (pThis->fUseMcfg)
     
    32993969        GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLHPET), 16);
    33003970    }
     3971#ifdef VBOX_WITH_IOMMU_AMD
     3972    if (pThis->u32IommuAmdPciAddress)
     3973    {
     3974        GCPhysIommuAmd = GCPhysCur;
     3975        GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLIOMMU), 16);
     3976    }
     3977#endif
    33013978    if (pThis->fUseMcfg)
    33023979    {
     
    33714048        aGCPhysXsdt[iHpet] = GCPhysHpet + addend;
    33724049    }
     4050#ifdef VBOX_WITH_IOMMU_AMD
     4051    if (pThis->u32IommuAmdPciAddress)
     4052    {
     4053        acpiR3SetupIommuAmd(pDevIns, pThis, GCPhysIommuAmd + addend);
     4054        aGCPhysRsdt[iIommuAmd] = GCPhysIommuAmd + addend;
     4055        aGCPhysXsdt[iIommuAmd] = GCPhysIommuAmd + addend;
     4056    }
     4057#endif
    33734058    if (pThis->fUseMcfg)
    33744059    {
     
    37274412                                  "|Parallel0Irq"
    37284413                                  "|Parallel1Irq"
     4414                                  "|IommuAmdPciAddress"
     4415                                  "|SbIoApicPciAddress"
    37294416                                  , "");
    37304417
     
    38824569    if (RT_FAILURE(rc))
    38834570        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"Parallel1IoPortBase\""));
     4571
     4572#ifdef VBOX_WITH_IOMMU_AMD
     4573    /* Query IOMMU AMD address (IOMA). */
     4574    rc = pHlp->pfnCFGMQueryU32Def(pCfg, "IommuAmdPciAddress", &pThis->u32IommuAmdPciAddress, 0);
     4575    if (RT_FAILURE(rc))
     4576        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"IommuAmdAddress\""));
     4577
     4578    /* Query southbridge I/O APIC address (required when an AMD IOMMU is configured). */
     4579    rc = pHlp->pfnCFGMQueryU32Def(pCfg, "SbIoApicPciAddress", &pThis->u32SbIoApicPciAddress, 0);
     4580    if (RT_FAILURE(rc))
     4581        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"SbIoApicAddress\""));
     4582
     4583    /* Warn if the SB IOAPIC is not at the required address if an AMD IOMMU is configured. */
     4584    if (   pThis->u32IocPciAddress
     4585        && pThis->u32SbIoApicPciAddress != VBOX_PCI_BDF_SB_IOAPIC)
     4586    {
     4587        /** @todo Maybe make this a VM startup failure later. */
     4588        LogRel(("ACPI: Warning! Southbridge I/O APIC not at %#x:%#x:%#x when an AMD IOMMU is present.\n",
     4589                VBOX_PCI_BUS_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC, VBOX_PCI_FN_SB_IOAPIC));
     4590    }
     4591#endif
    38844592
    38854593    /* Try to attach the other CPUs */
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