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