sparc32 asi cleanups and debug printf
PATCH 1/1 sparc32 asi cleanups and debug printf
This patch makes debugging asi and mxcc accesses easier to follow.
Index: target-sparc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v retrieving revision 1.51
op_helper.c +65 -32
@@ -6,6 +6,7 @@//#define DEBUG_MXCC //#define DEBUG_UNALIGNED //#define DEBUG_UNASSIGNED +//#define DEBUG_ASI #ifdef DEBUG_MMU #define DPRINTF_MMU(fmt, args...) \
@@ -187,7 +188,7 @@ void helper_ld_asi(int asi, int size, in {uint32_t ret =0 ;uint64_t tmp; -#ifdef DEBUG_MXCC +#if defined(DEBUG_MXCC ) || defined(DEBUG_ASI )uint32_t last_T0 =T0 ;#endif
@@ -199,26 +200,34 @@ void helper_ld_asi(int asi, int size, in ret = env->mxccregs[3 ];T0 = env->mxccregs[3 ] >>32 ; }else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("read %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); +DPRINTF_MXCC ("read %08x: unimplemented access size: %d\n" ,T0 , size); +break ; +case 0x01c00c00 :/* Module reset register */ +if (size ==8 ) { + ret = env->mxccregs[5 ]; +T0 = env->mxccregs[5 ] >>32 ; +// should we do something here? + }else +DPRINTF_MXCC ("read %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); +DPRINTF_MXCC ("read %08x: unimplemented access size: %d\n" ,T0 , size);break ;default : -DPRINTF_MXCC ("%08x: unimplemented address, size: %d\n" ,T0 , size); +DPRINTF_MXCC ("read %08x: unimplemented address, size: %d\n" ,T0 , size);break ; } -DPRINTF_MXCC ("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x," +DPRINTF_MXCC ("read(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);
@@ -355,6 +364,10 @@ void helper_ld_asi(int asi, int size, inbreak ; case 0x21 ... 0x2d: /* MMU passthrough, unassigned */default : +#ifdef DEBUG_ASI +printf ("read: %08x asi 0x%02x size %d unsupported address" , + last_T0, asi, size); +#endif do_unassigned_access (T0 ,0 ,0 ,1 ); ret =0 ;break ;
@@ -374,6 +387,11 @@ void helper_ld_asi(int asi, int size, in }else T1 = ret; + +#ifdef DEBUG_ASI +printf ("helper_ld_asi(asi 0x%02x, size %d, sign %d) T0 = %08x -> " +"T0 = %08x T1 = %08x\n" , asi, size, sign, last_T0,T0 ,T1 ); +#endif }void helper_st_asi (int asi,int size)
@@ -385,31 +403,31 @@ void helper_st_asi(int asi, int size)if (size ==8 ) env->mxccdata[0 ] = ((uint64_t )T1 <<32 ) |T2 ;else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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 );
@@ -419,7 +437,7 @@ void helper_st_asi(int asi, int size)if (size ==8 ) env->mxccregs[1 ] = ((uint64_t )T1 <<32 ) |T2 ;else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %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 ]);
@@ -429,34 +447,33 @@ void helper_st_asi(int asi, int size)if (size ==8 ) env->mxccregs[3 ] = ((uint64_t )T1 <<32 ) |T2 ;else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %08x: unimplemented access size: %d\n" ,T0 , size);break ;case 0x01c00e00 :/* MXCC error register */ +// writing a 1 bit clears the error if (size ==8 ) - env->mxccregs[6 ] = ((uint64_t )T1 <<32 ) |T2 ; + 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 - } +DPRINTF_MXCC ("write %08x: unimplemented access size: %d\n" ,T0 , size);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); +DPRINTF_MXCC ("write %08x: unimplemented access size: %d\n" ,T0 , size);break ;default : -DPRINTF_MXCC ("%08x: unimplemented address, size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %08x: unimplemented address, size: %d\n" ,T0 , size);break ; } -DPRINTF_MXCC ("asi = %d, size = %d, T0 = %08x, T1 = %08x\n" , asi, size,T0 ,T1 ); +DPRINTF_MXCC ("write(asi %d, size %d) T0 = %08x, T1 = %08x, T2 = %08x\n" , + asi, size,T0 ,T1 ,T2 );#ifdef DEBUG_MXCC dump_mxcc (env);#endif
@@ -483,8 +500,8 @@ void helper_st_asi(int asi, int size)#ifdef DEBUG_MMU dump_mmu (env);#endif -return ; } +break ;case 4 :/* write MMU regs */ {int reg = (T0 >>8 ) &0xf ;
@@ -515,14 +532,13 @@ void helper_st_asi(int asi, int size) env->mmuregs[reg] =T1 ;break ; } -if (oldreg != env->mmuregs[reg]) { +if (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 ; } +break ;case 0xa :/* User data access */ switch (size) {case 1 :
@@ -580,7 +596,7 @@ void helper_st_asi(int asi, int size)stl_kernel (dst, temp); } } -return ; +break ;case 0x1f :/* Block fill, stda access */ {// value (T1, T2)
@@ -595,7 +611,7 @@ void helper_st_asi(int asi, int size)for (i =0 ; i <32 ; i +=8 , dst +=8 )stq_kernel (dst, val); } -return ; +break ;case 0x20 :/* MMU passthrough */ {switch (size) {
@@ -614,7 +630,7 @@ void helper_st_asi(int asi, int size)break ; } } -return ; +break ;case 0x2e :/* MMU passthrough, 0xexxxxxxxx */ case 0x2f :/* MMU passthrough, 0xfxxxxxxxx */ {
@@ -639,17 +655,34 @@ void helper_st_asi(int asi, int size) break; } } -return ; -case 0x31 :/* Ross RT620 I-cache flush */ +break ; +case 0x30 :/* store buffer tags */ +case 0x31 :/* store buffer date or Ross RT620 I-cache flush */ +case 0x32 :/* store buffer control */ case 0x36 :/* I-cache flash clear */ case 0x37 :/* D-cache flash clear */ +case 0x38 :/* MMU Breakpoint */ +case 0x4c :/* Breakpoint action */ +#ifdef DEBUG_ASI +printf ("write: %08x asi 0x%02x, size %d unimplemented address space\n" , +T0 , asi, size); +#endif break ;case 9 :/* Supervisor code access, XXX */ case 0x21 ... 0x2d: /* MMU passthrough, unassigned */default : +#ifdef DEBUG_ASI +printf ("write: %08x asi 0x%02x, size %d unsupported address space\n" , +T0 , asi, size); +#endif do_unassigned_access (T0 ,1 ,0 ,1 ); -return ; +break ; } + +#ifdef DEBUG_ASI +printf ("helper_st_asi(asi 0x%02x, size %d) T0 = %08x T1 = %08x T2 = %08x\n" , + asi, size,T0 ,T1 ,T2 ); +#endif }#endif /* CONFIG_USER_ONLY */
Quoted 1 line · Robert Reif
This patch makes debugging asi and mxcc accesses easier to follow.
... and adds a new register.
DPRINTF_ASI would be nice.
Quoted 4 lines · Blue Swirl
DPRINTF_ASIwould be nice.
Here is a revised patch:
Index: target-sparc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v retrieving revision 1.51
op_helper.c +62 -32
@@ -6,6 +6,7 @@//#define DEBUG_MXCC //#define DEBUG_UNALIGNED //#define DEBUG_UNASSIGNED +//#define DEBUG_ASI #ifdef DEBUG_MMU #define DPRINTF_MMU(fmt, args...) \
@@ -21,6 +22,13 @@ do { printf("MXCC: " fmt , ##args); } wh #define DPRINTF_MXCC(fmt, args...)#endif +#ifdef DEBUG_ASI +#define DPRINTF_ASI(fmt, args...) \ +do { printf("ASI: " fmt , ##args); } while (0) +#else +#define DPRINTF_ASI(fmt, args...) +#endif +void raise_exception (int tt) { env->exception_index = tt;
@@ -187,7 +195,7 @@ void helper_ld_asi(int asi, int size, in {uint32_t ret =0 ;uint64_t tmp; -#ifdef DEBUG_MXCC +#if defined(DEBUG_MXCC ) || defined(DEBUG_ASI )uint32_t last_T0 =T0 ;#endif
@@ -199,26 +207,34 @@ void helper_ld_asi(int asi, int size, in ret = env->mxccregs[3 ];T0 = env->mxccregs[3 ] >>32 ; }else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("read %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); +DPRINTF_MXCC ("read %08x: unimplemented access size: %d\n" ,T0 , size); +break ; +case 0x01c00c00 :/* Module reset register */ +if (size ==8 ) { + ret = env->mxccregs[5 ]; +T0 = env->mxccregs[5 ] >>32 ; +// should we do something here? + }else +DPRINTF_MXCC ("read %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); +DPRINTF_MXCC ("read %08x: unimplemented access size: %d\n" ,T0 , size);break ;default : -DPRINTF_MXCC ("%08x: unimplemented address, size: %d\n" ,T0 , size); +DPRINTF_MXCC ("read %08x: unimplemented address, size: %d\n" ,T0 , size);break ; } -DPRINTF_MXCC ("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x," +DPRINTF_MXCC ("read(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);
@@ -355,6 +371,8 @@ void helper_ld_asi(int asi, int size, inbreak ; case 0x21 ... 0x2d: /* MMU passthrough, unassigned */default : +DPRINTF_ASI ("read: %08x asi 0x%02x size %d unsupported address" , + last_T0, asi, size);do_unassigned_access (T0 ,0 ,0 ,1 ); ret =0 ;break ;
@@ -374,6 +392,9 @@ void helper_ld_asi(int asi, int size, in }else T1 = ret; + +DPRINTF_ASI ("helper_ld_asi(asi 0x%02x, size %d, sign %d) T0 = %08x -> " +"T0 = %08x T1 = %08x\n" , asi, size, sign, last_T0,T0 ,T1 ); }void helper_st_asi (int asi,int size)
@@ -385,31 +406,31 @@ void helper_st_asi(int asi, int size)if (size ==8 ) env->mxccdata[0 ] = ((uint64_t )T1 <<32 ) |T2 ;else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %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 );
@@ -419,7 +440,7 @@ void helper_st_asi(int asi, int size)if (size ==8 ) env->mxccregs[1 ] = ((uint64_t )T1 <<32 ) |T2 ;else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %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 ]);
@@ -429,34 +450,33 @@ void helper_st_asi(int asi, int size)if (size ==8 ) env->mxccregs[3 ] = ((uint64_t )T1 <<32 ) |T2 ;else -DPRINTF_MXCC ("%08x: unimplemented access size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %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); +DPRINTF_MXCC ("write %08x: unimplemented access size: %d\n" ,T0 , size);break ;case 0x01c00e00 :/* MXCC error register */ +// writing a 1 bit clears the error if (size ==8 ) - env->mxccregs[6 ] = ((uint64_t )T1 <<32 ) |T2 ; + 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 - } +DPRINTF_MXCC ("write %08x: unimplemented access size: %d\n" ,T0 , size);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); +DPRINTF_MXCC ("write %08x: unimplemented access size: %d\n" ,T0 , size);break ;default : -DPRINTF_MXCC ("%08x: unimplemented address, size: %d\n" ,T0 , size); +DPRINTF_MXCC ("write %08x: unimplemented address, size: %d\n" ,T0 , size);break ; } -DPRINTF_MXCC ("asi = %d, size = %d, T0 = %08x, T1 = %08x\n" , asi, size,T0 ,T1 ); +DPRINTF_MXCC ("write(asi %d, size %d) T0 = %08x, T1 = %08x, T2 = %08x\n" , + asi, size,T0 ,T1 ,T2 );#ifdef DEBUG_MXCC dump_mxcc (env);#endif
@@ -483,8 +503,8 @@ void helper_st_asi(int asi, int size)#ifdef DEBUG_MMU dump_mmu (env);#endif -return ; } +break ;case 4 :/* write MMU regs */ {int reg = (T0 >>8 ) &0xf ;
@@ -515,14 +535,13 @@ void helper_st_asi(int asi, int size) env->mmuregs[reg] =T1 ;break ; } -if (oldreg != env->mmuregs[reg]) { +if (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 ; } +break ;case 0xa :/* User data access */ switch (size) {case 1 :
@@ -580,7 +599,7 @@ void helper_st_asi(int asi, int size)stl_kernel (dst, temp); } } -return ; +break ;case 0x1f :/* Block fill, stda access */ {// value (T1, T2)
@@ -595,7 +614,7 @@ void helper_st_asi(int asi, int size)for (i =0 ; i <32 ; i +=8 , dst +=8 )stq_kernel (dst, val); } -return ; +break ;case 0x20 :/* MMU passthrough */ {switch (size) {
@@ -614,7 +633,7 @@ void helper_st_asi(int asi, int size)break ; } } -return ; +break ;case 0x2e :/* MMU passthrough, 0xexxxxxxxx */ case 0x2f :/* MMU passthrough, 0xfxxxxxxxx */ {
@@ -639,17 +658,28 @@ void helper_st_asi(int asi, int size) break; } } -return ; -case 0x31 :/* Ross RT620 I-cache flush */ +break ; +case 0x30 :/* store buffer tags */ +case 0x31 :/* store buffer date or Ross RT620 I-cache flush */ +case 0x32 :/* store buffer control */ case 0x36 :/* I-cache flash clear */ case 0x37 :/* D-cache flash clear */ +case 0x38 :/* MMU Breakpoint */ +case 0x4c :/* Breakpoint action */ +DPRINTF_ASI ("write: %08x asi 0x%02x, size %d unimplemented address " +"space\n" ,T0 , asi, size);break ;case 9 :/* Supervisor code access, XXX */ case 0x21 ... 0x2d: /* MMU passthrough, unassigned */default : +DPRINTF_ASI ("write: %08x asi 0x%02x, size %d unsupported address " +"space\n" ,T0 , asi, size);do_unassigned_access (T0 ,1 ,0 ,1 ); -return ; +break ; } + +DPRINTF_ASI ("helper_st_asi(asi 0x%02x, size %d) T0 = %08x T1 = %08x " +"T2 = %08x\n" , asi, size,T0 ,T1 ,T2 ); }#endif /* CONFIG_USER_ONLY */
Quoted 7 lines · Robert Reif
Quoted 4 lines · Blue Swirl
DPRINTF_ASIwould be nice.Here is a revised patch:
Thanks. The patch didn't apply completely. I noticed that there are some too long lines, they should be wrapped. Module reset register should be in a different patch.
Cache ASIs are implemented, they just do nothing, so the debug text should only apply to the store buffer (but not Ross I-cache flush?) and breakpoint ASIs. This by the way highlights that there should be a mechanism to register CPU specific ASIs and their handlers so that these ASI conflicts can be resolved. Because on Sparc32 we know the ASI at translation time, the handler can be selected then to get a small speedup.