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