From 5548a5ba267f4a56fe8b0067c59b20a2e66bbfbd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 25 Sep 2025 22:37:47 +1000 Subject: [PATCH] execute1: Make mfspr/mtspr to SPRs 0,4,5,6 generate HEAI The ISA specifies that mfspr or mtspr to SPR 0, 4, 5 or 6 should generate a hypervisor emulation assistance interrupt in privileged mode, so this adds logic to do that. Signed-off-by: Paul Mackerras --- execute1.vhdl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/execute1.vhdl b/execute1.vhdl index 7046d16..9f7acaa 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -1216,6 +1216,7 @@ begin variable owait : std_ulogic; variable srr1 : std_ulogic_vector(63 downto 0); variable c32, c64 : std_ulogic; + variable sprnum : spr_num_t; begin v := actions_type_init; v.e.write_data := alu_result; @@ -1424,14 +1425,15 @@ begin when OP_DARN => when OP_MFMSR => when OP_MFSPR => + sprnum := decode_spr_num(e_in.insn); if e_in.spr_is_ram = '1' then 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)) & + report "MFSPR to SPR " & integer'image(sprnum) & "=" & to_hstring(alu_result); end if; elsif e_in.spr_select.valid = '1' and e_in.spr_select.wonly = '0' then if e_in.valid = '1' and not is_X(e_in.insn) then - report "MFSPR to slow SPR " & integer'image(decode_spr_num(e_in.insn)); + report "MFSPR to slow SPR " & integer'image(sprnum); end if; slow_op := '1'; if e_in.spr_select.noop = '1' then @@ -1454,12 +1456,12 @@ begin -- 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"; + report "MFSPR to SPR " & integer'image(sprnum) & " invalid"; end if; slow_op := '1'; v.e.write_enable := '0'; - if ex1.msr(MSR_PR) = '1' or ctrl.lpcr_evirt = '1' then + if ex1.msr(MSR_PR) = '1' or ctrl.lpcr_evirt = '1' or + sprnum = 0 or sprnum = 4 or sprnum = 5 or sprnum = 6 then illegal := '1'; end if; end if; @@ -1505,8 +1507,9 @@ begin end if; end if; when OP_MTSPR => + sprnum := decode_spr_num(e_in.insn); if e_in.valid = '1' and not is_X(e_in.insn) then - report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & + report "MTSPR to SPR " & integer'image(sprnum) & "=" & to_hstring(c_in); end if; v.se.write_pmuspr := e_in.spr_select.ispmu; @@ -1548,7 +1551,8 @@ begin -- mtspr to unimplemented SPRs should be a nop in -- 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 + if ex1.msr(MSR_PR) = '1' or ctrl.lpcr_evirt = '1' or + sprnum = 0 or sprnum = 4 or sprnum = 5 or sprnum = 6 then illegal := '1'; end if; end if;