aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.target10
-rw-r--r--bsd-user/main.c2
-rwxr-xr-xconfigure34
-rw-r--r--cpu-all.h2
-rw-r--r--cpu-exec.c149
-rw-r--r--cpus.c1
-rw-r--r--disas.c1
-rw-r--r--exec-all.h3
-rw-r--r--exec.c1
-rw-r--r--gdbstub.c2
-rw-r--r--hw/kvmclock.h10
-rw-r--r--hw/sh7750.c1
-rw-r--r--hw/spapr_hcall.c1
-rw-r--r--kvm-stub.c2
-rw-r--r--linux-user/main.c3
-rw-r--r--monitor.c2
-rw-r--r--target-alpha/cpu.h22
-rw-r--r--target-alpha/exec.h21
-rw-r--r--target-alpha/helper.c1
-rw-r--r--target-alpha/op_helper.c6
-rw-r--r--target-alpha/translate.c1
-rw-r--r--target-arm/cpu.h13
-rw-r--r--target-arm/exec.h13
-rw-r--r--target-arm/helper.c1
-rw-r--r--target-arm/op_helper.c6
-rw-r--r--target-arm/translate.c1
-rw-r--r--target-cris/cpu.h11
-rw-r--r--target-cris/exec.h12
-rw-r--r--target-cris/helper.c1
-rw-r--r--target-cris/mmu.c1
-rw-r--r--target-cris/op_helper.c4
-rw-r--r--target-cris/translate.c1
-rw-r--r--target-i386/cpu.h57
-rw-r--r--target-i386/exec.h57
-rw-r--r--target-i386/helper.c1
-rw-r--r--target-i386/machine.c2
-rw-r--r--target-i386/op_helper.c106
-rw-r--r--target-i386/translate.c1
-rw-r--r--target-lm32/cpu.h13
-rw-r--r--target-lm32/exec.h12
-rw-r--r--target-lm32/helper.c1
-rw-r--r--target-lm32/op_helper.c6
-rw-r--r--target-lm32/translate.c1
-rw-r--r--target-m68k/cpu.h15
-rw-r--r--target-m68k/exec.h12
-rw-r--r--target-m68k/helper.c1
-rw-r--r--target-m68k/op_helper.c35
-rw-r--r--target-m68k/translate.c1
-rw-r--r--target-microblaze/cpu.h13
-rw-r--r--target-microblaze/exec.h12
-rw-r--r--target-microblaze/helper.c1
-rw-r--r--target-microblaze/mmu.c1
-rw-r--r--target-microblaze/op_helper.c4
-rw-r--r--target-microblaze/translate.c1
-rw-r--r--target-mips/cpu.h24
-rw-r--r--target-mips/exec.h23
-rw-r--r--target-mips/helper.c1
-rw-r--r--target-mips/machine.c2
-rw-r--r--target-mips/op_helper.c4
-rw-r--r--target-mips/translate.c1
-rw-r--r--target-ppc/cpu.h12
-rw-r--r--target-ppc/exec.h12
-rw-r--r--target-ppc/helper.c1
-rw-r--r--target-ppc/op_helper.c2
-rw-r--r--target-ppc/translate.c1
-rw-r--r--target-s390x/cpu.h11
-rw-r--r--target-s390x/exec.h13
-rw-r--r--target-s390x/helper.c1
-rw-r--r--target-s390x/op_helper.c18
-rw-r--r--target-s390x/translate.c1
-rw-r--r--target-sh4/cpu.h13
-rw-r--r--target-sh4/exec.h12
-rw-r--r--target-sh4/helper.c1
-rw-r--r--target-sh4/op_helper.c10
-rw-r--r--target-sh4/translate.c1
-rw-r--r--target-sparc/cpu.h22
-rw-r--r--target-sparc/exec.h16
-rw-r--r--target-sparc/helper.c243
-rw-r--r--target-sparc/machine.c28
-rw-r--r--target-sparc/op_helper.c279
-rw-r--r--target-sparc/translate.c1
-rw-r--r--target-unicore32/cpu.h6
-rw-r--r--target-unicore32/exec.h7
-rw-r--r--target-unicore32/helper.c1
-rw-r--r--target-unicore32/op_helper.c2
-rw-r--r--target-unicore32/translate.c1
-rw-r--r--tcg/arm/tcg-target.c19
-rw-r--r--tcg/hppa/tcg-target.c8
-rw-r--r--tcg/i386/tcg-target.c32
-rw-r--r--tcg/ia64/tcg-target.c7
-rw-r--r--tcg/mips/tcg-target.c10
-rw-r--r--tcg/ppc/tcg-target.c8
-rw-r--r--tcg/ppc64/tcg-target.c8
-rw-r--r--tcg/s390/tcg-target.c7
-rw-r--r--tcg/sparc/tcg-target.c9
-rw-r--r--tcg/tcg.c22
-rw-r--r--tcg/tcg.h7
-rw-r--r--translate-all.c3
-rw-r--r--ui/vnc-enc-tight.c10
-rw-r--r--user-exec.c11
-rw-r--r--xen-mapcache-stub.c2
101 files changed, 871 insertions, 754 deletions
diff --git a/Makefile.target b/Makefile.target
index 03d3646b23..38afdb8e94 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -14,7 +14,10 @@ endif
TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
$(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw)
-QEMU_CFLAGS+= -I.. -I../linux-headers -I$(TARGET_PATH) -DNEED_CPU_H
+ifdef CONFIG_LINUX
+QEMU_CFLAGS += -I../linux-headers
+endif
+QEMU_CFLAGS += -I.. -I$(TARGET_PATH) -DNEED_CPU_H
include $(SRC_PATH)/Makefile.objs
@@ -91,7 +94,7 @@ tcg/tcg.o: cpu.h
# HELPER_CFLAGS is used for all the code compiled with static register
# variables
-%_helper.o cpu-exec.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+%_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
# Note: this is a workaround. The real fix is to avoid compiling
# cpu_signal_handler() in user-exec.c.
@@ -234,7 +237,8 @@ obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
obj-i386-y += vmport.o
obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
obj-i386-y += debugcon.o multiboot.o
-obj-i386-y += pc_piix.o kvmclock.o
+obj-i386-y += pc_piix.o
+obj-i386-$(CONFIG_KVM) += kvmclock.o
obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
# shared objects
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0af8a7e7f1..5f790b255a 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -29,7 +29,7 @@
#include "qemu.h"
#include "qemu-common.h"
/* For tb_lock */
-#include "exec-all.h"
+#include "cpu.h"
#include "tcg.h"
#include "qemu-timer.h"
#include "envlist.h"
diff --git a/configure b/configure
index a3110711d1..88159acde2 100755
--- a/configure
+++ b/configure
@@ -113,7 +113,7 @@ curl=""
curses=""
docs=""
fdt=""
-kvm="yes"
+kvm=""
nptl=""
sdl=""
vnc="yes"
@@ -129,7 +129,7 @@ xen=""
xen_ctrl_version=""
linux_aio=""
attr=""
-vhost_net="yes"
+vhost_net=""
xfs=""
gprof="no"
@@ -457,6 +457,8 @@ Haiku)
linux="yes"
linux_user="yes"
usb="linux"
+ kvm="yes"
+ vhost_net="yes"
if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
audio_possible_drivers="$audio_possible_drivers fmod"
fi
@@ -3444,19 +3446,21 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
fi
# use included Linux headers
-includes="-I\$(SRC_PATH)/linux-headers $includes"
-mkdir -p linux-headers
-case "$cpu" in
-i386|x86_64)
- symlink $source_path/linux-headers/asm-x86 linux-headers/asm
- ;;
-ppcemb|ppc|ppc64)
- symlink $source_path/linux-headers/asm-x86 linux-headers/asm
- ;;
-s390x)
- symlink $source_path/linux-headers/asm-s390 linux-headers/asm
- ;;
-esac
+if test "$linux" = "yes" ; then
+ includes="-I\$(SRC_PATH)/linux-headers $includes"
+ mkdir -p linux-headers
+ case "$cpu" in
+ i386|x86_64)
+ symlink $source_path/linux-headers/asm-x86 linux-headers/asm
+ ;;
+ ppcemb|ppc|ppc64)
+ symlink $source_path/linux-headers/asm-powerpc linux-headers/asm
+ ;;
+ s390x)
+ symlink $source_path/linux-headers/asm-s390 linux-headers/asm
+ ;;
+ esac
+fi
echo "LDFLAGS+=$ldflags" >> $config_target_mak
echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
diff --git a/cpu-all.h b/cpu-all.h
index 880f570d56..e8391009a3 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -847,7 +847,7 @@ void cpu_reset_interrupt(CPUState *env, int mask);
void cpu_exit(CPUState *s);
-int qemu_cpu_has_work(CPUState *env);
+bool qemu_cpu_has_work(CPUState *env);
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ 0x01
diff --git a/cpu-exec.c b/cpu-exec.c
index 7aa1d004e8..20e3ec41d7 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -17,27 +17,21 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
-#include "exec.h"
+#include "cpu.h"
#include "disas.h"
#include "tcg.h"
#include "qemu-barrier.h"
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-// Work around ugly bugs in glibc that mangle global register contents
-#undef env
-#define env cpu_single_env
-#endif
-
int tb_invalidated_flag;
//#define CONFIG_DEBUG_EXEC
-int qemu_cpu_has_work(CPUState *env)
+bool qemu_cpu_has_work(CPUState *env)
{
return cpu_has_work(env);
}
-void cpu_loop_exit(void)
+void cpu_loop_exit(CPUState *env)
{
env->current_tb = NULL;
longjmp(env->jmp_env, 1);
@@ -47,10 +41,8 @@ void cpu_loop_exit(void)
restored in a state compatible with the CPU emulator
*/
#if defined(CONFIG_SOFTMMU)
-void cpu_resume_from_signal(CPUState *env1, void *puc)
+void cpu_resume_from_signal(CPUState *env, void *puc)
{
- env = env1;
-
/* XXX: restore cpu registers saved in host registers */
env->exception_index = -1;
@@ -60,7 +52,8 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
/* Execute the code without caching the generated code. An interpreter
could be used if available. */
-static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
+static void cpu_exec_nocache(CPUState *env, int max_cycles,
+ TranslationBlock *orig_tb)
{
unsigned long next_tb;
TranslationBlock *tb;
@@ -74,7 +67,7 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
max_cycles);
env->current_tb = tb;
/* execute the generated code */
- next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
+ next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
env->current_tb = NULL;
if ((next_tb & 3) == 2) {
@@ -86,7 +79,8 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
tb_free(tb);
}
-static TranslationBlock *tb_find_slow(target_ulong pc,
+static TranslationBlock *tb_find_slow(CPUState *env,
+ target_ulong pc,
target_ulong cs_base,
uint64_t flags)
{
@@ -140,7 +134,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
return tb;
}
-static inline TranslationBlock *tb_find_fast(void)
+static inline TranslationBlock *tb_find_fast(CPUState *env)
{
TranslationBlock *tb;
target_ulong cs_base, pc;
@@ -153,7 +147,7 @@ static inline TranslationBlock *tb_find_fast(void)
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
tb->flags != flags)) {
- tb = tb_find_slow(pc, cs_base, flags);
+ tb = tb_find_slow(env, pc, cs_base, flags);
}
return tb;
}
@@ -186,31 +180,22 @@ static void cpu_handle_debug_exception(CPUState *env)
volatile sig_atomic_t exit_request;
-int cpu_exec(CPUState *env1)
+int cpu_exec(CPUState *env)
{
- volatile host_reg_t saved_env_reg;
int ret, interrupt_request;
TranslationBlock *tb;
uint8_t *tc_ptr;
unsigned long next_tb;
- if (env1->halted) {
- if (!cpu_has_work(env1)) {
+ if (env->halted) {
+ if (!cpu_has_work(env)) {
return EXCP_HALTED;
}
- env1->halted = 0;
+ env->halted = 0;
}
- cpu_single_env = env1;
-
- /* the access to env below is actually saving the global register's
- value, so that files not including target-xyz/exec.h are free to
- use it. */
- QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env));
- saved_env_reg = (host_reg_t) env;
- barrier();
- env = env1;
+ cpu_single_env = env;
if (unlikely(exit_request)) {
env->exit_request = 1;
@@ -246,11 +231,6 @@ int cpu_exec(CPUState *env1)
/* prepare setjmp context for exception handling */
for(;;) {
if (setjmp(env->jmp_env) == 0) {
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
/* if an exception is pending, we execute it here */
if (env->exception_index >= 0) {
if (env->exception_index >= EXCP_INTERRUPT) {
@@ -266,51 +246,12 @@ int cpu_exec(CPUState *env1)
which will be handled outside the cpu execution
loop */
#if defined(TARGET_I386)
- do_interrupt_user(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip);
- /* successfully delivered */
- env->old_exception = -1;
+ do_interrupt(env);
#endif
ret = env->exception_index;
break;
#else
-#if defined(TARGET_I386)
- /* simulate a real cpu exception. On i386, it can
- trigger new exceptions, but we do not handle
- double or triple faults yet. */
- do_interrupt(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip, 0);
- /* successfully delivered */
- env->old_exception = -1;
-#elif defined(TARGET_PPC)
- do_interrupt(env);
-#elif defined(TARGET_LM32)
- do_interrupt(env);
-#elif defined(TARGET_MICROBLAZE)
- do_interrupt(env);
-#elif defined(TARGET_MIPS)
- do_interrupt(env);
-#elif defined(TARGET_SPARC)
do_interrupt(env);
-#elif defined(TARGET_ARM)
- do_interrupt(env);
-#elif defined(TARGET_UNICORE32)
- do_interrupt(env);
-#elif defined(TARGET_SH4)
- do_interrupt(env);
-#elif defined(TARGET_ALPHA)
- do_interrupt(env);
-#elif defined(TARGET_CRIS)
- do_interrupt(env);
-#elif defined(TARGET_M68K)
- do_interrupt(0);
-#elif defined(TARGET_S390X)
- do_interrupt(env);
-#endif
env->exception_index = -1;
#endif
}
@@ -327,7 +268,7 @@ int cpu_exec(CPUState *env1)
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
@@ -336,33 +277,33 @@ int cpu_exec(CPUState *env1)
env->interrupt_request &= ~CPU_INTERRUPT_HALT;
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#endif
#if defined(TARGET_I386)
if (interrupt_request & CPU_INTERRUPT_INIT) {
- svm_check_intercept(SVM_EXIT_INIT);
+ svm_check_intercept(env, SVM_EXIT_INIT);
do_cpu_init(env);
env->exception_index = EXCP_HALTED;
- cpu_loop_exit();
+ cpu_loop_exit(env);
} else if (interrupt_request & CPU_INTERRUPT_SIPI) {
do_cpu_sipi(env);
} else if (env->hflags2 & HF2_GIF_MASK) {
if ((interrupt_request & CPU_INTERRUPT_SMI) &&
!(env->hflags & HF_SMM_MASK)) {
- svm_check_intercept(SVM_EXIT_SMI);
+ svm_check_intercept(env, SVM_EXIT_SMI);
env->interrupt_request &= ~CPU_INTERRUPT_SMI;
- do_smm_enter();
+ do_smm_enter(env);
next_tb = 0;
} else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
!(env->hflags2 & HF2_NMI_MASK)) {
env->interrupt_request &= ~CPU_INTERRUPT_NMI;
env->hflags2 |= HF2_NMI_MASK;
- do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
+ do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
next_tb = 0;
} else if (interrupt_request & CPU_INTERRUPT_MCE) {
env->interrupt_request &= ~CPU_INTERRUPT_MCE;
- do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
+ do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
next_tb = 0;
} else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
(((env->hflags2 & HF2_VINTR_MASK) &&
@@ -371,16 +312,11 @@ int cpu_exec(CPUState *env1)
(env->eflags & IF_MASK &&
!(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
int intno;
- svm_check_intercept(SVM_EXIT_INTR);
+ svm_check_intercept(env, SVM_EXIT_INTR);
env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
- do_interrupt(intno, 0, 0, 0, 1);
+ do_interrupt_x86_hardirq(env, intno, 1);
/* ensure that no TB jump will be modified as
the program flow was changed */
next_tb = 0;
@@ -390,10 +326,10 @@ int cpu_exec(CPUState *env1)
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
int intno;
/* FIXME: this should respect TPR */
- svm_check_intercept(SVM_EXIT_VINTR);
+ svm_check_intercept(env, SVM_EXIT_VINTR);
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
- do_interrupt(intno, 0, 0, 0, 1);
+ do_interrupt_x86_hardirq(env, intno, 1);
env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
next_tb = 0;
#endif
@@ -542,7 +478,7 @@ int cpu_exec(CPUState *env1)
provide/save the vector when the interrupt is
first signalled. */
env->exception_index = env->pending_vector;
- do_interrupt(1);
+ do_interrupt_m68k_hardirq(env);
next_tb = 0;
}
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
@@ -564,13 +500,14 @@ int cpu_exec(CPUState *env1)
if (unlikely(env->exit_request)) {
env->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
/* restore flags in standard format */
#if defined(TARGET_I386)
- env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
+ env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
+ | (DF & DF_MASK);
log_cpu_state(env, X86_DUMP_CCOP);
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
#elif defined(TARGET_M68K)
@@ -585,7 +522,7 @@ int cpu_exec(CPUState *env1)
}
#endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */
spin_lock(&tb_lock);
- tb = tb_find_fast();
+ tb = tb_find_fast(env);
/* Note: we do it here to avoid a gcc bug on Mac OS X when
doing it in tb_find_slow */
if (tb_invalidated_flag) {
@@ -617,12 +554,7 @@ int cpu_exec(CPUState *env1)
if (likely(!env->exit_request)) {
tc_ptr = tb->tc_ptr;
/* execute the generated code */
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
- next_tb = tcg_qemu_tb_exec(tc_ptr);
+ next_tb = tcg_qemu_tb_exec(env, tc_ptr);
if ((next_tb & 3) == 2) {
/* Instruction counter expired. */
int insns_left;
@@ -643,11 +575,11 @@ int cpu_exec(CPUState *env1)
} else {
if (insns_left > 0) {
/* Execute remaining instructions. */
- cpu_exec_nocache(insns_left, tb);
+ cpu_exec_nocache(env, insns_left, tb);
}
env->exception_index = EXCP_INTERRUPT;
next_tb = 0;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
}
}
@@ -661,7 +593,8 @@ int cpu_exec(CPUState *env1)
#if defined(TARGET_I386)
/* restore flags in standard format */
- env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
+ env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
+ | (DF & DF_MASK);
#elif defined(TARGET_ARM)
/* XXX: Save/restore host fpu exception state?. */
#elif defined(TARGET_UNICORE32)
@@ -684,10 +617,6 @@ int cpu_exec(CPUState *env1)
#error unsupported target CPU
#endif
- /* restore global registers */
- barrier();
- env = (void *) saved_env_reg;
-
/* fail safe : never use cpu_single_env outside cpu_exec() */
cpu_single_env = NULL;
return ret;
diff --git a/cpus.c b/cpus.c
index ded21007e7..abd24ab31c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -30,7 +30,6 @@
#include "gdbstub.h"
#include "dma.h"
#include "kvm.h"
-#include "exec-all.h"
#include "qemu-thread.h"
#include "cpus.h"
diff --git a/disas.c b/disas.c
index d208c52402..1334b8e0f3 100644
--- a/disas.c
+++ b/disas.c
@@ -5,7 +5,6 @@
#include <errno.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
/* Filled in by elfload.c. Simplistic, but will do for now. */
diff --git a/exec-all.h b/exec-all.h
index 2a13a9535e..21a69d68ad 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -40,6 +40,7 @@ typedef ram_addr_t tb_page_addr_t;
#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
#define DISAS_TB_JUMP 3 /* only pc was modified statically */
+struct TranslationBlock;
typedef struct TranslationBlock TranslationBlock;
/* XXX: make safe guess about sizes */
@@ -95,7 +96,7 @@ TranslationBlock *tb_gen_code(CPUState *env,
target_ulong pc, target_ulong cs_base, int flags,
int cflags);
void cpu_exec_init(CPUState *env);
-void QEMU_NORETURN cpu_loop_exit(void);
+void QEMU_NORETURN cpu_loop_exit(CPUState *env1);
int page_unprotect(target_ulong address, unsigned long pc, void *puc);
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int is_cpu_write_access);
diff --git a/exec.c b/exec.c
index 72362810ec..4c45299906 100644
--- a/exec.c
+++ b/exec.c
@@ -26,7 +26,6 @@
#include "qemu-common.h"
#include "cpu.h"
-#include "exec-all.h"
#include "tcg.h"
#include "hw/hw.h"
#include "hw/qdev.h"
diff --git a/gdbstub.c b/gdbstub.c
index b9ae30dd7d..c085a5afb3 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -37,7 +37,7 @@
#define MAX_PACKET_LENGTH 4096
-#include "exec-all.h"
+#include "cpu.h"
#include "qemu_socket.h"
#include "kvm.h"
diff --git a/hw/kvmclock.h b/hw/kvmclock.h
index 7a83cbe8f6..252ea13461 100644
--- a/hw/kvmclock.h
+++ b/hw/kvmclock.h
@@ -11,4 +11,14 @@
*
*/
+#ifdef CONFIG_KVM
+
void kvmclock_create(void);
+
+#else /* CONFIG_KVM */
+
+static inline void kvmclock_create(void)
+{
+}
+
+#endif /* !CONFIG_KVM */
diff --git a/hw/sh7750.c b/hw/sh7750.c
index 19d5bf8537..4f279e7e51 100644
--- a/hw/sh7750.c
+++ b/hw/sh7750.c
@@ -29,7 +29,6 @@
#include "sh7750_regs.h"
#include "sh7750_regnames.h"
#include "sh_intc.h"
-#include "exec-all.h"
#include "cpu.h"
#define NB_DEVICES 4
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 43c441dc7d..84da8fc69c 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -3,7 +3,6 @@
#include "qemu-char.h"
#include "sysemu.h"
#include "qemu-char.h"
-#include "exec-all.h"
#include "exec.h"
#include "helper_regs.h"
#include "hw/spapr.h"
diff --git a/kvm-stub.c b/kvm-stub.c
index 1e835c6715..06064b9a86 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -12,7 +12,7 @@
#include "qemu-common.h"
#include "hw/hw.h"
-#include "exec-all.h"
+#include "cpu.h"
#include "gdbstub.h"
#include "kvm.h"
diff --git a/linux-user/main.c b/linux-user/main.c
index 71dd253786..1c91c30dcb 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -29,8 +29,7 @@
#include "qemu.h"
#include "qemu-common.h"
#include "cache-utils.h"
-/* For tb_lock */
-#include "exec-all.h"
+#include "cpu.h"
#include "tcg.h"
#include "qemu-timer.h"
#include "envlist.h"
diff --git a/monitor.c b/monitor.c
index 6af6a4d999..67ceb46a62 100644
--- a/monitor.c
+++ b/monitor.c
@@ -56,7 +56,7 @@
#include "json-streamer.h"
#include "json-parser.h"
#include "osdep.h"
-#include "exec-all.h"
+#include "cpu.h"
#ifdef CONFIG_SIMPLE_TRACE
#include "trace.h"
#endif
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index e98b32513c..411bd55328 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -492,4 +492,26 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
}
#endif
+static inline bool cpu_has_work(CPUState *env)
+{
+ /* Here we are checking to see if the CPU should wake up from HALT.
+ We will have gotten into this state only for WTINT from PALmode. */
+ /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
+ asleep even if (some) interrupts have been asserted. For now,
+ assume that if a CPU really wants to stay asleep, it will mask
+ interrupts at the chipset level, which will prevent these bits
+ from being set in the first place. */
+ return env->interrupt_request & (CPU_INTERRUPT_HARD
+ | CPU_INTERRUPT_TIMER
+ | CPU_INTERRUPT_SMP
+ | CPU_INTERRUPT_MCHK);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
+
#endif /* !defined (__CPU_ALPHA_H__) */
diff --git a/target-alpha/exec.h b/target-alpha/exec.h
index 7a325e7a75..afb01d3727 100644
--- a/target-alpha/exec.h
+++ b/target-alpha/exec.h
@@ -31,30 +31,9 @@ register struct CPUAlphaState *env asm(AREG0);
#define FP_STATUS (env->fp_status)
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- /* Here we are checking to see if the CPU should wake up from HALT.
- We will have gotten into this state only for WTINT from PALmode. */
- /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
- asleep even if (some) interrupts have been asserted. For now,
- assume that if a CPU really wants to stay asleep, it will mask
- interrupts at the chipset level, which will prevent these bits
- from being set in the first place. */
- return env->interrupt_request & (CPU_INTERRUPT_HARD
- | CPU_INTERRUPT_TIMER
- | CPU_INTERRUPT_SMP
- | CPU_INTERRUPT_MCHK);
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
#endif /* !defined (__ALPHA_EXEC_H__) */
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 32c2cf9db3..7049c80d5c 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -22,7 +22,6 @@
#include <stdio.h>
#include "cpu.h"
-#include "exec-all.h"
#include "softfloat.h"
uint64_t cpu_alpha_load_fpcr (CPUState *env)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index d33271958f..51d1bd7099 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -32,7 +32,7 @@ void QEMU_NORETURN helper_excp(int excp, int error)
{
env->exception_index = excp;
env->error_code = error;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static void do_restore_state(void *retaddr)
@@ -53,7 +53,7 @@ static void QEMU_NORETURN dynamic_excp(int excp, int error)
env->exception_index = excp;
env->error_code = error;
do_restore_state(GETPC());
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
@@ -1341,7 +1341,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
if (unlikely(ret != 0)) {
do_restore_state(retaddr);
/* Exception index and error code are already set */
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 936760c5ad..c61906a8b3 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -22,7 +22,6 @@
#include <stdio.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "host-utils.h"
#include "tcg-op.h"
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 01f5b57fbc..116131eef8 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -512,4 +512,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
}
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request &
+ (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->regs[15] = tb->pc;
+}
+
#endif
diff --git a/target-arm/exec.h b/target-arm/exec.h
index db6608ec8b..6793288d43 100644
--- a/target-arm/exec.h
+++ b/target-arm/exec.h
@@ -22,22 +22,9 @@
register struct CPUARMState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request &
- (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB));
-}
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
void raise_exception(int);
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->regs[15] = tb->pc;
-}
-
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 12084167d6..f4d12aab55 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3,7 +3,6 @@
#include <string.h>
#include "cpu.h"
-#include "exec-all.h"
#include "gdbstub.h"
#include "helper.h"
#include "qemu-common.h"
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 8334fbcf6d..46358844c5 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -25,7 +25,7 @@
void raise_exception(int tt)
{
env->exception_index = tt;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
@@ -234,13 +234,13 @@ void HELPER(wfi)(void)
{
env->exception_index = EXCP_HLT;
env->halted = 1;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void HELPER(exception)(uint32_t excp)
{
env->exception_index = excp;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
uint32_t HELPER(cpsr_read)(void)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f5507ec3b6..badbc5ff31 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -25,7 +25,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 2bc35e4975..ecb0df1d33 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -268,4 +268,15 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
#define cpu_list cris_cpu_list
void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
#endif
diff --git a/target-cris/exec.h b/target-cris/exec.h
index 2d5d297e1b..3294abe393 100644
--- a/target-cris/exec.h
+++ b/target-cris/exec.h
@@ -22,19 +22,7 @@
register struct CPUCRISState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
diff --git a/target-cris/helper.c b/target-cris/helper.c
index 2a4403b847..962d214177 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -24,7 +24,6 @@
#include "config.h"
#include "cpu.h"
#include "mmu.h"
-#include "exec-all.h"
#include "host-utils.h"
diff --git a/target-cris/mmu.c b/target-cris/mmu.c
index 1243745598..d481e39352 100644
--- a/target-cris/mmu.c
+++ b/target-cris/mmu.c
@@ -27,7 +27,6 @@
#include "config.h"
#include "cpu.h"
#include "mmu.h"
-#include "exec-all.h"
#ifdef DEBUG
#define D(x) x
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index 34329e2a60..b3ddd33e02 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -83,7 +83,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
helper_top_evaluate_flags();
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
@@ -93,7 +93,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
void helper_raise_exception(uint32_t index)
{
env->exception_index = index;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_tlb_flush_pid(uint32_t pid)
diff --git a/target-cris/translate.c b/target-cris/translate.c
index e2607d64c0..dd85859c0b 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -30,7 +30,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "helper.h"
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index cdf68ffd99..9819b5fdb9 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -957,6 +957,36 @@ static inline int cpu_mmu_index (CPUState *env)
return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
}
+#undef EAX
+#define EAX (env->regs[R_EAX])
+#undef ECX
+#define ECX (env->regs[R_ECX])
+#undef EDX
+#define EDX (env->regs[R_EDX])
+#undef EBX
+#define EBX (env->regs[R_EBX])
+#undef ESP
+#define ESP (env->regs[R_ESP])
+#undef EBP
+#define EBP (env->regs[R_EBP])
+#undef ESI
+#define ESI (env->regs[R_ESI])
+#undef EDI
+#define EDI (env->regs[R_EDI])
+#undef EIP
+#define EIP (env->eip)
+#define DF (env->df)
+
+#define CC_SRC (env->cc_src)
+#define CC_DST (env->cc_dst)
+#define CC_OP (env->cc_op)
+
+/* float macros */
+#define FT0 (env->ft0)
+#define ST0 (env->fpregs[env->fpstt].d)
+#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
+#define ST1 ST(1)
+
/* translate.c */
void optimize_flags_init(void);
@@ -981,6 +1011,23 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#include "hw/apic.h"
#endif
+static inline bool cpu_has_work(CPUState *env)
+{
+ return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->eflags & IF_MASK)) ||
+ (env->interrupt_request & (CPU_INTERRUPT_NMI |
+ CPU_INTERRUPT_INIT |
+ CPU_INTERRUPT_SIPI |
+ CPU_INTERRUPT_MCE));
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->eip = tb->pc - tb->cs_base;
+}
+
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
@@ -1000,4 +1047,14 @@ void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
uint64_t status, uint64_t mcg_status, uint64_t addr,
uint64_t misc, int flags);
+/* op_helper.c */
+void do_interrupt(CPUState *env);
+void do_interrupt_x86_hardirq(CPUState *env, int intno, int is_hw);
+
+void do_smm_enter(CPUState *env1);
+
+void svm_check_intercept(CPUState *env1, uint32_t type);
+
+uint32_t cpu_cc_compute_all(CPUState *env1, int op);
+
#endif /* CPU_I386_H */
diff --git a/target-i386/exec.h b/target-i386/exec.h
index 9bd080e3a8..dd9bce4eed 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -33,48 +33,12 @@ register struct CPUX86State *env asm(AREG0);
#include "qemu-common.h"
#include "qemu-log.h"
-#undef EAX
-#define EAX (env->regs[R_EAX])
-#undef ECX
-#define ECX (env->regs[R_ECX])
-#undef EDX
-#define EDX (env->regs[R_EDX])
-#undef EBX
-#define EBX (env->regs[R_EBX])
-#undef ESP
-#define ESP (env->regs[R_ESP])
-#undef EBP
-#define EBP (env->regs[R_EBP])
-#undef ESI
-#define ESI (env->regs[R_ESI])
-#undef EDI
-#define EDI (env->regs[R_EDI])
-#undef EIP
-#define EIP (env->eip)
-#define DF (env->df)
-
-#define CC_SRC (env->cc_src)
-#define CC_DST (env->cc_dst)
-#define CC_OP (env->cc_op)
-
-/* float macros */
-#define FT0 (env->ft0)
-#define ST0 (env->fpregs[env->fpstt].d)
-#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
-#define ST1 ST(1)
-
#include "cpu.h"
-#include "exec-all.h"
/* op_helper.c */
-void do_interrupt(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw);
-void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip);
void QEMU_NORETURN raise_exception_err(int exception_index, int error_code);
void QEMU_NORETURN raise_exception(int exception_index);
void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv);
-void do_smm_enter(void);
/* n must be a constant to be efficient */
static inline target_long lshift(target_long x, int n)
@@ -87,11 +51,6 @@ static inline target_long lshift(target_long x, int n)
#include "helper.h"
-static inline void svm_check_intercept(uint32_t type)
-{
- helper_svm_check_intercept_param(type, 0);
-}
-
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
@@ -170,16 +129,6 @@ static inline void load_eflags(int eflags, int update_mask)
(eflags & update_mask) | 0x2;
}
-static inline int cpu_has_work(CPUState *env)
-{
- return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->eflags & IF_MASK)) ||
- (env->interrupt_request & (CPU_INTERRUPT_NMI |
- CPU_INTERRUPT_INIT |
- CPU_INTERRUPT_SIPI |
- CPU_INTERRUPT_MCE));
-}
-
/* load efer and update the corresponding hflags. XXX: do consistency
checks with cpuid bits ? */
static inline void cpu_load_efer(CPUState *env, uint64_t val)
@@ -191,9 +140,3 @@ static inline void cpu_load_efer(CPUState *env, uint64_t val)
if (env->efer & MSR_EFER_SVME)
env->hflags |= HF_SVME_MASK;
}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->eip = tb->pc - tb->cs_base;
-}
-
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 509d68ca0f..e9be104293 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -23,7 +23,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "qemu-common.h"
#include "kvm.h"
#ifndef CONFIG_USER_ONLY
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 7662aa20b7..9aca8e0523 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -3,7 +3,7 @@
#include "hw/pc.h"
#include "hw/isa.h"
-#include "exec-all.h"
+#include "cpu.h"
#include "kvm.h"
static const VMStateDescription vmstate_segment = {
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index cec0c7686f..315e18b9a4 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -19,7 +19,6 @@
#include <math.h>
#include "exec.h"
-#include "exec-all.h"
#include "host-utils.h"
#include "ioport.h"
@@ -1000,7 +999,7 @@ void helper_syscall(int next_eip_addend)
{
env->exception_index = EXCP_SYSCALL;
env->exception_next_eip = env->eip + next_eip_addend;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#else
void helper_syscall(int next_eip_addend)
@@ -1150,9 +1149,10 @@ static void do_interrupt_real(int intno, int is_int, int error_code,
env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);
}
+#if defined(CONFIG_USER_ONLY)
/* fake user mode interrupt */
-void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip)
+static void do_interrupt_user(int intno, int is_int, int error_code,
+ target_ulong next_eip)
{
SegmentCache *dt;
target_ulong ptr;
@@ -1181,7 +1181,8 @@ void do_interrupt_user(int intno, int is_int, int error_code,
EIP = next_eip;
}
-#if !defined(CONFIG_USER_ONLY)
+#else
+
static void handle_even_inj(int intno, int is_int, int error_code,
int is_hw, int rm)
{
@@ -1207,8 +1208,8 @@ static void handle_even_inj(int intno, int is_int, int error_code,
* the int instruction. next_eip is the EIP value AFTER the interrupt
* instruction. It is only relevant if is_int is TRUE.
*/
-void do_interrupt(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw)
+static void do_interrupt_all(int intno, int is_int, int error_code,
+ target_ulong next_eip, int is_hw)
{
if (qemu_loglevel_mask(CPU_LOG_INT)) {
if ((env->cr[0] & CR0_PE_MASK)) {
@@ -1270,6 +1271,46 @@ void do_interrupt(int intno, int is_int, int error_code,
#endif
}
+void do_interrupt(CPUState *env1)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+#if defined(CONFIG_USER_ONLY)
+ /* if user mode only, we simulate a fake exception
+ which will be handled outside the cpu execution
+ loop */
+ do_interrupt_user(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip);
+ /* successfully delivered */
+ env->old_exception = -1;
+#else
+ /* simulate a real cpu exception. On i386, it can
+ trigger new exceptions, but we do not handle
+ double or triple faults yet. */
+ do_interrupt_all(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip, 0);
+ /* successfully delivered */
+ env->old_exception = -1;
+#endif
+ env = saved_env;
+}
+
+void do_interrupt_x86_hardirq(CPUState *env1, int intno, int is_hw)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ do_interrupt_all(intno, 0, 0, 0, is_hw);
+ env = saved_env;
+}
+
/* This should come from sysemu.h - if we could include it here... */
void qemu_system_reset_request(void);
@@ -1335,7 +1376,7 @@ static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code,
env->error_code = error_code;
env->exception_is_int = is_int;
env->exception_next_eip = env->eip + next_eip_addend;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
/* shortcuts to generate exceptions */
@@ -1359,7 +1400,7 @@ void raise_exception_env(int exception_index, CPUState *nenv)
#if defined(CONFIG_USER_ONLY)
-void do_smm_enter(void)
+void do_smm_enter(CPUState *env1)
{
}
@@ -1375,11 +1416,15 @@ void helper_rsm(void)
#define SMM_REVISION_ID 0x00020000
#endif
-void do_smm_enter(void)
+void do_smm_enter(CPUState *env1)
{
target_ulong sm_state;
SegmentCache *dt;
int i, offset;
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
@@ -1506,6 +1551,7 @@ void do_smm_enter(void)
cpu_x86_update_cr4(env, 0);
env->dr[7] = 0x00000400;
CC_OP = CC_OP_EFLAGS;
+ env = saved_env;
}
void helper_rsm(void)
@@ -4658,7 +4704,7 @@ static void do_hlt(void)
env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_hlt(int next_eip_addend)
@@ -4696,7 +4742,7 @@ void helper_mwait(int next_eip_addend)
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_reset_rf(void)
@@ -4859,6 +4905,10 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
{
}
+void svm_check_intercept(CPUState *env1, uint32_t type)
+{
+}
+
void helper_svm_check_io(uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
@@ -5040,7 +5090,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->exception_next_eip = -1;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
/* XXX: is it always correct ? */
- do_interrupt(vector, 0, 0, 0, 1);
+ do_interrupt_all(vector, 0, 0, 0, 1);
break;
case SVM_EVTINJ_TYPE_NMI:
env->exception_index = EXCP02_NMI;
@@ -5048,7 +5098,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->exception_is_int = 0;
env->exception_next_eip = EIP;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
- cpu_loop_exit();
+ cpu_loop_exit(env);
break;
case SVM_EVTINJ_TYPE_EXEPT:
env->exception_index = vector;
@@ -5056,7 +5106,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->exception_is_int = 0;
env->exception_next_eip = -1;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT");
- cpu_loop_exit();
+ cpu_loop_exit(env);
break;
case SVM_EVTINJ_TYPE_SOFT:
env->exception_index = vector;
@@ -5064,7 +5114,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->exception_is_int = 1;
env->exception_next_eip = EIP;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
- cpu_loop_exit();
+ cpu_loop_exit(env);
break;
}
qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index, env->error_code);
@@ -5249,6 +5299,16 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
}
}
+void svm_check_intercept(CPUState *env1, uint32_t type)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ helper_svm_check_intercept_param(type, 0);
+ env = saved_env;
+}
+
void helper_svm_check_io(uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
@@ -5400,7 +5460,7 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
env->error_code = 0;
env->old_exception = -1;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#endif
@@ -5575,6 +5635,18 @@ uint32_t helper_cc_compute_all(int op)
}
}
+uint32_t cpu_cc_compute_all(CPUState *env1, int op)
+{
+ CPUState *saved_env;
+ uint32_t ret;
+
+ saved_env = env;
+ env = env1;
+ ret = helper_cc_compute_all(op);
+ env = saved_env;
+ return ret;
+}
+
uint32_t helper_cc_compute_c(int op)
{
switch (op) {
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 10bd72a0e2..ccef381be8 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -24,7 +24,6 @@
#include <signal.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 8e2d26b995..876b5be2bd 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -241,4 +241,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
*cs_base = 0;
*flags = 0;
}
+
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
+
#endif
diff --git a/target-lm32/exec.h b/target-lm32/exec.h
index 348b723f29..2a227b2953 100644
--- a/target-lm32/exec.h
+++ b/target-lm32/exec.h
@@ -22,12 +22,6 @@
register struct CPULM32State *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
-
-static inline int cpu_has_work(CPUState *env)
-{
- return env->interrupt_request & CPU_INTERRUPT_HARD;
-}
static inline int cpu_halted(CPUState *env)
{
@@ -42,9 +36,3 @@ static inline int cpu_halted(CPUState *env)
}
return EXCP_HALTED;
}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 4f3e7e0fcb..e79428d8e0 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -23,7 +23,6 @@
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "host-utils.h"
int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index c72b1df47b..a34cecd295 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -20,14 +20,14 @@
void helper_raise_exception(uint32_t index)
{
env->exception_index = index;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_hlt(void)
{
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_wcsr_im(uint32_t im)
@@ -98,7 +98,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 5e197258eb..0be105d018 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -25,7 +25,6 @@
#include <assert.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "helper.h"
#include "tcg-op.h"
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index b025b6689d..e0f9b32014 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -119,7 +119,8 @@ void m68k_tcg_init(void);
CPUM68KState *cpu_m68k_init(const char *cpu_model);
int cpu_m68k_exec(CPUM68KState *s);
void cpu_m68k_close(CPUM68KState *s);
-void do_interrupt(int is_hw);
+void do_interrupt(CPUState *env1);
+void do_interrupt_m68k_hardirq(CPUState *env1);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
@@ -254,4 +255,16 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
| ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
+
#endif
diff --git a/target-m68k/exec.h b/target-m68k/exec.h
index 91daa6bac4..93e7912148 100644
--- a/target-m68k/exec.h
+++ b/target-m68k/exec.h
@@ -22,19 +22,7 @@
register struct CPUM68KState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & (CPU_INTERRUPT_HARD));
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index faa8c42ae8..a936fe7b76 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -23,7 +23,6 @@
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "qemu-common.h"
#include "gdbstub.h"
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 9b13bdbcc2..237fc4cb54 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -21,9 +21,13 @@
#if defined(CONFIG_USER_ONLY)
-void do_interrupt(int is_hw)
+void do_interrupt(CPUState *env1)
+{
+ env1->exception_index = -1;
+}
+
+void do_interrupt_m68k_hardirq(CPUState *env1)
{
- env->exception_index = -1;
}
#else
@@ -71,7 +75,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
@@ -90,7 +94,7 @@ static void do_rte(void)
env->aregs[7] = sp + 8;
}
-void do_interrupt(int is_hw)
+static void do_interrupt_all(int is_hw)
{
uint32_t sp;
uint32_t fmt;
@@ -118,7 +122,7 @@ void do_interrupt(int is_hw)
}
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
return;
}
if (env->exception_index >= EXCP_TRAP0
@@ -155,12 +159,31 @@ void do_interrupt(int is_hw)
env->pc = ldl_kernel(env->vbr + vector);
}
+void do_interrupt(CPUState *env1)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ do_interrupt_all(0);
+ env = saved_env;
+}
+
+void do_interrupt_m68k_hardirq(CPUState *env1)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ do_interrupt_all(1);
+ env = saved_env;
+}
#endif
static void raise_exception(int tt)
{
env->exception_index = tt;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void HELPER(raise_exception)(uint32_t tt)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 26f0ee42e9..0e7f1fe2c7 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -25,7 +25,6 @@
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 78fe14ff35..51a13e38d1 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -350,4 +350,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
int is_asi, int size);
#endif
+
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->sregs[SR_PC] = tb->pc;
+}
+
#endif
diff --git a/target-microblaze/exec.h b/target-microblaze/exec.h
index 1efff30620..71b4d397ed 100644
--- a/target-microblaze/exec.h
+++ b/target-microblaze/exec.h
@@ -21,19 +21,7 @@
register struct CPUMBState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->sregs[SR_PC] = tb->pc;
-}
-
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index a623c7b04a..299259c3f0 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -23,7 +23,6 @@
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "host-utils.h"
#define D(x)
diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c
index b38f7d98b7..281fc8d8c4 100644
--- a/target-microblaze/mmu.c
+++ b/target-microblaze/mmu.c
@@ -22,7 +22,6 @@
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#define D(x)
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index c7b2f97d96..1a0a476a62 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -63,7 +63,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
@@ -107,7 +107,7 @@ uint32_t helper_get(uint32_t id, uint32_t ctrl)
void helper_raise_exception(uint32_t index)
{
env->exception_index = index;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_debug(void)
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index b47b92e909..31e8306ef3 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -25,7 +25,6 @@
#include <assert.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "helper.h"
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 0b98d10266..b0ac4da5a7 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -656,4 +656,28 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
env->tls_value = newtls;
}
+static inline int cpu_has_work(CPUState *env)
+{
+ int has_work = 0;
+
+ /* It is implementation dependent if non-enabled interrupts
+ wake-up the CPU, however most of the implementations only
+ check for interrupts that can be taken. */
+ if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ cpu_mips_hw_interrupts_pending(env)) {
+ has_work = 1;
+ }
+
+ return has_work;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->active_tc.PC = tb->pc;
+ env->hflags &= ~MIPS_HFLAG_BMASK;
+ env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
+}
+
#endif /* !defined (__MIPS_CPU_H__) */
diff --git a/target-mips/exec.h b/target-mips/exec.h
index 607edf12ca..e787e9a8ba 100644
--- a/target-mips/exec.h
+++ b/target-mips/exec.h
@@ -11,27 +11,11 @@
register struct CPUMIPSState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- int has_work = 0;
-
- /* It is implementation dependent if non-enabled interrupts
- wake-up the CPU, however most of the implementations only
- check for interrupts that can be taken. */
- if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
- cpu_mips_hw_interrupts_pending(env)) {
- has_work = 1;
- }
-
- return has_work;
-}
-
static inline void compute_hflags(CPUState *env)
{
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
@@ -73,11 +57,4 @@ static inline void compute_hflags(CPUState *env)
}
}
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->active_tc.PC = tb->pc;
- env->hflags &= ~MIPS_HFLAG_BMASK;
- env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
-}
-
#endif /* !defined(__QEMU_MIPS_EXEC_H__) */
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 0f057c2171..ecf6182f56 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -24,7 +24,6 @@
#include <signal.h>
#include "cpu.h"
-#include "exec-all.h"
enum {
TLBRET_DIRTY = -4,
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 9ffac711ce..be72b36de6 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -1,7 +1,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
-#include "exec-all.h"
+#include "cpu.h"
static void save_tc(QEMUFile *f, TCState *tc)
{
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index b8e4991f32..6b966b1849 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -38,7 +38,7 @@ void helper_raise_exception_err (uint32_t exception, int error_code)
#endif
env->exception_index = exception;
env->error_code = error_code;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_raise_exception (uint32_t exception)
@@ -277,7 +277,7 @@ static inline target_phys_addr_t do_translate_address(target_ulong address, int
lladdr = cpu_mips_translate_address(env, address, rw);
if (lladdr == -1LL) {
- cpu_loop_exit();
+ cpu_loop_exit(env);
} else {
return lladdr;
}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 4eaa8261c3..2848c6a692 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -27,7 +27,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-common.h"
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 8e4582f6ab..6d60d14769 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1999,4 +1999,16 @@ static inline ppcemb_tlb_t *booke206_get_tlbe(CPUState *env, const int tlbn,
extern void (*cpu_ppc_hypercall)(CPUState *);
+static inline bool cpu_has_work(CPUState *env)
+{
+ return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->nip = tb->pc;
+}
+
#endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-ppc/exec.h b/target-ppc/exec.h
index f87847acb1..f4453e4965 100644
--- a/target-ppc/exec.h
+++ b/target-ppc/exec.h
@@ -24,7 +24,6 @@
#include "dyngen-exec.h"
#include "cpu.h"
-#include "exec-all.h"
register struct CPUPPCState *env asm(AREG0);
@@ -32,15 +31,4 @@ register struct CPUPPCState *env asm(AREG0);
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- return (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD));
-}
-
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->nip = tb->pc;
-}
-
#endif /* !defined (__PPC_H__) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index cf2a368b57..395ea0e549 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -23,7 +23,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "helper_regs.h"
#include "qemu-common.h"
#include "kvm.h"
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 15d9222c72..29f72e1a34 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -44,7 +44,7 @@ void helper_raise_exception_err (uint32_t exception, uint32_t error_code)
#endif
env->exception_index = exception;
env->error_code = error_code;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_raise_exception (uint32_t exception)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 59aef855d4..0a03b4465a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -24,7 +24,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-common.h"
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index b5e587fbe6..d48a9b7a0c 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -962,4 +962,15 @@ static inline void cpu_inject_ext(CPUState *env, uint32_t code, uint32_t param,
cpu_interrupt(env, CPU_INTERRUPT_HARD);
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->psw.mask & PSW_MASK_EXT);
+}
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
+{
+ env->psw.addr = tb->pc;
+}
+
#endif
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index 7a87fffca6..fb73f31804 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -23,18 +23,11 @@ register struct CPUS390XState *env asm(AREG0);
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->psw.mask & PSW_MASK_EXT));
-}
-
static inline void regs_to_env(void)
{
}
@@ -42,9 +35,3 @@ static inline void regs_to_env(void)
static inline void env_to_regs(void)
{
}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
-{
- env->psw.addr = tb->pc;
-}
-
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 745d8c52bb..1ce7079af7 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -23,7 +23,6 @@
#include <string.h>
#include "cpu.h"
-#include "exec-all.h"
#include "gdbstub.h"
#include "qemu-common.h"
#include "qemu-timer.h"
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 9429698c2c..cd33f99d21 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -23,8 +23,10 @@
#include "helpers.h"
#include <string.h>
#include "kvm.h"
-#include <linux/kvm.h>
#include "qemu-timer.h"
+#ifdef CONFIG_KVM
+#include <linux/kvm.h>
+#endif
/*****************************************************************************/
/* Softmmu support */
@@ -71,7 +73,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
@@ -90,7 +92,7 @@ void HELPER(exception)(uint32_t excp)
{
HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp);
env->exception_index = excp;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#ifndef CONFIG_USER_ONLY
@@ -2324,7 +2326,7 @@ void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
void HELPER(load_psw)(uint64_t mask, uint64_t addr)
{
load_psw(env, mask, addr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static void program_interrupt(CPUState *env, uint32_t code, int ilc)
@@ -2332,12 +2334,14 @@ static void program_interrupt(CPUState *env, uint32_t code, int ilc)
qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
if (kvm_enabled()) {
+#ifdef CONFIG_KVM
kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
+#endif
} else {
env->int_pgm_code = code;
env->int_pgm_ilc = ilc;
env->exception_index = EXCP_PGM;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
}
@@ -2824,12 +2828,12 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
}
if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
dest |= a1 & ~TARGET_PAGE_MASK;
if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
src |= a2 & ~TARGET_PAGE_MASK;
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index eda4624d11..77fb4482aa 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -35,7 +35,6 @@
#endif
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 74ff97a908..00e32f2b10 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -361,4 +361,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
| (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+ env->flags = tb->flags;
+}
+
#endif /* _CPU_SH4_H */
diff --git a/target-sh4/exec.h b/target-sh4/exec.h
index 9f1c1f6a00..4a6ae58898 100644
--- a/target-sh4/exec.h
+++ b/target-sh4/exec.h
@@ -25,21 +25,9 @@
register struct CPUSH4State *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & CPU_INTERRUPT_HARD);
-}
#ifndef CONFIG_USER_ONLY
#include "softmmu_exec.h"
#endif
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
- env->flags = tb->flags;
-}
-
#endif /* _EXEC_SH4_H */
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 8f36d313cd..20e9b134d6 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -24,7 +24,6 @@
#include <signal.h>
#include "cpu.h"
-#include "exec-all.h"
#include "hw/sh_intc.h"
#if defined(CONFIG_USER_ONLY)
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index b909d18bc4..a932225880 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -66,7 +66,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
if (ret) {
/* now we have a real cpu fault */
cpu_restore_state_from_retaddr(retaddr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
@@ -87,7 +87,7 @@ static inline void raise_exception(int index, void *retaddr)
{
env->exception_index = index;
cpu_restore_state_from_retaddr(retaddr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_raise_illegal_instruction(void)
@@ -113,7 +113,7 @@ void helper_raise_slot_fpu_disable(void)
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_sleep(uint32_t next_pc)
@@ -122,7 +122,7 @@ void helper_sleep(uint32_t next_pc)
env->in_sleep = 1;
env->exception_index = EXCP_HLT;
env->pc = next_pc;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_trapa(uint32_t tra)
@@ -482,7 +482,7 @@ static void update_fpscr(void *retaddr)
if (cause & enable) {
cpu_restore_state_from_retaddr(retaddr);
env->exception_index = 0x120;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
}
}
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 93c863650d..569bc738cb 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -27,7 +27,6 @@
//#define SH4_SINGLE_STEP
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-common.h"
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 320530ec9f..4edae78ca3 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -403,6 +403,8 @@ typedef struct CPUSPARCState {
uint32_t mmuregs[32];
uint64_t mxccdata[4];
uint64_t mxccregs[8];
+ uint32_t mmubpctrv, mmubpctrc, mmubpctrs;
+ uint64_t mmubpaction;
uint64_t mmubpregs[4];
uint64_t prom_addr;
#endif
@@ -474,6 +476,7 @@ target_ulong cpu_get_ccr(CPUState *env1);
void cpu_put_ccr(CPUState *env1, target_ulong val);
target_ulong cpu_get_cwp64(CPUState *env1);
void cpu_put_cwp64(CPUState *env1, int cwp);
+void cpu_change_pstate(CPUState *env1, uint32_t new_pstate);
#endif
int cpu_cwp_inc(CPUState *env1, int cwp);
int cpu_cwp_dec(CPUState *env1, int cwp);
@@ -521,7 +524,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
#define cpu_signal_handler cpu_sparc_signal_handler
#define cpu_list sparc_cpu_list
-#define CPU_SAVE_VERSION 6
+#define CPU_SAVE_VERSION 7
/* MMU modes definitions */
#if defined (TARGET_SPARC64)
@@ -656,4 +659,21 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
#endif
}
+/* helper.c */
+void do_interrupt(CPUState *env);
+
+static inline bool cpu_has_work(CPUState *env1)
+{
+ return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
+ cpu_interrupts_enabled(env1);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+ env->npc = tb->cs_base;
+}
+
#endif
diff --git a/target-sparc/exec.h b/target-sparc/exec.h
index f5c221e48c..2395b0092f 100644
--- a/target-sparc/exec.h
+++ b/target-sparc/exec.h
@@ -12,20 +12,4 @@ register struct CPUSPARCState *env asm(AREG0);
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-/* op_helper.c */
-void do_interrupt(CPUState *env);
-
-static inline int cpu_has_work(CPUState *env1)
-{
- return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
- cpu_interrupts_enabled(env1);
-}
-
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
- env->npc = tb->cs_base;
-}
-
#endif
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index e9b42d03a9..7eea1acbd5 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -23,7 +23,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "qemu-common.h"
//#define DEBUG_MMU
@@ -729,6 +728,248 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
}
#endif
+#ifdef TARGET_SPARC64
+#ifdef DEBUG_PCALL
+static const char * const excp_names[0x80] = {
+ [TT_TFAULT] = "Instruction Access Fault",
+ [TT_TMISS] = "Instruction Access MMU Miss",
+ [TT_CODE_ACCESS] = "Instruction Access Error",
+ [TT_ILL_INSN] = "Illegal Instruction",
+ [TT_PRIV_INSN] = "Privileged Instruction",
+ [TT_NFPU_INSN] = "FPU Disabled",
+ [TT_FP_EXCP] = "FPU Exception",
+ [TT_TOVF] = "Tag Overflow",
+ [TT_CLRWIN] = "Clean Windows",
+ [TT_DIV_ZERO] = "Division By Zero",
+ [TT_DFAULT] = "Data Access Fault",
+ [TT_DMISS] = "Data Access MMU Miss",
+ [TT_DATA_ACCESS] = "Data Access Error",
+ [TT_DPROT] = "Data Protection Error",
+ [TT_UNALIGNED] = "Unaligned Memory Access",
+ [TT_PRIV_ACT] = "Privileged Action",
+ [TT_EXTINT | 0x1] = "External Interrupt 1",
+ [TT_EXTINT | 0x2] = "External Interrupt 2",
+ [TT_EXTINT | 0x3] = "External Interrupt 3",
+ [TT_EXTINT | 0x4] = "External Interrupt 4",
+ [TT_EXTINT | 0x5] = "External Interrupt 5",
+ [TT_EXTINT | 0x6] = "External Interrupt 6",
+ [TT_EXTINT | 0x7] = "External Interrupt 7",
+ [TT_EXTINT | 0x8] = "External Interrupt 8",
+ [TT_EXTINT | 0x9] = "External Interrupt 9",
+ [TT_EXTINT | 0xa] = "External Interrupt 10",
+ [TT_EXTINT | 0xb] = "External Interrupt 11",
+ [TT_EXTINT | 0xc] = "External Interrupt 12",
+ [TT_EXTINT | 0xd] = "External Interrupt 13",
+ [TT_EXTINT | 0xe] = "External Interrupt 14",
+ [TT_EXTINT | 0xf] = "External Interrupt 15",
+};
+#endif
+
+void do_interrupt(CPUState *env)
+{
+ int intno = env->exception_index;
+ trap_state *tsptr;
+
+#ifdef DEBUG_PCALL
+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
+ static int count;
+ const char *name;
+
+ if (intno < 0 || intno >= 0x180) {
+ name = "Unknown";
+ } else if (intno >= 0x100) {
+ name = "Trap Instruction";
+ } else if (intno >= 0xc0) {
+ name = "Window Fill";
+ } else if (intno >= 0x80) {
+ name = "Window Spill";
+ } else {
+ name = excp_names[intno];
+ if (!name) {
+ name = "Unknown";
+ }
+ }
+
+ qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
+ " SP=%016" PRIx64 "\n",
+ count, name, intno,
+ env->pc,
+ env->npc, env->regwptr[6]);
+ log_cpu_state(env, 0);
+#if 0
+ {
+ int i;
+ uint8_t *ptr;
+
+ qemu_log(" code=");
+ ptr = (uint8_t *)env->pc;
+ for (i = 0; i < 16; i++) {
+ qemu_log(" %02x", ldub(ptr + i));
+ }
+ qemu_log("\n");
+ }
+#endif
+ count++;
+ }
+#endif
+#if !defined(CONFIG_USER_ONLY)
+ if (env->tl >= env->maxtl) {
+ cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
+ " Error state", env->exception_index, env->tl, env->maxtl);
+ return;
+ }
+#endif
+ if (env->tl < env->maxtl - 1) {
+ env->tl++;
+ } else {
+ env->pstate |= PS_RED;
+ if (env->tl < env->maxtl) {
+ env->tl++;
+ }
+ }
+ tsptr = cpu_tsptr(env);
+
+ tsptr->tstate = (cpu_get_ccr(env) << 32) |
+ ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
+ cpu_get_cwp64(env);
+ tsptr->tpc = env->pc;
+ tsptr->tnpc = env->npc;
+ tsptr->tt = intno;
+
+ switch (intno) {
+ case TT_IVEC:
+ cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
+ break;
+ case TT_TFAULT:
+ case TT_DFAULT:
+ case TT_TMISS ... TT_TMISS + 3:
+ case TT_DMISS ... TT_DMISS + 3:
+ case TT_DPROT ... TT_DPROT + 3:
+ cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
+ break;
+ default:
+ cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
+ break;
+ }
+
+ if (intno == TT_CLRWIN) {
+ cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
+ } else if ((intno & 0x1c0) == TT_SPILL) {
+ cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
+ } else if ((intno & 0x1c0) == TT_FILL) {
+ cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
+ }
+ env->tbr &= ~0x7fffULL;
+ env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
+ env->pc = env->tbr;
+ env->npc = env->pc + 4;
+ env->exception_index = -1;
+}
+#else
+#ifdef DEBUG_PCALL
+static const char * const excp_names[0x80] = {
+ [TT_TFAULT] = "Instruction Access Fault",
+ [TT_ILL_INSN] = "Illegal Instruction",
+ [TT_PRIV_INSN] = "Privileged Instruction",
+ [TT_NFPU_INSN] = "FPU Disabled",
+ [TT_WIN_OVF] = "Window Overflow",
+ [TT_WIN_UNF] = "Window Underflow",
+ [TT_UNALIGNED] = "Unaligned Memory Access",
+ [TT_FP_EXCP] = "FPU Exception",
+ [TT_DFAULT] = "Data Access Fault",
+ [TT_TOVF] = "Tag Overflow",
+ [TT_EXTINT | 0x1] = "External Interrupt 1",
+ [TT_EXTINT | 0x2] = "External Interrupt 2",
+ [TT_EXTINT | 0x3] = "External Interrupt 3",
+ [TT_EXTINT | 0x4] = "External Interrupt 4",
+ [TT_EXTINT | 0x5] = "External Interrupt 5",
+ [TT_EXTINT | 0x6] = "External Interrupt 6",
+ [TT_EXTINT | 0x7] = "External Interrupt 7",
+ [TT_EXTINT | 0x8] = "External Interrupt 8",
+ [TT_EXTINT | 0x9] = "External Interrupt 9",
+ [TT_EXTINT | 0xa] = "External Interrupt 10",
+ [TT_EXTINT | 0xb] = "External Interrupt 11",
+ [TT_EXTINT | 0xc] = "External Interrupt 12",
+ [TT_EXTINT | 0xd] = "External Interrupt 13",
+ [TT_EXTINT | 0xe] = "External Interrupt 14",
+ [TT_EXTINT | 0xf] = "External Interrupt 15",
+ [TT_TOVF] = "Tag Overflow",
+ [TT_CODE_ACCESS] = "Instruction Access Error",
+ [TT_DATA_ACCESS] = "Data Access Error",
+ [TT_DIV_ZERO] = "Division By Zero",
+ [TT_NCP_INSN] = "Coprocessor Disabled",
+};
+#endif
+
+void do_interrupt(CPUState *env)
+{
+ int cwp, intno = env->exception_index;
+
+#ifdef DEBUG_PCALL
+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
+ static int count;
+ const char *name;
+
+ if (intno < 0 || intno >= 0x100) {
+ name = "Unknown";
+ } else if (intno >= 0x80) {
+ name = "Trap Instruction";
+ } else {
+ name = excp_names[intno];
+ if (!name) {
+ name = "Unknown";
+ }
+ }
+
+ qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
+ count, name, intno,
+ env->pc,
+ env->npc, env->regwptr[6]);
+ log_cpu_state(env, 0);
+#if 0
+ {
+ int i;
+ uint8_t *ptr;
+
+ qemu_log(" code=");
+ ptr = (uint8_t *)env->pc;
+ for (i = 0; i < 16; i++) {
+ qemu_log(" %02x", ldub(ptr + i));
+ }
+ qemu_log("\n");
+ }
+#endif
+ count++;
+ }
+#endif
+#if !defined(CONFIG_USER_ONLY)
+ if (env->psret == 0) {
+ cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
+ env->exception_index);
+ return;
+ }
+#endif
+ env->psret = 0;
+ cwp = cpu_cwp_dec(env, env->cwp - 1);
+ cpu_set_cwp(env, cwp);
+ env->regwptr[9] = env->pc;
+ env->regwptr[10] = env->npc;
+ env->psrps = env->psrs;
+ env->psrs = 1;
+ env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
+ env->pc = env->tbr;
+ env->npc = env->pc + 4;
+ env->exception_index = -1;
+
+#if !defined(CONFIG_USER_ONLY)
+ /* IRQ acknowledgment */
+ if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
+ env->qemu_irq_ack(env->irq_manager, intno);
+ }
+#endif
+}
+#endif
+
void cpu_reset(CPUSPARCState *env)
{
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
diff --git a/target-sparc/machine.c b/target-sparc/machine.c
index 752e431778..56ae0412cd 100644
--- a/target-sparc/machine.c
+++ b/target-sparc/machine.c
@@ -2,7 +2,7 @@
#include "hw/boards.h"
#include "qemu-timer.h"
-#include "exec-all.h"
+#include "cpu.h"
void cpu_save(QEMUFile *f, void *opaque)
{
@@ -45,6 +45,19 @@ void cpu_save(QEMUFile *f, void *opaque)
/* MMU */
for (i = 0; i < 32; i++)
qemu_put_be32s(f, &env->mmuregs[i]);
+ for (i = 0; i < 4; i++) {
+ qemu_put_be64s(f, &env->mxccdata[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ qemu_put_be64s(f, &env->mxccregs[i]);
+ }
+ qemu_put_be32s(f, &env->mmubpctrv);
+ qemu_put_be32s(f, &env->mmubpctrc);
+ qemu_put_be32s(f, &env->mmubpctrs);
+ qemu_put_be64s(f, &env->mmubpaction);
+ for (i = 0; i < 4; i++) {
+ qemu_put_be64s(f, &env->mmubpregs[i]);
+ }
#else
qemu_put_be64s(f, &env->lsu);
for (i = 0; i < 16; i++) {
@@ -141,6 +154,19 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
/* MMU */
for (i = 0; i < 32; i++)
qemu_get_be32s(f, &env->mmuregs[i]);
+ for (i = 0; i < 4; i++) {
+ qemu_get_be64s(f, &env->mxccdata[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ qemu_get_be64s(f, &env->mxccregs[i]);
+ }
+ qemu_get_be32s(f, &env->mmubpctrv);
+ qemu_get_be32s(f, &env->mmubpctrc);
+ qemu_get_be32s(f, &env->mmubpctrs);
+ qemu_get_be64s(f, &env->mmubpaction);
+ for (i = 0; i < 4; i++) {
+ qemu_get_be64s(f, &env->mmubpregs[i]);
+ }
#else
qemu_get_be64s(f, &env->lsu);
for (i = 0; i < 16; i++) {
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index b38691e19d..fd0cfbdb73 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -316,7 +316,7 @@ static inline target_ulong asi_address_mask(CPUState *env1,
static void raise_exception(int tt)
{
env->exception_index = tt;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void HELPER(raise_exception)(int tt)
@@ -1940,7 +1940,6 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
case 0x31: // Turbosparc RAM snoop
case 0x32: // Turbosparc page table descriptor diagnostic
case 0x39: /* data cache diagnostic register */
- case 0x4c: /* SuperSPARC MMU Breakpoint Action register */
ret = 0;
break;
case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
@@ -1966,6 +1965,18 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
ret);
}
break;
+ case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+ ret = env->mmubpctrv;
+ break;
+ case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+ ret = env->mmubpctrc;
+ break;
+ case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+ ret = env->mmubpctrs;
+ break;
+ case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+ ret = env->mmubpaction;
+ break;
case 8: /* User code access, XXX */
default:
do_unassigned_access(addr, 0, 0, asi, size);
@@ -2304,7 +2315,6 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
// descriptor diagnostic
case 0x36: /* I-cache flash clear */
case 0x37: /* D-cache flash clear */
- case 0x4c: /* breakpoint action */
break;
case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
{
@@ -2328,6 +2338,18 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
env->mmuregs[reg]);
}
break;
+ case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+ env->mmubpctrv = val & 0xffffffff;
+ break;
+ case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+ env->mmubpctrc = val & 0x3;
+ break;
+ case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+ env->mmubpctrs = val & 0x3;
+ break;
+ case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+ env->mmubpaction = val & 0x1fff;
+ break;
case 8: /* User code access, XXX */
case 9: /* Supervisor code access, XXX */
default:
@@ -3702,7 +3724,7 @@ void helper_ldxfsr(uint64_t new_fsr)
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#ifndef TARGET_SPARC64
@@ -4007,6 +4029,16 @@ void helper_wrpstate(target_ulong new_state)
#endif
}
+void cpu_change_pstate(CPUState *env1, uint32_t new_pstate)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ change_pstate(new_pstate);
+ env = saved_env;
+}
+
void helper_wrpil(target_ulong new_pil)
{
#if !defined(CONFIG_USER_ONLY)
@@ -4093,247 +4125,10 @@ void helper_write_softint(uint64_t value)
#endif
#ifdef TARGET_SPARC64
-#ifdef DEBUG_PCALL
-static const char * const excp_names[0x80] = {
- [TT_TFAULT] = "Instruction Access Fault",
- [TT_TMISS] = "Instruction Access MMU Miss",
- [TT_CODE_ACCESS] = "Instruction Access Error",
- [TT_ILL_INSN] = "Illegal Instruction",
- [TT_PRIV_INSN] = "Privileged Instruction",
- [TT_NFPU_INSN] = "FPU Disabled",
- [TT_FP_EXCP] = "FPU Exception",
- [TT_TOVF] = "Tag Overflow",
- [TT_CLRWIN] = "Clean Windows",
- [TT_DIV_ZERO] = "Division By Zero",
- [TT_DFAULT] = "Data Access Fault",
- [TT_DMISS] = "Data Access MMU Miss",
- [TT_DATA_ACCESS] = "Data Access Error",
- [TT_DPROT] = "Data Protection Error",
- [TT_UNALIGNED] = "Unaligned Memory Access",
- [TT_PRIV_ACT] = "Privileged Action",
- [TT_EXTINT | 0x1] = "External Interrupt 1",
- [TT_EXTINT | 0x2] = "External Interrupt 2",
- [TT_EXTINT | 0x3] = "External Interrupt 3",
- [TT_EXTINT | 0x4] = "External Interrupt 4",
- [TT_EXTINT | 0x5] = "External Interrupt 5",
- [TT_EXTINT | 0x6] = "External Interrupt 6",
- [TT_EXTINT | 0x7] = "External Interrupt 7",
- [TT_EXTINT | 0x8] = "External Interrupt 8",
- [TT_EXTINT | 0x9] = "External Interrupt 9",
- [TT_EXTINT | 0xa] = "External Interrupt 10",
- [TT_EXTINT | 0xb] = "External Interrupt 11",
- [TT_EXTINT | 0xc] = "External Interrupt 12",
- [TT_EXTINT | 0xd] = "External Interrupt 13",
- [TT_EXTINT | 0xe] = "External Interrupt 14",
- [TT_EXTINT | 0xf] = "External Interrupt 15",
-};
-#endif
-
trap_state* cpu_tsptr(CPUState* env)
{
return &env->ts[env->tl & MAXTL_MASK];
}
-
-void do_interrupt(CPUState *env)
-{
- int intno = env->exception_index;
- trap_state* tsptr;
-
-#ifdef DEBUG_PCALL
- if (qemu_loglevel_mask(CPU_LOG_INT)) {
- static int count;
- const char *name;
-
- if (intno < 0 || intno >= 0x180)
- name = "Unknown";
- else if (intno >= 0x100)
- name = "Trap Instruction";
- else if (intno >= 0xc0)
- name = "Window Fill";
- else if (intno >= 0x80)
- name = "Window Spill";
- else {
- name = excp_names[intno];
- if (!name)
- name = "Unknown";
- }
-
- qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
- " SP=%016" PRIx64 "\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
- log_cpu_state(env, 0);
-#if 0
- {
- int i;
- uint8_t *ptr;
-
- qemu_log(" code=");
- ptr = (uint8_t *)env->pc;
- for(i = 0; i < 16; i++) {
- qemu_log(" %02x", ldub(ptr + i));
- }
- qemu_log("\n");
- }
-#endif
- count++;
- }
-#endif
-#if !defined(CONFIG_USER_ONLY)
- if (env->tl >= env->maxtl) {
- cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
- " Error state", env->exception_index, env->tl, env->maxtl);
- return;
- }
-#endif
- if (env->tl < env->maxtl - 1) {
- env->tl++;
- } else {
- env->pstate |= PS_RED;
- if (env->tl < env->maxtl)
- env->tl++;
- }
- tsptr = cpu_tsptr(env);
-
- tsptr->tstate = (get_ccr() << 32) |
- ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
- get_cwp64();
- tsptr->tpc = env->pc;
- tsptr->tnpc = env->npc;
- tsptr->tt = intno;
-
- switch (intno) {
- case TT_IVEC:
- change_pstate(PS_PEF | PS_PRIV | PS_IG);
- break;
- case TT_TFAULT:
- case TT_DFAULT:
- case TT_TMISS ... TT_TMISS + 3:
- case TT_DMISS ... TT_DMISS + 3:
- case TT_DPROT ... TT_DPROT + 3:
- change_pstate(PS_PEF | PS_PRIV | PS_MG);
- break;
- default:
- change_pstate(PS_PEF | PS_PRIV | PS_AG);
- break;
- }
-
- if (intno == TT_CLRWIN) {
- set_cwp(cwp_dec(env->cwp - 1));
- } else if ((intno & 0x1c0) == TT_SPILL) {
- set_cwp(cwp_dec(env->cwp - env->cansave - 2));
- } else if ((intno & 0x1c0) == TT_FILL) {
- set_cwp(cwp_inc(env->cwp + 1));
- }
- env->tbr &= ~0x7fffULL;
- env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
- env->pc = env->tbr;
- env->npc = env->pc + 4;
- env->exception_index = -1;
-}
-#else
-#ifdef DEBUG_PCALL
-static const char * const excp_names[0x80] = {
- [TT_TFAULT] = "Instruction Access Fault",
- [TT_ILL_INSN] = "Illegal Instruction",
- [TT_PRIV_INSN] = "Privileged Instruction",
- [TT_NFPU_INSN] = "FPU Disabled",
- [TT_WIN_OVF] = "Window Overflow",
- [TT_WIN_UNF] = "Window Underflow",
- [TT_UNALIGNED] = "Unaligned Memory Access",
- [TT_FP_EXCP] = "FPU Exception",
- [TT_DFAULT] = "Data Access Fault",
- [TT_TOVF] = "Tag Overflow",
- [TT_EXTINT | 0x1] = "External Interrupt 1",
- [TT_EXTINT | 0x2] = "External Interrupt 2",
- [TT_EXTINT | 0x3] = "External Interrupt 3",
- [TT_EXTINT | 0x4] = "External Interrupt 4",
- [TT_EXTINT | 0x5] = "External Interrupt 5",
- [TT_EXTINT | 0x6] = "External Interrupt 6",
- [TT_EXTINT | 0x7] = "External Interrupt 7",
- [TT_EXTINT | 0x8] = "External Interrupt 8",
- [TT_EXTINT | 0x9] = "External Interrupt 9",
- [TT_EXTINT | 0xa] = "External Interrupt 10",
- [TT_EXTINT | 0xb] = "External Interrupt 11",
- [TT_EXTINT | 0xc] = "External Interrupt 12",
- [TT_EXTINT | 0xd] = "External Interrupt 13",
- [TT_EXTINT | 0xe] = "External Interrupt 14",
- [TT_EXTINT | 0xf] = "External Interrupt 15",
- [TT_TOVF] = "Tag Overflow",
- [TT_CODE_ACCESS] = "Instruction Access Error",
- [TT_DATA_ACCESS] = "Data Access Error",
- [TT_DIV_ZERO] = "Division By Zero",
- [TT_NCP_INSN] = "Coprocessor Disabled",
-};
-#endif
-
-void do_interrupt(CPUState *env)
-{
- int cwp, intno = env->exception_index;
-
-#ifdef DEBUG_PCALL
- if (qemu_loglevel_mask(CPU_LOG_INT)) {
- static int count;
- const char *name;
-
- if (intno < 0 || intno >= 0x100)
- name = "Unknown";
- else if (intno >= 0x80)
- name = "Trap Instruction";
- else {
- name = excp_names[intno];
- if (!name)
- name = "Unknown";
- }
-
- qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
- log_cpu_state(env, 0);
-#if 0
- {
- int i;
- uint8_t *ptr;
-
- qemu_log(" code=");
- ptr = (uint8_t *)env->pc;
- for(i = 0; i < 16; i++) {
- qemu_log(" %02x", ldub(ptr + i));
- }
- qemu_log("\n");
- }
-#endif
- count++;
- }
-#endif
-#if !defined(CONFIG_USER_ONLY)
- if (env->psret == 0) {
- cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
- env->exception_index);
- return;
- }
-#endif
- env->psret = 0;
- cwp = cwp_dec(env->cwp - 1);
- set_cwp(cwp);
- env->regwptr[9] = env->pc;
- env->regwptr[10] = env->npc;
- env->psrps = env->psrs;
- env->psrs = 1;
- env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
- env->pc = env->tbr;
- env->npc = env->pc + 4;
- env->exception_index = -1;
-
-#if !defined(CONFIG_USER_ONLY)
- /* IRQ acknowledgment */
- if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
- env->qemu_irq_ack(env->irq_manager, intno);
- }
-#endif
-}
#endif
#if !defined(CONFIG_USER_ONLY)
@@ -4402,7 +4197,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
if (ret) {
cpu_restore_state2(retaddr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 0cc47e9ff3..992cd77e72 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -25,7 +25,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "helper.h"
#include "tcg-op.h"
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 1e10049f89..981760734f 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -179,4 +179,10 @@ void uc32_translate_init(void);
void do_interrupt(CPUState *);
void switch_mode(CPUState_UniCore32 *, int);
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request &
+ (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
+}
+
#endif /* __CPU_UC32_H__ */
diff --git a/target-unicore32/exec.h b/target-unicore32/exec.h
index 4ab55f42cf..7912105e32 100644
--- a/target-unicore32/exec.h
+++ b/target-unicore32/exec.h
@@ -16,7 +16,6 @@
register struct CPUState_UniCore32 *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
static inline void env_to_regs(void)
{
@@ -26,12 +25,6 @@ static inline void regs_to_env(void)
{
}
-static inline int cpu_has_work(CPUState *env)
-{
- return env->interrupt_request &
- (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
-}
-
static inline int cpu_halted(CPUState *env)
{
if (!env->halted) {
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index 483aeaeb14..02707d5857 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -10,7 +10,6 @@
#include <string.h>
#include "cpu.h"
-#include "exec-all.h"
#include "gdbstub.h"
#include "helper.h"
#include "qemu-common.h"
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
index 31e4b11e43..541e6f099d 100644
--- a/target-unicore32/op_helper.c
+++ b/target-unicore32/op_helper.c
@@ -16,7 +16,7 @@
void HELPER(exception)(uint32_t excp)
{
env->exception_index = excp;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static target_ulong asr_read(void)
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 98eaeb3d43..a15e42d663 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -14,7 +14,6 @@
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index fb858d8634..93eb0f1a45 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1804,6 +1804,8 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
tcg_add_target_add_op_defs(arm_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
@@ -1846,15 +1848,18 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
static void tcg_target_qemu_prologue(TCGContext *s)
{
- /* There is no need to save r7, it is used to store the address
- of the env structure and is not modified by GCC. */
+ /* Calling convention requires us to save r4-r11 and lr;
+ * save also r12 to maintain stack 8-alignment.
+ */
+
+ /* stmdb sp!, { r4 - r12, lr } */
+ tcg_out32(s, (COND_AL << 28) | 0x092d5ff0);
- /* stmdb sp!, { r4 - r6, r8 - r11, lr } */
- tcg_out32(s, (COND_AL << 28) | 0x092d4f70);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
- tcg_out_bx(s, COND_AL, TCG_REG_R0);
+ tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
tb_ret_addr = s->code_ptr;
- /* ldmia sp!, { r4 - r6, r8 - r11, pc } */
- tcg_out32(s, (COND_AL << 28) | 0x08bd8f70);
+ /* ldmia sp!, { r4 - r12, pc } */
+ tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0);
}
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 7f4653e342..79bca630c5 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1596,7 +1596,7 @@ static int tcg_target_callee_save_regs[] = {
TCG_REG_R14,
TCG_REG_R15,
TCG_REG_R16,
- /* R17 is the global env, so no need to save. */
+ TCG_REG_R17, /* R17 is the global env. */
TCG_REG_R18
};
@@ -1635,8 +1635,10 @@ static void tcg_target_qemu_prologue(TCGContext *s)
}
#endif
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+
/* Jump to TB, and adjust R18 to be the return address. */
- tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26));
+ tcg_out32(s, INSN_BLE_SR4 | INSN_R2(tcg_target_call_iarg_regs[1]));
tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R18, TCG_REG_R31);
/* Restore callee saved registers. */
@@ -1680,4 +1682,6 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
tcg_add_target_add_op_defs(hppa_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index bb19a950bf..7529677fe2 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1398,7 +1398,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
/* Pop and discard. This is 2 bytes smaller than the add. */
tcg_out_pop(s, TCG_REG_ECX);
} else if (stack_adjust != 0) {
- tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
+ tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
}
/* label2: */
@@ -1901,10 +1901,10 @@ static int tcg_target_callee_save_regs[] = {
TCG_REG_RBX,
TCG_REG_R12,
TCG_REG_R13,
- /* TCG_REG_R14, */ /* Currently used for the global env. */
+ TCG_REG_R14, /* Currently used for the global env. */
TCG_REG_R15,
#else
- /* TCG_REG_EBP, */ /* Currently used for the global env. */
+ TCG_REG_EBP, /* Currently used for the global env. */
TCG_REG_EBX,
TCG_REG_ESI,
TCG_REG_EDI,
@@ -1918,28 +1918,34 @@ static void tcg_target_qemu_prologue(TCGContext *s)
/* TB prologue */
- /* Save all callee saved registers. */
- for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
- tcg_out_push(s, tcg_target_callee_save_regs[i]);
- }
-
- /* Reserve some stack space. */
+ /* Reserve some stack space, also for TCG temps. */
push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs);
push_size *= TCG_TARGET_REG_BITS / 8;
- frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
+ frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE +
+ CPU_TEMP_BUF_NLONGS * sizeof(long);
frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
stack_addend = frame_size - push_size;
+ tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
+
+ /* Save all callee saved registers. */
+ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+ tcg_out_push(s, tcg_target_callee_save_regs[i]);
+ }
+
tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+
/* jmp *tb. */
- tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]);
+ tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
/* TB epilogue */
tb_ret_addr = s->code_ptr;
- tcg_out_addi(s, TCG_REG_ESP, stack_addend);
+ tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
tcg_out_pop(s, tcg_target_callee_save_regs[i]);
@@ -1976,7 +1982,7 @@ static void tcg_target_init(TCGContext *s)
}
tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
tcg_add_target_add_op_defs(x86_op_defs);
}
diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 8dac7f72fd..6386a5bf27 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -2292,7 +2292,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34,
TCG_REG_R33, 32, 24, 0),
tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
- TCG_REG_B6, TCG_REG_R32, 0),
+ TCG_REG_B6, TCG_REG_R33, 0),
tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
TCG_REG_R32, TCG_REG_B0));
@@ -2308,7 +2308,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
}
tcg_out_bundle(s, miB,
- tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_m48(TCG_REG_P0, OPC_MOV_I21,
+ TCG_REG_AREG0, TCG_REG_R32, 0),
tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
TCG_REG_R12, -frame_size, TCG_REG_R12),
tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
@@ -2387,4 +2388,6 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
tcg_add_target_add_op_defs(ia64_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index e04b0dc32f..12ff9d5259 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1452,9 +1452,7 @@ static const TCGTargetOpDef mips_op_defs[] = {
};
static int tcg_target_callee_save_regs[] = {
-#if 0 /* used for the global env (TCG_AREG0), so no need to save */
- TCG_REG_S0,
-#endif
+ TCG_REG_S0, /* used for the global env (TCG_AREG0) */
TCG_REG_S1,
TCG_REG_S2,
TCG_REG_S3,
@@ -1486,8 +1484,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
}
/* Call generated code */
- tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0);
- tcg_out_nop(s);
+ tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1]), 0);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
tb_ret_addr = s->code_ptr;
/* TB epilogue */
@@ -1530,4 +1528,6 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
tcg_add_target_add_op_defs(mips_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 7970268e5a..dde4e18570 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -160,8 +160,7 @@ static const int tcg_target_callee_save_regs[] = {
TCG_REG_R24,
TCG_REG_R25,
TCG_REG_R26,
- /* TCG_REG_R27, */ /* currently used for the global env, so no
- need to save */
+ TCG_REG_R27, /* currently used for the global env */
TCG_REG_R28,
TCG_REG_R29,
TCG_REG_R30,
@@ -939,7 +938,8 @@ static void tcg_target_qemu_prologue (TCGContext *s)
}
#endif
- tcg_out32 (s, MTSPR | RS (3) | CTR);
+ tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+ tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
tcg_out32 (s, BCCTR | BO_ALWAYS);
tb_ret_addr = s->code_ptr;
@@ -1919,4 +1919,6 @@ static void tcg_target_init(TCGContext *s)
#endif
tcg_add_target_add_op_defs(ppc_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index ebbee343fd..32184387e5 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -151,8 +151,7 @@ static const int tcg_target_callee_save_regs[] = {
TCG_REG_R24,
TCG_REG_R25,
TCG_REG_R26,
- /* TCG_REG_R27, */ /* currently used for the global env, so no
- need to save */
+ TCG_REG_R27, /* currently used for the global env */
TCG_REG_R28,
TCG_REG_R29,
TCG_REG_R30,
@@ -905,7 +904,8 @@ static void tcg_target_qemu_prologue (TCGContext *s)
}
#endif
- tcg_out32 (s, MTSPR | RS (3) | CTR);
+ tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+ tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
tcg_out32 (s, BCCTR | BO_ALWAYS);
/* Epilogue */
@@ -1696,4 +1696,6 @@ static void tcg_target_init (TCGContext *s)
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
tcg_add_target_add_op_defs (ppc_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 450fcabd70..2fc5646400 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -2291,6 +2291,8 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
tcg_add_target_add_op_defs(s390_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
static void tcg_target_qemu_prologue(TCGContext *s)
@@ -2306,8 +2308,9 @@ static void tcg_target_qemu_prologue(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
}
- /* br %r2 (go to TB) */
- tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+ /* br %r3 (go to TB) */
+ tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
tb_ret_addr = s->code_ptr;
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 5f1353adf8..ac76e1198d 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -693,11 +693,14 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
/* Generate global QEMU prologue and epilogue code */
static void tcg_target_qemu_prologue(TCGContext *s)
{
+ tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET,
+ CPU_TEMP_BUF_NLONGS * (int)sizeof(long));
tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
- INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) |
+ INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
+ CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
+ tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
INSN_RS2(TCG_REG_G0));
- tcg_out_nop(s);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
}
#if defined(CONFIG_SOFTMMU)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 184c208980..c05413baa4 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -54,7 +54,6 @@
instructions */
#define NO_CPU_IO_DEFS
#include "cpu.h"
-#include "exec-all.h"
#include "tcg-op.h"
#include "elf.h"
@@ -1440,13 +1439,19 @@ static void temp_allocate_frame(TCGContext *s, int temp)
{
TCGTemp *ts;
ts = &s->temps[temp];
- s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
- if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
+#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
+ s->current_frame_offset = (s->current_frame_offset +
+ (tcg_target_long)sizeof(tcg_target_long) - 1) &
+ ~(sizeof(tcg_target_long) - 1);
+#endif
+ if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
+ s->frame_end) {
tcg_abort();
+ }
ts->mem_offset = s->current_frame_offset;
ts->mem_reg = s->frame_reg;
ts->mem_allocated = 1;
- s->current_frame_offset += sizeof(tcg_target_long);
+ s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
}
/* free register 'reg' by spilling the corresponding temporary if necessary */
@@ -1842,13 +1847,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
nb_regs = nb_params;
/* assign stack slots first */
- /* XXX: preallocate call stack */
call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
if (allocate_args) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
+ /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
+ preallocate call stack */
+ tcg_abort();
}
stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
@@ -1967,10 +1973,6 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
}
tcg_out_op(s, opc, &func_arg, &const_func_arg);
-
- if (allocate_args) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
- }
/* assign output registers and emit moves if needed */
for(i = 0; i < nb_oargs; i++) {
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 3647390c5f..a2dd8b892a 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -515,8 +515,9 @@ TCGv_i64 tcg_const_local_i64(int64_t val);
extern uint8_t code_gen_prologue[];
#if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
-#define tcg_qemu_tb_exec(tb_ptr) \
- ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
+#define tcg_qemu_tb_exec(env, tb_ptr) \
+ ((long REGPARM __attribute__ ((longcall)) (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
#else
-#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
+#define tcg_qemu_tb_exec(env, tb_ptr) \
+ ((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
#endif
diff --git a/translate-all.c b/translate-all.c
index 2ca190ca8f..041c108948 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -26,7 +26,6 @@
#define NO_CPU_IO_DEFS
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg.h"
#include "qemu-timer.h"
@@ -44,8 +43,6 @@ uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
void cpu_gen_init(void)
{
tcg_context_init(&tcg_ctx);
- tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
- CPU_TEMP_BUF_NLONGS * sizeof(long));
}
/* return non zero if the very first instruction is invalid so that
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 87fdf35d3e..5c02803411 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -28,7 +28,15 @@
#include "config-host.h"
+/* This needs to be before jpeglib.h line because of conflict with
+ INT32 definitions between jmorecfg.h (included by jpeglib.h) and
+ Win32 basetsd.h (included by windows.h). */
+#include "qemu-common.h"
+
#ifdef CONFIG_VNC_PNG
+/* The following define is needed by pngconf.h. Otherwise it won't compile,
+ because setjmp.h was already included by qemu-common.h. */
+#define PNG_SKIP_SETJMP_CHECK
#include <png.h>
#endif
#ifdef CONFIG_VNC_JPEG
@@ -36,8 +44,6 @@
#include <jpeglib.h>
#endif
-#include "qemu-common.h"
-
#include "bswap.h"
#include "qint.h"
#include "vnc.h"
diff --git a/user-exec.c b/user-exec.c
index d4a6abb8f5..02c2f8ba43 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -37,13 +37,14 @@
//#define DEBUG_SIGNAL
+static void exception_action(CPUState *env1)
+{
#if defined(TARGET_I386)
-#define EXCEPTION_ACTION \
- raise_exception_err(env->exception_index, env->error_code)
+ raise_exception_err(env1->exception_index, env1->error_code);
#else
-#define EXCEPTION_ACTION \
- cpu_loop_exit()
+ cpu_loop_exit(env1);
#endif
+}
/* exit the current TB from a signal handler. The host registers are
restored in a state compatible with the CPU emulator
@@ -118,7 +119,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
- EXCEPTION_ACTION;
+ exception_action(env);
/* never comes here */
return 1;
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
index 8a2380a151..90a994dc2c 100644
--- a/xen-mapcache-stub.c
+++ b/xen-mapcache-stub.c
@@ -8,7 +8,7 @@
#include "config.h"
-#include "exec-all.h"
+#include "cpu.h"
#include "qemu-common.h"
#include "cpu-common.h"
#include "xen-mapcache.h"