X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=hw%2Fsysbus.c;h=702fc728f4ca32285af2b2f8b338a95487faed87;hb=6e72a00f909dcd093fbdd1faa2b3c8caa1697a6c;hp=282060abb6d59fbbbd65ea3fc6937c30b92fe853;hpb=dc717bfd057ac3d6b75c633d57e501d5e6d5ef50;p=qemu.git diff --git a/hw/sysbus.c b/hw/sysbus.c index 282060abb..702fc728f 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -17,18 +17,26 @@ * License along with this library; if not, see . */ -#include "sysbus.h" -#include "monitor.h" -#include "exec-memory.h" +#include "hw/sysbus.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,8 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) } } -void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) +static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr, + bool may_overlap, unsigned priority) { assert(n >= 0 && n < dev->num_mmio); @@ -48,16 +57,34 @@ 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. */ memory_region_del_subregion(get_system_memory(), dev->mmio[n].memory); } dev->mmio[n].addr = addr; - memory_region_add_subregion(get_system_memory(), - addr, - dev->mmio[n].memory); + if (may_overlap) { + memory_region_add_subregion_overlap(get_system_memory(), + addr, + dev->mmio[n].memory, + priority); + } + else { + memory_region_add_subregion(get_system_memory(), + addr, + dev->mmio[n].memory); + } } +void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr) +{ + sysbus_mmio_map_common(dev, n, addr, false, 0); +} + +void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr, + unsigned priority) +{ + sysbus_mmio_map_common(dev, n, addr, true, priority); +} /* Request an IRQ source. The actual IRQ object may be populated later. */ void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p) @@ -114,7 +141,7 @@ static int sysbus_device_init(DeviceState *dev) } DeviceState *sysbus_create_varargs(const char *name, - target_phys_addr_t addr, ...) + hwaddr addr, ...) { DeviceState *dev; SysBusDevice *s; @@ -123,9 +150,9 @@ DeviceState *sysbus_create_varargs(const char *name, int n; dev = qdev_create(NULL, name); - s = sysbus_from_qdev(dev); + s = SYS_BUS_DEVICE(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); @@ -143,7 +170,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; @@ -155,9 +182,9 @@ DeviceState *sysbus_try_create_varargs(const char *name, if (!dev) { return NULL; } - s = sysbus_from_qdev(dev); + s = SYS_BUS_DEVICE(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); @@ -176,8 +203,8 @@ 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; + SysBusDevice *s = SYS_BUS_DEVICE(dev); + hwaddr size; int i; monitor_printf(mon, "%*sirq %d\n", indent, "", s->num_irq); @@ -190,7 +217,7 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) static char *sysbus_get_fw_dev_path(DeviceState *dev) { - SysBusDevice *s = sysbus_from_qdev(dev); + SysBusDevice *s = SYS_BUS_DEVICE(dev); char path[40]; int off; @@ -203,16 +230,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, @@ -224,7 +251,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); @@ -244,10 +271,10 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->init = sysbus_device_init; - k->bus_info = &system_bus_info; + k->bus_type = TYPE_SYSTEM_BUS; } -static TypeInfo sysbus_device_type_info = { +static const TypeInfo sysbus_device_type_info = { .name = TYPE_SYS_BUS_DEVICE, .parent = TYPE_DEVICE, .instance_size = sizeof(SysBusDevice), @@ -256,9 +283,34 @@ static TypeInfo sysbus_device_type_info = { .class_init = sysbus_device_class_init, }; -static void sysbus_register(void) +/* 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); } -device_init(sysbus_register); +type_init(sysbus_register_types)