From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51421) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9ced-00024W-8g for qemu-devel@nongnu.org; Thu, 17 Dec 2015 12:47:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a9ceZ-0006zf-JN for qemu-devel@nongnu.org; Thu, 17 Dec 2015 12:47:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43696) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9ceZ-0006za-9o for qemu-devel@nongnu.org; Thu, 17 Dec 2015 12:47:47 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E59B3744 for ; Thu, 17 Dec 2015 17:47:46 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-23.ams2.redhat.com [10.36.112.23]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tBHHkfcc014618 for ; Thu, 17 Dec 2015 12:47:46 -0500 From: Paolo Bonzini Date: Thu, 17 Dec 2015 18:46:32 +0100 Message-Id: <1450374401-31352-37-git-send-email-pbonzini@redhat.com> In-Reply-To: <1450374401-31352-1-git-send-email-pbonzini@redhat.com> References: <1450374401-31352-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PULL 36/45] memory: split address_space_read and address_space_write List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Rather than dispatching on is_write for every iteration, make address_space_rw call one of the two functions. The amount of duplicate logic is pretty small, and memory_access_is_direct can be tweaked so that it inlines better in the callers. Signed-off-by: Paolo Bonzini --- exec.c | 208 ++++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 116 insertions(+), 92 deletions(-) diff --git a/exec.c b/exec.c index 069848b..44e6e38 100644 --- a/exec.c +++ b/exec.c @@ -392,11 +392,10 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) { - if (memory_region_is_ram(mr)) { - return !(is_write && mr->readonly); - } - if (memory_region_is_romd(mr)) { - return !is_write; + if (is_write) { + return memory_region_is_ram(mr) && !mr->readonly; + } else { + return memory_region_is_ram(mr) || memory_region_is_romd(mr); } return false; @@ -2469,8 +2468,8 @@ static bool prepare_mmio_access(MemoryRegion *mr) return release_lock; } -MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - uint8_t *buf, int len, bool is_write) +MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, + const uint8_t *buf, int len) { hwaddr l; uint8_t *ptr; @@ -2483,87 +2482,47 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, rcu_read_lock(); while (len > 0) { l = len; - mr = address_space_translate(as, addr, &addr1, &l, is_write); + mr = address_space_translate(as, addr, &addr1, &l, true); - if (is_write) { - if (!memory_access_is_direct(mr, is_write)) { - release_lock |= prepare_mmio_access(mr); - l = memory_access_size(mr, l, addr1); - /* XXX: could force current_cpu to NULL to avoid - potential bugs */ - switch (l) { - case 8: - /* 64 bit write access */ - val = ldq_p(buf); - result |= memory_region_dispatch_write(mr, addr1, val, 8, - attrs); - break; - case 4: - /* 32 bit write access */ - val = ldl_p(buf); - result |= memory_region_dispatch_write(mr, addr1, val, 4, - attrs); - break; - case 2: - /* 16 bit write access */ - val = lduw_p(buf); - result |= memory_region_dispatch_write(mr, addr1, val, 2, - attrs); - break; - case 1: - /* 8 bit write access */ - val = ldub_p(buf); - result |= memory_region_dispatch_write(mr, addr1, val, 1, - attrs); - break; - default: - abort(); - } - } else { - addr1 += memory_region_get_ram_addr(mr); - /* RAM case */ - ptr = qemu_get_ram_ptr(addr1); - memcpy(ptr, buf, l); - invalidate_and_set_dirty(mr, addr1, l); + if (!memory_access_is_direct(mr, true)) { + release_lock |= prepare_mmio_access(mr); + l = memory_access_size(mr, l, addr1); + /* XXX: could force current_cpu to NULL to avoid + potential bugs */ + switch (l) { + case 8: + /* 64 bit write access */ + val = ldq_p(buf); + result |= memory_region_dispatch_write(mr, addr1, val, 8, + attrs); + break; + case 4: + /* 32 bit write access */ + val = ldl_p(buf); + result |= memory_region_dispatch_write(mr, addr1, val, 4, + attrs); + break; + case 2: + /* 16 bit write access */ + val = lduw_p(buf); + result |= memory_region_dispatch_write(mr, addr1, val, 2, + attrs); + break; + case 1: + /* 8 bit write access */ + val = ldub_p(buf); + result |= memory_region_dispatch_write(mr, addr1, val, 1, + attrs); + break; + default: + abort(); } } else { - if (!memory_access_is_direct(mr, is_write)) { - /* I/O case */ - release_lock |= prepare_mmio_access(mr); - l = memory_access_size(mr, l, addr1); - switch (l) { - case 8: - /* 64 bit read access */ - result |= memory_region_dispatch_read(mr, addr1, &val, 8, - attrs); - stq_p(buf, val); - break; - case 4: - /* 32 bit read access */ - result |= memory_region_dispatch_read(mr, addr1, &val, 4, - attrs); - stl_p(buf, val); - break; - case 2: - /* 16 bit read access */ - result |= memory_region_dispatch_read(mr, addr1, &val, 2, - attrs); - stw_p(buf, val); - break; - case 1: - /* 8 bit read access */ - result |= memory_region_dispatch_read(mr, addr1, &val, 1, - attrs); - stb_p(buf, val); - break; - default: - abort(); - } - } else { - /* RAM case */ - ptr = qemu_get_ram_ptr(mr->ram_addr + addr1); - memcpy(buf, ptr, l); - } + addr1 += memory_region_get_ram_addr(mr); + /* RAM case */ + ptr = qemu_get_ram_ptr(addr1); + memcpy(ptr, buf, l); + invalidate_and_set_dirty(mr, addr1, l); } if (release_lock) { @@ -2580,18 +2539,83 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, return result; } -MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len) -{ - return address_space_rw(as, addr, attrs, (uint8_t *)buf, len, true); -} - MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, int len) { - return address_space_rw(as, addr, attrs, buf, len, false); + hwaddr l; + uint8_t *ptr; + uint64_t val; + hwaddr addr1; + MemoryRegion *mr; + MemTxResult result = MEMTX_OK; + bool release_lock = false; + + rcu_read_lock(); + while (len > 0) { + l = len; + mr = address_space_translate(as, addr, &addr1, &l, false); + + if (!memory_access_is_direct(mr, false)) { + /* I/O case */ + release_lock |= prepare_mmio_access(mr); + l = memory_access_size(mr, l, addr1); + switch (l) { + case 8: + /* 64 bit read access */ + result |= memory_region_dispatch_read(mr, addr1, &val, 8, + attrs); + stq_p(buf, val); + break; + case 4: + /* 32 bit read access */ + result |= memory_region_dispatch_read(mr, addr1, &val, 4, + attrs); + stl_p(buf, val); + break; + case 2: + /* 16 bit read access */ + result |= memory_region_dispatch_read(mr, addr1, &val, 2, + attrs); + stw_p(buf, val); + break; + case 1: + /* 8 bit read access */ + result |= memory_region_dispatch_read(mr, addr1, &val, 1, + attrs); + stb_p(buf, val); + break; + default: + abort(); + } + } else { + /* RAM case */ + ptr = qemu_get_ram_ptr(mr->ram_addr + addr1); + memcpy(buf, ptr, l); + } + + if (release_lock) { + qemu_mutex_unlock_iothread(); + release_lock = false; + } + + len -= l; + buf += l; + addr += l; + } + rcu_read_unlock(); + + return result; } +MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, + uint8_t *buf, int len, bool is_write) +{ + if (is_write) { + return address_space_write(as, addr, attrs, (uint8_t *)buf, len); + } else { + return address_space_read(as, addr, attrs, (uint8_t *)buf, len); + } +} void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, int len, int is_write) -- 2.5.0