From a88fa9c4599e0583b56b08579f61ec63a8db6ca9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 20 Sep 2023 20:38:22 +1000 Subject: [PATCH] Implement DSCR The DSCR (Data Stream Control Register) is a user-accessible SPR that controls aspects of data prefetching. It has 25 bits of state defined in the ISA. This implements the register as a 25 read/write bits that do nothing, since we don't have any prefetching. The DSCR is accessible at two SPR numbers, 3 (unprivileged) and 17 (privileged). Access via these SPR numbers is controlled by an FSCR bit and an HFSCR bit. The FSCR bit controls access via SPR 3 in user mode. The HFSCR bit controls access via SPR 3 in user mode and either SPR number in privileged non-hypervisor mode, but since we don't implement privileged non-hypervisor mode, it does essentially the same thing as the FSCR bit. Signed-off-by: Paul Mackerras --- common.vhdl | 16 ++++++++++++---- decode1.vhdl | 4 ++++ decode2.vhdl | 4 ++++ execute1.vhdl | 25 +++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/common.vhdl b/common.vhdl index 58033d1..033b004 100644 --- a/common.vhdl +++ b/common.vhdl @@ -60,6 +60,8 @@ package common is constant SPR_HEIR : spr_num_t := 339; constant SPR_CTRL : spr_num_t := 136; constant SPR_CTRLW : spr_num_t := 152; + constant SPR_UDSCR : spr_num_t := 3; + constant SPR_DSCR : spr_num_t := 17; -- PMU registers constant SPR_UPMC1 : spr_num_t := 771; @@ -166,13 +168,14 @@ package common is constant SPRSEL_HFSCR : spr_selector := 4x"8"; constant SPRSEL_HEIR : spr_selector := 4x"9"; constant SPRSEL_CTRL : spr_selector := 4x"a"; + constant SPRSEL_DSCR : spr_selector := 4x"b"; constant SPRSEL_XER : spr_selector := 4x"f"; -- FSCR and HFSCR bit numbers constant FSCR_PREFIX : integer := 63 - 50; constant FSCR_SCV : integer := 63 - 51; constant FSCR_TAR : integer := 63 - 55; - constant FSCR_DSCR3 : integer := 63 - 61; + constant FSCR_DSCR : integer := 63 - 61; constant HFSCR_PREFIX : integer := 63 - 50; constant HFSCR_MSG : integer := 63 - 53; constant HFSCR_TAR : integer := 63 - 55; @@ -258,16 +261,20 @@ package common is fscr_ic: std_ulogic_vector(3 downto 0); fscr_pref: std_ulogic; fscr_tar: std_ulogic; + fscr_dscr: std_ulogic; hfscr_ic: std_ulogic_vector(3 downto 0); hfscr_pref: std_ulogic; hfscr_tar: std_ulogic; + hfscr_dscr: std_ulogic; hfscr_fp: std_ulogic; heir: std_ulogic_vector(63 downto 0); + dscr: std_ulogic_vector(24 downto 0); end record; constant ctrl_t_init : ctrl_t := (wait_state => '0', run => '1', xer_low => 18x"0", - fscr_ic => x"0", fscr_pref => '1', fscr_tar => '1', - hfscr_ic => x"0", hfscr_pref => '1', hfscr_tar => '1', hfscr_fp => '1', + fscr_ic => x"0", fscr_pref => '1', fscr_tar => '1', fscr_dscr => '1', + hfscr_ic => x"0", hfscr_pref => '1', hfscr_tar => '1', hfscr_dscr => '1', hfscr_fp => '1', + dscr => (others => '0'), others => (others => '0')); type Fetch1ToIcacheType is record @@ -415,6 +422,7 @@ package common is illegal_suffix : std_ulogic; misaligned_prefix : std_ulogic; uses_tar : std_ulogic; + uses_dscr : std_ulogic; end record; constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', unit => ALU, fac => NONE, insn_type => OP_ILLEGAL, instr_tag => instr_tag_init, @@ -435,7 +443,7 @@ package common is dbg_spr_access => '0', dec_ctr => '0', prefixed => '0', prefix => (others => '0'), illegal_suffix => '0', - misaligned_prefix => '0', uses_tar => '0', + misaligned_prefix => '0', uses_tar => '0', uses_dscr => '0', others => (others => '0')); type MultiplyInputType is record diff --git a/decode1.vhdl b/decode1.vhdl index 252a21f..7fca54b 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -466,6 +466,10 @@ architecture behaviour of decode1 is when SPR_CTRLW => i.sel := SPRSEL_CTRL; i.wonly := '1'; + when SPR_UDSCR => + i.sel := SPRSEL_DSCR; + when SPR_DSCR => + i.sel := SPRSEL_DSCR; when others => i.valid := '0'; end case; diff --git a/decode2.vhdl b/decode2.vhdl index 1c3f324..b27f563 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -454,6 +454,8 @@ begin unit := LDST; when SPR_TAR => v.e.uses_tar := '1'; + when SPR_UDSCR => + v.e.uses_dscr := '1'; when others => end case; if d_in.spr_info.wonly = '1' then @@ -477,6 +479,8 @@ begin end if; when SPR_TAR => v.e.uses_tar := '1'; + when SPR_UDSCR => + v.e.uses_dscr := '1'; when others => end case; if d_in.spr_info.ronly = '1' then diff --git a/execute1.vhdl b/execute1.vhdl index b1087ba..7d714fb 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -94,6 +94,7 @@ architecture behaviour of execute1 is write_heir : std_ulogic; set_heir : std_ulogic; write_ctrl : std_ulogic; + write_dscr : std_ulogic; enter_wait : std_ulogic; end record; constant side_effect_init : side_effect_type := (others => '0'); @@ -393,6 +394,7 @@ architecture behaviour of execute1 is ret(59 downto 56) := c.fscr_ic; ret(FSCR_PREFIX) := c.fscr_pref; ret(FSCR_TAR) := c.fscr_tar; + ret(FSCR_DSCR) := c.fscr_dscr; return ret; end; @@ -403,6 +405,7 @@ architecture behaviour of execute1 is ret(59 downto 56) := c.hfscr_ic; ret(HFSCR_PREFIX) := c.hfscr_pref; ret(HFSCR_TAR) := c.hfscr_tar; + ret(HFSCR_DSCR) := c.hfscr_dscr; ret(HFSCR_FP) := c.hfscr_fp; return ret; end; @@ -1348,6 +1351,8 @@ begin v.se.write_heir := '1'; when SPRSEL_CTRL => v.se.write_ctrl := '1'; + when SPRSEL_DSCR => + v.se.write_dscr := '1'; when others => end case; end if; @@ -1480,6 +1485,20 @@ begin v.se.write_ic := '1'; end if; + elsif ex1.msr(MSR_PR) = '1' and e_in.uses_dscr = '1' and + (ctrl.hfscr_dscr = '0' or ctrl.fscr_dscr = '0') then + -- [Hypervisor] facility unavailable for DSCR access + v.exception := '1'; + v.ic := x"2"; + if ctrl.hfscr_dscr = '0' then + v.e.hv_intr := '1'; + v.e.intr_vec := 16#f80#; + v.se.write_hic := '1'; + else + v.e.intr_vec := 16#f60#; + v.se.write_ic := '1'; + end if; + elsif HAS_FPU and ex1.msr(MSR_PR) = '1' and e_in.fac = FPU and ctrl.hfscr_fp = '0' then -- Hypervisor facility unavailable for FP instructions @@ -1793,6 +1812,7 @@ begin assemble_hfscr(ctrl) when SPRSEL_HFSCR, ctrl.heir when SPRSEL_HEIR, assemble_ctrl(ctrl, ex1.msr(MSR_PR)) when SPRSEL_CTRL, + 39x"0" & ctrl.dscr when SPRSEL_DSCR, assemble_xer(ex1.e.xerc, ctrl.xer_low) when others; stage2_stall <= l_in.l2stall or fp_in.f2stall; @@ -1942,6 +1962,7 @@ begin ctrl_tmp.hfscr_ic <= ex1.e.write_data(59 downto 56); ctrl_tmp.hfscr_pref <= ex1.e.write_data(HFSCR_PREFIX); ctrl_tmp.hfscr_tar <= ex1.e.write_data(HFSCR_TAR); + ctrl_tmp.hfscr_dscr <= ex1.e.write_data(HFSCR_DSCR); ctrl_tmp.hfscr_fp <= ex1.e.write_data(HFSCR_FP); elsif ex1.se.write_hic = '1' then ctrl_tmp.hfscr_ic <= ex1.ic; @@ -1950,6 +1971,7 @@ begin ctrl_tmp.fscr_ic <= ex1.e.write_data(59 downto 56); ctrl_tmp.fscr_pref <= ex1.e.write_data(FSCR_PREFIX); ctrl_tmp.fscr_tar <= ex1.e.write_data(FSCR_TAR); + ctrl_tmp.fscr_dscr <= ex1.e.write_data(FSCR_DSCR); elsif ex1.se.write_ic = '1' then ctrl_tmp.fscr_ic <= ex1.ic; end if; @@ -1967,6 +1989,9 @@ begin if ex1.se.write_ctrl = '1' then ctrl_tmp.run <= ex1.e.write_data(0); end if; + if ex1.se.write_dscr = '1' then + ctrl_tmp.dscr <= ex1.e.write_data(24 downto 0); + end if; if ex1.se.enter_wait = '1' then ctrl_tmp.wait_state <= '1'; end if;