execute1: Implement LPCR[EVIRT] bit

This implements the EVIRT bit in the LPCR register.  When set to 1,
EVIRT causes mfspr and mtspr to an undefined SPR number in privileged
mode (i.e. hypervisor mode) to cause a hypervisor emulation assistance
interrupt.  When set to 0, such instructions are executed as no-ops.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/452/head
Paul Mackerras 3 weeks ago
parent 1d758f1d74
commit 9c40ddffd2

@ -249,6 +249,7 @@ package common is
-- LPCR bit numbers
constant LPCR_HAIL : integer := 63 - 37;
constant LPCR_UPRT : integer := 63 - 41;
constant LPCR_EVIRT : integer := 63 - 42;
constant LPCR_HR : integer := 63 - 43;
constant LPCR_LD : integer := 63 - 46;
constant LPCR_HEIC : integer := 63 - 59;
@ -322,6 +323,7 @@ package common is
hdexcr_hyp: aspect_bits_t;
hdexcr_enf: aspect_bits_t;
lpcr_hail: std_ulogic;
lpcr_evirt: std_ulogic;
lpcr_ld: std_ulogic;
lpcr_heic: std_ulogic;
lpcr_lpes: std_ulogic;
@ -333,7 +335,7 @@ package common is
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_hail => '0', lpcr_evirt => '0', lpcr_ld => '1', lpcr_heic => '0',
lpcr_lpes => '0', lpcr_hvice => '0',
others => (others => '0'));


@ -425,6 +425,7 @@ architecture behaviour of execute1 is
begin
ret := (others => '0');
ret(LPCR_HAIL) := c.lpcr_hail;
ret(LPCR_EVIRT) := c.lpcr_evirt;
ret(LPCR_UPRT) := '1';
ret(LPCR_HR) := '1';
ret(LPCR_LD) := c.lpcr_ld;
@ -1450,14 +1451,15 @@ begin
end if;
else
-- mfspr from unimplemented SPRs should be a nop in
-- supervisor mode and a program interrupt for user mode
-- supervisor mode and a program or HEAI interrupt for user mode
-- LPCR[EVIRT] = 1 makes it HEAI in privileged mode
if e_in.valid = '1' and not is_X(e_in.insn) then
report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
" invalid";
end if;
slow_op := '1';
v.e.write_enable := '0';
if ex1.msr(MSR_PR) = '1' then
if ex1.msr(MSR_PR) = '1' or ctrl.lpcr_evirt = '1' then
illegal := '1';
end if;
end if;
@ -1544,8 +1546,9 @@ begin
end if;
if e_in.spr_select.valid = '0' and e_in.spr_is_ram = '0' then
-- mtspr to unimplemented SPRs should be a nop in
-- supervisor mode and a program interrupt for user mode
if ex1.msr(MSR_PR) = '1' then
-- supervisor mode and a program interrupt or HEAI for user mode
-- LPCR[EVIRT] = 1 makes it HEAI in privileged mode
if ex1.msr(MSR_PR) = '1' or ctrl.lpcr_evirt = '1' then
illegal := '1';
end if;
end if;
@ -2185,6 +2188,7 @@ begin
end if;
if ex1.se.write_lpcr = '1' then
ctrl_tmp.lpcr_hail <= ex1.spr_write_data(LPCR_HAIL);
ctrl_tmp.lpcr_evirt <= ex1.spr_write_data(LPCR_EVIRT);
ctrl_tmp.lpcr_ld <= ex1.spr_write_data(LPCR_LD);
ctrl_tmp.lpcr_heic <= ex1.spr_write_data(LPCR_HEIC);
ctrl_tmp.lpcr_lpes <= ex1.spr_write_data(LPCR_LPES);

Loading…
Cancel
Save