summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-07-26 14:26:07 +0300
committerAnthony Liguori <aliguori@us.ibm.com>2011-07-29 08:25:43 -0500
commit16ef61c9e56657d39760e5ad6b9f5361f00b2083 (patch)
tree5afb31147fdff479bc86c44e0b0e0c70efbda484
parent14a3c10ac890e1982e55bffa37aaca764b4b525b (diff)
downloadqemu-16ef61c9e56657d39760e5ad6b9f5361f00b2083.tar.gz
qemu-16ef61c9e56657d39760e5ad6b9f5361f00b2083.tar.bz2
qemu-16ef61c9e56657d39760e5ad6b9f5361f00b2083.zip
memory: late initialization of ram_addr
For non-RAM memory regions, we cannot tell whether this is an I/O region or an MMIO region. Since the qemu backing registration is different for the two, we have to defer initialization until we know which address space we are in. These shenanigans will be removed once the backing registration is unified with the memory API. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--memory.c24
-rw-r--r--memory.h1
2 files changed, 21 insertions, 4 deletions
diff --git a/memory.c b/memory.c
index 9e1a838a89..e839c9ebdb 100644
--- a/memory.c
+++ b/memory.c
@@ -165,10 +165,14 @@ static void flatview_simplify(FlatView *view)
}
}
+static void memory_region_prepare_ram_addr(MemoryRegion *mr);
+
static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
{
ram_addr_t phys_offset, region_offset;
+ memory_region_prepare_ram_addr(fr->mr);
+
phys_offset = fr->mr->ram_addr;
region_offset = fr->offset_in_region;
/* cpu_register_physical_memory_log() wants region_offset for
@@ -519,6 +523,19 @@ static CPUWriteMemoryFunc * const memory_region_write_thunk[] = {
memory_region_write_thunk_l,
};
+static void memory_region_prepare_ram_addr(MemoryRegion *mr)
+{
+ if (mr->backend_registered) {
+ return;
+ }
+
+ mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
+ memory_region_write_thunk,
+ mr,
+ mr->ops->endianness);
+ mr->backend_registered = true;
+}
+
void memory_region_init_io(MemoryRegion *mr,
const MemoryRegionOps *ops,
void *opaque,
@@ -529,10 +546,7 @@ void memory_region_init_io(MemoryRegion *mr,
mr->ops = ops;
mr->opaque = opaque;
mr->terminates = true;
- mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
- memory_region_write_thunk,
- mr,
- mr->ops->endianness);
+ mr->backend_registered = false;
}
void memory_region_init_ram(MemoryRegion *mr,
@@ -543,6 +557,7 @@ void memory_region_init_ram(MemoryRegion *mr,
memory_region_init(mr, name, size);
mr->terminates = true;
mr->ram_addr = qemu_ram_alloc(dev, name, size);
+ mr->backend_registered = true;
}
void memory_region_init_ram_ptr(MemoryRegion *mr,
@@ -554,6 +569,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
memory_region_init(mr, name, size);
mr->terminates = true;
mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
+ mr->backend_registered = true;
}
void memory_region_init_alias(MemoryRegion *mr,
diff --git a/memory.h b/memory.h
index 47d6b9db2d..c481038f2e 100644
--- a/memory.h
+++ b/memory.h
@@ -89,6 +89,7 @@ struct MemoryRegion {
uint64_t size;
target_phys_addr_t addr;
target_phys_addr_t offset;
+ bool backend_registered;
ram_addr_t ram_addr;
bool terminates;
MemoryRegion *alias;