Merge remote-tracking branch 'stefanha/trivial-patches' into staging
diff --git a/Makefile.target b/Makefile.target index 03d3646..38afdb8 100644 --- a/Makefile.target +++ b/Makefile.target
@@ -14,7 +14,10 @@ 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 @@ # 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 += 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 0af8a7e..5f790b2 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 a311071..88159ac 100755 --- a/configure +++ b/configure
@@ -113,7 +113,7 @@ curses="" docs="" fdt="" -kvm="yes" +kvm="" nptl="" sdl="" vnc="yes" @@ -129,7 +129,7 @@ xen_ctrl_version="" linux_aio="" attr="" -vhost_net="yes" +vhost_net="" xfs="" gprof="no" @@ -457,6 +457,8 @@ 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 @@ 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 880f570..e839100 100644 --- a/cpu-all.h +++ b/cpu-all.h
@@ -847,7 +847,7 @@ 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 7aa1d00..20e3ec4 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ (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 @@ !(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 @@ 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 @@ 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 @@ } #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 @@ 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 @@ } 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 @@ #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 @@ #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 ded2100..abd24ab 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 d208c52..1334b8e 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 2a13a95..21a69d6 100644 --- a/exec-all.h +++ b/exec-all.h
@@ -40,6 +40,7 @@ #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 @@ 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 7236281..4c45299 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 b9ae30d..c085a5a 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 7a83cbe..252ea13 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 19d5bf8..4f279e7 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 43c441d..84da8fc 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 1e835c6..06064b9 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 71dd253..1c91c30 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 6af6a4d..67ceb46 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 e98b325..411bd55 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h
@@ -492,4 +492,26 @@ } #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 7a325e7..afb01d3 100644 --- a/target-alpha/exec.h +++ b/target-alpha/exec.h
@@ -31,30 +31,9 @@ #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 32c2cf9..7049c80 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 d332719..51d1bd7 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c
@@ -32,7 +32,7 @@ { 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 @@ 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 @@ 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 936760c..c61906a 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 01f5b57..116131e 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h
@@ -512,4 +512,17 @@ } } +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 db6608e..6793288 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 1208416..f4d12aa 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 8334fbc..4635884 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 @@ { 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 f5507ec..badbc5f 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 2bc35e4..ecb0df1 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h
@@ -268,4 +268,15 @@ #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 2d5d297..3294abe 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 2a4403b..962d214 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 1243745..d481e39 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 34329e2..b3ddd33 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c
@@ -83,7 +83,7 @@ helper_top_evaluate_flags(); } } - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } @@ -93,7 +93,7 @@ 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 e2607d6..dd85859 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 cdf68ff..9819b5f 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h
@@ -957,6 +957,36 @@ 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 @@ #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 @@ 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 9bd080e..dd9bce4 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h
@@ -33,48 +33,12 @@ #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 @@ #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 @@ (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 @@ 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 509d68c..e9be104 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 7662aa2..9aca8e0 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 cec0c76..315e18b 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 @@ { 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 @@ 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 @@ 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 @@ * 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 @@ #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 @@ 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 @@ #if defined(CONFIG_USER_ONLY) -void do_smm_enter(void) +void do_smm_enter(CPUState *env1) { } @@ -1375,11 +1416,15 @@ #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 @@ 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 @@ 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_debug(void) { env->exception_index = EXCP_DEBUG; - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_reset_rf(void) @@ -4859,6 +4905,10 @@ { } +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 @@ 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 @@ 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 @@ 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 @@ 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 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 @@ env->error_code = 0; env->old_exception = -1; - cpu_loop_exit(); + cpu_loop_exit(env); } #endif @@ -5575,6 +5635,18 @@ } } +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 10bd72a..ccef381 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 8e2d26b..876b5be 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h
@@ -241,4 +241,17 @@ *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 348b723..2a227b2 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 @@ } 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 4f3e7e0..e79428d 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 c72b1df..a34cecd 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 @@ 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 5e19725..0be105d 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 b025b66..e0f9b32 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h
@@ -119,7 +119,8 @@ 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 @@ | ((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 91daa6b..93e7912 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 faa8c42..a936fe7 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 9b13bdb..237fc4c 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) { - env->exception_index = -1; + env1->exception_index = -1; +} + +void do_interrupt_m68k_hardirq(CPUState *env1) +{ } #else @@ -71,7 +75,7 @@ cpu_restore_state(tb, env, pc); } } - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } @@ -90,7 +94,7 @@ 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 @@ } 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 @@ 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 26f0ee4..0e7f1fe 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 78fe14ff..51a13e3 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h
@@ -350,4 +350,17 @@ 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 1efff30..71b4d39 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 a623c7b..299259c 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 b38f7d9..281fc8d 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 c7b2f97..1a0a476 100644 --- a/target-microblaze/op_helper.c +++ b/target-microblaze/op_helper.c
@@ -63,7 +63,7 @@ cpu_restore_state(tb, env, pc); } } - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } @@ -107,7 +107,7 @@ 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 b47b92e..31e8306 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 0b98d10..b0ac4da 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h
@@ -656,4 +656,28 @@ 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 607edf1..e787e9a 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 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 0f057c2..ecf6182 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 9ffac71..be72b36 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 b8e4991..6b966b1 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c
@@ -38,7 +38,7 @@ #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 @@ 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 4eaa826..2848c6a 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 8e4582f..6d60d14 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h
@@ -1999,4 +1999,16 @@ 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 f87847a..f4453e4 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 @@ #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 cf2a368..395ea0e 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 15d9222..29f72e1 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c
@@ -44,7 +44,7 @@ #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 59aef85..0a03b44 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 b5e587f..d48a9b7 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h
@@ -962,4 +962,15 @@ 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 7a87fff..fb73f31 100644 --- a/target-s390x/exec.h +++ b/target-s390x/exec.h
@@ -23,18 +23,11 @@ #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 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 745d8c5..1ce7079 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 9429698..cd33f99 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 @@ cpu_restore_state(tb, env, pc); } } - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } @@ -90,7 +92,7 @@ { 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(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 @@ 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 @@ } 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 eda4624..77fb448 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 74ff97a..00e32f2 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h
@@ -361,4 +361,17 @@ | (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 9f1c1f6..4a6ae58 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 8f36d31..20e9b13 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 b909d18..a932225 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c
@@ -66,7 +66,7 @@ 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 @@ { 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_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 @@ 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 @@ 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 93c8636..569bc73 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 320530e..4edae78 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h
@@ -403,6 +403,8 @@ 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 @@ 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 @@ #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 @@ #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 f5c221e..2395b00 100644 --- a/target-sparc/exec.h +++ b/target-sparc/exec.h
@@ -12,20 +12,4 @@ #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 e9b42d0..7eea1ac 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 @@ } #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 752e431..56ae041 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 @@ /* 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 @@ /* 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 b38691e..fd0cfbd 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c
@@ -316,7 +316,7 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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_debug(void) { env->exception_index = EXCP_DEBUG; - cpu_loop_exit(); + cpu_loop_exit(env); } #ifndef TARGET_SPARC64 @@ -4007,6 +4029,16 @@ #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 @@ #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 @@ 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 0cc47e9..992cd77 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 1e10049..9817607 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h
@@ -179,4 +179,10 @@ 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 4ab55f4..7912105 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 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 483aeae..02707d5 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 31e4b11..541e6f0 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 98eaeb3..a15e42d 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 fb858d8..93eb0f1 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c
@@ -1804,6 +1804,8 @@ 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 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 - r6, r8 - r11, lr } */ - tcg_out32(s, (COND_AL << 28) | 0x092d4f70); + /* stmdb sp!, { r4 - r12, lr } */ + tcg_out32(s, (COND_AL << 28) | 0x092d5ff0); - tcg_out_bx(s, COND_AL, TCG_REG_R0); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + + 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 7f4653e..79bca63 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c
@@ -1596,7 +1596,7 @@ 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 @@ } #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 @@ 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 bb19a95..7529677 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c
@@ -1398,7 +1398,7 @@ /* 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 @@ 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 @@ /* TB prologue */ + /* 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 + + 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]); } - /* Reserve some stack space. */ - 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 = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & - ~(TCG_TARGET_STACK_ALIGN - 1); - stack_addend = frame_size - push_size; 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 @@ } 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 8dac7f7..6386a5b 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c
@@ -2292,7 +2292,7 @@ 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 @@ } 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 @@ 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 e04b0dc..12ff9d5 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c
@@ -1452,9 +1452,7 @@ }; 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 @@ } /* 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 @@ 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 7970268..dde4e18 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c
@@ -160,8 +160,7 @@ 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 @@ } #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 @@ #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 ebbee34..3218438 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c
@@ -151,8 +151,7 @@ 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 @@ } #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 @@ 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 450fcab..2fc5646 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c
@@ -2291,6 +2291,8 @@ 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 @@ 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 5f1353a..ac76e11 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c
@@ -693,11 +693,14 @@ /* 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 184c208..c05413b 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 @@ { 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 @@ 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 @@ } 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 3647390..a2dd8b8 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h
@@ -515,8 +515,9 @@ 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 2ca190c..041c108 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 @@ 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 87fdf35..5c02803 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 d4a6abb..02c2f8b 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 @@ /* 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 8a2380a..90a994d 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"