提交 878d3096 编写于 作者: B bellard

sparc fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1291 c046a42c-6fe2-441c-8c8c-71466251a162
上级 1a0c3292
...@@ -18,15 +18,17 @@ ...@@ -18,15 +18,17 @@
/*#define EXCP_INTERRUPT 0x100*/ /*#define EXCP_INTERRUPT 0x100*/
/* trap definitions */ /* trap definitions */
#define TT_TFAULT 0x01
#define TT_ILL_INSN 0x02 #define TT_ILL_INSN 0x02
#define TT_PRIV_INSN 0x03 #define TT_PRIV_INSN 0x03
#define TT_NFPU_INSN 0x04 #define TT_NFPU_INSN 0x04
#define TT_WIN_OVF 0x05 #define TT_WIN_OVF 0x05
#define TT_WIN_UNF 0x06 #define TT_WIN_UNF 0x06
#define TT_FP_EXCP 0x08 #define TT_FP_EXCP 0x08
#define TT_DFAULT 0x09
#define TT_EXTINT 0x10
#define TT_DIV_ZERO 0x2a #define TT_DIV_ZERO 0x2a
#define TT_TRAP 0x80 #define TT_TRAP 0x80
#define TT_EXTINT 0x10
#define PSR_NEG (1<<23) #define PSR_NEG (1<<23)
#define PSR_ZERO (1<<22) #define PSR_ZERO (1<<22)
...@@ -142,7 +144,6 @@ typedef struct CPUSPARCState { ...@@ -142,7 +144,6 @@ typedef struct CPUSPARCState {
/* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */ /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
int error_code;
/* MMU regs */ /* MMU regs */
uint32_t mmuregs[16]; uint32_t mmuregs[16];
/* temporary float registers */ /* temporary float registers */
......
...@@ -41,7 +41,7 @@ void do_fcmpd(void); ...@@ -41,7 +41,7 @@ void do_fcmpd(void);
void do_ldd_kernel(target_ulong addr); void do_ldd_kernel(target_ulong addr);
void do_ldd_user(target_ulong addr); void do_ldd_user(target_ulong addr);
void do_ldd_raw(target_ulong addr); void do_ldd_raw(target_ulong addr);
void do_interrupt(int intno, int error_code); void do_interrupt(int intno);
void raise_exception(int tt); void raise_exception(int tt);
void memcpy32(target_ulong *dst, const target_ulong *src); void memcpy32(target_ulong *dst, const target_ulong *src);
target_ulong mmu_probe(target_ulong address, int mmulev); target_ulong mmu_probe(target_ulong address, int mmulev);
......
...@@ -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,
int is_user, int is_softmmu) int is_user, int is_softmmu)
{ {
env->mmuregs[4] = address; env->mmuregs[4] = address;
env->exception_index = 0; /* XXX: must be incorrect */ if (rw & 2)
env->error_code = -2; /* XXX: is it really used ! */ env->exception_index = TT_TFAULT;
else
env->exception_index = TT_DFAULT;
return 1; return 1;
} }
...@@ -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)
cpu_restore_state(tb, env, pc, NULL); cpu_restore_state(tb, env, pc, NULL);
} }
} }
raise_exception(ret); cpu_loop_exit();
} }
env = saved_env; env = saved_env;
} }
...@@ -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
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
int is_user, int is_softmmu) int is_user, int is_softmmu)
{ {
int exception = 0;
target_ulong virt_addr; target_ulong virt_addr;
target_phys_addr_t paddr; target_phys_addr_t paddr;
unsigned long vaddr; 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,
env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;
env->mmuregs[4] = address; /* Fault address register */ env->mmuregs[4] = address; /* Fault address register */
if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) {
return 0; // No fault
env->exception_index = exception; cpu_abort(env, "Unsupported MMU no fault case");
env->error_code = error_code; }
return error_code; if (rw & 2)
env->exception_index = TT_TFAULT;
else
env->exception_index = TT_DFAULT;
return 1;
} }
#endif #endif
...@@ -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)
env = saved_env; env = saved_env;
} }
void do_interrupt(int intno, int error_code) void do_interrupt(int intno)
{ {
int cwp; int cwp;
#ifdef DEBUG_PCALL #ifdef DEBUG_PCALL
if (loglevel & CPU_LOG_INT) { if (loglevel & CPU_LOG_INT) {
static int count; static int count;
fprintf(logfile, "%6d: v=%02x e=%04x pc=%08x npc=%08x SP=%08x\n", fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
count, intno, error_code, count, intno,
env->pc, env->pc,
env->npc, env->regwptr[6]); env->npc, env->regwptr[6]);
#if 1 #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)
#endif #endif
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
if (env->psret == 0) { if (env->psret == 0) {
cpu_abort(cpu_single_env, "Trap while interrupts disabled, Error state"); cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
return; return;
} }
#endif #endif
env->psret = 0; env->psret = 0;
cwp = (env->cwp - 1) & (NWINDOWS - 1); cwp = (env->cwp - 1) & (NWINDOWS - 1);
set_cwp(cwp); set_cwp(cwp);
if (intno & 0x80) { env->regwptr[9] = env->pc;
env->regwptr[9] = env->pc; env->regwptr[10] = env->npc;
env->regwptr[10] = env->npc;
} else {
/* XXX: this code is clearly incorrect - npc should have the
incorrect value */
env->regwptr[9] = env->pc - 4; // XXX?
env->regwptr[10] = env->pc;
}
env->psrps = env->psrs; env->psrps = env->psrs;
env->psrs = 1; env->psrs = 1;
env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册