ISA v3.1 introduced prefix instructions. Among the changes, various synchronous interrupts report whether they were caused by a prefix instruction in (H)SRR1.
Signed-off-by: Nicholas Piggin <npig...@gmail.com> --- target/ppc/excp_helper.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index c8b8eca3b1..2e0321ab69 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1353,12 +1353,26 @@ static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu) return false; } +static bool is_prefix_excp(CPUPPCState *env, uint32_t insn) +{ + switch (env->excp_model) { + case POWERPC_EXCP_970: + case POWERPC_EXCP_POWER7: + case POWERPC_EXCP_POWER8: + case POWERPC_EXCP_POWER9: + return false; + default: /* POWER10 / ISAv3.1 onward */ + return ((insn & 0xfc000000) == 0x04000000); + } +} + static void powerpc_excp_books(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; target_ulong msr, new_msr, vector; int srr0, srr1, lev = -1; + uint32_t insn = 0; /* new srr1 value excluding must-be-zero bits */ msr = env->msr & ~0x783f0000ULL; @@ -1397,6 +1411,29 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp) vector |= env->excp_prefix; + switch (excp) { + case POWERPC_EXCP_MCHECK: + case POWERPC_EXCP_DSI: + case POWERPC_EXCP_DSEG: + case POWERPC_EXCP_ALIGN: + case POWERPC_EXCP_PROGRAM: + case POWERPC_EXCP_FPU: + case POWERPC_EXCP_TRACE: + case POWERPC_EXCP_HDSI: + case POWERPC_EXCP_HV_EMU: + case POWERPC_EXCP_VPU: + case POWERPC_EXCP_VSXU: + case POWERPC_EXCP_FU: + case POWERPC_EXCP_HV_FU: + insn = ppc_ldl_code(env, env->nip); + if (is_prefix_excp(env, insn)) { + msr |= PPC_BIT(34); + } + break; + default: + break; + } + switch (excp) { case POWERPC_EXCP_MCHECK: /* Machine check exception */ if (!FIELD_EX64(env->msr, MSR, ME)) { -- 2.37.2