Fix elf loader range checking
[qemu] / target-sparc / helper.c
index 7943e12..2f41418 100644 (file)
@@ -23,7 +23,6 @@
 #include <string.h>
 #include <inttypes.h>
 #include <signal.h>
-#include <assert.h>
 
 #include "cpu.h"
 #include "exec-all.h"
@@ -402,12 +401,12 @@ static int get_physical_address_data(CPUState *env,
             mask = 0xffffffffffc00000ULL;
             break;
         }
-        // ctx match, vaddr match?
+        // ctx match, vaddr match, valid?
         if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
-            (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
-            // valid, access ok?
-            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
-                ((env->dtlb_tte[i] & 0x4) && is_user) ||
+            (address & mask) == (env->dtlb_tag[i] & mask) &&
+            (env->dtlb_tte[i] & 0x8000000000000000ULL)) {
+            // access ok?
+            if (((env->dtlb_tte[i] & 0x4) && is_user) ||
                 (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
                 if (env->dmmuregs[3]) /* Fault status register */
                     env->dmmuregs[3] = 2; /* overflow (not read before
@@ -420,8 +419,8 @@ static int get_physical_address_data(CPUState *env,
 #endif
                 return 1;
             }
-            *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) +
-                (address & ~mask & 0x1fffffff000ULL);
+            *physical = ((env->dtlb_tte[i] & mask) | (address & ~mask)) &
+                        0x1ffffffe000ULL;
             *prot = PAGE_READ;
             if (env->dtlb_tte[i] & 0x2)
                 *prot |= PAGE_WRITE;
@@ -465,12 +464,12 @@ static int get_physical_address_code(CPUState *env,
             mask = 0xffffffffffc00000ULL;
                 break;
         }
-        // ctx match, vaddr match?
+        // ctx match, vaddr match, valid?
         if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
-            (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
-            // valid, access ok?
-            if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
-                ((env->itlb_tte[i] & 0x4) && is_user)) {
+            (address & mask) == (env->itlb_tag[i] & mask) &&
+            (env->itlb_tte[i] & 0x8000000000000000ULL)) {
+            // access ok?
+            if ((env->itlb_tte[i] & 0x4) && is_user) {
                 if (env->immuregs[3]) /* Fault status register */
                     env->immuregs[3] = 2; /* overflow (not read before
                                              another fault) */
@@ -481,8 +480,8 @@ static int get_physical_address_code(CPUState *env,
 #endif
                 return 1;
             }
-            *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) +
-                (address & ~mask & 0x1fffffff000ULL);
+            *physical = ((env->itlb_tte[i] & mask) | (address & ~mask)) &
+                        0x1ffffffe000ULL;
             *prot = PAGE_EXEC;
             return 0;
         }
@@ -490,6 +489,7 @@ static int get_physical_address_code(CPUState *env,
 #ifdef DEBUG_MMU
     printf("TMISS at 0x%" PRIx64 "\n", address);
 #endif
+    /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
     env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
     env->exception_index = TT_TMISS;
     return 1;
@@ -639,12 +639,16 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 
 void cpu_reset(CPUSPARCState *env)
 {
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
+
     tlb_flush(env, 1);
     env->cwp = 0;
     env->wim = 1;
     env->regwptr = env->regbase + (env->cwp * 16);
 #if defined(CONFIG_USER_ONLY)
-    env->user_mode_only = 1;
 #ifdef TARGET_SPARC64
     env->cleanwin = env->nwindows - 2;
     env->cansave = env->nwindows - 2;
@@ -655,10 +659,12 @@ void cpu_reset(CPUSPARCState *env)
     env->psret = 0;
     env->psrs = 1;
     env->psrps = 1;
+    CC_OP = CC_OP_FLAGS;
 #ifdef TARGET_SPARC64
     env->pstate = PS_PRIV;
     env->hpstate = HS_PRIV;
     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
+    env->lsu = 0;
 #else
     env->mmuregs[0] &= ~(MMU_E | MMU_NF);
     env->mmuregs[0] |= env->def->mmu_bm;
@@ -709,8 +715,6 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model)
     CPUSPARCState *env;
 
     env = qemu_mallocz(sizeof(CPUSPARCState));
-    if (!env)
-        return NULL;
     cpu_exec_init(env);
 
     gen_intermediate_code_init(env);
@@ -720,6 +724,7 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model)
         return NULL;
     }
     cpu_reset(env);
+    qemu_init_vcpu(env);
 
     return env;
 }
@@ -1363,8 +1368,6 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
                    "fpu_version mmu_version nwindows\n");
 }
 
-#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
-
 void cpu_dump_state(CPUState *env, FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags)
@@ -1408,6 +1411,9 @@ void cpu_dump_state(CPUState *env, FILE *f,
                 env->cansave, env->canrestore, env->otherwin, env->wstate,
                 env->cleanwin, env->nwindows - 1 - env->cwp);
 #else
+
+#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
+
     cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n",
                 GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
                 GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),