From 9c40ddffd2ccf541ed028de890a2a62c23d1e171 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 25 Sep 2025 09:01:19 +1000 Subject: [PATCH] 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 --- common.vhdl | 4 +++- execute1.vhdl | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/common.vhdl b/common.vhdl index ec38dfb..91f9ebd 100644 --- a/common.vhdl +++ b/common.vhdl @@ -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')); diff --git a/execute1.vhdl b/execute1.vhdl index 5d0f602..7046d16 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -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);