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_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');


@ -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;

@ -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;

@ -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);

Loading…
Cancel
Save