mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
core: Implement LPCR register
This implements the LPCR (Logical Partition Control Register) with 5 read/write bits. The other 59 bits are read-only; two (HR and UPRT) read as 1 and the rest as 0. The bits that are implemented are: * HAIL - enables taking interrupts with relocation on * LD - enables large decrementer mode * HEIC - disables external interrupts when set * LPES - controls how external interrupts are delivered * HVICE - does nothing at present since there is no source of Hypervisor Virtualization Interrupts. This also fixes a bug where MSR[RI] was getting cleared by the delivery of hypervisor interrupts. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
parent
63fff5e05c
commit
1b6ee631bc
30
common.vhdl
30
common.vhdl
@ -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;
|
||||||
@ -189,6 +190,7 @@ package common is
|
|||||||
constant SPRSEL_LOGD : spr_selector := 4x"5";
|
constant SPRSEL_LOGD : 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_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";
|
||||||
@ -235,6 +237,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,6 +312,11 @@ 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",
|
||||||
@ -308,6 +324,8 @@ package common is
|
|||||||
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
|
||||||
@ -778,6 +796,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;
|
||||||
@ -788,7 +807,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',
|
||||||
@ -796,11 +814,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;
|
||||||
@ -885,13 +903,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;
|
||||||
@ -917,6 +936,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;
|
||||||
|
|
||||||
|
|||||||
@ -327,6 +327,9 @@ begin
|
|||||||
when 5x"0e" =>
|
when 5x"0e" =>
|
||||||
isram := '0';
|
isram := '0';
|
||||||
sel := SPRSEL_FSCR;
|
sel := SPRSEL_FSCR;
|
||||||
|
when 5x"0f" =>
|
||||||
|
isram := '0';
|
||||||
|
sel := SPRSEL_LPCR;
|
||||||
when 5x"10" =>
|
when 5x"10" =>
|
||||||
isram := '0';
|
isram := '0';
|
||||||
sel := SPRSEL_HEIR;
|
sel := SPRSEL_HEIR;
|
||||||
|
|||||||
@ -490,6 +490,8 @@ architecture behaviour of decode1 is
|
|||||||
i.sel := SPRSEL_XER;
|
i.sel := SPRSEL_XER;
|
||||||
when SPR_FSCR =>
|
when SPR_FSCR =>
|
||||||
i.sel := SPRSEL_FSCR;
|
i.sel := SPRSEL_FSCR;
|
||||||
|
when SPR_LPCR =>
|
||||||
|
i.sel := SPRSEL_LPCR;
|
||||||
when SPR_HEIR =>
|
when SPR_HEIR =>
|
||||||
i.sel := SPRSEL_HEIR;
|
i.sel := SPRSEL_HEIR;
|
||||||
when SPR_CTRL =>
|
when SPR_CTRL =>
|
||||||
|
|||||||
@ -92,6 +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_lpcr : 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;
|
||||||
@ -210,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);
|
||||||
@ -408,6 +410,20 @@ architecture behaviour of execute1 is
|
|||||||
return ret;
|
return ret;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function assemble_lpcr(c: ctrl_t) return std_ulogic_vector is
|
||||||
|
variable ret : std_ulogic_vector(63 downto 0);
|
||||||
|
begin
|
||||||
|
ret := (others => '0');
|
||||||
|
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;
|
||||||
|
|
||||||
function assemble_ctrl(c: ctrl_t; msrpr: std_ulogic) return std_ulogic_vector is
|
function assemble_ctrl(c: ctrl_t; msrpr: std_ulogic) return std_ulogic_vector is
|
||||||
variable ret : std_ulogic_vector(63 downto 0);
|
variable ret : std_ulogic_vector(63 downto 0);
|
||||||
begin
|
begin
|
||||||
@ -443,6 +459,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;
|
||||||
@ -582,6 +607,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;
|
||||||
|
|
||||||
@ -782,6 +809,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_LPCR =>
|
||||||
|
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 =>
|
||||||
@ -1173,6 +1202,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;
|
||||||
@ -1441,6 +1471,8 @@ begin
|
|||||||
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_LPCR =>
|
||||||
|
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 =>
|
||||||
@ -1659,7 +1691,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;
|
||||||
@ -1701,14 +1734,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';
|
||||||
@ -1925,12 +1958,13 @@ begin
|
|||||||
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_wr_addr & ex2.log_addr_spr when SPRSEL_LOGA,
|
||||||
log_rd_data when SPRSEL_LOGD,
|
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_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,
|
||||||
@ -2089,6 +2123,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
|
||||||
@ -2117,7 +2158,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;
|
||||||
@ -2130,11 +2171,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;
|
||||||
@ -2158,7 +2201,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", "unused", "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…
x
Reference in New Issue
Block a user