From be64d7776bcc48a542acf1f74765a3930692cef4 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 5 Aug 2018 12:28:49 +0100 Subject: [PATCH] sysbus: always allow explicit_ofw_unit_address() to override address generation Some SysBusDevices either use sysbus_init_mmio() without sysbus_mmio_map() or the first MMIO memory region doesn't represent the bus address, causing a firmware device path with an invalid address to be generated. SysBusDeviceClass does provide a virtual explicit_ofw_unit_address() method that can be used to override this process, but it was originally intended only as as a fallback option meaning that any existing MMIO memory regions still take priority whilst determining the firmware device address. There is currently only one user of explicit_ofw_unit_address() and that is the PCI expander bridge (PXB) device which has no MMIO/PIO resources defined. This enables us to allow explicit_ofw_unit_address() to take priority without affecting backwards compatibility, allowing the address to be customised as required. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laszlo Ersek Message-Id: <20180805112850.26063-2-mark.cave-ayland@ilande.co.uk> Reviewed-by: Thomas Huth Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- hw/core/sysbus.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 3c8e53b188..7ac36ad3e7 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -293,16 +293,8 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) { SysBusDevice *s = SYS_BUS_DEVICE(dev); SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(s); - /* for the explicit unit address fallback case: */ char *addr, *fw_dev_path; - if (s->num_mmio) { - return g_strdup_printf("%s@" TARGET_FMT_plx, qdev_fw_name(dev), - s->mmio[0].addr); - } - if (s->num_pio) { - return g_strdup_printf("%s@i%04x", qdev_fw_name(dev), s->pio[0]); - } if (sbc->explicit_ofw_unit_address) { addr = sbc->explicit_ofw_unit_address(s); if (addr) { @@ -311,6 +303,13 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) return fw_dev_path; } } + if (s->num_mmio) { + return g_strdup_printf("%s@" TARGET_FMT_plx, qdev_fw_name(dev), + s->mmio[0].addr); + } + if (s->num_pio) { + return g_strdup_printf("%s@i%04x", qdev_fw_name(dev), s->pio[0]); + } return g_strdup(qdev_fw_name(dev)); }