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

Method check_pending_interrupt

crates/virtual-machine/src/cpu/pipeline.rs:809–852  ·  view source on GitHub ↗

Check whether a pending interrupt should be taken right now. Returns `Some((cause, tval, pc))` when an interrupt is ready to fire. Priority order per spec: MEI(11) > MSI(3) > MTI(7), then SEI(9) > SSI(1) > STI(5).

(&self)

Source from the content-addressed store, hash-verified

807 let in_s = self.regs.priv_mode == PrivilegeMode::Supervisor;
808 let mie_global = (self.csrs.mstatus >> 3) & 1; // mstatus.MIE
809 let sie_global = (self.csrs.mstatus >> 1) & 1; // mstatus.SIE
810
811 // M-mode interrupts: not delegated to S-mode.
812 // Taken if: not in M-mode (lower modes are always preempted), or MIE=1 in M-mode.
813 let m_pending = pending & !self.csrs.mideleg;
814 if m_pending != 0 && (!in_m || mie_global == 1) {
815 let cause_idx = if m_pending & (1 << 11) != 0 {
816 11u64
817 } else if m_pending & (1 << 3) != 0 {
818 3u64
819 } else if m_pending & (1 << 7) != 0 {
820 7u64
821 } else {
822 m_pending.trailing_zeros() as u64
823 };
824 return Some(((1u64 << 63) | cause_idx, 0, self.regs.pc));
825 }
826
827 // S-mode interrupts: delegated; only relevant when not in M-mode.
828 let s_pending = pending & self.csrs.mideleg;
829 if s_pending != 0 && !in_m && (!in_s || sie_global == 1) {
830 let cause_idx = if s_pending & (1 << 9) != 0 {
831 9u64
832 } else if s_pending & (1 << 1) != 0 {
833 1u64
834 } else if s_pending & (1 << 5) != 0 {
835 5u64
836 } else {
837 s_pending.trailing_zeros() as u64
838 };
839 return Some(((1u64 << 63) | cause_idx, 0, self.regs.pc));
840 }
841
842 None
843 }
844
845 // --- run() helper ---
846
847 pub fn run(&mut self, bus: &mut SystemBus, max_cycles: u64) -> (TickOutcome, String) {
848 let mut outcome = TickOutcome::Continue;
849 for _ in 0..max_cycles {
850 match self.tick(bus) {
851 Ok(TickOutcome::Continue | TickOutcome::EcallSquash) => {
852 if let Some(code) = bus.take_syscon_exit() {
853 outcome = TickOutcome::Halted(code);
854 break;
855 }

Callers 1

tickMethod · 0.80

Calls

no outgoing calls

Tested by

no test coverage detected