Fix typo
[qemu] / target-sh4 / helper.c
index f077462..94be136 100644 (file)
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
  */
 #include <stdarg.h>
 #include <stdlib.h>
@@ -23,7 +23,6 @@
 #include <string.h>
 #include <inttypes.h>
 #include <signal.h>
-#include <assert.h>
 
 #include "cpu.h"
 #include "exec-all.h"
@@ -60,6 +59,12 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
     return addr;
 }
 
+int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
+{
+    /* For user mode, only U0 area is cachable. */
+    return !(addr & 0x80000000);
+}
+
 #else /* !CONFIG_USER_ONLY */
 
 #define MMU_OK                   0
@@ -105,7 +110,7 @@ void do_interrupt(CPUState * env)
        }
     }
 
-    if (loglevel & CPU_LOG_INT) {
+    if (qemu_loglevel_mask(CPU_LOG_INT)) {
        const char *expname;
        switch (env->exception_index) {
        case 0x0e0:
@@ -151,9 +156,9 @@ void do_interrupt(CPUState * env)
             expname = do_irq ? "interrupt" : "???";
             break;
        }
-       fprintf(logfile, "exception 0x%03x [%s] raised\n",
-               irq_vector, expname);
-       cpu_dump_state(env, logfile, fprintf, 0);
+       qemu_log("exception 0x%03x [%s] raised\n",
+                 irq_vector, expname);
+       log_cpu_state(env, 0);
     }
 
     env->ssr = env->sr;
@@ -255,7 +260,7 @@ static int find_tlb_entry(CPUState * env, target_ulong address,
     for (i = 0; i < nbtlb; i++) {
        if (!entries[i].v)
            continue;           /* Invalid entry */
-       if (use_asid && entries[i].asid != asid)
+       if (!entries[i].sh && use_asid && entries[i].asid != asid)
            continue;           /* Bad ASID */
 #if 0
        switch (entries[i].sz) {
@@ -304,7 +309,7 @@ static void increment_urc(CPUState * env)
     urb = ((env->mmucr) >> 18) & 0x3f;
     urc = ((env->mmucr) >> 10) & 0x3f;
     urc++;
-    if (urc == urb || urc == UTLB_SIZE - 1)
+    if ((urb > 0 && urc > urb) || urc > (UTLB_SIZE - 1))
        urc = 0;
     env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10);
 }
@@ -313,8 +318,8 @@ static void increment_urc(CPUState * env)
    Return entry, MMU_ITLB_MISS, MMU_ITLB_MULTIPLE or MMU_DTLB_MULTIPLE
    Update the itlb from utlb if update is not 0
 */
-int find_itlb_entry(CPUState * env, target_ulong address,
-                   int use_asid, int update)
+static int find_itlb_entry(CPUState * env, target_ulong address,
+                           int use_asid, int update)
 {
     int e, n;
 
@@ -344,7 +349,7 @@ int find_itlb_entry(CPUState * env, target_ulong address,
 
 /* Find utlb entry
    Return entry, MMU_DTLB_MISS, MMU_DTLB_MULTIPLE */
-int find_utlb_entry(CPUState * env, target_ulong address, int use_asid)
+static int find_utlb_entry(CPUState * env, target_ulong address, int use_asid)
 {
     /* per utlb access */
     increment_urc(env);
@@ -418,9 +423,9 @@ static int get_mmu_address(CPUState * env, target_ulong * physical,
     return n;
 }
 
-int get_physical_address(CPUState * env, target_ulong * physical,
-                        int *prot, target_ulong address,
-                        int rw, int access_type)
+static int get_physical_address(CPUState * env, target_ulong * physical,
+                                int *prot, target_ulong address,
+                                int rw, int access_type)
 {
     /* P1, P2 and P4 areas do not use translation */
     if ((address >= 0x80000000 && address < 0xc0000000) ||
@@ -439,19 +444,7 @@ int get_physical_address(CPUState * env, target_ulong * physical,
        if (address >= 0x80000000 && address < 0xc0000000) {
            /* Mask upper 3 bits for P1 and P2 areas */
            *physical = address & 0x1fffffff;
-        } else if (address >= 0xfd000000 && address < 0xfe000000) {
-            /* PCI memory space */
-            *physical = address;
-       } else if (address >= 0xfc000000) {
-           /*
-            * Mask upper 3 bits for control registers in P4 area,
-            * to unify access to control registers via P0-P3 area.
-            * The addresses for cache store queue, TLB address array
-            * are not masked.
-            */
-       *physical = address & 0x1fffffff;
        } else {
-           /* access to cache store queue, or TLB address array. */
            *physical = address;
        }
        *prot = PAGE_READ | PAGE_WRITE;
@@ -537,7 +530,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
     return physical;
 }
 
-void cpu_load_tlb(CPUState * env)
+void cpu_load_tlb(CPUSH4State * env)
 {
     int n = cpu_mmucr_urc(env->mmucr);
     tlb_t * entry = &env->utlb[n];
@@ -550,9 +543,6 @@ void cpu_load_tlb(CPUState * env)
        }
     }
 
-    /* per utlb access cannot implemented. */
-    increment_urc(env);
-
     /* Take values into cpu status from registers. */
     entry->asid = (uint8_t)cpu_pteh_asid(env->pteh);
     entry->vpn  = cpu_pteh_vpn(env->pteh);
@@ -593,6 +583,7 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
     uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9);
     uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8);
     uint8_t asid = (uint8_t)(mem_value & 0x000000ff);
+    int use_asid = (s->mmucr & MMUCR_SV) == 0 || (s->sr & SR_MD) == 0;
 
     if (associate) {
         int i;
@@ -605,7 +596,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
             if (!entry->v)
                continue;
 
-            if (entry->vpn == vpn && entry->asid == asid) {
+            if (entry->vpn == vpn
+                && (!use_asid || entry->asid == asid || entry->sh)) {
                if (utlb_match_entry) {
                    /* Multiple TLB Exception */
                    s->exception_index = 0x140;
@@ -624,7 +616,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
        /* search ITLB */
        for (i = 0; i < ITLB_SIZE; i++) {
             tlb_t * entry = &s->itlb[i];
-            if (entry->vpn == vpn && entry->asid == asid) {
+            if (entry->vpn == vpn
+                && (!use_asid || entry->asid == asid || entry->sh)) {
                if (entry->v && !v)
                    needs_tlb_flush = 1;
                if (utlb_match_entry)
@@ -656,4 +649,48 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
     }
 }
 
+int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
+{
+    int n;
+    int use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
+
+    /* check area */
+    if (env->sr & SR_MD) {
+        /* For previledged mode, P2 and P4 area is not cachable. */
+        if ((0xA0000000 <= addr && addr < 0xC0000000) || 0xE0000000 <= addr)
+            return 0;
+    } else {
+        /* For user mode, only U0 area is cachable. */
+        if (0x80000000 <= addr)
+            return 0;
+    }
+
+    /*
+     * TODO : Evaluate CCR and check if the cache is on or off.
+     *        Now CCR is not in CPUSH4State, but in SH7750State.
+     *        When you move the ccr inot CPUSH4State, the code will be
+     *        as follows.
+     */
+#if 0
+    /* check if operand cache is enabled or not. */
+    if (!(env->ccr & 1))
+        return 0;
+#endif
+
+    /* if MMU is off, no check for TLB. */
+    if (env->mmucr & MMUCR_AT)
+        return 1;
+
+    /* check TLB */
+    n = find_tlb_entry(env, addr, env->itlb, ITLB_SIZE, use_asid);
+    if (n >= 0)
+        return env->itlb[n].c;
+
+    n = find_tlb_entry(env, addr, env->utlb, UTLB_SIZE, use_asid);
+    if (n >= 0)
+        return env->utlb[n].c;
+
+    return 0;
+}
+
 #endif