Commit 5210977a8511fc0c4a8a1a68c01fa3b65e29edc0

Authored by Igor Kovalenko
Committed by Blue Swirl
1 parent 49e66373

sparc64: trap handling corrections

On Sun, Jul 12, 2009 at 12:09 PM, Blue Swirl<blauwirbel@gmail.com> wrote:
> On 7/12/09, Igor Kovalenko <igor.v.kovalenko@gmail.com> wrote:
>> Good trap handling is required to process interrupts.
>>  This patch fixes the following:
>>
>>  - sparc64 has no wim register
>>  - sparc64 has no psret register, use IE bit of pstate
>>   extract IE checking code to cpu_interrupts_enabled
>>  - alternate globals are not available if cpu has GL feature
>>   in this case bit AG of pstate is constant zero
>>  - write to pstate must actually write pstate
>>   even if cpu has GL feature
>>
>>  Also timer interrupt is handled using do_interrupt.
>
> A bit too much for one patch. Please also remove the code instead of
> commenting out.

I now excluded timer interrupt related part.
To my mind other changes are essentially tied together.

> PUT_PSR for Sparc64 needs CC_OP = CC_OP_FLAGS; like Sparc32.

Fixed, please find attached the updated version.

--
Kind regards,
Igor V. Kovalenko
cpu-exec.c
@@ -475,7 +475,7 @@ int cpu_exec(CPUState *env1) @@ -475,7 +475,7 @@ int cpu_exec(CPUState *env1)
475 } 475 }
476 #elif defined(TARGET_SPARC) 476 #elif defined(TARGET_SPARC)
477 if ((interrupt_request & CPU_INTERRUPT_HARD) && 477 if ((interrupt_request & CPU_INTERRUPT_HARD) &&
478 - (env->psret != 0)) { 478 + cpu_interrupts_enabled(env)) {
479 int pil = env->interrupt_index & 15; 479 int pil = env->interrupt_index & 15;
480 int type = env->interrupt_index & 0xf0; 480 int type = env->interrupt_index & 0xf0;
481 481
@@ -486,7 +486,7 @@ int cpu_exec(CPUState *env1) @@ -486,7 +486,7 @@ int cpu_exec(CPUState *env1)
486 env->exception_index = env->interrupt_index; 486 env->exception_index = env->interrupt_index;
487 do_interrupt(env); 487 do_interrupt(env);
488 env->interrupt_index = 0; 488 env->interrupt_index = 0;
489 -#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) 489 +#if !defined(CONFIG_USER_ONLY)
490 cpu_check_irqs(env); 490 cpu_check_irqs(env);
491 #endif 491 #endif
492 next_tb = 0; 492 next_tb = 0;
target-sparc/cpu.h
@@ -115,15 +115,18 @@ enum { @@ -115,15 +115,18 @@ enum {
115 #define TBR_BASE_MASK 0xfffff000 115 #define TBR_BASE_MASK 0xfffff000
116 116
117 #if defined(TARGET_SPARC64) 117 #if defined(TARGET_SPARC64)
118 -#define PS_IG (1<<11)  
119 -#define PS_MG (1<<10) 118 +#define PS_TCT (1<<12) /* UA2007, impl.dep. trap on control transfer */
  119 +#define PS_IG (1<<11) /* v9, zero on UA2007 */
  120 +#define PS_MG (1<<10) /* v9, zero on UA2007 */
  121 +#define PS_CLE (1<<9) /* UA2007 */
  122 +#define PS_TLE (1<<8) /* UA2007 */
120 #define PS_RMO (1<<7) 123 #define PS_RMO (1<<7)
121 -#define PS_RED (1<<5)  
122 -#define PS_PEF (1<<4)  
123 -#define PS_AM (1<<3) 124 +#define PS_RED (1<<5) /* v9, zero on UA2007 */
  125 +#define PS_PEF (1<<4) /* enable fpu */
  126 +#define PS_AM (1<<3) /* address mask */
124 #define PS_PRIV (1<<2) 127 #define PS_PRIV (1<<2)
125 #define PS_IE (1<<1) 128 #define PS_IE (1<<1)
126 -#define PS_AG (1<<0) 129 +#define PS_AG (1<<0) /* v9, zero on UA2007 */
127 130
128 #define FPRS_FEF (1<<2) 131 #define FPRS_FEF (1<<2)
129 132
@@ -291,11 +294,15 @@ typedef struct CPUSPARCState { @@ -291,11 +294,15 @@ typedef struct CPUSPARCState {
291 float32 fpr[TARGET_FPREGS]; /* floating point registers */ 294 float32 fpr[TARGET_FPREGS]; /* floating point registers */
292 uint32_t cwp; /* index of current register window (extracted 295 uint32_t cwp; /* index of current register window (extracted
293 from PSR) */ 296 from PSR) */
  297 +#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
294 uint32_t wim; /* window invalid mask */ 298 uint32_t wim; /* window invalid mask */
  299 +#endif
295 target_ulong tbr; /* trap base register */ 300 target_ulong tbr; /* trap base register */
296 int psrs; /* supervisor mode (extracted from PSR) */ 301 int psrs; /* supervisor mode (extracted from PSR) */
297 int psrps; /* previous supervisor mode */ 302 int psrps; /* previous supervisor mode */
  303 +#if !defined(TARGET_SPARC64)
298 int psret; /* enable traps */ 304 int psret; /* enable traps */
  305 +#endif
299 uint32_t psrpil; /* interrupt blocking level */ 306 uint32_t psrpil; /* interrupt blocking level */
300 uint32_t pil_in; /* incoming interrupt level bitmap */ 307 uint32_t pil_in; /* incoming interrupt level bitmap */
301 int psref; /* enable fpu */ 308 int psref; /* enable fpu */
@@ -378,12 +385,21 @@ void gen_intermediate_code_init(CPUSPARCState *env); @@ -378,12 +385,21 @@ void gen_intermediate_code_init(CPUSPARCState *env);
378 /* cpu-exec.c */ 385 /* cpu-exec.c */
379 int cpu_sparc_exec(CPUSPARCState *s); 386 int cpu_sparc_exec(CPUSPARCState *s);
380 387
  388 +#if !defined (TARGET_SPARC64)
381 #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ 389 #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
382 (env->psref? PSR_EF : 0) | \ 390 (env->psref? PSR_EF : 0) | \
383 (env->psrpil << 8) | \ 391 (env->psrpil << 8) | \
384 (env->psrs? PSR_S : 0) | \ 392 (env->psrs? PSR_S : 0) | \
385 (env->psrps? PSR_PS : 0) | \ 393 (env->psrps? PSR_PS : 0) | \
386 (env->psret? PSR_ET : 0) | env->cwp) 394 (env->psret? PSR_ET : 0) | env->cwp)
  395 +#else
  396 +#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
  397 + (env->psref? PSR_EF : 0) | \
  398 + (env->psrpil << 8) | \
  399 + (env->psrs? PSR_S : 0) | \
  400 + (env->psrps? PSR_PS : 0) | \
  401 + env->cwp)
  402 +#endif
387 403
388 #ifndef NO_CPU_IO_DEFS 404 #ifndef NO_CPU_IO_DEFS
389 static inline void memcpy32(target_ulong *dst, const target_ulong *src) 405 static inline void memcpy32(target_ulong *dst, const target_ulong *src)
@@ -425,6 +441,7 @@ static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) @@ -425,6 +441,7 @@ static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp)
425 } 441 }
426 #endif 442 #endif
427 443
  444 +#if !defined (TARGET_SPARC64)
428 #define PUT_PSR(env, val) do { int _tmp = val; \ 445 #define PUT_PSR(env, val) do { int _tmp = val; \
429 env->psr = _tmp & PSR_ICC; \ 446 env->psr = _tmp & PSR_ICC; \
430 env->psref = (_tmp & PSR_EF)? 1 : 0; \ 447 env->psref = (_tmp & PSR_EF)? 1 : 0; \
@@ -435,6 +452,17 @@ static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) @@ -435,6 +452,17 @@ static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp)
435 cpu_set_cwp(env, _tmp & PSR_CWP); \ 452 cpu_set_cwp(env, _tmp & PSR_CWP); \
436 CC_OP = CC_OP_FLAGS; \ 453 CC_OP = CC_OP_FLAGS; \
437 } while (0) 454 } while (0)
  455 +#else
  456 +#define PUT_PSR(env, val) do { int _tmp = val; \
  457 + env->psr = _tmp & PSR_ICC; \
  458 + env->psref = (_tmp & PSR_EF)? 1 : 0; \
  459 + env->psrpil = (_tmp & PSR_PIL) >> 8; \
  460 + env->psrs = (_tmp & PSR_S)? 1 : 0; \
  461 + env->psrps = (_tmp & PSR_PS)? 1 : 0; \
  462 + cpu_set_cwp(env, _tmp & PSR_CWP); \
  463 + CC_OP = CC_OP_FLAGS; \
  464 + } while (0)
  465 +#endif
438 466
439 #ifdef TARGET_SPARC64 467 #ifdef TARGET_SPARC64
440 #define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20)) 468 #define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20))
target-sparc/exec.h
@@ -24,10 +24,23 @@ static inline void regs_to_env(void) @@ -24,10 +24,23 @@ static inline void regs_to_env(void)
24 /* op_helper.c */ 24 /* op_helper.c */
25 void do_interrupt(CPUState *env); 25 void do_interrupt(CPUState *env);
26 26
  27 +static inline int cpu_interrupts_enabled(CPUState *env1)
  28 +{
  29 +#if !defined (TARGET_SPARC64)
  30 + if (env1->psret != 0)
  31 + return 1;
  32 +#else
  33 + if (env1->pstate & PS_IE)
  34 + return 1;
  35 +#endif
  36 +
  37 + return 0;
  38 +}
  39 +
27 static inline int cpu_has_work(CPUState *env1) 40 static inline int cpu_has_work(CPUState *env1)
28 { 41 {
29 return (env1->interrupt_request & CPU_INTERRUPT_HARD) && 42 return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
30 - (env1->psret != 0); 43 + cpu_interrupts_enabled(env1);
31 } 44 }
32 45
33 46
target-sparc/helper.c
@@ -667,7 +667,9 @@ void cpu_reset(CPUSPARCState *env) @@ -667,7 +667,9 @@ void cpu_reset(CPUSPARCState *env)
667 667
668 tlb_flush(env, 1); 668 tlb_flush(env, 1);
669 env->cwp = 0; 669 env->cwp = 0;
  670 +#ifndef TARGET_SPARC64
670 env->wim = 1; 671 env->wim = 1;
  672 +#endif
671 env->regwptr = env->regbase + (env->cwp * 16); 673 env->regwptr = env->regbase + (env->cwp * 16);
672 #if defined(CONFIG_USER_ONLY) 674 #if defined(CONFIG_USER_ONLY)
673 #ifdef TARGET_SPARC64 675 #ifdef TARGET_SPARC64
@@ -677,7 +679,9 @@ void cpu_reset(CPUSPARCState *env) @@ -677,7 +679,9 @@ void cpu_reset(CPUSPARCState *env)
677 env->asi = 0x82; // Primary no-fault 679 env->asi = 0x82; // Primary no-fault
678 #endif 680 #endif
679 #else 681 #else
  682 +#if !defined(TARGET_SPARC64)
680 env->psret = 0; 683 env->psret = 0;
  684 +#endif
681 env->psrs = 1; 685 env->psrs = 1;
682 env->psrps = 1; 686 env->psrps = 1;
683 CC_OP = CC_OP_FLAGS; 687 CC_OP = CC_OP_FLAGS;
target-sparc/op_helper.c
@@ -3225,8 +3225,14 @@ static inline void change_pstate(uint64_t new_pstate) @@ -3225,8 +3225,14 @@ static inline void change_pstate(uint64_t new_pstate)
3225 uint64_t pstate_regs, new_pstate_regs; 3225 uint64_t pstate_regs, new_pstate_regs;
3226 uint64_t *src, *dst; 3226 uint64_t *src, *dst;
3227 3227
  3228 + if (env->def->features & CPU_FEATURE_GL) {
  3229 + // PS_AG is not implemented in this case
  3230 + new_pstate &= ~PS_AG;
  3231 + }
  3232 +
3228 pstate_regs = env->pstate & 0xc01; 3233 pstate_regs = env->pstate & 0xc01;
3229 new_pstate_regs = new_pstate & 0xc01; 3234 new_pstate_regs = new_pstate & 0xc01;
  3235 +
3230 if (new_pstate_regs != pstate_regs) { 3236 if (new_pstate_regs != pstate_regs) {
3231 // Switch global register bank 3237 // Switch global register bank
3232 src = get_gregset(new_pstate_regs); 3238 src = get_gregset(new_pstate_regs);
@@ -3239,8 +3245,7 @@ static inline void change_pstate(uint64_t new_pstate) @@ -3239,8 +3245,7 @@ static inline void change_pstate(uint64_t new_pstate)
3239 3245
3240 void helper_wrpstate(target_ulong new_state) 3246 void helper_wrpstate(target_ulong new_state)
3241 { 3247 {
3242 - if (!(env->def->features & CPU_FEATURE_GL))  
3243 - change_pstate(new_state & 0xf3f); 3248 + change_pstate(new_state & 0xf3f);
3244 } 3249 }
3245 3250
3246 void helper_done(void) 3251 void helper_done(void)
@@ -3392,23 +3397,23 @@ void do_interrupt(CPUState *env) @@ -3392,23 +3397,23 @@ void do_interrupt(CPUState *env)
3392 env->tsptr->tpc = env->pc; 3397 env->tsptr->tpc = env->pc;
3393 env->tsptr->tnpc = env->npc; 3398 env->tsptr->tnpc = env->npc;
3394 env->tsptr->tt = intno; 3399 env->tsptr->tt = intno;
3395 - if (!(env->def->features & CPU_FEATURE_GL)) {  
3396 - switch (intno) {  
3397 - case TT_IVEC:  
3398 - change_pstate(PS_PEF | PS_PRIV | PS_IG);  
3399 - break;  
3400 - case TT_TFAULT:  
3401 - case TT_TMISS:  
3402 - case TT_DFAULT:  
3403 - case TT_DMISS:  
3404 - case TT_DPROT:  
3405 - change_pstate(PS_PEF | PS_PRIV | PS_MG);  
3406 - break;  
3407 - default:  
3408 - change_pstate(PS_PEF | PS_PRIV | PS_AG);  
3409 - break;  
3410 - } 3400 +
  3401 + switch (intno) {
  3402 + case TT_IVEC:
  3403 + change_pstate(PS_PEF | PS_PRIV | PS_IG);
  3404 + break;
  3405 + case TT_TFAULT:
  3406 + case TT_TMISS:
  3407 + case TT_DFAULT:
  3408 + case TT_DMISS:
  3409 + case TT_DPROT:
  3410 + change_pstate(PS_PEF | PS_PRIV | PS_MG);
  3411 + break;
  3412 + default:
  3413 + change_pstate(PS_PEF | PS_PRIV | PS_AG);
  3414 + break;
3411 } 3415 }
  3416 +
3412 if (intno == TT_CLRWIN) 3417 if (intno == TT_CLRWIN)
3413 cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1)); 3418 cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
3414 else if ((intno & 0x1c0) == TT_SPILL) 3419 else if ((intno & 0x1c0) == TT_SPILL)