summaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-19 12:58:30 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-19 12:58:30 +0000
commit5dcb6b914e5b99b64243477a23aea7e2a9852d17 (patch)
treecb2627ac298e49f72e2cd6749c01eb5713e6150d /target-sparc
parent36ddb83bd8fcb587e5d3b759543a13680e6836fb (diff)
downloadqemu-5dcb6b914e5b99b64243477a23aea7e2a9852d17.tar.gz
Use full 36-bit physical address space on SS10
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2830 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/cpu.h2
-rw-r--r--target-sparc/helper.c43
-rw-r--r--target-sparc/op_helper.c62
3 files changed, 82 insertions, 25 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 7e993b7a1d..b067d7b9bd 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -290,7 +290,7 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
void raise_exception(int tt);
-void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
+void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
int is_asi);
#include "cpu-all.h"
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 8f12667df6..da81562fc3 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -117,7 +117,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
}
*access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
- *physical = 0xfffff000;
+ *physical = 0xffffffffffff0000ULL;
/* SPARC reference MMU table walk: Context table->L1->L2->PTE */
/* Context base + context number */
@@ -203,7 +203,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
/* Even if large ptes, we map only one 4KB page in the cache to
avoid filling it too fast */
- *physical = ((pde & PTE_ADDR_MASK) << 4) + page_offset;
+ *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset;
return error_code;
}
@@ -212,7 +212,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
int is_user, int is_softmmu)
{
target_phys_addr_t paddr;
- unsigned long vaddr;
+ target_ulong vaddr;
int error_code = 0, prot, ret = 0, access_index;
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
@@ -220,7 +220,8 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
vaddr = address & TARGET_PAGE_MASK;
paddr &= TARGET_PAGE_MASK;
#ifdef DEBUG_MMU
- printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr);
+ printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
+ TARGET_FMT_lx "\n", address, paddr, vaddr);
#endif
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
return ret;
@@ -255,7 +256,8 @@ target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
uint32_t pde;
/* Context base + context number */
- pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
+ pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) +
+ (env->mmuregs[2] << 2);
pde = ldl_phys(pde_ptr);
switch (pde & PTE_ENTRYTYPE_MASK) {
@@ -314,30 +316,35 @@ target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
#ifdef DEBUG_MMU
void dump_mmu(CPUState *env)
{
- target_ulong va, va1, va2;
- unsigned int n, m, o;
- target_phys_addr_t pde_ptr, pa;
+ target_ulong va, va1, va2;
+ unsigned int n, m, o;
+ target_phys_addr_t pde_ptr, pa;
uint32_t pde;
printf("MMU dump:\n");
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
pde = ldl_phys(pde_ptr);
- printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]);
+ printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
+ (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
- pde_ptr = mmu_probe(env, va, 2);
- if (pde_ptr) {
+ pde = mmu_probe(env, va, 2);
+ if (pde) {
pa = cpu_get_phys_page_debug(env, va);
- printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr);
+ printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
+ " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
- pde_ptr = mmu_probe(env, va1, 1);
- if (pde_ptr) {
+ pde = mmu_probe(env, va1, 1);
+ if (pde) {
pa = cpu_get_phys_page_debug(env, va1);
- printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr);
+ printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
+ " PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
- pde_ptr = mmu_probe(env, va2, 0);
- if (pde_ptr) {
+ pde = mmu_probe(env, va2, 0);
+ if (pde) {
pa = cpu_get_phys_page_debug(env, va2);
- printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr);
+ printf(" VA: " TARGET_FMT_lx ", PA: "
+ TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
+ va2, pa, pde);
}
}
}
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index bdc5b0e154..93f61a8025 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -223,7 +223,31 @@ void helper_ld_asi(int asi, int size, int sign)
break;
}
break;
- case 0x21 ... 0x2f: /* MMU passthrough, unassigned */
+ case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
+ case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
+ switch(size) {
+ case 1:
+ ret = ldub_phys((target_phys_addr_t)T0
+ | ((target_phys_addr_t)(asi & 0xf) << 32));
+ break;
+ case 2:
+ ret = lduw_phys((target_phys_addr_t)(T0 & ~1)
+ | ((target_phys_addr_t)(asi & 0xf) << 32));
+ break;
+ default:
+ case 4:
+ ret = ldl_phys((target_phys_addr_t)(T0 & ~3)
+ | ((target_phys_addr_t)(asi & 0xf) << 32));
+ break;
+ case 8:
+ ret = ldl_phys((target_phys_addr_t)(T0 & ~3)
+ | ((target_phys_addr_t)(asi & 0xf) << 32));
+ T0 = ldl_phys((target_phys_addr_t)((T0 + 4) & ~3)
+ | ((target_phys_addr_t)(asi & 0xf) << 32));
+ break;
+ }
+ break;
+ case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
default:
do_unassigned_access(T0, 0, 0, 1);
ret = 0;
@@ -360,12 +384,38 @@ void helper_st_asi(int asi, int size, int sign)
}
}
return;
+ case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
+ case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
+ {
+ switch(size) {
+ case 1:
+ stb_phys((target_phys_addr_t)T0
+ | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ break;
+ case 2:
+ stw_phys((target_phys_addr_t)(T0 & ~1)
+ | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ break;
+ case 4:
+ default:
+ stl_phys((target_phys_addr_t)(T0 & ~3)
+ | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ break;
+ case 8:
+ stl_phys((target_phys_addr_t)(T0 & ~3)
+ | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ stl_phys((target_phys_addr_t)((T0 + 4) & ~3)
+ | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ break;
+ }
+ }
+ return;
case 0x31: /* Ross RT620 I-cache flush */
case 0x36: /* I-cache flash clear */
case 0x37: /* D-cache flash clear */
break;
case 9: /* Supervisor code access, XXX */
- case 0x21 ... 0x2f: /* MMU passthrough, unassigned */
+ case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
default:
do_unassigned_access(T0, 1, 0, 1);
return;
@@ -1035,7 +1085,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
#endif
#ifndef TARGET_SPARC64
-void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
+void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
int is_asi)
{
CPUState *saved_env;
@@ -1058,7 +1108,7 @@ void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
env->mmuregs[4] = addr; /* Fault address register */
if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
#ifdef DEBUG_UNASSIGNED
- printf("Unassigned mem access to " TARGET_FMT_lx " from " TARGET_FMT_lx
+ printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
"\n", addr, env->pc);
#endif
raise_exception(TT_DATA_ACCESS);
@@ -1066,7 +1116,7 @@ void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
env = saved_env;
}
#else
-void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
+void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
int is_asi)
{
#ifdef DEBUG_UNASSIGNED
@@ -1076,7 +1126,7 @@ void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
generated code */
saved_env = env;
env = cpu_single_env;
- printf("Unassigned mem access to " TARGET_FMT_lx " from " TARGET_FMT_lx "\n",
+ printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n",
addr, env->pc);
env = saved_env;
#endif