summaryrefslogtreecommitdiff
path: root/target-sparc/op_helper.c
diff options
context:
space:
mode:
authorIgor Kovalenko <igor.v.kovalenko@gmail.com>2009-07-12 12:35:31 +0400
committerBlue Swirl <blauwirbel@gmail.com>2009-07-12 08:46:54 +0000
commit5210977a8511fc0c4a8a1a68c01fa3b65e29edc0 (patch)
treedd12f3bcc62297f325c30718c6d42764dff0afd6 /target-sparc/op_helper.c
parent49e6637386acb8824114ed10308ed7869472ec0f (diff)
downloadqemu-5210977a8511fc0c4a8a1a68c01fa3b65e29edc0.tar.gz
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
Diffstat (limited to 'target-sparc/op_helper.c')
-rw-r--r--target-sparc/op_helper.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 2449fc717b..d25b642c06 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3225,8 +3225,14 @@ static inline void change_pstate(uint64_t new_pstate)
uint64_t pstate_regs, new_pstate_regs;
uint64_t *src, *dst;
+ if (env->def->features & CPU_FEATURE_GL) {
+ // PS_AG is not implemented in this case
+ new_pstate &= ~PS_AG;
+ }
+
pstate_regs = env->pstate & 0xc01;
new_pstate_regs = new_pstate & 0xc01;
+
if (new_pstate_regs != pstate_regs) {
// Switch global register bank
src = get_gregset(new_pstate_regs);
@@ -3239,8 +3245,7 @@ static inline void change_pstate(uint64_t new_pstate)
void helper_wrpstate(target_ulong new_state)
{
- if (!(env->def->features & CPU_FEATURE_GL))
- change_pstate(new_state & 0xf3f);
+ change_pstate(new_state & 0xf3f);
}
void helper_done(void)
@@ -3392,23 +3397,23 @@ void do_interrupt(CPUState *env)
env->tsptr->tpc = env->pc;
env->tsptr->tnpc = env->npc;
env->tsptr->tt = intno;
- if (!(env->def->features & CPU_FEATURE_GL)) {
- switch (intno) {
- case TT_IVEC:
- change_pstate(PS_PEF | PS_PRIV | PS_IG);
- break;
- case TT_TFAULT:
- case TT_TMISS:
- case TT_DFAULT:
- case TT_DMISS:
- case TT_DPROT:
- change_pstate(PS_PEF | PS_PRIV | PS_MG);
- break;
- default:
- change_pstate(PS_PEF | PS_PRIV | PS_AG);
- break;
- }
+
+ switch (intno) {
+ case TT_IVEC:
+ change_pstate(PS_PEF | PS_PRIV | PS_IG);
+ break;
+ case TT_TFAULT:
+ case TT_TMISS:
+ case TT_DFAULT:
+ case TT_DMISS:
+ case TT_DPROT:
+ change_pstate(PS_PEF | PS_PRIV | PS_MG);
+ break;
+ default:
+ change_pstate(PS_PEF | PS_PRIV | PS_AG);
+ break;
}
+
if (intno == TT_CLRWIN)
cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
else if ((intno & 0x1c0) == TT_SPILL)