[Top][All Lists]
[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
- [Qemu-devel] [PATCH, RFC 3/4] Implement byte swapped MMIO type,
Blue Swirl <=