diff --git a/pythondata_cpu_microwatt/vhdl/common.vhdl b/pythondata_cpu_microwatt/vhdl/common.vhdl index 18378d58570961eada03bcd1b6139aef3f94549f..23f28e6074c4094e1e1f2795ac5adfd41b4272d9 100644 --- a/pythondata_cpu_microwatt/vhdl/common.vhdl +++ b/pythondata_cpu_microwatt/vhdl/common.vhdl @@ -43,6 +43,7 @@ package common is constant SPR_HSPRG1 : spr_num_t := 305; constant SPR_PID : spr_num_t := 48; constant SPR_PRTBL : spr_num_t := 720; + constant SPR_KAIVB : spr_num_t := 850; -- GPR indices in the register file (GPR only) subtype gpr_index_t is std_ulogic_vector(4 downto 0); @@ -96,6 +97,8 @@ package common is dec: std_ulogic_vector(63 downto 0); msr: std_ulogic_vector(63 downto 0); cfar: std_ulogic_vector(63 downto 0); + -- Kestrel arch interrupt vector base: location of the interrupt vector table for kestrel + kaivb: std_ulogic_vector(61 downto 13); irq_state : irq_state_t; srr1: std_ulogic_vector(63 downto 0); end record; diff --git a/pythondata_cpu_microwatt/vhdl/execute1.vhdl b/pythondata_cpu_microwatt/vhdl/execute1.vhdl index a1cd008f0b38ff40fd2033b90ffcba4071472bc1..f9fa01411a1dd835510d030254765e1ae2f1eec0 100644 --- a/pythondata_cpu_microwatt/vhdl/execute1.vhdl +++ b/pythondata_cpu_microwatt/vhdl/execute1.vhdl @@ -437,11 +437,11 @@ begin irq_valid := '0'; if ctrl.msr(MSR_EE) = '1' then if ctrl.dec(63) = '1' then - v.f.redirect_nia := std_logic_vector(to_unsigned(16#900#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"900", others => '0'); report "IRQ valid: DEC"; irq_valid := '1'; elsif ext_irq_in = '1' then - v.f.redirect_nia := std_logic_vector(to_unsigned(16#500#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"500", others => '0'); report "IRQ valid: External"; irq_valid := '1'; end if; @@ -500,7 +500,7 @@ begin instr_is_privileged(e_in.insn_type, e_in.insn) then -- generate a program interrupt exception := '1'; - v.f.redirect_nia := std_logic_vector(to_unsigned(16#700#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"700", others => '0'); -- set bit 45 to indicate privileged instruction type interrupt ctrl_tmp.srr1(63 - 45) <= '1'; report "privileged instruction"; @@ -530,7 +530,7 @@ begin if e_in.insn(1) = '1' then exception := '1'; exception_nextpc := '1'; - v.f.redirect_nia := std_logic_vector(to_unsigned(16#C00#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"C00", others => '0'); report "sc"; else illegal := '1'; @@ -622,7 +622,7 @@ begin if or (trapval and insn_to(e_in.insn)) = '1' then -- generate trap-type program interrupt exception := '1'; - v.f.redirect_nia := std_logic_vector(to_unsigned(16#700#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"700", others => '0'); -- set bit 46 to say trap occurred ctrl_tmp.srr1(63 - 46) <= '1'; report "trap"; @@ -762,6 +762,12 @@ begin when SPR_TBU => spr_val(63 downto 32) := (others => '0'); spr_val(31 downto 0) := ctrl.tb(63 downto 32); + when SPR_KAIVB => + if ctrl.msr(MSR_PR) = '1' then + illegal := '1'; + else + spr_val(61 downto 0) := (61 downto 13 => ctrl.kaivb(61 downto 13), others => '0'); + end if; when SPR_DEC => spr_val := ctrl.dec; when SPR_CFAR => @@ -846,6 +852,12 @@ begin ctrl_tmp.dec <= c_in; when 724 => -- LOG_ADDR SPR v.log_addr_spr := c_in(31 downto 0); + when SPR_KAIVB => + if ctrl.msr(MSR_PR) = '1' then + illegal := '1'; + else + ctrl_tmp.kaivb <= c_in(61 downto 13); + end if; when others => -- mtspr to unimplemented SPRs should be a nop in -- supervisor mode and a program interrupt for user mode @@ -989,7 +1001,7 @@ begin if illegal = '1' then exception := '1'; - v.f.redirect_nia := std_logic_vector(to_unsigned(16#700#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"700", others => '0'); -- Since we aren't doing Hypervisor emulation assist (0xe40) we -- set bit 44 to indicate we have an illegal ctrl_tmp.srr1(63 - 44) <= '1'; @@ -1010,9 +1022,9 @@ begin if l_in.exception = '1' then if l_in.instr_fault = '0' then if l_in.segment_fault = '0' then - v.f.redirect_nia := std_logic_vector(to_unsigned(16#300#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"300", others => '0'); else - v.f.redirect_nia := std_logic_vector(to_unsigned(16#380#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"380", others => '0'); end if; else if l_in.segment_fault = '0' then @@ -1020,9 +1032,9 @@ begin ctrl_tmp.srr1(63 - 35) <= l_in.perm_error; -- noexec fault ctrl_tmp.srr1(63 - 44) <= l_in.badtree; ctrl_tmp.srr1(63 - 45) <= l_in.rc_error; - v.f.redirect_nia := std_logic_vector(to_unsigned(16#400#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"400", others => '0'); else - v.f.redirect_nia := std_logic_vector(to_unsigned(16#480#, 64)); + v.f.redirect_nia := (61 downto 13 => ctrl.kaivb(61 downto 13), 11 downto 0 => x"480", others => '0'); end if; end if; v.e.exc_write_enable := '1';