OSDN Git Service

sparc fixes
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 13 Feb 2005 19:02:42 +0000 (19:02 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 13 Feb 2005 19:02:42 +0000 (19:02 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1291 c046a42c-6fe2-441c-8c8c-71466251a162

target-sparc/cpu.h
target-sparc/exec.h
target-sparc/helper.c

index a4b6c73..f07464d 100644 (file)
 /*#define EXCP_INTERRUPT 0x100*/
 
 /* trap definitions */
+#define TT_TFAULT   0x01
 #define TT_ILL_INSN 0x02
 #define TT_PRIV_INSN 0x03
 #define TT_NFPU_INSN 0x04
 #define TT_WIN_OVF  0x05
 #define TT_WIN_UNF  0x06 
 #define TT_FP_EXCP  0x08
+#define TT_DFAULT   0x09
+#define TT_EXTINT   0x10
 #define TT_DIV_ZERO 0x2a
 #define TT_TRAP     0x80
-#define TT_EXTINT   0x10
 
 #define PSR_NEG   (1<<23)
 #define PSR_ZERO  (1<<22)
@@ -142,7 +144,6 @@ typedef struct CPUSPARCState {
     /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
     CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
     CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
-    int error_code;
     /* MMU regs */
     uint32_t mmuregs[16];
     /* temporary float registers */
index f905bdf..5e6c062 100644 (file)
@@ -41,7 +41,7 @@ void do_fcmpd(void);
 void do_ldd_kernel(target_ulong addr);
 void do_ldd_user(target_ulong addr);
 void do_ldd_raw(target_ulong addr);
-void do_interrupt(int intno, int error_code);
+void do_interrupt(int intno);
 void raise_exception(int tt);
 void memcpy32(target_ulong *dst, const target_ulong *src);
 target_ulong mmu_probe(target_ulong address, int mmulev);
index b23be7c..671d2f9 100644 (file)
@@ -44,8 +44,10 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
                                int is_user, int is_softmmu)
 {
     env->mmuregs[4] = address;
-    env->exception_index = 0; /* XXX: must be incorrect */
-    env->error_code = -2; /* XXX: is it really used ! */
+    if (rw & 2)
+        env->exception_index = TT_TFAULT;
+    else
+        env->exception_index = TT_DFAULT;
     return 1;
 }
 
@@ -95,7 +97,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
                 cpu_restore_state(tb, env, pc, NULL);
             }
         }
-        raise_exception(ret);
+        cpu_loop_exit();
     }
     env = saved_env;
 }
@@ -229,7 +231,6 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                               int is_user, int is_softmmu)
 {
-    int exception = 0;
     target_ulong virt_addr;
     target_phys_addr_t paddr;
     unsigned long vaddr;
@@ -248,11 +249,15 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;
     env->mmuregs[4] = address; /* Fault address register */
 
-    if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault
-       return 0;
-    env->exception_index = exception;
-    env->error_code = error_code;
-    return error_code;
+    if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
+        // No fault
+       cpu_abort(env, "Unsupported MMU no fault case");
+    }
+    if (rw & 2)
+        env->exception_index = TT_TFAULT;
+    else
+        env->exception_index = TT_DFAULT;
+    return 1;
 }
 #endif
 
@@ -289,15 +294,15 @@ void cpu_set_cwp(CPUState *env1, int new_cwp)
     env = saved_env;
 }
 
-void do_interrupt(int intno, int error_code)
+void do_interrupt(int intno)
 {
     int cwp;
 
 #ifdef DEBUG_PCALL
     if (loglevel & CPU_LOG_INT) {
        static int count;
-       fprintf(logfile, "%6d: v=%02x e=%04x pc=%08x npc=%08x SP=%08x\n",
-                count, intno, error_code,
+       fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
+                count, intno,
                 env->pc,
                 env->npc, env->regwptr[6]);
 #if 1
@@ -319,22 +324,15 @@ void do_interrupt(int intno, int error_code)
 #endif
 #if !defined(CONFIG_USER_ONLY) 
     if (env->psret == 0) {
-        cpu_abort(cpu_single_env, "Trap while interrupts disabled, Error state");
+        cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
        return;
     }
 #endif
     env->psret = 0;
     cwp = (env->cwp - 1) & (NWINDOWS - 1); 
     set_cwp(cwp);
-    if (intno & 0x80) {
-       env->regwptr[9] = env->pc;
-       env->regwptr[10] = env->npc;
-    } else {
-        /* XXX: this code is clearly incorrect - npc should have the
-           incorrect value */
-       env->regwptr[9] = env->pc - 4; // XXX?
-       env->regwptr[10] = env->pc;
-    }
+    env->regwptr[9] = env->pc;
+    env->regwptr[10] = env->npc;
     env->psrps = env->psrs;
     env->psrs = 1;
     env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);