[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v7 27/28] xen/arm: ITS: Generate ITS node for Dom0
From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> Parse host dt and generate ITS node for Dom0. ITS node resides inside GIC node so when GIC node is encountered look for ITS node. Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> --- v7: - Check on return value v6: - Introduced get_its_phandle in gic_hw_ops - Removed make_hwdom_its_dt_node callback in gic_hw_ops - Renamed gic_get_msi_handle() as gic_update_msi_phandle() - Renamed its_get_phandle to its_update_phandle() - ITS node generation is wrapped inside GICv3 - Update msi-parent phandle only if msi-parent is ITS and find its phandle on demand v5: - Moved ITS dt node generation to ITS driver v4: - Generate only one ITS node for Dom0 - Replace msi-parent references to single its phandle --- xen/arch/arm/domain_build.c | 14 +++++ xen/arch/arm/gic-v3-its.c | 120 +++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/gic-v3.c | 17 +++++- xen/arch/arm/gic.c | 8 +++ xen/include/asm-arm/gic-its.h | 2 + xen/include/asm-arm/gic.h | 3 ++ 6 files changed, 163 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index a059de6..5119f47 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -469,6 +469,20 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo, continue; } + /* + * Replace all msi-parent phandle references to single ITS node + * generated for Dom0 + */ + if ( dt_property_name_is_equal(prop, "msi-parent") ) + { + DPRINT(" Set msi-parent with ITS phandle (if ITS available)\n"); + res = gic_update_msi_phandle(kinfo->fdt, prop); + if ( res ) + return res; + + continue; + } + res = fdt_property(kinfo->fdt, prop->name, prop_data, prop_len); xfree(new_data); diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c index 891a5e2..2b3cbe1 100644 --- a/xen/arch/arm/gic-v3-its.c +++ b/xen/arch/arm/gic-v3-its.c @@ -27,6 +27,8 @@ #include <xen/sched.h> #include <xen/errno.h> #include <xen/delay.h> +#include <xen/device_tree.h> +#include <xen/libfdt/libfdt.h> #include <xen/list.h> #include <xen/sizes.h> #include <xen/vmap.h> @@ -1298,6 +1300,124 @@ static void its_cpu_init_collection(void) spin_unlock(&its_lock); } +int its_make_dt_node(const struct domain *d, void *fdt) +{ + struct its_node *its; + const struct dt_device_node *node; + const void *compatible = NULL; + u32 len; + __be32 *new_cells, *tmp; + int res = 0; + + /* Will pass only first ITS node info */ + its = list_first_entry(&its_nodes, struct its_node, entry); + if ( !its ) + { + dprintk(XENLOG_ERR, "ITS node not found\n"); + return -FDT_ERR_XEN(ENOENT); + } + + node = its->dt_node; + + compatible = dt_get_property(node, "compatible", &len); + if ( !compatible ) + { + dprintk(XENLOG_ERR, "Can't find compatible property for the its node\n"); + return -FDT_ERR_XEN(ENOENT); + } + + res = fdt_begin_node(fdt, "gic-its"); + if ( res ) + return res; + + res = fdt_property(fdt, "compatible", compatible, len); + if ( res ) + return res; + + res = fdt_property(fdt, "msi-controller", NULL, 0); + if ( res ) + return res; + + len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node)); + + new_cells = xzalloc_bytes(len); + if ( new_cells == NULL ) + return -FDT_ERR_XEN(ENOMEM); + tmp = new_cells; + + dt_set_range(&tmp, node, its->phys_base, its->phys_size); + + res = fdt_property(fdt, "reg", new_cells, len); + xfree(new_cells); + if ( res ) + return res; + + if ( node->phandle ) + { + res = fdt_property_cell(fdt, "phandle", node->phandle); + if ( res ) + return res; + } + + res = fdt_end_node(fdt); + + return res; +} + +static int its_find_compatible_phandle(fdt32_t msi_parent_phandle) +{ + struct its_node *its; + const struct dt_device_node *node; + fdt32_t phandle; + + list_for_each_entry(its, &its_nodes, entry) + { + node = its->dt_node; + + if ( node->phandle ) + { + phandle = cpu_to_fdt32(node->phandle); + if ( phandle == msi_parent_phandle ) + return 0; + } + } + + return -FDT_ERR_XEN(ENOENT); +} + +int its_update_phandle(void *fdt, const struct dt_property *prop) +{ + struct its_node *its; + const struct dt_device_node *node; + fdt32_t phandle, msi_parent_phandle; + + memcpy(&msi_parent_phandle, prop->value, sizeof(msi_parent_phandle)); + + /* chech if msi-parent phandle is ITS */ + if ( its_find_compatible_phandle(msi_parent_phandle) ) + return -FDT_ERR_XEN(ENOENT); + + /* Only first ITS node phandle is considered */ + its = list_first_entry(&its_nodes, struct its_node, entry); + if ( !its ) + { + dprintk(XENLOG_ERR, "ITS node not found\n"); + return -FDT_ERR_XEN(ENOENT); + } + + node = its->dt_node; + + if ( node->phandle ) + { + phandle = cpu_to_fdt32(node->phandle); + fdt_property(fdt, prop->name, (void *)&phandle, sizeof(phandle)); + + return 0; + } + + return -FDT_ERR_XEN(ENOENT); +} + static int its_force_quiescent(void __iomem *base) { u32 count = 1000000; /* 1s */ diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index 2cdc065..b1977b0 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -1105,6 +1105,14 @@ static void gicv3_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask) spin_unlock(&gicv3.lock); } +static int gicv3_update_its_phandle(void *fdt, const struct dt_property *prop) +{ + if ( its_enabled ) + return its_update_phandle(fdt, prop); + + return 0; +} + static int gicv3_make_hwdom_dt_node(const struct domain *d, const struct dt_device_node *node, void *fdt) @@ -1126,6 +1134,10 @@ static int gicv3_make_hwdom_dt_node(const struct domain *d, if ( res ) return res; + res = fdt_property(fdt, "ranges", NULL, 0); + if ( res ) + return res; + res = fdt_property_cell(fdt, "redistributor-stride", d->arch.vgic.rdist_stride); if ( res ) @@ -1157,8 +1169,10 @@ static int gicv3_make_hwdom_dt_node(const struct domain *d, res = fdt_property(fdt, "reg", new_cells, len); xfree(new_cells); + if ( res ) + return res; - return res; + return its_make_dt_node(d, fdt); } static const hw_irq_controller gicv3_host_irq_type = { @@ -1384,6 +1398,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, + .update_its_phandle = gicv3_update_its_phandle, .make_hwdom_dt_node = gicv3_make_hwdom_dt_node, }; diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index ff24bb1..072382e 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -749,6 +749,14 @@ void __cpuinit init_maintenance_interrupt(void) "irq-maintenance", NULL); } +int gic_update_msi_phandle(void *fdt, const struct dt_property *prop) +{ + if ( gic_hw_ops->update_its_phandle != NULL ) + return gic_hw_ops->update_its_phandle(fdt, prop); + + return 0; +} + int gic_make_hwdom_dt_node(const struct domain *d, const struct dt_device_node *node, void *fdt) diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h index 52ced48..d27b52c 100644 --- a/xen/include/asm-arm/gic-its.h +++ b/xen/include/asm-arm/gic-its.h @@ -299,6 +299,8 @@ int its_assign_device(struct domain *d, u32 vdevid, u32 pdevid); void its_set_lpi_properties(struct irq_desc *desc, const cpumask_t *cpu_mask, unsigned int priority); +int its_update_phandle(void *fdt, const struct dt_property *prop); +int its_make_dt_node(const struct domain *d, void *fdt); #endif /* __ASM_ARM_GIC_ITS_H__ */ /* diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index b6b3a4f..4ca00ca 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -151,6 +151,7 @@ #ifndef __ASSEMBLY__ #include <xen/device_tree.h> +#include <xen/libfdt/libfdt.h> #include <xen/irq.h> #include <asm-arm/vgic.h> @@ -360,6 +361,7 @@ struct gic_hw_operations { int (*secondary_init)(void); int (*make_hwdom_dt_node)(const struct domain *d, const struct dt_device_node *node, void *fdt); + int (*update_its_phandle)(void *fdt, const struct dt_property *prop); }; void register_gic_ops(const struct gic_hw_operations *ops); @@ -368,6 +370,7 @@ int gic_make_hwdom_dt_node(const struct domain *d, void *fdt); unsigned int gic_nr_irq_ids(void); bool_t gic_is_lpi(unsigned int irq); +int gic_update_msi_phandle(void *fdt, const struct dt_property *prop); #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 |