All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC] sparc32 MXCC support
@ 2007-10-13 20:43 Robert Reif
  2007-10-14  7:37 ` Blue Swirl
  0 siblings, 1 reply; 3+ messages in thread
From: Robert Reif @ 2007-10-13 20:43 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 220 bytes --]

I'm trying to add SuperSparc II MXCC support and need some feedback.

Is there a better way to read and write physical memory in 64bit chunks?
I'm not sure what I'm doing is portable between 32/64 and big/little endian.

[-- Attachment #2: mxcc.diff.txt --]
[-- Type: text/plain, Size: 11808 bytes --]

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	13 Oct 2007 20:35:48 -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	13 Oct 2007 20:35:49 -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	13 Oct 2007 20:35:49 -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, 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	13 Oct 2007 20:35:51 -0000
@@ -2,6 +2,7 @@
 
 //#define DEBUG_PCALL
 //#define DEBUG_MMU
+#define DEBUG_MXCC
 //#define DEBUG_UNALIGNED
 //#define DEBUG_UNASSIGNED
 
@@ -139,12 +140,68 @@ 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;
+            }
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: unsupported size\n", asi, size, sign, T0);
+#endif
+            break;
+        case 0x01c00a04: /* MXCC control register */
+            if (size == 4)
+                ret = env->mxccregs[3];
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: unsupported size\n", asi, size, sign, T0);
+#endif
+            break;
+        case 0x01c00f00: /* MBus port address register */
+            if (size == 8) {
+                ret = env->mxccregs[7];
+                T0 = env->mxccregs[7] >> 32;
+            }
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: unsupported size\n", asi, size, sign, T0);
+#endif
+            break;
+        default:
+#ifdef DEBUG_MXCC
+            printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: unsupported address\n", asi, size, sign, T0);
+#endif
+            ret = 0;
+            break;
+        }
+#ifdef DEBUG_MXCC
+        printf("helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: ret = %08x, T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
+        dump_mxcc(env);
+#endif
         break;
     case 3: /* MMU probe */
         {
@@ -302,6 +359,116 @@ 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;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            break;
+        case 0x01c00008: /* MXCC stream data register 1 */
+            if (size == 8)
+                env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            break;
+        case 0x01c00010: /* MXCC stream data register 2 */
+            if (size == 8)
+                env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            break;
+        case 0x01c00018: /* MXCC stream data register 3 */
+            if (size == 8)
+                env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            break;
+        case 0x01c00100: /* MXCC stream source */
+            if (size == 8)
+                env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            env->mxccdata[0] = (uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] +  4) & 0xffffffffULL)) +
+                ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] +  0) & 0xffffffffULL))) << 32);
+            env->mxccdata[1] = (uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 12) & 0xffffffffULL)) +
+                ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] +  8) & 0xffffffffULL))) << 32);
+            env->mxccdata[2] = (uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 20) & 0xffffffffULL)) +
+                ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 16) & 0xffffffffULL))) << 32);
+            env->mxccdata[3] = (uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 28) & 0xffffffffULL)) +
+                ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 24) & 0xffffffffULL))) << 32);
+            break;
+        case 0x01c00200: /* MXCC stream destination */
+            if (size == 8)
+                env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] +  0) & 0xffffffffULL), env->mxccdata[0] >> 32);
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] +  4) & 0xffffffffULL), env->mxccdata[0]);
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] +  8) & 0xffffffffULL), env->mxccdata[1] >> 32);
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] + 12) & 0xffffffffULL), env->mxccdata[1]);
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] + 16) & 0xffffffffULL), env->mxccdata[2] >> 32);
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] + 20) & 0xffffffffULL), env->mxccdata[2]);
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] + 24) & 0xffffffffULL), env->mxccdata[3] >> 32);
+            stl_phys((target_phys_addr_t)((env->mxccregs[1] + 28) & 0xffffffffULL), env->mxccdata[3]);
+            break;
+        case 0x01c00a00: /* MXCC control register */
+            if (size == 8)
+                env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            break;
+        case 0x01c00a04: /* MXCC control register */
+            if (size == 4)
+                env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000) | T1;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            break;
+        case 0x01c00e00: /* MXCC error register  */
+            if (size == 8)
+                env->mxccregs[6] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            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;
+#ifdef DEBUG_MXCC
+            else
+                printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+            break;
+        default:
+#ifdef DEBUG_MXCC
+            printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x: unsupported address\n", asi, size, T0, T1);
+#endif
+            break;
+        }
+#ifdef DEBUG_MXCC
+        printf("helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x\n", asi, size, T0, T1);
+        dump_mxcc(env);
+#endif
         break;
     case 3: /* MMU flush */
         {
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	13 Oct 2007 20:35:53 -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, 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;
 }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [RFC] sparc32 MXCC support
  2007-10-13 20:43 [Qemu-devel] [RFC] sparc32 MXCC support Robert Reif
@ 2007-10-14  7:37 ` Blue Swirl
  2007-10-14 13:36   ` Robert Reif
  0 siblings, 1 reply; 3+ messages in thread
From: Blue Swirl @ 2007-10-14  7:37 UTC (permalink / raw)
  To: qemu-devel

On 10/13/07, Robert Reif <reif@earthlink.net> wrote:
> I'm trying to add SuperSparc II MXCC support and need some feedback.
>
> Is there a better way to read and write physical memory in 64bit chunks?
> I'm not sure what I'm doing is portable between 32/64 and big/little endian.

Thank you for your effort. Applying the patch allows NetBSD on SS-10
to boot as far as on SS-5, previously it crashed.

I think the code is portable, but I think changing the register type
to uint32_t and using a DPRINTF system like used in for example
hw/iommu.c should make the code slightly clearer.

For the memory access, ldl/q_phys/stl/q_phys is used in other block
copy routines. For longer blocks or if the address can be unaligned,
cpu_physical_memory_read() could be a better choice.

> +int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, int cpu);

unsigned int cpu?

> +                printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: unsupported size\n", asi, size, sign, T0);

If it's an error to access the registers with different size, you
should use do_unassigned_access() to report this.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [RFC] sparc32 MXCC support
  2007-10-14  7:37 ` Blue Swirl
@ 2007-10-14 13:36   ` Robert Reif
  0 siblings, 0 replies; 3+ messages in thread
From: Robert Reif @ 2007-10-14 13:36 UTC (permalink / raw)
  To: qemu-devel

Blue Swirl wrote:

>On 10/13/07, Robert Reif <reif@earthlink.net> wrote:
>  
>
>>I'm trying to add SuperSparc II MXCC support and need some feedback.
>>
>>Is there a better way to read and write physical memory in 64bit chunks?
>>I'm not sure what I'm doing is portable between 32/64 and big/little endian.
>>    
>>
>
>Thank you for your effort. Applying the patch allows NetBSD on SS-10
>to boot as far as on SS-5, previously it crashed.
>
>I think the code is portable, but I think changing the register type
>to uint32_t and using a DPRINTF system like used in for example
>hw/iommu.c should make the code slightly clearer.
>
I don't have access to chip specs but from reading linux and *bsd code it
appears that the registers are 64 bits wide but sometimes accessed as 32 
bits to get
only the bottom 32 bits.  Do you mean using two uint32_t for a 64 bit
register?  How about a union of 2 uint32_t and a uint64_t.  Is that 
portable?
Never mind.  I just found out there is an ldq_phys and stq_phys.  I'll 
use those.

I looked at DPRINTF but would need a DPRINTF_MMU and DPRINTF_MXCC ...
Would that be acceptable?

>
>For the memory access, ldl/q_phys/stl/q_phys is used in other block
>copy routines. For longer blocks or if the address can be unaligned,
>cpu_physical_memory_read() could be a better choice.
>  
>
>  
>
>>+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, int cpu);
>>    
>>
>
>unsigned int cpu?
>  
>
OK

>>+                printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: unsupported size\n", asi, size, sign, T0);
>>    
>>
>
>If it's an error to access the registers with different size, you
>should use do_unassigned_access() to report this.
>
>  
>
These are more for me to make sure I catch all the necessary accesses 
without adding unnecessary code.
linux 2.4 and netbsd only use the ones I have implemented.  openboot 
uses more and
also some undocumented ones which are caught by this but I don't know 
how to handle
them yet.  I will use do_unassigned_access where necessary now.

Thanks for the review.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-10-14 13:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-13 20:43 [Qemu-devel] [RFC] sparc32 MXCC support Robert Reif
2007-10-14  7:37 ` Blue Swirl
2007-10-14 13:36   ` Robert Reif

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.