|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH v2 21/22] 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>
---
v2: Multi-ITS support
---
xen/arch/arm/gic-v3-its.c | 25 +++++++++++++++++++++++--
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 | 8 ++++++++
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, 79 insertions(+), 2 deletions(-)
diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index a59bbb5..c2c59fa 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -565,7 +565,7 @@ static int its_chunk_to_lpi(int chunk)
return (chunk << IRQS_PER_CHUNK_SHIFT) + 8192;
}
-static int its_lpi_init(u32 id_bits)
+int its_lpi_init(u32 id_bits)
{
lpi_chunks = its_lpi_to_chunk(1UL << id_bits);
@@ -1079,6 +1079,28 @@ static int its_force_quiescent(void __iomem *base)
}
}
+void its_domain_init(uint32_t its_nr, struct domain *d)
+{
+ struct its_node *its;
+ u32 nr = 0;
+
+ ASSERT(its_nr < its_get_nr_its() );
+
+ if (is_hardware_domain(d)) {
+ list_for_each_entry(its, &its_nodes, entry) {
+ if ( nr == its_nr)
+ break;
+ nr++;
+ }
+
+ ASSERT(its != NULL);
+ d->arch.vits[its_nr].phys_base = its->phys_base;
+ d->arch.vits[its_nr].phys_size = its->phys_size;
+ d->arch.vits[its_nr].its = its;
+ }
+ /* TODO: Update for DomU */
+}
+
static int its_probe(struct dt_device_node *node)
{
paddr_t its_addr, its_size;
@@ -1231,7 +1253,6 @@ int its_init(struct dt_device_node *node, struct
rdist_prop *rdists)
gic_root_node = node;
its_alloc_lpi_tables();
- its_lpi_init(rdists->id_bits);
return 0;
}
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index ffdaecf..d3278f3 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -679,6 +679,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;
@@ -691,6 +696,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);
@@ -1324,10 +1338,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 6ac1f18..7c9b75c 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -68,6 +68,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_save_state(struct vcpu *v)
{
ASSERT(!local_irq_is_enabled());
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 9a1c285..ebd4bb9 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -773,6 +773,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 360be0d..bd0b8ae 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -1455,6 +1455,8 @@ int vgic_its_domain_init(struct domain *d)
for ( i = 0; i < num_its; i++)
{
spin_lock_init(&d->arch.vits[i].lock);
+
+ its_domain_init(i, d);
register_mmio_handler(d, &vgic_gits_mmio_handler,
d->arch.vits[i].phys_base,
SZ_64K);
@@ -1465,6 +1467,12 @@ int vgic_its_domain_init(struct domain *d)
return 0;
}
+void vgic_its_init(void)
+{
+ if ( gic_lpi_supported() )
+ its_lpi_init(gic_nr_id_bits());
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index e9ec7fa..578537f 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -1204,6 +1204,7 @@ static int vgic_v3_domain_init(struct domain *d)
d->arch.vgic.rdist_regions[i].size);
d->arch.vgic.ctlr = VGICD_CTLR_DEFAULT;
+ 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 ed9cbc9..519321b 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -226,6 +226,10 @@ int gic_its_send_cmd(struct vcpu *v, struct its_node *its,
struct its_cmd_block *phys_cmd, int send_all);
int its_make_dt_node(const struct domain *d,
const struct dt_device_node *node, void *fdt);
+int its_cpu_init(void);
+int its_init(struct dt_device_node *node, struct rdist_prop *rdist);
+int its_lpi_init(u32 id_bits);
+void its_domain_init(uint32_t its_nr, struct domain *d);
void its_lpi_free(unsigned long *bitmap, int base, int nr_ids);
void its_set_affinity(struct irq_desc *d, int cpu);
void lpi_set_config(struct irq_desc *d, int enable);
@@ -235,6 +239,7 @@ uint32_t its_get_nr_its(void);
struct its_node * its_get_phys_node(uint32_t dev_id);
int vgic_its_unmap_lpi_prop(struct vcpu *v);
int vgic_its_get_pid(struct vcpu *v, uint32_t vlpi, uint32_t *plpi);
+int vgic_its_domain_init(struct domain *d);
uint8_t vgic_its_get_priority(struct vcpu *v, uint32_t pid);
#endif /* __ASM_ARM_GIC_ITS_H__ */
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index d927f35..2467212 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -271,6 +271,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,
@@ -286,6 +290,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_hw_operations {
diff --git a/xen/include/asm-arm/gic_v3_defs.h
b/xen/include/asm-arm/gic_v3_defs.h
index 125fc28..214b492 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -48,6 +48,7 @@
#define GICR_CTL_ENABLE (1U << 0)
/* Additional bits in GICD_TYPER defined by GICv3 */
#define GICD_TYPE_ID_BITS_SHIFT 19
+#define GICD_TYPER_LPIS_SUPPORTED (1U << 17)
#define GICD_CTLR_RWP (1UL << 31)
#define GICD_CTLR_ARE_NS (1U << 4)
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index dd93872..f2cb268 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 |