Commit 878d3096d20c3b77f5aaa25460d470bc7d8da15b

Authored by bellard
1 parent 1a0c3292

sparc fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1291 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/cpu.h
@@ -18,15 +18,17 @@ @@ -18,15 +18,17 @@
18 /*#define EXCP_INTERRUPT 0x100*/ 18 /*#define EXCP_INTERRUPT 0x100*/
19 19
20 /* trap definitions */ 20 /* trap definitions */
  21 +#define TT_TFAULT 0x01
21 #define TT_ILL_INSN 0x02 22 #define TT_ILL_INSN 0x02
22 #define TT_PRIV_INSN 0x03 23 #define TT_PRIV_INSN 0x03
23 #define TT_NFPU_INSN 0x04 24 #define TT_NFPU_INSN 0x04
24 #define TT_WIN_OVF 0x05 25 #define TT_WIN_OVF 0x05
25 #define TT_WIN_UNF 0x06 26 #define TT_WIN_UNF 0x06
26 #define TT_FP_EXCP 0x08 27 #define TT_FP_EXCP 0x08
  28 +#define TT_DFAULT 0x09
  29 +#define TT_EXTINT 0x10
27 #define TT_DIV_ZERO 0x2a 30 #define TT_DIV_ZERO 0x2a
28 #define TT_TRAP 0x80 31 #define TT_TRAP 0x80
29 -#define TT_EXTINT 0x10  
30 32
31 #define PSR_NEG (1<<23) 33 #define PSR_NEG (1<<23)
32 #define PSR_ZERO (1<<22) 34 #define PSR_ZERO (1<<22)
@@ -142,7 +144,6 @@ typedef struct CPUSPARCState { @@ -142,7 +144,6 @@ typedef struct CPUSPARCState {
142 /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */ 144 /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
143 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; 145 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
144 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; 146 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
145 - int error_code;  
146 /* MMU regs */ 147 /* MMU regs */
147 uint32_t mmuregs[16]; 148 uint32_t mmuregs[16];
148 /* temporary float registers */ 149 /* temporary float registers */
target-sparc/exec.h
@@ -41,7 +41,7 @@ void do_fcmpd(void); @@ -41,7 +41,7 @@ void do_fcmpd(void);
41 void do_ldd_kernel(target_ulong addr); 41 void do_ldd_kernel(target_ulong addr);
42 void do_ldd_user(target_ulong addr); 42 void do_ldd_user(target_ulong addr);
43 void do_ldd_raw(target_ulong addr); 43 void do_ldd_raw(target_ulong addr);
44 -void do_interrupt(int intno, int error_code); 44 +void do_interrupt(int intno);
45 void raise_exception(int tt); 45 void raise_exception(int tt);
46 void memcpy32(target_ulong *dst, const target_ulong *src); 46 void memcpy32(target_ulong *dst, const target_ulong *src);
47 target_ulong mmu_probe(target_ulong address, int mmulev); 47 target_ulong mmu_probe(target_ulong address, int mmulev);
target-sparc/helper.c
@@ -44,8 +44,10 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, @@ -44,8 +44,10 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
44 int is_user, int is_softmmu) 44 int is_user, int is_softmmu)
45 { 45 {
46 env->mmuregs[4] = address; 46 env->mmuregs[4] = address;
47 - env->exception_index = 0; /* XXX: must be incorrect */  
48 - env->error_code = -2; /* XXX: is it really used ! */ 47 + if (rw & 2)
  48 + env->exception_index = TT_TFAULT;
  49 + else
  50 + env->exception_index = TT_DFAULT;
49 return 1; 51 return 1;
50 } 52 }
51 53
@@ -95,7 +97,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) @@ -95,7 +97,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
95 cpu_restore_state(tb, env, pc, NULL); 97 cpu_restore_state(tb, env, pc, NULL);
96 } 98 }
97 } 99 }
98 - raise_exception(ret); 100 + cpu_loop_exit();
99 } 101 }
100 env = saved_env; 102 env = saved_env;
101 } 103 }
@@ -229,7 +231,6 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot @@ -229,7 +231,6 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
229 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 231 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
230 int is_user, int is_softmmu) 232 int is_user, int is_softmmu)
231 { 233 {
232 - int exception = 0;  
233 target_ulong virt_addr; 234 target_ulong virt_addr;
234 target_phys_addr_t paddr; 235 target_phys_addr_t paddr;
235 unsigned long vaddr; 236 unsigned long vaddr;
@@ -248,11 +249,15 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -248,11 +249,15 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
248 env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; 249 env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;
249 env->mmuregs[4] = address; /* Fault address register */ 250 env->mmuregs[4] = address; /* Fault address register */
250 251
251 - if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault  
252 - return 0;  
253 - env->exception_index = exception;  
254 - env->error_code = error_code;  
255 - return error_code; 252 + if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) {
  253 + // No fault
  254 + cpu_abort(env, "Unsupported MMU no fault case");
  255 + }
  256 + if (rw & 2)
  257 + env->exception_index = TT_TFAULT;
  258 + else
  259 + env->exception_index = TT_DFAULT;
  260 + return 1;
256 } 261 }
257 #endif 262 #endif
258 263
@@ -289,15 +294,15 @@ void cpu_set_cwp(CPUState *env1, int new_cwp) @@ -289,15 +294,15 @@ void cpu_set_cwp(CPUState *env1, int new_cwp)
289 env = saved_env; 294 env = saved_env;
290 } 295 }
291 296
292 -void do_interrupt(int intno, int error_code) 297 +void do_interrupt(int intno)
293 { 298 {
294 int cwp; 299 int cwp;
295 300
296 #ifdef DEBUG_PCALL 301 #ifdef DEBUG_PCALL
297 if (loglevel & CPU_LOG_INT) { 302 if (loglevel & CPU_LOG_INT) {
298 static int count; 303 static int count;
299 - fprintf(logfile, "%6d: v=%02x e=%04x pc=%08x npc=%08x SP=%08x\n",  
300 - count, intno, error_code, 304 + fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
  305 + count, intno,
301 env->pc, 306 env->pc,
302 env->npc, env->regwptr[6]); 307 env->npc, env->regwptr[6]);
303 #if 1 308 #if 1
@@ -319,22 +324,15 @@ void do_interrupt(int intno, int error_code) @@ -319,22 +324,15 @@ void do_interrupt(int intno, int error_code)
319 #endif 324 #endif
320 #if !defined(CONFIG_USER_ONLY) 325 #if !defined(CONFIG_USER_ONLY)
321 if (env->psret == 0) { 326 if (env->psret == 0) {
322 - cpu_abort(cpu_single_env, "Trap while interrupts disabled, Error state"); 327 + cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
323 return; 328 return;
324 } 329 }
325 #endif 330 #endif
326 env->psret = 0; 331 env->psret = 0;
327 cwp = (env->cwp - 1) & (NWINDOWS - 1); 332 cwp = (env->cwp - 1) & (NWINDOWS - 1);
328 set_cwp(cwp); 333 set_cwp(cwp);
329 - if (intno & 0x80) {  
330 - env->regwptr[9] = env->pc;  
331 - env->regwptr[10] = env->npc;  
332 - } else {  
333 - /* XXX: this code is clearly incorrect - npc should have the  
334 - incorrect value */  
335 - env->regwptr[9] = env->pc - 4; // XXX?  
336 - env->regwptr[10] = env->pc;  
337 - } 334 + env->regwptr[9] = env->pc;
  335 + env->regwptr[10] = env->npc;
338 env->psrps = env->psrs; 336 env->psrps = env->psrs;
339 env->psrs = 1; 337 env->psrs = 1;
340 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); 338 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);