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,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); |