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