From 8a8c92c8afbb8a153968a72dd4ce504884a3209d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 6 Nov 2024 23:24:04 +0000 Subject: [PATCH] hw/char/xilinx_uartlite: Make device endianness configurable MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Replace the DEVICE_NATIVE_ENDIAN MemoryRegionOps by a pair of DEVICE_LITTLE_ENDIAN / DEVICE_BIG_ENDIAN. Add the "endianness" property to select the device endianness. This property is unspecified by default, and machines need to set it explicitly. Set the proper endianness for each machine using the device. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20250213122217.62654-6-philmd@linaro.org> --- hw/char/xilinx_uartlite.c | 34 ++++++++++++++++-------- hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 + hw/riscv/microblaze-v-generic.c | 1 + 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c index 56955e0d74..4037c937ee 100644 --- a/hw/char/xilinx_uartlite.c +++ b/hw/char/xilinx_uartlite.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" +#include "qapi/error.h" #include "hw/char/xilinx_uartlite.h" #include "hw/irq.h" #include "hw/qdev-properties.h" @@ -57,6 +58,7 @@ struct XilinxUARTLite { SysBusDevice parent_obj; + EndianMode model_endianness; MemoryRegion mmio; CharBackend chr; qemu_irq irq; @@ -166,17 +168,21 @@ uart_write(void *opaque, hwaddr addr, uart_update_irq(s); } -static const MemoryRegionOps uart_ops = { - .read = uart_read, - .write = uart_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .valid = { - .min_access_size = 1, - .max_access_size = 4 - } +static const MemoryRegionOps uart_ops[2] = { + [0 ... 1] = { + .read = uart_read, + .write = uart_write, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, + }, + [0].endianness = DEVICE_LITTLE_ENDIAN, + [1].endianness = DEVICE_BIG_ENDIAN, }; static const Property xilinx_uartlite_properties[] = { + DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XilinxUARTLite, model_endianness), DEFINE_PROP_CHR("chardev", XilinxUARTLite, chr), }; @@ -214,6 +220,15 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp) { XilinxUARTLite *s = XILINX_UARTLITE(dev); + if (s->model_endianness == ENDIAN_MODE_UNSPECIFIED) { + error_setg(errp, TYPE_XILINX_UARTLITE " property 'endianness'" + " must be set to 'big' or 'little'"); + return; + } + + memory_region_init_io(&s->mmio, OBJECT(dev), + &uart_ops[s->model_endianness == ENDIAN_MODE_BIG], + s, "xlnx.xps-uartlite", R_MAX * 4); qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event, NULL, s, NULL, true); } @@ -223,9 +238,6 @@ static void xilinx_uartlite_init(Object *obj) XilinxUARTLite *s = XILINX_UARTLITE(obj); sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); - - memory_region_init_io(&s->mmio, obj, &uart_ops, s, - "xlnx.xps-uartlite", R_MAX * 4); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); } diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index caaea222a8..bdba2006b7 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -109,6 +109,7 @@ petalogix_s3adsp1800_init(MachineState *machine) } dev = qdev_new(TYPE_XILINX_UARTLITE); + qdev_prop_set_enum(dev, "endianness", endianness); qdev_prop_set_chr(dev, "chardev", serial_hd(0)); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR); diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c index 3c79f5733b..d8e67906d2 100644 --- a/hw/riscv/microblaze-v-generic.c +++ b/hw/riscv/microblaze-v-generic.c @@ -92,6 +92,7 @@ static void mb_v_generic_init(MachineState *machine) /* Uartlite */ dev = qdev_new(TYPE_XILINX_UARTLITE); + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); qdev_prop_set_chr(dev, "chardev", serial_hd(0)); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR); -- 2.30.2