X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=hw%2Fsysbus.c;h=49a41775f8ad7e2adab05a59a97011a24dec99c0;hb=5d5b24d042072fb4d13e7027f6e52e44390a9896;hp=7016903163859f2b13168dfb992109c73dfeeef2;hpb=62ec4832ea1093b20a8a0893a016a00ef8145496;p=qemu.git diff --git a/hw/sysbus.c b/hw/sysbus.c index 701690316..49a41775f 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -18,17 +18,25 @@ */ #include "sysbus.h" -#include "monitor.h" -#include "exec-memory.h" +#include "monitor/monitor.h" +#include "exec/address-spaces.h" static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *sysbus_get_fw_dev_path(DeviceState *dev); -struct BusInfo system_bus_info = { - .name = "System", - .size = sizeof(BusState), - .print_dev = sysbus_dev_print, - .get_fw_dev_path = sysbus_get_fw_dev_path, +static void system_bus_class_init(ObjectClass *klass, void *data) +{ + BusClass *k = BUS_CLASS(klass); + + k->print_dev = sysbus_dev_print; + k->get_fw_dev_path = sysbus_get_fw_dev_path; +} + +static const TypeInfo system_bus_info = { + .name = TYPE_SYSTEM_BUS, + .parent = TYPE_BUS, + .instance_size = sizeof(BusState), + .class_init = system_bus_class_init, }; void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) @@ -40,7 +48,7 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) } } -void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) +void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr) { assert(n >= 0 && n < dev->num_mmio); @@ -48,19 +56,14 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) /* ??? region already mapped here. */ return; } - if (dev->mmio[n].addr != (target_phys_addr_t)-1) { + if (dev->mmio[n].addr != (hwaddr)-1) { /* Unregister previous mapping. */ - if (dev->mmio[n].memory) { - memory_region_del_subregion(get_system_memory(), - dev->mmio[n].memory); - } + memory_region_del_subregion(get_system_memory(), dev->mmio[n].memory); } dev->mmio[n].addr = addr; - if (dev->mmio[n].memory) { - memory_region_add_subregion(get_system_memory(), - addr, - dev->mmio[n].memory); - } + memory_region_add_subregion(get_system_memory(), + addr, + dev->mmio[n].memory); } @@ -110,35 +113,16 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) } } -static int sysbus_device_init(DeviceState *dev, DeviceInfo *base) -{ - SysBusDeviceInfo *info = container_of(base, SysBusDeviceInfo, qdev); - - return info->init(sysbus_from_qdev(dev)); -} - -void sysbus_register_withprop(SysBusDeviceInfo *info) -{ - info->qdev.init = sysbus_device_init; - info->qdev.bus_info = &system_bus_info; - - assert(info->qdev.size >= sizeof(SysBusDevice)); - qdev_register(&info->qdev); -} - -void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init) +static int sysbus_device_init(DeviceState *dev) { - SysBusDeviceInfo *info; + SysBusDevice *sd = SYS_BUS_DEVICE(dev); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd); - info = g_malloc0(sizeof(*info)); - info->qdev.name = g_strdup(name); - info->qdev.size = size; - info->init = init; - sysbus_register_withprop(info); + return sbc->init(sd); } DeviceState *sysbus_create_varargs(const char *name, - target_phys_addr_t addr, ...) + hwaddr addr, ...) { DeviceState *dev; SysBusDevice *s; @@ -149,7 +133,7 @@ DeviceState *sysbus_create_varargs(const char *name, dev = qdev_create(NULL, name); s = sysbus_from_qdev(dev); qdev_init_nofail(dev); - if (addr != (target_phys_addr_t)-1) { + if (addr != (hwaddr)-1) { sysbus_mmio_map(s, 0, addr); } va_start(va, addr); @@ -167,7 +151,7 @@ DeviceState *sysbus_create_varargs(const char *name, } DeviceState *sysbus_try_create_varargs(const char *name, - target_phys_addr_t addr, ...) + hwaddr addr, ...) { DeviceState *dev; SysBusDevice *s; @@ -181,7 +165,7 @@ DeviceState *sysbus_try_create_varargs(const char *name, } s = sysbus_from_qdev(dev); qdev_init_nofail(dev); - if (addr != (target_phys_addr_t)-1) { + if (addr != (hwaddr)-1) { sysbus_mmio_map(s, 0, addr); } va_start(va, addr); @@ -201,15 +185,12 @@ DeviceState *sysbus_try_create_varargs(const char *name, static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) { SysBusDevice *s = sysbus_from_qdev(dev); - target_phys_addr_t size; + hwaddr size; int i; monitor_printf(mon, "%*sirq %d\n", indent, "", s->num_irq); for (i = 0; i < s->num_mmio; i++) { - size = 0; - if (s->mmio[i].memory) { - size = memory_region_size(s->mmio[i].memory); - } + size = memory_region_size(s->mmio[i].memory); monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", indent, "", s->mmio[i].addr, size); } @@ -230,16 +211,16 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) snprintf(path + off, sizeof(path) - off, "@i%04x", s->pio[0]); } - return strdup(path); + return g_strdup(path); } -void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr, +void sysbus_add_memory(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem) { memory_region_add_subregion(get_system_memory(), addr, mem); } -void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr, +void sysbus_add_memory_overlap(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem, unsigned priority) { memory_region_add_subregion_overlap(get_system_memory(), addr, mem, @@ -251,7 +232,7 @@ void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem) memory_region_del_subregion(get_system_memory(), mem); } -void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr, +void sysbus_add_io(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem) { memory_region_add_subregion(get_system_io(), addr, mem); @@ -266,3 +247,51 @@ MemoryRegion *sysbus_address_space(SysBusDevice *dev) { return get_system_memory(); } + +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; +} + +static TypeInfo sysbus_device_type_info = { + .name = TYPE_SYS_BUS_DEVICE, + .parent = TYPE_DEVICE, + .instance_size = sizeof(SysBusDevice), + .abstract = true, + .class_size = sizeof(SysBusDeviceClass), + .class_init = sysbus_device_class_init, +}; + +/* This is a nasty hack to allow passing a NULL bus to qdev_create. */ +static BusState *main_system_bus; + +static void main_system_bus_create(void) +{ + /* assign main_system_bus before qbus_create_inplace() + * in order to make "if (bus != sysbus_get_default())" work */ + main_system_bus = g_malloc0(system_bus_info.instance_size); + qbus_create_inplace(main_system_bus, TYPE_SYSTEM_BUS, NULL, + "main-system-bus"); + OBJECT(main_system_bus)->free = g_free; + object_property_add_child(container_get(qdev_get_machine(), + "/unattached"), + "sysbus", OBJECT(main_system_bus), NULL); +} + +BusState *sysbus_get_default(void) +{ + if (!main_system_bus) { + main_system_bus_create(); + } + return main_system_bus; +} + +static void sysbus_register_types(void) +{ + type_register_static(&system_bus_info); + type_register_static(&sysbus_device_type_info); +} + +type_init(sysbus_register_types)