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 <lvivier@redhat.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Stafford Horne <shorne@gmail.com>
This commit is contained in:
Stafford Horne 2022-06-12 20:53:44 +09:00
parent 0fd8a106ef
commit 65f5144e17
3 changed files with 31 additions and 9 deletions

View File

@ -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);

View File

@ -216,14 +216,25 @@ static int goldfish_rtc_post_load(void *opaque, int version_id)
return 0;
}
static const MemoryRegionOps goldfish_rtc_ops = {
static const MemoryRegionOps goldfish_rtc_ops[2] = {
[false] = {
.read = goldfish_rtc_read,
.write = goldfish_rtc_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.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;

View File

@ -42,6 +42,8 @@ struct GoldfishRTCState {
uint32_t irq_pending;
uint32_t irq_enabled;
uint32_t time_high;
bool big_endian;
};
#endif