|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH 19/19] xen/arm: its: Initialize virtual and physical ITS driver
From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
Intialize physical ITS driver and virtual ITS driver
based on HW support information available in GICD_TYPER
register.
Based on outcome of lpi_supported() and gic_nr_id_bits()
functions ITS driver is initialized
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
---
xen/arch/arm/gic-v3-its.c | 10 ++++++++++
xen/arch/arm/gic-v3.c | 21 +++++++++++++++++++++
xen/arch/arm/gic.c | 10 ++++++++++
xen/arch/arm/setup.c | 1 +
xen/arch/arm/vgic-v3-its.c | 28 ++++++++++++++++++++--------
xen/arch/arm/vgic-v3.c | 1 +
xen/include/asm-arm/gic-its.h | 5 +++++
xen/include/asm-arm/gic.h | 8 ++++++++
xen/include/asm-arm/gic_v3_defs.h | 1 +
xen/include/asm-arm/vgic.h | 1 +
10 files changed, 78 insertions(+), 8 deletions(-)
diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index dbfda30..b2116d9 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -900,6 +900,16 @@ int its_make_dt_node(const struct domain *d,
return res;
}
+void its_domain_init(struct domain *d)
+{
+ if ( is_hardware_domain(d) )
+ {
+ d->arch.vits->phys_base = its->phys_base;
+ d->arch.vits->phys_size = its->phys_size;
+ }
+ /* TODO: To implement for domU */
+}
+
static int its_probe(struct dt_device_node *node)
{
paddr_t its_addr, its_size;
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index b654535..67d34a6 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -658,6 +658,11 @@ static int __init gicv3_populate_rdist(void)
return -ENODEV;
}
+static int gicv3_dist_supports_lpis(void)
+{
+ return readl_relaxed(GICD + GICD_TYPER) & GICD_TYPER_LPIS_SUPPORTED;
+}
+
static int __cpuinit gicv3_cpu_init(void)
{
int i;
@@ -670,6 +675,15 @@ static int __cpuinit gicv3_cpu_init(void)
if ( gicv3_enable_redist() )
return -ENODEV;
+ if ( gicv3_dist_supports_lpis() )
+ gicv3_info.lpi_supported = 1;
+ else
+ gicv3_info.lpi_supported = 0;
+
+ /* Give LPIs a spin */
+ if ( gicv3_info.lpi_supported )
+ its_cpu_init();
+
/* Set priority on PPI and SGI interrupts */
priority = (GIC_PRI_IPI << 24 | GIC_PRI_IPI << 16 | GIC_PRI_IPI << 8 |
GIC_PRI_IPI);
@@ -1269,10 +1283,17 @@ static int __init gicv3_init(struct dt_device_node
*node, const void *data)
gicv3.rdist_regions[0].size, gicv3.rdist_regions[0].map_base,
gicv3_info.maintenance_irq);
+ reg = readl_relaxed(GICD + GICD_TYPER);
+ gicv3.rdist_data.id_bits = ((reg >> 19) & 0x1f) + 1;
+ gicv3_info.nr_id_bits = gicv3.rdist_data.id_bits;
+
spin_lock_init(&gicv3.lock);
spin_lock(&gicv3.lock);
+ if ( gicv3_info.lpi_supported )
+ its_init(node, &gicv3.rdist_data);
+
gicv3_dist_init();
res = gicv3_cpu_init();
gicv3_hyp_init();
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index c4d352a..dbd906d 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -74,6 +74,16 @@ unsigned int gic_number_lines(void)
return gic_hw_ops->info->nr_lines;
}
+unsigned int gic_nr_id_bits(void)
+{
+ return gic_hw_ops->info->nr_id_bits;
+}
+
+bool_t gic_lpi_supported(void)
+{
+ return gic_hw_ops->info->lpi_supported;
+}
+
void gic_eoi_irq(struct irq_desc *d)
{
gic_hw_ops->eoi_irq(d);
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 43b626b..8c75e0e 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -762,6 +762,7 @@ void __init start_xen(unsigned long boot_phys_offset,
init_xen_time();
gic_init();
+ vgic_its_init();
p2m_vmid_allocator_init();
diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index 51b9614..e12111d 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -1544,19 +1544,31 @@ static int vgic_map_translation_space(struct domain *d)
int vgic_its_domain_init(struct domain *d)
{
- d->arch.vits = xzalloc(struct vgic_its);
- if ( d->arch.vits == NULL )
- return -ENOMEM;
+ if ( gic_lpi_supported() )
+ {
+ d->arch.vits = xzalloc(struct vgic_its);
+ if ( d->arch.vits == NULL )
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&d->arch.vits->vits_dev_list);
+ spin_lock_init(&d->arch.vits->lock);
+
+ its_domain_init(d);
- INIT_LIST_HEAD(&d->arch.vits->vits_dev_list);
- spin_lock_init(&d->arch.vits->lock);
+ register_mmio_handler(d, &vgic_gits_mmio_handler,
d->arch.vits->phys_base,
+ SZ_64K);
- register_mmio_handler(d, &vgic_gits_mmio_handler, d->arch.vits->phys_base,
- SZ_64K);
+ return vgic_map_translation_space(d);
+ }
- return vgic_map_translation_space(d);
+ return 0;
}
+void vgic_its_init(void)
+{
+ if ( gic_lpi_supported() )
+ its_lpi_init(gic_nr_id_bits());
+}
/*
* Local variables:
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 89e6195..fa7b241 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -1124,6 +1124,7 @@ static int vgic_v3_domain_init(struct domain *d)
register_mmio_handler(d, &vgic_rdistr_mmio_handler,
d->arch.vgic.rbase[i], d->arch.vgic.rbase_size[i]);
+ vgic_its_domain_init(d);
return 0;
}
diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
index 0defe6e..329b8a0 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -22,6 +22,8 @@
#ifndef __ASM_ARM_GIC_ITS_H__
#define __ASM_ARM_GIC_ITS_H__
+#include <asm/gic_v3_defs.h>
+
#define IRQ_PER_CHUNK 32
/* ITS device structure */
@@ -238,6 +240,9 @@ int its_get_physical_cid(uint32_t *col_id, uint64_t ta);
int gic_its_send_cmd(struct vcpu *v, struct its_cmd_block *phys_cmd);
int its_make_dt_node(const struct domain *d,
const struct dt_device_node *node, void *fdt);
+void its_domain_init(struct domain *d);
+int its_cpu_init(void);
+int its_init(struct dt_device_node *node, struct rdist_prop *rdist);
#endif /* __ASM_ARM_GIC_ITS_H__ */
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index efc9ac3..67a7122 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -279,6 +279,10 @@ extern void gic_dump_info(struct vcpu *v);
/* Number of interrupt lines */
extern unsigned int gic_number_lines(void);
+/* Number of interrupt id bits supported */
+extern unsigned int gic_nr_id_bits(void);
+/* LPI support info */
+bool_t gic_lpi_supported(void);
/* IRQ translation function for the device tree */
int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
@@ -294,6 +298,10 @@ struct gic_info {
uint8_t nr_lrs;
/* Maintenance irq number */
unsigned int maintenance_irq;
+ /* Number of IRQ ID bits supported */
+ uint32_t nr_id_bits;
+ /* LPIs are support information */
+ bool_t lpi_supported;
};
struct gic_its_hw_operations {
diff --git a/xen/include/asm-arm/gic_v3_defs.h
b/xen/include/asm-arm/gic_v3_defs.h
index b81f83f..574a838 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -133,6 +133,7 @@
#define GICR_TYPER_LAST (1U << 4)
#define GICR_TYPER_DISTRIBUTED_IMP (1U << 3)
+#define GICD_TYPER_LPIS_SUPPORTED (1U << 17)
#define DEFAULT_PMR_VALUE 0xff
#define GICH_VMCR_EOI (1 << 9)
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 74d5a4e..e0a6166 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -177,6 +177,7 @@ enum gic_sgi_mode;
#define vgic_num_irqs(d) ((d)->arch.vgic.nr_spis + 32)
+extern void vgic_its_init(void);
extern int domain_vgic_init(struct domain *d);
extern void domain_vgic_free(struct domain *d);
extern int vcpu_vgic_init(struct vcpu *v);
--
1.7.9.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |