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