aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-i386/Makefile.objs3
-rw-r--r--target-i386/mem_helper.c161
-rw-r--r--target-i386/op_helper.c138
3 files changed, 165 insertions, 137 deletions
diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 72bd423277..9a921c400c 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -1,6 +1,6 @@
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
@@ -13,3 +13,4 @@ $(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/svm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/smm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/misc_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 0000000000..91353c0788
--- /dev/null
+++ b/target-i386/mem_helper.c
@@ -0,0 +1,161 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 = helper_cc_compute_all(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 = helper_cc_compute_all(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
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 441c0aed2a..a4b8b640a0 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 = helper_cc_compute_all(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 = helper_cc_compute_all(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,76 +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