[PATCH v2 08/13] hw/riscv/fdt-common, virt.c, tt_atlantis.c: add create_fdt_uart()
Daniel Henrique Barboza <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Add a common uart FDT helper to be used by 'virt' and 'tt-atlantis'. To accomodate both boards the helper is doing the following: - an 'uses_32_bit_spacing' flag controls whether we need to set a different uart reg spacing for the 'tt-atlantis' board; - an 'is_serial0' flag is added to control whether we need to set additional properties related to the first serial. This is required because the 'virt' board adds two uarts in the FDT. No FDT changes intended. Reviewed-by: Anirudh Srinivasan <[email protected]> Signed-off-by: Daniel Henrique Barboza <[email protected]> --- hw/riscv/fdt-common.c | 39 +++++++++++++++++++++++++++++++ hw/riscv/tt_atlantis.c | 21 +---------------- hw/riscv/virt.c | 44 +++++++---------------------------- include/hw/riscv/fdt-common.h | 4 ++++ 4 files changed, 52 insertions(+), 56 deletions(-) diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c index f31cc9d3cc..d254534654 100644 --- a/hw/riscv/fdt-common.c +++ b/hw/riscv/fdt-common.c @@ -791,3 +791,42 @@ void create_fdt_socket_aclint(void *fdt, ACLINTFdtProps *props, g_free(name); } } + +void create_fdt_uart(void *fdt, const MemMapEntry *uart_mem, + int uart_irq, int aia_type, + bool uses_32_bit_spacing, bool is_serial0, + uint32_t irq_mmio_phandle) +{ + g_autofree char *name = NULL; + + name = g_strdup_printf("/soc/serial@%"HWADDR_PRIx, uart_mem->base); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "ns16550a"); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", + 2, uart_mem->base, + 2, uart_mem->size); + + /* + * The tt-atlantis board uses an uart that has 32 bit + * register spacing (0x0, 0x4, 0x8, 0xc....) rather than + * 8 bit spacing like 'virt'. + */ + if (uses_32_bit_spacing) { + qemu_fdt_setprop_cell(fdt, name, "reg-shift", 2); + qemu_fdt_setprop_cell(fdt, name, "reg-io-width", 4); + } + + qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 3686400); + qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irq_mmio_phandle); + + if (aia_type == AIA_TYPE_NONE) { + qemu_fdt_setprop_cell(fdt, name, "interrupts", uart_irq); + } else { + qemu_fdt_setprop_cells(fdt, name, "interrupts", uart_irq, 0x4); + } + + if (is_serial0) { + qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name); + qemu_fdt_setprop_string(fdt, "/aliases", "serial0", name); + } +} diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index d808bcc11c..eb22b67b71 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -259,25 +259,6 @@ static void create_fdt_cpu(TTAtlantisState *s, const MemMapEntry *memmap, IRQ_S_EXT, s->soc.num_harts); } -static void create_fdt_uart(void *fdt, const MemMapEntry *mem, int irq, - int irqchip_phandle) -{ - g_autofree char *name = g_strdup_printf("/soc/serial@%"HWADDR_PRIX, - mem->base); - - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_string(fdt, name, "compatible", "ns16550a"); - qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->size); - qemu_fdt_setprop_cell(fdt, name, "reg-shift", 2); - qemu_fdt_setprop_cell(fdt, name, "reg-io-width", 4); - qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 3686400); - qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle); - qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4); - - qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name); - qemu_fdt_setprop_string(fdt, "/aliases", "serial0", name); -} - static void create_fdt_rng(void *fdt) { uint8_t rng_seed[32]; @@ -345,7 +326,7 @@ static void finalize_fdt(TTAtlantisState *s) */ create_fdt_uart(fdt, &s->memmap[TT_ATL_UART1], TT_ATL_UART1_IRQ, - aplic_s_phandle); + AIA_TYPE_APLIC_IMSIC, true, true, aplic_s_phandle); create_fdt_clk(fdt, "periph-clk", 100000000, periph_clk_phandle); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index ef2670f20e..e4bf9c26ef 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -415,41 +415,6 @@ static void create_fdt_virtio(RISCVVirtState *s, uint32_t irq_virtio_phandle) } } -static void create_fdt_uart(RISCVVirtState *s, - uint32_t irq_mmio_phandle, int memId, int irqNo) -{ - g_autofree char *name = NULL; - MachineState *ms = MACHINE(s); - - name = g_strdup_printf("/soc/serial@%"HWADDR_PRIx, - s->memmap[memId].base); - qemu_fdt_add_subnode(ms->fdt, name); - qemu_fdt_setprop_string(ms->fdt, name, "compatible", "ns16550a"); - qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg", - 2, s->memmap[memId].base, - 2, s->memmap[memId].size); - qemu_fdt_setprop_cell(ms->fdt, name, "clock-frequency", 3686400); - qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_mmio_phandle); - if (s->aia_type == VIRT_AIA_TYPE_NONE) { - qemu_fdt_setprop_cell(ms->fdt, name, "interrupts", irqNo); - } else { - qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", irqNo, 0x4); - } - - if (VIRT_UART0 == memId) { - qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", name); - qemu_fdt_setprop_string(ms->fdt, "/aliases", "serial0", name); - } -} - -static void create_fdt_uarts(RISCVVirtState *s, uint32_t irq_mmio_phandle) -{ - if (s->uart1_present) { - create_fdt_uart(s, irq_mmio_phandle, VIRT_UART1, UART1_IRQ); - } - create_fdt_uart(s, irq_mmio_phandle, VIRT_UART0, UART0_IRQ); -} - static void create_fdt_rtc(RISCVVirtState *s, uint32_t irq_mmio_phandle) { @@ -571,7 +536,14 @@ static void finalize_fdt(RISCVVirtState *s) s->memmap[VIRT_TEST].base, s->memmap[VIRT_TEST].size, FINISHER_RESET, FINISHER_PASS, true); - create_fdt_uarts(s, irq_mmio_phandle); + create_fdt_uart(MACHINE(s)->fdt, &s->memmap[VIRT_UART0], UART0_IRQ, + s->aia_type, false, true, irq_mmio_phandle); + + if (s->uart1_present) { + create_fdt_uart(MACHINE(s)->fdt, &s->memmap[VIRT_UART1], + UART1_IRQ, s->aia_type, false, false, + irq_mmio_phandle); + } create_fdt_rtc(s, irq_mmio_phandle); } diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h index fbcf9aaffb..9a80e0734d 100644 --- a/include/hw/riscv/fdt-common.h +++ b/include/hw/riscv/fdt-common.h @@ -123,4 +123,8 @@ void create_fdt_socket_aplic(void *fdt, APLICFdtProps *props, uint32_t *aplic_phandles); void create_fdt_socket_aclint(void *fdt, ACLINTFdtProps *props, uint32_t *intc_phandles); +void create_fdt_uart(void *fdt, const MemMapEntry *uart_mem, + int uart_irq, int aia_type, + bool uses_32_bit_spacing, bool is_serial0, + uint32_t irq_mmio_phandle); #endif -- 2.43.0