qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH, RFC 3/4] Implement byte swapped MMIO type


From: Blue Swirl
Subject: [Qemu-devel] [PATCH, RFC 3/4] Implement byte swapped MMIO type
Date: Sun, 23 May 2010 20:34:47 +0000

BROKEN

Signed-off-by: Blue Swirl <address@hidden>
---
 cpu-common.h       |    3 +-
 softmmu_template.h |   69 ++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index b24cecc..f96cea0 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -123,8 +123,9 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
 #define IO_MEM_NOTDIRTY    (3 << IO_MEM_SHIFT)

 /* Acts like a ROM when read and like a device when written.  */
-#define IO_MEM_ROMD        (1)
+#define IO_MEM_ROMD        (4)
 #define IO_MEM_SUBPAGE     (2)
+#define IO_MEM_BSWAP       (1)

 #endif

diff --git a/softmmu_template.h b/softmmu_template.h
index c2df9ec..feb5d85 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -24,18 +24,22 @@
 #define SUFFIX q
 #define USUFFIX q
 #define DATA_TYPE uint64_t
+#define SWAP(x) bswap64(x)
 #elif DATA_SIZE == 4
 #define SUFFIX l
 #define USUFFIX l
 #define DATA_TYPE uint32_t
+#define SWAP(x) bswap32(x)
 #elif DATA_SIZE == 2
 #define SUFFIX w
 #define USUFFIX uw
 #define DATA_TYPE uint16_t
+#define SWAP(x) bswap16(x)
 #elif DATA_SIZE == 1
 #define SUFFIX b
 #define USUFFIX ub
 #define DATA_TYPE uint8_t
+#define SWAP(x) (x)
 #else
 #error unsupported data size
 #endif
@@ -68,14 +72,35 @@ static inline DATA_TYPE glue(io_read,
SUFFIX)(target_phys_addr_t physaddr,
     env->mem_io_vaddr = addr;
 #if SHIFT <= 2
     res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
+    if (index & IO_MEM_BSWAP) {
+        res = SWAP(res);
+    }
 #else
+    {
+        DATA_TYPE tmp;
 #ifdef TARGET_WORDS_BIGENDIAN
-    res = (uint64_t)io_mem_read[index][2](io_mem_opaque[index],
physaddr) << 32;
-    res |= io_mem_read[index][2](io_mem_opaque[index], physaddr + 4);
+        res = (uint64_t)io_mem_read[index][2](io_mem_opaque[index],
+                                              physaddr) << 32;
+        if (index & IO_MEM_BSWAP) {
+            res = bswap32(res);
+        }
+        tmp = io_mem_read[index][2](io_mem_opaque[index], physaddr + 4);
+        if (index & IO_MEM_BSWAP) {
+            tmp = bswap32(tmp);
+        }
+        res |= tmp;
 #else
-    res = io_mem_read[index][2](io_mem_opaque[index], physaddr);
-    res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index],
physaddr + 4) << 32;
+        res = io_mem_read[index][2](io_mem_opaque[index], physaddr);
+        if (index & IO_MEM_BSWAP) {
+            res = bswap32(res);
+        }
+        tmp = (uint64_t)io_mem_read[index][2](io_mem_opaque[index],
physaddr + 4) << 32;
+        if (index & IO_MEM_BSWAP) {
+            tmp = bswap32(tmp);
+        }
+        res |= tmp;
 #endif
+    }
 #endif /* SHIFT > 2 */
     return res;
 }
@@ -174,6 +199,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX),
MMUSUFFIX)(target_ulong addr,
             res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
 #endif
             res = (DATA_TYPE)res;
+            if (tlb_addr & IO_MEM_BSWAP) {
+                res = SWAP(res);
+            }
         } else {
             /* unaligned/aligned access in the same page */
             addend = env->tlb_table[mmu_idx][index].addend;
@@ -209,16 +237,37 @@ static inline void glue(io_write,
SUFFIX)(target_phys_addr_t physaddr,

     env->mem_io_vaddr = addr;
     env->mem_io_pc = (unsigned long)retaddr;
+    if (index & IO_MEM_BSWAP) {
+        val = SWAP(val);
+    }
 #if SHIFT <= 2
     io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
+    if (index & IO_MEM_BSWAP) {
+        val = SWAP(val);
+    }
 #else
+    {
+        DATA_TYPE tmp;
 #ifdef TARGET_WORDS_BIGENDIAN
-    io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32);
-    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val);
+        if (index & IO_MEM_BSWAP) {
+            tmp = bswap32(val >> 32);
+        }
+        io_mem_write[index][2](io_mem_opaque[index], physaddr, tmp);
+        if (index & IO_MEM_BSWAP) {
+            tmp = bswap32(val);
+        }
+        io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, tmp);
 #else
-    io_mem_write[index][2](io_mem_opaque[index], physaddr, val);
-    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
+        if (index & IO_MEM_BSWAP) {
+            tmp = bswap32(val);
+        }
+        io_mem_write[index][2](io_mem_opaque[index], physaddr, tmp);
+        if (index & IO_MEM_BSWAP) {
+            tmp = bswap32(val >> 32);
+        }
+        io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, tmp);
 #endif
+    }
 #endif /* SHIFT > 2 */
 }

@@ -297,6 +346,9 @@ static void glue(glue(slow_st, SUFFIX),
MMUSUFFIX)(target_ulong addr,
             glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
         } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >=
TARGET_PAGE_SIZE) {
         do_unaligned_access:
+            if (tlb_addr & IO_MEM_BSWAP) {
+                val = SWAP(val);
+            }
             /* XXX: not efficient, but simple */
             /* Note: relies on the fact that tlb_fill() does not remove the
              * previous page from the TLB cache.  */
@@ -330,3 +382,4 @@ static void glue(glue(slow_st, SUFFIX),
MMUSUFFIX)(target_ulong addr,
 #undef USUFFIX
 #undef DATA_SIZE
 #undef ADDR_READ
+#undef SWAP
-- 
1.6.2.4



reply via email to

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