@@ -33,6 +33,7 @@
#define ITS_CMD_QUEUE_SZ SZ_1M
+#define ACPI_GICV3_ITS_MEM_SIZE (SZ_64K)
/*
* No lock here, as this list gets only populated upon boot while scanning
* firmware tables for all host ITSes, and only gets iterated afterwards.
@@ -976,11 +977,35 @@ int gicv3_its_make_hwdom_dt_nodes(const struct
domain *d,
return res;
}
+/* Common function for addind to host_its_list
+*/
+static int add_to_host_its_list(u64 addr, u64 size,
+ u32 translation_id, const void *node)
+{
+ struct host_its *its_data;
+ its_data = xzalloc(struct host_its);
+
+ if ( !its_data )
+ return -1;
+
+ if ( node )
+ its_data->dt_node = node;
+
+ its_data->addr = addr;
+ its_data->size = size;
+ its_data->translation_id = translation_id;
+ printk("GICv3: Found ITS @0x%lx\n", addr);
+
+ list_add_tail(&its_data->entry, &host_its_list);
+
+ return 0;
+}
+
/* Scan the DT for any ITS nodes and create a list of host ITSes out
of it. */
void gicv3_its_dt_init(const struct dt_device_node *node)
{
const struct dt_device_node *its = NULL;
- struct host_its *its_data;
+ static int its_id = 1;
/*
* Check for ITS MSI subnodes. If any, add the ITS register
@@ -996,19 +1021,23 @@ void gicv3_its_dt_init(const struct
dt_device_node *node)
if ( dt_device_get_address(its, 0, &addr, &size) )
panic("GICv3: Cannot find a valid ITS frame address");
- its_data = xzalloc(struct host_its);
- if ( !its_data )
- panic("GICv3: Cannot allocate memory for ITS frame");
+ if ( add_to_host_its_list(addr, size, its_id++, its) )
+ panic("GICV3: Adding Host ITS failed ");
+ }
+}
- its_data->addr = addr;
- its_data->size = size;
- its_data->dt_node = its;
+#ifdef CONFIG_ACPI
+int gicv3_its_acpi_init(struct acpi_subtable_header *header, const
unsigned long end)
+{
+ struct acpi_madt_generic_translator *its_entry;
- printk("GICv3: Found ITS @0x%lx\n", addr);
+ its_entry = (struct acpi_madt_generic_translator *)header;
- list_add_tail(&its_data->entry, &host_its_list);
- }
+ return add_to_host_its_list(its_entry->base_address,
+ ACPI_GICV3_ITS_MEM_SIZE,
+ its_entry->translation_id, NULL);
}
+#endif
/*
* Local variables:
@@ -1567,6 +1567,12 @@ static void __init gicv3_acpi_init(void)
gicv3.rdist_stride = 0;
+ count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+ gicv3_its_acpi_init, 0);
+
+ if ( count <= 0 )
+ panic("GICv3: Can't get ITS entry");
+
/*
* In ACPI, 0 is considered as the invalid address. However the rest
* of the initialization rely on the invalid address to be
b/xen/include/asm-arm/gic_v3_its.h
@@ -105,6 +105,7 @@
#include <xen/device_tree.h>
#include <xen/rbtree.h>
+#include <xen/acpi.h>
#define HOST_ITS_FLUSH_CMD_QUEUE (1U << 0)
#define HOST_ITS_USES_PTA (1U << 1)
@@ -137,6 +138,11 @@ extern struct list_head host_its_list;
/* Parse the host DT and pick up all host ITSes. */
void gicv3_its_dt_init(const struct dt_device_node *node);
+#ifdef CONFIG_ACPI
+int gicv3_its_acpi_init(struct acpi_subtable_header *header,
+ const unsigned long end);
+#endif
+
bool gicv3_its_host_has_its(void);
unsigned int vgic_v3_its_count(const struct domain *d);
@@ -198,6 +204,14 @@ static inline void gicv3_its_dt_init(const struct
dt_device_node *node)
{
}
+#ifdef CONFIG_ACPI
+static inline int gicv3_its_acpi_init(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ return false;
+}
+#endif
+
static inline bool gicv3_its_host_has_its(void)
{
This patch adds gicv3_its_acpi_init. To avoid duplicate code for initializing and adding to host_its_list a common function add_to_host_its_list is added which is called by both _dt_init and _acpi_init. Signed-off-by: Manish Jaggi <mjaggi@cavium.com> --- xen/arch/arm/gic-v3-its.c | 49 ++++++++++++++++++++++++++++++++-------- xen/arch/arm/gic-v3.c | 6 +++++ xen/include/asm-arm/gic_v3_its.h | 14 ++++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) return false;