Merge pull request #443 from paulusmack/compliance

More architecture compliance improvements: LPCR, [U]SIER[23], [U]MMCR3,
HMER, HMEER. Remove HFSCR and associated logic.
pull/430/merge
Paul Mackerras 1 week ago committed by GitHub
commit b14dd43ce6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -56,6 +56,7 @@ package common is
constant SPR_HSPRG1 : spr_num_t := 305; constant SPR_HSPRG1 : spr_num_t := 305;
constant SPR_PID : spr_num_t := 48; constant SPR_PID : spr_num_t := 48;
constant SPR_PTCR : spr_num_t := 464; constant SPR_PTCR : spr_num_t := 464;
constant SPR_LPCR : spr_num_t := 318;
constant SPR_PVR : spr_num_t := 287; constant SPR_PVR : spr_num_t := 287;
constant SPR_FSCR : spr_num_t := 153; constant SPR_FSCR : spr_num_t := 153;
constant SPR_HFSCR : spr_num_t := 190; constant SPR_HFSCR : spr_num_t := 190;
@ -81,6 +82,8 @@ package common is
constant SPR_NOOP1 : spr_num_t := 809; constant SPR_NOOP1 : spr_num_t := 809;
constant SPR_NOOP2 : spr_num_t := 810; constant SPR_NOOP2 : spr_num_t := 810;
constant SPR_NOOP3 : spr_num_t := 811; constant SPR_NOOP3 : spr_num_t := 811;
constant SPR_HMER : spr_num_t := 336;
constant SPR_HMEER : spr_num_t := 337;


-- PMU registers -- PMU registers
constant SPR_UPMC1 : spr_num_t := 771; constant SPR_UPMC1 : spr_num_t := 771;
@ -96,6 +99,9 @@ package common is
constant SPR_USIER : spr_num_t := 768; constant SPR_USIER : spr_num_t := 768;
constant SPR_USIAR : spr_num_t := 780; constant SPR_USIAR : spr_num_t := 780;
constant SPR_USDAR : spr_num_t := 781; 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_PMC1 : spr_num_t := 787;
constant SPR_PMC2 : spr_num_t := 788; constant SPR_PMC2 : spr_num_t := 788;
constant SPR_PMC3 : spr_num_t := 789; constant SPR_PMC3 : spr_num_t := 789;
@ -109,6 +115,9 @@ package common is
constant SPR_SIER : spr_num_t := 784; constant SPR_SIER : spr_num_t := 784;
constant SPR_SIAR : spr_num_t := 796; constant SPR_SIAR : spr_num_t := 796;
constant SPR_SDAR : spr_num_t := 797; 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) -- GPR indices in the register file (GPR only)
subtype gpr_index_t is std_ulogic_vector(4 downto 0); subtype gpr_index_t is std_ulogic_vector(4 downto 0);
@ -181,15 +190,15 @@ package common is
end record; end record;
constant spr_id_init : spr_id := (sel => "0000", others => '0'); constant spr_id_init : spr_id := (sel => "0000", others => '0');


constant SPRSEL_TB : spr_selector := 4x"0"; constant SPRSEL_ZERO : spr_selector := 4x"0";
constant SPRSEL_TBU : spr_selector := 4x"1"; constant SPRSEL_TB : spr_selector := 4x"1";
constant SPRSEL_DEC : spr_selector := 4x"2"; constant SPRSEL_TBU : spr_selector := 4x"2";
constant SPRSEL_PVR : spr_selector := 4x"3"; constant SPRSEL_DEC : spr_selector := 4x"3";
constant SPRSEL_LOGA : spr_selector := 4x"4"; constant SPRSEL_PVR : spr_selector := 4x"4";
constant SPRSEL_LOGD : spr_selector := 4x"5"; constant SPRSEL_LOGR : spr_selector := 4x"5";
constant SPRSEL_CFAR : spr_selector := 4x"6"; constant SPRSEL_CFAR : spr_selector := 4x"6";
constant SPRSEL_FSCR : spr_selector := 4x"7"; 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_HEIR : spr_selector := 4x"9";
constant SPRSEL_CTRL : spr_selector := 4x"a"; constant SPRSEL_CTRL : spr_selector := 4x"a";
constant SPRSEL_DSCR : spr_selector := 4x"b"; constant SPRSEL_DSCR : spr_selector := 4x"b";
@ -198,17 +207,11 @@ package common is
constant SPRSEL_DEXCR : spr_selector := 4x"e"; constant SPRSEL_DEXCR : spr_selector := 4x"e";
constant SPRSEL_XER : spr_selector := 4x"f"; constant SPRSEL_XER : spr_selector := 4x"f";


-- FSCR and HFSCR bit numbers -- FSCR bit numbers
constant FSCR_PREFIX : integer := 63 - 50; constant FSCR_PREFIX : integer := 63 - 50;
constant FSCR_SCV : integer := 63 - 51; constant FSCR_SCV : integer := 63 - 51;
constant FSCR_TAR : integer := 63 - 55; constant FSCR_TAR : integer := 63 - 55;
constant FSCR_DSCR : integer := 63 - 61; 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 -- FPSCR bit numbers
constant FPSCR_FX : integer := 63 - 32; constant FPSCR_FX : integer := 63 - 32;
@ -242,6 +245,15 @@ package common is
constant FPSCR_NI : integer := 63 - 61; constant FPSCR_NI : integer := 63 - 61;
constant FPSCR_RN : integer := 63 - 63; 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 addresses
-- REAL_ADDR_BITS is the number of real address bits that we store -- REAL_ADDR_BITS is the number of real address bits that we store
constant REAL_ADDR_BITS : positive := 56; constant REAL_ADDR_BITS : positive := 56;
@ -301,11 +313,6 @@ package common is
fscr_scv: std_ulogic; fscr_scv: std_ulogic;
fscr_tar: std_ulogic; fscr_tar: std_ulogic;
fscr_dscr: 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); heir: std_ulogic_vector(63 downto 0);
dscr: std_ulogic_vector(24 downto 0); dscr: std_ulogic_vector(24 downto 0);
ciabr: std_ulogic_vector(63 downto 0); ciabr: std_ulogic_vector(63 downto 0);
@ -313,14 +320,20 @@ package common is
dexcr_pro: aspect_bits_t; dexcr_pro: aspect_bits_t;
hdexcr_hyp: aspect_bits_t; hdexcr_hyp: aspect_bits_t;
hdexcr_enf: 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; end record;
constant ctrl_t_init : ctrl_t := constant ctrl_t_init : ctrl_t :=
(wait_state => '0', run => '1', xer_low => 18x"0", (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', 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'), dscr => (others => '0'),
dexcr_pnh => aspect_bits_init, dexcr_pro => aspect_bits_init, dexcr_pnh => aspect_bits_init, dexcr_pro => aspect_bits_init,
hdexcr_hyp => aspect_bits_init, hdexcr_enf => 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')); others => (others => '0'));


type timebase_ctrl is record type timebase_ctrl is record
@ -792,6 +805,7 @@ package common is
write_xerc_enable : std_ulogic; write_xerc_enable : std_ulogic;
xerc : xer_common_t; xerc : xer_common_t;
interrupt : std_ulogic; interrupt : std_ulogic;
alt_intr : std_ulogic;
hv_intr : std_ulogic; hv_intr : std_ulogic;
is_scv : std_ulogic; is_scv : std_ulogic;
intr_vec : intr_vector_t; intr_vec : intr_vector_t;
@ -802,7 +816,6 @@ package common is
br_taken: std_ulogic; br_taken: std_ulogic;
abs_br: std_ulogic; abs_br: std_ulogic;
srr1: std_ulogic_vector(15 downto 0); srr1: std_ulogic_vector(15 downto 0);
msr: std_ulogic_vector(63 downto 0);
end record; end record;
constant Execute1ToWritebackInit : Execute1ToWritebackType := constant Execute1ToWritebackInit : Execute1ToWritebackType :=
(valid => '0', instr_tag => instr_tag_init, rc => '0', mode_32bit => '0', (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_xerc_enable => '0', xerc => xerc_init,
write_data => (others => '0'), write_cr_mask => (others => '0'), write_data => (others => '0'), write_cr_mask => (others => '0'),
write_cr_data => (others => '0'), write_reg => (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", redirect => '0', redir_mode => "0000",
last_nia => (others => '0'), last_nia => (others => '0'),
br_last => '0', br_taken => '0', abs_br => '0', br_last => '0', br_taken => '0', abs_br => '0',
srr1 => (others => '0'), msr => (others => '0')); srr1 => (others => '0'));


type Execute1ToFPUType is record type Execute1ToFPUType is record
valid : std_ulogic; valid : std_ulogic;
@ -899,13 +912,14 @@ package common is
br_last : std_ulogic; br_last : std_ulogic;
br_taken : std_ulogic; br_taken : std_ulogic;
interrupt : 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; end record;
constant WritebackToFetch1Init : WritebackToFetch1Type := constant WritebackToFetch1Init : WritebackToFetch1Type :=
(redirect => '0', virt_mode => '0', priv_mode => '0', big_endian => '0', (redirect => '0', virt_mode => '0', priv_mode => '0', big_endian => '0',
mode_32bit => '0', redirect_nia => (others => '0'), mode_32bit => '0', redirect_nia => (others => '0'),
br_last => '0', br_taken => '0', br_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 type WritebackToRegisterFileType is record
write_reg : gspr_index_t; write_reg : gspr_index_t;
@ -931,6 +945,7 @@ package common is
intr : std_ulogic; intr : std_ulogic;
hv_intr : std_ulogic; hv_intr : std_ulogic;
scv_int : std_ulogic; scv_int : std_ulogic;
alt_int : std_ulogic;
srr1 : std_ulogic_vector(15 downto 0); srr1 : std_ulogic_vector(15 downto 0);
end record; end record;



@ -329,7 +329,7 @@ begin
sel := SPRSEL_FSCR; sel := SPRSEL_FSCR;
when 5x"0f" => when 5x"0f" =>
isram := '0'; isram := '0';
sel := SPRSEL_HFSCR; sel := SPRSEL_LPCR;
when 5x"10" => when 5x"10" =>
isram := '0'; isram := '0';
sel := SPRSEL_HEIR; sel := SPRSEL_HEIR;

@ -476,22 +476,25 @@ architecture behaviour of decode1 is
when SPR_PVR => when SPR_PVR =>
i.sel := SPRSEL_PVR; i.sel := SPRSEL_PVR;
when 724 => -- LOG_ADDR SPR when 724 => -- LOG_ADDR SPR
i.sel := SPRSEL_LOGA; i.sel := SPRSEL_LOGR;
when 725 => -- LOG_DATA SPR 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 | 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_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_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 => SPR_MMCR0 | SPR_MMCR1 | SPR_MMCR2 | SPR_MMCRA | SPR_SIER | SPR_SIAR | SPR_SDAR =>
i.ispmu := '1'; i.ispmu := '1';
when SPR_USIER2 | SPR_USIER3 | SPR_UMMCR3 | SPR_SIER2 | SPR_SIER3 | SPR_MMCR3 =>
i.sel := SPRSEL_ZERO;
when SPR_CFAR => when SPR_CFAR =>
i.sel := SPRSEL_CFAR; i.sel := SPRSEL_CFAR;
when SPR_XER => when SPR_XER =>
i.sel := SPRSEL_XER; i.sel := SPRSEL_XER;
when SPR_FSCR => when SPR_FSCR =>
i.sel := SPRSEL_FSCR; i.sel := SPRSEL_FSCR;
when SPR_HFSCR => when SPR_LPCR =>
i.sel := SPRSEL_HFSCR; i.sel := SPRSEL_LPCR;
when SPR_HEIR => when SPR_HEIR =>
i.sel := SPRSEL_HEIR; i.sel := SPRSEL_HEIR;
when SPR_CTRL => when SPR_CTRL =>
@ -515,6 +518,8 @@ architecture behaviour of decode1 is
i.ronly := '1'; i.ronly := '1';
when SPR_NOOP0 | SPR_NOOP1 | SPR_NOOP2 | SPR_NOOP3 => when SPR_NOOP0 | SPR_NOOP1 | SPR_NOOP2 | SPR_NOOP3 =>
i.noop := '1'; i.noop := '1';
when SPR_HMER | SPR_HMEER =>
i.sel := SPRSEL_ZERO;
when others => when others =>
i.valid := '0'; i.valid := '0';
end case; end case;

@ -92,8 +92,7 @@ architecture behaviour of execute1 is
mult_32s : std_ulogic; mult_32s : std_ulogic;
write_fscr : std_ulogic; write_fscr : std_ulogic;
write_ic : std_ulogic; write_ic : std_ulogic;
write_hfscr : std_ulogic; write_lpcr : std_ulogic;
write_hic : std_ulogic;
write_heir : std_ulogic; write_heir : std_ulogic;
set_heir : std_ulogic; set_heir : std_ulogic;
write_ctrl : std_ulogic; write_ctrl : std_ulogic;
@ -212,6 +211,7 @@ architecture behaviour of execute1 is
signal valid_in : std_ulogic; signal valid_in : std_ulogic;
signal ctrl: ctrl_t := ctrl_t_init; signal ctrl: ctrl_t := ctrl_t_init;
signal ctrl_tmp: 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_result: std_ulogic_vector(63 downto 0);
signal rotator_carry: std_ulogic; signal rotator_carry: std_ulogic;
signal logical_result: std_ulogic_vector(63 downto 0); 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 spr_result: std_ulogic_vector(63 downto 0);
signal next_nia : 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 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_32 : std_ulogic;
signal carry_64 : std_ulogic; signal carry_64 : std_ulogic;
@ -410,15 +411,17 @@ architecture behaviour of execute1 is
return ret; return ret;
end; 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); variable ret : std_ulogic_vector(63 downto 0);
begin begin
ret := (others => '0'); ret := (others => '0');
ret(59 downto 56) := c.hfscr_ic; ret(LPCR_HAIL) := c.lpcr_hail;
ret(HFSCR_PREFIX) := c.hfscr_pref; ret(LPCR_UPRT) := '1';
ret(HFSCR_TAR) := c.hfscr_tar; ret(LPCR_HR) := '1';
ret(HFSCR_DSCR) := c.hfscr_dscr; ret(LPCR_LD) := c.lpcr_ld;
ret(HFSCR_FP) := c.hfscr_fp; ret(LPCR_HEIC) := c.lpcr_heic;
ret(LPCR_LPES) := c.lpcr_lpes;
ret(LPCR_HVICE) := c.lpcr_hvice;
return ret; return ret;
end; end;


@ -457,6 +460,15 @@ architecture behaviour of execute1 is
return ret; return ret;
end; 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 -- Tell vivado to keep the hierarchy for the random module so that the
-- net names in the xdc file match. -- net names in the xdc file match.
attribute keep_hierarchy : string; attribute keep_hierarchy : string;
@ -596,6 +608,8 @@ begin
tb_next <= thi & tlo; tb_next <= thi & tlo;
end process; end process;


dec_sign <= (ctrl.dec(63) and ctrl.lpcr_ld) or (ctrl.dec(31) and not ctrl.lpcr_ld);

dbg_ctrl_out <= ctrl; dbg_ctrl_out <= ctrl;
log_rd_addr <= ex2.log_addr_spr; log_rd_addr <= ex2.log_addr_spr;


@ -796,8 +810,8 @@ begin
case dbg_spr_addr(3 downto 0) is case dbg_spr_addr(3 downto 0) is
when SPRSEL_FSCR => when SPRSEL_FSCR =>
dbg_spr_data <= assemble_fscr(ctrl); dbg_spr_data <= assemble_fscr(ctrl);
when SPRSEL_HFSCR => when SPRSEL_LPCR =>
dbg_spr_data <= assemble_hfscr(ctrl); dbg_spr_data <= assemble_lpcr(ctrl);
when SPRSEL_HEIR => when SPRSEL_HEIR =>
dbg_spr_data <= ctrl.heir; dbg_spr_data <= ctrl.heir;
when SPRSEL_CFAR => when SPRSEL_CFAR =>
@ -1189,6 +1203,7 @@ begin
v.e.redir_mode := ex1.msr(MSR_IR) & not ex1.msr(MSR_PR) & v.e.redir_mode := ex1.msr(MSR_IR) & not ex1.msr(MSR_PR) &
not ex1.msr(MSR_LE) & not ex1.msr(MSR_SF); not ex1.msr(MSR_LE) & not ex1.msr(MSR_SF);
v.e.intr_vec := 16#700#; 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.mode_32bit := not ex1.msr(MSR_SF);
v.e.instr_tag := e_in.instr_tag; v.e.instr_tag := e_in.instr_tag;
v.e.last_nia := e_in.nia; v.e.last_nia := e_in.nia;
@ -1387,8 +1402,10 @@ begin
slow_op := '1'; slow_op := '1';
if e_in.spr_select.ispmu = '0' then if e_in.spr_select.ispmu = '0' then
case e_in.spr_select.sel is case e_in.spr_select.sel is
when SPRSEL_LOGD => when SPRSEL_LOGR =>
v.se.inc_loga := '1'; if e_in.insn(16) = '0' then
v.se.inc_loga := '1';
end if;
when others => when others =>
end case; end case;
v.res2_sel := "10"; v.res2_sel := "10";
@ -1451,14 +1468,14 @@ begin
v.se.write_xerlow := '1'; v.se.write_xerlow := '1';
when SPRSEL_DEC => when SPRSEL_DEC =>
v.se.write_dec := '1'; v.se.write_dec := '1';
when SPRSEL_LOGA => when SPRSEL_LOGR =>
v.se.write_loga := '1'; v.se.write_loga := '1';
when SPRSEL_CFAR => when SPRSEL_CFAR =>
v.se.write_cfar := '1'; v.se.write_cfar := '1';
when SPRSEL_FSCR => when SPRSEL_FSCR =>
v.se.write_fscr := '1'; v.se.write_fscr := '1';
when SPRSEL_HFSCR => when SPRSEL_LPCR =>
v.se.write_hfscr := '1'; v.se.write_lpcr := '1';
when SPRSEL_HEIR => when SPRSEL_HEIR =>
v.se.write_heir := '1'; v.se.write_heir := '1';
when SPRSEL_CTRL => when SPRSEL_CTRL =>
@ -1548,22 +1565,15 @@ begin
end case; end case;


if ex1.msr(MSR_PR) = '1' and e_in.prefixed = '1' and if ex1.msr(MSR_PR) = '1' and e_in.prefixed = '1' and
(ctrl.hfscr_pref = '0' or ctrl.fscr_pref = '0') then ctrl.fscr_pref = '0' then
-- [Hypervisor] facility unavailable for prefixed instructions, -- Facility unavailable for prefixed instructions,
-- which has higher priority than the alignment interrupt for -- which has higher priority than the alignment interrupt for
-- misaligned prefixed instructions, which has higher priority than -- misaligned prefixed instructions, which has higher priority than
-- other [hypervisor] facility unavailable interrupts (e.g. for -- other facility unavailable interrupts.
-- plfs with HFSCR[FP] = 0).
v.exception := '1'; v.exception := '1';
v.ic := x"b"; v.ic := x"b";
if ctrl.hfscr_pref = '0' then v.e.intr_vec := 16#f60#;
v.e.hv_intr := '1'; v.se.write_ic := '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 misaligned = '1' then elsif misaligned = '1' then
-- generate an alignment interrupt -- generate an alignment interrupt
@ -1608,41 +1618,20 @@ begin
v.se.write_ic := '1'; v.se.write_ic := '1';


elsif ex1.msr(MSR_PR) = '1' and e_in.uses_tar = '1' and elsif ex1.msr(MSR_PR) = '1' and e_in.uses_tar = '1' and
(ctrl.hfscr_tar = '0' or ctrl.fscr_tar = '0') then ctrl.fscr_tar = '0' then
-- [Hypervisor] facility unavailable for TAR access -- Facility unavailable for TAR access
v.exception := '1'; v.exception := '1';
v.ic := x"8"; v.ic := x"8";
if ctrl.hfscr_tar = '0' then v.e.intr_vec := 16#f60#;
v.e.hv_intr := '1'; v.se.write_ic := '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 ex1.msr(MSR_PR) = '1' and e_in.uses_dscr = '1' and elsif ex1.msr(MSR_PR) = '1' and e_in.uses_dscr = '1' and
(ctrl.hfscr_dscr = '0' or ctrl.fscr_dscr = '0') then ctrl.fscr_dscr = '0' then
-- [Hypervisor] facility unavailable for DSCR access -- Facility unavailable for DSCR access
v.exception := '1'; v.exception := '1';
v.ic := x"2"; v.ic := x"2";
if ctrl.hfscr_dscr = '0' then v.e.intr_vec := 16#f60#;
v.e.hv_intr := '1'; v.se.write_ic := '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';


elsif HAS_FPU and ex1.msr(MSR_FP) = '0' and e_in.fac = FPU then elsif HAS_FPU and ex1.msr(MSR_FP) = '0' and e_in.fac = FPU then
-- generate a floating-point unavailable interrupt -- generate a floating-point unavailable interrupt
@ -1705,7 +1694,8 @@ begin
v.busy := '0'; v.busy := '0';
bypass_valid := actions.bypass_valid; 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 if valid_in = '1' then
v.prev_op := e_in.insn_type; v.prev_op := e_in.insn_type;
@ -1747,14 +1737,14 @@ begin
if pmu_to_x.intr = '1' then if pmu_to_x.intr = '1' then
v.e.intr_vec := 16#f00#; v.e.intr_vec := 16#f00#;
report "IRQ valid: PMU"; report "IRQ valid: PMU";
elsif ctrl.dec(63) = '1' then elsif dec_sign = '1' then
v.e.intr_vec := 16#900#; v.e.intr_vec := 16#900#;
report "IRQ valid: DEC"; report "IRQ valid: DEC";
elsif ext_irq_in = '1' then elsif ext_irq_in = '1' then
v.e.intr_vec := 16#500#; v.e.intr_vec := 16#500#;
report "IRQ valid: External"; report "IRQ valid: External";
v.ext_interrupt := '1'; v.ext_interrupt := '1';
v.e.hv_intr := '1'; v.e.hv_intr := not ctrl.lpcr_lpes;
end if; end if;
v.e.srr1 := (others => '0'); v.e.srr1 := (others => '0');
exception := '1'; exception := '1';
@ -1968,23 +1958,25 @@ begin
end process; end process;


-- Slow SPR read mux -- 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 <= with ex1.spr_select.sel select spr_result <=
timebase when SPRSEL_TB, timebase when SPRSEL_TB,
32x"0" & timebase(63 downto 32) when SPRSEL_TBU, 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, 32x"0" & PVR_MICROWATT when SPRSEL_PVR,
log_wr_addr & ex2.log_addr_spr when SPRSEL_LOGA, log_spr_data when SPRSEL_LOGR,
log_rd_data when SPRSEL_LOGD,
ctrl.cfar when SPRSEL_CFAR, ctrl.cfar when SPRSEL_CFAR,
assemble_fscr(ctrl) when SPRSEL_FSCR, assemble_fscr(ctrl) when SPRSEL_FSCR,
assemble_hfscr(ctrl) when SPRSEL_HFSCR, assemble_lpcr(ctrl) when SPRSEL_LPCR,
ctrl.heir when SPRSEL_HEIR, ctrl.heir when SPRSEL_HEIR,
assemble_ctrl(ctrl, ex1.msr(MSR_PR)) when SPRSEL_CTRL, assemble_ctrl(ctrl, ex1.msr(MSR_PR)) when SPRSEL_CTRL,
39x"0" & ctrl.dscr when SPRSEL_DSCR, 39x"0" & ctrl.dscr when SPRSEL_DSCR,
56x"0" & std_ulogic_vector(to_unsigned(CPU_INDEX, 8)) when SPRSEL_PIR, 56x"0" & std_ulogic_vector(to_unsigned(CPU_INDEX, 8)) when SPRSEL_PIR,
ctrl.ciabr when SPRSEL_CIABR, ctrl.ciabr when SPRSEL_CIABR,
assemble_dexcr(ctrl, ex1.insn) when SPRSEL_DEXCR, 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; 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); v.log_addr_spr := std_ulogic_vector(unsigned(ex2.log_addr_spr) + 1);
end if; end if;
x_to_pmu.mtspr <= ex1.se.write_pmuspr; 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 if ex1.se.write_fscr = '1' then
ctrl_tmp.fscr_ic <= ex1.e.write_data(59 downto 56); ctrl_tmp.fscr_ic <= ex1.e.write_data(59 downto 56);
ctrl_tmp.fscr_pref <= ex1.e.write_data(FSCR_PREFIX); ctrl_tmp.fscr_pref <= ex1.e.write_data(FSCR_PREFIX);
@ -2145,6 +2128,13 @@ begin
elsif ex1.se.write_ic = '1' then elsif ex1.se.write_ic = '1' then
ctrl_tmp.fscr_ic <= ex1.ic; ctrl_tmp.fscr_ic <= ex1.ic;
end if; 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 if ex1.se.write_heir = '1' then
ctrl_tmp.heir <= ex1.e.write_data; ctrl_tmp.heir <= ex1.e.write_data;
elsif ex1.se.set_heir = '1' then elsif ex1.se.set_heir = '1' then
@ -2173,7 +2163,7 @@ begin
-- pending exceptions clear any wait state -- pending exceptions clear any wait state
-- ex1.fp_exception_next is not tested because it is not possible to -- ex1.fp_exception_next is not tested because it is not possible to
-- get into wait state with a pending FP exception. -- 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 if ex1.trace_next = '1' or irq_exc = '1' or interrupt_in.intr = '1' then
ctrl_tmp.wait_state <= '0'; ctrl_tmp.wait_state <= '0';
end if; end if;
@ -2186,11 +2176,13 @@ begin
ctrl_tmp.msr(MSR_FP) <= '0'; ctrl_tmp.msr(MSR_FP) <= '0';
ctrl_tmp.msr(MSR_FE0) <= '0'; ctrl_tmp.msr(MSR_FE0) <= '0';
ctrl_tmp.msr(MSR_FE1) <= '0'; ctrl_tmp.msr(MSR_FE1) <= '0';
ctrl_tmp.msr(MSR_IR) <= '0'; ctrl_tmp.msr(MSR_IR) <= interrupt_in.alt_int;
ctrl_tmp.msr(MSR_DR) <= '0'; ctrl_tmp.msr(MSR_DR) <= interrupt_in.alt_int;
ctrl_tmp.msr(MSR_LE) <= '1'; ctrl_tmp.msr(MSR_LE) <= '1';
if interrupt_in.scv_int = '0' then if interrupt_in.scv_int = '0' then
ctrl_tmp.msr(MSR_EE) <= '0'; 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'; ctrl_tmp.msr(MSR_RI) <= '0';
end if; end if;
end if; end if;
@ -2214,7 +2206,6 @@ begin


-- update outputs -- update outputs
e_out <= ex2.e; e_out <= ex2.e;
e_out.msr <= msr_copy(ctrl.msr);


run_out <= ctrl.run; run_out <= ctrl.run;
terminate_out <= ex2.se.terminate; terminate_out <= ex2.se.terminate;

@ -391,11 +391,11 @@ begin
v_int.next_nia := RESET_ADDRESS; v_int.next_nia := RESET_ADDRESS;
end if; end if;
elsif w_in.interrupt = '1' then 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; end if;
if rst /= '0' or w_in.interrupt = '1' then if rst /= '0' or w_in.interrupt = '1' then
v.req := '0'; v.req := '0';
v.virt_mode := '0'; v.virt_mode := w_in.alt_intr and not rst;
v.priv_mode := '1'; v.priv_mode := '1';
v.big_endian := '0'; v.big_endian := '0';
v_int.mode_32bit := '0'; v_int.mode_32bit := '0';

@ -552,7 +552,7 @@ static const char *fast_spr_names[] =
"lr", "ctr", "srr0", "srr1", "hsrr0", "hsrr1", "lr", "ctr", "srr0", "srr1", "hsrr0", "hsrr1",
"sprg0", "sprg1", "sprg2", "sprg3", "sprg0", "sprg1", "sprg2", "sprg3",
"hsprg0", "hsprg1", "xer", "tar", "hsprg0", "hsprg1", "xer", "tar",
"fscr", "hfscr", "heir", "cfar", "fscr", "lpcr", "heir", "cfar",
}; };


static const char *ldst_spr_names[] = { static const char *ldst_spr_names[] = {

@ -75,6 +75,7 @@ begin
variable hvi : std_ulogic; variable hvi : std_ulogic;
variable scv : std_ulogic; variable scv : std_ulogic;
variable intr_page : std_ulogic_vector(4 downto 0); variable intr_page : std_ulogic_vector(4 downto 0);
variable intr_seg : std_ulogic_vector(1 downto 0);
begin begin
w_out <= WritebackToRegisterFileInit; w_out <= WritebackToRegisterFileInit;
c_out <= WritebackToCrFileInit; c_out <= WritebackToCrFileInit;
@ -98,6 +99,10 @@ begin


srr1 := (others => '0'); srr1 := (others => '0');
intr_page := 5x"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'; scv := '0';
if e_in.interrupt = '1' then if e_in.interrupt = '1' then
vec := e_in.intr_vec; vec := e_in.intr_vec;
@ -105,7 +110,11 @@ begin
hvi := e_in.hv_intr; hvi := e_in.hv_intr;
scv := e_in.is_scv; scv := e_in.is_scv;
if e_in.is_scv = '1' then 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; end if;
elsif l_in.interrupt = '1' then elsif l_in.interrupt = '1' then
vec := l_in.intr_vec; vec := l_in.intr_vec;
@ -117,6 +126,7 @@ begin
interrupt_out.hv_intr <= hvi; interrupt_out.hv_intr <= hvi;
interrupt_out.srr1 <= srr1; interrupt_out.srr1 <= srr1;
interrupt_out.scv_int <= scv; interrupt_out.scv_int <= scv;
interrupt_out.alt_int <= e_in.alt_intr;


if intr = '0' then if intr = '0' then
if e_in.write_enable = '1' then if e_in.write_enable = '1' then
@ -174,7 +184,8 @@ begin


-- Outputs to fetch1 -- Outputs to fetch1
f.interrupt := intr; 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 := e_in.redirect;
f.redirect_nia := e_in.write_data; f.redirect_nia := e_in.write_data;
f.br_nia := e_in.last_nia; f.br_nia := e_in.last_nia;

Loading…
Cancel
Save