[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 |