From b55c9cc2987d30974adb06d2130ad774944252fd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 28 Apr 2020 20:28:20 +1000 Subject: [PATCH] execute1: Improve architecture compliance of MSR and related instructions This makes our treatment of the MSR conform better with the ISA. - On reset, initialize the MSR to have the SF and LE bits set and all the others reset. For good measure initialize r properly too. - Fix the bit numbering in msr_copy (the code was using big-endian bit numbers, not little-endian). - Use constants like MSR_EE to index MSR bits instead of expressions like '63 - 48', for readability. - Set MSR[SF, LE] and clear MSR[PR, IR, DR, RI] on interrupts. - Copy the relevant fields for rfid instead of using msr_copy, because the partial function fields of the MSR should be left unchanged, not zeroed. Our implementation of rfid is like the architecture description of hrfid, because we don't implement hypervisor mode. - Return the whole MSR for mfmsr. - Implement the L field for mtmsrd (L=1 copies just EE and RI). - For mtmsrd with L=0, leave out the HV, ME and LE bits as per the arch. - For mtmsrd and rfid, if PR ends up set, then also set EE, IR and DR as per the arch. - A few other minor tidyups (no semantic change). Signed-off-by: Paul Mackerras --- common.vhdl | 9 ++++++ execute1.vhdl | 83 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/common.vhdl b/common.vhdl index 9f6e96d..9041d32 100644 --- a/common.vhdl +++ b/common.vhdl @@ -7,6 +7,15 @@ use work.decode_types.all; package common is + -- MSR bit numbers + constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode + constant MSR_EE : integer := (63 - 48); -- External interrupt Enable + constant MSR_PR : integer := (63 - 49); -- PRoblem state + constant MSR_IR : integer := (63 - 58); -- Instruction Relocation + constant MSR_DR : integer := (63 - 59); -- Data Relocation + constant MSR_RI : integer := (63 - 62); -- Recoverable Interrupt + constant MSR_LE : integer := (63 - 63); -- Little Endian + -- SPR numbers subtype spr_num_t is integer range 0 to 1023; diff --git a/execute1.vhdl b/execute1.vhdl index 2c0a558..0f4eea9 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -48,6 +48,11 @@ architecture behaviour of execute1 is slow_op_oe : std_ulogic; slow_op_xerc : xer_common_t; end record; + constant reg_type_init : reg_type := + (e => Execute1ToWritebackInit, lr_update => '0', + mul_in_progress => '0', div_in_progress => '0', cntz_in_progress => '0', + slow_op_rc => '0', slow_op_oe => '0', slow_op_xerc => xerc_init, + others => (others => '0')); signal r, rin : reg_type; @@ -124,11 +129,11 @@ architecture behaviour of execute1 is -- tion MSR bits are not saved or restored. -- Full function MSR bits lie in the range 0:32, 37:41, and -- 48:63, and partial function MSR bits lie in the range - -- 33:36 and 42:47. + -- 33:36 and 42:47. (Note this is IBM bit numbering). msr_out := (others => '0'); - msr_out(32 downto 0) := msr(32 downto 0); - msr_out(41 downto 37) := msr(41 downto 37); - msr_out(63 downto 48) := msr(63 downto 48); + msr_out(63 downto 31) := msr(63 downto 31); + msr_out(26 downto 22) := msr(26 downto 22); + msr_out(15 downto 0) := msr(15 downto 0); return msr_out; end; @@ -193,14 +198,20 @@ begin execute1_0: process(clk) begin if rising_edge(clk) then - r <= rin; - ctrl <= ctrl_tmp; - assert not (r.lr_update = '1' and e_in.valid = '1') - report "LR update collision with valid in EX1" - severity failure; - if r.lr_update = '1' then - report "LR update to " & to_hstring(r.next_lr); - end if; + if rst = '1' then + r <= reg_type_init; + ctrl.msr <= (MSR_SF => '1', MSR_LE => '1', others => '0'); + ctrl.irq_state <= WRITE_SRR0; + else + r <= rin; + ctrl <= ctrl_tmp; + assert not (r.lr_update = '1' and e_in.valid = '1') + report "LR update collision with valid in EX1" + severity failure; + if r.lr_update = '1' then + report "LR update to " & to_hstring(r.next_lr); + end if; + end if; end if; end process; @@ -370,7 +381,7 @@ begin ctrl_tmp.dec <= std_ulogic_vector(unsigned(ctrl.dec) - 1); irq_valid := '0'; - if ctrl.msr(63 - 48) = '1' and ctrl.dec(63) = '1' then + if ctrl.msr(MSR_EE) = '1' and ctrl.dec(63) = '1' then report "IRQ valid"; irq_valid := '1'; end if; @@ -400,7 +411,13 @@ begin v.e.exc_write_reg := fast_spr_num(SPR_SRR1); v.e.exc_write_data := ctrl.srr1; v.e.exc_write_enable := '1'; - ctrl_tmp.msr(63 - 48) <= '0'; -- clear EE + ctrl_tmp.msr(MSR_SF) <= '1'; + ctrl_tmp.msr(MSR_EE) <= '0'; + ctrl_tmp.msr(MSR_PR) <= '0'; + ctrl_tmp.msr(MSR_IR) <= '0'; + ctrl_tmp.msr(MSR_DR) <= '0'; + ctrl_tmp.msr(MSR_RI) <= '0'; + ctrl_tmp.msr(MSR_LE) <= '1'; f_out.redirect <= '1'; f_out.redirect_nia <= ctrl.irq_nia; v.e.valid := e_in.valid; @@ -545,7 +562,7 @@ begin when OP_B => f_out.redirect <= '1'; if (insn_aa(e_in.insn)) then - f_out.redirect_nia <= std_ulogic_vector(signed(b_in)); + f_out.redirect_nia <= b_in; else f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in)); end if; @@ -561,7 +578,7 @@ begin if ppc_bc_taken(bo, bi, e_in.cr, a_in) = 1 then f_out.redirect <= '1'; if (insn_aa(e_in.insn)) then - f_out.redirect_nia <= std_ulogic_vector(signed(b_in)); + f_out.redirect_nia <= b_in; else f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in)); end if; @@ -584,7 +601,17 @@ begin when OP_RFID => f_out.redirect <= '1'; f_out.redirect_nia <= a_in(63 downto 2) & "00"; -- srr0 - ctrl_tmp.msr <= msr_copy(std_ulogic_vector(signed(b_in))); -- srr1 + -- Can't use msr_copy here because the partial function MSR + -- bits should be left unchanged, not zeroed. + ctrl_tmp.msr(63 downto 31) <= b_in(63 downto 31); + ctrl_tmp.msr(26 downto 22) <= b_in(26 downto 22); + ctrl_tmp.msr(15 downto 0) <= b_in(15 downto 0); + if b_in(MSR_PR) = '1' then + ctrl_tmp.msr(MSR_EE) <= '1'; + ctrl_tmp.msr(MSR_IR) <= '1'; + ctrl_tmp.msr(MSR_DR) <= '1'; + end if; + when OP_CMPB => result := ppc_cmpb(c_in, b_in); result_en := '1'; @@ -658,7 +685,7 @@ begin end loop; end if; when OP_MFMSR => - result := msr_copy(ctrl.msr); + result := ctrl.msr; result_en := '1'; when OP_MFSPR => report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & @@ -714,9 +741,23 @@ begin v.e.write_cr_mask := num_to_fxm(crnum); end if; v.e.write_cr_data := c_in(31 downto 0); - when OP_MTMSRD => - -- FIXME handle just the bits we need to. - ctrl_tmp.msr <= msr_copy(c_in); + when OP_MTMSRD => + if e_in.insn(16) = '1' then + -- just update EE and RI + ctrl_tmp.msr(MSR_EE) <= c_in(MSR_EE); + ctrl_tmp.msr(MSR_RI) <= c_in(MSR_RI); + else + -- Architecture says to leave out bits 3 (HV), 51 (ME) + -- and 63 (LE) (IBM bit numbering) + ctrl_tmp.msr(63 downto 61) <= c_in(63 downto 61); + ctrl_tmp.msr(59 downto 13) <= c_in(59 downto 13); + ctrl_tmp.msr(11 downto 1) <= c_in(11 downto 1); + if c_in(MSR_PR) = '1' then + ctrl_tmp.msr(MSR_EE) <= '1'; + ctrl_tmp.msr(MSR_IR) <= '1'; + ctrl_tmp.msr(MSR_DR) <= '1'; + end if; + end if; when OP_MTSPR => report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & "=" & to_hstring(c_in);