X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/776346cd63e5a1ceeeb4d81fa111d911abb73a69..03e947f9c2264356aef037e6bf9c496b5deae2d2:/hw/core/sysbus.c diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 84af59379d..5d0887f499 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -17,6 +17,7 @@ * License along with this library; if not, see . */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "monitor/monitor.h" #include "exec/address-spaces.h" @@ -91,6 +92,8 @@ bool sysbus_has_irq(SysBusDevice *dev, int n) ObjectProperty *r; r = object_property_find(OBJECT(dev), prop, NULL); + g_free(prop); + return (r != NULL); } @@ -107,7 +110,13 @@ qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n) void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) { + SysBusDeviceClass *sbd = SYS_BUS_DEVICE_GET_CLASS(dev); + qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq); + + if (sbd->connect_irq_notifier) { + sbd->connect_irq_notifier(dev, irq); + } } /* Check whether an MMIO region exists */ @@ -181,9 +190,9 @@ MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n) return dev->mmio[n].memory; } -void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) +void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size) { - pio_addr_t i; + uint32_t i; for (i = 0; i < size; i++) { assert(dev->num_pio < QDEV_MAX_PIO); @@ -279,19 +288,26 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) static char *sysbus_get_fw_dev_path(DeviceState *dev) { SysBusDevice *s = SYS_BUS_DEVICE(dev); - char path[40]; - int off; - - off = snprintf(path, sizeof(path), "%s", qdev_fw_name(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) { - snprintf(path + off, sizeof(path) - off, "@"TARGET_FMT_plx, - s->mmio[0].addr); - } else if (s->num_pio) { - snprintf(path + off, sizeof(path) - off, "@i%04x", s->pio[0]); + return g_strdup_printf("%s@" TARGET_FMT_plx, qdev_fw_name(dev), + s->mmio[0].addr); } - - return g_strdup(path); + 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) { + fw_dev_path = g_strdup_printf("%s@%s", qdev_fw_name(dev), addr); + g_free(addr); + return fw_dev_path; + } + } + return g_strdup(qdev_fw_name(dev)); } void sysbus_add_io(SysBusDevice *dev, hwaddr addr, @@ -310,6 +326,17 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data) DeviceClass *k = DEVICE_CLASS(klass); k->init = sysbus_device_init; k->bus_type = TYPE_SYSTEM_BUS; + /* + * device_add plugs devices into a suitable bus. For "real" buses, + * that actually connects the device. For sysbus, the connections + * need to be made separately, and device_add can't do that. The + * device would be left unconnected, and will probably not work + * + * However, a few machines can handle device_add/-device with + * a few specific sysbus devices. In those cases, the device + * subclass needs to override it and set user_creatable=true. + */ + k->user_creatable = false; } static const TypeInfo sysbus_device_type_info = {