qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ messages in thread

end of thread, other threads:[~2008-05-28 18:04 UTC | newest]

Thread overview: 10+ 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

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).