On Thu, Aug 27, 2026 at 07:25:56PM +0800, Daniel Henrique Barboza wrote:
> 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]>
> Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Reviewed-by: Chao Liu <[email protected]>

Thanks,
Chao

> ---
>  hw/riscv/fdt-common.c         | 54 +++++++++++++++++++++++++++++++++++
>  hw/riscv/virt.c               | 46 +++--------------------------
>  include/hw/riscv/fdt-common.h |  4 +++
>  3 files changed, 62 insertions(+), 42 deletions(-)
> 
> diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
> index 6fcc1ce21f..eac5ca9322 100644
> --- a/hw/riscv/fdt-common.c
> +++ b/hw/riscv/fdt-common.c
> @@ -295,3 +295,57 @@ void riscv_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 riscv_create_fdt_syscon(void *fdt, uint32_t *next_phandle,
> +                             hwaddr addr, hwaddr size,
> +                             uint32_t reboot, uint32_t poweroff,
> +                             bool sifive_test_compat)
> +{
> +    uint32_t syscon_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);
> +
> +    syscon_phandle = next_phandle ? (*next_phandle)++ : 
> qemu_fdt_alloc_phandle(fdt);
> +    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 e48337dfd9..ab6c53c78a 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -768,47 +768,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)
>  {
> @@ -994,7 +953,10 @@ static void finalize_fdt(RISCVVirtState *s)
>      create_fdt_pcie(s, irq_pcie_phandle, msi_pcie_phandle,
>                      iommu_sys_phandle);
>  
> -    create_fdt_reset(s, &phandle);
> +    riscv_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 b422da6aef..e377682b32 100644
> --- a/include/hw/riscv/fdt-common.h
> +++ b/include/hw/riscv/fdt-common.h
> @@ -39,4 +39,8 @@ void riscv_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 riscv_create_fdt_flash(void *fdt, hwaddr flashbase, hwaddr flashsize);
> +void riscv_create_fdt_syscon(void *fdt, uint32_t *next_phandle,
> +                             hwaddr addr, hwaddr size,
> +                             uint32_t reboot, uint32_t poweroff,
> +                             bool sifive_test_compat);
>  #endif
> -- 
> 2.43.0
> 

Reply via email to