@@ -127,6 +127,21 @@ Xlen Core::get_xlen() const {
127127
128128void Core::set_current_privilege (CSR::PrivilegeLevel privilege) {
129129 state.set_current_privilege (privilege);
130+ const unsigned PRIV_BITS = unsigned (IMF_PRIV_M) | unsigned (IMF_PRIV_H) | unsigned (IMF_PRIV_S);
131+
132+ InstructionFlags base_mask = InstructionFlags (unsigned (check_inst_flags_mask) & ~PRIV_BITS);
133+ InstructionFlags base_val = InstructionFlags (unsigned (check_inst_flags_val) & ~PRIV_BITS);
134+
135+ unsigned allowed_priv = 0 ;
136+ if (privilege >= CSR::PrivilegeLevel::SUPERVISOR) { allowed_priv |= unsigned (IMF_PRIV_S); }
137+ if (privilege >= CSR::PrivilegeLevel::HYPERVISOR) { allowed_priv |= unsigned (IMF_PRIV_H); }
138+ if (privilege >= CSR::PrivilegeLevel::MACHINE) { allowed_priv |= unsigned (IMF_PRIV_M); }
139+ unsigned disallowed_priv = (PRIV_BITS & ~allowed_priv);
140+ InstructionFlags new_mask = InstructionFlags (unsigned (base_mask) | disallowed_priv);
141+ InstructionFlags new_val = base_val;
142+
143+ check_inst_flags_mask = new_mask;
144+ check_inst_flags_val = new_val;
130145}
131146
132147CSR::PrivilegeLevel Core::get_current_privilege () const {
@@ -317,7 +332,18 @@ DecodeState Core::decode(const FetchInterstage &dt) {
317332 ExceptionCause excause = dt.excause ;
318333
319334 dt.inst .flags_alu_op_mem_ctl (flags, alu_op, mem_ctl);
320-
335+ CSR::PrivilegeLevel inst_xret_priv = CSR::PrivilegeLevel::UNPRIVILEGED;
336+ if (flags & IMF_XRET) {
337+ if (flags & IMF_PRIV_M) {
338+ inst_xret_priv = CSR::PrivilegeLevel::MACHINE;
339+ } else if (flags & IMF_PRIV_H) {
340+ inst_xret_priv = CSR::PrivilegeLevel::HYPERVISOR;
341+ } else if (flags & IMF_PRIV_S) {
342+ inst_xret_priv = CSR::PrivilegeLevel::SUPERVISOR;
343+ } else {
344+ inst_xret_priv = CSR::PrivilegeLevel::UNPRIVILEGED;
345+ }
346+ }
321347 if ((flags ^ check_inst_flags_val) & check_inst_flags_mask) { excause = EXCAUSE_INSN_ILLEGAL; }
322348
323349 RegisterId num_rs = (flags & (IMF_ALU_REQ_RS | IMF_ALU_RS_ID)) ? dt.inst .rs () : 0 ;
@@ -332,8 +358,9 @@ DecodeState Core::decode(const FetchInterstage &dt) {
332358 const bool regwrite = flags & IMF_REGWRITE;
333359
334360 CSR::Address csr_address = (flags & IMF_CSR) ? dt.inst .csr_address () : CSR::Address (0 );
335- RegisterValue csr_read_val
336- = ((control_state != nullptr && (flags & IMF_CSR))) ? control_state->read (csr_address) : 0 ;
361+ RegisterValue csr_read_val = ((control_state != nullptr && (flags & IMF_CSR)))
362+ ? control_state->read (csr_address, get_current_privilege ())
363+ : 0 ;
337364 bool csr_write = (flags & IMF_CSR) && (!(flags & IMF_CSR_TO_ALU) || (num_rs != 0 ));
338365
339366 if ((flags & IMF_EXCEPTION) && (excause == EXCAUSE_NONE)) {
@@ -393,6 +420,7 @@ DecodeState Core::decode(const FetchInterstage &dt) {
393420 .csr_to_alu = bool (flags & IMF_CSR_TO_ALU),
394421 .csr_write = csr_write,
395422 .xret = bool (flags & IMF_XRET),
423+ .xret_privlev = inst_xret_priv,
396424 .insert_stall_before = bool (flags & IMF_CSR) } };
397425}
398426
@@ -463,6 +491,7 @@ ExecuteState Core::execute(const DecodeInterstage &dt) {
463491 .csr = dt.csr ,
464492 .csr_write = dt.csr_write ,
465493 .xret = dt.xret ,
494+ .xret_privlev = dt.xret_privlev ,
466495 } };
467496}
468497
@@ -523,11 +552,12 @@ MemoryState Core::memory(const ExecuteInterstage &dt) {
523552 if (control_state != nullptr && dt.is_valid && dt.excause == EXCAUSE_NONE) {
524553 control_state->increment_internal (CSR::Id::MINSTRET, 1 );
525554 if (dt.csr_write ) {
526- control_state->write (dt.csr_address , dt.alu_val );
555+ control_state->write (dt.csr_address , dt.alu_val , get_current_privilege () );
527556 csr_written = true ;
528557 }
529558 if (dt.xret ) {
530- CSR::PrivilegeLevel restored = control_state->exception_return (get_current_privilege ());
559+ CSR::PrivilegeLevel restored
560+ = control_state->exception_return (get_current_privilege (), dt.xret_privlev );
531561 set_current_privilege (restored);
532562 if (this ->xlen == Xlen::_32)
533563 computed_next_inst_addr
@@ -577,6 +607,7 @@ MemoryState Core::memory(const ExecuteInterstage &dt) {
577607 .regwrite = regwrite,
578608 .is_valid = dt.is_valid ,
579609 .csr_written = csr_written,
610+ .xret_privlev = dt.xret_privlev ,
580611 } };
581612}
582613
0 commit comments