From 5d282a950c5be5a92b2d705f529f13fc55cd0c59 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 2 May 2020 20:08:10 +1000 Subject: [PATCH] Improve architectural compliance of mfspr and mtspr Mfspr from an unimplemented SPR should be a no-op in privileged state, so in this case we need to write back whatever was previously in the destination register. For problem state, both mtspr and mfspr to unimplemented SPRs should cause a program interrupt. There are special cases in the architecture for SPRs 0, 4 5 and 6 which we still don't implement. Signed-off-by: Paul Mackerras --- decode1.vhdl | 2 +- execute1.vhdl | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index 0e88ef3..a819b79 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -249,7 +249,7 @@ architecture behaviour of decode1 is -- 2#1001000000# mcrxrx 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfcr/mfocrf 2#0001010011# => (ALU, OP_MFMSR, NONE, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfmsr - 2#0101010011# => (ALU, OP_MFSPR, SPR, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfspr + 2#0101010011# => (ALU, OP_MFSPR, SPR, NONE, RS, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfspr 2#0100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- modud 2#0100001011# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0'), -- moduw 2#1100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- modsd diff --git a/execute1.vhdl b/execute1.vhdl index 6940049..c479a45 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -735,6 +735,7 @@ begin when OP_MFSPR => report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & "=" & to_hstring(a_in); + result_en := '1'; if is_fast_spr(e_in.read_reg1) then result := a_in; if decode_spr_num(e_in.insn) = SPR_XER then @@ -753,11 +754,15 @@ begin result := ctrl.tb; when SPR_DEC => result := ctrl.dec; - when others => - result := (others => '0'); + when others => + -- mfspr from unimplemented SPRs should be a nop in + -- supervisor mode and a program interrupt for user mode + result := c_in; + if ctrl.msr(MSR_PR) = '1' then + illegal := '1'; + end if; end case; end if; - result_en := '1'; when OP_MFCR => if e_in.insn(20) = '0' then -- mfcr @@ -823,6 +828,11 @@ begin when SPR_DEC => ctrl_tmp.dec <= c_in; when others => + -- mtspr to unimplemented SPRs should be a nop in + -- supervisor mode and a program interrupt for user mode + if ctrl.msr(MSR_PR) = '1' then + illegal := '1'; + end if; end case; end if; when OP_POPCNT =>