From d7d7a3afd4789875ce253369d1fe631f8b1c6192 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 22 Sep 2023 12:30:13 +1000 Subject: [PATCH] Implement VRSAVE SPR VRSAVE is a 32-bit software-use SPR accessible in user mode. It is stored in the SPR RAM. The value read from the RAM is trimmed to 32 bits at the ramspr_read process. Signed-off-by: Paul Mackerras --- common.vhdl | 5 +++++ decode1.vhdl | 6 +++++- decode2.vhdl | 1 + execute1.vhdl | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/common.vhdl b/common.vhdl index 790d98c..4f7fced 100644 --- a/common.vhdl +++ b/common.vhdl @@ -62,6 +62,7 @@ package common is constant SPR_CTRLW : spr_num_t := 152; constant SPR_UDSCR : spr_num_t := 3; constant SPR_DSCR : spr_num_t := 17; + constant SPR_VRSAVE : spr_num_t := 256; -- PMU registers constant SPR_UPMC1 : spr_num_t := 771; @@ -139,10 +140,12 @@ package common is constant RAMSPR_SPRG3 : ramspr_index := to_unsigned(3,3); constant RAMSPR_HSPRG1 : ramspr_index := to_unsigned(4,3); constant RAMSPR_CTR : ramspr_index := to_unsigned(5,3); -- must equal RAMSPR_LR + constant RAMSPR_VRSAVE : ramspr_index := to_unsigned(6,3); type ram_spr_info is record index : ramspr_index; isodd : std_ulogic; + is32b : std_ulogic; valid : std_ulogic; end record; constant ram_spr_info_init: ram_spr_info := (index => to_unsigned(0,3), others => '0'); @@ -416,6 +419,7 @@ package common is ramspr_wraddr : ramspr_index; ramspr_write_even : std_ulogic; ramspr_write_odd : std_ulogic; + ramspr_32bit : std_ulogic; dbg_spr_access : std_ulogic; dec_ctr : std_ulogic; prefixed : std_ulogic; @@ -441,6 +445,7 @@ package common is spr_is_ram => '0', ramspr_even_rdaddr => (others => '0'), ramspr_odd_rdaddr => (others => '0'), ramspr_rd_odd => '0', ramspr_wraddr => (others => '0'), ramspr_write_even => '0', ramspr_write_odd => '0', + ramspr_32bit => '0', dbg_spr_access => '0', dec_ctr => '0', prefixed => '0', prefix => (others => '0'), illegal_suffix => '0', diff --git a/decode1.vhdl b/decode1.vhdl index ccfdf9f..75bb9c3 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -385,7 +385,7 @@ architecture behaviour of decode1 is function decode_ram_spr(sprn : spr_num_t) return ram_spr_info is variable ret : ram_spr_info; begin - ret := (index => (others => '0'), isodd => '0', valid => '1'); + ret := (index => (others => '0'), isodd => '0', is32b => '0', valid => '1'); case sprn is when SPR_LR => ret.index := RAMSPR_LR; @@ -419,6 +419,10 @@ architecture behaviour of decode1 is when SPR_HSPRG1 => ret.index := RAMSPR_HSPRG1; ret.isodd := '1'; + when SPR_VRSAVE => + ret.index := RAMSPR_VRSAVE; + ret.isodd := '1'; + ret.is32b := '1'; when others => ret.valid := '0'; end case; diff --git a/decode2.vhdl b/decode2.vhdl index d094681..94fb6a7 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -545,6 +545,7 @@ begin v.e.ramspr_even_rdaddr := d_in.ram_spr.index; v.e.ramspr_odd_rdaddr := d_in.ram_spr.index; v.e.ramspr_rd_odd := d_in.ram_spr.isodd; + v.e.ramspr_32bit := d_in.ram_spr.is32b; v.e.spr_is_ram := d_in.ram_spr.valid; sprs_busy := d_in.ram_spr.valid; when OP_MTSPR => diff --git a/execute1.vhdl b/execute1.vhdl index dad8d72..9b55195 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -635,6 +635,9 @@ begin else ramspr_result <= ramspr_odd; end if; + if e_in.ramspr_32bit = '1' then + ramspr_result(63 downto 32) <= 32x"0"; + end if; end process; ramspr_write: process(clk)