xous-kernel/src/exception.rs

219 lines
7.2 KiB
Rust

use core::fmt;
#[derive(PartialEq)]
pub enum RiscvException {
/// When things are all 0
NoException,
/// 1 0
UserSoftwareInterrupt(usize /* mepc */),
/// 1 1
SupervisorSoftwareInterrupt(usize /* mepc */),
// [reserved]
/// 1 3
MachineSoftwareInterrupt(usize /* mepc */),
/// 1 4
UserTimerInterrupt(usize /* mepc */),
/// 1 5
SupervisorTimerInterrupt(usize /* mepc */),
// [reserved]
/// 1 7
MachineTimerInterrupt(usize /* mepc */),
/// 1 8
UserExternalInterrupt(usize /* mepc */),
/// 1 9
SupervisorExternalInterrupt(usize /* mepc */),
// [reserved]
/// 1 11
MachineExternalInterrupt(usize /* mepc */),
ReservedInterrupt(usize /* unknown cause number */, usize /* mepc */),
/// 0 0
InstructionAddressMisaligned(usize /* mepc */, usize /* target address */),
/// 0 1
InstructionAccessFault(usize /* mepc */, usize /* target address */),
/// 0 2
IllegalInstruction(usize /* mepc */, usize /* instruction value */),
/// 0 3
Breakpoint(usize /* mepc */),
/// 0 4
LoadAddressMisaligned(usize /* mepc */, usize /* target address */),
/// 0 5
LoadAccessFault(usize /* mepc */, usize /* target address */),
/// 0 6
StoreAddressMisaligned(usize /* mepc */, usize /* target address */),
/// 0 7
StoreAccessFault(usize /* mepc */, usize /* target address */),
/// 0 8
CallFromUMode(usize /* mepc */),
/// 0 9
CallFromSMode(usize /* mepc */),
// [reserved]
/// 0 11
CallFromMMode(usize /* mepc */),
/// 0 12
InstructionPageFault(usize /* mepc */, usize /* target address */),
/// 0 13
LoadPageFault(usize /* mepc */, usize /* target address */),
// [reserved]
/// 0 15
StorePageFault(usize /* mepc */, usize /* target address */),
ReservedFault(
usize, /* unknown cause number */
usize, /* mepc */
usize, /* mtval */
),
}
impl fmt::Display for RiscvException {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use RiscvException::*;
match *self {
NoException => write!(f, "No trap"),
UserSoftwareInterrupt(epc) => write!(f, "User swi from 0x{:08x}", epc),
SupervisorSoftwareInterrupt(epc) => write!(f, "Supervisor swi from 0x{:08x}", epc),
// --reserved--
MachineSoftwareInterrupt(epc) => write!(f, "Machine swi at 0x{:08x}", epc),
UserTimerInterrupt(epc) => write!(f, "User timer interrupt at 0x{:08x}", epc),
SupervisorTimerInterrupt(epc) => {
write!(f, "Supervisor timer interrupt at 0x{:08x}", epc)
}
// --reserved--
MachineTimerInterrupt(epc) => write!(f, "Machine timer interrupt at 0x{:08x}", epc),
UserExternalInterrupt(epc) => write!(f, "User external interrupt at 0x{:08x}", epc),
SupervisorExternalInterrupt(epc) => {
write!(f, "Machine external interrupt at 0x{:08x}", epc)
}
// --reserved--
MachineExternalInterrupt(epc) => {
write!(f, "Supervisor external interrupt at 0x{:08x}", epc)
}
ReservedInterrupt(code, epc) => {
write!(f, "Reserved interrupt 0x{:08x} at 0x{:08x}", code, epc)
}
InstructionAddressMisaligned(epc, mtval) => write!(
f,
"Misaligned address instruction 0x{:08x} at 0x{:08x}",
mtval, epc
),
InstructionAccessFault(epc, mtval) => write!(
f,
"Instruction access fault to 0x{:08x} at 0x{:08x}",
mtval, epc
),
IllegalInstruction(epc, mtval) => {
write!(f, "Illegal instruction 0x{:08x} at 0x{:08x}", mtval, epc)
}
Breakpoint(epc) => write!(f, "Breakpoint at 0x{:08x}", epc),
LoadAddressMisaligned(epc, mtval) => write!(
f,
"Misaligned load address of 0x{:08x} at 0x{:08x}",
mtval, epc
),
LoadAccessFault(epc, mtval) => {
write!(f, "Load access fault from 0x{:08x} at 0x{:08x}", mtval, epc)
}
StoreAddressMisaligned(epc, mtval) => write!(
f,
"Misaligned store address of 0x{:08x} at 0x{:08x}",
mtval, epc
),
StoreAccessFault(epc, mtval) => {
write!(f, "Store access fault to 0x{:08x} at 0x{:08x}", mtval, epc)
}
CallFromUMode(epc) => write!(f, "Call from User mode at 0x{:08x}", epc),
CallFromSMode(epc) => write!(f, "Call from Supervisor mode at 0x{:08x}", epc),
// --reserved--
CallFromMMode(epc) => write!(f, "Call from Machine mode at 0x{:08x}", epc),
InstructionPageFault(epc, mtval) => write!(
f,
"Instruction page fault of 0x{:08x} at 0x{:08x}",
mtval, epc
),
LoadPageFault(epc, mtval) => {
write!(f, "Load page fault of 0x{:08x} at 0x{:08x}", mtval, epc)
}
// --reserved--
StorePageFault(epc, mtval) => {
write!(f, "Load page fault of 0x{:08x} at 0x{:08x}", mtval, epc)
}
ReservedFault(code, epc, mtval) => write!(
f,
"Reserved interrupt 0x{:08x} with cause 0x{:08x} at 0x{:08x}",
code, mtval, epc
),
}
}
}
impl RiscvException {
pub fn from_regs(mcause: usize, mepc: usize, mtval: usize) -> RiscvException {
use RiscvException::*;
if mepc == 0 && mtval == 0 {
return NoException;
}
match mcause {
0x80000000 => UserSoftwareInterrupt(mepc),
0x80000001 => SupervisorSoftwareInterrupt(mepc),
// --reserved--
0x80000003 => MachineSoftwareInterrupt(mepc),
0x80000004 => UserTimerInterrupt(mepc),
0x80000005 => SupervisorTimerInterrupt(mepc),
// --reserved--
0x80000007 => MachineTimerInterrupt(mepc),
0x80000008 => UserExternalInterrupt(mepc),
0x80000009 => SupervisorExternalInterrupt(mepc),
// --reserved--
0x8000000b => MachineExternalInterrupt(mepc),
0 => InstructionAddressMisaligned(mepc, mtval),
1 => InstructionAccessFault(mepc, mtval),
2 => IllegalInstruction(mepc, mtval),
3 => Breakpoint(mepc),
4 => LoadAddressMisaligned(mepc, mtval),
5 => LoadAccessFault(mepc, mtval),
6 => StoreAddressMisaligned(mepc, mtval),
7 => StoreAccessFault(mepc, mtval),
8 => CallFromUMode(mepc),
9 => CallFromSMode(mepc),
// --reserved--
11 => CallFromMMode(mepc),
12 => InstructionPageFault(mepc, mtval),
13 => LoadPageFault(mepc, mtval),
// --reserved--
15 => StorePageFault(mepc, mtval),
x @ 10 | x @ 14 | x @ 16..=0x7fffffff => ReservedFault(x, mepc, mtval),
x => {
ReservedInterrupt(x & 0x7fffffff, mepc)
}
}
}
}