[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] xen/arm: Update Dom0 GIC dt node with GICv3 information
commit 5dd422c656c6781a4703bb5b681d558d7c199996 Author: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> AuthorDate: Fri Sep 12 16:39:47 2014 +0530 Commit: Ian Campbell <ian.campbell@xxxxxxxxxx> CommitDate: Mon Sep 15 22:56:42 2014 +0100 xen/arm: Update Dom0 GIC dt node with GICv3 information Update GIC device tree node for DOM0 with GICv3 information. GIC hw specfic device tree information is moved to respective GIC driver. Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> Acked-by: Julien Grall <julien.grall@xxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- xen/arch/arm/domain_build.c | 47 +------------------------- xen/arch/arm/gic-v2.c | 51 ++++++++++++++++++++++++++++ xen/arch/arm/gic-v3.c | 78 +++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/gic.c | 6 +++ xen/include/asm-arm/gic.h | 4 ++ 5 files changed, 141 insertions(+), 45 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 2d316dd..90abc3a 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -777,9 +777,6 @@ static int make_gic_node(const struct domain *d, void *fdt, const struct dt_device_node *node) { const struct dt_device_node *gic = dt_interrupt_controller; - const void *compatible = NULL; - u32 len; - __be32 *new_cells, *tmp; int res = 0; /* @@ -794,48 +791,7 @@ static int make_gic_node(const struct domain *d, void *fdt, DPRINT("Create gic node\n"); - compatible = dt_get_property(gic, "compatible", &len); - if ( !compatible ) - { - dprintk(XENLOG_ERR, "Can't find compatible property for the gic node\n"); - return -FDT_ERR_XEN(ENOENT); - } - - res = fdt_begin_node(fdt, "interrupt-controller"); - if ( res ) - return res; - - res = fdt_property(fdt, "compatible", compatible, len); - if ( res ) - return res; - - res = fdt_property_cell(fdt, "#interrupt-cells", 3); - if ( res ) - return res; - - res = fdt_property(fdt, "interrupt-controller", NULL, 0); - - if ( res ) - return res; - - len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node)); - len *= 2; /* GIC has two memory regions: Distributor + CPU interface */ - new_cells = xzalloc_bytes(len); - if ( new_cells == NULL ) - return -FDT_ERR_XEN(ENOMEM); - - tmp = new_cells; - DPRINT(" Set Distributor Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", - d->arch.vgic.dbase, d->arch.vgic.dbase + PAGE_SIZE - 1); - dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE); - - DPRINT(" Set Cpu Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n", - d->arch.vgic.cbase, d->arch.vgic.cbase + (PAGE_SIZE * 2) - 1); - dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2); - - res = fdt_property(fdt, "reg", new_cells, len); - xfree(new_cells); - + res = gic_make_node(d, node, fdt); if ( res ) return res; @@ -1058,6 +1014,7 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo, static const struct dt_device_match gic_matches[] __initconst = { DT_MATCH_GIC_V2, + DT_MATCH_GIC_V3, { /* sentinel */ }, }; static const struct dt_device_match timer_matches[] __initconst = diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index 78ad4de..f053b5d 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -27,6 +27,7 @@ #include <xen/softirq.h> #include <xen/list.h> #include <xen/device_tree.h> +#include <xen/libfdt/libfdt.h> #include <asm/p2m.h> #include <asm/domain.h> #include <asm/platform.h> @@ -585,6 +586,55 @@ static void gicv2_irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_m spin_unlock(&gicv2.lock); } +static int gicv2_make_dt_node(const struct domain *d, + const struct dt_device_node *node, void *fdt) +{ + const struct dt_device_node *gic = dt_interrupt_controller; + const void *compatible = NULL; + u32 len; + __be32 *new_cells, *tmp; + int res = 0; + + compatible = dt_get_property(gic, "compatible", &len); + if ( !compatible ) + { + dprintk(XENLOG_ERR, "Can't find compatible property for the gic node\n"); + return -FDT_ERR_XEN(ENOENT); + } + + res = fdt_begin_node(fdt, "interrupt-controller"); + if ( res ) + return res; + + res = fdt_property(fdt, "compatible", compatible, len); + if ( res ) + return res; + + res = fdt_property_cell(fdt, "#interrupt-cells", 3); + if ( res ) + return res; + + res = fdt_property(fdt, "interrupt-controller", NULL, 0); + + if ( res ) + return res; + + len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node)); + len *= 2; /* GIC has two memory regions: Distributor + CPU interface */ + new_cells = xzalloc_bytes(len); + if ( new_cells == NULL ) + return -FDT_ERR_XEN(ENOMEM); + + tmp = new_cells; + dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE); + dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2); + + res = fdt_property(fdt, "reg", new_cells, len); + xfree(new_cells); + + return res; +} + /* XXX different for level vs edge */ static hw_irq_controller gicv2_host_irq_type = { .typename = "gic-v2", @@ -630,6 +680,7 @@ const static struct gic_hw_operations gicv2_ops = { .write_lr = gicv2_write_lr, .read_vmcr_priority = gicv2_read_vmcr_priority, .read_apr = gicv2_read_apr, + .make_dt_node = gicv2_make_dt_node, }; /* Set up the GIC */ diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index 6ccde02..ca450f9 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -32,6 +32,7 @@ #include <xen/delay.h> #include <xen/device_tree.h> #include <xen/sizes.h> +#include <xen/libfdt/libfdt.h> #include <asm/p2m.h> #include <asm/domain.h> #include <asm/io.h> @@ -1027,6 +1028,82 @@ static void gicv3_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask) spin_unlock(&gicv3.lock); } +static int gicv3_make_dt_node(const struct domain *d, + const struct dt_device_node *node, void *fdt) +{ + const struct dt_device_node *gic = dt_interrupt_controller; + const void *compatible = NULL; + uint32_t len; + __be32 *new_cells, *tmp; + uint32_t rd_stride = 0; + uint32_t rd_count = 0; + + int i, res = 0; + + compatible = dt_get_property(gic, "compatible", &len); + if ( !compatible ) + { + dprintk(XENLOG_ERR, "Can't find compatible property for the gic node\n"); + return -FDT_ERR_XEN(ENOENT); + } + + res = fdt_begin_node(fdt, "interrupt-controller"); + if ( res ) + return res; + + res = fdt_property(fdt, "compatible", compatible, len); + if ( res ) + return res; + + res = fdt_property_cell(fdt, "#interrupt-cells", 3); + if ( res ) + return res; + + res = fdt_property(fdt, "interrupt-controller", NULL, 0); + if ( res ) + return res; + + res = dt_property_read_u32(gic, "redistributor-stride", &rd_stride); + if ( !res ) + rd_stride = 0; + + res = dt_property_read_u32(gic, "#redistributor-regions", &rd_count); + if ( !res ) + rd_count = 1; + + res = fdt_property_cell(fdt, "redistributor-stride", rd_stride); + if ( res ) + return res; + + res = fdt_property_cell(fdt, "#redistributor-regions", rd_count); + if ( res ) + return res; + + len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node)); + /* + * GIC has two memory regions: Distributor + rdist regions + * CPU interface and virtual cpu interfaces accessesed as System registers + * So cells are created only for Distributor and rdist regions + */ + len = len * (d->arch.vgic.rdist_count + 1); + new_cells = xzalloc_bytes(len); + if ( new_cells == NULL ) + return -FDT_ERR_XEN(ENOMEM); + + tmp = new_cells; + + dt_set_range(&tmp, node, d->arch.vgic.dbase, d->arch.vgic.dbase_size); + + for ( i = 0; i < d->arch.vgic.rdist_count; i++ ) + dt_set_range(&tmp, node, d->arch.vgic.rbase[i], + d->arch.vgic.rbase_size[i]); + + res = fdt_property(fdt, "reg", new_cells, len); + xfree(new_cells); + + return res; +} + static const hw_irq_controller gicv3_host_irq_type = { .typename = "gic-v3", .startup = gicv3_irq_startup, @@ -1071,6 +1148,7 @@ static const struct gic_hw_operations gicv3_ops = { .read_vmcr_priority = gicv3_read_vmcr_priority, .read_apr = gicv3_read_apr, .secondary_init = gicv3_secondary_cpu_init, + .make_dt_node = gicv3_make_dt_node, }; /* Set up the GIC */ diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 6611ba0..70d10d6 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -625,6 +625,12 @@ void __cpuinit init_maintenance_interrupt(void) "irq-maintenance", NULL); } +int gic_make_node(const struct domain *d,const struct dt_device_node *node, + void *fdt) +{ + return gic_hw_ops->make_dt_node(d, node, fdt); +} + /* * Local variables: * mode: C diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index c4daf5b..51a0a26 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -336,9 +336,13 @@ struct gic_hw_operations { unsigned int (*read_apr)(int apr_reg); /* Secondary CPU init */ int (*secondary_init)(void); + int (*make_dt_node)(const struct domain *d, + const struct dt_device_node *node, void *fdt); }; void register_gic_ops(const struct gic_hw_operations *ops); +int gic_make_node(const struct domain *d,const struct dt_device_node *node, + void *fdt); #endif /* __ASSEMBLY__ */ #endif -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |