From patchwork Fri Jul 26 06:47:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Nguyen X-Patchwork-Id: 1137271 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=bt.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45w06q12Fhz9s8m for ; Fri, 26 Jul 2019 16:49:07 +1000 (AEST) Received: from localhost ([::1]:36776 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hqu2K-0006kR-T8 for incoming@patchwork.ozlabs.org; Fri, 26 Jul 2019 02:49:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57656) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hqu26-0006RC-Gc for qemu-devel@nongnu.org; Fri, 26 Jul 2019 02:48:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hqu22-0006d1-CR for qemu-devel@nongnu.org; Fri, 26 Jul 2019 02:48:49 -0400 Received: from smtpe1.intersmtp.com ([213.121.35.77]:51296) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hqu1G-0005Rv-G8; Fri, 26 Jul 2019 02:48:00 -0400 Received: from tpw09926dag18h.domain1.systemhost.net (10.9.212.42) by BWP09926082.bt.com (10.36.82.113) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.1713.5; Fri, 26 Jul 2019 07:47:46 +0100 Received: from tpw09926dag18e.domain1.systemhost.net (10.9.212.18) by tpw09926dag18h.domain1.systemhost.net (10.9.212.42) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Fri, 26 Jul 2019 07:47:47 +0100 Received: from tpw09926dag18e.domain1.systemhost.net ([fe80::a946:6348:ccf4:fa6c]) by tpw09926dag18e.domain1.systemhost.net ([fe80::a946:6348:ccf4:fa6c%12]) with mapi id 15.00.1395.000; Fri, 26 Jul 2019 07:47:47 +0100 From: To: Thread-Topic: [Qemu-devel] [PATCH v5 11/15] memory: Single byte swap along the I/O path Thread-Index: AQHVQ34JFcVl51mE9EO/EnEfwkEv1Q== Date: Fri, 26 Jul 2019 06:47:47 +0000 Message-ID: <1564123667210.66446@bt.com> References: <3106a3c959c4498fad13a5799c89ba7b@tpw09926dag18e.domain1.systemhost.net> In-Reply-To: <3106a3c959c4498fad13a5799c89ba7b@tpw09926dag18e.domain1.systemhost.net> Accept-Language: en-AU, en-GB, en-US Content-Language: en-AU X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.187.101.42] MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 213.121.35.77 X-Content-Filtered-By: Mailman/MimeDel 2.1.23 Subject: [Qemu-devel] [PATCH v5 11/15] memory: Single byte swap along the I/O path X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, walling@linux.ibm.com, sagark@eecs.berkeley.edu, mst@redhat.com, palmer@sifive.com, mark.cave-ayland@ilande.co.uk, laurent@vivier.eu, Alistair.Francis@wdc.com, edgar.iglesias@gmail.com, arikalo@wavecomp.com, david@redhat.com, pasic@linux.ibm.com, borntraeger@de.ibm.com, rth@twiddle.net, atar4qemu@gmail.com, ehabkost@redhat.com, qemu-s390x@nongnu.org, qemu-arm@nongnu.org, stefanha@redhat.com, shorne@gmail.com, david@gibson.dropbear.id.au, qemu-riscv@nongnu.org, kbastian@mail.uni-paderborn.de, cohuck@redhat.com, alex.williamson@redhat.com, qemu-ppc@nongnu.org, amarkovic@wavecomp.com, pbonzini@redhat.com, aurelien@aurel32.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Now that MemOp has been pushed down into the memory API, we can collapse the two byte swaps adjust_endianness and handle_bswap into the former. Collapsing byte swaps along the I/O path enables additional endian inversion logic, e.g. SPARC64 Invert Endian TTE bit, with redundant byte swaps cancelling out. Signed-off-by: Tony Nguyen --- accel/tcg/cputlb.c | 41 +++++++++++++++++++---------------------- memory.c | 30 +++++++++++++++++------------- 2 files changed, 36 insertions(+), 35 deletions(-) -- 1.8.3.1 diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 5d88cec..e61b1eb 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -1209,26 +1209,13 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr, #endif /* - * Byte Swap Helper + * Byte Swap Checker * - * This should all dead code away depending on the build host and - * access type. + * Dead code should all go away depending on the build host and access type. */ - -static inline uint64_t handle_bswap(uint64_t val, int size, bool big_endian) +static inline bool need_bswap(bool big_endian) { - if ((big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP)) { - switch (size) { - case 1: return val; - case 2: return bswap16(val); - case 4: return bswap32(val); - case 8: return bswap64(val); - default: - g_assert_not_reached(); - } - } else { - return val; - } + return (big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP); } /* @@ -1259,6 +1246,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, unsigned a_bits = get_alignment_bits(get_memop(oi)); void *haddr; uint64_t res; + MemOp op; /* Handle CPU specific unaligned behaviour */ if (addr & ((1 << a_bits) - 1)) { @@ -1304,9 +1292,13 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, } } - res = io_readx(env, &env_tlb(env)->d[mmu_idx].iotlb[index], - mmu_idx, addr, retaddr, access_type, SIZE_MEMOP(size)); - return handle_bswap(res, size, big_endian); + op = SIZE_MEMOP(size); + if (need_bswap(big_endian)) { + op ^= MO_BSWAP; + } + + return io_readx(env, &env_tlb(env)->d[mmu_idx].iotlb[index], + mmu_idx, addr, retaddr, access_type, op); } /* Handle slow unaligned access (it spans two pages or IO). */ @@ -1507,6 +1499,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, const size_t tlb_off = offsetof(CPUTLBEntry, addr_write); unsigned a_bits = get_alignment_bits(get_memop(oi)); void *haddr; + MemOp op; /* Handle CPU specific unaligned behaviour */ if (addr & ((1 << a_bits) - 1)) { @@ -1552,9 +1545,13 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, } } + op = SIZE_MEMOP(size); + if (need_bswap(big_endian)) { + op ^= MO_BSWAP; + } + io_writex(env, &env_tlb(env)->d[mmu_idx].iotlb[index], mmu_idx, - handle_bswap(val, size, big_endian), - addr, retaddr, SIZE_MEMOP(size)); + val, addr, retaddr, op); return; } diff --git a/memory.c b/memory.c index 6982e19..0277d3d 100644 --- a/memory.c +++ b/memory.c @@ -352,7 +352,7 @@ static bool memory_region_big_endian(MemoryRegion *mr) #endif } -static bool memory_region_wrong_endianness(MemoryRegion *mr) +static bool memory_region_endianness_inverted(MemoryRegion *mr) { #ifdef TARGET_WORDS_BIGENDIAN return mr->ops->endianness == DEVICE_LITTLE_ENDIAN; @@ -361,23 +361,27 @@ static bool memory_region_wrong_endianness(MemoryRegion *mr) #endif } -static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size) +static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op) { - if (memory_region_wrong_endianness(mr)) { - switch (size) { - case 1: + if (memory_region_endianness_inverted(mr)) { + op ^= MO_BSWAP; + } + + if (op & MO_BSWAP) { + switch (op & MO_SIZE) { + case MO_8: break; - case 2: + case MO_16: *data = bswap16(*data); break; - case 4: + case MO_32: *data = bswap32(*data); break; - case 8: + case MO_64: *data = bswap64(*data); break; default: - abort(); + g_assert_not_reached(); } } } @@ -1451,7 +1455,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr, } r = memory_region_dispatch_read1(mr, addr, pval, size, attrs); - adjust_endianness(mr, pval, size); + adjust_endianness(mr, pval, op); return r; } @@ -1494,7 +1498,7 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr, return MEMTX_DECODE_ERROR; } - adjust_endianness(mr, &data, size); + adjust_endianness(mr, &data, op); if ((!kvm_eventfds_enabled()) && memory_region_dispatch_write_eventfds(mr, addr, data, size, attrs)) { @@ -2340,7 +2344,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, } if (size) { - adjust_endianness(mr, &mrfd.data, size); + adjust_endianness(mr, &mrfd.data, SIZE_MEMOP(size)); } memory_region_transaction_begin(); for (i = 0; i < mr->ioeventfd_nb; ++i) { @@ -2375,7 +2379,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, unsigned i; if (size) { - adjust_endianness(mr, &mrfd.data, size); + adjust_endianness(mr, &mrfd.data, SIZE_MEMOP(size)); } memory_region_transaction_begin(); for (i = 0; i < mr->ioeventfd_nb; ++i) {