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;

Reply via email to