core: Implement hashstp and hashchkp instructions and HASHPKEYR register

These provide facilities similar to hashstp, hashchk and HASHKEYR, but
restricted to privileged mode.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/437/head
Paul Mackerras 3 months ago
parent 00a3db8457
commit 3bcc31fdda

@ -70,6 +70,7 @@ package common is
constant SPR_DAWRX0 : spr_num_t := 188; constant SPR_DAWRX0 : spr_num_t := 188;
constant SPR_DAWRX1 : spr_num_t := 189; constant SPR_DAWRX1 : spr_num_t := 189;
constant SPR_HASHKEYR : spr_num_t := 468; constant SPR_HASHKEYR : spr_num_t := 468;
constant SPR_HASHPKEYR : spr_num_t := 469;


-- PMU registers -- PMU registers
constant SPR_UPMC1 : spr_num_t := 771; constant SPR_UPMC1 : spr_num_t := 771;

@ -200,7 +200,9 @@ architecture behaviour of decode1 is
INSN_ftdiv => (FPU, FPU, OP_FP_CMP, FRA, FRB, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_ftdiv => (FPU, FPU, OP_FP_CMP, FRA, FRB, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_ftsqrt => (FPU, FPU, OP_FP_CMP, NONE, FRB, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_ftsqrt => (FPU, FPU, OP_FP_CMP, NONE, FRB, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_hashchk => (LDST, NONE, OP_LOAD, RA, DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), INSN_hashchk => (LDST, NONE, OP_LOAD, RA, DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE),
INSN_hashchkp => (LDST, NONE, OP_LOAD, RA, DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '0', NONE),
INSN_hashst => (LDST, NONE, OP_STORE, RA, DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE), INSN_hashst => (LDST, NONE, OP_STORE, RA, DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '0', '0', NONE),
INSN_hashstp => (LDST, NONE, OP_STORE, RA, DSX, RBC, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '1', NONE, '0', '1', '0', NONE),
INSN_icbi => (ALU, NONE, OP_ICBI, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '1', NONE), INSN_icbi => (ALU, NONE, OP_ICBI, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '1', NONE),
INSN_icbt => (ALU, NONE, OP_ICBT, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_icbt => (ALU, NONE, OP_ICBT, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
INSN_isel => (ALU, NONE, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE), INSN_isel => (ALU, NONE, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', '0', NONE),
@ -701,7 +703,7 @@ begin
-- See if this is an instruction where we need to use the RS/RC -- See if this is an instruction where we need to use the RS/RC
-- read port to read the RB operand, because we want to get an -- read port to read the RB operand, because we want to get an
-- immediate operand to execute1 via read_data2. -- immediate operand to execute1 via read_data2.
if (icode = INSN_hashst or icode = INSN_hashchk) then if (icode = INSN_hashst or icode = INSN_hashchk or icode = INSN_hashstp or icode = INSN_hashchkp) then
vr.reg_3_addr := '0' & insn_rb(f_in.insn); vr.reg_3_addr := '0' & insn_rb(f_in.insn);
end if; end if;
vr.read_1_enable := f_in.valid; vr.read_1_enable := f_in.valid;

@ -500,7 +500,7 @@ begin
v.input_ov := '1'; v.input_ov := '1';
when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR | when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR |
SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 | SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 |
SPR_HASHKEYR => SPR_HASHKEYR | SPR_HASHPKEYR =>
unit := LDST; unit := LDST;
when SPR_TAR => when SPR_TAR =>
v.e.uses_tar := '1'; v.e.uses_tar := '1';
@ -524,7 +524,7 @@ begin
v.output_ov := '1'; v.output_ov := '1';
when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR | when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR |
SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 | SPR_DAWR0 | SPR_DAWR1 | SPR_DAWRX0 | SPR_DAWRX1 |
SPR_HASHKEYR => SPR_HASHKEYR | SPR_HASHPKEYR =>
unit := LDST; unit := LDST;
if d_in.valid = '1' then if d_in.valid = '1' then
v.sgl_pipe := '1'; v.sgl_pipe := '1';

@ -206,10 +206,12 @@ package decode_types is
INSN_divweu, INSN_divweu,
INSN_eqv, INSN_eqv,
INSN_hashchk, INSN_hashchk,
INSN_hashchkp,
INSN_hashst, INSN_hashst,
INSN_icbi, INSN_hashstp,
INSN_icbi, -- 160
INSN_icbt, INSN_icbt,
INSN_isel, -- 160 INSN_isel,
INSN_lbarx, INSN_lbarx,
INSN_lbzcix, INSN_lbzcix,
INSN_lbzux, INSN_lbzux,
@ -217,9 +219,9 @@ package decode_types is
INSN_ldarx, INSN_ldarx,
INSN_ldbrx, INSN_ldbrx,
INSN_ldcix, INSN_ldcix,
INSN_ldx, INSN_ldx, -- 170
INSN_ldux, INSN_ldux,
INSN_lharx, -- 170 INSN_lharx,
INSN_lhax, INSN_lhax,
INSN_lhaux, INSN_lhaux,
INSN_lhbrx, INSN_lhbrx,
@ -227,9 +229,9 @@ package decode_types is
INSN_lhzx, INSN_lhzx,
INSN_lhzux, INSN_lhzux,
INSN_lqarx, INSN_lqarx,
INSN_lwarx, INSN_lwarx, -- 180
INSN_lwax, INSN_lwax,
INSN_lwaux, -- 180 INSN_lwaux,
INSN_lwbrx, INSN_lwbrx,
INSN_lwzcix, INSN_lwzcix,
INSN_lwzx, INSN_lwzx,
@ -237,9 +239,9 @@ package decode_types is
INSN_modsd, INSN_modsd,
INSN_modsw, INSN_modsw,
INSN_moduw, INSN_moduw,
INSN_modud, INSN_modud, -- 190
INSN_mulhw, INSN_mulhw,
INSN_mulhwu, -- 190 INSN_mulhwu,
INSN_mulhd, INSN_mulhd,
INSN_mulhdu, INSN_mulhdu,
INSN_mullw, INSN_mullw,
@ -247,9 +249,9 @@ package decode_types is
INSN_nand, INSN_nand,
INSN_nor, INSN_nor,
INSN_or, INSN_or,
INSN_orc, INSN_orc, -- 200
INSN_pdepd, INSN_pdepd,
INSN_pextd, -- 200 INSN_pextd,
INSN_rldcl, INSN_rldcl,
INSN_rldcr, INSN_rldcr,
INSN_rlwnm, INSN_rlwnm,
@ -257,9 +259,9 @@ package decode_types is
INSN_sld, INSN_sld,
INSN_sraw, INSN_sraw,
INSN_srad, INSN_srad,
INSN_srw, INSN_srw, -- 210
INSN_srd, INSN_srd,
INSN_stbcix, -- 210 INSN_stbcix,
INSN_stbcx, INSN_stbcx,
INSN_stbx, INSN_stbx,
INSN_stbux, INSN_stbux,
@ -267,9 +269,9 @@ package decode_types is
INSN_stdcix, INSN_stdcix,
INSN_stdcx, INSN_stdcx,
INSN_stdx, INSN_stdx,
INSN_stdux, INSN_stdux, -- 220
INSN_sthbrx, INSN_sthbrx,
INSN_sthcix, -- 220 INSN_sthcix,
INSN_sthcx, INSN_sthcx,
INSN_sthx, INSN_sthx,
INSN_sthux, INSN_sthux,
@ -277,9 +279,9 @@ package decode_types is
INSN_stwbrx, INSN_stwbrx,
INSN_stwcix, INSN_stwcix,
INSN_stwcx, INSN_stwcx,
INSN_stwx, INSN_stwx, -- 230
INSN_stwux, INSN_stwux,
INSN_subf, -- 230 INSN_subf,
INSN_subfc, INSN_subfc,
INSN_subfe, INSN_subfe,
INSN_td, INSN_td,
@ -289,7 +291,6 @@ package decode_types is
INSN_xor, INSN_xor,


-- pad to 240 to simplify comparison logic -- pad to 240 to simplify comparison logic
INSN_238, INSN_239,


-- The following instructions have a third input addressed by RC -- The following instructions have a third input addressed by RC
INSN_maddld, INSN_maddld,
@ -640,7 +641,9 @@ package body decode_types is
when INSN_divd => return "011111"; when INSN_divd => return "011111";
when INSN_divw => return "011111"; when INSN_divw => return "011111";
when INSN_hashchk => return "011111"; when INSN_hashchk => return "011111";
when INSN_hashchkp => return "011111";
when INSN_hashst => return "011111"; when INSN_hashst => return "011111";
when INSN_hashstp => return "011111";
when INSN_eieio => return "011111"; when INSN_eieio => return "011111";
when INSN_eqv => return "011111"; when INSN_eqv => return "011111";
when INSN_extsb => return "011111"; when INSN_extsb => return "011111";

@ -172,6 +172,7 @@ architecture behave of loadstore1 is
dawr_uplim : dawr_array_t; dawr_uplim : dawr_array_t;
dawr_upd : std_ulogic; dawr_upd : std_ulogic;
hashkeyr : std_ulogic_vector(63 downto 0); hashkeyr : std_ulogic_vector(63 downto 0);
hashpkeyr : std_ulogic_vector(63 downto 0);
end record; end record;


signal req_in : request_t; signal req_in : request_t;
@ -387,6 +388,8 @@ begin
r3.dawr_uplim(i) <= (others => '0'); r3.dawr_uplim(i) <= (others => '0');
end loop; end loop;
r3.dawr_upd <= '0'; r3.dawr_upd <= '0';
r3.hashkeyr <= (others => '0');
r3.hashpkeyr <= (others => '0');
flushing <= '0'; flushing <= '0';
else else
r1 <= r1in; r1 <= r1in;
@ -531,7 +534,11 @@ begin
hv.z0 := 31x"7D12B0E6"; -- 0xFA2561CD >> 1 hv.z0 := 31x"7D12B0E6"; -- 0xFA2561CD >> 1
ra := l_in.addr1; ra := l_in.addr1;
rb := l_in.data; rb := l_in.data;
key := r3.hashkeyr; if l_in.insn(7) = '1' then
key := r3.hashkeyr; -- hashst/hashchk
else
key := r3.hashpkeyr; -- hashstp/hashchkp
end if;
for lane in 0 to 3 loop for lane in 0 to 3 loop
j := lane * 16; j := lane * 16;
k := (3 - lane) * 16; k := (3 - lane) * 16;
@ -898,6 +905,8 @@ begin
sprval := 48x"0" & r3.dawrx(1); sprval := 48x"0" & r3.dawrx(1);
when "000" => when "000" =>
sprval := r3.hashkeyr; sprval := r3.hashkeyr;
when "001" =>
sprval := r3.hashpkeyr;
when "010" => when "010" =>
sprval := x"00000000" & r3.dsisr; sprval := x"00000000" & r3.dsisr;
when "011" => when "011" =>
@ -1142,6 +1151,8 @@ begin
v.dar := r2.req.store_data; v.dar := r2.req.store_data;
when "0000" => when "0000" =>
v.hashkeyr := r2.req.store_data; v.hashkeyr := r2.req.store_data;
when "0001" =>
v.hashpkeyr := r2.req.store_data;
when others => when others =>
end case; end case;
end if; end if;

@ -364,15 +364,15 @@ architecture behaviour of predecoder is
2#0_01110_11100# => INSN_nand, 2#0_01110_11100# => INSN_nand,
2#0_00011_01000# => INSN_neg, 2#0_00011_01000# => INSN_neg,
2#0_10011_01000# => INSN_neg, -- nego 2#0_10011_01000# => INSN_neg, -- nego
-- next 6 are reserved no-op instructions -- next 4 are reserved no-op instructions
2#0_10000_10010# => INSN_rnop, 2#0_10000_10010# => INSN_rnop,
2#0_10001_10010# => INSN_rnop, 2#0_10001_10010# => INSN_rnop,
2#0_10010_10010# => INSN_rnop, 2#0_10010_10010# => INSN_rnop,
2#0_10011_10010# => INSN_rnop, 2#0_10011_10010# => INSN_rnop,
2#0_10100_10010# => INSN_rnop,
2#0_10101_10010# => INSN_rnop,
2#0_10110_10010# => INSN_hashst, 2#0_10110_10010# => INSN_hashst,
2#0_10111_10010# => INSN_hashchk, 2#0_10111_10010# => INSN_hashchk,
2#0_10100_10010# => INSN_hashstp,
2#0_10101_10010# => INSN_hashchkp,
2#0_00011_11100# => INSN_nor, 2#0_00011_11100# => INSN_nor,
2#0_01101_11100# => INSN_or, 2#0_01101_11100# => INSN_or,
2#0_01100_11100# => INSN_orc, 2#0_01100_11100# => INSN_orc,

Loading…
Cancel
Save