diff options
Diffstat (limited to 'hw/sysbus.c')
-rw-r--r-- | hw/sysbus.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/hw/sysbus.c b/hw/sysbus.c index 2e22be7b25..ea442acb50 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -19,6 +19,7 @@ #include "sysbus.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); @@ -49,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, @@ -107,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; |