44 |
int is_user, int is_softmmu) |
int is_user, int is_softmmu) |
45 |
{ |
{ |
46 |
env->mmuregs[4] = address; |
env->mmuregs[4] = address; |
47 |
env->exception_index = 0; /* XXX: must be incorrect */ |
if (rw & 2) |
48 |
env->error_code = -2; /* XXX: is it really used ! */ |
env->exception_index = TT_TFAULT; |
49 |
|
else |
50 |
|
env->exception_index = TT_DFAULT; |
51 |
return 1; |
return 1; |
52 |
} |
} |
53 |
|
|
97 |
cpu_restore_state(tb, env, pc, NULL); |
cpu_restore_state(tb, env, pc, NULL); |
98 |
} |
} |
99 |
} |
} |
100 |
raise_exception(ret); |
cpu_loop_exit(); |
101 |
} |
} |
102 |
env = saved_env; |
env = saved_env; |
103 |
} |
} |
231 |
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, |
232 |
int is_user, int is_softmmu) |
int is_user, int is_softmmu) |
233 |
{ |
{ |
|
int exception = 0; |
|
234 |
target_ulong virt_addr; |
target_ulong virt_addr; |
235 |
target_phys_addr_t paddr; |
target_phys_addr_t paddr; |
236 |
unsigned long vaddr; |
unsigned long vaddr; |
249 |
env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; |
env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; |
250 |
env->mmuregs[4] = address; /* Fault address register */ |
env->mmuregs[4] = address; /* Fault address register */ |
251 |
|
|
252 |
if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault |
if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) { |
253 |
return 0; |
// No fault |
254 |
env->exception_index = exception; |
cpu_abort(env, "Unsupported MMU no fault case"); |
255 |
env->error_code = error_code; |
} |
256 |
return error_code; |
if (rw & 2) |
257 |
|
env->exception_index = TT_TFAULT; |
258 |
|
else |
259 |
|
env->exception_index = TT_DFAULT; |
260 |
|
return 1; |
261 |
} |
} |
262 |
#endif |
#endif |
263 |
|
|
294 |
env = saved_env; |
env = saved_env; |
295 |
} |
} |
296 |
|
|
297 |
void do_interrupt(int intno, int error_code) |
void do_interrupt(int intno) |
298 |
{ |
{ |
299 |
int cwp; |
int cwp; |
300 |
|
|
301 |
#ifdef DEBUG_PCALL |
#ifdef DEBUG_PCALL |
302 |
if (loglevel & CPU_LOG_INT) { |
if (loglevel & CPU_LOG_INT) { |
303 |
static int count; |
static int count; |
304 |
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", |
305 |
count, intno, error_code, |
count, intno, |
306 |
env->pc, |
env->pc, |
307 |
env->npc, env->regwptr[6]); |
env->npc, env->regwptr[6]); |
308 |
#if 1 |
#if 1 |
324 |
#endif |
#endif |
325 |
#if !defined(CONFIG_USER_ONLY) |
#if !defined(CONFIG_USER_ONLY) |
326 |
if (env->psret == 0) { |
if (env->psret == 0) { |
327 |
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); |
328 |
return; |
return; |
329 |
} |
} |
330 |
#endif |
#endif |
331 |
env->psret = 0; |
env->psret = 0; |
332 |
cwp = (env->cwp - 1) & (NWINDOWS - 1); |
cwp = (env->cwp - 1) & (NWINDOWS - 1); |
333 |
set_cwp(cwp); |
set_cwp(cwp); |
334 |
if (intno & 0x80) { |
env->regwptr[9] = env->pc; |
335 |
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; |
|
|
} |
|
336 |
env->psrps = env->psrs; |
env->psrps = env->psrs; |
337 |
env->psrs = 1; |
env->psrs = 1; |
338 |
env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); |
env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); |