BROKEN Signed-off-by: Blue Swirl <blauwir...@gmail.com> --- 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