WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 5 of 6] amd iommu: Compress hyper-transport flags int

To: <JBeulich@xxxxxxxx>
Subject: [Xen-devel] [PATCH 5 of 6] amd iommu: Compress hyper-transport flags into a single byte
From: Wei Wang <wei.wang2@xxxxxxx>
Date: Wed, 9 Nov 2011 16:51:00 +0100
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Wed, 09 Nov 2011 07:54:23 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1320853855@xxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1320853855@xxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.9.3
# HG changeset patch
# User Wei Wang <wei.wang2@xxxxxxx>
# Date 1320852003 -3600
# Node ID c75cf540a1fe57a439f9cb0503bf69f120066b92
# Parent  60d51bc20139471cf71e3d6854534d4176853de2
amd iommu: Compress hyper-transport flags into a single byte.
These flags are single bit, no need to be saved as integers.
Add 3 inline helpers to make single bit access easier.
Introduce iommu_has_ht_flag and set_iommu_ht_flags

Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>

diff -r 60d51bc20139 -r c75cf540a1fe xen/drivers/passthrough/amd/iommu_detect.c
--- a/xen/drivers/passthrough/amd/iommu_detect.c        Wed Nov 09 16:20:02 
2011 +0100
+++ b/xen/drivers/passthrough/amd/iommu_detect.c        Wed Nov 09 16:20:03 
2011 +0100
@@ -98,25 +98,8 @@ int __init amd_iommu_detect_one_acpi(voi
     iommu->cap_offset = ivhd_block->cap_offset;
     iommu->mmio_base_phys = ivhd_block->mmio_base;
 
-    /* override IOMMU support flags */
-    iommu->coherent = get_field_from_byte(ivhd_block->header.flags,
-                        AMD_IOMMU_ACPI_COHERENT_MASK,
-                        AMD_IOMMU_ACPI_COHERENT_SHIFT);
-    iommu->iotlb_support = get_field_from_byte(ivhd_block->header.flags,
-                        AMD_IOMMU_ACPI_IOTLB_SUP_MASK,
-                        AMD_IOMMU_ACPI_IOTLB_SUP_SHIFT);
-    iommu->isochronous = get_field_from_byte(ivhd_block->header.flags,
-                        AMD_IOMMU_ACPI_ISOC_MASK,
-                        AMD_IOMMU_ACPI_ISOC_SHIFT);
-    iommu->res_pass_pw = get_field_from_byte(ivhd_block->header.flags,
-                        AMD_IOMMU_ACPI_RES_PASS_PW_MASK,
-                        AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT);
-    iommu->pass_pw = get_field_from_byte(ivhd_block->header.flags,
-                        AMD_IOMMU_ACPI_PASS_PW_MASK,
-                        AMD_IOMMU_ACPI_PASS_PW_SHIFT);
-    iommu->ht_tunnel_enable = get_field_from_byte(ivhd_block->header.flags,
-                        AMD_IOMMU_ACPI_HT_TUN_ENB_MASK,
-                        AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT);
+    /* override IOMMU HT flags */
+    iommu->ht_flags = ivhd_block->header.flags;
 
     bus = PCI_BUS(iommu->bdf);
     dev = PCI_SLOT(iommu->bdf);
diff -r 60d51bc20139 -r c75cf540a1fe xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c  Wed Nov 09 16:20:02 2011 +0100
+++ b/xen/drivers/passthrough/amd/iommu_init.c  Wed Nov 09 16:20:03 2011 +0100
@@ -28,6 +28,7 @@
 #include <asm/hvm/svm/amd-iommu-proto.h>
 #include <asm-x86/fixmap.h>
 #include <mach_apic.h>
+#include <asm/hvm/svm/amd-iommu-acpi.h>
 
 static int __initdata nr_amd_iommus;
 
@@ -36,6 +37,12 @@ static struct radix_tree_root ivrs_maps;
 struct list_head amd_iommu_head;
 struct table_struct device_table;
 
+static int iommu_has_ht_flag(struct amd_iommu *iommu, uint8_t bit)
+{
+    u8 mask = (1U << bit) & 0xff;
+    return iommu->ht_flags & mask;
+}
+
 static int __init map_iommu_mmio_region(struct amd_iommu *iommu)
 {
     unsigned long mfn;
@@ -66,6 +73,34 @@ static void __init unmap_iommu_mmio_regi
     }
 }
 
+static void set_iommu_ht_flags(struct amd_iommu *iommu)
+{
+    u32 entry;
+    entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
+
+    /* Setup HT flags */
+    iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT) ?
+        iommu_set_bit(&entry, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT):
+        iommu_clear_bit(&entry, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT);
+
+    iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT) ?
+        iommu_set_bit(&entry, IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT):
+        iommu_clear_bit(&entry, IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT);
+
+    iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_ISOC_SHIFT) ?
+        iommu_set_bit(&entry, IOMMU_CONTROL_ISOCHRONOUS_SHIFT):
+        iommu_clear_bit(&entry, IOMMU_CONTROL_ISOCHRONOUS_SHIFT);
+
+    iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_PASS_PW_SHIFT) ?
+        iommu_set_bit(&entry, IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT):
+        iommu_clear_bit(&entry, IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT);
+
+    /* Force coherent */
+    iommu_set_bit(&entry, IOMMU_CONTROL_COHERENT_SHIFT);
+
+    writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
+}
+
 static void register_iommu_dev_table_in_mmio_space(struct amd_iommu *iommu)
 {
     u64 addr_64, addr_lo, addr_hi;
@@ -150,33 +185,10 @@ static void set_iommu_translation_contro
 
     entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
 
-    if ( enable )
-    {
-        set_field_in_reg_u32(iommu->ht_tunnel_support ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_MASK,
-                         IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT, &entry);
-        set_field_in_reg_u32(iommu->isochronous ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_ISOCHRONOUS_MASK,
-                         IOMMU_CONTROL_ISOCHRONOUS_SHIFT, &entry);
-        set_field_in_reg_u32(iommu->coherent ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_COHERENT_MASK,
-                         IOMMU_CONTROL_COHERENT_SHIFT, &entry);
-        set_field_in_reg_u32(iommu->res_pass_pw ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_MASK,
-                         IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT, &entry);
-        /* do not set PassPW bit */
-        set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_PASS_POSTED_WRITE_MASK,
-                         IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT, &entry);
-    }
-    set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_TRANSLATION_ENABLE_MASK,
-                         IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT, &entry);
+    enable ?
+        iommu_set_bit(&entry, IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT):
+        iommu_clear_bit(&entry, IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT);
+
     writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
 }
 
@@ -186,17 +198,17 @@ static void set_iommu_command_buffer_con
     u32 entry;
 
     entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
-    set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_MASK,
-                         IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT, &entry);
 
     /*reset head and tail pointer manually before enablement */
-    if ( enable == IOMMU_CONTROL_ENABLED )
+    if ( enable )
     {
         writel(0x0, iommu->mmio_base + IOMMU_CMD_BUFFER_HEAD_OFFSET);
         writel(0x0, iommu->mmio_base + IOMMU_CMD_BUFFER_TAIL_OFFSET);
+
+        iommu_set_bit(&entry, IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT);
     }
+    else
+        iommu_clear_bit(&entry, IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT);
 
     writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
 }
@@ -247,24 +259,24 @@ static void set_iommu_event_log_control(
     u32 entry;
 
     entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
-    set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_EVENT_LOG_ENABLE_MASK,
-                         IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT, &entry);
-    set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
-                         IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_EVENT_LOG_INT_MASK,
-                         IOMMU_CONTROL_EVENT_LOG_INT_SHIFT, &entry);
-    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_CONTROL_COMP_WAIT_INT_MASK,
-                         IOMMU_CONTROL_COMP_WAIT_INT_SHIFT, &entry);
 
     /*reset head and tail pointer manually before enablement */
-    if ( enable == IOMMU_CONTROL_ENABLED )
+    if ( enable )
     {
         writel(0x0, iommu->mmio_base + IOMMU_EVENT_LOG_HEAD_OFFSET);
         writel(0x0, iommu->mmio_base + IOMMU_EVENT_LOG_TAIL_OFFSET);
+
+        iommu_set_bit(&entry, IOMMU_CONTROL_EVENT_LOG_INT_SHIFT);
+        iommu_set_bit(&entry, IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT);
     }
+    else
+    {
+        iommu_clear_bit(&entry, IOMMU_CONTROL_EVENT_LOG_INT_SHIFT);
+        iommu_clear_bit(&entry, IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT);
+    }
+
+    iommu_clear_bit(&entry, IOMMU_CONTROL_COMP_WAIT_INT_SHIFT);
+
     writel(entry, iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
 }
 
@@ -313,9 +325,7 @@ static void amd_iommu_reset_event_log(st
     /* wait until EventLogRun bit = 0 */
     do {
         entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-        log_run = get_field_from_reg_u32(entry,
-                                        IOMMU_STATUS_EVENT_LOG_RUN_MASK,
-                                        IOMMU_STATUS_EVENT_LOG_RUN_SHIFT);
+        log_run = iommu_get_bit(entry, IOMMU_STATUS_EVENT_LOG_RUN_SHIFT);
         loop_count--;
     } while ( log_run && loop_count );
 
@@ -330,11 +340,9 @@ static void amd_iommu_reset_event_log(st
 
     /* read event log for debugging */
     amd_iommu_read_event_log(iommu);
+    /*clear overflow bit */
+    iommu_clear_bit(&entry, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT);
 
-    /*clear overflow bit */
-    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry,
-                         IOMMU_STATUS_EVENT_OVERFLOW_MASK,
-                         IOMMU_STATUS_EVENT_OVERFLOW_SHIFT, &entry);
     writel(entry, iommu->mmio_base+IOMMU_STATUS_MMIO_OFFSET);
 
     /*reset event log base address */
@@ -519,7 +527,6 @@ static void amd_iommu_page_fault(int irq
 {
     u32 entry;
     unsigned long flags;
-    int of;
     struct amd_iommu *iommu = dev_id;
 
     spin_lock_irqsave(&iommu->lock, flags);
@@ -527,19 +534,14 @@ static void amd_iommu_page_fault(int irq
 
     /*check event overflow */
     entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-    of = get_field_from_reg_u32(entry,
-                               IOMMU_STATUS_EVENT_OVERFLOW_MASK,
-                               IOMMU_STATUS_EVENT_OVERFLOW_SHIFT);
 
-    /* reset event log if event overflow */
-    if ( of )
+    if ( iommu_get_bit(entry, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT) )
         amd_iommu_reset_event_log(iommu);
 
     /* reset interrupt status bit */
     entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
-                         IOMMU_STATUS_EVENT_LOG_INT_MASK,
-                         IOMMU_STATUS_EVENT_LOG_INT_SHIFT, &entry);
+    iommu_set_bit(&entry, IOMMU_STATUS_EVENT_LOG_INT_SHIFT);
+
     writel(entry, iommu->mmio_base+IOMMU_STATUS_MMIO_OFFSET);
     spin_unlock_irqrestore(&iommu->lock, flags);
 }
@@ -590,6 +592,7 @@ static void enable_iommu(struct amd_iomm
     iommu_msi_set_affinity(irq_to_desc(iommu->irq), &cpu_online_map);
     amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
 
+    set_iommu_ht_flags(iommu);
     set_iommu_command_buffer_control(iommu, IOMMU_CONTROL_ENABLED);
     set_iommu_event_log_control(iommu, IOMMU_CONTROL_ENABLED);
     set_iommu_translation_control(iommu, IOMMU_CONTROL_ENABLED);
diff -r 60d51bc20139 -r c75cf540a1fe xen/include/asm-x86/amd-iommu.h
--- a/xen/include/asm-x86/amd-iommu.h   Wed Nov 09 16:20:02 2011 +0100
+++ b/xen/include/asm-x86/amd-iommu.h   Wed Nov 09 16:20:03 2011 +0100
@@ -57,11 +57,7 @@ struct amd_iommu {
     u8 ht_tunnel_support;
     u8 iotlb_support;
 
-    u8 isochronous;
-    u8 coherent;
-    u8 res_pass_pw;
-    u8 pass_pw;
-    u8 ht_tunnel_enable;
+    u8 ht_flags;
 
     void *mmio_base;
     unsigned long mmio_base_phys;
diff -r 60d51bc20139 -r c75cf540a1fe 
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Wed Nov 09 16:20:02 
2011 +0100
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Wed Nov 09 16:20:03 
2011 +0100
@@ -166,4 +166,19 @@ static inline void __free_amd_iommu_tabl
     free_xenheap_pages(table, order);
 }
 
+static inline void iommu_set_bit(uint32_t *reg, uint32_t bit)
+{
+    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, *reg, 1U << bit, bit, reg);
+}
+
+static inline void iommu_clear_bit(uint32_t *reg, uint32_t bit)
+{
+    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, *reg, 1U << bit, bit, reg);
+}
+
+static inline uint32_t iommu_get_bit(uint32_t reg, uint32_t bit)
+{
+    return get_field_from_reg_u32(reg, 1U << bit, bit);
+}
+
 #endif /* _ASM_X86_64_AMD_IOMMU_PROTO_H */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel