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