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 18 /*#define EXCP_INTERRUPT 0x100*/
19 19  
20 20 /* trap definitions */
  21 +#define TT_TFAULT 0x01
21 22 #define TT_ILL_INSN 0x02
22 23 #define TT_PRIV_INSN 0x03
23 24 #define TT_NFPU_INSN 0x04
24 25 #define TT_WIN_OVF 0x05
25 26 #define TT_WIN_UNF 0x06
26 27 #define TT_FP_EXCP 0x08
  28 +#define TT_DFAULT 0x09
  29 +#define TT_EXTINT 0x10
27 30 #define TT_DIV_ZERO 0x2a
28 31 #define TT_TRAP 0x80
29   -#define TT_EXTINT 0x10
30 32  
31 33 #define PSR_NEG (1<<23)
32 34 #define PSR_ZERO (1<<22)
... ... @@ -142,7 +144,6 @@ typedef struct CPUSPARCState {
142 144 /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
143 145 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
144 146 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
145   - int error_code;
146 147 /* MMU regs */
147 148 uint32_t mmuregs[16];
148 149 /* temporary float registers */
... ...
target-sparc/exec.h
... ... @@ -41,7 +41,7 @@ void do_fcmpd(void);
41 41 void do_ldd_kernel(target_ulong addr);
42 42 void do_ldd_user(target_ulong addr);
43 43 void do_ldd_raw(target_ulong addr);
44   -void do_interrupt(int intno, int error_code);
  44 +void do_interrupt(int intno);
45 45 void raise_exception(int tt);
46 46 void memcpy32(target_ulong *dst, const target_ulong *src);
47 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 44 int is_user, int is_softmmu)
45 45 {
46 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 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 97 cpu_restore_state(tb, env, pc, NULL);
96 98 }
97 99 }
98   - raise_exception(ret);
  100 + cpu_loop_exit();
99 101 }
100 102 env = saved_env;
101 103 }
... ... @@ -229,7 +231,6 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
229 231 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
230 232 int is_user, int is_softmmu)
231 233 {
232   - int exception = 0;
233 234 target_ulong virt_addr;
234 235 target_phys_addr_t paddr;
235 236 unsigned long vaddr;
... ... @@ -248,11 +249,15 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
248 249 env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;
249 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 262 #endif
258 263  
... ... @@ -289,15 +294,15 @@ void cpu_set_cwp(CPUState *env1, int new_cwp)
289 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 299 int cwp;
295 300  
296 301 #ifdef DEBUG_PCALL
297 302 if (loglevel & CPU_LOG_INT) {
298 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 306 env->pc,
302 307 env->npc, env->regwptr[6]);
303 308 #if 1
... ... @@ -319,22 +324,15 @@ void do_interrupt(int intno, int error_code)
319 324 #endif
320 325 #if !defined(CONFIG_USER_ONLY)
321 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 328 return;
324 329 }
325 330 #endif
326 331 env->psret = 0;
327 332 cwp = (env->cwp - 1) & (NWINDOWS - 1);
328 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 336 env->psrps = env->psrs;
339 337 env->psrs = 1;
340 338 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
... ...