aboutsummaryrefslogtreecommitdiff
path: root/hw/ssi
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2023-06-07 06:39:38 +0200
committerCédric Le Goater <clg@kaod.org>2023-09-01 11:40:04 +0200
commita617e65f43788e08dd390aa41798b0e57b936c6d (patch)
tree4f1e6dd5c664fb182ea54162b66c2f0f75290fc5 /hw/ssi
parent27a2c66c92ec1f7a1e6456c8b274ae538d68ae7f (diff)
hw/ssi: Check for duplicate CS indexes
This to avoid indexes conflicts on the same SSI bus. Adapt machines using multiple devices on the same bus to avoid breakage. Cc: "Edgar E. Iglesias" <edgar.iglesias@gmail.com> Cc: Alistair Francis <alistair@alistair23.me> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'hw/ssi')
-rw-r--r--hw/ssi/ssi.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 54ca3c34e9..1f3e540ab8 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -42,10 +42,31 @@ DeviceState *ssi_get_cs(SSIBus *bus, uint8_t cs_index)
return NULL;
}
+static bool ssi_bus_check_address(BusState *b, DeviceState *dev, Error **errp)
+{
+ SSIPeripheral *s = SSI_PERIPHERAL(dev);
+
+ if (ssi_get_cs(SSI_BUS(b), s->cs_index)) {
+ error_setg(errp, "CS index '0x%x' in use by a %s device", s->cs_index,
+ object_get_typename(OBJECT(dev)));
+ return false;
+ }
+
+ return true;
+}
+
+static void ssi_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->check_address = ssi_bus_check_address;
+}
+
static const TypeInfo ssi_bus_info = {
.name = TYPE_SSI_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(SSIBus),
+ .class_init = ssi_bus_class_init,
};
static void ssi_cs_default(void *opaque, int n, int level)