You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.8 KiB

//! Exception syndrome from ESR
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Fault {
AddressSize,
Translation,
AccessFlag,
Permission,
Alignment,
TlbConflict,
Other(u8),
}
impl From<u32> for Fault {
fn from(val: u32) -> Fault {
use self::Fault::*;
// IFSC or DFSC bits (ref: D10.2.39, Page 2457~2464).
match val & 0b111100 {
0b000000 => AddressSize,
0b000100 => Translation,
0b001000 => AccessFlag,
0b001100 => Permission,
0b100000 => Alignment,
0b110000 => TlbConflict,
_ => Other((val & 0b111111) as u8),
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Syndrome {
Unknown,
WfiWfe,
McrMrc,
McrrMrrc,
LdcStc,
SimdFp,
Vmrs,
Mrrc,
IllegalExecutionState,
Svc(u16),
Hvc(u16),
Smc(u16),
MsrMrsSystem,
InstructionAbort { kind: Fault, level: u8 },
PCAlignmentFault,
DataAbort { kind: Fault, level: u8 },
SpAlignmentFault,
TrappedFpu,
SError,
Breakpoint,
Step,
Watchpoint,
Brk(u16),
Other(u32),
}
/// Converts a raw syndrome value (ESR) into a `Syndrome` (ref: D1.10.4, D10.2.39).
impl From<u32> for Syndrome {
fn from(esr: u32) -> Syndrome {
use self::Syndrome::*;
let ec = esr >> 26;
let iss = esr & 0xFFFFFF;
match ec {
0b000000 => Unknown,
0b000001 => WfiWfe,
0b000011 => McrMrc,
0b000100 => McrrMrrc,
0b000101 => McrMrc,
0b000110 => LdcStc,
0b000111 => SimdFp,
0b001000 => Vmrs,
0b001100 => Mrrc,
0b001110 => IllegalExecutionState,
0b010001 => Svc((iss & 0xFFFF) as u16),
0b010010 => Hvc((iss & 0xFFFF) as u16),
0b010011 => Smc((iss & 0xFFFF) as u16),
0b010101 => Svc((iss & 0xFFFF) as u16),
0b010110 => Hvc((iss & 0xFFFF) as u16),
0b010111 => Smc((iss & 0xFFFF) as u16),
0b011000 => MsrMrsSystem,
0b100000 | 0b100001 => InstructionAbort {
kind: Fault::from(iss),
level: (iss & 0b11) as u8,
},
0b100010 => PCAlignmentFault,
0b100100 | 0b100101 => DataAbort {
kind: Fault::from(iss),
level: (iss & 0b11) as u8,
},
0b100110 => SpAlignmentFault,
0b101000 => TrappedFpu,
0b101100 => TrappedFpu,
0b101111 => SError,
0b110000 => Breakpoint,
0b110001 => Breakpoint,
0b110010 => Step,
0b110011 => Step,
0b110100 => Watchpoint,
0b110101 => Watchpoint,
0b111100 => Brk((iss & 0xFFFF) as u16),
other => Other(other),
}
}
}