On Mon, Jun 8, 2020 at 7:23 AM Bin Meng <bmeng...@gmail.com> wrote: > > From: Bin Meng <bin.m...@windriver.com> > > The HiFive Unleashed board wires GPIO pin#10 to the input of the > system reset signal. Let's set up the GPIO pin#10 and insert a > "gpio-restart" device tree node so that reboot is now functional > with QEMU 'sifive_u' machine. > > Signed-off-by: Bin Meng <bin.m...@windriver.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > > hw/riscv/sifive_u.c | 24 +++++++++++++++++++++++- > 1 file changed, 23 insertions(+), 1 deletion(-) > > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c > index 881949b..ef51874 100644 > --- a/hw/riscv/sifive_u.c > +++ b/hw/riscv/sifive_u.c > @@ -37,6 +37,7 @@ > #include "qapi/error.h" > #include "qapi/visitor.h" > #include "hw/boards.h" > +#include "hw/irq.h" > #include "hw/loader.h" > #include "hw/sysbus.h" > #include "hw/char/serial.h" > @@ -53,6 +54,7 @@ > #include "net/eth.h" > #include "sysemu/arch_init.h" > #include "sysemu/device_tree.h" > +#include "sysemu/runstate.h" > #include "sysemu/sysemu.h" > #include "exec/address-spaces.h" > > @@ -96,7 +98,7 @@ static void create_fdt(SiFiveUState *s, const struct > MemmapEntry *memmap, > uint32_t *cells; > char *nodename; > char ethclk_names[] = "pclk\0hclk"; > - uint32_t plic_phandle, prci_phandle, phandle = 1; > + uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1; > uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle; > > fdt = s->fdt = create_device_tree(&s->fdt_size); > @@ -270,9 +272,11 @@ static void create_fdt(SiFiveUState *s, const struct > MemmapEntry *memmap, > g_free(cells); > g_free(nodename); > > + gpio_phandle = phandle++; > nodename = g_strdup_printf("/soc/gpio@%lx", > (long)memmap[SIFIVE_U_GPIO].base); > qemu_fdt_add_subnode(fdt, nodename); > + qemu_fdt_setprop_cell(fdt, nodename, "phandle", gpio_phandle); > qemu_fdt_setprop_cells(fdt, nodename, "clocks", > prci_phandle, PRCI_CLK_TLCLK); > qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2); > @@ -292,6 +296,12 @@ static void create_fdt(SiFiveUState *s, const struct > MemmapEntry *memmap, > qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0"); > g_free(nodename); > > + nodename = g_strdup_printf("/gpio-restart"); > + qemu_fdt_add_subnode(fdt, nodename); > + qemu_fdt_setprop_cells(fdt, nodename, "gpios", gpio_phandle, 10, 1); > + qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart"); > + g_free(nodename); > + > phy_phandle = phandle++; > nodename = g_strdup_printf("/soc/ethernet@%lx", > (long)memmap[SIFIVE_U_GEM].base); > @@ -352,6 +362,14 @@ static void create_fdt(SiFiveUState *s, const struct > MemmapEntry *memmap, > g_free(nodename); > } > > +static void sifive_u_machine_reset(void *opaque, int n, int level) > +{ > + /* gpio pin active low triggers reset */ > + if (!level) { > + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); > + } > +} > + > static void sifive_u_machine_init(MachineState *machine) > { > const struct MemmapEntry *memmap = sifive_u_memmap; > @@ -383,6 +401,10 @@ static void sifive_u_machine_init(MachineState *machine) > memory_region_add_subregion(system_memory, memmap[SIFIVE_U_FLASH0].base, > flash0); > > + /* register gpio-restart */ > + qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10, > + qemu_allocate_irq(sifive_u_machine_reset, NULL, > 0)); > + > /* create device tree */ > create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); > > -- > 2.7.4 > >