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 <paulus@ozlabs.org>
pull/434/head
Paul Mackerras 1 year ago
parent d112a7ad94
commit d7d7a3afd4

@ -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',

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

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

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

Loading…
Cancel
Save