45e84a0
From 2061800b85ddcc9b34b5ccbfaa87f7e8b94626a6 Mon Sep 17 00:00:00 2001
45e84a0
From: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>
45e84a0
Date: Wed, 30 Nov 2011 16:26:21 +0100
45e84a0
Subject: [PATCH 02/25] exec.c: Fix subpage memory access to RAM MemoryRegion
45e84a0
MIME-Version: 1.0
45e84a0
Content-Type: text/plain; charset=UTF-8
45e84a0
Content-Transfer-Encoding: 8bit
45e84a0
45e84a0
Commit 95c318f5e1f88d7e5bcc6deac17330fd4806a2d3 (Fix segfault in mmio
45e84a0
subpage handling code.) prevented a segfault by making all subpage
45e84a0
registrations over an existing memory page perform an unassigned access.
45e84a0
Symptoms were writes not taking effect and reads returning zero.
45e84a0
45e84a0
Very small page sizes are not currently supported either,
45e84a0
so subpage memory areas cannot fully be avoided.
45e84a0
45e84a0
Therefore change the previous fix to use a new IO_MEM_SUBPAGE_RAM
45e84a0
instead of IO_MEM_UNASSIGNED. Suggested by Avi.
45e84a0
45e84a0
Reviewed-by: Avi Kivity <avi@redhat.com>
45e84a0
Signed-off-by: Andreas Färber <afaerber@suse.de>
45e84a0
Cc: Avi Kivity <avi@redhat.com>
45e84a0
Cc: Gleb Natapov <gleb@redhat.com>
45e84a0
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
45e84a0
---
45e84a0
 cpu-common.h |    1 +
45e84a0
 exec.c       |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
45e84a0
 2 files changed, 64 insertions(+), 2 deletions(-)
45e84a0
45e84a0
diff --git a/cpu-common.h b/cpu-common.h
45e84a0
index c9878ba..3f45428 100644
45e84a0
--- a/cpu-common.h
45e84a0
+++ b/cpu-common.h
45e84a0
@@ -172,6 +172,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
45e84a0
 #define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
45e84a0
 #define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
45e84a0
 #define IO_MEM_NOTDIRTY    (3 << IO_MEM_SHIFT)
45e84a0
+#define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT)
45e84a0
45e84a0
 /* Acts like a ROM when read and like a device when written.  */
45e84a0
 #define IO_MEM_ROMD        (1)
45e84a0
diff --git a/exec.c b/exec.c
45e84a0
index 6b92198..6c206ff 100644
45e84a0
--- a/exec.c
45e84a0
+++ b/exec.c
45e84a0
@@ -3570,6 +3570,63 @@ static CPUWriteMemoryFunc * const subpage_write[] = {
45e84a0
     &subpage_writel,
45e84a0
 };
45e84a0
45e84a0
+static uint32_t subpage_ram_readb(void *opaque, target_phys_addr_t addr)
45e84a0
+{
45e84a0
+    ram_addr_t raddr = addr;
45e84a0
+    void *ptr = qemu_get_ram_ptr(raddr);
45e84a0
+    return ldub_p(ptr);
45e84a0
+}
45e84a0
+
45e84a0
+static void subpage_ram_writeb(void *opaque, target_phys_addr_t addr,
45e84a0
+                               uint32_t value)
45e84a0
+{
45e84a0
+    ram_addr_t raddr = addr;
45e84a0
+    void *ptr = qemu_get_ram_ptr(raddr);
45e84a0
+    stb_p(ptr, value);
45e84a0
+}
45e84a0
+
45e84a0
+static uint32_t subpage_ram_readw(void *opaque, target_phys_addr_t addr)
45e84a0
+{
45e84a0
+    ram_addr_t raddr = addr;
45e84a0
+    void *ptr = qemu_get_ram_ptr(raddr);
45e84a0
+    return lduw_p(ptr);
45e84a0
+}
45e84a0
+
45e84a0
+static void subpage_ram_writew(void *opaque, target_phys_addr_t addr,
45e84a0
+                               uint32_t value)
45e84a0
+{
45e84a0
+    ram_addr_t raddr = addr;
45e84a0
+    void *ptr = qemu_get_ram_ptr(raddr);
45e84a0
+    stw_p(ptr, value);
45e84a0
+}
45e84a0
+
45e84a0
+static uint32_t subpage_ram_readl(void *opaque, target_phys_addr_t addr)
45e84a0
+{
45e84a0
+    ram_addr_t raddr = addr;
45e84a0
+    void *ptr = qemu_get_ram_ptr(raddr);
45e84a0
+    return ldl_p(ptr);
45e84a0
+}
45e84a0
+
45e84a0
+static void subpage_ram_writel(void *opaque, target_phys_addr_t addr,
45e84a0
+                               uint32_t value)
45e84a0
+{
45e84a0
+    ram_addr_t raddr = addr;
45e84a0
+    void *ptr = qemu_get_ram_ptr(raddr);
45e84a0
+    stl_p(ptr, value);
45e84a0
+}
45e84a0
+
45e84a0
+static CPUReadMemoryFunc * const subpage_ram_read[] = {
45e84a0
+    &subpage_ram_readb,
45e84a0
+    &subpage_ram_readw,
45e84a0
+    &subpage_ram_readl,
45e84a0
+};
45e84a0
+
45e84a0
+static CPUWriteMemoryFunc * const subpage_ram_write[] = {
45e84a0
+    &subpage_ram_writeb,
45e84a0
+    &subpage_ram_writew,
45e84a0
+    &subpage_ram_writel,
45e84a0
+};
45e84a0
+
45e84a0
 static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
45e84a0
                              ram_addr_t memory, ram_addr_t region_offset)
45e84a0
 {
45e84a0
@@ -3583,8 +3640,9 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
45e84a0
     printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
45e84a0
            mmio, start, end, idx, eidx, memory);
45e84a0
 #endif
45e84a0
-    if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
45e84a0
-        memory = IO_MEM_UNASSIGNED;
45e84a0
+    if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
45e84a0
+        memory = IO_MEM_SUBPAGE_RAM;
45e84a0
+    }
45e84a0
     memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
45e84a0
     for (; idx <= eidx; idx++) {
45e84a0
         mmio->sub_io_index[idx] = memory;
45e84a0
@@ -3817,6 +3875,9 @@ static void io_mem_init(void)
45e84a0
     cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read,
45e84a0
                                  notdirty_mem_write, NULL,
45e84a0
                                  DEVICE_NATIVE_ENDIAN);
45e84a0
+    cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read,
45e84a0
+                                 subpage_ram_write, NULL,
45e84a0
+                                 DEVICE_NATIVE_ENDIAN);
45e84a0
     for (i=0; i<5; i++)
45e84a0
         io_mem_used[i] = 1;
45e84a0
45e84a0
-- 
45e84a0
1.7.7.5
45e84a0