core: Implement various SPRs which read zero and ignore writes

This implements [U]SIER2, [U]SIER3, [U]MMCR3, HMER and HMEER as
SPRs which return zero when read, and ignore writes.  The zero value
is provided via the slow SPR read multiplexer.  To avoid increasing
the size of the selector from 4 bits to 5, the (implementation
specific) LOG_ADDR and LOG_DATA SPRs now share a single selector
value.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/443/head
Paul Mackerras 2 weeks ago
parent 1b6ee631bc
commit 8f7326a824

@ -82,6 +82,8 @@ package common is
constant SPR_NOOP1 : spr_num_t := 809; constant SPR_NOOP1 : spr_num_t := 809;
constant SPR_NOOP2 : spr_num_t := 810; constant SPR_NOOP2 : spr_num_t := 810;
constant SPR_NOOP3 : spr_num_t := 811; constant SPR_NOOP3 : spr_num_t := 811;
constant SPR_HMER : spr_num_t := 336;
constant SPR_HMEER : spr_num_t := 337;


-- PMU registers -- PMU registers
constant SPR_UPMC1 : spr_num_t := 771; constant SPR_UPMC1 : spr_num_t := 771;
@ -97,6 +99,9 @@ package common is
constant SPR_USIER : spr_num_t := 768; constant SPR_USIER : spr_num_t := 768;
constant SPR_USIAR : spr_num_t := 780; constant SPR_USIAR : spr_num_t := 780;
constant SPR_USDAR : spr_num_t := 781; constant SPR_USDAR : spr_num_t := 781;
constant SPR_USIER2 : spr_num_t := 736;
constant SPR_USIER3 : spr_num_t := 737;
constant SPR_UMMCR3 : spr_num_t := 738;
constant SPR_PMC1 : spr_num_t := 787; constant SPR_PMC1 : spr_num_t := 787;
constant SPR_PMC2 : spr_num_t := 788; constant SPR_PMC2 : spr_num_t := 788;
constant SPR_PMC3 : spr_num_t := 789; constant SPR_PMC3 : spr_num_t := 789;
@ -110,6 +115,9 @@ package common is
constant SPR_SIER : spr_num_t := 784; constant SPR_SIER : spr_num_t := 784;
constant SPR_SIAR : spr_num_t := 796; constant SPR_SIAR : spr_num_t := 796;
constant SPR_SDAR : spr_num_t := 797; constant SPR_SDAR : spr_num_t := 797;
constant SPR_SIER2 : spr_num_t := 752;
constant SPR_SIER3 : spr_num_t := 753;
constant SPR_MMCR3 : spr_num_t := 754;


-- GPR indices in the register file (GPR only) -- GPR indices in the register file (GPR only)
subtype gpr_index_t is std_ulogic_vector(4 downto 0); subtype gpr_index_t is std_ulogic_vector(4 downto 0);
@ -182,12 +190,12 @@ package common is
end record; end record;
constant spr_id_init : spr_id := (sel => "0000", others => '0'); constant spr_id_init : spr_id := (sel => "0000", others => '0');


constant SPRSEL_TB : spr_selector := 4x"0"; constant SPRSEL_ZERO : spr_selector := 4x"0";
constant SPRSEL_TBU : spr_selector := 4x"1"; constant SPRSEL_TB : spr_selector := 4x"1";
constant SPRSEL_DEC : spr_selector := 4x"2"; constant SPRSEL_TBU : spr_selector := 4x"2";
constant SPRSEL_PVR : spr_selector := 4x"3"; constant SPRSEL_DEC : spr_selector := 4x"3";
constant SPRSEL_LOGA : spr_selector := 4x"4"; constant SPRSEL_PVR : spr_selector := 4x"4";
constant SPRSEL_LOGD : spr_selector := 4x"5"; constant SPRSEL_LOGR : spr_selector := 4x"5";
constant SPRSEL_CFAR : spr_selector := 4x"6"; constant SPRSEL_CFAR : spr_selector := 4x"6";
constant SPRSEL_FSCR : spr_selector := 4x"7"; constant SPRSEL_FSCR : spr_selector := 4x"7";
constant SPRSEL_LPCR : spr_selector := 4x"8"; constant SPRSEL_LPCR : spr_selector := 4x"8";

@ -476,14 +476,17 @@ architecture behaviour of decode1 is
when SPR_PVR => when SPR_PVR =>
i.sel := SPRSEL_PVR; i.sel := SPRSEL_PVR;
when 724 => -- LOG_ADDR SPR when 724 => -- LOG_ADDR SPR
i.sel := SPRSEL_LOGA; i.sel := SPRSEL_LOGR;
when 725 => -- LOG_DATA SPR when 725 => -- LOG_DATA SPR
i.sel := SPRSEL_LOGD; i.sel := SPRSEL_LOGR;
i.ronly := '1';
when SPR_UPMC1 | SPR_UPMC2 | SPR_UPMC3 | SPR_UPMC4 | SPR_UPMC5 | SPR_UPMC6 | when SPR_UPMC1 | SPR_UPMC2 | SPR_UPMC3 | SPR_UPMC4 | SPR_UPMC5 | SPR_UPMC6 |
SPR_UMMCR0 | SPR_UMMCR1 | SPR_UMMCR2 | SPR_UMMCRA | SPR_USIER | SPR_USIAR | SPR_USDAR | SPR_UMMCR0 | SPR_UMMCR1 | SPR_UMMCR2 | SPR_UMMCRA | SPR_USIER | SPR_USIAR | SPR_USDAR |
SPR_PMC1 | SPR_PMC2 | SPR_PMC3 | SPR_PMC4 | SPR_PMC5 | SPR_PMC6 | SPR_PMC1 | SPR_PMC2 | SPR_PMC3 | SPR_PMC4 | SPR_PMC5 | SPR_PMC6 |
SPR_MMCR0 | SPR_MMCR1 | SPR_MMCR2 | SPR_MMCRA | SPR_SIER | SPR_SIAR | SPR_SDAR => SPR_MMCR0 | SPR_MMCR1 | SPR_MMCR2 | SPR_MMCRA | SPR_SIER | SPR_SIAR | SPR_SDAR =>
i.ispmu := '1'; i.ispmu := '1';
when SPR_USIER2 | SPR_USIER3 | SPR_UMMCR3 | SPR_SIER2 | SPR_SIER3 | SPR_MMCR3 =>
i.sel := SPRSEL_ZERO;
when SPR_CFAR => when SPR_CFAR =>
i.sel := SPRSEL_CFAR; i.sel := SPRSEL_CFAR;
when SPR_XER => when SPR_XER =>
@ -515,6 +518,8 @@ architecture behaviour of decode1 is
i.ronly := '1'; i.ronly := '1';
when SPR_NOOP0 | SPR_NOOP1 | SPR_NOOP2 | SPR_NOOP3 => when SPR_NOOP0 | SPR_NOOP1 | SPR_NOOP2 | SPR_NOOP3 =>
i.noop := '1'; i.noop := '1';
when SPR_HMER | SPR_HMEER =>
i.sel := SPRSEL_ZERO;
when others => when others =>
i.valid := '0'; i.valid := '0';
end case; end case;

@ -224,6 +224,7 @@ architecture behaviour of execute1 is
signal spr_result: std_ulogic_vector(63 downto 0); signal spr_result: std_ulogic_vector(63 downto 0);
signal next_nia : std_ulogic_vector(63 downto 0); signal next_nia : std_ulogic_vector(63 downto 0);
signal s1_sel : std_ulogic_vector(2 downto 0); signal s1_sel : std_ulogic_vector(2 downto 0);
signal log_spr_data : std_ulogic_vector(63 downto 0);


signal carry_32 : std_ulogic; signal carry_32 : std_ulogic;
signal carry_64 : std_ulogic; signal carry_64 : std_ulogic;
@ -1401,8 +1402,10 @@ begin
slow_op := '1'; slow_op := '1';
if e_in.spr_select.ispmu = '0' then if e_in.spr_select.ispmu = '0' then
case e_in.spr_select.sel is case e_in.spr_select.sel is
when SPRSEL_LOGD => when SPRSEL_LOGR =>
v.se.inc_loga := '1'; if e_in.insn(16) = '0' then
v.se.inc_loga := '1';
end if;
when others => when others =>
end case; end case;
v.res2_sel := "10"; v.res2_sel := "10";
@ -1465,7 +1468,7 @@ begin
v.se.write_xerlow := '1'; v.se.write_xerlow := '1';
when SPRSEL_DEC => when SPRSEL_DEC =>
v.se.write_dec := '1'; v.se.write_dec := '1';
when SPRSEL_LOGA => when SPRSEL_LOGR =>
v.se.write_loga := '1'; v.se.write_loga := '1';
when SPRSEL_CFAR => when SPRSEL_CFAR =>
v.se.write_cfar := '1'; v.se.write_cfar := '1';
@ -1955,13 +1958,14 @@ begin
end process; end process;


-- Slow SPR read mux -- Slow SPR read mux
log_spr_data <= (log_wr_addr & ex2.log_addr_spr) when ex1.insn(16) = '0'
else log_rd_data;
with ex1.spr_select.sel select spr_result <= with ex1.spr_select.sel select spr_result <=
timebase when SPRSEL_TB, timebase when SPRSEL_TB,
32x"0" & timebase(63 downto 32) when SPRSEL_TBU, 32x"0" & timebase(63 downto 32) when SPRSEL_TBU,
assemble_dec(ctrl) when SPRSEL_DEC, assemble_dec(ctrl) when SPRSEL_DEC,
32x"0" & PVR_MICROWATT when SPRSEL_PVR, 32x"0" & PVR_MICROWATT when SPRSEL_PVR,
log_wr_addr & ex2.log_addr_spr when SPRSEL_LOGA, log_spr_data when SPRSEL_LOGR,
log_rd_data when SPRSEL_LOGD,
ctrl.cfar when SPRSEL_CFAR, ctrl.cfar when SPRSEL_CFAR,
assemble_fscr(ctrl) when SPRSEL_FSCR, assemble_fscr(ctrl) when SPRSEL_FSCR,
assemble_lpcr(ctrl) when SPRSEL_LPCR, assemble_lpcr(ctrl) when SPRSEL_LPCR,
@ -1971,7 +1975,8 @@ begin
56x"0" & std_ulogic_vector(to_unsigned(CPU_INDEX, 8)) when SPRSEL_PIR, 56x"0" & std_ulogic_vector(to_unsigned(CPU_INDEX, 8)) when SPRSEL_PIR,
ctrl.ciabr when SPRSEL_CIABR, ctrl.ciabr when SPRSEL_CIABR,
assemble_dexcr(ctrl, ex1.insn) when SPRSEL_DEXCR, assemble_dexcr(ctrl, ex1.insn) when SPRSEL_DEXCR,
assemble_xer(ex1.e.xerc, ctrl.xer_low) when others; assemble_xer(ex1.e.xerc, ctrl.xer_low) when SPRSEL_XER,
64x"0" when others;


stage2_stall <= l_in.l2stall or fp_in.f2stall; stage2_stall <= l_in.l2stall or fp_in.f2stall;



Loading…
Cancel
Save