On Fri, 2026-10-02 at 09:33 +1000, Portia Stephens wrote: > Replace the ns16550 UART with a Designware UART now that a model is > available. The hack which sets the rest of the UART register space as > unimplemented can be removed. > > Signed-off-by: Portia Stephens <[email protected]> > Reviewed-by: Daniel Henrique Barboza > <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > hw/riscv/Kconfig | 2 +- > hw/riscv/tt_atlantis.c | 45 +++++++++++--------------------- > -- > include/hw/riscv/tt_atlantis.h | 4 +-- > 3 files changed, 17 insertions(+), 34 deletions(-) > > diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig > index d06ac26648..5d2abdbb67 100644 > --- a/hw/riscv/Kconfig > +++ b/hw/riscv/Kconfig > @@ -127,7 +127,7 @@ config TENSTORRENT > select RISCV_ACLINT > select RISCV_APLIC > select RISCV_IMSIC > - select SERIAL_MM > + select DW8250 > select DEVICE_TREE > select DESIGNWARE_I2C > select DS1338 > diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c > index 8a219afef7..70815e12ef 100644 > --- a/hw/riscv/tt_atlantis.c > +++ b/hw/riscv/tt_atlantis.c > @@ -24,9 +24,8 @@ > #include "hw/riscv/fdt-common.h" > #include "hw/riscv/riscv_hart.h" > > -#include "hw/char/serial-mm.h" > +#include "hw/char/dw8250.h" > #include "hw/intc/riscv_aclint.h" > -#include "hw/misc/unimp.h" > > #include "system/system.h" > #include "system/device_tree.h" > @@ -262,11 +261,15 @@ static void create_fdt_cpu(void *fdt, > TTAtlantisSoCState *s, > static void create_fdt_uart(void *fdt, const MemMapEntry *mem, int > irq, > int irqchip_phandle) > { > + static const char * const compat[2] = { > + "snps,dw-apb-uart", "ns16550a" > + }; > 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_string_array(fdt, name, "compatible", > + (char **)&compat, > ARRAY_SIZE(compat)); > 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); > @@ -409,17 +412,6 @@ static void load_fdt(TTAtlantisState *ams) > create_fdt_memory(ms->fdt, &ams->soc); > } > > -static void mmio_map_unimplemented(MemoryRegion *memory, > SysBusDevice *dev, > - const char *name, hwaddr addr, > uint64_t size) > -{ > - qdev_prop_set_string(DEVICE(dev), "name", name); > - qdev_prop_set_uint64(DEVICE(dev), "size", size); > - sysbus_realize(dev, &error_abort); > - > - memory_region_add_subregion_overlap(memory, addr, > - sysbus_mmio_get_region(dev, > 0), -1000); > -} > - > static void tt_atlantis_machine_done(Notifier *n, void *data) > { > TTAtlantisState *ams = container_of(n, TTAtlantisState, > machine_done); > @@ -488,8 +480,7 @@ static void tt_atlantis_soc_init(Object *obj) > > object_initialize_child(obj, "cpus", &s->cpus, > TYPE_RISCV_HART_ARRAY); > > - object_initialize_child(obj, "uart1", &s->uart1, > - TYPE_UNIMPLEMENTED_DEVICE); > + object_initialize_child(obj, "uart1", &s->uart1, TYPE_DW8250); > > for (int i = 0; i < TT_ATL_NUM_I2C; i++) { > object_initialize_child(obj, "i2c[*]", &s->i2c[i], > @@ -584,21 +575,13 @@ static void tt_atlantis_soc_realize(DeviceState > *dev, Error **errp) > &s->bootrom); > > /* UART1, the soc console (UART0 is for the boot > microcontroller) */ > - serial_mm_init(s->memory, s->memmap[TT_ATL_UART1].base, 2, > - qdev_get_gpio_in(s->irqchip, TT_ATL_UART1_IRQ), > - 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); > - /* > - * Atlantis contains a DesignWare uart while the QEMU machine > - * uses the serial_mm model with the base ns16550 register set. > - * Linux's dw driver writes outside of serial_mm's 0x20 sized > - * mapping and faults. > - * > - * Create an unimplemented device region so writes don't fault > - * and reads return zero, which keeps Linux happy. > - */ > - mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->uart1), > - "tt-atlantis.uart1", s- > >memmap[TT_ATL_UART1].base, > - s->memmap[TT_ATL_UART1].size); > + qdev_prop_set_chr(DEVICE(&s->uart1), "chardev", serial_hd(0)); > + sysbus_realize(SYS_BUS_DEVICE(&s->uart1), &error_fatal); > + memory_region_add_subregion(s->memory, > + s->memmap[TT_ATL_UART1].base, > + > sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart1), 0)); > + sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart1), 0, > + qdev_get_gpio_in(s->irqchip, > TT_ATL_UART1_IRQ)); > > /* I2C */ > for (int i = 0; i < TT_ATL_NUM_I2C; i++) { > diff --git a/include/hw/riscv/tt_atlantis.h > b/include/hw/riscv/tt_atlantis.h > index 3923308b7c..000988c037 100644 > --- a/include/hw/riscv/tt_atlantis.h > +++ b/include/hw/riscv/tt_atlantis.h > @@ -13,7 +13,7 @@ > #include "hw/core/sysbus.h" > #include "hw/i2c/designware_i2c.h" > #include "hw/intc/riscv_imsic.h" > -#include "hw/misc/unimp.h" > +#include "hw/char/dw8250.h" > #include "hw/riscv/riscv_hart.h" > > #define TYPE_TT_ATLANTIS_MACHINE MACHINE_TYPE_NAME("tt-atlantis") > @@ -39,7 +39,7 @@ struct TTAtlantisSoCState { > RISCVHartArrayState cpus; > DeviceState *irqchip; > DesignWareI2CState i2c[TT_ATL_NUM_I2C]; > - UnimplementedDeviceState uart1; > + DW8250State uart1; > MemoryRegion bootrom; > > uint32_t num_harts;
