sh4: implement missing mmaped TLB read functions
authorAurelien Jarno <aurelien@aurel32.net>
Wed, 26 Jan 2011 01:16:39 +0000 (02:16 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Wed, 26 Jan 2011 13:30:24 +0000 (14:30 +0100)
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
hw/sh7750.c
target-sh4/cpu.h
target-sh4/helper.c

index f76f2711059162f8dd5bf1ebbb67752cc41eba00..19d5bf8537e5bb00c5b710a1691a3c40507bdc72 100644 (file)
@@ -625,6 +625,7 @@ static uint32_t invalid_read(void *opaque, target_phys_addr_t addr)
 
 static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr)
 {
+    SH7750State *s = opaque;
     uint32_t ret = 0;
 
     switch (MM_REGION_TYPE(addr)) {
@@ -633,19 +634,21 @@ static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr)
         /* do nothing */
        break;
     case MM_ITLB_ADDR:
+        ret = cpu_sh4_read_mmaped_itlb_addr(s->cpu, addr);
+        break;
     case MM_ITLB_DATA:
-        /* XXXXX */
-        abort();
-       break;
+        ret = cpu_sh4_read_mmaped_itlb_data(s->cpu, addr);
+        break;
     case MM_OCACHE_ADDR:
     case MM_OCACHE_DATA:
         /* do nothing */
        break;
     case MM_UTLB_ADDR:
+        ret = cpu_sh4_read_mmaped_utlb_addr(s->cpu, addr);
+        break;
     case MM_UTLB_DATA:
-        /* XXXXX */
-        abort();
-       break;
+        ret = cpu_sh4_read_mmaped_utlb_data(s->cpu, addr);
+        break;
     default:
         abort();
     }
index 9eccb0cf8c12492968517ee6faf284d6a0cf3cfa..789d1880b7249066e2892031ef4e848b2a9a9e2c 100644 (file)
@@ -201,12 +201,20 @@ void do_interrupt(CPUSH4State * env);
 void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #if !defined(CONFIG_USER_ONLY)
 void cpu_sh4_invalidate_tlb(CPUSH4State *s);
+uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s,
+                                       target_phys_addr_t addr);
 void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
                                     uint32_t mem_value);
+uint32_t cpu_sh4_read_mmaped_itlb_data(CPUSH4State *s,
+                                       target_phys_addr_t addr);
 void cpu_sh4_write_mmaped_itlb_data(CPUSH4State *s, target_phys_addr_t addr,
                                     uint32_t mem_value);
+uint32_t cpu_sh4_read_mmaped_utlb_addr(CPUSH4State *s,
+                                       target_phys_addr_t addr);
 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
                                     uint32_t mem_value);
+uint32_t cpu_sh4_read_mmaped_utlb_data(CPUSH4State *s,
+                                       target_phys_addr_t addr);
 void cpu_sh4_write_mmaped_utlb_data(CPUSH4State *s, target_phys_addr_t addr,
                                     uint32_t mem_value);
 #endif
index 4cd42b51cbf0b6193217b8ba625c43f51cd88b1b..785e9e54e74089ea84fa08a8fb81fea961942dd0 100644 (file)
@@ -567,6 +567,17 @@ void cpu_load_tlb(CPUSH4State * env)
     tlb_flush(s, 1);
 }
 
+uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s,
+                                       target_phys_addr_t addr)
+{
+    int index = (addr & 0x00000300) >> 8;
+    tlb_t * entry = &s->itlb[index];
+
+    return (entry->vpn  << 10) |
+           (entry->v    <<  8) |
+           (entry->asid);
+}
+
 void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
                                    uint32_t mem_value)
 {
@@ -586,6 +597,29 @@ void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
     entry->v = v;
 }
 
+uint32_t cpu_sh4_read_mmaped_itlb_data(CPUSH4State *s,
+                                       target_phys_addr_t addr)
+{
+    int array = (addr & 0x00800000) >> 23;
+    int index = (addr & 0x00000300) >> 8;
+    tlb_t * entry = &s->itlb[index];
+
+    if (array == 0) {
+        /* ITLB Data Array 1 */
+        return (entry->ppn << 10) |
+               (entry->v   <<  8) |
+               (entry->pr  <<  5) |
+               ((entry->sz & 1) <<  6) |
+               ((entry->sz & 2) <<  4) |
+               (entry->c   <<  3) |
+               (entry->sh  <<  1);
+    } else {
+        /* ITLB Data Array 2 */
+        return (entry->tc << 1) |
+               (entry->sa);
+    }
+}
+
 void cpu_sh4_write_mmaped_itlb_data(CPUSH4State *s, target_phys_addr_t addr,
                                     uint32_t mem_value)
 {
@@ -614,6 +648,19 @@ void cpu_sh4_write_mmaped_itlb_data(CPUSH4State *s, target_phys_addr_t addr,
     }
 }
 
+uint32_t cpu_sh4_read_mmaped_utlb_addr(CPUSH4State *s,
+                                       target_phys_addr_t addr)
+{
+    int index = (addr & 0x00003f00) >> 8;
+    tlb_t * entry = &s->utlb[index];
+
+    increment_urc(s); /* per utlb access */
+
+    return (entry->vpn  << 10) |
+           (entry->v    <<  8) |
+           (entry->asid);
+}
+
 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
                                    uint32_t mem_value)
 {
@@ -686,6 +733,33 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
     }
 }
 
+uint32_t cpu_sh4_read_mmaped_utlb_data(CPUSH4State *s,
+                                       target_phys_addr_t addr)
+{
+    int array = (addr & 0x00800000) >> 23;
+    int index = (addr & 0x00003f00) >> 8;
+    tlb_t * entry = &s->utlb[index];
+
+    increment_urc(s); /* per utlb access */
+
+    if (array == 0) {
+        /* ITLB Data Array 1 */
+        return (entry->ppn << 10) |
+               (entry->v   <<  8) |
+               (entry->pr  <<  5) |
+               ((entry->sz & 1) <<  6) |
+               ((entry->sz & 2) <<  4) |
+               (entry->c   <<  3) |
+               (entry->d   <<  2) |
+               (entry->sh  <<  1) |
+               (entry->wt);
+    } else {
+        /* ITLB Data Array 2 */
+        return (entry->tc << 1) |
+               (entry->sa);
+    }
+}
+
 void cpu_sh4_write_mmaped_utlb_data(CPUSH4State *s, target_phys_addr_t addr,
                                     uint32_t mem_value)
 {