qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] sparc32: add MXCC support


From: Robert Reif
Subject: [Qemu-devel] [PATCH] sparc32: add MXCC support
Date: Sun, 14 Oct 2007 11:16:51 -0400
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.2) Gecko/20040308

Updated patch base of feedback.

This patch adds SuperSparc MXCC support.
DPRINTF_MMU and DPRINTF_MXCC added.

I decided not to use do_unassigned_access() at this time because I don't know what real hardware does.
Index: hw/sun4m.c
===================================================================
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.55
diff -p -u -r1.55 sun4m.c
--- hw/sun4m.c  6 Oct 2007 11:28:21 -0000       1.55
+++ hw/sun4m.c  14 Oct 2007 15:07:52 -0000
@@ -327,7 +327,7 @@ static void *sun4m_hw_init(const struct 
 
     for(i = 0; i < smp_cpus; i++) {
         env = cpu_init();
-        cpu_sparc_register(env, def);
+        cpu_sparc_register(env, def, i);
         envs[i] = env;
         if (i == 0) {
             qemu_register_reset(main_cpu_reset, env);
Index: linux-user/main.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/main.c,v
retrieving revision 1.132
diff -p -u -r1.132 main.c
--- linux-user/main.c   12 Oct 2007 06:47:46 -0000      1.132
+++ linux-user/main.c   14 Oct 2007 15:07:53 -0000
@@ -2139,7 +2139,7 @@ int main(int argc, char **argv)
             fprintf(stderr, "Unable to find Sparc CPU definition\n");
             exit(1);
         }
-        cpu_sparc_register(env, def);
+        cpu_sparc_register(env, def, 0);
        env->pc = regs->pc;
        env->npc = regs->npc;
         env->y = regs->y;
Index: target-sparc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.53
diff -p -u -r1.53 cpu.h
--- target-sparc/cpu.h  12 Oct 2007 06:47:46 -0000      1.53
+++ target-sparc/cpu.h  14 Oct 2007 15:07:53 -0000
@@ -210,6 +210,8 @@ typedef struct CPUSPARCState {
     uint64_t dtlb_tte[64];
 #else
     uint32_t mmuregs[16];
+    uint64_t mxccdata[4];
+    uint64_t mxccregs[8];
 #endif
     /* temporary float registers */
     float32 ft0, ft1;
@@ -266,7 +268,7 @@ int cpu_sparc_close(CPUSPARCState *s);
 int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
                                                  ...));
-int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def);
+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, unsigned 
int cpu);
 
 #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) |             \
                       (env->psref? PSR_EF : 0) |                        \
Index: target-sparc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.41
diff -p -u -r1.41 op_helper.c
--- target-sparc/op_helper.c    1 Oct 2007 17:07:58 -0000       1.41
+++ target-sparc/op_helper.c    14 Oct 2007 15:07:54 -0000
@@ -2,9 +2,24 @@
 
 //#define DEBUG_PCALL
 //#define DEBUG_MMU
+//#define DEBUG_MXCC
 //#define DEBUG_UNALIGNED
 //#define DEBUG_UNASSIGNED
 
+#ifdef DEBUG_MMU
+#define DPRINTF_MMU(fmt, args...) \
+do { printf("MMU: " fmt , ##args); } while (0)
+#else
+#define DPRINTF_MMU(fmt, args...)
+#endif
+
+#ifdef DEBUG_MXCC
+#define DPRINTF_MXCC(fmt, args...) \
+do { printf("MXCC: " fmt , ##args); } while (0)
+#else
+#define DPRINTF_MXCC(fmt, args...)
+#endif
+
 void raise_exception(int tt)
 {
     env->exception_index = tt;
@@ -139,12 +154,57 @@ GEN_FCMP(fcmped_fcc3, float64, DT0, DT1,
 
 #ifndef TARGET_SPARC64
 #ifndef CONFIG_USER_ONLY
+
+#ifdef DEBUG_MXCC
+void dump_mxcc(CPUState *env)
+{
+    printf("mxccdata: %016llx %016llx %016llx %016llx\n",
+        env->mxccdata[0], env->mxccdata[1], env->mxccdata[2], 
env->mxccdata[3]);
+    printf("mxccregs: %016llx %016llx %016llx %016llx\n"
+           "          %016llx %016llx %016llx %016llx\n",
+        env->mxccregs[0], env->mxccregs[1], env->mxccregs[2], env->mxccregs[3],
+        env->mxccregs[4], env->mxccregs[5], env->mxccregs[6], 
env->mxccregs[7]);
+}
+#endif
+
 void helper_ld_asi(int asi, int size, int sign)
 {
     uint32_t ret = 0;
+#ifdef DEBUG_MXCC
+    uint32_t last_T0 = T0;
+#endif
 
     switch (asi) {
     case 2: /* SuperSparc MXCC registers */
+        switch (T0) {
+        case 0x01c00a00: /* MXCC control register */
+            if (size == 8) {
+                ret = env->mxccregs[3];
+                T0 = env->mxccregs[3] >> 32;
+            } else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00a04: /* MXCC control register */
+            if (size == 4)
+                ret = env->mxccregs[3];
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00f00: /* MBus port address register */
+            if (size == 8) {
+                ret = env->mxccregs[7];
+                T0 = env->mxccregs[7] >> 32;
+            } else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        default:
+            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
+            break;
+        }
+        DPRINTF_MXCC("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x, 
T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
+#ifdef DEBUG_MXCC
+        dump_mxcc(env);
+#endif
         break;
     case 3: /* MMU probe */
         {
@@ -157,9 +217,7 @@ void helper_ld_asi(int asi, int size, in
                 ret = mmu_probe(env, T0, mmulev);
                 //bswap32s(&ret);
             }
-#ifdef DEBUG_MMU
-            printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
-#endif
+            DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, 
ret);
         }
         break;
     case 4: /* read MMU regs */
@@ -169,9 +227,7 @@ void helper_ld_asi(int asi, int size, in
             ret = env->mmuregs[reg];
             if (reg == 3) /* Fault status cleared on read */
                 env->mmuregs[reg] = 0;
-#ifdef DEBUG_MMU
-            printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
-#endif
+            DPRINTF_MMU("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
         }
         break;
     case 9: /* Supervisor code access */
@@ -302,15 +358,93 @@ void helper_st_asi(int asi, int size)
 {
     switch(asi) {
     case 2: /* SuperSparc MXCC registers */
+        switch (T0) {
+        case 0x01c00000: /* MXCC stream data register 0 */
+            if (size == 8)
+                env->mxccdata[0] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00008: /* MXCC stream data register 1 */
+            if (size == 8)
+                env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00010: /* MXCC stream data register 2 */
+            if (size == 8)
+                env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00018: /* MXCC stream data register 3 */
+            if (size == 8)
+                env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00100: /* MXCC stream source */
+            if (size == 8)
+                env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +  
0);
+            env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +  
8);
+            env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 
16);
+            env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 
24);
+            break;
+        case 0x01c00200: /* MXCC stream destination */
+            if (size == 8)
+                env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0, 
env->mxccdata[0]);
+            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8, 
env->mxccdata[1]);
+            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, 
env->mxccdata[2]);
+            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24, 
env->mxccdata[3]);
+            break;
+        case 0x01c00a00: /* MXCC control register */
+            if (size == 8)
+                env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00a04: /* MXCC control register */
+            if (size == 4)
+                env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000) | 
T1;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        case 0x01c00e00: /* MXCC error register  */
+            if (size == 8)
+                env->mxccregs[6] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            if (env->mxccregs[6] == 0xffffffffffffffffULL) {
+                // this is probably a reset
+            }
+            break;
+        case 0x01c00f00: /* MBus port address register */
+            if (size == 8)
+                env->mxccregs[7] = ((uint64_t)T1 << 32) | T2;
+            else
+                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, 
size);
+            break;
+        default:
+            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
+            break;
+        }
+        DPRINTF_MXCC("asi = %d, size = %d, T0 = %08x, T1 = %08x\n", asi, size, 
T0, T1);
+#ifdef DEBUG_MXCC
+        dump_mxcc(env);
+#endif
         break;
     case 3: /* MMU flush */
         {
             int mmulev;
 
             mmulev = (T0 >> 8) & 15;
-#ifdef DEBUG_MMU
-            printf("mmu flush level %d\n", mmulev);
-#endif
+            DPRINTF_MMU("mmu flush level %d\n", mmulev);
             switch (mmulev) {
             case 0: // flush page
                 tlb_flush_page(env, T0 & 0xfffff000);
@@ -359,10 +493,10 @@ void helper_st_asi(int asi, int size)
                 env->mmuregs[reg] = T1;
                 break;
             }
-#ifdef DEBUG_MMU
             if (oldreg != env->mmuregs[reg]) {
-                printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, 
env->mmuregs[reg]);
+                DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, 
oldreg, env->mmuregs[reg]);
             }
+#ifdef DEBUG_MMU
             dump_mmu(env);
 #endif
             return;
@@ -962,8 +1096,8 @@ void helper_st_asi(int asi, int size)
             // Mappings generated during D/I MMU disabled mode are
             // invalid in normal mode
             if (oldreg != env->lsu) {
+                DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", 
oldreg, env->lsu);
 #ifdef DEBUG_MMU
-                printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, 
env->lsu);
                 dump_mmu(env);
 #endif
                 tlb_flush(env, 1);
@@ -995,10 +1129,10 @@ void helper_st_asi(int asi, int size)
                 break;
             }
             env->immuregs[reg] = T1;
-#ifdef DEBUG_MMU
             if (oldreg != env->immuregs[reg]) {
-                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 
"\n", reg, oldreg, env->immuregs[reg]);
+                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" 
PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
             }
+#ifdef DEBUG_MMU
             dump_mmu(env);
 #endif
             return;
@@ -1064,10 +1198,10 @@ void helper_st_asi(int asi, int size)
                 break;
             }
             env->dmmuregs[reg] = T1;
-#ifdef DEBUG_MMU
             if (oldreg != env->dmmuregs[reg]) {
-                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 
"\n", reg, oldreg, env->dmmuregs[reg]);
+                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" 
PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
             }
+#ifdef DEBUG_MMU
             dump_mmu(env);
 #endif
             return;
Index: target-sparc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.74
diff -p -u -r1.74 translate.c
--- target-sparc/translate.c    10 Oct 2007 19:11:54 -0000      1.74
+++ target-sparc/translate.c    14 Oct 2007 15:07:56 -0000
@@ -3618,12 +3618,13 @@ void sparc_cpu_list (FILE *f, int (*cpu_
     }
 }
 
-int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def)
+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, unsigned 
int cpu)
 {
     env->version = def->iu_version;
     env->fsr = def->fpu_version;
 #if !defined(TARGET_SPARC64)
     env->mmuregs[0] |= def->mmu_version;
+    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
 #endif
     return 0;
 }

reply via email to

[Prev in Thread] Current Thread [Next in Thread]