Decrementer IRQ, rfid, mtmsr implementation

The interrupt controller is done in execute1. execute 1 then takes two
cycles to write fast SPRS SRR0 and SRR1.

MSR is stored in execute1 for now so it can be checked and tested for EE
atomically. This may need to move in the future.

DEC lives in execute1 also.

Signed-off-by: Michael Neuling <mikey@neuling.org>
pull/154/head
Michael Neuling 5 years ago
parent cc20989bda
commit 91f2692c8c

@ -16,6 +16,7 @@ package common is
constant SPR_LR : spr_num_t := 8; constant SPR_LR : spr_num_t := 8;
constant SPR_CTR : spr_num_t := 9; constant SPR_CTR : spr_num_t := 9;
constant SPR_TB : spr_num_t := 268; constant SPR_TB : spr_num_t := 268;
constant SPR_DEC : spr_num_t := 22;
constant SPR_SRR0 : spr_num_t := 26; constant SPR_SRR0 : spr_num_t := 26;
constant SPR_SRR1 : spr_num_t := 27; constant SPR_SRR1 : spr_num_t := 27;
constant SPR_HSRR0 : spr_num_t := 314; constant SPR_HSRR0 : spr_num_t := 314;
@ -65,6 +66,8 @@ package common is
-- This needs to die... -- This needs to die...
type ctrl_t is record type ctrl_t is record
tb: std_ulogic_vector(63 downto 0); tb: std_ulogic_vector(63 downto 0);
dec: std_ulogic_vector(63 downto 0);
msr: std_ulogic_vector(63 downto 0);
end record; end record;


type Fetch1ToIcacheType is record type Fetch1ToIcacheType is record

@ -94,6 +94,7 @@ architecture behaviour of decode1 is
2#0011000001# => '1', -- crxor 2#0011000001# => '1', -- crxor
2#0010010110# => '1', -- isync 2#0010010110# => '1', -- isync
2#0000000000# => '1', -- mcrf 2#0000000000# => '1', -- mcrf
2#0000010010# => '1', -- rfid
others => '0' others => '0'
); );


@ -109,6 +110,8 @@ architecture behaviour of decode1 is
2#100# => (ALU, OP_BCREG, SPR, SPR, NONE, SPR, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), 2#100# => (ALU, OP_BCREG, SPR, SPR, NONE, SPR, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'),
-- isync -- isync
2#111# => (ALU, OP_ISYNC, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), 2#111# => (ALU, OP_ISYNC, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
-- rfid
2#101# => (ALU, OP_RFID, SPR, SPR, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'),
others => illegal_inst others => illegal_inst
); );


@ -237,12 +240,14 @@ architecture behaviour of decode1 is
-- 2#1000000000# mcrxr -- 2#1000000000# mcrxr
-- 2#1001000000# mcrxrx -- 2#1001000000# mcrxrx
2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfcr/mfocrf 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfcr/mfocrf
2#0001010011# => (ALU, OP_MFMSR, NONE, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfmsr
2#0101010011# => (ALU, OP_MFSPR, SPR, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfspr 2#0101010011# => (ALU, OP_MFSPR, SPR, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfspr
2#0100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- modud 2#0100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- modud
2#0100001011# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0'), -- moduw 2#0100001011# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0'), -- moduw
2#1100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- modsd 2#1100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- modsd
2#1100001011# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', NONE, '0', '0'), -- modsw 2#1100001011# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', NONE, '0', '0'), -- modsw
2#0010010000# => (ALU, OP_MTCRF, NONE, NONE, RS, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mtcrf/mtocrf 2#0010010000# => (ALU, OP_MTCRF, NONE, NONE, RS, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mtcrf/mtocrf
2#0010110010# => (ALU, OP_MTMSRD, NONE, NONE, RS, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtmsrd # ignore top bits and d
2#0111010011# => (ALU, OP_MTSPR, NONE, NONE, RS, SPR, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mtspr 2#0111010011# => (ALU, OP_MTSPR, NONE, NONE, RS, SPR, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mtspr
2#0001001001# => (ALU, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0'), -- mulhd 2#0001001001# => (ALU, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0'), -- mulhd
2#0000001001# => (ALU, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- mulhdu 2#0000001001# => (ALU, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- mulhdu
@ -425,6 +430,10 @@ begin
if is_fast_spr(v.ispr1) = '0' then if is_fast_spr(v.ispr1) = '0' then
v.decode.sgl_pipe := '1'; v.decode.sgl_pipe := '1';
end if; end if;
elsif v.decode.insn_type = OP_RFID then
report "PPC RFID";
v.ispr1 := fast_spr_num(SPR_SRR0);
v.ispr2 := fast_spr_num(SPR_SRR1);
end if; end if;


if flush_in = '1' then if flush_in = '1' then

@ -9,18 +9,17 @@ package decode_types is
OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC, OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC,
OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST, OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,
OP_DCBZ, OP_DIV, OP_DIVE, OP_EXTS, OP_DCBZ, OP_DIV, OP_DIVE, OP_EXTS,
OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC, OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_IRQ_M0, OP_IRQ_M1, OP_ISEL, OP_ISYNC,
OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF, OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF,
OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFSPR, OP_MOD, OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFMSR, OP_MFSPR, OP_MOD,
OP_MTCRF, OP_MTSPR, OP_MUL_L64, OP_MTCRF, OP_MTMSRD, OP_MTSPR, OP_MUL_L64,
OP_MUL_H64, OP_MUL_H32, OP_OR, OP_MUL_H64, OP_MUL_H32, OP_OR,
OP_POPCNT, OP_PRTY, OP_POPCNT, OP_PRTY, OP_RFID,
OP_RLC, OP_RLCL, OP_RLCR, OP_SETB, OP_RLC, OP_RLCL, OP_RLCR, OP_SETB,
OP_SHL, OP_SHR, OP_SHL, OP_SHR,
OP_SYNC, OP_TD, OP_TDI, OP_TW, OP_SYNC, OP_TD, OP_TDI, OP_TW,
OP_TWI, OP_XOR, OP_SIM_CONFIG OP_TWI, OP_XOR, OP_SIM_CONFIG
); );

type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR); type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR);
type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR); type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR);
type input_reg_c_t is (NONE, RS); type input_reg_c_t is (NONE, RS);

@ -49,6 +49,10 @@ architecture behaviour of execute1 is
slow_op_xerc : xer_common_t; slow_op_xerc : xer_common_t;
end record; end record;


type irq_state_t is (WRITE_SRR0, WRITE_SRR1);

signal irq_state, irq_state_in : irq_state_t;

signal r, rin : reg_type; signal r, rin : reg_type;


signal a_in, b_in, c_in : std_ulogic_vector(63 downto 0); signal a_in, b_in, c_in : std_ulogic_vector(63 downto 0);
@ -175,6 +179,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
r <= rin; r <= rin;
ctrl <= ctrl_tmp; ctrl <= ctrl_tmp;
irq_state <= irq_state_in;
assert not (r.lr_update = '1' and e_in.valid = '1') assert not (r.lr_update = '1' and e_in.valid = '1')
report "LR update collision with valid in EX1" report "LR update collision with valid in EX1"
severity failure; severity failure;
@ -214,6 +219,8 @@ begin
variable msb_a, msb_b : std_ulogic; variable msb_a, msb_b : std_ulogic;
variable a_lt : std_ulogic; variable a_lt : std_ulogic;
variable lv : Execute1ToLoadstore1Type; variable lv : Execute1ToLoadstore1Type;
variable irq_nia : std_ulogic_vector(63 downto 0);
variable irq_valid : std_ulogic;
begin begin
result := (others => '0'); result := (others => '0');
result_with_carry := (others => '0'); result_with_carry := (others => '0');
@ -340,6 +347,15 @@ begin
ctrl_tmp <= ctrl; ctrl_tmp <= ctrl;
-- FIXME: run at 512MHz not core freq -- FIXME: run at 512MHz not core freq
ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1); ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);
ctrl_tmp.dec <= std_ulogic_vector(unsigned(ctrl.dec) - 1);

irq_valid := '0';
irq_nia := (others => '-');
if ctrl.msr(15) = '1' and ctrl.dec(63) = '1' then
report "IRQ valid";
irq_valid := '1';
irq_nia := std_logic_vector(to_unsigned(16#900#, 64));
end if;


terminate_out <= '0'; terminate_out <= '0';
icache_inval <= '0'; icache_inval <= '0';
@ -354,7 +370,33 @@ begin
rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0'; rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0';
rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0'; rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0';


irq_state_in <= WRITE_SRR0;

if irq_state = WRITE_SRR1 then
v.e.write_reg := fast_spr_num(SPR_SRR1);
result := ctrl.msr;
result_en := '1';
-- do this second so IRQ is still valid
-- FIXME frob other bits like HV/PR
ctrl_tmp.msr(15) <= '0';
f_out.redirect <= '1';
f_out.redirect_nia <= irq_nia;

elsif irq_valid = '1' then
-- we need two cycles to write srr0 and 1
-- will need more when we have to write DSISR, DAR and HIER
if irq_state = WRITE_SRR0 then
v.e.write_reg := fast_spr_num(SPR_SRR0);
result := e_in.nia;
if e_in.valid = '1' then if e_in.valid = '1' then
result_en := '1';
irq_state_in <= WRITE_SRR1;
stall_out <= '1';
v.e.valid := '1';
end if;
end if;

elsif e_in.valid = '1' then


v.e.valid := '1'; v.e.valid := '1';
v.e.write_reg := e_in.write_reg; v.e.write_reg := e_in.write_reg;
@ -473,6 +515,11 @@ begin
f_out.redirect <= '1'; f_out.redirect <= '1';
f_out.redirect_nia <= b_in(63 downto 2) & "00"; f_out.redirect_nia <= b_in(63 downto 2) & "00";
end if; end if;

when OP_RFID =>
f_out.redirect <= '1';
f_out.redirect_nia <= a_in(63 downto 2) & "00"; -- srr0
ctrl_tmp.msr <= std_ulogic_vector(signed(b_in)); -- srr1
when OP_CMPB => when OP_CMPB =>
result := ppc_cmpb(c_in, b_in); result := ppc_cmpb(c_in, b_in);
result_en := '1'; result_en := '1';
@ -562,7 +609,12 @@ begin
end if; end if;
end loop; end loop;
end if; end if;
when OP_MFMSR =>
result := ctrl.msr;
result_en := '1';
when OP_MFSPR => when OP_MFSPR =>
report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
"=" & to_hstring(a_in);
if is_fast_spr(e_in.read_reg1) then if is_fast_spr(e_in.read_reg1) then
result := a_in; result := a_in;
if decode_spr_num(e_in.insn) = SPR_XER then if decode_spr_num(e_in.insn) = SPR_XER then
@ -579,6 +631,8 @@ begin
case decode_spr_num(e_in.insn) is case decode_spr_num(e_in.insn) is
when SPR_TB => when SPR_TB =>
result := ctrl.tb; result := ctrl.tb;
when SPR_DEC =>
result := ctrl.dec;
when others => when others =>
result := (others => '0'); result := (others => '0');
end case; end case;
@ -612,6 +666,9 @@ begin
v.e.write_cr_mask := num_to_fxm(crnum); v.e.write_cr_mask := num_to_fxm(crnum);
end if; end if;
v.e.write_cr_data := c_in(31 downto 0); v.e.write_cr_data := c_in(31 downto 0);
when OP_MTMSRD =>
-- FIXME handle just the bits we need to.
ctrl_tmp.msr <= e_in.read_data3;
when OP_MTSPR => when OP_MTSPR =>
report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
"=" & to_hstring(c_in); "=" & to_hstring(c_in);
@ -627,10 +684,12 @@ begin
v.e.write_xerc_enable := '1'; v.e.write_xerc_enable := '1';
end if; end if;
else else
-- TODO: Implement slow SPRs -- slow spr
-- case decode_spr_num(e_in.insn) is case decode_spr_num(e_in.insn) is
-- when others => when SPR_DEC =>
-- end case; ctrl_tmp.dec <= c_in;
when others =>
end case;
end if; end if;
when OP_POPCNT => when OP_POPCNT =>
result := popcnt_result; result := popcnt_result;

Loading…
Cancel
Save