qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Chinmay Rath <rathc@linux.ibm.com>
To: Glenn Miles <milesg@linux.ibm.com>, qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, clg@redhat.com, npiggin@gmail.com,
	harshpb@linux.ibm.com, thuth@redhat.com,
	richard.henderson@linaro.org
Subject: Re: [PATCH v5 4/9] target/ppc: Add IBM PPE42 exception model
Date: Thu, 25 Sep 2025 22:19:40 +0530	[thread overview]
Message-ID: <18f62b28-d4ea-4b7c-8e61-375520b6ecb9@linux.ibm.com> (raw)
In-Reply-To: <20250918182731.528944-5-milesg@linux.ibm.com>


On 9/18/25 23:57, Glenn Miles wrote:
> Add support for the IBM PPE42 exception model including
> new exception vectors, exception priorities and setting
> of PPE42 SPRs for determining the cause of an exception.
>
> Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
> ---
>   target/ppc/cpu_init.c        |  39 ++++++++-
>   target/ppc/excp_helper.c     | 163 +++++++++++++++++++++++++++++++++++
>   target/ppc/tcg-excp_helper.c |  12 +++
>   3 files changed, 213 insertions(+), 1 deletion(-)
>
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index b42673c6b5..097e3b3818 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -1720,6 +1720,30 @@ static void init_excp_4xx(CPUPPCState *env)
>   #endif
>   }
>   
> +static void init_excp_ppe42(CPUPPCState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    /* Machine Check vector changed after version 0 */
> +    if (((env->spr[SPR_PVR] & 0xf00000ul) >> 20) == 0) {
> +        env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000000;
> +    } else {
> +        env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000020;
> +    }
> +    env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000040;
> +    env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000060;
> +    env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000080;
> +    env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x000000A0;
> +    env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x000000C0;
> +    env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x000000E0;
> +    env->excp_vectors[POWERPC_EXCP_DECR]     = 0x00000100;
> +    env->excp_vectors[POWERPC_EXCP_FIT]      = 0x00000120;
> +    env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00000140;
> +    env->ivpr_mask = 0xFFFFFE00UL;
> +    /* Hardware reset vector */
> +    env->hreset_vector = 0x00000040UL;
> +#endif
> +}
> +
>   static void init_excp_MPC5xx(CPUPPCState *env)
>   {
>   #if !defined(CONFIG_USER_ONLY)
> @@ -2245,6 +2269,7 @@ static void init_proc_ppe42(CPUPPCState *env)
>   {
>       register_ppe42_sprs(env);
>   
> +    init_excp_ppe42(env);
>       env->dcache_line_size = 32;
>       env->icache_line_size = 32;
>       /* Allocate hardware IRQ controller */
> @@ -2278,7 +2303,7 @@ static void ppe42_class_common_init(PowerPCCPUClass *pcc)
>                       (1ull << MSR_IPE) |
>                       R_MSR_SIBRCA_MASK;
>       pcc->mmu_model = POWERPC_MMU_REAL;
> -    pcc->excp_model = POWERPC_EXCP_40x;
> +    pcc->excp_model = POWERPC_EXCP_PPE42;
>       pcc->bus_model = PPC_FLAGS_INPUT_PPE42;
>       pcc->bfd_mach = bfd_mach_ppc_403;
>       pcc->flags = POWERPC_FLAG_PPE42 | POWERPC_FLAG_BUS_CLK;
> @@ -7855,6 +7880,18 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
>            * they can be read with "p $ivor0", "p $ivor1", etc.
>            */
>           break;
> +    case POWERPC_EXCP_PPE42:
> +        qemu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx "\n",
> +                     env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
> +
> +        qemu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
> +                     "    ISR " TARGET_FMT_lx "   EDR " TARGET_FMT_lx "\n",
> +                     env->spr[SPR_PPE42_TCR], env->spr[SPR_PPE42_TSR],
> +                     env->spr[SPR_PPE42_ISR], env->spr[SPR_PPE42_EDR]);
> +
> +        qemu_fprintf(f, "  PIR " TARGET_FMT_lx "   IVPR " TARGET_FMT_lx "\n",
> +                     env->spr[SPR_PPE42_PIR], env->spr[SPR_PPE42_IVPR]);
> +        break;
>       case POWERPC_EXCP_40x:
>           qemu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
>                        "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 1efdc4066e..d8bca19fff 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -949,6 +949,125 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
>       powerpc_set_excp_state(cpu, vector, new_msr);
>   }
>   
> +static void powerpc_excp_ppe42(PowerPCCPU *cpu, int excp)
> +{
> +    CPUPPCState *env = &cpu->env;
> +    target_ulong msr, new_msr, vector;
> +    target_ulong mcs = PPE42_ISR_MCS_INSTRUCTION;
> +    bool promote_unmaskable;
> +
> +    msr = env->msr;
> +
> +    /*
> +     * New interrupt handler msr preserves SIBRC and ME unless explicitly
> +     * overridden by the exception.  All other MSR bits are zeroed out.
> +     */
> +    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | R_MSR_SIBRC_MASK);
> +
> +    /* HV emu assistance interrupt only exists on server arch 2.05 or later */
> +    if (excp == POWERPC_EXCP_HV_EMU) {
> +        excp = POWERPC_EXCP_PROGRAM;
> +    }
> +
> +    /*
> +     * Unmaskable interrupts (Program, ISI, Alignment and DSI) are promoted to
> +     * machine check if MSR_UIE is 0.
> +     */
> +    promote_unmaskable = !(msr & ((target_ulong)1 << MSR_UIE));
> +
> +
> +    switch (excp) {
> +    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
> +        break;
> +    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
> +        trace_ppc_excp_dsi(env->spr[SPR_PPE42_ISR], env->spr[SPR_PPE42_EDR]);
> +        if (promote_unmaskable) {
> +            excp = POWERPC_EXCP_MCHECK;
> +            mcs = PPE42_ISR_MCS_DSI;
> +        }
> +        break;
> +    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
> +        trace_ppc_excp_isi(msr, env->nip);
> +        if (promote_unmaskable) {
> +            excp = POWERPC_EXCP_MCHECK;
> +            mcs = PPE42_ISR_MCS_ISI;
> +        }
> +        break;
> +    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
> +        break;
> +    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
> +        if (promote_unmaskable) {
> +            excp = POWERPC_EXCP_MCHECK;
> +            mcs = PPE42_ISR_MCS_ALIGNMENT;
> +        }
> +        break;
> +    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
> +        if (promote_unmaskable) {
> +            excp = POWERPC_EXCP_MCHECK;
> +            mcs = PPE42_ISR_MCS_PROGRAM;
> +        }
> +        switch (env->error_code & ~0xF) {
> +        case POWERPC_EXCP_INVAL:
> +            trace_ppc_excp_inval(env->nip);
> +            env->spr[SPR_PPE42_ISR] &= ~((target_ulong)1 << PPE42_ISR_PTR);
> +            break;
> +        case POWERPC_EXCP_TRAP:
> +            env->spr[SPR_PPE42_ISR] |= ((target_ulong)1 << PPE42_ISR_PTR);
> +            break;
> +        default:
> +            /* Should never occur */
> +            cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
> +                      env->error_code);
> +            break;
> +        }
> +#ifdef CONFIG_TCG
> +        env->spr[SPR_PPE42_EDR] = ppc_ldl_code(env, env->nip);
> +#endif
> +        break;
> +    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
> +        break;
> +    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
> +        trace_ppc_excp_print("FIT");
> +        break;
> +    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
> +        trace_ppc_excp_print("WDT");
> +        break;
> +    case POWERPC_EXCP_RESET:     /* System reset exception                   */
> +        /* reset exceptions don't have ME set */
> +        new_msr &= ~((target_ulong)1 << MSR_ME);
> +        break;
> +    default:
> +        cpu_abort(env_cpu(env), "Invalid PPE42 exception %d. Aborting\n",
> +                  excp);
> +        break;
> +    }
> +
> +    env->spr[SPR_SRR0] = env->nip;
> +    env->spr[SPR_SRR1] = msr;
> +
> +    vector = env->excp_vectors[excp];
> +    if (vector == (target_ulong)-1ULL) {
> +        cpu_abort(env_cpu(env),
> +                  "Raised an exception without defined vector %d\n", excp);
> +    }
> +    vector |= env->spr[SPR_PPE42_IVPR];
> +
> +    if (excp == POWERPC_EXCP_MCHECK) {
> +        /* Also set the Machine Check Status (MCS) */
> +        env->spr[SPR_PPE42_ISR] &= ~R_PPE42_ISR_MCS_MASK;
> +        env->spr[SPR_PPE42_ISR] |= (mcs & R_PPE42_ISR_MCS_MASK);
> +        env->spr[SPR_PPE42_ISR] &= ~((target_ulong)1 << PPE42_ISR_MFE);
> +
> +        /* Machine checks halt execution if MSR_ME is 0 */
> +        powerpc_mcheck_checkstop(env);
> +
> +        /* machine check exceptions don't have ME set */
> +        new_msr &= ~((target_ulong)1 << MSR_ME);
> +    }
> +
> +    powerpc_set_excp_state(cpu, vector, new_msr);
> +}
> +
>   static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
>   {
>       CPUPPCState *env = &cpu->env;
> @@ -1589,6 +1708,9 @@ void powerpc_excp(PowerPCCPU *cpu, int excp)
>       case POWERPC_EXCP_POWER11:
>           powerpc_excp_books(cpu, excp);
>           break;
> +    case POWERPC_EXCP_PPE42:
> +        powerpc_excp_ppe42(cpu, excp);
> +        break;
>       default:
>           g_assert_not_reached();
>       }
> @@ -1945,6 +2067,43 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
>   }
>   #endif /* TARGET_PPC64 */
>   
> +static int ppe42_next_unmasked_interrupt(CPUPPCState *env)
> +{
> +    bool async_deliver;
> +
> +    /* External reset */
> +    if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
> +        return PPC_INTERRUPT_RESET;
> +    }
> +    /* Machine check exception */
> +    if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
> +        return PPC_INTERRUPT_MCK;
> +    }
> +
> +    async_deliver = FIELD_EX64(env->msr, MSR, EE);
> +
> +    if (async_deliver != 0) {
> +        /* Watchdog timer */
> +        if (env->pending_interrupts & PPC_INTERRUPT_WDT) {
> +            return PPC_INTERRUPT_WDT;
> +        }
> +        /* External Interrupt */
> +        if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
> +            return PPC_INTERRUPT_EXT;
> +        }
> +        /* Fixed interval timer */
> +        if (env->pending_interrupts & PPC_INTERRUPT_FIT) {
> +            return PPC_INTERRUPT_FIT;
> +        }
> +        /* Decrementer exception */
> +        if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
> +            return PPC_INTERRUPT_DECR;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>   static int ppc_next_unmasked_interrupt(CPUPPCState *env)
>   {
>       uint32_t pending_interrupts = env->pending_interrupts;
> @@ -1970,6 +2129,10 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
>       }
>   #endif
>   
> +    if (env->excp_model == POWERPC_EXCP_PPE42) {
> +        return ppe42_next_unmasked_interrupt(env);
> +    }
> +
>       /* External reset */
>       if (pending_interrupts & PPC_INTERRUPT_RESET) {
>           return PPC_INTERRUPT_RESET;
> diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c
> index f835be5156..edecfb8572 100644
> --- a/target/ppc/tcg-excp_helper.c
> +++ b/target/ppc/tcg-excp_helper.c
> @@ -229,6 +229,18 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
>       case POWERPC_MMU_BOOKE206:
>           env->spr[SPR_BOOKE_DEAR] = vaddr;
>           break;
> +    case POWERPC_MMU_REAL:
> +        if (env->flags & POWERPC_FLAG_PPE42) {
> +            env->spr[SPR_PPE42_EDR] = vaddr;
> +            if (access_type == MMU_DATA_STORE) {
> +                env->spr[SPR_PPE42_ISR] |= PPE42_ISR_ST;
> +            } else {
> +                env->spr[SPR_PPE42_ISR] &= ~PPE42_ISR_ST;
> +            }
> +        } else {
> +            env->spr[SPR_DAR] = vaddr;
> +        }
> +        break;
>       default:
>           env->spr[SPR_DAR] = vaddr;
>           break;


  reply	other threads:[~2025-09-25 16:51 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-18 18:27 [PATCH v5 0/9] Add IBM PPE42 CPU support Glenn Miles
2025-09-18 18:27 ` [PATCH v5 1/9] target/ppc: IBM PPE42 general regs and flags Glenn Miles
2025-09-24 12:28   ` Chinmay Rath
2025-09-18 18:27 ` [PATCH v5 2/9] target/ppc: Add IBM PPE42 family of processors Glenn Miles
2025-09-24 12:32   ` Chinmay Rath
2025-09-24 14:52     ` Miles Glenn
2025-09-24 15:06       ` Miles Glenn
2025-09-25  4:57         ` Harsh Prateek Bora
2025-09-25 15:29           ` Miles Glenn
2025-09-25 15:54             ` Harsh Prateek Bora
2025-09-18 18:27 ` [PATCH v5 3/9] target/ppc: IBM PPE42 exception flags and regs Glenn Miles
2025-09-25 16:25   ` Chinmay Rath
2025-09-18 18:27 ` [PATCH v5 4/9] target/ppc: Add IBM PPE42 exception model Glenn Miles
2025-09-25 16:49   ` Chinmay Rath [this message]
2025-09-18 18:27 ` [PATCH v5 5/9] target/ppc: Support for IBM PPE42 MMU Glenn Miles
2025-09-25 18:57   ` Chinmay Rath
2025-09-18 18:27 ` [PATCH v5 6/9] target/ppc: Add IBM PPE42 special instructions Glenn Miles
2025-09-22 10:18   ` Chinmay Rath
2025-09-18 18:27 ` [PATCH v5 7/9] hw/ppc: Support for an IBM PPE42 CPU decrementer Glenn Miles
2025-09-18 18:27 ` [PATCH v5 8/9] hw/ppc: Add a test machine for the IBM PPE42 CPU Glenn Miles
2025-09-18 18:27 ` [PATCH v5 9/9] tests/functional: Add test for IBM PPE42 instructions Glenn Miles
2025-09-19  8:29   ` Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=18f62b28-d4ea-4b7c-8e61-375520b6ecb9@linux.ibm.com \
    --to=rathc@linux.ibm.com \
    --cc=clg@redhat.com \
    --cc=harshpb@linux.ibm.com \
    --cc=milesg@linux.ibm.com \
    --cc=npiggin@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).