aboutsummaryrefslogtreecommitdiff
path: root/hw/riscv/virt.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/riscv/virt.c')
-rw-r--r--hw/riscv/virt.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index c44b865959..7f9e1e5176 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -58,6 +58,7 @@ static const struct MemmapEntry {
[VIRT_DEBUG] = { 0x0, 0x100 },
[VIRT_MROM] = { 0x1000, 0x11000 },
[VIRT_TEST] = { 0x100000, 0x1000 },
+ [VIRT_RTC] = { 0x101000, 0x1000 },
[VIRT_CLINT] = { 0x2000000, 0x10000 },
[VIRT_PLIC] = { 0xc000000, 0x4000000 },
[VIRT_UART0] = { 0x10000000, 0x100 },
@@ -182,11 +183,10 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
uint64_t mem_size, const char *cmdline)
{
void *fdt;
- int cpu;
+ int cpu, i;
uint32_t *cells;
char *nodename;
- uint32_t plic_phandle, phandle = 1;
- int i;
+ uint32_t plic_phandle, test_phandle, phandle = 1;
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
@@ -356,16 +356,35 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
create_pcie_irq_map(fdt, nodename, plic_phandle);
g_free(nodename);
+ test_phandle = phandle++;
nodename = g_strdup_printf("/test@%lx",
(long)memmap[VIRT_TEST].base);
qemu_fdt_add_subnode(fdt, nodename);
{
- const char compat[] = "sifive,test1\0sifive,test0";
+ const char compat[] = "sifive,test1\0sifive,test0\0syscon";
qemu_fdt_setprop(fdt, nodename, "compatible", compat, sizeof(compat));
}
qemu_fdt_setprop_cells(fdt, nodename, "reg",
0x0, memmap[VIRT_TEST].base,
0x0, memmap[VIRT_TEST].size);
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", test_phandle);
+ test_phandle = qemu_fdt_get_phandle(fdt, nodename);
+ g_free(nodename);
+
+ nodename = g_strdup_printf("/reboot");
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-reboot");
+ qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
+ qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
+ qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_RESET);
+ g_free(nodename);
+
+ nodename = g_strdup_printf("/poweroff");
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-poweroff");
+ qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
+ qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
+ qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_PASS);
g_free(nodename);
nodename = g_strdup_printf("/uart@%lx",
@@ -386,6 +405,18 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
}
g_free(nodename);
+ nodename = g_strdup_printf("/rtc@%lx",
+ (long)memmap[VIRT_RTC].base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
+ "google,goldfish-rtc");
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
+ 0x0, memmap[VIRT_RTC].base,
+ 0x0, memmap[VIRT_RTC].size);
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
+ g_free(nodename);
+
nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
qemu_fdt_add_subnode(s->fdt, nodename);
qemu_fdt_setprop_string(s->fdt, nodename, "compatible", "cfi-flash");
@@ -583,6 +614,9 @@ static void riscv_virt_board_init(MachineState *machine)
0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
serial_hd(0), DEVICE_LITTLE_ENDIAN);
+ sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
+ qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
+
virt_flash_create(s);
for (i = 0; i < ARRAY_SIZE(s->flash); i++) {