From patchwork Sat Jun 9 16:19:18 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Blue Swirl X-Patchwork-Id: 163944 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3EDC4B6FCA for ; Sun, 10 Jun 2012 03:30:40 +1000 (EST) Received: from localhost ([::1]:58309 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SdOPX-0005uY-3K for incoming@patchwork.ozlabs.org; Sat, 09 Jun 2012 12:21:11 -0400 Received: from eggs.gnu.org ([208.118.235.92]:51773) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SdOOW-0004Pt-OJ for qemu-devel@nongnu.org; Sat, 09 Jun 2012 12:20:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SdOOU-0003gE-5w for qemu-devel@nongnu.org; Sat, 09 Jun 2012 12:20:08 -0400 Received: from mail-ey0-f173.google.com ([209.85.215.173]:53467) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SdOOT-0003JC-TR for qemu-devel@nongnu.org; Sat, 09 Jun 2012 12:20:06 -0400 Received: by mail-ey0-f173.google.com with SMTP id k12so1788727eaa.4 for ; Sat, 09 Jun 2012 09:20:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references; bh=D7oZF58wtFeg7hDhzIppJTZILYa7AiP02/UC9tjUGF4=; b=lVLfdx/fz4UOM4/V5uWeMeU1rXfbBO1jvH/aQUDwzuJOZPI25HsWyJq8DqhSfNS7FE ecLWiJEi5ejr9fNXRHcTc7DOfbyMNXuCRiyqxXglzuPEfMoP84M7zrVZf4bJq6VkZAcW YROpayDXuGu00vbez/XSUApH/qEcK6Z67KSKZxCW9Hd3I8aOvS8OGVe3t5zKApTiipK3 C0spjKAK1N1axmC0BxlfctTzJ9HO01qw1NWpL8IET84xhFMq8ddaE0xLvFXhE7KDdrcN eqKHU81E4YgIcUahch943PYxUinasffioyeCIGRMZV8iPRg4x1uCdTiNMmwXpJp2y16q eMwg== Received: by 10.14.99.10 with SMTP id w10mr5088829eef.175.1339258804838; Sat, 09 Jun 2012 09:20:04 -0700 (PDT) Received: from localhost.localdomain (blueswirl.broker.freenet6.net. [2001:5c0:1400:b::d5a3]) by mx.google.com with ESMTPS id h53sm33625570eea.1.2012.06.09.09.20.03 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 09 Jun 2012 09:20:04 -0700 (PDT) From: Blue Swirl To: qemu-devel@nongnu.org Date: Sat, 9 Jun 2012 16:19:18 +0000 Message-Id: <543132c4f4dce1450fb855f406fcd02fdbff00d3.1339258554.git.blauwirbel@gmail.com> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.215.173 Subject: [Qemu-devel] [PATCH 22/25] x86: split off memory access helpers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Move memory access helpers to mem_helper.c. Signed-off-by: Blue Swirl --- target-i386/Makefile.objs | 3 +- target-i386/mem_helper.c | 212 +++++++++++++++++++++++++++++++++++++++++++++ target-i386/op_helper.c | 189 +--------------------------------------- 3 files changed, 216 insertions(+), 188 deletions(-) create mode 100644 target-i386/mem_helper.c diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 22d4c13..7d97f4f 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -1,9 +1,10 @@ obj-y += translate.o op_helper.o helper.o cpu.o obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o -obj-y += smm_helper.o misc_helper.o +obj-y += smm_helper.o misc_helper.o mem_helper.o obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) +$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c new file mode 100644 index 0000000..d078ded --- /dev/null +++ b/target-i386/mem_helper.c @@ -0,0 +1,212 @@ +/* + * x86 memory access helpers + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "cpu.h" +#include "dyngen-exec.h" +#include "helper.h" + +#if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" +#endif /* !defined(CONFIG_USER_ONLY) */ + +/* broken thread support */ + +static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; + +void helper_lock(void) +{ + spin_lock(&global_cpu_lock); +} + +void helper_unlock(void) +{ + spin_unlock(&global_cpu_lock); +} + +void helper_cmpxchg8b(target_ulong a0) +{ + uint64_t d; + int eflags; + + eflags = cpu_cc_compute_all(env, CC_OP); + d = ldq(a0); + if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) { + stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX); + eflags |= CC_Z; + } else { + /* always do the store */ + stq(a0, d); + EDX = (uint32_t)(d >> 32); + EAX = (uint32_t)d; + eflags &= ~CC_Z; + } + CC_SRC = eflags; +} + +#ifdef TARGET_X86_64 +void helper_cmpxchg16b(target_ulong a0) +{ + uint64_t d0, d1; + int eflags; + + if ((a0 & 0xf) != 0) { + raise_exception(env, EXCP0D_GPF); + } + eflags = cpu_cc_compute_all(env, CC_OP); + d0 = ldq(a0); + d1 = ldq(a0 + 8); + if (d0 == EAX && d1 == EDX) { + stq(a0, EBX); + stq(a0 + 8, ECX); + eflags |= CC_Z; + } else { + /* always do the store */ + stq(a0, d0); + stq(a0 + 8, d1); + EDX = d1; + EAX = d0; + eflags &= ~CC_Z; + } + CC_SRC = eflags; +} +#endif + +void helper_boundw(target_ulong a0, int v) +{ + int low, high; + + low = ldsw(a0); + high = ldsw(a0 + 2); + v = (int16_t)v; + if (v < low || v > high) { + raise_exception(env, EXCP05_BOUND); + } +} + +void helper_boundl(target_ulong a0, int v) +{ + int low, high; + + low = ldl(a0); + high = ldl(a0 + 4); + if (v < low || v > high) { + raise_exception(env, EXCP05_BOUND); + } +} + +#if !defined(CONFIG_USER_ONLY) + +#define MMUSUFFIX _mmu + +#define SHIFT 0 +#include "softmmu_template.h" + +#define SHIFT 1 +#include "softmmu_template.h" + +#define SHIFT 2 +#include "softmmu_template.h" + +#define SHIFT 3 +#include "softmmu_template.h" + +#endif + +#if !defined(CONFIG_USER_ONLY) +/* try to fill the TLB and return an exception if error. If retaddr is + NULL, it means that the function was called in C code (i.e. not + from generated code or from helper.c) */ +/* XXX: fix it to restore all registers */ +void tlb_fill(CPUX86State *env1, target_ulong addr, int is_write, int mmu_idx, + uintptr_t retaddr) +{ + TranslationBlock *tb; + int ret; + CPUX86State *saved_env; + + saved_env = env; + env = env1; + + ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx); + if (ret) { + if (retaddr) { + /* now we have a real cpu fault */ + tb = tb_find_pc(retaddr); + if (tb) { + /* the PC is inside the translated code. It means that we have + a virtual CPU fault */ + cpu_restore_state(tb, env, retaddr); + } + } + raise_exception_err(env, env->exception_index, env->error_code); + } + env = saved_env; +} +#endif + +/* temporary wrappers */ +#if defined(CONFIG_USER_ONLY) +#define ldub_data(addr) ldub_raw(addr) +#define lduw_data(addr) lduw_raw(addr) +#define ldl_data(addr) ldl_raw(addr) +#define ldq_data(addr) ldq_raw(addr) + +#define stb_data(addr, data) stb_raw(addr, data) +#define stw_data(addr, data) stw_raw(addr, data) +#define stl_data(addr, data) stl_raw(addr, data) +#define stq_data(addr, data) stq_raw(addr, data) +#endif + +#define WRAP_LD(rettype, fn) \ + rettype cpu_ ## fn(CPUX86State *env1, target_ulong addr) \ + { \ + CPUX86State *saved_env; \ + rettype ret; \ + \ + saved_env = env; \ + env = env1; \ + ret = fn(addr); \ + env = saved_env; \ + return ret; \ + } + +WRAP_LD(uint32_t, ldub_data) +WRAP_LD(uint32_t, lduw_data) +WRAP_LD(uint32_t, ldl_data) +WRAP_LD(uint64_t, ldq_data) + +WRAP_LD(uint32_t, lduw_kernel) +#undef WRAP_LD + +#define WRAP_ST(datatype, fn) \ + void cpu_ ## fn(CPUX86State *env1, target_ulong addr, datatype val) \ + { \ + CPUX86State *saved_env; \ + \ + saved_env = env; \ + env = env1; \ + fn(addr, val); \ + env = saved_env; \ + } + +WRAP_ST(uint32_t, stb_data) +WRAP_ST(uint32_t, stw_data) +WRAP_ST(uint32_t, stl_data) +WRAP_ST(uint64_t, stq_data) +#undef WRAP_ST diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index a9f31d5..41d146c 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -1,5 +1,6 @@ /* - * i386 helpers + * x86 segmentation related helpers: + * TSS, interrupts, system calls, jumps and call/task gates, descriptors * * Copyright (c) 2003 Fabrice Bellard * @@ -37,20 +38,6 @@ # define LOG_PCALL_STATE(env) do { } while (0) #endif -/* broken thread support */ - -static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; - -void helper_lock(void) -{ - spin_lock(&global_cpu_lock); -} - -void helper_unlock(void) -{ - spin_unlock(&global_cpu_lock); -} - /* return non zero if error */ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, int selector) @@ -1279,54 +1266,6 @@ void do_interrupt_x86_hardirq(CPUX86State *env1, int intno, int is_hw) env = saved_env; } -void helper_cmpxchg8b(target_ulong a0) -{ - uint64_t d; - int eflags; - - eflags = cpu_cc_compute_all(env, CC_OP); - d = ldq(a0); - if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) { - stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX); - eflags |= CC_Z; - } else { - /* always do the store */ - stq(a0, d); - EDX = (uint32_t)(d >> 32); - EAX = (uint32_t)d; - eflags &= ~CC_Z; - } - CC_SRC = eflags; -} - -#ifdef TARGET_X86_64 -void helper_cmpxchg16b(target_ulong a0) -{ - uint64_t d0, d1; - int eflags; - - if ((a0 & 0xf) != 0) { - raise_exception(env, EXCP0D_GPF); - } - eflags = cpu_cc_compute_all(env, CC_OP); - d0 = ldq(a0); - d1 = ldq(a0 + 8); - if (d0 == EAX && d1 == EDX) { - stq(a0, EBX); - stq(a0 + 8, ECX); - eflags |= CC_Z; - } else { - /* always do the store */ - stq(a0, d0); - stq(a0 + 8, d1); - EDX = d1; - EAX = d0; - eflags &= ~CC_Z; - } - CC_SRC = eflags; -} -#endif - void helper_enter_level(int level, int data32, target_ulong t1) { target_ulong ssp; @@ -2534,127 +2473,3 @@ void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) env = saved_env; } #endif - -void helper_boundw(target_ulong a0, int v) -{ - int low, high; - - low = ldsw(a0); - high = ldsw(a0 + 2); - v = (int16_t)v; - if (v < low || v > high) { - raise_exception(env, EXCP05_BOUND); - } -} - -void helper_boundl(target_ulong a0, int v) -{ - int low, high; - - low = ldl(a0); - high = ldl(a0 + 4); - if (v < low || v > high) { - raise_exception(env, EXCP05_BOUND); - } -} - -#if !defined(CONFIG_USER_ONLY) - -#define MMUSUFFIX _mmu - -#define SHIFT 0 -#include "softmmu_template.h" - -#define SHIFT 1 -#include "softmmu_template.h" - -#define SHIFT 2 -#include "softmmu_template.h" - -#define SHIFT 3 -#include "softmmu_template.h" - -#endif - -#if !defined(CONFIG_USER_ONLY) -/* try to fill the TLB and return an exception if error. If retaddr is - NULL, it means that the function was called in C code (i.e. not - from generated code or from helper.c) */ -/* XXX: fix it to restore all registers */ -void tlb_fill(CPUX86State *env1, target_ulong addr, int is_write, int mmu_idx, - uintptr_t retaddr) -{ - TranslationBlock *tb; - int ret; - CPUX86State *saved_env; - - saved_env = env; - env = env1; - - ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx); - if (ret) { - if (retaddr) { - /* now we have a real cpu fault */ - tb = tb_find_pc(retaddr); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, retaddr); - } - } - raise_exception_err(env, env->exception_index, env->error_code); - } - env = saved_env; -} -#endif - -/* temporary wrappers */ -#if defined(CONFIG_USER_ONLY) -#define ldub_data(addr) ldub_raw(addr) -#define lduw_data(addr) lduw_raw(addr) -#define ldl_data(addr) ldl_raw(addr) -#define ldq_data(addr) ldq_raw(addr) - -#define stb_data(addr, data) stb_raw(addr, data) -#define stw_data(addr, data) stw_raw(addr, data) -#define stl_data(addr, data) stl_raw(addr, data) -#define stq_data(addr, data) stq_raw(addr, data) -#endif - -#define WRAP_LD(rettype, fn) \ - rettype cpu_ ## fn(CPUX86State *env1, target_ulong addr) \ - { \ - CPUX86State *saved_env; \ - rettype ret; \ - \ - saved_env = env; \ - env = env1; \ - ret = fn(addr); \ - env = saved_env; \ - return ret; \ - } - -WRAP_LD(uint32_t, ldub_data) -WRAP_LD(uint32_t, lduw_data) -WRAP_LD(uint32_t, ldl_data) -WRAP_LD(uint64_t, ldq_data) - -WRAP_LD(uint32_t, lduw_kernel) -#undef WRAP_LD - -#define WRAP_ST(datatype, fn) \ - void cpu_ ## fn(CPUX86State *env1, target_ulong addr, datatype val) \ - { \ - CPUX86State *saved_env; \ - \ - saved_env = env; \ - env = env1; \ - fn(addr, val); \ - env = saved_env; \ - } - -WRAP_ST(uint32_t, stb_data) -WRAP_ST(uint32_t, stw_data) -WRAP_ST(uint32_t, stl_data) -WRAP_ST(uint64_t, stq_data) -#undef WRAP_ST