mirror of https://github.com/xqemu/xqemu.git
sparc fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1291 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
1a0c3292b5
commit
878d3096d2
|
@ -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 {
|
||||||
/* 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);
|
||||||
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,
|
||||||
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)
|
||||||
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
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
#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);
|
||||||
|
|
Loading…
Reference in New Issue