diff --git a/common.vhdl b/common.vhdl index 76eaec2..d182a32 100644 --- a/common.vhdl +++ b/common.vhdl @@ -64,6 +64,7 @@ package common is constant SPR_DSCR : spr_num_t := 17; constant SPR_VRSAVE : spr_num_t := 256; constant SPR_PIR : spr_num_t := 1023; + constant SPR_CIABR : spr_num_t := 187; -- PMU registers constant SPR_UPMC1 : spr_num_t := 771; @@ -174,6 +175,7 @@ package common is constant SPRSEL_CTRL : spr_selector := 4x"a"; constant SPRSEL_DSCR : spr_selector := 4x"b"; constant SPRSEL_PIR : spr_selector := 4x"c"; + constant SPRSEL_CIABR : spr_selector := 4x"d"; constant SPRSEL_XER : spr_selector := 4x"f"; -- FSCR and HFSCR bit numbers @@ -275,6 +277,7 @@ package common is hfscr_fp: std_ulogic; heir: std_ulogic_vector(63 downto 0); dscr: std_ulogic_vector(24 downto 0); + ciabr: std_ulogic_vector(63 downto 0); end record; constant ctrl_t_init : ctrl_t := (wait_state => '0', run => '1', xer_low => 18x"0", diff --git a/decode1.vhdl b/decode1.vhdl index 0ea9ed1..8d2d2fb 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -488,6 +488,8 @@ architecture behaviour of decode1 is i.sel := SPRSEL_DSCR; when SPR_PIR => i.sel := SPRSEL_PIR; + when SPR_CIABR => + i.sel := SPRSEL_CIABR; when others => i.valid := '0'; end case; diff --git a/execute1.vhdl b/execute1.vhdl index 3b7ec2f..5240063 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -96,6 +96,7 @@ architecture behaviour of execute1 is set_heir : std_ulogic; write_ctrl : std_ulogic; write_dscr : std_ulogic; + write_ciabr : std_ulogic; enter_wait : std_ulogic; scv_trap : std_ulogic; end record; @@ -116,6 +117,7 @@ architecture behaviour of execute1 is start_div : std_ulogic; start_bsort : std_ulogic; do_trace : std_ulogic; + ciabr_trace : std_ulogic; fp_intr : std_ulogic; res2_sel : std_ulogic_vector(1 downto 0); bypass_valid : std_ulogic; @@ -133,6 +135,7 @@ architecture behaviour of execute1 is busy: std_ulogic; fp_exception_next : std_ulogic; trace_next : std_ulogic; + trace_ciabr : std_ulogic; prev_op : insn_type_t; prev_prefixed : std_ulogic; oe : std_ulogic; @@ -165,8 +168,8 @@ architecture behaviour of execute1 is constant reg_stage1_type_init : reg_stage1_type := (e => Execute1ToWritebackInit, se => side_effect_init, busy => '0', - fp_exception_next => '0', trace_next => '0', prev_op => OP_ILLEGAL, - prev_prefixed => '0', + fp_exception_next => '0', trace_next => '0', trace_ciabr => '0', + prev_op => OP_ILLEGAL, prev_prefixed => '0', oe => '0', mul_select => "000", res2_sel => "00", spr_select => spr_id_init, pmu_spr_num => 5x"0", redir_to_next => '0', advance_nia => '0', lr_from_next => '0', @@ -1157,6 +1160,13 @@ begin end if; v.do_trace := ex1.msr(MSR_SE); + -- see if we have a CIABR map + if ctrl.ciabr(0) = '1' and ctrl.ciabr(1) = not ex1.msr(MSR_PR) and + ctrl.ciabr(63 downto 2) = e_in.nia(63 downto 2) then + v.do_trace := '1'; + v.ciabr_trace := '1'; + end if; + case_0: case e_in.insn_type is when OP_ILLEGAL => illegal := '1'; @@ -1392,6 +1402,8 @@ begin v.se.write_ctrl := '1'; when SPRSEL_DSCR => v.se.write_dscr := '1'; + when SPRSEL_CIABR => + v.se.write_ciabr := '1'; when others => end case; end if; @@ -1655,12 +1667,14 @@ begin v.e.srr1 := (others => '0'); v.e.srr1(47 - 33) := '1'; v.e.srr1(47 - 34) := ex1.prev_prefixed; - if ex1.prev_op = OP_LOAD or ex1.prev_op = OP_ICBI or ex1.prev_op = OP_ICBT or - ex1.prev_op = OP_DCBF then + if (ex1.prev_op = OP_LOAD or ex1.prev_op = OP_ICBI or ex1.prev_op = OP_ICBT or + ex1.prev_op = OP_DCBF) and ex1.trace_ciabr = '0' then v.e.srr1(47 - 35) := '1'; - elsif ex1.prev_op = OP_STORE or ex1.prev_op = OP_DCBZ then + elsif (ex1.prev_op = OP_STORE or ex1.prev_op = OP_DCBZ) and + ex1.trace_ciabr = '0' then v.e.srr1(47 - 36) := '1'; end if; + v.e.srr1(47 - 43) := ex1.trace_ciabr; elsif irq_valid = '1' then -- Don't deliver the interrupt until we have a valid instruction @@ -1694,6 +1708,7 @@ begin bypass_valid := actions.bypass_valid; v.taken_branch_event := actions.take_branch; v.trace_next := actions.do_trace; + v.trace_ciabr := actions.ciabr_trace; v.fp_exception_next := actions.fp_intr; v.res2_sel := actions.res2_sel; v.msr := actions.new_msr; @@ -1877,6 +1892,7 @@ begin assemble_ctrl(ctrl, ex1.msr(MSR_PR)) when SPRSEL_CTRL, 39x"0" & ctrl.dscr when SPRSEL_DSCR, 56x"0" & std_ulogic_vector(to_unsigned(CPU_INDEX, 8)) when SPRSEL_PIR, + ctrl.ciabr when SPRSEL_CIABR, assemble_xer(ex1.e.xerc, ctrl.xer_low) when others; stage2_stall <= l_in.l2stall or fp_in.f2stall; @@ -2057,6 +2073,9 @@ begin if ex1.se.write_dscr = '1' then ctrl_tmp.dscr <= ex1.e.write_data(24 downto 0); end if; + if ex1.se.write_ciabr = '1' then + ctrl_tmp.ciabr <= ex1.e.write_data; + end if; if ex1.se.enter_wait = '1' then ctrl_tmp.wait_state <= '1'; end if;