PPC: Redesign interrupt trigger path
According to the Book3S spec, the interrupt context starts with an MSR value that is rather simple. If we leave out the HV case, it's almost always 0. To reflect this, let's redesign the way that MSR value gets calculated. Using this, we also squash the bug where MSR_POW can slip through into the interrupt handler MSR. Reported-by: Thomas Monjalon <thomas.monjalon@openwide.fr> Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
parent
f844c817d7
commit
41557447d3
|
@ -2073,18 +2073,24 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
|
|
||||||
qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
|
qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
|
||||||
" => %08x (%02x)\n", env->nip, excp, env->error_code);
|
" => %08x (%02x)\n", env->nip, excp, env->error_code);
|
||||||
msr = env->msr;
|
|
||||||
new_msr = msr;
|
/* new srr1 value excluding must-be-zero bits */
|
||||||
|
msr = env->msr & ~0x783f0000ULL;
|
||||||
|
|
||||||
|
/* new interrupt handler msr */
|
||||||
|
new_msr = env->msr & ((target_ulong)1 << MSR_ME);
|
||||||
|
|
||||||
|
/* target registers */
|
||||||
srr0 = SPR_SRR0;
|
srr0 = SPR_SRR0;
|
||||||
srr1 = SPR_SRR1;
|
srr1 = SPR_SRR1;
|
||||||
asrr0 = -1;
|
asrr0 = -1;
|
||||||
asrr1 = -1;
|
asrr1 = -1;
|
||||||
|
|
||||||
switch (excp) {
|
switch (excp) {
|
||||||
case POWERPC_EXCP_NONE:
|
case POWERPC_EXCP_NONE:
|
||||||
/* Should never happen */
|
/* Should never happen */
|
||||||
return;
|
return;
|
||||||
case POWERPC_EXCP_CRITICAL: /* Critical input */
|
case POWERPC_EXCP_CRITICAL: /* Critical input */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
switch (excp_model) {
|
switch (excp_model) {
|
||||||
case POWERPC_EXCP_40x:
|
case POWERPC_EXCP_40x:
|
||||||
srr0 = SPR_40x_SRR2;
|
srr0 = SPR_40x_SRR2;
|
||||||
|
@ -2115,12 +2121,14 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
env->halted = 1;
|
env->halted = 1;
|
||||||
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
|
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
|
||||||
}
|
}
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_ME);
|
|
||||||
if (0) {
|
if (0) {
|
||||||
/* XXX: find a suitable condition to enable the hypervisor mode */
|
/* XXX: find a suitable condition to enable the hypervisor mode */
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* machine check exceptions don't have ME set */
|
||||||
|
new_msr &= ~((target_ulong)1 << MSR_ME);
|
||||||
|
|
||||||
/* XXX: should also have something loaded in DAR / DSISR */
|
/* XXX: should also have something loaded in DAR / DSISR */
|
||||||
switch (excp_model) {
|
switch (excp_model) {
|
||||||
case POWERPC_EXCP_40x:
|
case POWERPC_EXCP_40x:
|
||||||
|
@ -2140,25 +2148,21 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
case POWERPC_EXCP_DSI: /* Data storage exception */
|
case POWERPC_EXCP_DSI: /* Data storage exception */
|
||||||
LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
|
LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
|
||||||
"\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
|
"\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_ISI: /* Instruction storage exception */
|
case POWERPC_EXCP_ISI: /* Instruction storage exception */
|
||||||
LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
|
LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
|
||||||
"\n", msr, env->nip);
|
"\n", msr, env->nip);
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
msr |= env->error_code;
|
msr |= env->error_code;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_EXTERNAL: /* External input */
|
case POWERPC_EXCP_EXTERNAL: /* External input */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes0 == 1)
|
if (lpes0 == 1)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_ALIGN: /* Alignment exception */
|
case POWERPC_EXCP_ALIGN: /* Alignment exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
/* XXX: this is false */
|
/* XXX: this is false */
|
||||||
|
@ -2174,7 +2178,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
msr |= 0x00100000;
|
msr |= 0x00100000;
|
||||||
|
@ -2184,19 +2187,16 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
break;
|
break;
|
||||||
case POWERPC_EXCP_INVAL:
|
case POWERPC_EXCP_INVAL:
|
||||||
LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
|
LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
msr |= 0x00080000;
|
msr |= 0x00080000;
|
||||||
break;
|
break;
|
||||||
case POWERPC_EXCP_PRIV:
|
case POWERPC_EXCP_PRIV:
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
msr |= 0x00040000;
|
msr |= 0x00040000;
|
||||||
break;
|
break;
|
||||||
case POWERPC_EXCP_TRAP:
|
case POWERPC_EXCP_TRAP:
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
msr |= 0x00020000;
|
msr |= 0x00020000;
|
||||||
|
@ -2209,7 +2209,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
}
|
}
|
||||||
goto store_current;
|
goto store_current;
|
||||||
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_current;
|
goto store_current;
|
||||||
|
@ -2226,23 +2225,19 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dump_syscall(env);
|
dump_syscall(env);
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
lev = env->error_code;
|
lev = env->error_code;
|
||||||
if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
|
if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
|
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
goto store_current;
|
goto store_current;
|
||||||
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
|
case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
|
||||||
/* FIT on 4xx */
|
/* FIT on 4xx */
|
||||||
LOG_EXCP("FIT exception\n");
|
LOG_EXCP("FIT exception\n");
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
|
case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
|
||||||
LOG_EXCP("WDT exception\n");
|
LOG_EXCP("WDT exception\n");
|
||||||
|
@ -2254,13 +2249,10 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_DTLB: /* Data TLB error */
|
case POWERPC_EXCP_DTLB: /* Data TLB error */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_ITLB: /* Instruction TLB error */
|
case POWERPC_EXCP_ITLB: /* Instruction TLB error */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_DEBUG: /* Debug interrupt */
|
case POWERPC_EXCP_DEBUG: /* Debug interrupt */
|
||||||
switch (excp_model) {
|
switch (excp_model) {
|
||||||
|
@ -2277,7 +2269,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
cpu_abort(env, "Debug exception is not implemented yet !\n");
|
cpu_abort(env, "Debug exception is not implemented yet !\n");
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
|
case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
goto store_current;
|
goto store_current;
|
||||||
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
|
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
|
||||||
/* XXX: TODO */
|
/* XXX: TODO */
|
||||||
|
@ -2290,7 +2281,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
"is not implemented yet !\n");
|
"is not implemented yet !\n");
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
|
case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
/* XXX: TODO */
|
/* XXX: TODO */
|
||||||
cpu_abort(env,
|
cpu_abort(env,
|
||||||
"Performance counter exception is not implemented yet !\n");
|
"Performance counter exception is not implemented yet !\n");
|
||||||
|
@ -2314,19 +2304,23 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
"is not implemented yet !\n");
|
"is not implemented yet !\n");
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_RESET: /* System reset exception */
|
case POWERPC_EXCP_RESET: /* System reset exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
if (msr_pow) {
|
||||||
|
/* indicate that we resumed from power save mode */
|
||||||
|
msr |= 0x10000;
|
||||||
|
} else {
|
||||||
|
new_msr &= ~((target_ulong)1 << MSR_ME);
|
||||||
|
}
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
/* XXX: find a suitable condition to enable the hypervisor mode */
|
/* XXX: find a suitable condition to enable the hypervisor mode */
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
}
|
}
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_DSEG: /* Data segment exception */
|
case POWERPC_EXCP_DSEG: /* Data segment exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_ISEG: /* Instruction segment exception */
|
case POWERPC_EXCP_ISEG: /* Instruction segment exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
|
@ -2334,9 +2328,9 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
srr0 = SPR_HSRR0;
|
srr0 = SPR_HSRR0;
|
||||||
srr1 = SPR_HSRR1;
|
srr1 = SPR_HSRR1;
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
|
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_TRACE: /* Trace exception */
|
case POWERPC_EXCP_TRACE: /* Trace exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_next;
|
goto store_next;
|
||||||
|
@ -2344,30 +2338,32 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
srr0 = SPR_HSRR0;
|
srr0 = SPR_HSRR0;
|
||||||
srr1 = SPR_HSRR1;
|
srr1 = SPR_HSRR1;
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
|
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
|
case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
|
||||||
srr0 = SPR_HSRR0;
|
srr0 = SPR_HSRR0;
|
||||||
srr1 = SPR_HSRR1;
|
srr1 = SPR_HSRR1;
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
|
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
|
case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
|
||||||
srr0 = SPR_HSRR0;
|
srr0 = SPR_HSRR0;
|
||||||
srr1 = SPR_HSRR1;
|
srr1 = SPR_HSRR1;
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
|
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
|
case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
|
||||||
srr0 = SPR_HSRR0;
|
srr0 = SPR_HSRR0;
|
||||||
srr1 = SPR_HSRR1;
|
srr1 = SPR_HSRR1;
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
|
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_VPU: /* Vector unavailable exception */
|
case POWERPC_EXCP_VPU: /* Vector unavailable exception */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
goto store_current;
|
goto store_current;
|
||||||
case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
|
case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
|
||||||
LOG_EXCP("PIT exception\n");
|
LOG_EXCP("PIT exception\n");
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_IO: /* IO error exception */
|
case POWERPC_EXCP_IO: /* IO error exception */
|
||||||
/* XXX: TODO */
|
/* XXX: TODO */
|
||||||
|
@ -2383,7 +2379,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
"is not implemented yet !\n");
|
"is not implemented yet !\n");
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
|
case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
if (lpes1 == 0) /* XXX: check this */
|
if (lpes1 == 0) /* XXX: check this */
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
switch (excp_model) {
|
switch (excp_model) {
|
||||||
|
@ -2402,7 +2397,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
|
case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
if (lpes1 == 0) /* XXX: check this */
|
if (lpes1 == 0) /* XXX: check this */
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
switch (excp_model) {
|
switch (excp_model) {
|
||||||
|
@ -2421,7 +2415,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
|
case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
|
|
||||||
if (lpes1 == 0) /* XXX: check this */
|
if (lpes1 == 0) /* XXX: check this */
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
switch (excp_model) {
|
switch (excp_model) {
|
||||||
|
@ -2525,7 +2518,6 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
"is not implemented yet !\n");
|
"is not implemented yet !\n");
|
||||||
goto store_next;
|
goto store_next;
|
||||||
case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
|
case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
|
||||||
new_msr &= ~((target_ulong)1 << MSR_RI);
|
|
||||||
if (lpes1 == 0)
|
if (lpes1 == 0)
|
||||||
new_msr |= (target_ulong)MSR_HVB;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
/* XXX: TODO */
|
/* XXX: TODO */
|
||||||
|
@ -2579,23 +2571,11 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
/* If we disactivated any translation, flush TLBs */
|
/* If we disactivated any translation, flush TLBs */
|
||||||
if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
|
if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
|
||||||
tlb_flush(env, 1);
|
tlb_flush(env, 1);
|
||||||
/* reload MSR with correct bits */
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_EE);
|
if (msr_ile) {
|
||||||
new_msr &= ~((target_ulong)1 << MSR_PR);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_FP);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_FE0);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_SE);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_BE);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_FE1);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_IR);
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_DR);
|
|
||||||
#if 0 /* Fix this: not on all targets */
|
|
||||||
new_msr &= ~((target_ulong)1 << MSR_PMM);
|
|
||||||
#endif
|
|
||||||
if (msr_ile)
|
|
||||||
new_msr |= (target_ulong)1 << MSR_LE;
|
new_msr |= (target_ulong)1 << MSR_LE;
|
||||||
else
|
}
|
||||||
new_msr &= ~((target_ulong)1 << MSR_LE);
|
|
||||||
/* Jump to handler */
|
/* Jump to handler */
|
||||||
vector = env->excp_vectors[excp];
|
vector = env->excp_vectors[excp];
|
||||||
if (vector == (target_ulong)-1ULL) {
|
if (vector == (target_ulong)-1ULL) {
|
||||||
|
@ -2606,14 +2586,12 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
if (excp_model == POWERPC_EXCP_BOOKE) {
|
if (excp_model == POWERPC_EXCP_BOOKE) {
|
||||||
if (!msr_icm) {
|
if (!msr_icm) {
|
||||||
new_msr &= ~((target_ulong)1 << MSR_CM);
|
|
||||||
vector = (uint32_t)vector;
|
vector = (uint32_t)vector;
|
||||||
} else {
|
} else {
|
||||||
new_msr |= (target_ulong)1 << MSR_CM;
|
new_msr |= (target_ulong)1 << MSR_CM;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
|
if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
|
||||||
new_msr &= ~((target_ulong)1 << MSR_SF);
|
|
||||||
vector = (uint32_t)vector;
|
vector = (uint32_t)vector;
|
||||||
} else {
|
} else {
|
||||||
new_msr |= (target_ulong)1 << MSR_SF;
|
new_msr |= (target_ulong)1 << MSR_SF;
|
||||||
|
|
Loading…
Reference in a new issue