1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-02-18 13:27:06 +00:00

execute1: Generate privileged instruction interrupts when MSR[PR] = 1

This adds logic to execute1 to check, when MSR[PR] = 1, whether each
instruction arriving to be executed is a privileged instruction.
If it is, a privileged-instruction type program interrupt is generated.
For the mtspr and mfspr instructions, we need to look at bit 20 of the
instruction (bit 4 of the SPR number) to determine if the SPR is
privileged.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
Paul Mackerras
2020-04-28 19:38:58 +10:00
parent b55c9cc298
commit 74db071067

View File

@@ -76,6 +76,28 @@ architecture behaviour of execute1 is
signal x_to_divider: Execute1ToDividerType;
signal divider_to_x: DividerToExecute1Type;
type privilege_level is (USER, SUPER);
type op_privilege_array is array(insn_type_t) of privilege_level;
constant op_privilege: op_privilege_array := (
OP_ATTN => SUPER,
OP_MFMSR => SUPER,
OP_MTMSRD => SUPER,
OP_RFID => SUPER,
others => USER
);
function instr_is_privileged(op: insn_type_t; insn: std_ulogic_vector(31 downto 0))
return boolean is
begin
if op_privilege(op) = SUPER then
return true;
elsif op = OP_MFSPR or op = OP_MTSPR then
return insn(20) = '1';
else
return false;
end if;
end;
procedure set_carry(e: inout Execute1ToWritebackType;
carry32 : in std_ulogic;
carry : in std_ulogic) is
@@ -432,6 +454,16 @@ begin
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#900#, 64));
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
elsif e_in.valid = '1' and ctrl.msr(MSR_PR) = '1' and
instr_is_privileged(e_in.insn_type, e_in.insn) then
-- generate a program interrupt
exception := '1';
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#700#, 64));
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
-- set bit 45 to indicate privileged instruction type interrupt
ctrl_tmp.srr1(63 - 45) <= '1';
report "privileged instruction";
elsif e_in.valid = '1' then
v.e.valid := '1';