MCPcopy Create free account
hub / github.com/LPC4/Full-Stack / handle_mret

Function handle_mret

crates/virtual-machine/src/cpu/traps.rs:145–168  ·  view source on GitHub ↗

Handle MRET - return from machine-mode trap. Restores MIE from MPIE, privilege from MPP, returns PC from MEPC.

(regs: &mut Registers, csrs: &mut CsrFile)

Source from the content-addressed store, hash-verified

143/// Handle SRET - restore SIE from SPIE, privilege from SPP, return PC from SEPC. Err if illegal.
144pub fn handle_sret(regs: &mut Registers, csrs: &mut CsrFile) -> Result<u64, VmError> {
145 // SRET is illegal from U-mode.
146 if regs.priv_mode == PrivilegeMode::User {
147 return Err(VmError::IllegalInstruction(0x1020_0073));
148 }
149 // TSR bit (mstatus[22]): if set while in S-mode, SRET raises illegal instruction.
150 if regs.priv_mode == PrivilegeMode::Supervisor && (csrs.mstatus >> 22) & 1 == 1 {
151 return Err(VmError::IllegalInstruction(0x1020_0073));
152 }
153
154 // SIE = old SPIE; SPIE = 1
155 let spie = (csrs.mstatus >> 5) & 1;
156 csrs.mstatus = (csrs.mstatus & !(1u64 << 1)) | (spie << 1); // SIE = old SPIE
157 csrs.mstatus |= 1u64 << 5; // SPIE = 1
158
159 // Restore privilege from SPP (mstatus[8]), then set SPP = User (0).
160 let spp = (csrs.mstatus >> 8) & 1;
161 let prev_priv = if spp == 0 {
162 PrivilegeMode::User
163 } else {
164 PrivilegeMode::Supervisor
165 };
166 regs.priv_mode = prev_priv;
167 csrs.mstatus &= !(1u64 << 8); // SPP = User (0)
168
169 // Clear MPRV (not returning to M-mode).
170 csrs.mstatus &= !(1u64 << 17);
171

Callers 3

handle_mretMethod · 0.85

Calls

no outgoing calls