1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-01-11 23:43:15 +00:00

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>
This commit is contained in:
Paul Mackerras 2025-09-25 09:01:19 +10:00
parent 1d758f1d74
commit 9c40ddffd2
2 changed files with 11 additions and 5 deletions

View File

@ -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'));

View File

@ -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);