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 <paulus@ozlabs.org>
pull/440/head
Paul Mackerras 4 weeks ago
parent c49c32b5fe
commit f705fc5e19

@ -75,6 +75,10 @@ package common is
constant SPR_DEXCRU : spr_num_t := 812; constant SPR_DEXCRU : spr_num_t := 812;
constant SPR_HDEXCR : spr_num_t := 471; constant SPR_HDEXCR : spr_num_t := 471;
constant SPR_HDEXCU : spr_num_t := 455; 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 -- PMU registers
constant SPR_UPMC1 : spr_num_t := 771; constant SPR_UPMC1 : spr_num_t := 771;
@ -171,6 +175,7 @@ package common is
ispmu : std_ulogic; ispmu : std_ulogic;
ronly : std_ulogic; ronly : std_ulogic;
wonly : std_ulogic; wonly : std_ulogic;
noop : std_ulogic;
end record; end record;
constant spr_id_init : spr_id := (sel => "0000", others => '0'); constant spr_id_init : spr_id := (sel => "0000", others => '0');



@ -457,6 +457,7 @@ architecture behaviour of decode1 is
i.ispmu := '0'; i.ispmu := '0';
i.ronly := '0'; i.ronly := '0';
i.wonly := '0'; i.wonly := '0';
i.noop := '0';
case sprn is case sprn is
when SPR_TB => when SPR_TB =>
i.sel := SPRSEL_TB; i.sel := SPRSEL_TB;
@ -504,6 +505,8 @@ architecture behaviour of decode1 is
when SPR_DEXCRU | SPR_HDEXCU => when SPR_DEXCRU | SPR_HDEXCU =>
i.sel := SPRSEL_DEXCR; i.sel := SPRSEL_DEXCR;
i.ronly := '1'; i.ronly := '1';
when SPR_NOOP0 | SPR_NOOP1 | SPR_NOOP2 | SPR_NOOP3 =>
i.noop := '1';
when others => when others =>
i.valid := '0'; i.valid := '0';
end case; end case;

@ -696,9 +696,11 @@ begin
if op = OP_MFSPR then if op = OP_MFSPR then
if d_in.ram_spr.valid = '1' then if d_in.ram_spr.valid = '1' then
v.e.result_sel := "101"; -- ramspr_result 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 -- Privileged mfspr to invalid/unimplemented SPR numbers
-- writes the contents of RT back to RT (i.e. it's a no-op) -- 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 v.e.result_sel := "001"; -- logical_result
end if; end if;
end if; end if;

@ -1332,7 +1332,7 @@ begin
when OP_DARN => when OP_DARN =>
when OP_MFMSR => when OP_MFMSR =>
when OP_MFSPR => 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 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)) & report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
"=" & to_hstring(alu_result); "=" & to_hstring(alu_result);

Loading…
Cancel
Save