- Timestamp:
- Aug 7, 2020 9:34:12 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevACPI.cpp
r85347 r85639 27 27 #include <VBox/log.h> 28 28 #include <VBox/param.h> 29 #include <VBox/pci.h> 29 30 #include <iprt/assert.h> 30 31 #include <iprt/asm.h> … … 384 385 /** PCI address of the host bus controller device. */ 385 386 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; 386 391 387 392 /** Physical address of PCI config space MMIO region */ … … 502 507 /** Pointer to the shared ACPI device state. */ 503 508 typedef ACPISTATE *PACPISTATE; 509 504 510 505 511 … … 777 783 AssertCompileSize(ACPITBLHPET, 56); 778 784 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) 846 RT_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. */ 852 typedef 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; 858 AssertCompileSize(ACPIIVHDDEVENTRY4, 4); 859 860 /** AMD IOMMU: IVHD (I/O Virtualization Hardware Definition) Device Entry 861 * (8-byte). In accordance with the AMD spec. */ 862 typedef 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; 899 AssertCompileSize(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) 950 RT_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) 969 RT_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) 1015 RT_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) 1148 RT_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. */ 1159 typedef 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; 1172 AssertCompileSize(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) 1209 RT_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. */ 1215 typedef 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; 1230 AssertCompileSize(ACPIIVHDTYPE11, 40); 1231 1232 /** AMD IOMMU: IVHD (I/O Virtualization Hardware Definition) Type 40h. 1233 * In accordance with the AMD spec. */ 1234 typedef struct ACPIIVHDTYPE11 ACPIIVHDTYPE40; 1235 1236 /** AMD IOMMU: IVRS (I/O Virtualization Reporting Structure). 1237 * In accordance with the AMD spec. */ 1238 typedef 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; 1245 AssertCompileSize(ACPIIVRS, 48); 1246 AssertCompileMemberOffset(ACPIIVRS, u32IvInfo, 36); 1247 1248 /** 1249 * AMD IOMMU: The ACPI table. 1250 */ 1251 typedef 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; 1270 AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType10Start, 4); 1271 AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType10End, 4); 1272 AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType11Start, 4); 1273 AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType11End, 4); 1274 #endif 1275 779 1276 /** MCFG Descriptor Structure */ 780 1277 typedef struct ACPITBLMCFG … … 1348 1845 { 1349 1846 RT_NOREF(pvUser, offPort); 1350 Log (("acpiR3SysInfoIndexWrite: %#x (%#x)\n", u32, u32 >> 2));1847 LogRel(("acpiR3SysInfoIndexWrite: %#x (%#x)\n", u32, u32 >> 2)); 1351 1848 if (cb != 4) 1352 1849 return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "cb=%d offPort=%u u32=%#x\n", cb, offPort, u32); … … 1367 1864 1368 1865 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)); 1370 1867 pThis->uSystemInfoIndex = u32; 1371 1868 } … … 1554 2051 case SYSTEM_INFO_INDEX_PARALLEL1_IRQ: 1555 2052 *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; 1556 2061 break; 1557 2062 … … 3103 3608 3104 3609 3610 #ifdef VBOX_WITH_IOMMU_AMD 3611 /** 3612 * Plant the AMD IOMMU descriptor. 3613 */ 3614 static 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 3105 3759 /** 3106 3760 * Used by acpiR3PlantTables to plant a MMCONFIG PCI config space access (MCFG) … … 3202 3856 RTGCPHYS32 GCPhysCur, GCPhysRsdt, GCPhysXsdt, GCPhysFadtAcpi1, GCPhysFadtAcpi2, GCPhysFacs, GCPhysDsdt; 3203 3857 RTGCPHYS32 GCPhysHpet = 0; 3858 #ifdef VBOX_WITH_IOMMU_AMD 3859 RTGCPHYS32 GCPhysIommuAmd = 0; 3860 #endif 3204 3861 RTGCPHYS32 GCPhysApic = 0; 3205 3862 RTGCPHYS32 GCPhysSsdt = 0; … … 3207 3864 RTGCPHYS32 aGCPhysCust[MAX_CUST_TABLES] = {0}; 3208 3865 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 3209 3870 RTGCPHYS32 aGCPhysRsdt[7 + MAX_CUST_TABLES]; 3210 3871 RTGCPHYS32 aGCPhysXsdt[7 + MAX_CUST_TABLES]; 3872 #endif 3211 3873 uint32_t cAddr; 3212 3874 uint32_t iMadt = 0; 3213 3875 uint32_t iHpet = 0; 3876 #ifdef VBOX_WITH_IOMMU_AMD 3877 uint32_t iIommuAmd = 0; 3878 #endif 3214 3879 uint32_t iSsdt = 0; 3215 3880 uint32_t iMcfg = 0; … … 3224 3889 if (pThis->fUseHpet) 3225 3890 iHpet = cAddr++; /* HPET */ 3891 3892 #ifdef VBOX_WITH_IOMMU_AMD 3893 if (pThis->u32IommuAmdPciAddress) 3894 iIommuAmd = cAddr++; /* IOMMU (AMD) */ 3895 #endif 3226 3896 3227 3897 if (pThis->fUseMcfg) … … 3299 3969 GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLHPET), 16); 3300 3970 } 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 3301 3978 if (pThis->fUseMcfg) 3302 3979 { … … 3371 4048 aGCPhysXsdt[iHpet] = GCPhysHpet + addend; 3372 4049 } 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 3373 4058 if (pThis->fUseMcfg) 3374 4059 { … … 3727 4412 "|Parallel0Irq" 3728 4413 "|Parallel1Irq" 4414 "|IommuAmdPciAddress" 4415 "|SbIoApicPciAddress" 3729 4416 , ""); 3730 4417 … … 3882 4569 if (RT_FAILURE(rc)) 3883 4570 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 3884 4592 3885 4593 /* Try to attach the other CPUs */
Note:
See TracChangeset
for help on using the changeset viewer.