* [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 @ 2008-05-28 14:01 Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 1/6] remove REGWPTR Glauber Costa 2008-05-28 14:25 ` [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 Paul Brook 0 siblings, 2 replies; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:01 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Hi guys, here's a new spin of the patches I sent yesterday. It basically merges the comments I received, and adapts to the current state of the svn tree. Also, as Fabrice said multiple times inlining would be better, I'm taking a new approach, and instead of defining functions, I'm defining empty macros (for the general case), and archictectures that need it can then override. It results in substantially less code. Hope you like it, comments welcome ^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 1/6] remove REGWPTR 2008-05-28 14:01 [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 Glauber Costa @ 2008-05-28 14:01 ` Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 2/6] simplify cpu_exec Glauber Costa 2008-05-28 14:25 ` [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 Paul Brook 1 sibling, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:01 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Blue Swirl points out that it is not used anymore. Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-exec.c | 13 ------------- 1 files changed, 0 insertions(+), 13 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 5e64fa4..9b02447 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -247,11 +247,6 @@ int cpu_exec(CPUState *env1) { #define DECLARE_HOST_REGS 1 #include "hostregs_helper.h" -#if defined(TARGET_SPARC) -#if defined(reg_REGWPTR) - uint32_t *saved_regwptr; -#endif -#endif int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; @@ -274,9 +269,6 @@ int cpu_exec(CPUState *env1) CC_OP = CC_OP_EFLAGS; env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_SPARC) -#if defined(reg_REGWPTR) - saved_regwptr = REGWPTR; -#endif #elif defined(TARGET_M68K) env->cc_op = CC_OP_FLAGS; env->cc_dest = env->sr & 0xf; @@ -563,8 +555,6 @@ int cpu_exec(CPUState *env1) #elif defined(TARGET_ARM) cpu_dump_state(env, logfile, fprintf, 0); #elif defined(TARGET_SPARC) - REGWPTR = env->regbase + (env->cwp * 16); - env->regwptr = REGWPTR; cpu_dump_state(env, logfile, fprintf, 0); #elif defined(TARGET_PPC) cpu_dump_state(env, logfile, fprintf, 0); @@ -648,9 +638,6 @@ int cpu_exec(CPUState *env1) #elif defined(TARGET_ARM) /* XXX: Save/restore host fpu exception state?. */ #elif defined(TARGET_SPARC) -#if defined(reg_REGWPTR) - REGWPTR = saved_regwptr; -#endif #elif defined(TARGET_PPC) #elif defined(TARGET_M68K) cpu_m68k_flush_flags(env, env->cc_op); -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 2/6] simplify cpu_exec 2008-05-28 14:01 ` [Qemu-devel] [PATCH 1/6] remove REGWPTR Glauber Costa @ 2008-05-28 14:01 ` Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 3/6] Push common interrupt variables to cpu-defs.h Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:01 UTC (permalink / raw) To: qemu-devel; +Cc: kvm This is a first attempt to simplify cpu_exec(): it has simply too many ifdefs, which is not a very good practice at all. Following some work I've already posted in the past, I'm moving the target-b ifdefs to target-xxx/helper.c, encapsuled into relevant functions. Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-exec.c | 43 ++----------------------------------------- exec-all.h | 10 ++++++++++ target-i386/exec.h | 15 +++++++++++++++ target-m68k/exec.h | 16 ++++++++++++++++ 4 files changed, 43 insertions(+), 41 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 9b02447..af22e3c 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -262,27 +262,8 @@ int cpu_exec(CPUState *env1) env = env1; env_to_regs(); -#if defined(TARGET_I386) - /* put eflags in CPU temporary format */ - CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((env->eflags >> 10) & 1)); - CC_OP = CC_OP_EFLAGS; - env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); -#elif defined(TARGET_SPARC) -#elif defined(TARGET_M68K) - env->cc_op = CC_OP_FLAGS; - env->cc_dest = env->sr & 0xf; - env->cc_x = (env->sr >> 4) & 1; -#elif defined(TARGET_ALPHA) -#elif defined(TARGET_ARM) -#elif defined(TARGET_PPC) -#elif defined(TARGET_MIPS) -#elif defined(TARGET_SH4) -#elif defined(TARGET_CRIS) + cpu_load_flags(env); /* XXXXX */ -#else -#error unsupported target CPU -#endif env->exception_index = -1; /* prepare setjmp context for exception handling */ @@ -631,27 +612,7 @@ int cpu_exec(CPUState *env1) } } /* for(;;) */ - -#if defined(TARGET_I386) - /* restore flags in standard format */ - env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); -#elif defined(TARGET_ARM) - /* XXX: Save/restore host fpu exception state?. */ -#elif defined(TARGET_SPARC) -#elif defined(TARGET_PPC) -#elif defined(TARGET_M68K) - cpu_m68k_flush_flags(env, env->cc_op); - env->cc_op = CC_OP_FLAGS; - env->sr = (env->sr & 0xffe0) - | env->cc_dest | (env->cc_x << 4); -#elif defined(TARGET_MIPS) -#elif defined(TARGET_SH4) -#elif defined(TARGET_ALPHA) -#elif defined(TARGET_CRIS) - /* XXXXX */ -#else -#error unsupported target CPU -#endif + cpu_save_flags(env); /* restore global registers */ #include "hostregs_helper.h" diff --git a/exec-all.h b/exec-all.h index 51b27b5..0eea2f1 100644 --- a/exec-all.h +++ b/exec-all.h @@ -82,6 +82,16 @@ int cpu_restore_state_copy(struct TranslationBlock *tb, void *puc); void cpu_resume_from_signal(CPUState *env1, void *puc); void cpu_exec_init(CPUState *env); + +/* load flags for current execution. Architecture can override */ +#ifndef cpu_load_flags +#define cpu_load_flags(env) do {} while (0) +#endif +/* save flags after cpu execution. Architecture can override */ +#ifndef cpu_save_flags +#define cpu_save_flags(env) do {} while (0) +#endif + int page_unprotect(target_ulong address, unsigned long pc, void *puc); void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, int is_cpu_write_access); diff --git a/target-i386/exec.h b/target-i386/exec.h index 5e46c5a..38ee96b 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -31,6 +31,21 @@ register struct CPUX86State *env asm(AREG0); +#define cpu_load_flags(env) \ +do { \ + /* put eflags in CPU temporary format */ \ + CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); \ + DF = 1 - (2 * ((env->eflags >> 10) & 1)); \ + CC_OP = CC_OP_EFLAGS; \ + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);\ +} while (0) + +#define cpu_save_flags(env) \ +do { \ + /* restore flags in standard format */ \ + env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); \ +} while (0) + extern FILE *logfile; extern int loglevel; diff --git a/target-m68k/exec.h b/target-m68k/exec.h index 1269445..d4f51b3 100644 --- a/target-m68k/exec.h +++ b/target-m68k/exec.h @@ -26,6 +26,22 @@ register uint32_t T0 asm(AREG1); /* ??? We don't use T1, but common code expects it to exist */ #define T1 env->t1 +#define cpu_load_flags(env) \ +do { \ + env->cc_op = CC_OP_FLAGS; \ + env->cc_dest = env->sr & 0xf; \ + env->cc_x = (env->sr >> 4) & 1; \ +} while (0) + +#define cpu_save_flags(env) \ +do { \ + cpu_m68k_flush_flags(env, env->cc_op); \ + env->cc_op = CC_OP_FLAGS; \ + env->sr = (env->sr & 0xffe0) \ + | env->cc_dest | (env->cc_x << 4); \ +} while (0) + + #include "cpu.h" #include "exec-all.h" -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 3/6] Push common interrupt variables to cpu-defs.h 2008-05-28 14:01 ` [Qemu-devel] [PATCH 2/6] simplify cpu_exec Glauber Costa @ 2008-05-28 14:01 ` Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 4/6] use halted attribute for i386 too Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:01 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Some interrupt-related attributes, which includes the jmp_buf, are present in all, or almost all, architectures. So move them to common code in cpu-defs.h instead of replicating them everywhere Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-defs.h | 4 ++++ target-alpha/cpu.h | 2 -- target-arm/cpu.h | 2 -- target-cris/cpu.h | 2 -- target-i386/cpu.h | 2 -- target-m68k/cpu.h | 2 -- target-mips/cpu.h | 2 -- target-ppc/cpu.h | 2 -- target-sh4/cpu.h | 2 -- target-sparc/cpu.h | 2 -- 10 files changed, 4 insertions(+), 18 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index c4389ed..fe25703 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -159,6 +159,10 @@ typedef struct CPUTLBEntry { int nb_watchpoints; \ int watchpoint_hit; \ \ + /* Core interrupt code */ \ + jmp_buf jmp_env; \ + int exception_index; \ + \ void *next_cpu; /* next CPU sharing TB cache */ \ int cpu_index; /* CPU index (informative) */ \ /* user data */ \ diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index f8bbc70..a71bed1 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -282,12 +282,10 @@ struct CPUAlphaState { /* Those resources are used only in Qemu core */ CPU_COMMON - jmp_buf jmp_env; int user_mode_only; /* user mode only simulation */ uint32_t hflags; int halted; - int exception_index; int error_code; int interrupt_request; diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 2ff25a5..60a7a64 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -156,8 +156,6 @@ typedef struct CPUARMState { void *irq_opaque; /* exception/interrupt handling */ - jmp_buf jmp_env; - int exception_index; int interrupt_request; int user_mode_only; int halted; diff --git a/target-cris/cpu.h b/target-cris/cpu.h index a26dd80..d45abea 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -124,7 +124,6 @@ typedef struct CPUCRISState { int cc_x_live; int cc_x; - int exception_index; int interrupt_request; int interrupt_vector; int fault_vector; @@ -164,7 +163,6 @@ typedef struct CPUCRISState { int user_mode_only; int halted; - jmp_buf jmp_env; CPU_COMMON } CPUCRISState; diff --git a/target-i386/cpu.h b/target-i386/cpu.h index f23a782..dc6b56c 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -548,8 +548,6 @@ typedef struct CPUX86State { uint64_t pat; /* exception/interrupt handling */ - jmp_buf jmp_env; - int exception_index; int error_code; int exception_is_int; target_ulong exception_next_eip; diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index e8e3381..82d7558 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -104,8 +104,6 @@ typedef struct CPUM68KState { uint32_t t1; /* exception/interrupt handling */ - jmp_buf jmp_env; - int exception_index; int interrupt_request; int user_mode_only; uint32_t halted; diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 49b7e63..cf1d7aa 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -411,8 +411,6 @@ struct CPUMIPSState { int32_t CP0_DESAVE; /* Qemu */ int interrupt_request; - jmp_buf jmp_env; - int exception_index; int error_code; int user_mode_only; /* user mode only simulation */ uint32_t hflags; /* CPU State */ diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 7f7916f..b3dcc73 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -648,7 +648,6 @@ struct CPUPPCState { int bfd_mach; uint32_t flags; - int exception_index; int error_code; int interrupt_request; uint32_t pending_interrupts; @@ -674,7 +673,6 @@ struct CPUPPCState { opc_handler_t *opcodes[0x40]; /* Those resources are used only in Qemu core */ - jmp_buf jmp_env; int user_mode_only; /* user mode only simulation */ target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */ target_ulong hflags_nmsr; /* specific hflags, not comming from MSR */ diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 72ac82f..534ada3 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -114,11 +114,9 @@ typedef struct CPUSH4State { uint32_t expevt; /* exception event register */ uint32_t intevt; /* interrupt event register */ - jmp_buf jmp_env; int user_mode_only; int interrupt_request; int halted; - int exception_index; CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index af0ebd1..b663fe2 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -214,9 +214,7 @@ typedef struct CPUSPARCState { uint32_t pil_in; /* incoming interrupt level bitmap */ int psref; /* enable fpu */ target_ulong version; - jmp_buf jmp_env; int user_mode_only; - int exception_index; int interrupt_index; int interrupt_request; int halted; -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 4/6] use halted attribute for i386 too. 2008-05-28 14:01 ` [Qemu-devel] [PATCH 3/6] Push common interrupt variables to cpu-defs.h Glauber Costa @ 2008-05-28 14:01 ` Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 5/6] simply cpu_exec further Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:01 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Unlike other architectures, i386 lacked a "halted" attribute, going with a flag into hflags. By using the halted attribute, we can make the code look like more other architectures, and simplify the code in some instances. In this commit, we make the code for info_cpus simpler in monitor.c Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-defs.h | 2 ++ exec-all.h | 4 ++++ hw/apic.c | 4 ++-- hw/pc.c | 2 +- monitor.c | 23 +++++------------------ target-alpha/cpu.h | 1 - target-arm/cpu.h | 1 - target-cris/cpu.h | 1 - target-i386/exec.h | 6 ++++-- target-i386/helper.c | 8 +++++++- target-m68k/cpu.h | 1 - target-mips/cpu.h | 2 -- target-mips/exec.h | 2 ++ target-ppc/cpu.h | 2 -- target-ppc/exec.h | 1 + target-ppc/helper.c | 6 ++++++ target-sh4/cpu.h | 1 - target-sparc/cpu.h | 1 - target-sparc/exec.h | 2 ++ target-sparc/helper.c | 6 ++++++ 20 files changed, 42 insertions(+), 34 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index fe25703..bcfec91 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -163,6 +163,8 @@ typedef struct CPUTLBEntry { jmp_buf jmp_env; \ int exception_index; \ \ + int halted; \ + \ void *next_cpu; /* next CPU sharing TB cache */ \ int cpu_index; /* CPU index (informative) */ \ /* user data */ \ diff --git a/exec-all.h b/exec-all.h index 0eea2f1..9999761 100644 --- a/exec-all.h +++ b/exec-all.h @@ -92,6 +92,10 @@ void cpu_exec_init(CPUState *env); #define cpu_save_flags(env) do {} while (0) #endif +#ifndef cpu_info_ip +#define cpu_info_ip(env, buf) (0) +#endif + int page_unprotect(target_ulong address, unsigned long pc, void *puc); void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, int is_cpu_write_access); diff --git a/hw/apic.c b/hw/apic.c index a1ebf21..0dc9f8e 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -443,12 +443,12 @@ static void apic_init_ipi(APICState *s) static void apic_startup(APICState *s, int vector_num) { CPUState *env = s->cpu_env; - if (!(env->hflags & HF_HALTED_MASK)) + if (!(env->halted)) return; env->eip = 0; cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12, 0xffff, 0); - env->hflags &= ~HF_HALTED_MASK; + env->halted = 0; } static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, diff --git a/hw/pc.c b/hw/pc.c index c92384c..c68323b 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -761,7 +761,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, exit(1); } if (i != 0) - env->hflags |= HF_HALTED_MASK; + env->halted = 1; if (smp_cpus > 1) { /* XXX: enable it in all cases */ env->cpuid_features |= CPUID_APIC; diff --git a/monitor.c b/monitor.c index a0bf2ee..406f6d2 100644 --- a/monitor.c +++ b/monitor.c @@ -36,6 +36,8 @@ #include "disas.h" #include <dirent.h> +#include "exec-all.h" + #ifdef CONFIG_PROFILER #include "qemu-timer.h" /* for ticks_per_sec */ #endif @@ -304,6 +306,7 @@ static void do_info_registers(void) static void do_info_cpus(void) { CPUState *env; + char buf[1024]; /* just to set the default cpu if not already done */ mon_get_cpu(); @@ -312,24 +315,8 @@ static void do_info_cpus(void) term_printf("%c CPU #%d:", (env == mon_cpu) ? '*' : ' ', env->cpu_index); -#if defined(TARGET_I386) - term_printf(" pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base); - if (env->hflags & HF_HALTED_MASK) - term_printf(" (halted)"); -#elif defined(TARGET_PPC) - term_printf(" nip=0x" TARGET_FMT_lx, env->nip); - if (env->halted) - term_printf(" (halted)"); -#elif defined(TARGET_SPARC) - term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc); - if (env->halted) - term_printf(" (halted)"); -#elif defined(TARGET_MIPS) - term_printf(" PC=0x" TARGET_FMT_lx, env->PC[env->current_tc]); - if (env->halted) - term_printf(" (halted)"); -#endif - term_printf("\n"); + if (cpu_info_ip(env, buf)) + term_printf("%s %s\n", buf, env->halted ? "(halted)" : ""); } } diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index a71bed1..c955997 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -284,7 +284,6 @@ struct CPUAlphaState { int user_mode_only; /* user mode only simulation */ uint32_t hflags; - int halted; int error_code; int interrupt_request; diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 60a7a64..8d0558c 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -158,7 +158,6 @@ typedef struct CPUARMState { /* exception/interrupt handling */ int interrupt_request; int user_mode_only; - int halted; /* VFP coprocessor state. */ struct { diff --git a/target-cris/cpu.h b/target-cris/cpu.h index d45abea..acc1b5d 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -161,7 +161,6 @@ typedef struct CPUCRISState { int features; int user_mode_only; - int halted; CPU_COMMON } CPUCRISState; diff --git a/target-i386/exec.h b/target-i386/exec.h index 38ee96b..f2da292 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -46,6 +46,8 @@ do { env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); \ } while (0) +#define cpu_info_ip x86_cpu_info_ip + extern FILE *logfile; extern int loglevel; @@ -400,13 +402,13 @@ static inline void regs_to_env(void) static inline int cpu_halted(CPUState *env) { /* handle exit of HALTED state */ - if (!(env->hflags & HF_HALTED_MASK)) + if (!(env->halted)) return 0; /* disable halt condition */ if (((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK)) || (env->interrupt_request & CPU_INTERRUPT_NMI)) { - env->hflags &= ~HF_HALTED_MASK; + env->halted = 0; return 0; } return EXCP_HALTED; diff --git a/target-i386/helper.c b/target-i386/helper.c index cab085a..89c18ee 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -4550,7 +4550,7 @@ void helper_idivq_EAX(target_ulong t0) void helper_hlt(void) { env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ - env->hflags |= HF_HALTED_MASK; + env->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(); } @@ -4727,6 +4727,12 @@ void helper_clgi(void) env->hflags &= ~HF_GIF_MASK; } +int x86_cpu_info_ip(CPUState *env, char *buf) +{ + sprintf(buf, " pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base); + return 1; +} + #if defined(CONFIG_USER_ONLY) void helper_vmrun(void) diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 82d7558..d5c5a10 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -106,7 +106,6 @@ typedef struct CPUM68KState { /* exception/interrupt handling */ int interrupt_request; int user_mode_only; - uint32_t halted; int pending_vector; int pending_level; diff --git a/target-mips/cpu.h b/target-mips/cpu.h index cf1d7aa..51bafe7 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -446,8 +446,6 @@ struct CPUMIPSState { target_ulong btarget; /* Jump / branch target */ int bcond; /* Branch condition (if needed) */ - int halted; /* TRUE if the CPU is in suspend state */ - int SYNCI_Step; /* Address step size for SYNCI */ int CCRes; /* Cycle count resolution/divisor */ uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */ diff --git a/target-mips/exec.h b/target-mips/exec.h index f10a35d..35fbb11 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -41,6 +41,8 @@ register target_ulong T1 asm(AREG2); #define WTH2 (env->fpu->ft2.w[!FP_ENDIAN_IDX]) #endif +#define cpu_info_ip mips_cpu_info_ip + #include "cpu.h" #include "exec-all.h" diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index b3dcc73..a884fd6 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -586,8 +586,6 @@ struct CPUPPCState { CPU_COMMON - int halted; /* TRUE if the CPU is in suspend state */ - int access_type; /* when a memory exception occurs, the access type is stored here */ diff --git a/target-ppc/exec.h b/target-ppc/exec.h index 76fdb0b..fd07349 100644 --- a/target-ppc/exec.h +++ b/target-ppc/exec.h @@ -24,6 +24,7 @@ #include "dyngen-exec.h" +#define cpu_info_ip ppc_cpu_info_ip #include "cpu.h" #include "exec-all.h" diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 2a52dc6..2f83438 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2988,3 +2988,9 @@ void cpu_ppc_close (CPUPPCState *env) /* Should also remove all opcode tables... */ qemu_free(env); } + +int ppc_cpu_info_ip(CPUState *env, char *buf) +{ + sprintf(buf, " nip=0x" TARGET_FMT_lx, env->nip); + return 1; +} diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 534ada3..c03cdb1 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -116,7 +116,6 @@ typedef struct CPUSH4State { int user_mode_only; int interrupt_request; - int halted; CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index b663fe2..ba3ee01 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -217,7 +217,6 @@ typedef struct CPUSPARCState { int user_mode_only; int interrupt_index; int interrupt_request; - int halted; uint32_t mmu_bm; uint32_t mmu_ctpr_mask; uint32_t mmu_cxr_mask; diff --git a/target-sparc/exec.h b/target-sparc/exec.h index 3ef0cf9..cf51280 100644 --- a/target-sparc/exec.h +++ b/target-sparc/exec.h @@ -13,6 +13,8 @@ register struct CPUSPARCState *env asm(AREG0); #define QT0 (env->qt0) #define QT1 (env->qt1) +#define cpu_info_ip sparc_cpu_info_ip + #include "cpu.h" #include "exec-all.h" diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 8bf40e4..78a3fe5 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -1525,6 +1525,12 @@ void cpu_dump_state(CPUState *env, FILE *f, cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env)); } +int sparc_cpu_info_ip(CPUState *env, char *buf) +{ + sprintf(buf, " pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc); + return 1; +} + #ifdef TARGET_SPARC64 #if !defined(CONFIG_USER_ONLY) #include "qemu-common.h" -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 5/6] simply cpu_exec further 2008-05-28 14:01 ` [Qemu-devel] [PATCH 4/6] use halted attribute for i386 too Glauber Costa @ 2008-05-28 14:01 ` Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 6/6] cpu-exec-dump Glauber Costa 2008-05-28 18:03 ` [Qemu-devel] [PATCH 5/6] simply cpu_exec further Blue Swirl 0 siblings, 2 replies; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:01 UTC (permalink / raw) To: qemu-devel; +Cc: kvm We change interrupt functions so they have the same signature, getting only an env parameter. When necessary, some more attributed were added to the relevant CPUState to make it possible. Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-defs.h | 1 + cpu-exec.c | 198 +++++------------------------------------------ exec-all.h | 6 ++ target-alpha/helper.c | 9 ++ target-arm/helper.c | 27 +++++++ target-cris/helper.c | 9 ++ target-i386/exec.h | 5 +- target-i386/helper.c | 69 ++++++++++++++++- target-m68k/cpu.h | 2 +- target-m68k/helper.c | 16 ++++ target-m68k/op_helper.c | 8 +- target-mips/helper.c | 16 ++++ target-ppc/helper.c | 15 ++++ target-sh4/helper.c | 8 ++ target-sparc/helper.c | 23 ++++++ 15 files changed, 222 insertions(+), 190 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index bcfec91..742f24d 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -162,6 +162,7 @@ typedef struct CPUTLBEntry { /* Core interrupt code */ \ jmp_buf jmp_env; \ int exception_index; \ + int exception_is_hw; \ \ int halted; \ \ diff --git a/cpu-exec.c b/cpu-exec.c index af22e3c..46b0eb8 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -241,6 +241,21 @@ static inline TranslationBlock *tb_find_fast(void) return tb; } +void handle_interrupt_common(CPUState *env) +{ + if (env->interrupt_request & CPU_INTERRUPT_HALT) { + env->interrupt_request &= ~CPU_INTERRUPT_HALT; + env->halted = 1; + env->exception_index = EXCP_HLT; + cpu_loop_exit(); + } +} + +void reset_tb(void) +{ + next_tb = 0; +} + /* main execution loop */ int cpu_exec(CPUState *env1) @@ -281,43 +296,16 @@ 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_MIPS) - do_interrupt(env); -#elif defined(TARGET_SPARC) - do_interrupt(env); -#elif defined(TARGET_ARM) - do_interrupt(env); -#elif defined(TARGET_SH4) - do_interrupt(env); -#elif defined(TARGET_ALPHA) + env->exception_is_hw = 0; do_interrupt(env); -#elif defined(TARGET_CRIS) - do_interrupt(env); -#elif defined(TARGET_M68K) - do_interrupt(0); -#endif } env->exception_index = -1; } @@ -360,157 +348,9 @@ int cpu_exec(CPUState *env1) env->exception_index = EXCP_DEBUG; cpu_loop_exit(); } -#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ - defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) - if (interrupt_request & CPU_INTERRUPT_HALT) { - env->interrupt_request &= ~CPU_INTERRUPT_HALT; - env->halted = 1; - env->exception_index = EXCP_HLT; - cpu_loop_exit(); - } -#endif -#if defined(TARGET_I386) - if ((interrupt_request & CPU_INTERRUPT_SMI) && - !(env->hflags & HF_SMM_MASK)) { - svm_check_intercept(SVM_EXIT_SMI); - env->interrupt_request &= ~CPU_INTERRUPT_SMI; - do_smm_enter(); - next_tb = 0; - } else if ((interrupt_request & CPU_INTERRUPT_NMI) && - !(env->hflags & HF_NMI_MASK)) { - env->interrupt_request &= ~CPU_INTERRUPT_NMI; - env->hflags |= HF_NMI_MASK; - do_interrupt(EXCP02_NMI, 0, 0, 0, 1); - next_tb = 0; - } else if ((interrupt_request & CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && - !(env->hflags & HF_INHIBIT_IRQ_MASK)) { - int intno; - svm_check_intercept(SVM_EXIT_INTR); - env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); - intno = cpu_get_pic_interrupt(env); - if (loglevel & CPU_LOG_TB_IN_ASM) { - fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); - } - do_interrupt(intno, 0, 0, 0, 1); - /* ensure that no TB jump will be modified as - the program flow was changed */ - next_tb = 0; -#if !defined(CONFIG_USER_ONLY) - } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && - (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { - int intno; - /* FIXME: this should respect TPR */ - env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; - svm_check_intercept(SVM_EXIT_VINTR); - intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); - if (loglevel & CPU_LOG_TB_IN_ASM) - fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno); - do_interrupt(intno, 0, 0, -1, 1); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), - ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); - next_tb = 0; -#endif - } -#elif defined(TARGET_PPC) -#if 0 - if ((interrupt_request & CPU_INTERRUPT_RESET)) { - cpu_ppc_reset(env); - } -#endif - if (interrupt_request & CPU_INTERRUPT_HARD) { - ppc_hw_interrupt(env); - if (env->pending_interrupts == 0) - env->interrupt_request &= ~CPU_INTERRUPT_HARD; - next_tb = 0; - } -#elif defined(TARGET_MIPS) - if ((interrupt_request & CPU_INTERRUPT_HARD) && - (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && - (env->CP0_Status & (1 << CP0St_IE)) && - !(env->CP0_Status & (1 << CP0St_EXL)) && - !(env->CP0_Status & (1 << CP0St_ERL)) && - !(env->hflags & MIPS_HFLAG_DM)) { - /* Raise it */ - env->exception_index = EXCP_EXT_INTERRUPT; - env->error_code = 0; - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_SPARC) - if ((interrupt_request & CPU_INTERRUPT_HARD) && - (env->psret != 0)) { - int pil = env->interrupt_index & 15; - int type = env->interrupt_index & 0xf0; - - if (((type == TT_EXTINT) && - (pil == 15 || pil > env->psrpil)) || - type != TT_EXTINT) { - env->interrupt_request &= ~CPU_INTERRUPT_HARD; - env->exception_index = env->interrupt_index; - do_interrupt(env); - env->interrupt_index = 0; -#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) - cpu_check_irqs(env); -#endif - next_tb = 0; - } - } else if (interrupt_request & CPU_INTERRUPT_TIMER) { - //do_interrupt(0, 0, 0, 0, 0); - env->interrupt_request &= ~CPU_INTERRUPT_TIMER; - } -#elif defined(TARGET_ARM) - if (interrupt_request & CPU_INTERRUPT_FIQ - && !(env->uncached_cpsr & CPSR_F)) { - env->exception_index = EXCP_FIQ; - do_interrupt(env); - next_tb = 0; - } - /* ARMv7-M interrupt return works by loading a magic value - into the PC. On real hardware the load causes the - return to occur. The qemu implementation performs the - jump normally, then does the exception return when the - CPU tries to execute code at the magic address. - This will cause the magic PC value to be pushed to - the stack if an interrupt occured at the wrong time. - We avoid this by disabling interrupts when - pc contains a magic address. */ - if (interrupt_request & CPU_INTERRUPT_HARD - && ((IS_M(env) && env->regs[15] < 0xfffffff0) - || !(env->uncached_cpsr & CPSR_I))) { - env->exception_index = EXCP_IRQ; - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_SH4) - if (interrupt_request & CPU_INTERRUPT_HARD) { - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_ALPHA) - if (interrupt_request & CPU_INTERRUPT_HARD) { - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_CRIS) - if (interrupt_request & CPU_INTERRUPT_HARD) { - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_M68K) - if (interrupt_request & CPU_INTERRUPT_HARD - && ((env->sr & SR_I) >> SR_I_SHIFT) - < env->pending_level) { - /* Real hardware gets the interrupt vector via an - IACK cycle at this point. Current emulated - hardware doesn't rely on this, so we - provide/save the vector when the interrupt is - first signalled. */ - env->exception_index = env->pending_vector; - do_interrupt(1); - next_tb = 0; - } -#endif + + cpu_handle_interrupt_request(env); + /* Don't use the cached interupt_request value, do_interrupt may have updated the EXITTB flag. */ if (env->interrupt_request & CPU_INTERRUPT_EXITTB) { diff --git a/exec-all.h b/exec-all.h index 9999761..b9a9348 100644 --- a/exec-all.h +++ b/exec-all.h @@ -96,6 +96,12 @@ void cpu_exec_init(CPUState *env); #define cpu_info_ip(env, buf) (0) #endif +/* implemented by the targets */ +void cpu_handle_interrupt_request(CPUState *env); +/* implemented by cpu-exec.c */ +void handle_interrupt_common(CPUState *env); +void reset_tb(void); + int page_unprotect(target_ulong address, unsigned long pc, void *puc); void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, int is_cpu_write_access); diff --git a/target-alpha/helper.c b/target-alpha/helper.c index fd39f5f..3ffdc23 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -452,3 +452,12 @@ void cpu_dump_EA (target_ulong EA) f = stdout; fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA); } + +void cpu_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-arm/helper.c b/target-arm/helper.c index 8e85435..9326be2 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2522,3 +2522,30 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env) tmp = float32_scalbn(tmp, 31, s); return float32_to_int32(tmp, s); } + +void cpu_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if (env->interrupt_request & CPU_INTERRUPT_FIQ + && !(env->uncached_cpsr & CPSR_F)) { + env->exception_index = EXCP_FIQ; + do_interrupt(env); + reset_tb(); + } + /* ARMv7-M interrupt return works by loading a magic value + into the PC. On real hardware the load causes the + return to occur. The qemu implementation performs the + jump normally, then does the exception return when the + CPU tries to execute code at the magic address. + This will cause the magic PC value to be pushed to + the stack if an interrupt occured at the wrong time. + We avoid this by disabling interrupts when + pc contains a magic address. */ + if (env->interrupt_request & CPU_INTERRUPT_HARD + && ((IS_M(env) && env->regs[15] < 0xfffffff0) + || !(env->uncached_cpsr & CPSR_I))) { + env->exception_index = EXCP_IRQ; + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-cris/helper.c b/target-cris/helper.c index 5548b76..94d7660 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -183,3 +183,12 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) return phy; } #endif + +void cpu_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-i386/exec.h b/target-i386/exec.h index f2da292..2c96914 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -85,10 +85,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr); void __hidden cpu_lock(void); void __hidden cpu_unlock(void); -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 do_interrupt(CPUState *env); void raise_interrupt(int intno, int is_int, int error_code, int next_eip_addend); void raise_exception_err(int exception_index, int error_code); diff --git a/target-i386/helper.c b/target-i386/helper.c index 89c18ee..5e83efd 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1213,8 +1213,8 @@ void do_interrupt_user(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) +void do_interrupt_system(int intno, int is_int, int error_code, + target_ulong next_eip, int is_hw) { if (loglevel & CPU_LOG_INT) { if ((env->cr[0] & CR0_PE_MASK)) { @@ -1261,6 +1261,71 @@ void do_interrupt(int intno, int is_int, int error_code, } } +void do_interrupt(CPUState *env) +{ + if (env->user_mode_only) + do_interrupt_user(env->exception_index, + env->exception_is_int, + env->error_code, + env->exception_next_eip); + else + do_interrupt_system(env->exception_index, + env->exception_is_int, + env->error_code, + env->exception_next_eip, + env->exception_is_hw); + + env->old_exception = -1; +} + +void cpu_handle_interrupt_request(CPUState *env) +{ + int interrupt_request = env->interrupt_request; + int intno; + + if ((interrupt_request & CPU_INTERRUPT_SMI) && + !(env->hflags & HF_SMM_MASK)) { + svm_check_intercept(SVM_EXIT_SMI); + env->interrupt_request &= ~CPU_INTERRUPT_SMI; + do_smm_enter(); + reset_tb(); + } else if ((interrupt_request & CPU_INTERRUPT_NMI) && + !(env->hflags & HF_NMI_MASK)) { + env->interrupt_request &= ~CPU_INTERRUPT_NMI; + env->hflags |= HF_NMI_MASK; + do_interrupt_system(EXCP02_NMI, 0, 0, 0, 1); + reset_tb(); + } else if ((interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && + !(env->hflags & HF_INHIBIT_IRQ_MASK)) { + svm_check_intercept(SVM_EXIT_INTR); + env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); + intno = cpu_get_pic_interrupt(env); + if (loglevel & CPU_LOG_TB_IN_ASM) { + fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); + } + + do_interrupt_system(intno, 0, 0, 0, 1); + /* ensure that no TB jump will be modified as + the program flow was changed */ + reset_tb(); +#if !defined(CONFIG_USER_ONLY) + } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && + (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { + /* FIXME: this should respect TPR */ + env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; + svm_check_intercept(SVM_EXIT_VINTR); + intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); + if (loglevel & CPU_LOG_TB_IN_ASM) + fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno); + + do_interrupt_system(intno, 0, 0, -1, 1); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), + ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); + reset_tb(); +#endif + } +} /* * Check nested exceptions and change to double or triple fault if * needed. It should only be called, if this is not an interrupt. diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index d5c5a10..027ae61 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -121,7 +121,7 @@ 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(CPUM68KState *s); /* 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. */ diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 7f01392..f3e95d7 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -305,6 +305,22 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) return addr; } +void cpu_handle_interrupt_request(CPUState *env) +{ + if (env->interrupt_request & CPU_INTERRUPT_HARD + && ((env->sr & SR_I) >> SR_I_SHIFT) + < env->pending_level) { + /* Real hardware gets the interrupt vector via an + IACK cycle at this point. Current emulated + hardware doesn't rely on this, so we + provide/save the vector when the interrupt is + signalled. */ + env->exception_index = env->pending_vector; + env->exception_is_hw = 1; + do_interrupt(env); + reset_tb(); + } +} #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index f2e9f03..0233911 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -22,7 +22,7 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt(int is_hw) +void do_interrupt(CPUState *env) { env->exception_index = -1; } @@ -91,7 +91,7 @@ static void do_rte(void) env->aregs[7] = sp + 8; } -void do_interrupt(int is_hw) +void do_interrupt(CPUState *env) { uint32_t sp; uint32_t fmt; @@ -101,7 +101,7 @@ void do_interrupt(int is_hw) fmt = 0; retaddr = env->pc; - if (!is_hw) { + if (!env->exception_is_hw) { switch (env->exception_index) { case EXCP_RTE: /* Return from an exception. */ @@ -139,7 +139,7 @@ void do_interrupt(int is_hw) fmt |= env->sr; env->sr |= SR_S; - if (is_hw) { + if (env->exception_is_hw) { env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT); env->sr &= ~SR_M; } diff --git a/target-mips/helper.c b/target-mips/helper.c index b962295..5677a8e 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -583,6 +583,22 @@ void do_interrupt (CPUState *env) env->exception_index = EXCP_NONE; } +void cpu_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if ((env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && + (env->CP0_Status & (1 << CP0St_IE)) && + !(env->CP0_Status & (1 << CP0St_EXL)) && + !(env->CP0_Status & (1 << CP0St_ERL)) && + !(env->hflags & MIPS_HFLAG_DM)) { + /* Raise it */ + env->exception_index = EXCP_EXT_INTERRUPT; + env->error_code = 0; + do_interrupt(env); + reset_tb(); + } +} void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra) { r4k_tlb_t *tlb; diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 2f83438..38a6a34 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2994,3 +2994,18 @@ int ppc_cpu_info_ip(CPUState *env, char *buf) sprintf(buf, " nip=0x" TARGET_FMT_lx, env->nip); return 1; } + +void cpu_handle_interrupt_request(CPUState *env) +{ +#if 0 + if ((interrupt_request & CPU_INTERRUPT_RESET)) { + cpu_ppc_reset(env); + } +#endif + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + ppc_hw_interrupt(env); + if (env->pending_interrupts == 0) + env->interrupt_request &= ~CPU_INTERRUPT_HARD; + reset_tb(); + } +} diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 917f02f..71436cd 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -534,3 +534,11 @@ void cpu_load_tlb(CPUState * env) } #endif + +void cpu_handle_interrupt_request(CPUState *env) +{ + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 78a3fe5..68cf78c 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -866,6 +866,29 @@ void do_interrupt(CPUState *env) } #endif +void cpu_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if ((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->psret != 0)) { + int pil = env->interrupt_index & 15; + int type = env->interrupt_index & 0xf0; + + if (((type == TT_EXTINT) && + (pil == 15 || pil > env->psrpil)) || type != TT_EXTINT) { + env->interrupt_request &= ~CPU_INTERRUPT_HARD; + do_interrupt(env); + env->interrupt_index = 0; +#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) + cpu_check_irqs(env); +#endif + reset_tb(); + } + } else if (env->interrupt_request & CPU_INTERRUPT_TIMER) { + //do_interrupt(0, 0, 0, 0, 0); + env->interrupt_request &= ~CPU_INTERRUPT_TIMER; + } +} + void memcpy32(target_ulong *dst, const target_ulong *src) { dst[0] = src[0]; -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 6/6] cpu-exec-dump 2008-05-28 14:01 ` [Qemu-devel] [PATCH 5/6] simply cpu_exec further Glauber Costa @ 2008-05-28 14:01 ` Glauber Costa 2008-05-28 18:03 ` [Qemu-devel] [PATCH 5/6] simply cpu_exec further Blue Swirl 1 sibling, 0 replies; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:01 UTC (permalink / raw) To: qemu-devel; +Cc: kvm enclose the cpu dumping logic in cpu_exec() inside cpu_exec_dump() --- cpu-exec.c | 29 ++--------------------------- exec-all.h | 4 ++++ target-i386/exec.h | 2 ++ target-i386/helper.c | 6 ++++++ 4 files changed, 14 insertions(+), 27 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 46b0eb8..52d74f7 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -369,33 +369,8 @@ int cpu_exec(CPUState *env1) if ((loglevel & CPU_LOG_TB_CPU)) { /* restore flags in standard format */ regs_to_env(); -#if defined(TARGET_I386) - env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); - cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP); - env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); -#elif defined(TARGET_ARM) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_SPARC) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_PPC) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_M68K) - cpu_m68k_flush_flags(env, env->cc_op); - env->cc_op = CC_OP_FLAGS; - env->sr = (env->sr & 0xffe0) - | env->cc_dest | (env->cc_x << 4); - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_MIPS) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_SH4) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_ALPHA) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_CRIS) - cpu_dump_state(env, logfile, fprintf, 0); -#else -#error unsupported target CPU -#endif + cpu_save_flags(env); + cpu_exec_dump(env); } #endif tb = tb_find_fast(); diff --git a/exec-all.h b/exec-all.h index b9a9348..97b9f10 100644 --- a/exec-all.h +++ b/exec-all.h @@ -96,6 +96,10 @@ void cpu_exec_init(CPUState *env); #define cpu_info_ip(env, buf) (0) #endif +#ifndef cpu_exec_dump +#define cpu_exec_dump(env) cpu_dump_state(env, logfile, fprintf, 0) +#endif + /* implemented by the targets */ void cpu_handle_interrupt_request(CPUState *env); /* implemented by cpu-exec.c */ diff --git a/target-i386/exec.h b/target-i386/exec.h index 2c96914..ee36f5e 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -48,6 +48,8 @@ do { #define cpu_info_ip x86_cpu_info_ip +#define cpu_exec_dump x86_cpu_exec_dump + extern FILE *logfile; extern int loglevel; diff --git a/target-i386/helper.c b/target-i386/helper.c index 5e83efd..b10ebb8 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -4798,6 +4798,12 @@ int x86_cpu_info_ip(CPUState *env, char *buf) return 1; } +void x86_cpu_exec_dump(CPUState *env) +{ + cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP); + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); +} + #if defined(CONFIG_USER_ONLY) void helper_vmrun(void) -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 5/6] simply cpu_exec further 2008-05-28 14:01 ` [Qemu-devel] [PATCH 5/6] simply cpu_exec further Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 6/6] cpu-exec-dump Glauber Costa @ 2008-05-28 18:03 ` Blue Swirl 1 sibling, 0 replies; 12+ messages in thread From: Blue Swirl @ 2008-05-28 18:03 UTC (permalink / raw) To: qemu-devel; +Cc: kvm On 5/28/08, Glauber Costa <gcosta@redhat.com> wrote: > We change interrupt functions so they have the same > signature, getting only an env parameter. When necessary, > some more attributed were added to the relevant CPUState to > make it possible. > -#elif defined(TARGET_SPARC) > - if ((interrupt_request & CPU_INTERRUPT_HARD) && > - (env->psret != 0)) { > - int pil = env->interrupt_index & 15; > - int type = env->interrupt_index & 0xf0; > - > - if (((type == TT_EXTINT) && > - (pil == 15 || pil > env->psrpil)) || > - type != TT_EXTINT) { > - env->interrupt_request &= ~CPU_INTERRUPT_HARD; > - env->exception_index = env->interrupt_index; The above line, which I added in the previous commit is missing below. > - do_interrupt(env); > +/* implemented by the targets */ > +void cpu_handle_interrupt_request(CPUState *env); > +/* implemented by cpu-exec.c */ > +void handle_interrupt_common(CPUState *env); > +void reset_tb(void); Maybe also do_interrupt(CPUState *env) prototype could be better defined here to save space and to discourage making different versions. > diff --git a/target-sparc/helper.c b/target-sparc/helper.c > index 78a3fe5..68cf78c 100644 > --- a/target-sparc/helper.c > +++ b/target-sparc/helper.c > @@ -866,6 +866,29 @@ void do_interrupt(CPUState *env) > } > #endif > > +void cpu_handle_interrupt_request(CPUState *env) > +{ > + handle_interrupt_common(env); > + if ((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->psret != 0)) { > + int pil = env->interrupt_index & 15; > + int type = env->interrupt_index & 0xf0; > + > + if (((type == TT_EXTINT) && > + (pil == 15 || pil > env->psrpil)) || type != TT_EXTINT) { > + env->interrupt_request &= ~CPU_INTERRUPT_HARD; One line missing here. > + do_interrupt(env); ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 2008-05-28 14:01 [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 1/6] remove REGWPTR Glauber Costa @ 2008-05-28 14:25 ` Paul Brook 2008-05-28 14:44 ` Glauber Costa 1 sibling, 1 reply; 12+ messages in thread From: Paul Brook @ 2008-05-28 14:25 UTC (permalink / raw) To: qemu-devel; +Cc: kvm, Glauber Costa On Wednesday 28 May 2008, Glauber Costa wrote: > Hi guys, > > here's a new spin of the patches I sent yesterday. It basically merges the > comments I received, and adapts to the current state of the svn tree. > Also, as Fabrice said multiple times inlining would be better, I'm taking > a new approach, and instead of defining functions, I'm defining empty > macros (for the general case), and archictectures that need it can then > override. It results in substantially less code. I'm not so sure this is a good idea. IMHO using macros to implement functions is ugly. That's what inline functions are for :-) Providing a default implementation is also a fairly suspect idea. When adding a new target I like that we generate an error error when I forget to populate all of the target specific routines. The same applies when making changes to generic code, you're forced to go through every target and update them. Paul ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 2008-05-28 14:25 ` [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 Paul Brook @ 2008-05-28 14:44 ` Glauber Costa 0 siblings, 0 replies; 12+ messages in thread From: Glauber Costa @ 2008-05-28 14:44 UTC (permalink / raw) To: Paul Brook; +Cc: qemu-devel, kvm, Glauber Costa On Wed, May 28, 2008 at 11:25 AM, Paul Brook <paul@codesourcery.com> wrote: > On Wednesday 28 May 2008, Glauber Costa wrote: >> Hi guys, >> >> here's a new spin of the patches I sent yesterday. It basically merges the >> comments I received, and adapts to the current state of the svn tree. >> Also, as Fabrice said multiple times inlining would be better, I'm taking >> a new approach, and instead of defining functions, I'm defining empty >> macros (for the general case), and archictectures that need it can then >> override. It results in substantially less code. > > I'm not so sure this is a good idea. IMHO using macros to implement functions > is ugly. That's what inline functions are for :-) > > Providing a default implementation is also a fairly suspect idea. When adding > a new target I like that we generate an error error when I forget to populate > all of the target specific routines. The same applies when making changes to > generic code, you're forced to go through every target and update them. ok. If all the rest is fine, I can then switch back to the old model and resend it. > Paul > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Glauber Costa. "Free as in Freedom" http://glommer.net "The less confident you are, the more serious you have to act." ^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 0/6] simplify cpu-exec new spin @ 2008-05-27 15:18 Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 1/6] simplify cpu_exec Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-27 15:18 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Hi, This is an update on the previous series I sent that aims at simplifying cpu_exec. It fixes some bugs I've found myself, merge some comments from anthony, and goes a little bit further in enclosing functions. Comments welcome ^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 1/6] simplify cpu_exec 2008-05-27 15:18 [Qemu-devel] [PATCH 0/6] simplify cpu-exec new spin Glauber Costa @ 2008-05-27 15:18 ` Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 2/6] Push common interrupt variables to cpu-defs.h Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-27 15:18 UTC (permalink / raw) To: qemu-devel; +Cc: kvm This is a first attempt to simplify cpu_exec(): it has simply too many ifdefs, which is not a very good practice at all. Following some work I've already posted in the past, I'm moving the target-b ifdefs to target-xxx/helper.c, encapsuled into relevant functions. Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-exec.c | 54 +----------------------------------------------- exec-all.h | 4 +++ target-alpha/helper.c | 3 ++ target-arm/helper.c | 4 +++ target-cris/helper.c | 3 ++ target-i386/helper.c | 14 ++++++++++++ target-m68k/helper.c | 16 ++++++++++++++ target-mips/helper.c | 3 ++ target-ppc/helper.c | 3 ++ target-sh4/helper.c | 3 ++ target-sparc/helper.c | 17 +++++++++++++++ 11 files changed, 72 insertions(+), 52 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 65af9a6..a829b7b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -247,11 +247,6 @@ int cpu_exec(CPUState *env1) { #define DECLARE_HOST_REGS 1 #include "hostregs_helper.h" -#if defined(TARGET_SPARC) -#if defined(reg_REGWPTR) - uint32_t *saved_regwptr; -#endif -#endif int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; @@ -267,30 +262,8 @@ int cpu_exec(CPUState *env1) env = env1; env_to_regs(); -#if defined(TARGET_I386) - /* put eflags in CPU temporary format */ - CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((env->eflags >> 10) & 1)); - CC_OP = CC_OP_EFLAGS; - env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); -#elif defined(TARGET_SPARC) -#if defined(reg_REGWPTR) - saved_regwptr = REGWPTR; -#endif -#elif defined(TARGET_M68K) - env->cc_op = CC_OP_FLAGS; - env->cc_dest = env->sr & 0xf; - env->cc_x = (env->sr >> 4) & 1; -#elif defined(TARGET_ALPHA) -#elif defined(TARGET_ARM) -#elif defined(TARGET_PPC) -#elif defined(TARGET_MIPS) -#elif defined(TARGET_SH4) -#elif defined(TARGET_CRIS) + cpu_load_flags(env); /* XXXXX */ -#else -#error unsupported target CPU -#endif env->exception_index = -1; /* prepare setjmp context for exception handling */ @@ -640,30 +613,7 @@ int cpu_exec(CPUState *env1) } } /* for(;;) */ - -#if defined(TARGET_I386) - /* restore flags in standard format */ - env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); -#elif defined(TARGET_ARM) - /* XXX: Save/restore host fpu exception state?. */ -#elif defined(TARGET_SPARC) -#if defined(reg_REGWPTR) - REGWPTR = saved_regwptr; -#endif -#elif defined(TARGET_PPC) -#elif defined(TARGET_M68K) - cpu_m68k_flush_flags(env, env->cc_op); - env->cc_op = CC_OP_FLAGS; - env->sr = (env->sr & 0xffe0) - | env->cc_dest | (env->cc_x << 4); -#elif defined(TARGET_MIPS) -#elif defined(TARGET_SH4) -#elif defined(TARGET_ALPHA) -#elif defined(TARGET_CRIS) - /* XXXXX */ -#else -#error unsupported target CPU -#endif + cpu_put_flags(env); /* restore global registers */ #include "hostregs_helper.h" diff --git a/exec-all.h b/exec-all.h index 51b27b5..fd2164f 100644 --- a/exec-all.h +++ b/exec-all.h @@ -82,6 +82,10 @@ int cpu_restore_state_copy(struct TranslationBlock *tb, void *puc); void cpu_resume_from_signal(CPUState *env1, void *puc); void cpu_exec_init(CPUState *env); + +void cpu_load_flags(CPUState *env); +void cpu_put_flags(CPUState *env); + int page_unprotect(target_ulong address, unsigned long pc, void *puc); void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, int is_cpu_write_access); diff --git a/target-alpha/helper.c b/target-alpha/helper.c index fd39f5f..73d565f 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -452,3 +452,6 @@ void cpu_dump_EA (target_ulong EA) f = stdout; fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA); } + +void cpu_load_flags(CPUState *env) {} +void cpu_put_flags(CPUState *env) {} diff --git a/target-arm/helper.c b/target-arm/helper.c index 8e85435..496f326 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2522,3 +2522,7 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env) tmp = float32_scalbn(tmp, 31, s); return float32_to_int32(tmp, s); } + +void cpu_load_flags(CPUState *env) { } +/* XXX: Save/restore host fpu exception state?. */ +void cpu_put_flags(CPUState *env) { } diff --git a/target-cris/helper.c b/target-cris/helper.c index 5548b76..1e216aa 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -183,3 +183,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) return phy; } #endif + +void cpu_load_flags(CPUState *env) {} +void cpu_put_flags(CPUState *env) {} diff --git a/target-i386/helper.c b/target-i386/helper.c index 5322491..1d88a9e 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -4668,6 +4668,20 @@ void helper_clgi(void) { env->hflags &= ~HF_GIF_MASK; } +void cpu_load_flags(CPUState *env) +{ + /* put eflags in CPU temporary format */ + CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + DF = 1 - (2 * ((env->eflags >> 10) & 1)); + CC_OP = CC_OP_EFLAGS; + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); +} + +void cpu_put_flags(CPUState *env) +{ + /* restore flags in standard format */ + env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); +} #if defined(CONFIG_USER_ONLY) diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 848c589..73e93bc 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -339,6 +339,21 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) return addr; } +void cpu_load_flags(CPUState *env) +{ + env->cc_op = CC_OP_FLAGS; + env->cc_dest = env->sr & 0xf; + env->cc_x = (env->sr >> 4) & 1; +} + +void cpu_put_flags(CPUState *env) +{ + cpu_m68k_flush_flags(env, env->cc_op); + env->cc_op = CC_OP_FLAGS; + env->sr = (env->sr & 0xffe0) + | env->cc_dest | (env->cc_x << 4); +} + #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -376,3 +391,4 @@ void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector) } #endif + diff --git a/target-mips/helper.c b/target-mips/helper.c index b962295..90e6dbe 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -636,3 +636,6 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra) } } } + +void cpu_put_flags(CPUState *env) { } +void cpu_load_flags(CPUState *env) { } diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 2a52dc6..300532f 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2988,3 +2988,6 @@ void cpu_ppc_close (CPUPPCState *env) /* Should also remove all opcode tables... */ qemu_free(env); } + +void cpu_load_flags(CPUState *env) { } +void cpu_put_flags(CPUState *env) { } diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 917f02f..ebc16ac 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -534,3 +534,6 @@ void cpu_load_tlb(CPUState * env) } #endif + +void cpu_load_flags(CPUState *env) {} +void cpu_put_flags(CPUState *env) {} diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 1bc2fed..76c68fa 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -1316,6 +1316,23 @@ void cpu_dump_state(CPUState *env, FILE *f, cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env)); } +#if defined(reg_REGWPTR) +static uint32_t *saved_regwptr; +#endif + +void cpu_load_flags(CPUState *env) +{ +#if defined(reg_REGWPTR) + saved_regwptr = REGWPTR; +#endif +} + +void cpu_put_flags(CPUState *env) +{ +#if defined(reg_REGWPTR) + REGWPTR = saved_regwptr; +#endif +} #ifdef TARGET_SPARC64 #if !defined(CONFIG_USER_ONLY) #include "qemu-common.h" -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 2/6] Push common interrupt variables to cpu-defs.h 2008-05-27 15:18 ` [Qemu-devel] [PATCH 1/6] simplify cpu_exec Glauber Costa @ 2008-05-27 15:18 ` Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 3/6] use halted attribute for i386 too Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-27 15:18 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Some interrupt-related attributes, which includes the jmp_buf, are present in all, or almost all, architectures. So move them to common code in cpu-defs.h instead of replicating them everywhere Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-defs.h | 5 +++++ target-alpha/cpu.h | 3 --- target-arm/cpu.h | 2 -- target-cris/cpu.h | 2 -- target-i386/cpu.h | 3 --- target-m68k/cpu.h | 2 -- target-mips/cpu.h | 3 --- target-ppc/cpu.h | 3 --- target-sh4/cpu.h | 2 -- target-sparc/cpu.h | 2 -- 10 files changed, 5 insertions(+), 22 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index c4389ed..bb00c80 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -159,6 +159,11 @@ typedef struct CPUTLBEntry { int nb_watchpoints; \ int watchpoint_hit; \ \ + /* Core interrupt code */ \ + jmp_buf jmp_env; \ + int exception_index; \ + int error_code; \ + \ void *next_cpu; /* next CPU sharing TB cache */ \ int cpu_index; /* CPU index (informative) */ \ /* user data */ \ diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index f8bbc70..b3c10d7 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -282,13 +282,10 @@ struct CPUAlphaState { /* Those resources are used only in Qemu core */ CPU_COMMON - jmp_buf jmp_env; int user_mode_only; /* user mode only simulation */ uint32_t hflags; int halted; - int exception_index; - int error_code; int interrupt_request; uint32_t features; diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 2ff25a5..60a7a64 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -156,8 +156,6 @@ typedef struct CPUARMState { void *irq_opaque; /* exception/interrupt handling */ - jmp_buf jmp_env; - int exception_index; int interrupt_request; int user_mode_only; int halted; diff --git a/target-cris/cpu.h b/target-cris/cpu.h index a26dd80..d45abea 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -124,7 +124,6 @@ typedef struct CPUCRISState { int cc_x_live; int cc_x; - int exception_index; int interrupt_request; int interrupt_vector; int fault_vector; @@ -164,7 +163,6 @@ typedef struct CPUCRISState { int user_mode_only; int halted; - jmp_buf jmp_env; CPU_COMMON } CPUCRISState; diff --git a/target-i386/cpu.h b/target-i386/cpu.h index eb784b4..c8a4559 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -553,9 +553,6 @@ typedef struct CPUX86State { uint64_t pat; /* exception/interrupt handling */ - jmp_buf jmp_env; - int exception_index; - int error_code; int exception_is_int; target_ulong exception_next_eip; target_ulong dr[8]; /* debug registers */ diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 732929b..ba36387 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -104,8 +104,6 @@ typedef struct CPUM68KState { uint32_t t1; /* exception/interrupt handling */ - jmp_buf jmp_env; - int exception_index; int interrupt_request; int user_mode_only; int halted; diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 49b7e63..08aad3e 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -411,9 +411,6 @@ struct CPUMIPSState { int32_t CP0_DESAVE; /* Qemu */ int interrupt_request; - jmp_buf jmp_env; - int exception_index; - int error_code; int user_mode_only; /* user mode only simulation */ uint32_t hflags; /* CPU State */ /* TMASK defines different execution modes */ diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 7f7916f..e9f9287 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -648,8 +648,6 @@ struct CPUPPCState { int bfd_mach; uint32_t flags; - int exception_index; - int error_code; int interrupt_request; uint32_t pending_interrupts; #if !defined(CONFIG_USER_ONLY) @@ -674,7 +672,6 @@ struct CPUPPCState { opc_handler_t *opcodes[0x40]; /* Those resources are used only in Qemu core */ - jmp_buf jmp_env; int user_mode_only; /* user mode only simulation */ target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */ target_ulong hflags_nmsr; /* specific hflags, not comming from MSR */ diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 72ac82f..534ada3 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -114,11 +114,9 @@ typedef struct CPUSH4State { uint32_t expevt; /* exception event register */ uint32_t intevt; /* interrupt event register */ - jmp_buf jmp_env; int user_mode_only; int interrupt_request; int halted; - int exception_index; CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index af0ebd1..b663fe2 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -214,9 +214,7 @@ typedef struct CPUSPARCState { uint32_t pil_in; /* incoming interrupt level bitmap */ int psref; /* enable fpu */ target_ulong version; - jmp_buf jmp_env; int user_mode_only; - int exception_index; int interrupt_index; int interrupt_request; int halted; -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 3/6] use halted attribute for i386 too. 2008-05-27 15:18 ` [Qemu-devel] [PATCH 2/6] Push common interrupt variables to cpu-defs.h Glauber Costa @ 2008-05-27 15:18 ` Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 4/6] simply cpu_exec further Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-27 15:18 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Unlike other architectures, i386 lacked a "halted" attribute, going with a flag into hflags. By using the halted attribute, we can make the code look like more other architectures, and simplify the code in some instances. In this commit, we make the code for info_cpus simpler in monitor.c Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-defs.h | 2 ++ exec-all.h | 1 + hw/apic.c | 4 ++-- hw/pc.c | 2 +- monitor.c | 23 +++++------------------ target-alpha/cpu.h | 1 - target-alpha/helper.c | 1 + target-arm/cpu.h | 1 - target-arm/helper.c | 1 + target-cris/cpu.h | 1 - target-cris/helper.c | 1 + target-i386/exec.h | 4 ++-- target-i386/helper.c | 9 ++++++++- target-m68k/cpu.h | 1 - target-m68k/helper.c | 1 + target-mips/cpu.h | 2 -- target-mips/helper.c | 6 ++++++ target-ppc/cpu.h | 2 -- target-ppc/helper.c | 6 ++++++ target-sh4/cpu.h | 1 - target-sh4/helper.c | 1 + target-sparc/cpu.h | 1 - target-sparc/helper.c | 6 ++++++ 23 files changed, 44 insertions(+), 34 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index bb00c80..5bcd1ee 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -164,6 +164,8 @@ typedef struct CPUTLBEntry { int exception_index; \ int error_code; \ \ + int halted; \ + \ void *next_cpu; /* next CPU sharing TB cache */ \ int cpu_index; /* CPU index (informative) */ \ /* user data */ \ diff --git a/exec-all.h b/exec-all.h index fd2164f..fd1ea6a 100644 --- a/exec-all.h +++ b/exec-all.h @@ -83,6 +83,7 @@ int cpu_restore_state_copy(struct TranslationBlock *tb, void cpu_resume_from_signal(CPUState *env1, void *puc); void cpu_exec_init(CPUState *env); +extern int cpu_info_ip(CPUState *env, char *buf); void cpu_load_flags(CPUState *env); void cpu_put_flags(CPUState *env); diff --git a/hw/apic.c b/hw/apic.c index a1ebf21..0dc9f8e 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -443,12 +443,12 @@ static void apic_init_ipi(APICState *s) static void apic_startup(APICState *s, int vector_num) { CPUState *env = s->cpu_env; - if (!(env->hflags & HF_HALTED_MASK)) + if (!(env->halted)) return; env->eip = 0; cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12, 0xffff, 0); - env->hflags &= ~HF_HALTED_MASK; + env->halted = 0; } static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, diff --git a/hw/pc.c b/hw/pc.c index c92384c..c68323b 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -761,7 +761,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, exit(1); } if (i != 0) - env->hflags |= HF_HALTED_MASK; + env->halted = 1; if (smp_cpus > 1) { /* XXX: enable it in all cases */ env->cpuid_features |= CPUID_APIC; diff --git a/monitor.c b/monitor.c index 236b827..f34d147 100644 --- a/monitor.c +++ b/monitor.c @@ -36,6 +36,8 @@ #include "disas.h" #include <dirent.h> +#include "exec-all.h" + #ifdef CONFIG_PROFILER #include "qemu-timer.h" /* for ticks_per_sec */ #endif @@ -304,6 +306,7 @@ static void do_info_registers(void) static void do_info_cpus(void) { CPUState *env; + char buf[1024]; /* just to set the default cpu if not already done */ mon_get_cpu(); @@ -312,24 +315,8 @@ static void do_info_cpus(void) term_printf("%c CPU #%d:", (env == mon_cpu) ? '*' : ' ', env->cpu_index); -#if defined(TARGET_I386) - term_printf(" pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base); - if (env->hflags & HF_HALTED_MASK) - term_printf(" (halted)"); -#elif defined(TARGET_PPC) - term_printf(" nip=0x" TARGET_FMT_lx, env->nip); - if (env->halted) - term_printf(" (halted)"); -#elif defined(TARGET_SPARC) - term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc); - if (env->halted) - term_printf(" (halted)"); -#elif defined(TARGET_MIPS) - term_printf(" PC=0x" TARGET_FMT_lx, env->PC[env->current_tc]); - if (env->halted) - term_printf(" (halted)"); -#endif - term_printf("\n"); + if (cpu_info_ip(env, buf)) + term_printf("%s %s\n", buf, env->halted ? "(halted)" : ""); } } diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index b3c10d7..dc2460a 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -284,7 +284,6 @@ struct CPUAlphaState { int user_mode_only; /* user mode only simulation */ uint32_t hflags; - int halted; int interrupt_request; diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 73d565f..6056d6c 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -453,5 +453,6 @@ void cpu_dump_EA (target_ulong EA) fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA); } +int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 60a7a64..8d0558c 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -158,7 +158,6 @@ typedef struct CPUARMState { /* exception/interrupt handling */ int interrupt_request; int user_mode_only; - int halted; /* VFP coprocessor state. */ struct { diff --git a/target-arm/helper.c b/target-arm/helper.c index 496f326..6724909 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2523,6 +2523,7 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env) return float32_to_int32(tmp, s); } +int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) { } /* XXX: Save/restore host fpu exception state?. */ void cpu_put_flags(CPUState *env) { } diff --git a/target-cris/cpu.h b/target-cris/cpu.h index d45abea..acc1b5d 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -161,7 +161,6 @@ typedef struct CPUCRISState { int features; int user_mode_only; - int halted; CPU_COMMON } CPUCRISState; diff --git a/target-cris/helper.c b/target-cris/helper.c index 1e216aa..0ed169c 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -184,5 +184,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) } #endif +int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} diff --git a/target-i386/exec.h b/target-i386/exec.h index 8597e79..f6517ce 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -425,13 +425,13 @@ static inline void regs_to_env(void) static inline int cpu_halted(CPUState *env) { /* handle exit of HALTED state */ - if (!(env->hflags & HF_HALTED_MASK)) + if (!(env->halted)) return 0; /* disable halt condition */ if (((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK)) || (env->interrupt_request & CPU_INTERRUPT_NMI)) { - env->hflags &= ~HF_HALTED_MASK; + env->halted = 0; return 0; } return EXCP_HALTED; diff --git a/target-i386/helper.c b/target-i386/helper.c index 1d88a9e..7e690de 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -4487,7 +4487,7 @@ void helper_idivq_EAX(target_ulong t0) void helper_hlt(void) { env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ - env->hflags |= HF_HALTED_MASK; + env->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(); } @@ -4668,6 +4668,13 @@ void helper_clgi(void) { env->hflags &= ~HF_GIF_MASK; } + +int cpu_info_ip(CPUState *env, char *buf) +{ + sprintf(buf, " pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base); + return 1; +} + void cpu_load_flags(CPUState *env) { /* put eflags in CPU temporary format */ diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index ba36387..e8c1dfc 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -106,7 +106,6 @@ typedef struct CPUM68KState { /* exception/interrupt handling */ int interrupt_request; int user_mode_only; - int halted; int pending_vector; int pending_level; diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 73e93bc..82b5576 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -339,6 +339,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) return addr; } +int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) { env->cc_op = CC_OP_FLAGS; diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 08aad3e..38ae0b4 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -445,8 +445,6 @@ struct CPUMIPSState { target_ulong btarget; /* Jump / branch target */ int bcond; /* Branch condition (if needed) */ - int halted; /* TRUE if the CPU is in suspend state */ - int SYNCI_Step; /* Address step size for SYNCI */ int CCRes; /* Cycle count resolution/divisor */ uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */ diff --git a/target-mips/helper.c b/target-mips/helper.c index 90e6dbe..81a1a6b 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -637,5 +637,11 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra) } } +int cpu_info_ip(CPUState *env, char *buf) +{ + sprintf(buf, " PC=0x" TARGET_FMT_lx, env->PC[env->current_tc]); + return 1; +} + void cpu_put_flags(CPUState *env) { } void cpu_load_flags(CPUState *env) { } diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index e9f9287..a1f90e2 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -586,8 +586,6 @@ struct CPUPPCState { CPU_COMMON - int halted; /* TRUE if the CPU is in suspend state */ - int access_type; /* when a memory exception occurs, the access type is stored here */ diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 300532f..2858780 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2989,5 +2989,11 @@ void cpu_ppc_close (CPUPPCState *env) qemu_free(env); } +int cpu_info_ip(CPUState *env, char *buf) +{ + sprintf(buf, " nip=0x" TARGET_FMT_lx, env->nip); + return 1; +} + void cpu_load_flags(CPUState *env) { } void cpu_put_flags(CPUState *env) { } diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 534ada3..c03cdb1 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -116,7 +116,6 @@ typedef struct CPUSH4State { int user_mode_only; int interrupt_request; - int halted; CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; diff --git a/target-sh4/helper.c b/target-sh4/helper.c index ebc16ac..df64d28 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -535,5 +535,6 @@ void cpu_load_tlb(CPUState * env) #endif +int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index b663fe2..ba3ee01 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -217,7 +217,6 @@ typedef struct CPUSPARCState { int user_mode_only; int interrupt_index; int interrupt_request; - int halted; uint32_t mmu_bm; uint32_t mmu_ctpr_mask; uint32_t mmu_cxr_mask; diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 76c68fa..0a300fc 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -1320,6 +1320,12 @@ void cpu_dump_state(CPUState *env, FILE *f, static uint32_t *saved_regwptr; #endif +int cpu_info_ip(CPUState *env, char *buf) +{ + sprintf(buf, " pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc); + return 1; +} + void cpu_load_flags(CPUState *env) { #if defined(reg_REGWPTR) -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 4/6] simply cpu_exec further 2008-05-27 15:18 ` [Qemu-devel] [PATCH 3/6] use halted attribute for i386 too Glauber Costa @ 2008-05-27 15:18 ` Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 5/6] isolate mmu code in arch-specific function Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-27 15:18 UTC (permalink / raw) To: qemu-devel; +Cc: kvm We change interrupt functions so they have the same signature, getting only an env parameter. When necessary, some more attributed were added to the relevant CPUState to make it possible. Signed-off-by: Glauber Costa <gcosta@redhat.com> --- cpu-defs.h | 1 + cpu-exec.c | 197 +++++----------------------------------------- exec-all.h | 7 ++ target-alpha/helper.c | 9 ++ target-arm/helper.c | 27 ++++++ target-cris/helper.c | 9 ++ target-i386/exec.h | 5 +- target-i386/helper.c | 69 ++++++++++++++++- target-m68k/cpu.h | 2 +- target-m68k/helper.c | 16 ++++ target-m68k/op_helper.c | 8 +- target-mips/helper.c | 17 ++++ target-ppc/helper.c | 16 ++++ target-sh4/helper.c | 8 ++ target-sparc/exec.h | 3 +- target-sparc/helper.c | 1 + target-sparc/op_helper.c | 29 ++++++- 17 files changed, 232 insertions(+), 192 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index 5bcd1ee..5f3f9df 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -162,6 +162,7 @@ typedef struct CPUTLBEntry { /* Core interrupt code */ \ jmp_buf jmp_env; \ int exception_index; \ + int exception_is_hw; \ int error_code; \ \ int halted; \ diff --git a/cpu-exec.c b/cpu-exec.c index a829b7b..e798b03 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -241,6 +241,21 @@ static inline TranslationBlock *tb_find_fast(void) return tb; } +void handle_interrupt_common(CPUState *env) +{ + if (env->interrupt_request & CPU_INTERRUPT_HALT) { + env->interrupt_request &= ~CPU_INTERRUPT_HALT; + env->halted = 1; + env->exception_index = EXCP_HLT; + cpu_loop_exit(); + } +} + +void reset_tb(void) +{ + next_tb = 0; +} + /* main execution loop */ int cpu_exec(CPUState *env1) @@ -281,43 +296,16 @@ 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_MIPS) - do_interrupt(env); -#elif defined(TARGET_SPARC) - do_interrupt(env->exception_index); -#elif defined(TARGET_ARM) + env->exception_is_hw = 0; 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); -#endif } env->exception_index = -1; } @@ -360,156 +348,9 @@ int cpu_exec(CPUState *env1) env->exception_index = EXCP_DEBUG; cpu_loop_exit(); } -#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ - defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) - if (interrupt_request & CPU_INTERRUPT_HALT) { - env->interrupt_request &= ~CPU_INTERRUPT_HALT; - env->halted = 1; - env->exception_index = EXCP_HLT; - cpu_loop_exit(); - } -#endif -#if defined(TARGET_I386) - if ((interrupt_request & CPU_INTERRUPT_SMI) && - !(env->hflags & HF_SMM_MASK)) { - svm_check_intercept(SVM_EXIT_SMI); - env->interrupt_request &= ~CPU_INTERRUPT_SMI; - do_smm_enter(); - next_tb = 0; - } else if ((interrupt_request & CPU_INTERRUPT_NMI) && - !(env->hflags & HF_NMI_MASK)) { - env->interrupt_request &= ~CPU_INTERRUPT_NMI; - env->hflags |= HF_NMI_MASK; - do_interrupt(EXCP02_NMI, 0, 0, 0, 1); - next_tb = 0; - } else if ((interrupt_request & CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && - !(env->hflags & HF_INHIBIT_IRQ_MASK)) { - int intno; - svm_check_intercept(SVM_EXIT_INTR); - env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); - intno = cpu_get_pic_interrupt(env); - if (loglevel & CPU_LOG_TB_IN_ASM) { - fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); - } - do_interrupt(intno, 0, 0, 0, 1); - /* ensure that no TB jump will be modified as - the program flow was changed */ - next_tb = 0; -#if !defined(CONFIG_USER_ONLY) - } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && - (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { - int intno; - /* FIXME: this should respect TPR */ - env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; - svm_check_intercept(SVM_EXIT_VINTR); - intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); - if (loglevel & CPU_LOG_TB_IN_ASM) - fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno); - do_interrupt(intno, 0, 0, -1, 1); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), - ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); - next_tb = 0; -#endif - } -#elif defined(TARGET_PPC) -#if 0 - if ((interrupt_request & CPU_INTERRUPT_RESET)) { - cpu_ppc_reset(env); - } -#endif - if (interrupt_request & CPU_INTERRUPT_HARD) { - ppc_hw_interrupt(env); - if (env->pending_interrupts == 0) - env->interrupt_request &= ~CPU_INTERRUPT_HARD; - next_tb = 0; - } -#elif defined(TARGET_MIPS) - if ((interrupt_request & CPU_INTERRUPT_HARD) && - (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && - (env->CP0_Status & (1 << CP0St_IE)) && - !(env->CP0_Status & (1 << CP0St_EXL)) && - !(env->CP0_Status & (1 << CP0St_ERL)) && - !(env->hflags & MIPS_HFLAG_DM)) { - /* Raise it */ - env->exception_index = EXCP_EXT_INTERRUPT; - env->error_code = 0; - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_SPARC) - if ((interrupt_request & CPU_INTERRUPT_HARD) && - (env->psret != 0)) { - int pil = env->interrupt_index & 15; - int type = env->interrupt_index & 0xf0; - - if (((type == TT_EXTINT) && - (pil == 15 || pil > env->psrpil)) || - type != TT_EXTINT) { - env->interrupt_request &= ~CPU_INTERRUPT_HARD; - do_interrupt(env->interrupt_index); - env->interrupt_index = 0; -#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) - cpu_check_irqs(env); -#endif - next_tb = 0; - } - } else if (interrupt_request & CPU_INTERRUPT_TIMER) { - //do_interrupt(0, 0, 0, 0, 0); - env->interrupt_request &= ~CPU_INTERRUPT_TIMER; - } -#elif defined(TARGET_ARM) - if (interrupt_request & CPU_INTERRUPT_FIQ - && !(env->uncached_cpsr & CPSR_F)) { - env->exception_index = EXCP_FIQ; - do_interrupt(env); - next_tb = 0; - } - /* ARMv7-M interrupt return works by loading a magic value - into the PC. On real hardware the load causes the - return to occur. The qemu implementation performs the - jump normally, then does the exception return when the - CPU tries to execute code at the magic address. - This will cause the magic PC value to be pushed to - the stack if an interrupt occured at the wrong time. - We avoid this by disabling interrupts when - pc contains a magic address. */ - if (interrupt_request & CPU_INTERRUPT_HARD - && ((IS_M(env) && env->regs[15] < 0xfffffff0) - || !(env->uncached_cpsr & CPSR_I))) { - env->exception_index = EXCP_IRQ; - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_SH4) - if (interrupt_request & CPU_INTERRUPT_HARD) { - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_ALPHA) - if (interrupt_request & CPU_INTERRUPT_HARD) { - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_CRIS) - if (interrupt_request & CPU_INTERRUPT_HARD) { - do_interrupt(env); - next_tb = 0; - } -#elif defined(TARGET_M68K) - if (interrupt_request & CPU_INTERRUPT_HARD - && ((env->sr & SR_I) >> SR_I_SHIFT) - < env->pending_level) { - /* Real hardware gets the interrupt vector via an - IACK cycle at this point. Current emulated - hardware doesn't rely on this, so we - provide/save the vector when the interrupt is - first signalled. */ - env->exception_index = env->pending_vector; - do_interrupt(1); - next_tb = 0; - } -#endif + + arch_handle_interrupt_request(env); + /* Don't use the cached interupt_request value, do_interrupt may have updated the EXITTB flag. */ if (env->interrupt_request & CPU_INTERRUPT_EXITTB) { diff --git a/exec-all.h b/exec-all.h index fd1ea6a..b43526c 100644 --- a/exec-all.h +++ b/exec-all.h @@ -84,6 +84,13 @@ void cpu_resume_from_signal(CPUState *env1, void *puc); void cpu_exec_init(CPUState *env); extern int cpu_info_ip(CPUState *env, char *buf); + +/* implemented by the targets */ +void arch_handle_interrupt_request(CPUState *env); +/* implemented by cpu-exec.c */ +void handle_interrupt_common(CPUState *env); +void reset_tb(void); + void cpu_load_flags(CPUState *env); void cpu_put_flags(CPUState *env); diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 6056d6c..003601a 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -456,3 +456,12 @@ void cpu_dump_EA (target_ulong EA) int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} + +void arch_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-arm/helper.c b/target-arm/helper.c index 6724909..c0b3e84 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2527,3 +2527,30 @@ int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) { } /* XXX: Save/restore host fpu exception state?. */ void cpu_put_flags(CPUState *env) { } + +void arch_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if (env->interrupt_request & CPU_INTERRUPT_FIQ + && !(env->uncached_cpsr & CPSR_F)) { + env->exception_index = EXCP_FIQ; + do_interrupt(env); + reset_tb(); + } + /* ARMv7-M interrupt return works by loading a magic value + into the PC. On real hardware the load causes the + return to occur. The qemu implementation performs the + jump normally, then does the exception return when the + CPU tries to execute code at the magic address. + This will cause the magic PC value to be pushed to + the stack if an interrupt occured at the wrong time. + We avoid this by disabling interrupts when + pc contains a magic address. */ + if (env->interrupt_request & CPU_INTERRUPT_HARD + && ((IS_M(env) && env->regs[15] < 0xfffffff0) + || !(env->uncached_cpsr & CPSR_I))) { + env->exception_index = EXCP_IRQ; + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-cris/helper.c b/target-cris/helper.c index 0ed169c..7acba95 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -187,3 +187,12 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} + +void arch_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-i386/exec.h b/target-i386/exec.h index f6517ce..b4adabf 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -108,10 +108,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr); void __hidden cpu_lock(void); void __hidden cpu_unlock(void); -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 do_interrupt(CPUState *env); void raise_interrupt(int intno, int is_int, int error_code, int next_eip_addend); void raise_exception_err(int exception_index, int error_code); diff --git a/target-i386/helper.c b/target-i386/helper.c index 7e690de..7682d8e 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1199,8 +1199,8 @@ void do_interrupt_user(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) +void do_interrupt_system(int intno, int is_int, int error_code, + target_ulong next_eip, int is_hw) { if (loglevel & CPU_LOG_INT) { if ((env->cr[0] & CR0_PE_MASK)) { @@ -1247,6 +1247,71 @@ void do_interrupt(int intno, int is_int, int error_code, } } +void do_interrupt(CPUState *env) +{ + if (env->user_mode_only) + do_interrupt_user(env->exception_index, + env->exception_is_int, + env->error_code, + env->exception_next_eip); + else + do_interrupt_system(env->exception_index, + env->exception_is_int, + env->error_code, + env->exception_next_eip, + env->exception_is_hw); + + env->old_exception = -1; +} + +void arch_handle_interrupt_request(CPUState *env) +{ + int interrupt_request = env->interrupt_request; + int intno; + + if ((interrupt_request & CPU_INTERRUPT_SMI) && + !(env->hflags & HF_SMM_MASK)) { + svm_check_intercept(SVM_EXIT_SMI); + env->interrupt_request &= ~CPU_INTERRUPT_SMI; + do_smm_enter(); + reset_tb(); + } else if ((interrupt_request & CPU_INTERRUPT_NMI) && + !(env->hflags & HF_NMI_MASK)) { + env->interrupt_request &= ~CPU_INTERRUPT_NMI; + env->hflags |= HF_NMI_MASK; + do_interrupt_system(EXCP02_NMI, 0, 0, 0, 1); + reset_tb(); + } else if ((interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && + !(env->hflags & HF_INHIBIT_IRQ_MASK)) { + svm_check_intercept(SVM_EXIT_INTR); + env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); + intno = cpu_get_pic_interrupt(env); + if (loglevel & CPU_LOG_TB_IN_ASM) { + fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); + } + + do_interrupt_system(intno, 0, 0, 0, 1); + /* ensure that no TB jump will be modified as + the program flow was changed */ + reset_tb(); +#if !defined(CONFIG_USER_ONLY) + } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && + (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { + /* FIXME: this should respect TPR */ + env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; + svm_check_intercept(SVM_EXIT_VINTR); + intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); + if (loglevel & CPU_LOG_TB_IN_ASM) + fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno); + + do_interrupt_system(intno, 0, 0, -1, 1); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), + ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); + reset_tb(); +#endif + } +} /* * Check nested exceptions and change to double or triple fault if * needed. It should only be called, if this is not an interrupt. diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index e8c1dfc..1acb4a3 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -120,7 +120,7 @@ typedef struct CPUM68KState { 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(CPUM68KState *s); /* 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. */ diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 82b5576..65d68c9 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -355,6 +355,22 @@ void cpu_put_flags(CPUState *env) | env->cc_dest | (env->cc_x << 4); } +void arch_handle_interrupt_request(CPUState *env) +{ + if (env->interrupt_request & CPU_INTERRUPT_HARD + && ((env->sr & SR_I) >> SR_I_SHIFT) + < env->pending_level) { + /* Real hardware gets the interrupt vector via an + IACK cycle at this point. Current emulated + hardware doesn't rely on this, so we + provide/save the vector when the interrupt is + signalled. */ + env->exception_index = env->pending_vector; + env->exception_is_hw = 1; + do_interrupt(env); + reset_tb(); + } +} #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index 547f13d..2b0fc1c 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -21,7 +21,7 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt(int is_hw) +void do_interrupt(CPUState *env) { env->exception_index = -1; } @@ -95,7 +95,7 @@ static void do_rte(void) env->aregs[7] = sp + 8; } -void do_interrupt(int is_hw) +void do_interrupt(CPUState *env) { uint32_t sp; uint32_t fmt; @@ -105,7 +105,7 @@ void do_interrupt(int is_hw) fmt = 0; retaddr = env->pc; - if (!is_hw) { + if (!env->exception_is_hw) { switch (env->exception_index) { case EXCP_RTE: /* Return from an exception. */ @@ -143,7 +143,7 @@ void do_interrupt(int is_hw) fmt |= env->sr; env->sr |= SR_S; - if (is_hw) { + if (env->exception_is_hw) { env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT); env->sr &= ~SR_M; } diff --git a/target-mips/helper.c b/target-mips/helper.c index 81a1a6b..f10930a 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -645,3 +645,20 @@ int cpu_info_ip(CPUState *env, char *buf) void cpu_put_flags(CPUState *env) { } void cpu_load_flags(CPUState *env) { } + +void arch_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if ((env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && + (env->CP0_Status & (1 << CP0St_IE)) && + !(env->CP0_Status & (1 << CP0St_EXL)) && + !(env->CP0_Status & (1 << CP0St_ERL)) && + !(env->hflags & MIPS_HFLAG_DM)) { + /* Raise it */ + env->exception_index = EXCP_EXT_INTERRUPT; + env->error_code = 0; + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 2858780..ff8398f 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2997,3 +2997,19 @@ int cpu_info_ip(CPUState *env, char *buf) void cpu_load_flags(CPUState *env) { } void cpu_put_flags(CPUState *env) { } + +void arch_handle_interrupt_request(CPUState *env) +{ +#if 0 + if ((interrupt_request & CPU_INTERRUPT_RESET)) { + cpu_ppc_reset(env); + } +#endif + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + ppc_hw_interrupt(env); + if (env->pending_interrupts == 0) + env->interrupt_request &= ~CPU_INTERRUPT_HARD; + reset_tb(); + } +} + diff --git a/target-sh4/helper.c b/target-sh4/helper.c index df64d28..9d475ba 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -538,3 +538,11 @@ void cpu_load_tlb(CPUState * env) int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} + +void arch_handle_interrupt_request(CPUState *env) +{ + if (env->interrupt_request & CPU_INTERRUPT_HARD) { + do_interrupt(env); + reset_tb(); + } +} diff --git a/target-sparc/exec.h b/target-sparc/exec.h index 19d1732..33c5267 100644 --- a/target-sparc/exec.h +++ b/target-sparc/exec.h @@ -30,7 +30,8 @@ static inline void regs_to_env(void) int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, int mmu_idx, int is_softmmu); -void do_interrupt(int intno); + +void do_interrupt(CPUState *env); static inline int cpu_halted(CPUState *env1) { if (!env1->halted) diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 0a300fc..d63a91d 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -1339,6 +1339,7 @@ void cpu_put_flags(CPUState *env) REGWPTR = saved_regwptr; #endif } + #ifdef TARGET_SPARC64 #if !defined(CONFIG_USER_ONLY) #include "qemu-common.h" diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 2d85560..a22e752 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -2689,8 +2689,9 @@ static const char * const excp_names[0x50] = { }; #endif -void do_interrupt(int intno) +void do_interrupt(CPUState *cpu) { + int intno = cpu->exception_index; #ifdef DEBUG_PCALL if (loglevel & CPU_LOG_INT) { static int count; @@ -2803,9 +2804,10 @@ static const char * const excp_names[0x80] = { }; #endif -void do_interrupt(int intno) +void do_interrupt(CPUState *env) { int cwp; + int intno = env->exception_index; #ifdef DEBUG_PCALL if (loglevel & CPU_LOG_INT) { @@ -2864,6 +2866,29 @@ void do_interrupt(int intno) } #endif +void arch_handle_interrupt_request(CPUState *env) +{ + handle_interrupt_common(env); + if ((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->psret != 0)) { + int pil = env->interrupt_index & 15; + int type = env->interrupt_index & 0xf0; + + if (((type == TT_EXTINT) && + (pil == 15 || pil > env->psrpil)) || type != TT_EXTINT) { + env->interrupt_request &= ~CPU_INTERRUPT_HARD; + do_interrupt(env); + env->interrupt_index = 0; +#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) + cpu_check_irqs(env); +#endif + reset_tb(); + } + } else if (env->interrupt_request & CPU_INTERRUPT_TIMER) { + //do_interrupt(0, 0, 0, 0, 0); + env->interrupt_request &= ~CPU_INTERRUPT_TIMER; + } +} + #if !defined(CONFIG_USER_ONLY) static void do_unaligned_access(target_ulong addr, int is_write, int is_user, -- 1.5.4.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 5/6] isolate mmu code in arch-specific function 2008-05-27 15:18 ` [Qemu-devel] [PATCH 4/6] simply cpu_exec further Glauber Costa @ 2008-05-27 15:18 ` Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 6/6] cpu-exec-dump Glauber Costa 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-27 15:18 UTC (permalink / raw) To: qemu-devel; +Cc: kvm Simplify cpu_exec by removing a TARGET_I386 block, responsible for conditionally resetting the mmu, and enclosing it inside a function. --- cpu-exec.c | 17 +---------------- exec-all.h | 1 + target-alpha/helper.c | 1 + target-arm/helper.c | 1 + target-cris/helper.c | 1 + target-i386/helper.c | 19 +++++++++++++++++++ target-m68k/helper.c | 2 ++ target-mips/helper.c | 1 + target-ppc/helper.c | 1 + target-sh4/helper.c | 1 + target-sparc/helper.c | 2 ++ 11 files changed, 31 insertions(+), 16 deletions(-) Index: qemu/cpu-exec.c =================================================================== --- qemu.orig/cpu-exec.c +++ qemu/cpu-exec.c @@ -432,15 +432,7 @@ int cpu_exec(CPUState *env1) #endif next_tb = tcg_qemu_tb_exec(tc_ptr); env->current_tb = NULL; - /* reset soft MMU for next block (it can currently - only be set by a memory fault) */ -#if defined(TARGET_I386) && !defined(CONFIG_SOFTMMU) - if (env->hflags & HF_SOFTMMU_MASK) { - env->hflags &= ~HF_SOFTMMU_MASK; - /* do not allow linking to another block */ - next_tb = 0; - } -#endif + cpu_reset_mmu(env); #if defined(USE_KQEMU) #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000) if (kqemu_is_ok(env) && @@ -448,6 +440,7 @@ int cpu_exec(CPUState *env1) cpu_loop_exit(); } #endif + } /* for(;;) */ } else { env_to_regs(); Index: qemu/exec-all.h =================================================================== --- qemu.orig/exec-all.h +++ qemu/exec-all.h @@ -93,6 +93,7 @@ void reset_tb(void); void cpu_load_flags(CPUState *env); void cpu_put_flags(CPUState *env); +void cpu_reset_mmu(CPUState *env); int page_unprotect(target_ulong address, unsigned long pc, void *puc); void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, Index: qemu/target-alpha/helper.c =================================================================== --- qemu.orig/target-alpha/helper.c +++ qemu/target-alpha/helper.c @@ -456,6 +456,7 @@ void cpu_dump_EA (target_ulong EA) int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} +void cpu_reset_mmu(CPUState *env) {} void arch_handle_interrupt_request(CPUState *env) { Index: qemu/target-arm/helper.c =================================================================== --- qemu.orig/target-arm/helper.c +++ qemu/target-arm/helper.c @@ -2527,6 +2527,7 @@ int cpu_info_ip(CPUState *env, char *buf void cpu_load_flags(CPUState *env) { } /* XXX: Save/restore host fpu exception state?. */ void cpu_put_flags(CPUState *env) { } +void cpu_reset_mmu(CPUState *env) {} void arch_handle_interrupt_request(CPUState *env) { Index: qemu/target-cris/helper.c =================================================================== --- qemu.orig/target-cris/helper.c +++ qemu/target-cris/helper.c @@ -187,6 +187,7 @@ target_phys_addr_t cpu_get_phys_page_deb int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} +void cpu_reset_mmu(CPUState *env) {} void arch_handle_interrupt_request(CPUState *env) { Index: qemu/target-i386/helper.c =================================================================== --- qemu.orig/target-i386/helper.c +++ qemu/target-i386/helper.c @@ -4755,6 +4755,18 @@ void cpu_put_flags(CPUState *env) env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); } +void cpu_reset_mmu(CPUState *env) +{ + /* reset soft MMU for next block (it can currently + only be set by a memory fault) */ +#if !defined(CONFIG_SOFTMMU) + if (env->hflags & HF_SOFTMMU_MASK) { + env->hflags &= ~HF_SOFTMMU_MASK; + /* do not allow linking to another block */ + reset_tb(); + } +#endif +} #if defined(CONFIG_USER_ONLY) void helper_vmrun(void) Index: qemu/target-m68k/helper.c =================================================================== --- qemu.orig/target-m68k/helper.c +++ qemu/target-m68k/helper.c @@ -355,6 +355,8 @@ void cpu_put_flags(CPUState *env) | env->cc_dest | (env->cc_x << 4); } +void cpu_reset_mmu(CPUState *env) {} + void arch_handle_interrupt_request(CPUState *env) { if (env->interrupt_request & CPU_INTERRUPT_HARD Index: qemu/target-mips/helper.c =================================================================== --- qemu.orig/target-mips/helper.c +++ qemu/target-mips/helper.c @@ -645,6 +645,7 @@ int cpu_info_ip(CPUState *env, char *buf void cpu_put_flags(CPUState *env) { } void cpu_load_flags(CPUState *env) { } +void cpu_reset_mmu(CPUState *env) { } void arch_handle_interrupt_request(CPUState *env) { Index: qemu/target-ppc/helper.c =================================================================== --- qemu.orig/target-ppc/helper.c +++ qemu/target-ppc/helper.c @@ -2997,6 +2997,7 @@ int cpu_info_ip(CPUState *env, char *buf void cpu_load_flags(CPUState *env) { } void cpu_put_flags(CPUState *env) { } +void cpu_reset_mmu(CPUState *env) { } void arch_handle_interrupt_request(CPUState *env) { Index: qemu/target-sh4/helper.c =================================================================== --- qemu.orig/target-sh4/helper.c +++ qemu/target-sh4/helper.c @@ -538,6 +538,7 @@ void cpu_load_tlb(CPUState * env) int cpu_info_ip(CPUState *env, char *buf) { return 0; } void cpu_load_flags(CPUState *env) {} void cpu_put_flags(CPUState *env) {} +void cpu_reset_mmu(CPUState *env) {} void arch_handle_interrupt_request(CPUState *env) { Index: qemu/target-sparc/helper.c =================================================================== --- qemu.orig/target-sparc/helper.c +++ qemu/target-sparc/helper.c @@ -1340,6 +1340,8 @@ void cpu_put_flags(CPUState *env) #endif } +void cpu_reset_mmu(CPUState *env) {} + #ifdef TARGET_SPARC64 #if !defined(CONFIG_USER_ONLY) #include "qemu-common.h" ^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 6/6] cpu-exec-dump 2008-05-27 15:18 ` [Qemu-devel] [PATCH 5/6] isolate mmu code in arch-specific function Glauber Costa @ 2008-05-27 15:18 ` Glauber Costa 2008-05-27 15:38 ` Paul Brook 0 siblings, 1 reply; 12+ messages in thread From: Glauber Costa @ 2008-05-27 15:18 UTC (permalink / raw) To: qemu-devel; +Cc: kvm enclose the cpu dumping logic in cpu_exec() inside cpu_exec_dump() --- cpu-exec.c | 30 +----------------------------- target-alpha/helper.c | 5 +++++ target-arm/helper.c | 5 +++++ target-cris/helper.c | 5 +++++ target-i386/helper.c | 8 ++++++++ target-m68k/helper.c | 10 ++++++++++ target-mips/helper.c | 5 +++++ target-ppc/helper.c | 4 ++++ target-sh4/helper.c | 5 +++++ target-sparc/helper.c | 9 +++++++++ 10 files changed, 57 insertions(+), 29 deletions(-) Index: qemu/cpu-exec.c =================================================================== --- qemu.orig/cpu-exec.c +++ qemu/cpu-exec.c @@ -369,35 +369,7 @@ int cpu_exec(CPUState *env1) if ((loglevel & CPU_LOG_TB_CPU)) { /* restore flags in standard format */ regs_to_env(); -#if defined(TARGET_I386) - env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); - cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP); - env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); -#elif defined(TARGET_ARM) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_SPARC) - REGWPTR = env->regbase + (env->cwp * 16); - env->regwptr = REGWPTR; - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_PPC) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_M68K) - cpu_m68k_flush_flags(env, env->cc_op); - env->cc_op = CC_OP_FLAGS; - env->sr = (env->sr & 0xffe0) - | env->cc_dest | (env->cc_x << 4); - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_MIPS) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_SH4) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_ALPHA) - cpu_dump_state(env, logfile, fprintf, 0); -#elif defined(TARGET_CRIS) - cpu_dump_state(env, logfile, fprintf, 0); -#else -#error unsupported target CPU -#endif + cpu_exec_dump(env); } #endif tb = tb_find_fast(); Index: qemu/target-alpha/helper.c =================================================================== --- qemu.orig/target-alpha/helper.c +++ qemu/target-alpha/helper.c @@ -466,3 +466,8 @@ void arch_handle_interrupt_request(CPUSt reset_tb(); } } + +void cpu_exec_dump(CPUState *env) +{ + cpu_dump_state(env, logfile, fprintf, 0); +} Index: qemu/target-arm/helper.c =================================================================== --- qemu.orig/target-arm/helper.c +++ qemu/target-arm/helper.c @@ -2555,3 +2555,8 @@ void arch_handle_interrupt_request(CPUSt reset_tb(); } } + +void cpu_exec_dump(CPUState *env) +{ + cpu_dump_state(env, logfile, fprintf, 0); +} Index: qemu/target-cris/helper.c =================================================================== --- qemu.orig/target-cris/helper.c +++ qemu/target-cris/helper.c @@ -197,3 +197,8 @@ void arch_handle_interrupt_request(CPUSt reset_tb(); } } + +void cpu_exec_dump(CPUState *env) +{ + cpu_dump_state(env, logfile, fprintf, 0); +} Index: qemu/target-i386/helper.c =================================================================== --- qemu.orig/target-i386/helper.c +++ qemu/target-i386/helper.c @@ -4767,6 +4767,14 @@ void cpu_reset_mmu(CPUState *env) } #endif } + +void cpu_exec_dump(CPUState *env) +{ + env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); + cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP); + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); +} + #if defined(CONFIG_USER_ONLY) void helper_vmrun(void) Index: qemu/target-m68k/helper.c =================================================================== --- qemu.orig/target-m68k/helper.c +++ qemu/target-m68k/helper.c @@ -373,6 +373,16 @@ void arch_handle_interrupt_request(CPUSt reset_tb(); } } + +void cpu_exec_dump(CPUState *env) +{ + cpu_m68k_flush_flags(env, env->cc_op); + env->cc_op = CC_OP_FLAGS; + env->sr = (env->sr & 0xffe0) + | env->cc_dest | (env->cc_x << 4); + cpu_dump_state(env, logfile, fprintf, 0); +} + #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, Index: qemu/target-mips/helper.c =================================================================== --- qemu.orig/target-mips/helper.c +++ qemu/target-mips/helper.c @@ -663,3 +663,8 @@ void arch_handle_interrupt_request(CPUSt reset_tb(); } } + +void cpu_exec_dump(CPUState *env) +{ + cpu_dump_state(env, logfile, fprintf, 0); +} Index: qemu/target-ppc/helper.c =================================================================== --- qemu.orig/target-ppc/helper.c +++ qemu/target-ppc/helper.c @@ -3014,3 +3014,7 @@ void arch_handle_interrupt_request(CPUSt } } +void cpu_exec_dump(CPUState *env) +{ + cpu_dump_state(env, logfile, fprintf, 0); +} Index: qemu/target-sh4/helper.c =================================================================== --- qemu.orig/target-sh4/helper.c +++ qemu/target-sh4/helper.c @@ -547,3 +547,8 @@ void arch_handle_interrupt_request(CPUSt reset_tb(); } } + +void cpu_exec_dump(CPUState *env) +{ + cpu_dump_state(env, logfile, fprintf, 0); +} Index: qemu/target-sparc/helper.c =================================================================== --- qemu.orig/target-sparc/helper.c +++ qemu/target-sparc/helper.c @@ -1342,6 +1342,15 @@ void cpu_put_flags(CPUState *env) void cpu_reset_mmu(CPUState *env) {} +void cpu_exec_dump(CPUState *env) +{ +#if defined(reg_REGWPTR) + REGWPTR = env->regbase + (env->cwp * 16); + env->regwptr = REGWPTR; +#endif + cpu_dump_state(env, logfile, fprintf, 0); +} + #ifdef TARGET_SPARC64 #if !defined(CONFIG_USER_ONLY) #include "qemu-common.h" ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 6/6] cpu-exec-dump 2008-05-27 15:18 ` [Qemu-devel] [PATCH 6/6] cpu-exec-dump Glauber Costa @ 2008-05-27 15:38 ` Paul Brook 0 siblings, 0 replies; 12+ messages in thread From: Paul Brook @ 2008-05-27 15:38 UTC (permalink / raw) To: qemu-devel; +Cc: kvm, Glauber Costa On Tuesday 27 May 2008, Glauber Costa wrote: > - cpu_m68k_flush_flags(env, env->cc_op); > - env->cc_op = CC_OP_FLAGS; > - env->sr = (env->sr & 0xffe0) > - | env->cc_dest | (env->cc_x << 4); This should have been part of your first patch (cpu_put_flags). Paul ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2008-05-28 18:04 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-05-28 14:01 [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 1/6] remove REGWPTR Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 2/6] simplify cpu_exec Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 3/6] Push common interrupt variables to cpu-defs.h Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 4/6] use halted attribute for i386 too Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 5/6] simply cpu_exec further Glauber Costa 2008-05-28 14:01 ` [Qemu-devel] [PATCH 6/6] cpu-exec-dump Glauber Costa 2008-05-28 18:03 ` [Qemu-devel] [PATCH 5/6] simply cpu_exec further Blue Swirl 2008-05-28 14:25 ` [Qemu-devel] [PATCH 0/6] Simplify cpu_exec - spin 3 Paul Brook 2008-05-28 14:44 ` Glauber Costa -- strict thread matches above, loose matches on Subject: below -- 2008-05-27 15:18 [Qemu-devel] [PATCH 0/6] simplify cpu-exec new spin Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 1/6] simplify cpu_exec Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 2/6] Push common interrupt variables to cpu-defs.h Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 3/6] use halted attribute for i386 too Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 4/6] simply cpu_exec further Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 5/6] isolate mmu code in arch-specific function Glauber Costa 2008-05-27 15:18 ` [Qemu-devel] [PATCH 6/6] cpu-exec-dump Glauber Costa 2008-05-27 15:38 ` Paul Brook
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).