From: Wei Wang Date: Tue, 22 Nov 2011 13:25:42 +0000 (+0000) Subject: amd iommu: Advertise iommu extended feature bits to xen. X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7e82d0d14ac2b27e09a53daa5943d907f625d514;p=xen.git amd iommu: Advertise iommu extended feature bits to xen. Signed-off-by: Wei Wang Committed-by: Keir Fraser --- diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c index e0bce2d390..0bf933b110 100644 --- a/xen/drivers/passthrough/amd/iommu_detect.c +++ b/xen/drivers/passthrough/amd/iommu_detect.c @@ -62,6 +62,47 @@ static int __init get_iommu_capabilities( return 0; } +void __init get_iommu_features(struct amd_iommu *iommu) +{ + u32 low, high; + int i = 0 ; + char * feature_str[] = { + "- Prefetch Pages Command", + "- Peripheral Page Service Request", + "- X2APIC Supported", + "- NX bit Supported", + "- Guest Translation", + "- Reserved bit [5]", + "- Invalidate All Command", + "- Guest APIC supported", + "- Hardware Error Registers", + "- Performance Counters", + NULL + }; + + ASSERT( iommu->mmio_base ); + + if ( !iommu_has_cap(iommu, PCI_CAP_EFRSUP_SHIFT) ) + { + iommu->features = 0; + return; + } + + low = readl(iommu->mmio_base + IOMMU_EXT_FEATURE_MMIO_OFFSET); + high = readl(iommu->mmio_base + IOMMU_EXT_FEATURE_MMIO_OFFSET + 4); + + iommu->features = ((u64)high << 32) | low; + + printk("AMD-Vi: IOMMU Extended Features:\n"); + + while ( feature_str[i] ) + { + if ( iommu_has_feature(iommu, i) ) + printk( " %s\n", feature_str[i]); + i++; + } +} + int __init amd_iommu_detect_one_acpi(void *ivhd) { struct amd_iommu *iommu; diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c index 9ccd1f497d..854d092e51 100644 --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -684,6 +684,8 @@ static int __init amd_iommu_init_one(struct amd_iommu *iommu) iommu->dev_table.entries = device_table.entries; iommu->dev_table.buffer = device_table.buffer; + get_iommu_features(iommu); + enable_iommu(iommu); printk("AMD-Vi: IOMMU %d Enabled.\n", nr_amd_iommus ); nr_amd_iommus++; diff --git a/xen/include/asm-x86/amd-iommu.h b/xen/include/asm-x86/amd-iommu.h index 9346da88b0..876d9b998a 100644 --- a/xen/include/asm-x86/amd-iommu.h +++ b/xen/include/asm-x86/amd-iommu.h @@ -54,6 +54,7 @@ struct amd_iommu { iommu_cap_t cap; u8 ht_flags; + u64 features; void *mmio_base; unsigned long mmio_base_phys; diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h index b5c35b0027..59d33e98d0 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h @@ -54,6 +54,7 @@ #define PCI_CAP_HT_TUNNEL_SHIFT 25 #define PCI_CAP_NP_CACHE_MASK 0x04000000 #define PCI_CAP_NP_CACHE_SHIFT 26 +#define PCI_CAP_EFRSUP_SHIFT 27 #define PCI_CAP_RESET_MASK 0x80000000 #define PCI_CAP_RESET_SHIFT 31 @@ -327,6 +328,26 @@ #define IOMMU_EXCLUSION_LIMIT_HIGH_MASK 0xFFFFFFFF #define IOMMU_EXCLUSION_LIMIT_HIGH_SHIFT 0 +/* Extended Feature Register*/ +#define IOMMU_EXT_FEATURE_MMIO_OFFSET 0x30 +#define IOMMU_EXT_FEATURE_PREFSUP_SHIFT 0x0 +#define IOMMU_EXT_FEATURE_PPRSUP_SHIFT 0x1 +#define IOMMU_EXT_FEATURE_XTSUP_SHIFT 0x2 +#define IOMMU_EXT_FEATURE_NXSUP_SHIFT 0x3 +#define IOMMU_EXT_FEATURE_GTSUP_SHIFT 0x4 +#define IOMMU_EXT_FEATURE_IASUP_SHIFT 0x6 +#define IOMMU_EXT_FEATURE_GASUP_SHIFT 0x7 +#define IOMMU_EXT_FEATURE_HESUP_SHIFT 0x8 +#define IOMMU_EXT_FEATURE_PCSUP_SHIFT 0x9 +#define IOMMU_EXT_FEATURE_HATS_SHIFT 0x10 +#define IOMMU_EXT_FEATURE_HATS_MASK 0x00000C00 +#define IOMMU_EXT_FEATURE_GATS_SHIFT 0x12 +#define IOMMU_EXT_FEATURE_GATS_MASK 0x00003000 +#define IOMMU_EXT_FEATURE_GLXSUP 0x14 + +#define IOMMU_EXT_FEATURE_PASMAX_SHIFT 0x0 +#define IOMMU_EXT_FEATURE_PASMAX_MASK 0x0000001F + /* Status Register*/ #define IOMMU_STATUS_MMIO_OFFSET 0x2020 #define IOMMU_STATUS_EVENT_OVERFLOW_MASK 0x00000001 diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h index c67f463f8b..c639bf54c7 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h @@ -43,6 +43,7 @@ int amd_iommu_get_ivrs_dev_entries(void); int amd_iommu_detect_one_acpi(void *ivhd); int amd_iommu_detect_acpi(void); +void get_iommu_features(struct amd_iommu *iommu); /* amd-iommu-init functions */ int amd_iommu_init(void); @@ -183,8 +184,14 @@ static inline uint32_t iommu_get_bit(uint32_t reg, uint32_t bit) static inline int iommu_has_cap(struct amd_iommu *iommu, uint32_t bit) { - u32 mask = 1U << bit; - return iommu->cap.header & mask; + return !!(iommu->cap.header & (1u << bit)); +} + +static inline int iommu_has_feature(struct amd_iommu *iommu, uint32_t bit) +{ + if ( !iommu_has_cap(iommu, PCI_CAP_EFRSUP_SHIFT) ) + return 0; + return !!(iommu->features & (1U << bit)); } #endif /* _ASM_X86_64_AMD_IOMMU_PROTO_H */