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