Commit 878d3096d20c3b77f5aaa25460d470bc7d8da15b
1 parent
1a0c3292
sparc fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1291 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
24 additions
and
25 deletions
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); | ... | ... |