@@ -626,15 +626,14 @@ static int __init fdt_property_interrupts(const struct kernel_info *kinfo,
unsigned num_irq)
{
int res;
- uint32_t phandle = is_hardware_domain(kinfo->d) ?
- dt_interrupt_controller->phandle : GUEST_PHANDLE_GIC;
res = fdt_property(kinfo->fdt, "interrupts",
intr, sizeof(intr[0]) * num_irq);
if ( res )
return res;
- res = fdt_property_cell(kinfo->fdt, "interrupt-parent", phandle);
+ res = fdt_property_cell(kinfo->fdt, "interrupt-parent",
+ kinfo->phandle_gic);
return res;
}
@@ -1537,8 +1536,9 @@ static int __init handle_node(struct domain *d, struct kernel_info *kinfo,
return res;
}
-static int __init make_gicv2_domU_node(const struct domain *d, void *fdt)
+static int __init make_gicv2_domU_node(struct kernel_info *kinfo)
{
+ void *fdt = kinfo->fdt;
int res = 0;
__be32 reg[(GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS) * 2];
__be32 *cells;
@@ -1573,11 +1573,11 @@ static int __init make_gicv2_domU_node(const struct domain *d, void *fdt)
if (res)
return res;
- res = fdt_property_cell(fdt, "linux,phandle", GUEST_PHANDLE_GIC);
+ res = fdt_property_cell(fdt, "linux,phandle", kinfo->phandle_gic);
if (res)
return res;
- res = fdt_property_cell(fdt, "phandle", GUEST_PHANDLE_GIC);
+ res = fdt_property_cell(fdt, "phandle", kinfo->phandle_gic);
if (res)
return res;
@@ -1586,8 +1586,9 @@ static int __init make_gicv2_domU_node(const struct domain *d, void *fdt)
return res;
}
-static int __init make_gicv3_domU_node(const struct domain *d, void *fdt)
+static int __init make_gicv3_domU_node(struct kernel_info *kinfo)
{
+ void *fdt = kinfo->fdt;
int res = 0;
__be32 reg[(GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS) * 2];
__be32 *cells;
@@ -1622,11 +1623,11 @@ static int __init make_gicv3_domU_node(const struct domain *d, void *fdt)
if (res)
return res;
- res = fdt_property_cell(fdt, "linux,phandle", GUEST_PHANDLE_GIC);
+ res = fdt_property_cell(fdt, "linux,phandle", kinfo->phandle_gic);
if (res)
return res;
- res = fdt_property_cell(fdt, "phandle", GUEST_PHANDLE_GIC);
+ res = fdt_property_cell(fdt, "phandle", kinfo->phandle_gic);
if (res)
return res;
@@ -1635,22 +1636,23 @@ static int __init make_gicv3_domU_node(const struct domain *d, void *fdt)
return res;
}
-static int __init make_gic_domU_node(const struct domain *d, void *fdt)
+static int __init make_gic_domU_node(struct kernel_info *kinfo)
{
- switch ( d->arch.vgic.version )
+ switch ( kinfo->d->arch.vgic.version )
{
case GIC_V3:
- return make_gicv3_domU_node(d, fdt);
+ return make_gicv3_domU_node(kinfo);
case GIC_V2:
- return make_gicv2_domU_node(d, fdt);
+ return make_gicv2_domU_node(kinfo);
default:
panic("Unsupported GIC version\n");
}
}
#ifdef CONFIG_SBSA_VUART_CONSOLE
-static int __init make_vpl011_uart_node(const struct domain *d, void *fdt)
+static int __init make_vpl011_uart_node(struct kernel_info *kinfo)
{
+ void *fdt = kinfo->fdt;
int res;
gic_interrupt_t intr;
__be32 reg[GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS];
@@ -1681,7 +1683,7 @@ static int __init make_vpl011_uart_node(const struct domain *d, void *fdt)
return res;
res = fdt_property_cell(fdt, "interrupt-parent",
- GUEST_PHANDLE_GIC);
+ kinfo->phandle_gic);
if ( res )
return res;
@@ -1706,6 +1708,8 @@ static int __init prepare_dtb_domU(struct domain *d, struct kernel_info *kinfo)
int addrcells, sizecells;
int ret;
+ kinfo->phandle_gic = GUEST_PHANDLE_GIC;
+
addrcells = GUEST_ROOT_ADDRESS_CELLS;
sizecells = GUEST_ROOT_SIZE_CELLS;
@@ -1749,7 +1753,7 @@ static int __init prepare_dtb_domU(struct domain *d, struct kernel_info *kinfo)
if ( ret )
goto err;
- ret = make_gic_domU_node(d, kinfo->fdt);
+ ret = make_gic_domU_node(kinfo);
if ( ret )
goto err;
@@ -1761,7 +1765,7 @@ static int __init prepare_dtb_domU(struct domain *d, struct kernel_info *kinfo)
{
ret = -EINVAL;
#ifdef CONFIG_SBSA_VUART_CONSOLE
- ret = make_vpl011_uart_node(d, kinfo->fdt);
+ ret = make_vpl011_uart_node(kinfo);
#endif
if ( ret )
goto err;
@@ -1793,6 +1797,7 @@ static int __init prepare_dtb_hwdom(struct domain *d, struct kernel_info *kinfo)
ASSERT(dt_host && (dt_host->sibling == NULL));
+ kinfo->phandle_gic = dt_interrupt_controller->phandle;
fdt = device_tree_flattened;
new_size = fdt_totalsize(fdt) + DOM0_FDT_EXTRA_SIZE;
@@ -36,6 +36,9 @@ struct kernel_info {
/* Enable pl011 emulation */
bool vpl011;
+ /* GIC phandle */
+ uint32_t phandle_gic;
+
/* loader to use for this kernel */
void (*load)(struct kernel_info *info);
/* loader specific state */
Instead of always hard-coding the GIC phandle (GUEST_PHANDLE_GIC), store it in a variable under kinfo. This way it can be dynamically chosen per domain. Remove the fdt pointer argument to the make_*_domU_node functions and oass a struct kernel_info * instead. The fdt pointer can be accessed from kinfo->fdt. Remove the struct domain *d parameter to the make_*_domU_node functions because it becomes unused. Initialize phandle_gic to GUEST_PHANDLE_GIC at the beginning of prepare_dtb_domU for DomUs. Later patches will change the value of phandle_gic depending on user provided information. For Dom0, initialize phandle_gic to dt_interrupt_controller->phandle (current value) at the beginning of prepare_dtb. Signed-off-by: Stefano Stabellini <stefanos@xilinx.com> --- Changes in v6: - rename guest_phandle_gic to phandle_gic - use phandle_gic for dom0 too Changes in v5: - improve commit message Changes in v4: - new patch --- xen/arch/arm/domain_build.c | 39 ++++++++++++++++++++---------------- xen/include/asm-arm/kernel.h | 3 +++ 2 files changed, 25 insertions(+), 17 deletions(-)