| 23 |
//#define DEBUG_MMU |
//#define DEBUG_MMU |
| 24 |
|
|
| 25 |
/* Sparc MMU emulation */ |
/* Sparc MMU emulation */ |
|
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
|
|
int is_user, int is_softmmu); |
|
| 26 |
|
|
| 27 |
/* thread support */ |
/* thread support */ |
| 28 |
|
|
| 38 |
spin_unlock(&global_cpu_lock); |
spin_unlock(&global_cpu_lock); |
| 39 |
} |
} |
| 40 |
|
|
| 41 |
#if !defined(CONFIG_USER_ONLY) |
#if defined(CONFIG_USER_ONLY) |
| 42 |
|
|
| 43 |
|
int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, |
| 44 |
|
int is_user, int is_softmmu) |
| 45 |
|
{ |
| 46 |
|
env->mmuregs[4] = address; |
| 47 |
|
env->exception_index = 0; /* XXX: must be incorrect */ |
| 48 |
|
env->error_code = -2; /* XXX: is it really used ! */ |
| 49 |
|
return 1; |
| 50 |
|
} |
| 51 |
|
|
| 52 |
|
#else |
| 53 |
|
|
| 54 |
#define MMUSUFFIX _mmu |
#define MMUSUFFIX _mmu |
| 55 |
#define GETPC() (__builtin_return_address(0)) |
#define GETPC() (__builtin_return_address(0)) |
| 95 |
cpu_restore_state(tb, env, pc, NULL); |
cpu_restore_state(tb, env, pc, NULL); |
| 96 |
} |
} |
| 97 |
} |
} |
| 98 |
raise_exception_err(ret, env->error_code); |
raise_exception(ret); |
| 99 |
} |
} |
| 100 |
env = saved_env; |
env = saved_env; |
| 101 |
} |
} |
|
#endif |
|
| 102 |
|
|
| 103 |
static const int access_table[8][8] = { |
static const int access_table[8][8] = { |
| 104 |
{ 0, 0, 0, 0, 2, 0, 3, 3 }, |
{ 0, 0, 0, 0, 2, 0, 3, 3 }, |
| 235 |
unsigned long vaddr; |
unsigned long vaddr; |
| 236 |
int error_code = 0, prot, ret = 0, access_index; |
int error_code = 0, prot, ret = 0, access_index; |
| 237 |
|
|
|
if (env->user_mode_only) { |
|
|
/* user mode only emulation */ |
|
|
error_code = -2; |
|
|
goto do_fault_user; |
|
|
} |
|
|
|
|
| 238 |
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); |
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); |
| 239 |
if (error_code == 0) { |
if (error_code == 0) { |
| 240 |
virt_addr = address & TARGET_PAGE_MASK; |
virt_addr = address & TARGET_PAGE_MASK; |
| 250 |
|
|
| 251 |
if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault |
if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault |
| 252 |
return 0; |
return 0; |
|
do_fault_user: |
|
| 253 |
env->exception_index = exception; |
env->exception_index = exception; |
| 254 |
env->error_code = error_code; |
env->error_code = error_code; |
| 255 |
return error_code; |
return error_code; |
| 256 |
} |
} |
| 257 |
|
#endif |
| 258 |
|
|
| 259 |
void memcpy32(target_ulong *dst, const target_ulong *src) |
void memcpy32(target_ulong *dst, const target_ulong *src) |
| 260 |
{ |
{ |
| 289 |
env = saved_env; |
env = saved_env; |
| 290 |
} |
} |
| 291 |
|
|
| 292 |
/* |
void do_interrupt(int intno, int error_code) |
|
* Begin execution of an interruption. is_int is TRUE if coming from |
|
|
* the int instruction. next_eip is the EIP value AFTER the interrupt |
|
|
* instruction. It is only relevant if is_int is TRUE. |
|
|
*/ |
|
|
void do_interrupt(int intno, int is_int, int error_code, |
|
|
unsigned int next_eip, int is_hw) |
|
| 293 |
{ |
{ |
| 294 |
int cwp; |
int cwp; |
| 295 |
|
|
| 296 |
#ifdef DEBUG_PCALL |
#ifdef DEBUG_PCALL |
| 297 |
if (loglevel & CPU_LOG_INT) { |
if (loglevel & CPU_LOG_INT) { |
| 298 |
static int count; |
static int count; |
| 299 |
fprintf(logfile, "%6d: v=%02x e=%04x i=%d pc=%08x npc=%08x SP=%08x\n", |
fprintf(logfile, "%6d: v=%02x e=%04x pc=%08x npc=%08x SP=%08x\n", |
| 300 |
count, intno, error_code, is_int, |
count, intno, error_code, |
| 301 |
env->pc, |
env->pc, |
| 302 |
env->npc, env->regwptr[6]); |
env->npc, env->regwptr[6]); |
| 303 |
#if 1 |
#if 1 |
| 304 |
cpu_dump_state(env, logfile, fprintf, 0); |
cpu_dump_state(env, logfile, fprintf, 0); |
| 305 |
{ |
{ |
| 330 |
env->regwptr[9] = env->pc; |
env->regwptr[9] = env->pc; |
| 331 |
env->regwptr[10] = env->npc; |
env->regwptr[10] = env->npc; |
| 332 |
} else { |
} else { |
| 333 |
|
/* XXX: this code is clearly incorrect - npc should have the |
| 334 |
|
incorrect value */ |
| 335 |
env->regwptr[9] = env->pc - 4; // XXX? |
env->regwptr[9] = env->pc - 4; // XXX? |
| 336 |
env->regwptr[10] = env->pc; |
env->regwptr[10] = env->pc; |
| 337 |
} |
} |
| 343 |
env->exception_index = 0; |
env->exception_index = 0; |
| 344 |
} |
} |
| 345 |
|
|
|
void raise_exception_err(int exception_index, int error_code) |
|
|
{ |
|
|
raise_exception(exception_index); |
|
|
} |
|
|
|
|
| 346 |
target_ulong mmu_probe(target_ulong address, int mmulev) |
target_ulong mmu_probe(target_ulong address, int mmulev) |
| 347 |
{ |
{ |
| 348 |
target_phys_addr_t pde_ptr; |
target_phys_addr_t pde_ptr; |