From f705fc5e197b746e2f3103f8ac4e2abc8f8b8696 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 30 Jan 2025 22:41:59 +1100 Subject: [PATCH] core: Implement reserved/no-op SPR numbers SPR numbers 808 - 811 do nothing when read or written, that is, mfspr doesn't modify the destination register. This is accomplished in the same way that privileged mfspr to an unimplemented SPR is made a no-op, by supplying the old contents of the destination register as an input and writing that same value back. Signed-off-by: Paul Mackerras --- common.vhdl | 5 +++++ decode1.vhdl | 3 +++ decode2.vhdl | 4 +++- execute1.vhdl | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/common.vhdl b/common.vhdl index 3cb552d..16ba2b3 100644 --- a/common.vhdl +++ b/common.vhdl @@ -75,6 +75,10 @@ package common is constant SPR_DEXCRU : spr_num_t := 812; constant SPR_HDEXCR : spr_num_t := 471; constant SPR_HDEXCU : spr_num_t := 455; + constant SPR_NOOP0 : spr_num_t := 808; + constant SPR_NOOP1 : spr_num_t := 809; + constant SPR_NOOP2 : spr_num_t := 810; + constant SPR_NOOP3 : spr_num_t := 811; -- PMU registers constant SPR_UPMC1 : spr_num_t := 771; @@ -171,6 +175,7 @@ package common is ispmu : std_ulogic; ronly : std_ulogic; wonly : std_ulogic; + noop : std_ulogic; end record; constant spr_id_init : spr_id := (sel => "0000", others => '0'); diff --git a/decode1.vhdl b/decode1.vhdl index c762b18..1e59725 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -457,6 +457,7 @@ architecture behaviour of decode1 is i.ispmu := '0'; i.ronly := '0'; i.wonly := '0'; + i.noop := '0'; case sprn is when SPR_TB => i.sel := SPRSEL_TB; @@ -504,6 +505,8 @@ architecture behaviour of decode1 is when SPR_DEXCRU | SPR_HDEXCU => i.sel := SPRSEL_DEXCR; i.ronly := '1'; + when SPR_NOOP0 | SPR_NOOP1 | SPR_NOOP2 | SPR_NOOP3 => + i.noop := '1'; when others => i.valid := '0'; end case; diff --git a/decode2.vhdl b/decode2.vhdl index 1bc8f2b..711f5d8 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -696,9 +696,11 @@ begin if op = OP_MFSPR then if d_in.ram_spr.valid = '1' then v.e.result_sel := "101"; -- ramspr_result - elsif d_in.spr_info.valid = '0' or d_in.spr_info.wonly = '1' then + elsif d_in.spr_info.valid = '0' or d_in.spr_info.wonly = '1' or + d_in.spr_info.noop = '1' then -- Privileged mfspr to invalid/unimplemented SPR numbers -- writes the contents of RT back to RT (i.e. it's a no-op) + -- as does any mfspr from the reserved/noop SPR numbers v.e.result_sel := "001"; -- logical_result end if; end if; diff --git a/execute1.vhdl b/execute1.vhdl index 26f8dae..121d004 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -1332,7 +1332,7 @@ begin when OP_DARN => when OP_MFMSR => when OP_MFSPR => - if e_in.spr_is_ram = '1' then + if e_in.spr_is_ram = '1' or e_in.spr_select.noop = '1' then if e_in.valid = '1' and not is_X(e_in.insn) then report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & "=" & to_hstring(alu_result);