mirror of https://gitee.com/openkylin/qemu.git
ppc: Make tlb_fill() use new exception helper
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
af6d376ea1
commit
bd6fefe71c
|
@ -1814,7 +1814,7 @@ void cpu_loop(CPUPPCState *env)
|
|||
env->error_code);
|
||||
break;
|
||||
}
|
||||
info._sifields._sigfault._addr = env->nip - 4;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
||||
|
@ -1822,7 +1822,7 @@ void cpu_loop(CPUPPCState *env)
|
|||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip - 4;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_SYSCALL: /* System call exception */
|
||||
|
@ -1834,7 +1834,7 @@ void cpu_loop(CPUPPCState *env)
|
|||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip - 4;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
||||
|
@ -1862,7 +1862,7 @@ void cpu_loop(CPUPPCState *env)
|
|||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip - 4;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
|
||||
|
@ -1926,7 +1926,7 @@ void cpu_loop(CPUPPCState *env)
|
|||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_COPROC;
|
||||
info._sifields._sigfault._addr = env->nip - 4;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
|
||||
|
@ -2001,9 +2001,9 @@ void cpu_loop(CPUPPCState *env)
|
|||
env->gpr[5], env->gpr[6], env->gpr[7],
|
||||
env->gpr[8], 0, 0);
|
||||
if (ret == -TARGET_ERESTARTSYS) {
|
||||
env->nip -= 4;
|
||||
break;
|
||||
}
|
||||
env->nip += 4;
|
||||
if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
|
||||
/* Returning from a successful sigreturn syscall.
|
||||
Avoid corrupting register state. */
|
||||
|
|
|
@ -198,7 +198,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
default:
|
||||
goto excp_invalid;
|
||||
}
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_MCHECK: /* Machine check exception */
|
||||
if (msr_me == 0) {
|
||||
/* Machine check exception is not enabled.
|
||||
|
@ -235,16 +235,16 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_DSI: /* Data storage exception */
|
||||
LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
|
||||
"\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_ISI: /* Instruction storage exception */
|
||||
LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
|
||||
"\n", msr, env->nip);
|
||||
msr |= env->error_code;
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_EXTERNAL: /* External input */
|
||||
cs = CPU(cpu);
|
||||
|
||||
|
@ -258,13 +258,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
/* IACK the IRQ on delivery */
|
||||
env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
|
||||
}
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_ALIGN: /* Alignment exception */
|
||||
/* XXX: this is false */
|
||||
/* Get rS/rD and rA from faulting opcode */
|
||||
env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
|
||||
/* Broken for LE mode */
|
||||
env->spr[SPR_DSISR] |= (cpu_ldl_code(env, env->nip)
|
||||
& 0x03FF0000) >> 16;
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_PROGRAM: /* Program exception */
|
||||
switch (env->error_code & ~0xF) {
|
||||
case POWERPC_EXCP_FP:
|
||||
|
@ -280,15 +281,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
* precise in the MSR.
|
||||
*/
|
||||
msr |= 0x00100000;
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_INVAL:
|
||||
LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
|
||||
msr |= 0x00080000;
|
||||
env->spr[SPR_BOOKE_ESR] = ESR_PIL;
|
||||
/* Some invalids will have the PC in the right place already */
|
||||
if (env->error_code & POWERPC_EXCP_INVAL_LSWX) {
|
||||
goto store_next;
|
||||
}
|
||||
break;
|
||||
case POWERPC_EXCP_PRIV:
|
||||
msr |= 0x00040000;
|
||||
|
@ -304,23 +301,16 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
env->error_code);
|
||||
break;
|
||||
}
|
||||
goto store_current;
|
||||
case POWERPC_EXCP_HV_EMU:
|
||||
srr0 = SPR_HSRR0;
|
||||
srr1 = SPR_HSRR1;
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||
/* Some invalids will have the PC in the right place already */
|
||||
if (env->error_code == (POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX)) {
|
||||
goto store_next;
|
||||
}
|
||||
goto store_current;
|
||||
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
||||
goto store_current;
|
||||
break;
|
||||
case POWERPC_EXCP_SYSCALL: /* System call exception */
|
||||
dump_syscall(env);
|
||||
lev = env->error_code;
|
||||
|
||||
/* We need to correct the NIP which in this case is supposed
|
||||
* to point to the next instruction
|
||||
*/
|
||||
env->nip += 4;
|
||||
|
||||
/* "PAPR mode" built-in hypercall emulation */
|
||||
if ((lev == 1) && cpu_ppc_hypercall) {
|
||||
cpu_ppc_hypercall(cpu);
|
||||
|
@ -329,15 +319,15 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
if (lev == 1) {
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
}
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
||||
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
|
||||
goto store_current;
|
||||
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
|
||||
/* FIT on 4xx */
|
||||
LOG_EXCP("FIT exception\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
|
||||
LOG_EXCP("WDT exception\n");
|
||||
switch (excp_model) {
|
||||
|
@ -348,11 +338,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_DTLB: /* Data TLB error */
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_ITLB: /* Instruction TLB error */
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_DEBUG: /* Debug interrupt */
|
||||
switch (excp_model) {
|
||||
case POWERPC_EXCP_BOOKE:
|
||||
|
@ -367,33 +356,33 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
}
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "Debug exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
|
||||
env->spr[SPR_BOOKE_ESR] = ESR_SPV;
|
||||
goto store_current;
|
||||
break;
|
||||
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "Embedded floating point data exception "
|
||||
"is not implemented yet !\n");
|
||||
env->spr[SPR_BOOKE_ESR] = ESR_SPV;
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "Embedded floating point round exception "
|
||||
"is not implemented yet !\n");
|
||||
env->spr[SPR_BOOKE_ESR] = ESR_SPV;
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs,
|
||||
"Performance counter exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
|
||||
srr0 = SPR_BOOKE_CSRR0;
|
||||
srr1 = SPR_BOOKE_CSRR1;
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_RESET: /* System reset exception */
|
||||
if (msr_pow) {
|
||||
/* indicate that we resumed from power save mode */
|
||||
|
@ -404,65 +393,42 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
ail = 0;
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_DSEG: /* Data segment exception */
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_ISEG: /* Instruction segment exception */
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
|
||||
srr0 = SPR_HSRR0;
|
||||
srr1 = SPR_HSRR1;
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_TRACE: /* Trace exception */
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
|
||||
case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
|
||||
srr0 = SPR_HSRR0;
|
||||
srr1 = SPR_HSRR1;
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
|
||||
srr0 = SPR_HSRR0;
|
||||
srr1 = SPR_HSRR1;
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
|
||||
srr0 = SPR_HSRR0;
|
||||
srr1 = SPR_HSRR1;
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
|
||||
case POWERPC_EXCP_HV_EMU:
|
||||
srr0 = SPR_HSRR0;
|
||||
srr1 = SPR_HSRR1;
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_VPU: /* Vector unavailable exception */
|
||||
goto store_current;
|
||||
case POWERPC_EXCP_VSXU: /* VSX unavailable exception */
|
||||
goto store_current;
|
||||
case POWERPC_EXCP_FU: /* Facility unavailable exception */
|
||||
goto store_current;
|
||||
break;
|
||||
case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
|
||||
LOG_EXCP("PIT exception\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_IO: /* IO error exception */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "601 IO error exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_RUNM: /* Run mode exception */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "601 run mode exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_EMUL: /* Emulation trap exception */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "602 emulation trap exception "
|
||||
"is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
|
||||
switch (excp_model) {
|
||||
case POWERPC_EXCP_602:
|
||||
|
@ -577,71 +543,67 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||
cpu_abort(cs, "Invalid data store TLB miss exception\n");
|
||||
break;
|
||||
}
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_FPA: /* Floating-point assist exception */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "Floating point assist exception "
|
||||
"is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_DABR: /* Data address breakpoint */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "DABR exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "IABR exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_SMI: /* System management interrupt */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "SMI exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_THERM: /* Thermal interrupt */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "Thermal management exception "
|
||||
"is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs,
|
||||
"Performance counter exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_VPUA: /* Vector assist exception */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "VPU assist exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_SOFTP: /* Soft patch exception */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs,
|
||||
"970 soft-patch exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_MAINT: /* Maintenance exception */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs,
|
||||
"970 maintenance exception is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "Maskable external exception "
|
||||
"is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */
|
||||
/* XXX: TODO */
|
||||
cpu_abort(cs, "Non maskable external exception "
|
||||
"is not implemented yet !\n");
|
||||
goto store_next;
|
||||
break;
|
||||
default:
|
||||
excp_invalid:
|
||||
cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
|
||||
break;
|
||||
store_current:
|
||||
/* save current instruction location */
|
||||
env->spr[srr0] = env->nip - 4;
|
||||
break;
|
||||
store_next:
|
||||
/* save next instruction location */
|
||||
env->spr[srr0] = env->nip;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Save PC */
|
||||
env->spr[srr0] = env->nip;
|
||||
|
||||
/* Save MSR */
|
||||
env->spr[srr1] = msr;
|
||||
|
||||
|
|
|
@ -2892,10 +2892,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
|
|||
ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, mmu_idx);
|
||||
}
|
||||
if (unlikely(ret != 0)) {
|
||||
if (likely(retaddr)) {
|
||||
/* now we have a real cpu fault */
|
||||
cpu_restore_state(cs, retaddr);
|
||||
}
|
||||
helper_raise_exception_err(env, cs->exception_index, env->error_code);
|
||||
raise_exception_err_ra(env, cs->exception_index, env->error_code,
|
||||
retaddr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,8 +276,12 @@ void gen_update_current_nip(void *opaque)
|
|||
static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
|
||||
{
|
||||
TCGv_i32 t0, t1;
|
||||
|
||||
/* These are all synchronous exceptions, we set the PC back to
|
||||
* the faulting instruction
|
||||
*/
|
||||
if (ctx->exception == POWERPC_EXCP_NONE) {
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
}
|
||||
t0 = tcg_const_i32(excp);
|
||||
t1 = tcg_const_i32(error);
|
||||
|
@ -290,8 +294,12 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
|
|||
static void gen_exception(DisasContext *ctx, uint32_t excp)
|
||||
{
|
||||
TCGv_i32 t0;
|
||||
|
||||
/* These are all synchronous exceptions, we set the PC back to
|
||||
* the faulting instruction
|
||||
*/
|
||||
if (ctx->exception == POWERPC_EXCP_NONE) {
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
}
|
||||
t0 = tcg_const_i32(excp);
|
||||
gen_helper_raise_exception(cpu_env, t0);
|
||||
|
@ -299,13 +307,28 @@ static void gen_exception(DisasContext *ctx, uint32_t excp)
|
|||
ctx->exception = (excp);
|
||||
}
|
||||
|
||||
static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
|
||||
target_ulong nip)
|
||||
{
|
||||
TCGv_i32 t0;
|
||||
|
||||
gen_update_nip(ctx, nip);
|
||||
t0 = tcg_const_i32(excp);
|
||||
gen_helper_raise_exception(cpu_env, t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
ctx->exception = (excp);
|
||||
}
|
||||
|
||||
static void gen_debug_exception(DisasContext *ctx)
|
||||
{
|
||||
TCGv_i32 t0;
|
||||
|
||||
/* These are all synchronous exceptions, we set the PC back to
|
||||
* the faulting instruction
|
||||
*/
|
||||
if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
|
||||
(ctx->exception != POWERPC_EXCP_SYNC)) {
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
}
|
||||
t0 = tcg_const_i32(EXCP_DEBUG);
|
||||
gen_helper_raise_exception(cpu_env, t0);
|
||||
|
@ -1643,7 +1666,7 @@ static void gen_pause(DisasContext *ctx)
|
|||
tcg_temp_free_i32(t0);
|
||||
|
||||
/* Stop translation, this gives other CPUs a chance to run */
|
||||
gen_exception_err(ctx, EXCP_HLT, 1);
|
||||
gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
|
||||
}
|
||||
#endif /* defined(TARGET_PPC64) */
|
||||
|
||||
|
@ -2912,12 +2935,6 @@ static void gen_lswi(DisasContext *ctx)
|
|||
nb = 32;
|
||||
nr = (nb + 3) / 4;
|
||||
if (unlikely(lsw_reg_in_range(start, nr, ra))) {
|
||||
/* The handler expects the PC to point to *this* instruction,
|
||||
* so setting ctx->exception here prevents it from being
|
||||
* improperly updated again by gen_inval_exception
|
||||
*/
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
ctx->exception = POWERPC_EXCP_HV_EMU;
|
||||
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
|
||||
return;
|
||||
}
|
||||
|
@ -3055,16 +3072,12 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
|
|||
int reg, int size)
|
||||
{
|
||||
TCGv t0 = tcg_temp_new();
|
||||
uint32_t save_exception = ctx->exception;
|
||||
|
||||
tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
|
||||
tcg_gen_movi_tl(t0, (size << 5) | reg);
|
||||
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
|
||||
tcg_temp_free(t0);
|
||||
gen_update_nip(ctx, ctx->nip-4);
|
||||
ctx->exception = POWERPC_EXCP_BRANCH;
|
||||
gen_exception(ctx, POWERPC_EXCP_STCX);
|
||||
ctx->exception = save_exception;
|
||||
gen_exception_err(ctx, POWERPC_EXCP_STCX, 0);
|
||||
}
|
||||
#else
|
||||
static void gen_conditional_store(DisasContext *ctx, TCGv EA,
|
||||
|
@ -3203,7 +3216,7 @@ static void gen_wait(DisasContext *ctx)
|
|||
-offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
|
||||
tcg_temp_free_i32(t0);
|
||||
/* Stop translation, as the CPU is supposed to sleep from now */
|
||||
gen_exception_err(ctx, EXCP_HLT, 1);
|
||||
gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
|
@ -3306,10 +3319,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
|||
(CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
|
||||
(ctx->exception == POWERPC_EXCP_BRANCH ||
|
||||
ctx->exception == POWERPC_EXCP_TRACE)) {
|
||||
target_ulong tmp = ctx->nip;
|
||||
ctx->nip = dest;
|
||||
gen_exception(ctx, POWERPC_EXCP_TRACE);
|
||||
ctx->nip = tmp;
|
||||
gen_exception_nip(ctx, POWERPC_EXCP_TRACE, dest);
|
||||
}
|
||||
if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
|
||||
gen_debug_exception(ctx);
|
||||
|
@ -3578,7 +3588,7 @@ static void gen_tw(DisasContext *ctx)
|
|||
{
|
||||
TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
|
||||
/* Update the nip since this might generate a trap exception */
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
|
||||
t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
|
@ -3590,7 +3600,7 @@ static void gen_twi(DisasContext *ctx)
|
|||
TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
|
||||
TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
|
||||
/* Update the nip since this might generate a trap exception */
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free_i32(t1);
|
||||
|
@ -3602,7 +3612,7 @@ static void gen_td(DisasContext *ctx)
|
|||
{
|
||||
TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
|
||||
/* Update the nip since this might generate a trap exception */
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
|
||||
t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
|
@ -3614,7 +3624,7 @@ static void gen_tdi(DisasContext *ctx)
|
|||
TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
|
||||
TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
|
||||
/* Update the nip since this might generate a trap exception */
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free_i32(t1);
|
||||
|
@ -7054,7 +7064,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
|
|||
ctx.exception != POWERPC_SYSCALL &&
|
||||
ctx.exception != POWERPC_EXCP_TRAP &&
|
||||
ctx.exception != POWERPC_EXCP_BRANCH)) {
|
||||
gen_exception(ctxp, POWERPC_EXCP_TRACE);
|
||||
gen_exception_nip(ctxp, POWERPC_EXCP_TRACE, ctx.nip);
|
||||
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
|
||||
(cs->singlestep_enabled) ||
|
||||
singlestep ||
|
||||
|
|
Loading…
Reference in New Issue