qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 01/16] memory: move endianness compensation to memor


From: Avi Kivity
Subject: [Qemu-devel] [PATCH 01/16] memory: move endianness compensation to memory core
Date: Mon, 2 Jan 2012 18:33:20 +0200

Instead of doing device endianness compensation in cpu_register_io_memory(),
do it in the memory core.

Signed-off-by: Avi Kivity <address@hidden>
---
 exec-obsolete.h |    2 +-
 exec.c          |  142 ++++---------------------------------------------------
 memory.c        |   37 ++++++++++++--
 3 files changed, 41 insertions(+), 140 deletions(-)

diff --git a/exec-obsolete.h b/exec-obsolete.h
index 698d7fc..79f989c 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -33,7 +33,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr);
 
 int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
                            CPUWriteMemoryFunc * const *mem_write,
-                           void *opaque, enum device_endian endian);
+                           void *opaque);
 void cpu_unregister_io_memory(int table_address);
 
 void cpu_register_physical_memory_log(target_phys_addr_t start_addr,
diff --git a/exec.c b/exec.c
index 28c057c..507d37c 100644
--- a/exec.c
+++ b/exec.c
@@ -3507,8 +3507,7 @@ static int subpage_register (subpage_t *mmio, uint32_t 
start, uint32_t end,
     mmio = g_malloc0(sizeof(subpage_t));
 
     mmio->base = base;
-    subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio,
-                                            DEVICE_NATIVE_ENDIAN);
+    subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio);
 #if defined(DEBUG_SUBPAGE)
     printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
            mmio, base, TARGET_PAGE_SIZE, subpage_memory);
@@ -3532,106 +3531,6 @@ static int get_free_io_mem_idx(void)
     return -1;
 }
 
-/*
- * Usually, devices operate in little endian mode. There are devices out
- * there that operate in big endian too. Each device gets byte swapped
- * mmio if plugged onto a CPU that does the other endianness.
- *
- * CPU          Device           swap?
- *
- * little       little           no
- * little       big              yes
- * big          little           yes
- * big          big              no
- */
-
-typedef struct SwapEndianContainer {
-    CPUReadMemoryFunc *read[3];
-    CPUWriteMemoryFunc *write[3];
-    void *opaque;
-} SwapEndianContainer;
-
-static uint32_t swapendian_mem_readb (void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val;
-    SwapEndianContainer *c = opaque;
-    val = c->read[0](c->opaque, addr);
-    return val;
-}
-
-static uint32_t swapendian_mem_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val;
-    SwapEndianContainer *c = opaque;
-    val = bswap16(c->read[1](c->opaque, addr));
-    return val;
-}
-
-static uint32_t swapendian_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val;
-    SwapEndianContainer *c = opaque;
-    val = bswap32(c->read[2](c->opaque, addr));
-    return val;
-}
-
-static CPUReadMemoryFunc * const swapendian_readfn[3]={
-    swapendian_mem_readb,
-    swapendian_mem_readw,
-    swapendian_mem_readl
-};
-
-static void swapendian_mem_writeb(void *opaque, target_phys_addr_t addr,
-                                  uint32_t val)
-{
-    SwapEndianContainer *c = opaque;
-    c->write[0](c->opaque, addr, val);
-}
-
-static void swapendian_mem_writew(void *opaque, target_phys_addr_t addr,
-                                  uint32_t val)
-{
-    SwapEndianContainer *c = opaque;
-    c->write[1](c->opaque, addr, bswap16(val));
-}
-
-static void swapendian_mem_writel(void *opaque, target_phys_addr_t addr,
-                                  uint32_t val)
-{
-    SwapEndianContainer *c = opaque;
-    c->write[2](c->opaque, addr, bswap32(val));
-}
-
-static CPUWriteMemoryFunc * const swapendian_writefn[3]={
-    swapendian_mem_writeb,
-    swapendian_mem_writew,
-    swapendian_mem_writel
-};
-
-static void swapendian_init(int io_index)
-{
-    SwapEndianContainer *c = g_malloc(sizeof(SwapEndianContainer));
-    int i;
-
-    /* Swap mmio for big endian targets */
-    c->opaque = io_mem_opaque[io_index];
-    for (i = 0; i < 3; i++) {
-        c->read[i] = io_mem_read[io_index][i];
-        c->write[i] = io_mem_write[io_index][i];
-
-        io_mem_read[io_index][i] = swapendian_readfn[i];
-        io_mem_write[io_index][i] = swapendian_writefn[i];
-    }
-    io_mem_opaque[io_index] = c;
-}
-
-static void swapendian_del(int io_index)
-{
-    if (io_mem_read[io_index][0] == swapendian_readfn[0]) {
-        g_free(io_mem_opaque[io_index]);
-    }
-}
-
 /* mem_read and mem_write are arrays of functions containing the
    function to access byte (index 0), word (index 1) and dword (index
    2). Functions can be omitted with a NULL function pointer.
@@ -3642,7 +3541,7 @@ static void swapendian_del(int io_index)
 static int cpu_register_io_memory_fixed(int io_index,
                                         CPUReadMemoryFunc * const *mem_read,
                                         CPUWriteMemoryFunc * const *mem_write,
-                                        void *opaque, enum device_endian 
endian)
+                                        void *opaque)
 {
     int i;
 
@@ -3666,30 +3565,14 @@ static int cpu_register_io_memory_fixed(int io_index,
     }
     io_mem_opaque[io_index] = opaque;
 
-    switch (endian) {
-    case DEVICE_BIG_ENDIAN:
-#ifndef TARGET_WORDS_BIGENDIAN
-        swapendian_init(io_index);
-#endif
-        break;
-    case DEVICE_LITTLE_ENDIAN:
-#ifdef TARGET_WORDS_BIGENDIAN
-        swapendian_init(io_index);
-#endif
-        break;
-    case DEVICE_NATIVE_ENDIAN:
-    default:
-        break;
-    }
-
     return (io_index << IO_MEM_SHIFT);
 }
 
 int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
                            CPUWriteMemoryFunc * const *mem_write,
-                           void *opaque, enum device_endian endian)
+                           void *opaque)
 {
-    return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque, 
endian);
+    return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque);
 }
 
 void cpu_unregister_io_memory(int io_table_address)
@@ -3697,8 +3580,6 @@ void cpu_unregister_io_memory(int io_table_address)
     int i;
     int io_index = io_table_address >> IO_MEM_SHIFT;
 
-    swapendian_del(io_index);
-
     for (i=0;i < 3; i++) {
         io_mem_read[io_index][i] = unassigned_mem_read[i];
         io_mem_write[io_index][i] = unassigned_mem_write[i];
@@ -3712,23 +3593,18 @@ static void io_mem_init(void)
     int i;
 
     cpu_register_io_memory_fixed(IO_MEM_ROM, error_mem_read,
-                                 unassigned_mem_write, NULL,
-                                 DEVICE_NATIVE_ENDIAN);
+                                 unassigned_mem_write, NULL);
     cpu_register_io_memory_fixed(IO_MEM_UNASSIGNED, unassigned_mem_read,
-                                 unassigned_mem_write, NULL,
-                                 DEVICE_NATIVE_ENDIAN);
+                                 unassigned_mem_write, NULL);
     cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read,
-                                 notdirty_mem_write, NULL,
-                                 DEVICE_NATIVE_ENDIAN);
+                                 notdirty_mem_write, NULL);
     cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read,
-                                 subpage_ram_write, NULL,
-                                 DEVICE_NATIVE_ENDIAN);
+                                 subpage_ram_write, NULL);
     for (i=0; i<5; i++)
         io_mem_used[i] = 1;
 
     io_mem_watch = cpu_register_io_memory(watch_mem_read,
-                                          watch_mem_write, NULL,
-                                          DEVICE_NATIVE_ENDIAN);
+                                          watch_mem_write, NULL);
 }
 
 static void memory_map_init(void)
diff --git a/memory.c b/memory.c
index 868ffd0..6f9fea1 100644
--- a/memory.c
+++ b/memory.c
@@ -857,6 +857,15 @@ static void 
memory_region_destructor_rom_device(MemoryRegion *mr)
     cpu_unregister_io_memory(mr->ram_addr & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
 }
 
+static bool memory_region_wrong_endianness(MemoryRegion *mr)
+{
+#ifdef TARGET_BIG_ENDIAN
+    return mr->ops->endianness == DEVICE_LITTLE_ENDIAN;
+#else
+    return mr->ops->endianness == DEVICE_BIG_ENDIAN;
+#endif
+}
+
 void memory_region_init(MemoryRegion *mr,
                         const char *name,
                         uint64_t size)
@@ -967,12 +976,24 @@ static uint32_t memory_region_read_thunk_b(void *mr, 
target_phys_addr_t addr)
 
 static uint32_t memory_region_read_thunk_w(void *mr, target_phys_addr_t addr)
 {
-    return memory_region_read_thunk_n(mr, addr, 2);
+    uint32_t data;
+
+    data = memory_region_read_thunk_n(mr, addr, 2);
+    if (memory_region_wrong_endianness(mr)) {
+        data = bswap16(data);
+    }
+    return data;
 }
 
 static uint32_t memory_region_read_thunk_l(void *mr, target_phys_addr_t addr)
 {
-    return memory_region_read_thunk_n(mr, addr, 4);
+    uint32_t data;
+
+    data = memory_region_read_thunk_n(mr, addr, 4);
+    if (memory_region_wrong_endianness(mr)) {
+        data = bswap32(data);
+    }
+    return data;
 }
 
 static void memory_region_write_thunk_b(void *mr, target_phys_addr_t addr,
@@ -984,12 +1005,18 @@ static void memory_region_write_thunk_b(void *mr, 
target_phys_addr_t addr,
 static void memory_region_write_thunk_w(void *mr, target_phys_addr_t addr,
                                         uint32_t data)
 {
+    if (memory_region_wrong_endianness(mr)) {
+        data = bswap16(data);
+    }
     memory_region_write_thunk_n(mr, addr, 2, data);
 }
 
 static void memory_region_write_thunk_l(void *mr, target_phys_addr_t addr,
                                         uint32_t data)
 {
+    if (memory_region_wrong_endianness(mr)) {
+        data = bswap32(data);
+    }
     memory_region_write_thunk_n(mr, addr, 4, data);
 }
 
@@ -1014,8 +1041,7 @@ static void memory_region_prepare_ram_addr(MemoryRegion 
*mr)
     mr->destructor = memory_region_destructor_iomem;
     mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
                                           memory_region_write_thunk,
-                                          mr,
-                                          mr->ops->endianness);
+                                          mr);
     mr->backend_registered = true;
 }
 
@@ -1082,8 +1108,7 @@ void memory_region_init_rom_device(MemoryRegion *mr,
     mr->ram_addr = qemu_ram_alloc(size, mr);
     mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk,
                                            memory_region_write_thunk,
-                                           mr,
-                                           mr->ops->endianness);
+                                           mr);
     mr->ram_addr |= IO_MEM_ROMD;
     mr->backend_registered = true;
 }
-- 
1.7.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]