diff --git a/common.vhdl b/common.vhdl index 8c42caf..a3ead86 100644 --- a/common.vhdl +++ b/common.vhdl @@ -56,6 +56,7 @@ package common is constant SPR_HSPRG1 : spr_num_t := 305; constant SPR_PID : spr_num_t := 48; constant SPR_PTCR : spr_num_t := 464; + constant SPR_LPCR : spr_num_t := 318; constant SPR_PVR : spr_num_t := 287; constant SPR_FSCR : spr_num_t := 153; constant SPR_HFSCR : spr_num_t := 190; @@ -81,6 +82,8 @@ package common is constant SPR_NOOP1 : spr_num_t := 809; constant SPR_NOOP2 : spr_num_t := 810; constant SPR_NOOP3 : spr_num_t := 811; + constant SPR_HMER : spr_num_t := 336; + constant SPR_HMEER : spr_num_t := 337; -- PMU registers constant SPR_UPMC1 : spr_num_t := 771; @@ -96,6 +99,9 @@ package common is constant SPR_USIER : spr_num_t := 768; constant SPR_USIAR : spr_num_t := 780; constant SPR_USDAR : spr_num_t := 781; + constant SPR_USIER2 : spr_num_t := 736; + constant SPR_USIER3 : spr_num_t := 737; + constant SPR_UMMCR3 : spr_num_t := 738; constant SPR_PMC1 : spr_num_t := 787; constant SPR_PMC2 : spr_num_t := 788; constant SPR_PMC3 : spr_num_t := 789; @@ -109,6 +115,9 @@ package common is constant SPR_SIER : spr_num_t := 784; constant SPR_SIAR : spr_num_t := 796; constant SPR_SDAR : spr_num_t := 797; + constant SPR_SIER2 : spr_num_t := 752; + constant SPR_SIER3 : spr_num_t := 753; + constant SPR_MMCR3 : spr_num_t := 754; -- GPR indices in the register file (GPR only) subtype gpr_index_t is std_ulogic_vector(4 downto 0); @@ -181,15 +190,15 @@ package common is end record; constant spr_id_init : spr_id := (sel => "0000", others => '0'); - constant SPRSEL_TB : spr_selector := 4x"0"; - constant SPRSEL_TBU : spr_selector := 4x"1"; - constant SPRSEL_DEC : spr_selector := 4x"2"; - constant SPRSEL_PVR : spr_selector := 4x"3"; - constant SPRSEL_LOGA : spr_selector := 4x"4"; - constant SPRSEL_LOGD : spr_selector := 4x"5"; + constant SPRSEL_ZERO : spr_selector := 4x"0"; + constant SPRSEL_TB : spr_selector := 4x"1"; + constant SPRSEL_TBU : spr_selector := 4x"2"; + constant SPRSEL_DEC : spr_selector := 4x"3"; + constant SPRSEL_PVR : spr_selector := 4x"4"; + constant SPRSEL_LOGR : spr_selector := 4x"5"; constant SPRSEL_CFAR : spr_selector := 4x"6"; constant SPRSEL_FSCR : spr_selector := 4x"7"; - constant SPRSEL_HFSCR : spr_selector := 4x"8"; + constant SPRSEL_LPCR : spr_selector := 4x"8"; constant SPRSEL_HEIR : spr_selector := 4x"9"; constant SPRSEL_CTRL : spr_selector := 4x"a"; constant SPRSEL_DSCR : spr_selector := 4x"b"; @@ -198,17 +207,11 @@ package common is constant SPRSEL_DEXCR : spr_selector := 4x"e"; constant SPRSEL_XER : spr_selector := 4x"f"; - -- FSCR and HFSCR bit numbers + -- FSCR bit numbers constant FSCR_PREFIX : integer := 63 - 50; constant FSCR_SCV : integer := 63 - 51; constant FSCR_TAR : integer := 63 - 55; constant FSCR_DSCR : integer := 63 - 61; - constant HFSCR_PREFIX : integer := 63 - 50; - constant HFSCR_MSG : integer := 63 - 53; - constant HFSCR_TAR : integer := 63 - 55; - constant HFSCR_PMUSPR : integer := 63 - 60; - constant HFSCR_DSCR : integer := 63 - 61; - constant HFSCR_FP : integer := 63 - 63; -- FPSCR bit numbers constant FPSCR_FX : integer := 63 - 32; @@ -242,6 +245,15 @@ package common is constant FPSCR_NI : integer := 63 - 61; constant FPSCR_RN : integer := 63 - 63; + -- LPCR bit numbers + constant LPCR_HAIL : integer := 63 - 37; + constant LPCR_UPRT : integer := 63 - 41; + constant LPCR_HR : integer := 63 - 43; + constant LPCR_LD : integer := 63 - 46; + constant LPCR_HEIC : integer := 63 - 59; + constant LPCR_LPES : integer := 63 - 60; + constant LPCR_HVICE : integer := 63 - 62; + -- Real addresses -- REAL_ADDR_BITS is the number of real address bits that we store constant REAL_ADDR_BITS : positive := 56; @@ -301,11 +313,6 @@ package common is fscr_scv: std_ulogic; fscr_tar: std_ulogic; fscr_dscr: std_ulogic; - hfscr_ic: std_ulogic_vector(3 downto 0); - hfscr_pref: std_ulogic; - hfscr_tar: std_ulogic; - hfscr_dscr: std_ulogic; - 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); @@ -313,14 +320,20 @@ package common is dexcr_pro: aspect_bits_t; hdexcr_hyp: aspect_bits_t; hdexcr_enf: aspect_bits_t; + lpcr_hail: std_ulogic; + lpcr_ld: std_ulogic; + lpcr_heic: std_ulogic; + lpcr_lpes: std_ulogic; + lpcr_hvice: std_ulogic; end record; constant ctrl_t_init : ctrl_t := (wait_state => '0', run => '1', xer_low => 18x"0", fscr_ic => x"0", fscr_pref => '1', fscr_scv => '1', fscr_tar => '1', fscr_dscr => '1', - hfscr_ic => x"0", hfscr_pref => '1', hfscr_tar => '1', hfscr_dscr => '1', hfscr_fp => '1', dscr => (others => '0'), dexcr_pnh => aspect_bits_init, dexcr_pro => aspect_bits_init, hdexcr_hyp => aspect_bits_init, hdexcr_enf => aspect_bits_init, + lpcr_hail => '0', lpcr_ld => '1', lpcr_heic => '0', + lpcr_lpes => '0', lpcr_hvice => '0', others => (others => '0')); type timebase_ctrl is record @@ -792,6 +805,7 @@ package common is write_xerc_enable : std_ulogic; xerc : xer_common_t; interrupt : std_ulogic; + alt_intr : std_ulogic; hv_intr : std_ulogic; is_scv : std_ulogic; intr_vec : intr_vector_t; @@ -802,7 +816,6 @@ package common is br_taken: std_ulogic; abs_br: std_ulogic; srr1: std_ulogic_vector(15 downto 0); - msr: std_ulogic_vector(63 downto 0); end record; constant Execute1ToWritebackInit : Execute1ToWritebackType := (valid => '0', instr_tag => instr_tag_init, rc => '0', mode_32bit => '0', @@ -810,11 +823,11 @@ package common is write_xerc_enable => '0', xerc => xerc_init, write_data => (others => '0'), write_cr_mask => (others => '0'), write_cr_data => (others => '0'), write_reg => (others => '0'), - interrupt => '0', hv_intr => '0', is_scv => '0', intr_vec => 0, + interrupt => '0', alt_intr => '0', hv_intr => '0', is_scv => '0', intr_vec => 0, redirect => '0', redir_mode => "0000", last_nia => (others => '0'), br_last => '0', br_taken => '0', abs_br => '0', - srr1 => (others => '0'), msr => (others => '0')); + srr1 => (others => '0')); type Execute1ToFPUType is record valid : std_ulogic; @@ -899,13 +912,14 @@ package common is br_last : std_ulogic; br_taken : std_ulogic; interrupt : std_ulogic; - intr_vec : std_ulogic_vector(16 downto 0); + alt_intr : std_ulogic; + intr_vec : std_ulogic_vector(63 downto 0); end record; constant WritebackToFetch1Init : WritebackToFetch1Type := (redirect => '0', virt_mode => '0', priv_mode => '0', big_endian => '0', mode_32bit => '0', redirect_nia => (others => '0'), br_last => '0', br_taken => '0', br_nia => (others => '0'), - interrupt => '0', intr_vec => 17x"0"); + interrupt => '0', alt_intr => '0', intr_vec => 64x"0"); type WritebackToRegisterFileType is record write_reg : gspr_index_t; @@ -931,6 +945,7 @@ package common is intr : std_ulogic; hv_intr : std_ulogic; scv_int : std_ulogic; + alt_int : std_ulogic; srr1 : std_ulogic_vector(15 downto 0); end record; diff --git a/core_debug.vhdl b/core_debug.vhdl index 67b41fb..b1abe83 100644 --- a/core_debug.vhdl +++ b/core_debug.vhdl @@ -329,7 +329,7 @@ begin sel := SPRSEL_FSCR; when 5x"0f" => isram := '0'; - sel := SPRSEL_HFSCR; + sel := SPRSEL_LPCR; when 5x"10" => isram := '0'; sel := SPRSEL_HEIR; diff --git a/decode1.vhdl b/decode1.vhdl index 1978a27..823667c 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -476,22 +476,25 @@ architecture behaviour of decode1 is when SPR_PVR => i.sel := SPRSEL_PVR; when 724 => -- LOG_ADDR SPR - i.sel := SPRSEL_LOGA; + i.sel := SPRSEL_LOGR; when 725 => -- LOG_DATA SPR - i.sel := SPRSEL_LOGD; + i.sel := SPRSEL_LOGR; + i.ronly := '1'; when SPR_UPMC1 | SPR_UPMC2 | SPR_UPMC3 | SPR_UPMC4 | SPR_UPMC5 | SPR_UPMC6 | SPR_UMMCR0 | SPR_UMMCR1 | SPR_UMMCR2 | SPR_UMMCRA | SPR_USIER | SPR_USIAR | SPR_USDAR | SPR_PMC1 | SPR_PMC2 | SPR_PMC3 | SPR_PMC4 | SPR_PMC5 | SPR_PMC6 | SPR_MMCR0 | SPR_MMCR1 | SPR_MMCR2 | SPR_MMCRA | SPR_SIER | SPR_SIAR | SPR_SDAR => i.ispmu := '1'; + when SPR_USIER2 | SPR_USIER3 | SPR_UMMCR3 | SPR_SIER2 | SPR_SIER3 | SPR_MMCR3 => + i.sel := SPRSEL_ZERO; when SPR_CFAR => i.sel := SPRSEL_CFAR; when SPR_XER => i.sel := SPRSEL_XER; when SPR_FSCR => i.sel := SPRSEL_FSCR; - when SPR_HFSCR => - i.sel := SPRSEL_HFSCR; + when SPR_LPCR => + i.sel := SPRSEL_LPCR; when SPR_HEIR => i.sel := SPRSEL_HEIR; when SPR_CTRL => @@ -515,6 +518,8 @@ architecture behaviour of decode1 is i.ronly := '1'; when SPR_NOOP0 | SPR_NOOP1 | SPR_NOOP2 | SPR_NOOP3 => i.noop := '1'; + when SPR_HMER | SPR_HMEER => + i.sel := SPRSEL_ZERO; when others => i.valid := '0'; end case; diff --git a/execute1.vhdl b/execute1.vhdl index ee38863..a0961f7 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -92,8 +92,7 @@ architecture behaviour of execute1 is mult_32s : std_ulogic; write_fscr : std_ulogic; write_ic : std_ulogic; - write_hfscr : std_ulogic; - write_hic : std_ulogic; + write_lpcr : std_ulogic; write_heir : std_ulogic; set_heir : std_ulogic; write_ctrl : std_ulogic; @@ -212,6 +211,7 @@ architecture behaviour of execute1 is signal valid_in : std_ulogic; signal ctrl: ctrl_t := ctrl_t_init; signal ctrl_tmp: ctrl_t := ctrl_t_init; + signal dec_sign: std_ulogic; signal rotator_result: std_ulogic_vector(63 downto 0); signal rotator_carry: std_ulogic; signal logical_result: std_ulogic_vector(63 downto 0); @@ -224,6 +224,7 @@ architecture behaviour of execute1 is signal spr_result: std_ulogic_vector(63 downto 0); signal next_nia : std_ulogic_vector(63 downto 0); signal s1_sel : std_ulogic_vector(2 downto 0); + signal log_spr_data : std_ulogic_vector(63 downto 0); signal carry_32 : std_ulogic; signal carry_64 : std_ulogic; @@ -410,15 +411,17 @@ architecture behaviour of execute1 is return ret; end; - function assemble_hfscr(c: ctrl_t) return std_ulogic_vector is + function assemble_lpcr(c: ctrl_t) return std_ulogic_vector is variable ret : std_ulogic_vector(63 downto 0); begin ret := (others => '0'); - ret(59 downto 56) := c.hfscr_ic; - ret(HFSCR_PREFIX) := c.hfscr_pref; - ret(HFSCR_TAR) := c.hfscr_tar; - ret(HFSCR_DSCR) := c.hfscr_dscr; - ret(HFSCR_FP) := c.hfscr_fp; + ret(LPCR_HAIL) := c.lpcr_hail; + ret(LPCR_UPRT) := '1'; + ret(LPCR_HR) := '1'; + ret(LPCR_LD) := c.lpcr_ld; + ret(LPCR_HEIC) := c.lpcr_heic; + ret(LPCR_LPES) := c.lpcr_lpes; + ret(LPCR_HVICE) := c.lpcr_hvice; return ret; end; @@ -457,6 +460,15 @@ architecture behaviour of execute1 is return ret; end; + function assemble_dec(c: ctrl_t) return std_ulogic_vector is + begin + if c.lpcr_ld = '1' then + return c.dec; + else + return 32x"0" & c.dec(31 downto 0); + end if; + end; + -- Tell vivado to keep the hierarchy for the random module so that the -- net names in the xdc file match. attribute keep_hierarchy : string; @@ -596,6 +608,8 @@ begin tb_next <= thi & tlo; end process; + dec_sign <= (ctrl.dec(63) and ctrl.lpcr_ld) or (ctrl.dec(31) and not ctrl.lpcr_ld); + dbg_ctrl_out <= ctrl; log_rd_addr <= ex2.log_addr_spr; @@ -796,8 +810,8 @@ begin case dbg_spr_addr(3 downto 0) is when SPRSEL_FSCR => dbg_spr_data <= assemble_fscr(ctrl); - when SPRSEL_HFSCR => - dbg_spr_data <= assemble_hfscr(ctrl); + when SPRSEL_LPCR => + dbg_spr_data <= assemble_lpcr(ctrl); when SPRSEL_HEIR => dbg_spr_data <= ctrl.heir; when SPRSEL_CFAR => @@ -1189,6 +1203,7 @@ begin v.e.redir_mode := ex1.msr(MSR_IR) & not ex1.msr(MSR_PR) & not ex1.msr(MSR_LE) & not ex1.msr(MSR_SF); v.e.intr_vec := 16#700#; + v.e.alt_intr := ctrl.lpcr_hail and ex1.msr(MSR_IR) and ex1.msr(MSR_DR); v.e.mode_32bit := not ex1.msr(MSR_SF); v.e.instr_tag := e_in.instr_tag; v.e.last_nia := e_in.nia; @@ -1387,8 +1402,10 @@ begin slow_op := '1'; if e_in.spr_select.ispmu = '0' then case e_in.spr_select.sel is - when SPRSEL_LOGD => - v.se.inc_loga := '1'; + when SPRSEL_LOGR => + if e_in.insn(16) = '0' then + v.se.inc_loga := '1'; + end if; when others => end case; v.res2_sel := "10"; @@ -1451,14 +1468,14 @@ begin v.se.write_xerlow := '1'; when SPRSEL_DEC => v.se.write_dec := '1'; - when SPRSEL_LOGA => + when SPRSEL_LOGR => v.se.write_loga := '1'; when SPRSEL_CFAR => v.se.write_cfar := '1'; when SPRSEL_FSCR => v.se.write_fscr := '1'; - when SPRSEL_HFSCR => - v.se.write_hfscr := '1'; + when SPRSEL_LPCR => + v.se.write_lpcr := '1'; when SPRSEL_HEIR => v.se.write_heir := '1'; when SPRSEL_CTRL => @@ -1548,22 +1565,15 @@ begin end case; if ex1.msr(MSR_PR) = '1' and e_in.prefixed = '1' and - (ctrl.hfscr_pref = '0' or ctrl.fscr_pref = '0') then - -- [Hypervisor] facility unavailable for prefixed instructions, + ctrl.fscr_pref = '0' then + -- Facility unavailable for prefixed instructions, -- which has higher priority than the alignment interrupt for -- misaligned prefixed instructions, which has higher priority than - -- other [hypervisor] facility unavailable interrupts (e.g. for - -- plfs with HFSCR[FP] = 0). + -- other facility unavailable interrupts. v.exception := '1'; v.ic := x"b"; - if ctrl.hfscr_pref = '0' then - v.e.hv_intr := '1'; - v.e.intr_vec := 16#f80#; - v.se.write_hic := '1'; - else - v.e.intr_vec := 16#f60#; - v.se.write_ic := '1'; - end if; + v.e.intr_vec := 16#f60#; + v.se.write_ic := '1'; elsif misaligned = '1' then -- generate an alignment interrupt @@ -1608,41 +1618,20 @@ begin v.se.write_ic := '1'; elsif ex1.msr(MSR_PR) = '1' and e_in.uses_tar = '1' and - (ctrl.hfscr_tar = '0' or ctrl.fscr_tar = '0') then - -- [Hypervisor] facility unavailable for TAR access + ctrl.fscr_tar = '0' then + -- Facility unavailable for TAR access v.exception := '1'; v.ic := x"8"; - if ctrl.hfscr_tar = '0' then - v.e.hv_intr := '1'; - v.e.intr_vec := 16#f80#; - v.se.write_hic := '1'; - else - v.e.intr_vec := 16#f60#; - v.se.write_ic := '1'; - end if; + v.e.intr_vec := 16#f60#; + v.se.write_ic := '1'; elsif ex1.msr(MSR_PR) = '1' and e_in.uses_dscr = '1' and - (ctrl.hfscr_dscr = '0' or ctrl.fscr_dscr = '0') then - -- [Hypervisor] facility unavailable for DSCR access + ctrl.fscr_dscr = '0' then + -- Facility unavailable for DSCR access v.exception := '1'; v.ic := x"2"; - if ctrl.hfscr_dscr = '0' then - v.e.hv_intr := '1'; - v.e.intr_vec := 16#f80#; - v.se.write_hic := '1'; - else - v.e.intr_vec := 16#f60#; - v.se.write_ic := '1'; - end if; - - elsif HAS_FPU and ex1.msr(MSR_PR) = '1' and e_in.fac = FPU and - ctrl.hfscr_fp = '0' then - -- Hypervisor facility unavailable for FP instructions - v.exception := '1'; - v.ic := x"0"; - v.e.hv_intr := '1'; - v.e.intr_vec := 16#f80#; - v.se.write_hic := '1'; + v.e.intr_vec := 16#f60#; + v.se.write_ic := '1'; elsif HAS_FPU and ex1.msr(MSR_FP) = '0' and e_in.fac = FPU then -- generate a floating-point unavailable interrupt @@ -1705,7 +1694,8 @@ begin v.busy := '0'; bypass_valid := actions.bypass_valid; - irq_valid := ex1.msr(MSR_EE) and (pmu_to_x.intr or ctrl.dec(63) or ext_irq_in); + irq_valid := ex1.msr(MSR_EE) and (pmu_to_x.intr or dec_sign or + (ext_irq_in and not ctrl.lpcr_heic)); if valid_in = '1' then v.prev_op := e_in.insn_type; @@ -1747,14 +1737,14 @@ begin if pmu_to_x.intr = '1' then v.e.intr_vec := 16#f00#; report "IRQ valid: PMU"; - elsif ctrl.dec(63) = '1' then + elsif dec_sign = '1' then v.e.intr_vec := 16#900#; report "IRQ valid: DEC"; elsif ext_irq_in = '1' then v.e.intr_vec := 16#500#; report "IRQ valid: External"; v.ext_interrupt := '1'; - v.e.hv_intr := '1'; + v.e.hv_intr := not ctrl.lpcr_lpes; end if; v.e.srr1 := (others => '0'); exception := '1'; @@ -1968,23 +1958,25 @@ begin end process; -- Slow SPR read mux + log_spr_data <= (log_wr_addr & ex2.log_addr_spr) when ex1.insn(16) = '0' + else log_rd_data; with ex1.spr_select.sel select spr_result <= timebase when SPRSEL_TB, 32x"0" & timebase(63 downto 32) when SPRSEL_TBU, - ctrl.dec when SPRSEL_DEC, + assemble_dec(ctrl) when SPRSEL_DEC, 32x"0" & PVR_MICROWATT when SPRSEL_PVR, - log_wr_addr & ex2.log_addr_spr when SPRSEL_LOGA, - log_rd_data when SPRSEL_LOGD, + log_spr_data when SPRSEL_LOGR, ctrl.cfar when SPRSEL_CFAR, assemble_fscr(ctrl) when SPRSEL_FSCR, - assemble_hfscr(ctrl) when SPRSEL_HFSCR, + assemble_lpcr(ctrl) when SPRSEL_LPCR, ctrl.heir when SPRSEL_HEIR, 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_dexcr(ctrl, ex1.insn) when SPRSEL_DEXCR, - assemble_xer(ex1.e.xerc, ctrl.xer_low) when others; + assemble_xer(ex1.e.xerc, ctrl.xer_low) when SPRSEL_XER, + 64x"0" when others; stage2_stall <= l_in.l2stall or fp_in.f2stall; @@ -2127,15 +2119,6 @@ begin v.log_addr_spr := std_ulogic_vector(unsigned(ex2.log_addr_spr) + 1); end if; x_to_pmu.mtspr <= ex1.se.write_pmuspr; - if ex1.se.write_hfscr = '1' then - ctrl_tmp.hfscr_ic <= ex1.e.write_data(59 downto 56); - ctrl_tmp.hfscr_pref <= ex1.e.write_data(HFSCR_PREFIX); - ctrl_tmp.hfscr_tar <= ex1.e.write_data(HFSCR_TAR); - ctrl_tmp.hfscr_dscr <= ex1.e.write_data(HFSCR_DSCR); - ctrl_tmp.hfscr_fp <= ex1.e.write_data(HFSCR_FP); - elsif ex1.se.write_hic = '1' then - ctrl_tmp.hfscr_ic <= ex1.ic; - end if; if ex1.se.write_fscr = '1' then ctrl_tmp.fscr_ic <= ex1.e.write_data(59 downto 56); ctrl_tmp.fscr_pref <= ex1.e.write_data(FSCR_PREFIX); @@ -2145,6 +2128,13 @@ begin elsif ex1.se.write_ic = '1' then ctrl_tmp.fscr_ic <= ex1.ic; end if; + if ex1.se.write_lpcr = '1' then + ctrl_tmp.lpcr_hail <= ex1.e.write_data(LPCR_HAIL); + ctrl_tmp.lpcr_ld <= ex1.e.write_data(LPCR_LD); + ctrl_tmp.lpcr_heic <= ex1.e.write_data(LPCR_HEIC); + ctrl_tmp.lpcr_lpes <= ex1.e.write_data(LPCR_LPES); + ctrl_tmp.lpcr_hvice <= ex1.e.write_data(LPCR_HVICE); + end if; if ex1.se.write_heir = '1' then ctrl_tmp.heir <= ex1.e.write_data; elsif ex1.se.set_heir = '1' then @@ -2173,7 +2163,7 @@ begin -- pending exceptions clear any wait state -- ex1.fp_exception_next is not tested because it is not possible to -- get into wait state with a pending FP exception. - irq_exc := pmu_to_x.intr or ctrl.dec(63) or ext_irq_in; + irq_exc := pmu_to_x.intr or dec_sign or ext_irq_in; if ex1.trace_next = '1' or irq_exc = '1' or interrupt_in.intr = '1' then ctrl_tmp.wait_state <= '0'; end if; @@ -2186,11 +2176,13 @@ begin ctrl_tmp.msr(MSR_FP) <= '0'; ctrl_tmp.msr(MSR_FE0) <= '0'; ctrl_tmp.msr(MSR_FE1) <= '0'; - ctrl_tmp.msr(MSR_IR) <= '0'; - ctrl_tmp.msr(MSR_DR) <= '0'; + ctrl_tmp.msr(MSR_IR) <= interrupt_in.alt_int; + ctrl_tmp.msr(MSR_DR) <= interrupt_in.alt_int; ctrl_tmp.msr(MSR_LE) <= '1'; if interrupt_in.scv_int = '0' then ctrl_tmp.msr(MSR_EE) <= '0'; + end if; + if interrupt_in.scv_int = '0' and interrupt_in.hv_intr = '0' then ctrl_tmp.msr(MSR_RI) <= '0'; end if; end if; @@ -2214,7 +2206,6 @@ begin -- update outputs e_out <= ex2.e; - e_out.msr <= msr_copy(ctrl.msr); run_out <= ctrl.run; terminate_out <= ex2.se.terminate; diff --git a/fetch1.vhdl b/fetch1.vhdl index f07188d..bd5ca1a 100644 --- a/fetch1.vhdl +++ b/fetch1.vhdl @@ -391,11 +391,11 @@ begin v_int.next_nia := RESET_ADDRESS; end if; elsif w_in.interrupt = '1' then - v_int.next_nia := 47x"0" & w_in.intr_vec(16 downto 2) & "00"; + v_int.next_nia := w_in.intr_vec(63 downto 2) & "00"; end if; if rst /= '0' or w_in.interrupt = '1' then v.req := '0'; - v.virt_mode := '0'; + v.virt_mode := w_in.alt_intr and not rst; v.priv_mode := '1'; v.big_endian := '0'; v_int.mode_32bit := '0'; diff --git a/scripts/mw_debug/mw_debug.c b/scripts/mw_debug/mw_debug.c index 1a0b96b..06822ec 100644 --- a/scripts/mw_debug/mw_debug.c +++ b/scripts/mw_debug/mw_debug.c @@ -552,7 +552,7 @@ static const char *fast_spr_names[] = "lr", "ctr", "srr0", "srr1", "hsrr0", "hsrr1", "sprg0", "sprg1", "sprg2", "sprg3", "hsprg0", "hsprg1", "xer", "tar", - "fscr", "hfscr", "heir", "cfar", + "fscr", "lpcr", "heir", "cfar", }; static const char *ldst_spr_names[] = { diff --git a/writeback.vhdl b/writeback.vhdl index d7690a5..49a53cc 100644 --- a/writeback.vhdl +++ b/writeback.vhdl @@ -75,6 +75,7 @@ begin variable hvi : std_ulogic; variable scv : std_ulogic; variable intr_page : std_ulogic_vector(4 downto 0); + variable intr_seg : std_ulogic_vector(1 downto 0); begin w_out <= WritebackToRegisterFileInit; c_out <= WritebackToCrFileInit; @@ -98,6 +99,10 @@ begin srr1 := (others => '0'); intr_page := 5x"0"; + if e_in.alt_intr = '1' then + intr_page := 5x"4"; + end if; + intr_seg := e_in.alt_intr & e_in.alt_intr; scv := '0'; if e_in.interrupt = '1' then vec := e_in.intr_vec; @@ -105,7 +110,11 @@ begin hvi := e_in.hv_intr; scv := e_in.is_scv; if e_in.is_scv = '1' then - intr_page := 5x"17"; + if e_in.alt_intr = '0' then + intr_page := 5x"17"; + else + intr_page := 5x"3"; + end if; end if; elsif l_in.interrupt = '1' then vec := l_in.intr_vec; @@ -117,6 +126,7 @@ begin interrupt_out.hv_intr <= hvi; interrupt_out.srr1 <= srr1; interrupt_out.scv_int <= scv; + interrupt_out.alt_int <= e_in.alt_intr; if intr = '0' then if e_in.write_enable = '1' then @@ -174,7 +184,8 @@ begin -- Outputs to fetch1 f.interrupt := intr; - f.intr_vec := intr_page & std_ulogic_vector(to_unsigned(vec, 12)); + f.alt_intr := e_in.alt_intr; + f.intr_vec := intr_seg & 45x"0" & intr_page & std_ulogic_vector(to_unsigned(vec, 12)); f.redirect := e_in.redirect; f.redirect_nia := e_in.write_data; f.br_nia := e_in.last_nia;