aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Mathieu-Daudé <philmd@linaro.org>2024-09-25 23:16:21 +0200
committerPhilippe Mathieu-Daudé <philmd@linaro.org>2025-02-16 14:34:44 +0100
commitdf1f35ab67e50f572934b7ea705764b77cf6d525 (patch)
tree01d5e8943fdc32be585110f56bb912015eba30f2
parent644276db5d707eba7dd89cc8550b3639dbd29f75 (diff)
downloadqemu-df1f35ab67e50f572934b7ea705764b77cf6d525.zip
qemu-df1f35ab67e50f572934b7ea705764b77cf6d525.tar.gz
qemu-df1f35ab67e50f572934b7ea705764b77cf6d525.tar.bz2
hw/timer/xilinx_timer: Make device endianness configurable
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. Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20250213122217.62654-5-philmd@linaro.org>
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c1
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c1
-rw-r--r--hw/ppc/virtex_ml507.c1
-rw-r--r--hw/riscv/microblaze-v-generic.c2
-rw-r--r--hw/timer/xilinx_timer.c43
5 files changed, 35 insertions, 13 deletions
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index a876aeb..984287f 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -129,6 +129,7 @@ petalogix_ml605_init(MachineState *machine)
/* 2 timers at irq 2 @ 100 Mhz. */
dev = qdev_new("xlnx.xps-timer");
+ qdev_prop_set_enum(dev, "endianness", endianness);
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index d419dc4..caaea22 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -116,6 +116,7 @@ petalogix_s3adsp1800_init(MachineState *machine)
/* 2 timers at irq 2 @ 62 Mhz. */
dev = qdev_new("xlnx.xps-timer");
+ qdev_prop_set_enum(dev, "endianness", endianness);
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index df8f964..a01354d 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -231,6 +231,7 @@ static void virtex_init(MachineState *machine)
/* 2 timers at irq 2 @ 62 Mhz. */
dev = qdev_new("xlnx.xps-timer");
+ qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_BIG);
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c
index a21fdfb..3c79f57 100644
--- a/hw/riscv/microblaze-v-generic.c
+++ b/hw/riscv/microblaze-v-generic.c
@@ -104,6 +104,7 @@ static void mb_v_generic_init(MachineState *machine)
/* 2 timers at irq 0 @ 100 Mhz. */
dev = qdev_new("xlnx.xps-timer");
+ qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE);
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 100000000);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
@@ -112,6 +113,7 @@ static void mb_v_generic_init(MachineState *machine)
/* 2 timers at irq 3 @ 100 Mhz. */
dev = qdev_new("xlnx.xps-timer");
+ qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE);
qdev_prop_set_uint32(dev, "one-timer-only", 0);
qdev_prop_set_uint32(dev, "clock-frequency", 100000000);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
index 6595cf5..4620528 100644
--- a/hw/timer/xilinx_timer.c
+++ b/hw/timer/xilinx_timer.c
@@ -3,6 +3,9 @@
*
* Copyright (c) 2009 Edgar E. Iglesias.
*
+ * DS573: https://docs.amd.com/v/u/en-US/xps_timer
+ * LogiCORE IP XPS Timer/Counter (v1.02a)
+ *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
@@ -23,10 +26,12 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/ptimer.h"
#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qom/object.h"
@@ -69,6 +74,7 @@ struct XpsTimerState
{
SysBusDevice parent_obj;
+ EndianMode model_endianness;
MemoryRegion mmio;
qemu_irq irq;
uint8_t one_timer_only;
@@ -189,18 +195,21 @@ timer_write(void *opaque, hwaddr addr,
timer_update_irq(t);
}
-static const MemoryRegionOps timer_ops = {
- .read = timer_read,
- .write = timer_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
+static const MemoryRegionOps timer_ops[2] = {
+ [0 ... 1] = {
+ .read = timer_read,
+ .write = timer_write,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
},
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4
- }
+ [0].endianness = DEVICE_LITTLE_ENDIAN,
+ [1].endianness = DEVICE_BIG_ENDIAN,
};
static void timer_hit(void *opaque)
@@ -220,6 +229,12 @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp)
XpsTimerState *t = XILINX_TIMER(dev);
unsigned int i;
+ if (t->model_endianness == ENDIAN_MODE_UNSPECIFIED) {
+ error_setg(errp, TYPE_XILINX_TIMER " property 'endianness'"
+ " must be set to 'big' or 'little'");
+ return;
+ }
+
/* Init all the ptimers. */
t->timers = g_malloc0(sizeof t->timers[0] * num_timers(t));
for (i = 0; i < num_timers(t); i++) {
@@ -233,8 +248,9 @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp)
ptimer_transaction_commit(xt->ptimer);
}
- memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, "xlnx.xps-timer",
- R_MAX * 4 * num_timers(t));
+ memory_region_init_io(&t->mmio, OBJECT(t),
+ &timer_ops[t->model_endianness == ENDIAN_MODE_BIG],
+ t, "xlnx.xps-timer", R_MAX * 4 * num_timers(t));
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &t->mmio);
}
@@ -247,6 +263,7 @@ static void xilinx_timer_init(Object *obj)
}
static const Property xilinx_timer_properties[] = {
+ DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XpsTimerState, model_endianness),
DEFINE_PROP_UINT32("clock-frequency", XpsTimerState, freq_hz, 62 * 1000000),
DEFINE_PROP_UINT8("one-timer-only", XpsTimerState, one_timer_only, 0),
};