mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-03-10 20:34:07 +00:00
Merge pull request #443 from paulusmack/compliance
More architecture compliance improvements: LPCR, [U]SIER[23], [U]MMCR3, HMER, HMEER. Remove HFSCR and associated logic.
This commit is contained in:
65
common.vhdl
65
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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
13
decode1.vhdl
13
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;
|
||||
|
||||
145
execute1.vhdl
145
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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user