Skip to content

Commit 5133ed1

Browse files
lbmengalistair23
authored andcommitted
hw/riscv: sifive_u: Add reset functionality
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 <[email protected]> Reviewed-by: Alistair Francis <[email protected]> Message-id: [email protected] Message-Id: <[email protected]> Signed-off-by: Alistair Francis <[email protected]>
1 parent 621c100 commit 5133ed1

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

hw/riscv/sifive_u.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "qapi/error.h"
3838
#include "qapi/visitor.h"
3939
#include "hw/boards.h"
40+
#include "hw/irq.h"
4041
#include "hw/loader.h"
4142
#include "hw/sysbus.h"
4243
#include "hw/char/serial.h"
@@ -53,6 +54,7 @@
5354
#include "net/eth.h"
5455
#include "sysemu/arch_init.h"
5556
#include "sysemu/device_tree.h"
57+
#include "sysemu/runstate.h"
5658
#include "sysemu/sysemu.h"
5759
#include "exec/address-spaces.h"
5860

@@ -96,7 +98,7 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
9698
uint32_t *cells;
9799
char *nodename;
98100
char ethclk_names[] = "pclk\0hclk";
99-
uint32_t plic_phandle, prci_phandle, phandle = 1;
101+
uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
100102
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
101103

102104
fdt = s->fdt = create_device_tree(&s->fdt_size);
@@ -270,9 +272,11 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
270272
g_free(cells);
271273
g_free(nodename);
272274

275+
gpio_phandle = phandle++;
273276
nodename = g_strdup_printf("/soc/gpio@%lx",
274277
(long)memmap[SIFIVE_U_GPIO].base);
275278
qemu_fdt_add_subnode(fdt, nodename);
279+
qemu_fdt_setprop_cell(fdt, nodename, "phandle", gpio_phandle);
276280
qemu_fdt_setprop_cells(fdt, nodename, "clocks",
277281
prci_phandle, PRCI_CLK_TLCLK);
278282
qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
@@ -292,6 +296,12 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
292296
qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
293297
g_free(nodename);
294298

299+
nodename = g_strdup_printf("/gpio-restart");
300+
qemu_fdt_add_subnode(fdt, nodename);
301+
qemu_fdt_setprop_cells(fdt, nodename, "gpios", gpio_phandle, 10, 1);
302+
qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart");
303+
g_free(nodename);
304+
295305
phy_phandle = phandle++;
296306
nodename = g_strdup_printf("/soc/ethernet@%lx",
297307
(long)memmap[SIFIVE_U_GEM].base);
@@ -352,6 +362,14 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
352362
g_free(nodename);
353363
}
354364

365+
static void sifive_u_machine_reset(void *opaque, int n, int level)
366+
{
367+
/* gpio pin active low triggers reset */
368+
if (!level) {
369+
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
370+
}
371+
}
372+
355373
static void sifive_u_machine_init(MachineState *machine)
356374
{
357375
const struct MemmapEntry *memmap = sifive_u_memmap;
@@ -380,6 +398,10 @@ static void sifive_u_machine_init(MachineState *machine)
380398
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_FLASH0].base,
381399
flash0);
382400

401+
/* register gpio-restart */
402+
qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10,
403+
qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
404+
383405
/* create device tree */
384406
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
385407

0 commit comments

Comments
 (0)