]> git.proxmox.com Git - qemu.git/blobdiff - hw/sysbus.c
Use glib memory allocation and free functions
[qemu.git] / hw / sysbus.c
index 1583bd85895f528601acfdb4f8e2ce710ff8880e..f8f174665864ba8a19ca963cfdeaa3423ff3c563 100644 (file)
@@ -18,8 +18,8 @@
  */
 
 #include "sysbus.h"
-#include "sysemu.h"
 #include "monitor.h"
+#include "exec-memory.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 static char *sysbus_get_fw_dev_path(DeviceState *dev);
@@ -50,11 +50,20 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr)
     }
     if (dev->mmio[n].addr != (target_phys_addr_t)-1) {
         /* Unregister previous mapping.  */
-        cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
-                                     IO_MEM_UNASSIGNED);
+        if (dev->mmio[n].memory) {
+            memory_region_del_subregion(get_system_memory(),
+                                        dev->mmio[n].memory);
+        } else {
+            cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
+                                         IO_MEM_UNASSIGNED);
+        }
     }
     dev->mmio[n].addr = addr;
-    if (dev->mmio[n].cb) {
+    if (dev->mmio[n].memory) {
+        memory_region_add_subregion(get_system_memory(),
+                                    addr,
+                                    dev->mmio[n].memory);
+    } else if (dev->mmio[n].cb) {
         dev->mmio[n].cb(dev, addr);
     } else {
         cpu_register_physical_memory(addr, dev->mmio[n].size,
@@ -108,6 +117,17 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
     dev->mmio[n].cb = cb;
 }
 
+void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
+{
+    int n;
+
+    assert(dev->num_mmio < QDEV_MAX_MMIO);
+    n = dev->num_mmio++;
+    dev->mmio[n].addr = -1;
+    dev->mmio[n].size = memory_region_size(memory);
+    dev->mmio[n].memory = memory;
+}
+
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 {
     pio_addr_t i;
@@ -138,8 +158,8 @@ void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
 {
     SysBusDeviceInfo *info;
 
-    info = qemu_mallocz(sizeof(*info));
-    info->qdev.name = qemu_strdup(name);
+    info = g_malloc0(sizeof(*info));
+    info->qdev.name = g_strdup(name);
     info->qdev.size = size;
     info->init = init;
     sysbus_register_withprop(info);
@@ -173,11 +193,43 @@ DeviceState *sysbus_create_varargs(const char *name,
     return dev;
 }
 
+DeviceState *sysbus_try_create_varargs(const char *name,
+                                       target_phys_addr_t addr, ...)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+    va_list va;
+    qemu_irq irq;
+    int n;
+
+    dev = qdev_try_create(NULL, name);
+    if (!dev) {
+        return NULL;
+    }
+    s = sysbus_from_qdev(dev);
+    qdev_init_nofail(dev);
+    if (addr != (target_phys_addr_t)-1) {
+        sysbus_mmio_map(s, 0, addr);
+    }
+    va_start(va, addr);
+    n = 0;
+    while (1) {
+        irq = va_arg(va, qemu_irq);
+        if (!irq) {
+            break;
+        }
+        sysbus_connect_irq(s, n, irq);
+        n++;
+    }
+    return dev;
+}
+
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
 {
     SysBusDevice *s = sysbus_from_qdev(dev);
     int i;
 
+    monitor_printf(mon, "%*sirq %d\n", indent, "", s->num_irq);
     for (i = 0; i < s->num_mmio; i++) {
         monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n",
                        indent, "", s->mmio[i].addr, s->mmio[i].size);