summary refs log tree commit diff stats
path: root/target-sparc
diff options
context:
space:
mode:
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