From patchwork Thu Jul 22 22:02:06 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Blue Swirl X-Patchwork-Id: 59669 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7618BB70EC for ; Fri, 23 Jul 2010 08:24:08 +1000 (EST) Received: from localhost ([127.0.0.1]:50491 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Oc4BA-0003gU-QN for incoming@patchwork.ozlabs.org; Thu, 22 Jul 2010 18:23:48 -0400 Received: from [140.186.70.92] (port=42713 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Oc3we-00031d-2O for qemu-devel@nongnu.org; Thu, 22 Jul 2010 18:08:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Oc3qY-0003Nl-3a for qemu-devel@nongnu.org; Thu, 22 Jul 2010 18:02:31 -0400 Received: from mail-yx0-f173.google.com ([209.85.213.173]:36008) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Oc3qY-0003Ng-0G for qemu-devel@nongnu.org; Thu, 22 Jul 2010 18:02:30 -0400 Received: by yxn35 with SMTP id 35so3122350yxn.4 for ; Thu, 22 Jul 2010 15:02:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:mime-version:received:from:date :message-id:subject:to:content-type; bh=gisbsis8uj3KUzuCylAxUpLgWDVxxeKdwibsLVQmN3M=; b=gLWxC0cEDkuET0RDcrw1Np9TWpUoIcoPdm7HZ2Rawp7re5sG6ee0xAXdX34B9fMF1y npXBcvYKE6Sd4MikAHgm0RusfkxDSucRAMEcPbqTz21qJXDSkrp/+UPZ/mbBdIC+jtde 7JsoPucJT6kF2VrjNC8C69clSGaqHCGRF+ojo= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; b=s6sDDGw3s+LoyIcBTXBbS6Baupjp3afyCrWhuncFxnDiKO+TIkU8nhvIgJp7/GRnhv 8hL8YZGPHTYk0NHLN8iXVHgxsNBv+URqGL3ATC0KQesHPGDhWSRpnaAwInLzhqJrD4oU p4R0TL5vu6HX8zd421jTle8mAotUwwZkNFeg8= Received: by 10.224.122.11 with SMTP id j11mr1667717qar.247.1279836148948; Thu, 22 Jul 2010 15:02:28 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.185.146 with HTTP; Thu, 22 Jul 2010 15:02:06 -0700 (PDT) From: Blue Swirl Date: Thu, 22 Jul 2010 22:02:06 +0000 Message-ID: To: qemu-devel X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 28/34] Implement byte swapped MMIO type X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add a flag to indicate a byte swapped MMIO type. Signed-off-by: Blue Swirl --- cpu-common.h | 4 +++- exec.c | 42 ++++++++++++++++++++++++++++++++++++++++++ softmmu_template.h | 16 +++++++++++++++- 3 files changed, 60 insertions(+), 2 deletions(-) env->mem_io_pc = (unsigned long)retaddr; @@ -77,6 +83,9 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32; #endif #endif /* SHIFT > 2 */ + if (do_bswap) { + res = SWAP(res); + } return res; } @@ -200,6 +209,10 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, void *retaddr) { int index; + + if (physaddr & IO_MEM_BSWAP) { + val = SWAP(val); + } index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT) @@ -330,3 +343,4 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, #undef USUFFIX #undef DATA_SIZE #undef ADDR_READ +#undef SWAP diff --git a/cpu-common.h b/cpu-common.h index 71e7933..16bb467 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -123,9 +123,11 @@ 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) +int cpu_physical_memory_toggle_bswap(int ix); #endif #endif /* !CPU_COMMON_H */ diff --git a/exec.c b/exec.c index 868cd7f..7d39747 100644 --- a/exec.c +++ b/exec.c @@ -3473,11 +3473,17 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, if (l >= 4 && ((addr1 & 3) == 0)) { /* 32 bit write access */ val = ldl_p(buf); + if (pd & IO_MEM_BSWAP) { + val = bswap32(val); + } io_mem_write[io_index][2](io_mem_opaque[io_index], addr1, val); l = 4; } else if (l >= 2 && ((addr1 & 1) == 0)) { /* 16 bit write access */ val = lduw_p(buf); + if (pd & IO_MEM_BSWAP) { + val = bswap16(val); + } io_mem_write[io_index][1](io_mem_opaque[io_index], addr1, val); l = 2; } else { @@ -3511,11 +3517,17 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, if (l >= 4 && ((addr1 & 3) == 0)) { /* 32 bit read access */ val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr1); + if (pd & IO_MEM_BSWAP) { + val = bswap32(val); + } stl_p(buf, val); l = 4; } else if (l >= 2 && ((addr1 & 1) == 0)) { /* 16 bit read access */ val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr1); + if (pd & IO_MEM_BSWAP) { + val = bswap16(val); + } stw_p(buf, val); l = 2; } else { @@ -3743,6 +3755,9 @@ uint32_t ldl_phys(target_phys_addr_t addr) if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); + if (pd & IO_MEM_BSWAP) { + val = bswap32(val); + } } else { /* RAM case */ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + @@ -3781,6 +3796,9 @@ uint64_t ldq_phys(target_phys_addr_t addr) val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32; #endif + if (pd & IO_MEM_BSWAP) { + val = bswap64(val); + } } else { /* RAM case */ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + @@ -3821,6 +3839,9 @@ uint32_t lduw_phys(target_phys_addr_t addr) if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr); + if (pd & IO_MEM_BSWAP) { + val = bswap16(val); + } } else { /* RAM case */ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + @@ -3851,6 +3872,9 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; + if (pd & IO_MEM_BSWAP) { + val = bswap32(val); + } io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); @@ -3887,6 +3911,9 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; + if (pd & IO_MEM_BSWAP) { + val = bswap64(val); + } #ifdef TARGET_WORDS_BIGENDIAN io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32); io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val); @@ -3920,6 +3947,9 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; + if (pd & IO_MEM_BSWAP) { + val = bswap32(val); + } io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1; @@ -3963,6 +3993,9 @@ void stw_phys(target_phys_addr_t addr, uint32_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; + if (pd & IO_MEM_BSWAP) { + val = bswap16(val); + } io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1; @@ -4015,6 +4048,15 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, } return 0; } + +int cpu_physical_memory_toggle_bswap(int ix) +{ + /* Don't toggle for memory backed pages */ + if ((ix & ~TARGET_PAGE_MASK) != 0) { + ix ^= IO_MEM_BSWAP; + } + return ix; +} #endif /* in deterministic execution mode, instructions doing device I/Os diff --git a/softmmu_template.h b/softmmu_template.h index c2df9ec..5500408 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 @@ -56,7 +60,9 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, void *retaddr) { DATA_TYPE res; - int index; + int index, do_bswap; + + do_bswap = physaddr & IO_MEM_BSWAP; index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); physaddr = (physaddr & TARGET_PAGE_MASK) + addr;