[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 15/15] xen/arm: update GIC dt node with GIC v3 information
From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> Update GIC device tree node for DOM0 with GICv3 information. Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> --- xen/arch/arm/domain_build.c | 41 ++++++++++++++++++++++++++++++++++------- xen/arch/arm/gic-v2.c | 8 ++++++++ xen/arch/arm/gic-v3.c | 8 ++++++++ xen/arch/arm/gic.c | 5 +++++ xen/include/asm-arm/gic.h | 5 +++++ 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 66a98f1..5a75403 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -532,6 +532,8 @@ static int make_gic_node(const struct domain *d, void *fdt, u32 len; __be32 *new_cells, *tmp; int res = 0; + int hw_type = GIC_VERSION_V2; + u32 rd_stride = 0; /* * Xen currently supports only a single GIC. Discard any secondary @@ -545,6 +547,8 @@ static int make_gic_node(const struct domain *d, void *fdt, DPRINT("Create gic node\n"); + hw_type = gic_hw_version(); + compatible = dt_get_property(gic, "compatible", &len); if ( !compatible ) { @@ -552,6 +556,12 @@ static int make_gic_node(const struct domain *d, void *fdt, return -FDT_ERR_XEN(ENOENT); } + if ( hw_type == GIC_VERSION_V3 ) + { + res = dt_property_read_u32(gic, "redistributor-stride", &rd_stride); + if ( !res ) + rd_stride = 0; + } res = fdt_begin_node(fdt, "interrupt-controller"); if ( res ) return res; @@ -576,14 +586,31 @@ static int make_gic_node(const struct domain *d, void *fdt, return -FDT_ERR_XEN(ENOMEM); tmp = new_cells; - DPRINT(" Set Distributor Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", - d->arch.vgic.info->dbase, d->arch.vgic.info->dbase + PAGE_SIZE - 1); - dt_set_range(&tmp, node, d->arch.vgic.info->dbase, PAGE_SIZE); - - DPRINT(" Set Cpu Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", - d->arch.vgic.info->cbase, d->arch.vgic.info->cbase + (PAGE_SIZE * 2) - 1); - dt_set_range(&tmp, node, d->arch.vgic.info->cbase, PAGE_SIZE * 2); + if ( hw_type == GIC_VERSION_V3 ) + { + res = fdt_property_cell(fdt, "redistributor-stride", rd_stride); + if ( res ) + return res; + DPRINT(" gicv3 rd stride 0x%x\n", rd_stride); + + DPRINT(" Set Distributor Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", + d->arch.vgic.info->dbase, d->arch.vgic.info->dbase + d->arch.vgic.info->dbase_size - 1); + dt_set_range(&tmp, node, d->arch.vgic.info->dbase, d->arch.vgic.info->dbase_size); + + DPRINT(" Set Re-distributor Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", + d->arch.vgic.info->rbase, d->arch.vgic.info->rbase + d->arch.vgic.info->rbase_size - 1); + dt_set_range(&tmp, node, d->arch.vgic.info->rbase, d->arch.vgic.info->rbase_size); + } + else + { + DPRINT(" Set Distributor Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", + d->arch.vgic.info->dbase, d->arch.vgic.info->dbase + PAGE_SIZE - 1); + dt_set_range(&tmp, node, d->arch.vgic.info->dbase, PAGE_SIZE); + DPRINT(" Set Cpu Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", + d->arch.vgic.info->cbase, d->arch.vgic.info->cbase + (PAGE_SIZE * 2) - 1); + dt_set_range(&tmp, node, d->arch.vgic.info->cbase, PAGE_SIZE * 2); + } res = fdt_property(fdt, "reg", new_cells, len); xfree(new_cells); diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index 6443bf4..de3e709 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -43,6 +43,7 @@ /* Global state */ static struct { + int hw_version; paddr_t dbase; /* Address of distributor registers */ paddr_t cbase; /* Address of CPU interface registers */ paddr_t hbase; /* Address of virtual interface registers */ @@ -351,6 +352,7 @@ int __init gicv2_init(struct dt_device_node *node, const void *data) gic_cpu_init(); gic_hyp_init(); + gic.hw_version = GIC_VERSION_V2; register_gic_ops(&gic_ops); return 0; } @@ -361,6 +363,11 @@ static void gic_secondary_cpu_init(void) gic_hyp_init(); } +static int gic_hw_type(void) +{ + return gic.hw_version; +} + static struct dt_irq * gic_maintenance_irq(void) { return &gic.maintenance; @@ -504,6 +511,7 @@ static unsigned int gic_read_vmcr_priority(void) } static struct gic_hw_operations gic_ops = { + .gic_type = gic_hw_type, .nr_lines = gic_nr_lines, .nr_lrs = gic_nr_lrs, .secondary_init = gic_secondary_cpu_init, diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index 8cefdab..0fe1059 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -49,6 +49,7 @@ struct rdist_region { /* Global state */ static struct { + int hw_version; paddr_t dbase; /* Address of distributor registers */ paddr_t dbase_size; void __iomem *map_dbase; /* Mapped address of distributor registers */ @@ -766,6 +767,11 @@ int gicv_init(struct domain *d) return 0; } +static int gic_hw_type(void) +{ + return gic.hw_version; +} + static struct dt_irq * gic_maintenance_irq(void) { return &gic.maintenance; @@ -786,6 +792,7 @@ static unsigned int gic_read_vmcr_priority(void) } static struct gic_hw_operations gic_ops = { + .gic_type = gic_hw_type, .nr_lines = gic_nr_lines, .nr_lrs = gic_nr_lrs, .get_maintenance_irq = gic_maintenance_irq, @@ -893,6 +900,7 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data) gic_cpu_init(); gic_hyp_init(); + gic.hw_version = GIC_VERSION_V3; /* Register hw ops*/ register_gic_ops(&gic_ops); return 0; diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 87a7ad0..e09d5a5 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -58,6 +58,11 @@ void update_cpu_lr_mask(void) static void gic_clear_one_lr(struct vcpu *v, int i); +int gic_hw_version(void) +{ + return gic_hw_ops->gic_type(); +} + unsigned int gic_number_lines(void) { return gic_hw_ops->nr_lines(); diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index eadbfcc..32212f9 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -51,6 +51,9 @@ #define GICH_HCR_VGRP1EIE (1 << 6) #define GICH_HCR_VGRP1DIE (1 << 7) +#define GIC_VERSION_V3 0x3 +#define GIC_VERSION_V2 0x2 + #ifndef __ASSEMBLY__ #include <xen/device_tree.h> @@ -175,6 +178,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize, void gic_clear_lrs(struct vcpu *v); struct gic_hw_operations { + int (*gic_type)(void); struct dt_irq * (*get_maintenance_irq)(void); unsigned int (*nr_lines)(void); unsigned int (*nr_lrs)(void); @@ -211,6 +215,7 @@ struct vgic_ops { void register_vgic_ops(struct vgic_ops *ops); void register_gic_ops(struct gic_hw_operations *ops); extern void update_cpu_lr_mask(void); +extern int gic_hw_version(void); #endif /* __ASSEMBLY__ */ #endif -- 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 |