aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorPhilippe Mathieu-Daudé <philmd@linaro.org>2024-09-25 23:15:04 +0200
committerPhilippe Mathieu-Daudé <philmd@linaro.org>2025-02-16 14:34:09 +0100
commit2cdf693b197db6c6c27ff2bf02fce1c0bb384786 (patch)
treec504fd64a67cdbd0c3c01f825389d7bcd311dfc1 /hw/intc
parent4ec96630f93ec2a1fd8bf9c9150cdae330531de8 (diff)
downloadqemu-2cdf693b197db6c6c27ff2bf02fce1c0bb384786.zip
qemu-2cdf693b197db6c6c27ff2bf02fce1c0bb384786.tar.gz
qemu-2cdf693b197db6c6c27ff2bf02fce1c0bb384786.tar.bz2
hw/intc/xilinx_intc: 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-3-philmd@linaro.org>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/xilinx_intc.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c
index 6930f83..ab1c4a3 100644
--- a/hw/intc/xilinx_intc.c
+++ b/hw/intc/xilinx_intc.c
@@ -3,6 +3,9 @@
*
* Copyright (c) 2009 Edgar E. Iglesias.
*
+ * https://docs.amd.com/v/u/en-US/xps_intc
+ * DS572: LogiCORE IP XPS Interrupt Controller (v2.01a)
+ *
* 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 "qemu/module.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
#include "qom/object.h"
#define D(x)
@@ -49,6 +54,7 @@ struct XpsIntc
{
SysBusDevice parent_obj;
+ EndianMode model_endianness;
MemoryRegion mmio;
qemu_irq parent_irq;
@@ -140,18 +146,28 @@ static void pic_write(void *opaque, hwaddr addr,
update_irq(p);
}
-static const MemoryRegionOps pic_ops = {
- .read = pic_read,
- .write = pic_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
+static const MemoryRegionOps pic_ops[2] = {
+ [0 ... 1] = {
+ .read = pic_read,
+ .write = pic_write,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+ .valid = {
+ /*
+ * All XPS INTC registers are accessed through the PLB interface.
+ * The base address for these registers is provided by the
+ * configuration parameter, C_BASEADDR. Each register is 32 bits
+ * although some bits may be unused and is accessed on a 4-byte
+ * boundary offset from the base address.
+ */
+ .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 irq_handler(void *opaque, int irq, int level)
@@ -174,13 +190,27 @@ static void xilinx_intc_init(Object *obj)
qdev_init_gpio_in(DEVICE(obj), irq_handler, 32);
sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &p->mmio);
+}
- memory_region_init_io(&p->mmio, obj, &pic_ops, p, "xlnx.xps-intc",
+static void xilinx_intc_realize(DeviceState *dev, Error **errp)
+{
+ XpsIntc *p = XILINX_INTC(dev);
+
+ if (p->model_endianness == ENDIAN_MODE_UNSPECIFIED) {
+ error_setg(errp, TYPE_XILINX_INTC " property 'endianness'"
+ " must be set to 'big' or 'little'");
+ return;
+ }
+
+ memory_region_init_io(&p->mmio, OBJECT(dev),
+ &pic_ops[p->model_endianness == ENDIAN_MODE_BIG],
+ p, "xlnx.xps-intc",
R_MAX * 4);
- sysbus_init_mmio(SYS_BUS_DEVICE(obj), &p->mmio);
}
static const Property xilinx_intc_properties[] = {
+ DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XpsIntc, model_endianness),
DEFINE_PROP_UINT32("kind-of-intr", XpsIntc, c_kind_of_intr, 0),
};
@@ -188,6 +218,7 @@ static void xilinx_intc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->realize = xilinx_intc_realize;
device_class_set_props(dc, xilinx_intc_properties);
}