23 |
//#define DEBUG_MMU |
//#define DEBUG_MMU |
24 |
|
|
25 |
/* Sparc MMU emulation */ |
/* Sparc MMU emulation */ |
26 |
int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
27 |
int is_user, int is_softmmu); |
int is_user, int is_softmmu); |
28 |
|
|
29 |
/* thread support */ |
/* thread support */ |
109 |
{ 0, 1, 0, 1, 0, 0, 0, 0 } |
{ 0, 1, 0, 1, 0, 0, 0, 0 } |
110 |
}; |
}; |
111 |
|
|
112 |
int get_physical_address (CPUState *env, uint32_t *physical, int *prot, |
int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, |
113 |
int *access_index, uint32_t address, int rw, |
int *access_index, target_ulong address, int rw, |
114 |
int is_user) |
int is_user) |
115 |
{ |
{ |
116 |
int access_perms = 0; |
int access_perms = 0; |
117 |
target_phys_addr_t pde_ptr; |
target_phys_addr_t pde_ptr; |
118 |
uint32_t pde, virt_addr; |
uint32_t pde; |
119 |
|
target_ulong virt_addr; |
120 |
int error_code = 0, is_dirty; |
int error_code = 0, is_dirty; |
121 |
unsigned long page_offset; |
unsigned long page_offset; |
122 |
|
|
218 |
} |
} |
219 |
|
|
220 |
/* Perform address translation */ |
/* Perform address translation */ |
221 |
int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
222 |
int is_user, int is_softmmu) |
int is_user, int is_softmmu) |
223 |
{ |
{ |
224 |
int exception = 0; |
int exception = 0; |
225 |
uint32_t virt_addr, paddr; |
target_ulong virt_addr; |
226 |
|
target_phys_addr_t paddr; |
227 |
unsigned long vaddr; |
unsigned long vaddr; |
228 |
int error_code = 0, prot, ret = 0, access_index; |
int error_code = 0, prot, ret = 0, access_index; |
229 |
|
|
254 |
return error_code; |
return error_code; |
255 |
} |
} |
256 |
|
|
257 |
void memcpy32(uint32_t *dst, const uint32_t *src) |
void memcpy32(target_ulong *dst, const target_ulong *src) |
258 |
{ |
{ |
259 |
dst[0] = src[0]; |
dst[0] = src[0]; |
260 |
dst[1] = src[1]; |
dst[1] = src[1]; |
330 |
env->psret = 0; |
env->psret = 0; |
331 |
cwp = (env->cwp - 1) & (NWINDOWS - 1); |
cwp = (env->cwp - 1) & (NWINDOWS - 1); |
332 |
set_cwp(cwp); |
set_cwp(cwp); |
333 |
env->regwptr[9] = env->pc - 4; // XXX? |
if (intno & 0x80) { |
334 |
env->regwptr[10] = env->pc; |
env->regwptr[9] = env->pc; |
335 |
|
env->regwptr[10] = env->npc; |
336 |
|
} else { |
337 |
|
env->regwptr[9] = env->pc - 4; // XXX? |
338 |
|
env->regwptr[10] = env->pc; |
339 |
|
} |
340 |
env->psrps = env->psrs; |
env->psrps = env->psrs; |
341 |
env->psrs = 1; |
env->psrs = 1; |
342 |
env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); |
env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); |
350 |
raise_exception(exception_index); |
raise_exception(exception_index); |
351 |
} |
} |
352 |
|
|
353 |
uint32_t mmu_probe(uint32_t address, int mmulev) |
target_ulong mmu_probe(target_ulong address, int mmulev) |
354 |
{ |
{ |
355 |
target_phys_addr_t pde_ptr; |
target_phys_addr_t pde_ptr; |
356 |
uint32_t pde; |
uint32_t pde; |
415 |
void dump_mmu(void) |
void dump_mmu(void) |
416 |
{ |
{ |
417 |
#ifdef DEBUG_MMU |
#ifdef DEBUG_MMU |
418 |
uint32_t pa, va, va1, va2; |
target_ulong va, va1, va2; |
419 |
int n, m, o; |
unsigned int n, m, o; |
420 |
target_phys_addr_t pde_ptr; |
target_phys_addr_t pde_ptr, pa; |
421 |
uint32_t pde; |
uint32_t pde; |
422 |
|
|
423 |
printf("MMU dump:\n"); |
printf("MMU dump:\n"); |
424 |
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4); |
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4); |
425 |
pde = ldl_phys(pde_ptr); |
pde = ldl_phys(pde_ptr); |
426 |
printf("Root ptr: 0x%08x, ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); |
printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); |
427 |
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { |
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { |
428 |
pde_ptr = mmu_probe(va, 2); |
pde_ptr = mmu_probe(va, 2); |
429 |
if (pde_ptr) { |
if (pde_ptr) { |
430 |
pa = cpu_get_phys_page_debug(env, va); |
pa = cpu_get_phys_page_debug(env, va); |
431 |
printf("VA: 0x%08x, PA: 0x%08x PDE: 0x%08x\n", va, pa, pde_ptr); |
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr); |
432 |
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { |
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { |
433 |
pde_ptr = mmu_probe(va1, 1); |
pde_ptr = mmu_probe(va1, 1); |
434 |
if (pde_ptr) { |
if (pde_ptr) { |
435 |
pa = cpu_get_phys_page_debug(env, va1); |
pa = cpu_get_phys_page_debug(env, va1); |
436 |
printf(" VA: 0x%08x, PA: 0x%08x PDE: 0x%08x\n", va1, pa, pde_ptr); |
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr); |
437 |
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { |
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { |
438 |
pde_ptr = mmu_probe(va2, 0); |
pde_ptr = mmu_probe(va2, 0); |
439 |
if (pde_ptr) { |
if (pde_ptr) { |
440 |
pa = cpu_get_phys_page_debug(env, va2); |
pa = cpu_get_phys_page_debug(env, va2); |
441 |
printf(" VA: 0x%08x, PA: 0x%08x PTE: 0x%08x\n", va2, pa, pde_ptr); |
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr); |
442 |
} |
} |
443 |
} |
} |
444 |
} |
} |