[PATCH 02/13] hw/riscv/fdt-common, virt.c: add create_fdt_syscon()
Daniel Henrique Barboza <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
The soon to be added riscv-server-ref board will declare a syscon FDT similar to what the 'virt' board already does. It won't have a 'sifive,test0' and 'sifive,test1' compat string though, hence we'll add a flag to enable/disable these additional properties. The FDT is slightly changed: the subnode is now named 'soc/syscon' instead of 'soc/test' to be compatible with the latest device-tree docs. Signed-off-by: Daniel Henrique Barboza <[email protected]> --- hw/riscv/fdt-common.c | 53 +++++++++++++++++++++++++++++++++++ hw/riscv/virt.c | 45 ++--------------------------- include/hw/riscv/fdt-common.h | 4 +++ 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c index e74423a225..a2168c09ec 100644 --- a/hw/riscv/fdt-common.c +++ b/hw/riscv/fdt-common.c @@ -294,3 +294,56 @@ void create_fdt_flash(void *fdt, hwaddr flashbase, hwaddr flashsize) 2, flashbase + flashsize, 2, flashsize); qemu_fdt_setprop_cell(fdt, name, "bank-width", 4); } + +/* + * @sifive_test_compat is used to create a FDT that declares + * compat with "sifive,test1" and "sifive,test0". This happens + * to be the case for the 'virt' machine that also creates a + * 'sifive_test' syscon device. + */ +void create_fdt_syscon(void *fdt, uint32_t *phandle, + hwaddr addr, hwaddr size, + uint32_t reboot, uint32_t poweroff, + bool sifive_test_compat) +{ + uint32_t syscon_phandle = (*phandle)++; + char *name; + + name = g_strdup_printf("/soc/syscon@%"HWADDR_PRIx, addr); + qemu_fdt_add_subnode(fdt, name); + + if (sifive_test_compat) { + static const char * const compat[3] = { + "sifive,test1", "sifive,test0", "syscon" + }; + + qemu_fdt_setprop_string_array(fdt, name, "compatible", + (char **)&compat, ARRAY_SIZE(compat)); + } else { + qemu_fdt_setprop_string(fdt, name, "compatible", "syscon"); + } + + qemu_fdt_setprop_sized_cells(fdt, name, "reg", + 2, addr, + 2, size); + + qemu_fdt_setprop_cell(fdt, name, "phandle", syscon_phandle); + + g_free(name); + + name = g_strdup_printf("/reboot"); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "syscon-reboot"); + qemu_fdt_setprop_cell(fdt, name, "regmap", syscon_phandle); + qemu_fdt_setprop_cell(fdt, name, "offset", 0x0); + qemu_fdt_setprop_cell(fdt, name, "value", reboot); + g_free(name); + + name = g_strdup_printf("/poweroff"); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "syscon-poweroff"); + qemu_fdt_setprop_cell(fdt, name, "regmap", syscon_phandle); + qemu_fdt_setprop_cell(fdt, name, "offset", 0x0); + qemu_fdt_setprop_cell(fdt, name, "value", poweroff); + g_free(name); +} diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 33a121abd9..acbbe458fa 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -766,47 +766,6 @@ static void create_fdt_pcie(RISCVVirtState *s, create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle); } -static void create_fdt_reset(RISCVVirtState *s, uint32_t *phandle) -{ - char *name; - uint32_t test_phandle; - MachineState *ms = MACHINE(s); - - test_phandle = (*phandle)++; - name = g_strdup_printf("/soc/test@%"HWADDR_PRIx, - s->memmap[VIRT_TEST].base); - qemu_fdt_add_subnode(ms->fdt, name); - { - static const char * const compat[3] = { - "sifive,test1", "sifive,test0", "syscon" - }; - qemu_fdt_setprop_string_array(ms->fdt, name, "compatible", - (char **)&compat, ARRAY_SIZE(compat)); - } - qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg", - 2, s->memmap[VIRT_TEST].base, - 2, s->memmap[VIRT_TEST].size); - qemu_fdt_setprop_cell(ms->fdt, name, "phandle", test_phandle); - test_phandle = qemu_fdt_get_phandle(ms->fdt, name); - g_free(name); - - name = g_strdup_printf("/reboot"); - qemu_fdt_add_subnode(ms->fdt, name); - qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot"); - qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle); - qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0); - qemu_fdt_setprop_cell(ms->fdt, name, "value", FINISHER_RESET); - g_free(name); - - name = g_strdup_printf("/poweroff"); - qemu_fdt_add_subnode(ms->fdt, name); - qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-poweroff"); - qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle); - qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0); - qemu_fdt_setprop_cell(ms->fdt, name, "value", FINISHER_PASS); - g_free(name); -} - static void create_fdt_uart(RISCVVirtState *s, uint32_t irq_mmio_phandle, int memId, int irqNo) { @@ -992,7 +951,9 @@ static void finalize_fdt(RISCVVirtState *s) create_fdt_pcie(s, irq_pcie_phandle, msi_pcie_phandle, iommu_sys_phandle); - create_fdt_reset(s, &phandle); + create_fdt_syscon(MACHINE(s)->fdt, &phandle, + s->memmap[VIRT_TEST].base, s->memmap[VIRT_TEST].size, + FINISHER_RESET, FINISHER_PASS, true); create_fdt_uarts(s, irq_mmio_phandle); diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h index 6e438e0278..31203df517 100644 --- a/include/hw/riscv/fdt-common.h +++ b/include/hw/riscv/fdt-common.h @@ -37,4 +37,8 @@ void create_fdt_plic(void *fdt, hwaddr addr, uint64_t size, bool numa_enabled, int socket); void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name); void create_fdt_flash(void *fdt, hwaddr flashbase, hwaddr flashsize); +void create_fdt_syscon(void *fdt, uint32_t *phandle, + hwaddr addr, hwaddr size, + uint32_t reboot, uint32_t poweroff, + bool sifive_test_compat); #endif -- 2.43.0