The BookE PIR registration reuses the classic PowerPC 604 write
callback, which writes SPR 1023 and masks the value to four bits.
BookE PIR is SPR 286; on e500, SPR 1023 is SVR, so a PIR write can
corrupt SVR while leaving PIR unchanged.

The e500v1/e500v2 manual defines PIR as read-only. The e500mc, e5500
and e6500 manuals allow hypervisor software to write PIR after reset.
Reject writes on e500v1/e500v2 and use the generic 32-bit SPR write
callback on the other three cores to update the correct register
without the four-bit restriction.

Reference:
- E500CORERM (Rev.1), section 2.5.2
  https://www.nxp.com/docs/en/reference-manual/E500CORERM.pdf
- E500MCRM (Rev.3), section 2.9.7
  https://www.nxp.com/docs/en/reference-manual/E500MCRM.pdf
- E5500RM (Rev.4), section 2.9.7
  https://www.nxp.com/webapp/Download?colCode=E5500RM
- E6500RM (Rev.0), section 2.9.8
  https://www.nxp.com/docs/en/reference-manual/E6500RM.pdf

Fixes: 76a66253e5e4 ("Great PowerPC emulation code resynchronisation and 
improvments")
Cc: [email protected]
Signed-off-by: Bin Meng <[email protected]>
---

 target/ppc/cpu_init.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index b711f9c0a8..96bae6a6d1 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -2837,7 +2837,9 @@ static void init_proc_e500(CPUPPCState *env, int version)
     /* Processor identification */
     spr_register(env, SPR_BOOKE_PIR, "PIR",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_pir,
+                 &spr_read_generic,
+                 (version == fsl_e500v1 || version == fsl_e500v2) ?
+                     SPR_NOACCESS : &spr_write_generic32,
                  0x00000000);
 
     spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
-- 
2.53.0


Reply via email to