From 65f5144e1726c36c97df7e70484250941aafaa27 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Sun, 12 Jun 2022 20:53:44 +0900 Subject: [PATCH] goldfish_rtc: Add big-endian property Add a new property "big-endian" to allow configuring the RTC as either little or big endian, the default is little endian. Currently overriding the default to big endian is only used by the m68k virt platform. New platforms should prefer to use little endian and not set this. Cc: Laurent Vivier Reviewed-by: Anup Patel Reviewed-by: Richard Henderson Signed-off-by: Stafford Horne --- hw/m68k/virt.c | 1 + hw/rtc/goldfish_rtc.c | 37 ++++++++++++++++++++++++++--------- include/hw/rtc/goldfish_rtc.h | 2 ++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index 3122c8ef2c..2f3ffc0de6 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -173,6 +173,7 @@ static void virt_init(MachineState *machine) io_base = VIRT_GF_RTC_MMIO_BASE; for (i = 0; i < VIRT_GF_RTC_NB; i++) { dev = qdev_new(TYPE_GOLDFISH_RTC); + qdev_prop_set_bit(dev, "big-endian", true); sysbus = SYS_BUS_DEVICE(dev); sysbus_realize_and_unref(sysbus, &error_fatal); sysbus_mmio_map(sysbus, 0, io_base); diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c index 35e493be31..19a56402a0 100644 --- a/hw/rtc/goldfish_rtc.c +++ b/hw/rtc/goldfish_rtc.c @@ -216,14 +216,25 @@ static int goldfish_rtc_post_load(void *opaque, int version_id) return 0; } -static const MemoryRegionOps goldfish_rtc_ops = { - .read = goldfish_rtc_read, - .write = goldfish_rtc_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 4 - } +static const MemoryRegionOps goldfish_rtc_ops[2] = { + [false] = { + .read = goldfish_rtc_read, + .write = goldfish_rtc_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } + }, + [true] = { + .read = goldfish_rtc_read, + .write = goldfish_rtc_write, + .endianness = DEVICE_BIG_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } + }, }; static const VMStateDescription goldfish_rtc_vmstate = { @@ -265,7 +276,8 @@ static void goldfish_rtc_realize(DeviceState *d, Error **errp) SysBusDevice *dev = SYS_BUS_DEVICE(d); GoldfishRTCState *s = GOLDFISH_RTC(d); - memory_region_init_io(&s->iomem, OBJECT(s), &goldfish_rtc_ops, s, + memory_region_init_io(&s->iomem, OBJECT(s), + &goldfish_rtc_ops[s->big_endian], s, "goldfish_rtc", 0x24); sysbus_init_mmio(dev, &s->iomem); @@ -274,10 +286,17 @@ static void goldfish_rtc_realize(DeviceState *d, Error **errp) s->timer = timer_new_ns(rtc_clock, goldfish_rtc_interrupt, s); } +static Property goldfish_rtc_properties[] = { + DEFINE_PROP_BOOL("big-endian", GoldfishRTCState, big_endian, + false), + DEFINE_PROP_END_OF_LIST(), +}; + static void goldfish_rtc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + device_class_set_props(dc, goldfish_rtc_properties); dc->realize = goldfish_rtc_realize; dc->reset = goldfish_rtc_reset; dc->vmsd = &goldfish_rtc_vmstate; diff --git a/include/hw/rtc/goldfish_rtc.h b/include/hw/rtc/goldfish_rtc.h index 79ca7daf5d..162be33863 100644 --- a/include/hw/rtc/goldfish_rtc.h +++ b/include/hw/rtc/goldfish_rtc.h @@ -42,6 +42,8 @@ struct GoldfishRTCState { uint32_t irq_pending; uint32_t irq_enabled; uint32_t time_high; + + bool big_endian; }; #endif