[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH v3 12/18] xen/arm: ITS: Add GICR register emulation
From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> Emulate LPI related changes to GICR registers Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> --- xen/arch/arm/gic-v3.c | 15 ++++++++ xen/arch/arm/gic.c | 10 ++++++ xen/arch/arm/vgic-v3.c | 69 ++++++++++++++++++++++++++++++------- xen/include/asm-arm/domain.h | 1 + xen/include/asm-arm/gic-its.h | 1 + xen/include/asm-arm/gic.h | 9 +++++ xen/include/asm-arm/gic_v3_defs.h | 1 + 7 files changed, 94 insertions(+), 12 deletions(-) diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index 556b291..737646c 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -683,6 +683,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; @@ -1304,10 +1309,20 @@ static int __init gicv3_init(void) 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_dist_supports_lpis() ) + gicv3_info.lpi_supported = 1; + else + gicv3_info.lpi_supported = 0; + 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 c41e82e..cfc9c42 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -67,6 +67,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/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 4af5a84..44922fb 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -30,6 +30,7 @@ #include <asm/mmio.h> #include <asm/gic_v3_defs.h> #include <asm/gic.h> +#include <asm/gic-its.h> #include <asm/vgic.h> /* GICD_PIDRn register values for ARM implementations */ @@ -93,8 +94,15 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, switch ( gicr_reg ) { case GICR_CTLR: - /* We have not implemented LPI's, read zero */ - goto read_as_zero_32; + /* + * Enable LPI's for ITS. Direct injection of LPI + * by writing to GICR_{SET,CLR}LPIR are not supported + */ + if ( dabt.size != DABT_WORD ) goto bad_width; + vgic_lock(v); + *r = v->domain->arch.vgic.gicr_ctlr; + vgic_unlock(v); + return 1; case GICR_IIDR: if ( dabt.size != DABT_WORD ) goto bad_width; *r = GICV3_GICR_IIDR_VAL; @@ -106,6 +114,10 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 2) << 48 | MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 1) << 40 | MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 0) << 32); + /* Set LPI support */ + aff |= (GICR_TYPER_DISTRIBUTED_IMP | GICR_TYPER_PLPIS); + /* GITS_TYPER.PTA is 0. Provice vcpu number as ta */ + aff |= (v->vcpu_id << GICR_TYPER_PROCESSOR_SHIFT); *r = aff; if ( v->arch.vgic.flags & VGIC_V3_RDIST_LAST ) @@ -125,11 +137,13 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, /* WO. Read as zero */ goto read_as_zero_64; case GICR_PROPBASER: - /* LPI's not implemented */ - goto read_as_zero_64; + if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width; + /* Remove shareability attribute we don't want dom to flush */ + *r = v->domain->arch.vits->propbase; + return 1; case GICR_PENDBASER: - /* LPI's not implemented */ - goto read_as_zero_64; + if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width; + *r = v->domain->arch.vits->pendbase[v->vcpu_id]; case GICR_INVLPIR: /* WO. Read as zero */ goto read_as_zero_64; @@ -203,8 +217,15 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, switch ( gicr_reg ) { case GICR_CTLR: - /* LPI's not implemented */ - goto write_ignore_32; + /* + * Enable LPI's for ITS. Direct injection of LPI + * by writing to GICR_{SET,CLR}LPIR are not supported + */ + if ( dabt.size != DABT_WORD ) goto bad_width; + vgic_lock(v); + v->domain->arch.vgic.gicr_ctlr = (*r) & GICR_CTL_ENABLE; + vgic_unlock(v); + return 1; case GICR_IIDR: /* RO */ goto write_ignore_32; @@ -224,11 +245,27 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, /* LPI is not implemented */ goto write_ignore_64; case GICR_PROPBASER: - /* LPI is not implemented */ - goto write_ignore_64; + if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width; + vgic_lock(v); + /* LPI configuration tables are shared across cpus. Should be same */ + if ( (v->domain->arch.vits->propbase != 0) && + ((v->domain->arch.vits->propbase & 0xfffffffff000UL) != + (*r & 0xfffffffff000UL)) ) + { + dprintk(XENLOG_G_ERR, + "vGICv3: vITS: Wrong configuration of LPI_PROPBASER\n"); + return 0; + } + v->domain->arch.vits->propbase = *r; + vgic_unlock(v); + return vgic_its_unmap_lpi_prop(v); case GICR_PENDBASER: - /* LPI is not implemented */ - goto write_ignore_64; + /* Just hold pendbaser value for guest read */ + if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width; + vgic_lock(v); + v->domain->arch.vits->pendbase[v->vcpu_id] = *r; + vgic_unlock(v); + return 1; case GICR_INVLPIR: /* LPI is not implemented */ goto write_ignore_64; @@ -694,6 +731,14 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) *r = ((ncpus - 1) << GICD_TYPE_CPUS_SHIFT | DIV_ROUND_UP(v->domain->arch.vgic.nr_spis, 32)); + if ( gic_lpi_supported() ) + { + irq_bits = gic_nr_id_bits(); + *r |= GICD_TYPE_LPIS; + } + else + irq_bits = get_count_order(vgic_num_irqs(v->domain)); + *r |= (irq_bits - 1) << GICD_TYPE_ID_BITS_SHIFT; return 1; diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index da73cf5..db1d1db 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -102,6 +102,7 @@ struct arch_domain paddr_t dbase; /* Distributor base address */ paddr_t cbase; /* CPU base address */ #ifdef CONFIG_ARM_64 + int gicr_ctlr; /* GIC V3 addressing */ paddr_t dbase_size; /* Distributor base size */ /* List of contiguous occupied by the redistributors */ diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h index 3271477..1de57a7 100644 --- a/xen/include/asm-arm/gic-its.h +++ b/xen/include/asm-arm/gic-its.h @@ -277,6 +277,7 @@ static inline uint32_t its_decode_devid(struct domain *d, its_cmd_block *cmd) void its_set_affinity(struct irq_desc *desc, int cpu); void lpi_set_config(struct irq_desc *desc, int enable); uint32_t its_get_nr_events(void); +int vgic_its_unmap_lpi_prop(struct vcpu *v); struct vits_device * find_vits_device(struct rb_root *root, uint32_t devid); int insert_vits_device(struct rb_root *root, struct vits_device *dev); int remove_vits_device(struct rb_root *root, struct vits_device *dev); diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 0209cc5..ee612de 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -99,6 +99,7 @@ #define GICD_TYPE_CPUS_SHIFT 5 #define GICD_TYPE_CPUS 0x0e0 #define GICD_TYPE_SEC 0x400 +#define GICD_TYPE_LPIS (0x1UL << 17) #define GICC_CTL_ENABLE 0x1 #define GICC_CTL_EOI (0x1 << 9) @@ -282,6 +283,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, @@ -299,6 +304,10 @@ struct gic_info { unsigned int maintenance_irq; /* Pointer to the device tree node representing the interrupt controller */ const struct dt_device_node *node; + /* 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 dc4fe14..0872097 100644 --- a/xen/include/asm-arm/gic_v3_defs.h +++ b/xen/include/asm-arm/gic_v3_defs.h @@ -136,6 +136,7 @@ #define GICR_TYPER_VLPIS (1U << 1) #define GICR_TYPER_DISTRIBUTED_IMP (1U << 3) #define GICR_TYPER_LAST (1U << 4) +#define GICR_TYPER_PROCESSOR_SHIFT (8) #define DEFAULT_PMR_VALUE 0xff -- 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 |