From: "Cédric Le Goater" <clg@redhat.com>
To: Glenn Miles <milesg@linux.ibm.com>, qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, npiggin@gmail.com, harshpb@linux.ibm.com,
thuth@redhat.com, rathc@linux.ibm.com,
richard.henderson@linaro.org
Subject: Re: [PATCH v2 1/4] target/ppc: Add IBM PPE42 family of processors
Date: Mon, 1 Sep 2025 09:29:24 +0200 [thread overview]
Message-ID: <a388fe15-f32f-45a6-accd-a85fe123a3e4@redhat.com> (raw)
In-Reply-To: <20250826201920.335308-2-milesg@linux.ibm.com>
On 8/26/25 22:17, Glenn Miles wrote:
> Adds the IBM PPE42 family of 32-bit processors supporting
> the PPE42, PPE42X and PPE42XM processor versions. These
> processors are used as embedded processors in the IBM
> Power9, Power10 and Power12 processors for various
> tasks. It is basically a stripped down version of the
> IBM PowerPC 405 processor, with some added instructions
> for handling 64-bit loads and stores.
>
> For more information on the PPE 42 processor please visit:
>
> https://wiki.raptorcs.com/w/images/a/a3/PPE_42X_Core_Users_Manual.pdf
>
> Supports PPE42 SPR's (Including the MSR) and Exceptions.
>
> Does not yet support new PPE42 instructions and does not
> prevent access to some invalid instructions and registers
> (currently allows for access to invalid GPR's and CR fields).
>
> Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Could you please split these changes : CPU, exceptions, MMU ?
Introduce the flags first in case they are needed.
Thanks,
C.
> ---
>
> Changes since previous version
> - Added "32-bit" wording to commit message
> - Added 'unlikely' specifier to hreg_compute_hflags_value conditional
> - Added PPE42_ prefix to ISR definitions
> - Moved ISR_MCS* definitions from excp_helper.c to cpu.h
> - Moved common cpu_init code to a common function
> - Added 'likely' specifier to gen_mtmsr conditional
> - Formatting changes to fit comments within 80 character limit
>
> target/ppc/cpu-models.c | 7 +
> target/ppc/cpu-models.h | 4 +
> target/ppc/cpu.h | 76 ++++++++++-
> target/ppc/cpu_init.c | 241 +++++++++++++++++++++++++++++------
> target/ppc/excp_helper.c | 163 +++++++++++++++++++++++
> target/ppc/helper_regs.c | 28 +++-
> target/ppc/tcg-excp_helper.c | 12 ++
> target/ppc/translate.c | 6 +-
> 8 files changed, 492 insertions(+), 45 deletions(-)
>
> diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
> index ea86ea202a..09f73e23a8 100644
> --- a/target/ppc/cpu-models.c
> +++ b/target/ppc/cpu-models.c
> @@ -116,6 +116,13 @@
> NULL)
> POWERPC_DEF("x2vp20", CPU_POWERPC_X2VP20, 405,
> NULL)
> + /* PPE42 Embedded Controllers */
> + POWERPC_DEF("PPE42", CPU_POWERPC_PPE42, ppe42,
> + "Generic PPE 42")
> + POWERPC_DEF("PPE42X", CPU_POWERPC_PPE42X, ppe42x,
> + "Generic PPE 42X")
> + POWERPC_DEF("PPE42XM", CPU_POWERPC_PPE42XM, ppe42xm,
> + "Generic PPE 42XM")
> /* PowerPC 440 family */
> #if defined(TODO_USER_ONLY)
> POWERPC_DEF("440", CPU_POWERPC_440, 440GP,
> diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
> index 72ad31ba50..c6cd27f390 100644
> --- a/target/ppc/cpu-models.h
> +++ b/target/ppc/cpu-models.h
> @@ -69,6 +69,10 @@ enum {
> /* Xilinx cores */
> CPU_POWERPC_X2VP4 = 0x20010820,
> CPU_POWERPC_X2VP20 = 0x20010860,
> + /* IBM PPE42 Family */
> + CPU_POWERPC_PPE42 = 0x42000000,
> + CPU_POWERPC_PPE42X = 0x42100000,
> + CPU_POWERPC_PPE42XM = 0x42200000,
> /* PowerPC 440 family */
> /* Generic PowerPC 440 */
> #define CPU_POWERPC_440 CPU_POWERPC_440GXf
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 6b90543811..c68dd4f141 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -220,6 +220,8 @@ typedef enum powerpc_excp_t {
> POWERPC_EXCP_POWER10,
> /* POWER11 exception model */
> POWERPC_EXCP_POWER11,
> + /* PPE42 exception model */
> + POWERPC_EXCP_PPE42,
> } powerpc_excp_t;
>
> /*****************************************************************************/
> @@ -282,6 +284,8 @@ typedef enum powerpc_input_t {
> PPC_FLAGS_INPUT_POWER9,
> /* Freescale RCPU bus */
> PPC_FLAGS_INPUT_RCPU,
> + /* PPE42 bus */
> + PPC_FLAGS_INPUT_PPE42,
> } powerpc_input_t;
>
> #define PPC_INPUT(env) ((env)->bus_model)
> @@ -433,39 +437,64 @@ typedef enum {
> #define MSR_TM PPC_BIT_NR(31) /* Transactional Memory Available (Book3s) */
> #define MSR_CM PPC_BIT_NR(32) /* Computation mode for BookE hflags */
> #define MSR_ICM PPC_BIT_NR(33) /* Interrupt computation mode for BookE */
> +#define MSR_SEM0 PPC_BIT_NR(33) /* SIB Error Mask Bit 0 (PPE42) */
> +#define MSR_SEM1 PPC_BIT_NR(34) /* SIB Error Mask Bit 1 (PPE42) */
> +#define MSR_SEM2 PPC_BIT_NR(35) /* SIB Error Mask Bit 2 (PPE42) */
> #define MSR_GS PPC_BIT_NR(35) /* guest state for BookE */
> +#define MSR_SEM3 PPC_BIT_NR(36) /* SIB Error Mask Bit 3 (PPE42) */
> +#define MSR_SEM4 PPC_BIT_NR(37) /* SIB Error Mask Bit 4 (PPE42) */
> #define MSR_UCLE PPC_BIT_NR(37) /* User-mode cache lock enable for BookE */
> #define MSR_VR PPC_BIT_NR(38) /* altivec available x hflags */
> #define MSR_SPE PPC_BIT_NR(38) /* SPE enable for BookE x hflags */
> +#define MSR_SEM5 PPC_BIT_NR(38) /* SIB Error Mask Bit 5 (PPE42) */
> +#define MSR_SEM6 PPC_BIT_NR(39) /* SIB Error Mask Bit 6 (PPE42) */
> #define MSR_VSX PPC_BIT_NR(40) /* Vector Scalar Extension (>= 2.06)x hflags */
> +#define MSR_IS0 PPC_BIT_NR(40) /* Instance Specific Bit 0 (PPE42) */
> #define MSR_S PPC_BIT_NR(41) /* Secure state */
> +#define MSR_SIBRC0 PPC_BIT_NR(41) /* Last SIB return code Bit 0 (PPE42) */
> +#define MSR_SIBRC1 PPC_BIT_NR(42) /* Last SIB return code Bit 1 (PPE42) */
> +#define MSR_SIBRC2 PPC_BIT_NR(43) /* Last SIB return code Bit 2 (PPE42) */
> +#define MSR_LP PPC_BIT_NR(44) /* Low Priority (PPE42) */
> #define MSR_KEY PPC_BIT_NR(44) /* key bit on 603e */
> #define MSR_POW PPC_BIT_NR(45) /* Power management */
> #define MSR_WE PPC_BIT_NR(45) /* Wait State Enable on 405 */
> +#define MSR_IS1 PPC_BIT_NR(46) /* Instance Specific Bit 1 (PPE42) */
> #define MSR_TGPR PPC_BIT_NR(46) /* TGPR usage on 602/603 x */
> #define MSR_CE PPC_BIT_NR(46) /* Critical int. enable on embedded PPC x */
> #define MSR_ILE PPC_BIT_NR(47) /* Interrupt little-endian mode */
> +#define MSR_UIE PPC_BIT_NR(47) /* Unmaskable Interrupt Enable (PPE42) */
> #define MSR_EE PPC_BIT_NR(48) /* External interrupt enable */
> #define MSR_PR PPC_BIT_NR(49) /* Problem state hflags */
> #define MSR_FP PPC_BIT_NR(50) /* Floating point available hflags */
> #define MSR_ME PPC_BIT_NR(51) /* Machine check interrupt enable */
> #define MSR_FE0 PPC_BIT_NR(52) /* Floating point exception mode 0 */
> +#define MSR_IS2 PPC_BIT_NR(52) /* Instance Specific Bit 2 (PPE42) */
> +#define MSR_IS3 PPC_BIT_NR(53) /* Instance Specific Bit 3 (PPE42) */
> #define MSR_SE PPC_BIT_NR(53) /* Single-step trace enable x hflags */
> #define MSR_DWE PPC_BIT_NR(53) /* Debug wait enable on 405 x */
> #define MSR_UBLE PPC_BIT_NR(53) /* User BTB lock enable on e500 x */
> #define MSR_BE PPC_BIT_NR(54) /* Branch trace enable x hflags */
> #define MSR_DE PPC_BIT_NR(54) /* Debug int. enable on embedded PPC x */
> #define MSR_FE1 PPC_BIT_NR(55) /* Floating point exception mode 1 */
> +#define MSR_IPE PPC_BIT_NR(55) /* Imprecise Mode Enable (PPE42) */
> #define MSR_AL PPC_BIT_NR(56) /* AL bit on POWER */
> +#define MSR_SIBRCA0 PPC_BIT_NR(56) /* SIB Return Code Accumulator 0 (PPE42) */
> +#define MSR_SIBRCA1 PPC_BIT_NR(57) /* SIB Return Code Accumulator 1 (PPE42) */
> #define MSR_EP PPC_BIT_NR(57) /* Exception prefix on 601 */
> #define MSR_IR PPC_BIT_NR(58) /* Instruction relocate */
> #define MSR_IS PPC_BIT_NR(58) /* Instruction address space (BookE) */
> +#define MSR_SIBRCA2 PPC_BIT_NR(58) /* SIB Return Code Accumulator 2 (PPE42) */
> +#define MSR_SIBRCA3 PPC_BIT_NR(59) /* SIB Return Code Accumulator 3 (PPE42) */
> #define MSR_DR PPC_BIT_NR(59) /* Data relocate */
> #define MSR_DS PPC_BIT_NR(59) /* Data address space (BookE) */
> #define MSR_PE PPC_BIT_NR(60) /* Protection enable on 403 */
> +#define MSR_SIBRCA4 PPC_BIT_NR(60) /* SIB Return Code Accumulator 4 (PPE42) */
> +#define MSR_SIBRCA5 PPC_BIT_NR(61) /* SIB Return Code Accumulator 5 (PPE42) */
> #define MSR_PX PPC_BIT_NR(61) /* Protection exclusive on 403 x */
> #define MSR_PMM PPC_BIT_NR(61) /* Performance monitor mark on POWER x */
> #define MSR_RI PPC_BIT_NR(62) /* Recoverable interrupt 1 */
> +#define MSR_SIBRCA6 PPC_BIT_NR(62) /* SIB Return Code Accumulator 6 (PPE42) */
> +#define MSR_SIBRCA7 PPC_BIT_NR(63) /* SIB Return Code Accumulator 7 (PPE42) */
> #define MSR_LE PPC_BIT_NR(63) /* Little-endian mode 1 hflags */
>
> FIELD(MSR, SF, MSR_SF, 1)
> @@ -517,6 +546,9 @@ FIELD(MSR, PX, MSR_PX, 1)
> FIELD(MSR, PMM, MSR_PMM, 1)
> FIELD(MSR, RI, MSR_RI, 1)
> FIELD(MSR, LE, MSR_LE, 1)
> +FIELD(MSR, SEM, MSR_SEM6, 7)
> +FIELD(MSR, SIBRC, MSR_SIBRC2, 3)
> +FIELD(MSR, SIBRCA, MSR_SIBRCA7, 8)
>
> /*
> * FE0 and FE1 bits are not side-by-side
> @@ -730,6 +762,31 @@ FIELD(MSR, LE, MSR_LE, 1)
> #define ESR_VLEMI PPC_BIT(58) /* VLE operation */
> #define ESR_MIF PPC_BIT(62) /* Misaligned instruction (VLE) */
>
> +/* PPE42 Interrupt Status Register bits */
> +#define PPE42_ISR_SRSMS0 PPC_BIT_NR(48) /* Sys Reset State Machine State 0 */
> +#define PPE42_ISR_SRSMS1 PPC_BIT_NR(49) /* Sys Reset State Machine State 1 */
> +#define PPE42_ISR_SRSMS2 PPC_BIT_NR(50) /* Sys Reset State Machine State 2 */
> +#define PPE42_ISR_SRSMS3 PPC_BIT_NR(51) /* Sys Reset State Machine State 3 */
> +#define PPE42_ISR_EP PPC_BIT_NR(53) /* MSR[EE] Maskable Event Pending */
> +#define PPE42_ISR_PTR PPC_BIT_NR(56) /* Program Interrupt from trap */
> +#define PPE42_ISR_ST PPC_BIT_NR(57) /* Data Interrupt caused by store */
> +#define PPE42_ISR_MFE PPC_BIT_NR(60) /* Multiple Fault Error */
> +#define PPE42_ISR_MCS0 PPC_BIT_NR(61) /* Machine Check Status bit0 */
> +#define PPE42_ISR_MCS1 PPC_BIT_NR(62) /* Machine Check Status bit1 */
> +#define PPE42_ISR_MCS2 PPC_BIT_NR(63) /* Machine Check Status bit2 */
> +FIELD(PPE42_ISR, SRSMS, PPE42_ISR_SRSMS3, 4)
> +FIELD(PPE42_ISR, MCS, PPE42_ISR_MCS2, 3)
> +
> +/* PPE42 Machine Check Status field values */
> +#define PPE42_ISR_MCS_INSTRUCTION 0
> +#define PPE42_ISR_MCS_DATA_LOAD 1
> +#define PPE42_ISR_MCS_DATA_PRECISE_STORE 2
> +#define PPE42_ISR_MCS_DATA_IMPRECISE_STORE 3
> +#define PPE42_ISR_MCS_PROGRAM 4
> +#define PPE42_ISR_MCS_ISI 5
> +#define PPE42_ISR_MCS_ALIGNMENT 6
> +#define PPE42_ISR_MCS_DSI 7
> +
> /* Transaction EXception And Summary Register bits */
> #define TEXASR_FAILURE_PERSISTENT (63 - 7)
> #define TEXASR_DISALLOWED (63 - 8)
> @@ -785,6 +842,8 @@ enum {
> POWERPC_FLAG_SMT_1LPAR = 0x00800000,
> /* Has BHRB */
> POWERPC_FLAG_BHRB = 0x01000000,
> + /* Use PPE42-specific behavior */
> + POWERPC_FLAG_PPE42 = 0x02000000,
> };
>
> /*
> @@ -1750,9 +1809,12 @@ void ppc_compat_add_property(Object *obj, const char *name,
> #define SPR_BOOKE_CSRR0 (0x03A)
> #define SPR_BOOKE_CSRR1 (0x03B)
> #define SPR_BOOKE_DEAR (0x03D)
> +#define SPR_PPE42_EDR (0x03D)
> #define SPR_IAMR (0x03D)
> #define SPR_BOOKE_ESR (0x03E)
> +#define SPR_PPE42_ISR (0x03E)
> #define SPR_BOOKE_IVPR (0x03F)
> +#define SPR_PPE42_IVPR (0x03F)
> #define SPR_MPC_EIE (0x050)
> #define SPR_MPC_EID (0x051)
> #define SPR_MPC_NRI (0x052)
> @@ -1818,6 +1880,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
> #define SPR_TBU40 (0x11E)
> #define SPR_SVR (0x11E)
> #define SPR_BOOKE_PIR (0x11E)
> +#define SPR_PPE42_PIR (0x11E)
> #define SPR_PVR (0x11F)
> #define SPR_HSPRG0 (0x130)
> #define SPR_BOOKE_DBSR (0x130)
> @@ -1827,6 +1890,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
> #define SPR_BOOKE_EPCR (0x133)
> #define SPR_SPURR (0x134)
> #define SPR_BOOKE_DBCR0 (0x134)
> +#define SPR_PPE42_DBCR (0x134)
> #define SPR_IBCR (0x135)
> #define SPR_PURR (0x135)
> #define SPR_BOOKE_DBCR1 (0x135)
> @@ -1844,6 +1908,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
> #define SPR_HSRR1 (0x13B)
> #define SPR_BOOKE_IAC4 (0x13B)
> #define SPR_BOOKE_DAC1 (0x13C)
> +#define SPR_PPE42_DACR (0x13C)
> #define SPR_MMCRH (0x13C)
> #define SPR_DABR2 (0x13D)
> #define SPR_BOOKE_DAC2 (0x13D)
> @@ -1853,12 +1918,14 @@ void ppc_compat_add_property(Object *obj, const char *name,
> #define SPR_BOOKE_DVC2 (0x13F)
> #define SPR_LPIDR (0x13F)
> #define SPR_BOOKE_TSR (0x150)
> +#define SPR_PPE42_TSR (0x150)
> #define SPR_HMER (0x150)
> #define SPR_HMEER (0x151)
> #define SPR_PCR (0x152)
> #define SPR_HEIR (0x153)
> #define SPR_BOOKE_LPIDR (0x152)
> #define SPR_BOOKE_TCR (0x154)
> +#define SPR_PPE42_TCR (0x154)
> #define SPR_BOOKE_TLB0PS (0x158)
> #define SPR_BOOKE_TLB1PS (0x159)
> #define SPR_BOOKE_TLB2PS (0x15A)
> @@ -2528,6 +2595,12 @@ enum {
> PPC2_MEM_LWSYNC = 0x0000000000200000ULL,
> /* ISA 2.06 BCD assist instructions */
> PPC2_BCDA_ISA206 = 0x0000000000400000ULL,
> + /* PPE42 instructions */
> + PPC2_PPE42 = 0x0000000000800000ULL,
> + /* PPE42X instructions */
> + PPC2_PPE42X = 0x0000000001000000ULL,
> + /* PPE42XM instructions */
> + PPC2_PPE42XM = 0x0000000002000000ULL,
>
> #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
> PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
> @@ -2537,7 +2610,8 @@ enum {
> PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
> PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206 | \
> PPC2_ISA300 | PPC2_ISA310 | PPC2_MEM_LWSYNC | \
> - PPC2_BCDA_ISA206)
> + PPC2_BCDA_ISA206 | PPC2_PPE42 | PPC2_PPE42X | \
> + PPC2_PPE42XM)
> };
>
> /*****************************************************************************/
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index a0e77f2673..698d61bf0c 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -1653,6 +1653,47 @@ static void register_8xx_sprs(CPUPPCState *env)
> * ... and more (thermal management, performance counters, ...)
> */
>
> +static void register_ppe42_sprs(CPUPPCState *env)
> +{
> + spr_register(env, SPR_PPE42_EDR, "EDR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, &spr_write_generic,
> + 0x00000000);
> + spr_register(env, SPR_PPE42_ISR, "ISR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, &spr_write_generic,
> + 0x00000000);
> + spr_register(env, SPR_PPE42_IVPR, "IVPR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, SPR_NOACCESS,
> + 0xfff80000);
> + spr_register(env, SPR_PPE42_PIR, "PIR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, &spr_write_pir,
> + 0x00000000);
> + spr_register(env, SPR_PPE42_DBCR, "DBCR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, &spr_write_40x_dbcr0,
> + 0x00000000);
> + spr_register(env, SPR_PPE42_DACR, "DACR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, &spr_write_generic,
> + 0x00000000);
> + /* Timer */
> + spr_register(env, SPR_DECR, "DECR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_decr, &spr_write_decr,
> + 0x00000000);
> + spr_register(env, SPR_PPE42_TSR, "TSR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, &spr_write_booke_tsr,
> + 0x00000000);
> + spr_register(env, SPR_BOOKE_TCR, "TCR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, &spr_write_booke_tcr,
> + 0x00000000);
> +}
> +
> /*****************************************************************************/
> /* Exception vectors models */
> static void init_excp_4xx(CPUPPCState *env)
> @@ -1679,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)
> @@ -2200,6 +2265,80 @@ POWERPC_FAMILY(405)(ObjectClass *oc, const void *data)
> POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
> }
>
> +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 */
> + ppc40x_irq_init(env_archcpu(env));
> +
> + SET_FIT_PERIOD(8, 12, 16, 20);
> + SET_WDT_PERIOD(16, 20, 24, 28);
> +}
> +
> +static void ppe42_class_common_init(PowerPCCPUClass *pcc)
> +{
> + pcc->init_proc = init_proc_ppe42;
> + pcc->check_pow = check_pow_nocheck;
> + pcc->check_attn = check_attn_none;
> + pcc->insns_flags = PPC_INSNS_BASE |
> + PPC_WRTEE |
> + PPC_CACHE |
> + PPC_CACHE_DCBZ |
> + PPC_MEM_SYNC;
> + pcc->msr_mask = R_MSR_SEM_MASK |
> + (1ull << MSR_IS0) |
> + R_MSR_SIBRC_MASK |
> + (1ull << MSR_LP) |
> + (1ull << MSR_WE) |
> + (1ull << MSR_IS1) |
> + (1ull << MSR_UIE) |
> + (1ull << MSR_EE) |
> + (1ull << MSR_ME) |
> + (1ull << MSR_IS2) |
> + (1ull << MSR_IS3) |
> + (1ull << MSR_IPE) |
> + R_MSR_SIBRCA_MASK;
> + pcc->mmu_model = POWERPC_MMU_REAL;
> + 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;
> +}
> +
> +POWERPC_FAMILY(ppe42)(ObjectClass *oc, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> +
> + dc->desc = "PPE 42";
> + pcc->insns_flags2 = PPC2_PPE42;
> + ppe42_class_common_init(pcc);
> +}
> +
> +POWERPC_FAMILY(ppe42x)(ObjectClass *oc, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> +
> + dc->desc = "PPE 42X";
> + pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X;
> + ppe42_class_common_init(pcc);
> +}
> +
> +POWERPC_FAMILY(ppe42xm)(ObjectClass *oc, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> +
> + dc->desc = "PPE 42XM";
> + pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X | PPC2_PPE42XM;
> + ppe42_class_common_init(pcc);
> +}
> +
> static void init_proc_440EP(CPUPPCState *env)
> {
> register_BookE_sprs(env, 0x000000000000FFFFULL);
> @@ -6802,53 +6941,63 @@ static void init_ppc_proc(PowerPCCPU *cpu)
>
> /* MSR bits & flags consistency checks */
> if (env->msr_mask & (1 << 25)) {
> - switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
> + switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE |
> + POWERPC_FLAG_PPE42)) {
> case POWERPC_FLAG_SPE:
> case POWERPC_FLAG_VRE:
> + case POWERPC_FLAG_PPE42:
> break;
> default:
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> - "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
> + "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n"
> + "or POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> - "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
> + "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n"
> + "nor POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> if (env->msr_mask & (1 << 17)) {
> - switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
> + switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
> + POWERPC_FLAG_PPE42)) {
> case POWERPC_FLAG_TGPR:
> case POWERPC_FLAG_CE:
> + case POWERPC_FLAG_PPE42:
> break;
> default:
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> - "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
> + "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n"
> + "or POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> - } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
> + } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
> + POWERPC_FLAG_PPE42)) {
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> - "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
> + "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n"
> + "nor POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> if (env->msr_mask & (1 << 10)) {
> switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
> - POWERPC_FLAG_UBLE)) {
> + POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
> case POWERPC_FLAG_SE:
> case POWERPC_FLAG_DWE:
> case POWERPC_FLAG_UBLE:
> + case POWERPC_FLAG_PPE42:
> break;
> default:
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
> - "POWERPC_FLAG_UBLE\n");
> + "POWERPC_FLAG_UBLE or POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
> - POWERPC_FLAG_UBLE)) {
> + POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
> - "POWERPC_FLAG_UBLE\n");
> + "POWERPC_FLAG_UBLE nor POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> if (env->msr_mask & (1 << 9)) {
> @@ -6867,18 +7016,23 @@ static void init_ppc_proc(PowerPCCPU *cpu)
> exit(1);
> }
> if (env->msr_mask & (1 << 2)) {
> - switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
> + switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
> + POWERPC_FLAG_PPE42)) {
> case POWERPC_FLAG_PX:
> case POWERPC_FLAG_PMM:
> + case POWERPC_FLAG_PPE42:
> break;
> default:
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> - "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
> + "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n"
> + "or POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> - } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
> + } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
> + POWERPC_FLAG_PPE42)) {
> fprintf(stderr, "PowerPC MSR definition inconsistency\n"
> - "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
> + "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n"
> + "nor POWERPC_FLAG_PPE42\n");
> exit(1);
> }
> if ((env->flags & POWERPC_FLAG_BUS_CLK) == 0) {
> @@ -7243,39 +7397,40 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
> }
>
> msr = (target_ulong)0;
> - msr |= (target_ulong)MSR_HVB;
> - msr |= (target_ulong)1 << MSR_EP;
> + if (!(env->flags & POWERPC_FLAG_PPE42)) {
> + msr |= (target_ulong)MSR_HVB;
> + msr |= (target_ulong)1 << MSR_EP;
> #if defined(DO_SINGLE_STEP) && 0
> - /* Single step trace mode */
> - msr |= (target_ulong)1 << MSR_SE;
> - msr |= (target_ulong)1 << MSR_BE;
> + /* Single step trace mode */
> + msr |= (target_ulong)1 << MSR_SE;
> + msr |= (target_ulong)1 << MSR_BE;
> #endif
> #if defined(CONFIG_USER_ONLY)
> - msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
> - msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
> - msr |= (target_ulong)1 << MSR_FE1;
> - msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
> - msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
> - msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
> - msr |= (target_ulong)1 << MSR_PR;
> + msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
> + msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
> + msr |= (target_ulong)1 << MSR_FE1;
> + msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
> + msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
> + msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
> + msr |= (target_ulong)1 << MSR_PR;
> #if defined(TARGET_PPC64)
> - msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
> + msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
> #endif
> #if !TARGET_BIG_ENDIAN
> - msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
> - if (!((env->msr_mask >> MSR_LE) & 1)) {
> - fprintf(stderr, "Selected CPU does not support little-endian.\n");
> - exit(1);
> - }
> + msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
> + if (!((env->msr_mask >> MSR_LE) & 1)) {
> + fprintf(stderr, "Selected CPU does not support little-endian.\n");
> + exit(1);
> + }
> #endif
> #endif
>
> #if defined(TARGET_PPC64)
> - if (mmu_is_64bit(env->mmu_model)) {
> - msr |= (1ULL << MSR_SF);
> - }
> + if (mmu_is_64bit(env->mmu_model)) {
> + msr |= (1ULL << MSR_SF);
> + }
> #endif
> -
> + }
> hreg_store_msr(env, msr, 1);
>
> #if !defined(CONFIG_USER_ONLY)
> @@ -7725,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/helper_regs.c b/target/ppc/helper_regs.c
> index 7e5726871e..9953d73884 100644
> --- a/target/ppc/helper_regs.c
> +++ b/target/ppc/helper_regs.c
> @@ -186,6 +186,10 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
> if (env->spr[SPR_LPCR] & LPCR_HR) {
> hflags |= 1 << HFLAGS_HR;
> }
> + if (unlikely(ppc_flags & POWERPC_FLAG_PPE42)) {
> + /* PPE42 has a single address space and no problem state */
> + msr = 0;
> + }
>
> #ifndef CONFIG_USER_ONLY
> if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) {
> @@ -306,9 +310,6 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv)
> value &= ~(1 << MSR_ME);
> value |= env->msr & (1 << MSR_ME);
> }
> - if ((value ^ env->msr) & (R_MSR_IR_MASK | R_MSR_DR_MASK)) {
> - cpu_interrupt_exittb(cs);
> - }
> if ((env->mmu_model == POWERPC_MMU_BOOKE ||
> env->mmu_model == POWERPC_MMU_BOOKE206) &&
> ((value ^ env->msr) & R_MSR_GS_MASK)) {
> @@ -319,8 +320,14 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv)
> /* Swap temporary saved registers with GPRs */
> hreg_swap_gpr_tgpr(env);
> }
> - if (unlikely((value ^ env->msr) & R_MSR_EP_MASK)) {
> - env->excp_prefix = FIELD_EX64(value, MSR, EP) * 0xFFF00000;
> + /* PPE42 MSR has bits overlapping with others */
> + if (!(env->flags & POWERPC_FLAG_PPE42)) {
> + if ((value ^ env->msr) & (R_MSR_IR_MASK | R_MSR_DR_MASK)) {
> + cpu_interrupt_exittb(cs);
> + }
> + if (unlikely((value ^ env->msr) & R_MSR_EP_MASK)) {
> + env->excp_prefix = FIELD_EX64(value, MSR, EP) * 0xFFF00000;
> + }
> }
> /*
> * If PR=1 then EE, IR and DR must be 1
> @@ -462,6 +469,17 @@ void register_generic_sprs(PowerPCCPU *cpu)
> SPR_NOACCESS, SPR_NOACCESS,
> &spr_read_generic, &spr_write_generic,
> 0x00000000);
> +
> + if (env->insns_flags2 & PPC2_PPE42) {
> + spr_register(env, SPR_PVR, "PVR",
> + SPR_NOACCESS, SPR_NOACCESS,
> + &spr_read_generic, SPR_NOACCESS,
> + pcc->pvr);
> +
> + /* PPE42 doesn't support additional SPRG regs or timebase */
> + return;
> + }
> +
> spr_register(env, SPR_SPRG1, "SPRG1",
> SPR_NOACCESS, SPR_NOACCESS,
> &spr_read_generic, &spr_write_generic,
> 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;
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 27f90c3cc5..fc817dab54 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -4264,8 +4264,10 @@ static void gen_mtmsr(DisasContext *ctx)
> /* L=1 form only updates EE and RI */
> mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE);
> } else {
> - /* mtmsr does not alter S, ME, or LE */
> - mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
> + if (likely(!(ctx->insns_flags2 & PPC2_PPE42))) {
> + /* mtmsr does not alter S, ME, or LE */
> + mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
> + }
>
> /*
> * XXX: we need to update nip before the store if we enter
next prev parent reply other threads:[~2025-09-01 7:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-26 20:17 [PATCH v2 0/4] Add IBM PPE42 CPU support Glenn Miles
2025-08-26 20:17 ` [PATCH v2 1/4] target/ppc: Add IBM PPE42 family of processors Glenn Miles
2025-09-01 7:29 ` Cédric Le Goater [this message]
2025-09-02 16:59 ` Miles Glenn
2025-08-26 20:17 ` [PATCH v2 2/4] target/ppc: Add IBM PPE42 special instructions Glenn Miles
2025-09-04 12:24 ` Chinmay Rath
2025-09-04 12:30 ` Chinmay Rath
2025-09-04 14:56 ` Miles Glenn
2025-08-26 20:17 ` [PATCH v2 3/4] hw/ppc: Add a test machine for the IBM PPE42 CPU Glenn Miles
2025-09-01 7:25 ` Cédric Le Goater
2025-09-01 10:15 ` BALATON Zoltan
2025-09-02 16:56 ` Miles Glenn
2025-09-03 22:50 ` Miles Glenn
2025-08-26 20:17 ` [PATCH v2 4/4] tests/functional: Add test for IBM PPE42 instructions Glenn Miles
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=a388fe15-f32f-45a6-accd-a85fe123a3e4@redhat.com \
--to=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=rathc@linux.ibm.com \
--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).