Add debug registers output in exception handler
This commit is contained in:
parent
673edf2261
commit
3923e7c838
|
@ -84,6 +84,145 @@ unsafe extern "C" fn default_exception_handler() -> ! {
|
||||||
endless_sleep()
|
endless_sleep()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod esr_el1 {
|
||||||
|
// use cortex_a::{sys_coproc_read_raw, sys_coproc_write_raw};
|
||||||
|
use register::{cpu::RegisterReadWrite, register_bitfields};
|
||||||
|
|
||||||
|
pub struct Reg;
|
||||||
|
|
||||||
|
register_bitfields! {
|
||||||
|
u64,
|
||||||
|
|
||||||
|
ESR_EL1 [
|
||||||
|
ISS OFFSET(0) NUMBITS(25) [], // @todo Additional ISS encodings
|
||||||
|
IL OFFSET(25) NUMBITS(1) [], // Instruction Length
|
||||||
|
EC OFFSET(26) NUMBITS(6) [
|
||||||
|
Unknown = 0b000_000,
|
||||||
|
TrappedWfiOrWfe = 0b000_001,
|
||||||
|
TrappedMcrOrMrc = 0b000_011,
|
||||||
|
TrappedMcrrOrMrrc = 0b000_100,
|
||||||
|
TrappedMcrOrMrc2 = 0b000_101,
|
||||||
|
TrappedLdcOrStc = 0b000_110,
|
||||||
|
TrappedAdvSIMD = 0b000_111,
|
||||||
|
TrappedMrrc = 0b001_100,
|
||||||
|
IllegalExecState = 0b001_110,
|
||||||
|
SvcInAArch32 = 0b010_001,
|
||||||
|
SvcInAArch64 = 0b010_101,
|
||||||
|
TrappedMrsOrMsr = 0b011_000,
|
||||||
|
TrappedSve = 0b011_001,
|
||||||
|
InsnAbortFromLowerEL = 0b100_000,
|
||||||
|
InsnAbortFromSameEL = 0b100_001,
|
||||||
|
PcAlignmentFault = 0b100_010,
|
||||||
|
DataAbortFromLowerEL = 0b100_100,
|
||||||
|
DataAbortFromSameEL = 0b100_101,
|
||||||
|
SpAlignmentFault = 0b100_110,
|
||||||
|
TrappedFpuFromAArch32 = 0b101_000,
|
||||||
|
TrappedFpuFromAArch64 = 0b101_100,
|
||||||
|
SError = 0b101_111,
|
||||||
|
BreakpointFromLowerEL = 0b110_000,
|
||||||
|
BreakpointFromSameEL = 0b110_001,
|
||||||
|
SoftwareStepFromLowerEL = 0b110_010,
|
||||||
|
SoftwareStepFromSameEL = 0b110_011,
|
||||||
|
WatchpointFromLowerEL = 0b110_100,
|
||||||
|
WatchpointFromSameEL = 0b110_101,
|
||||||
|
BrkptInAArch32 = 0b111_000,
|
||||||
|
BrkInAArch64 = 0b111_100
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisterReadWrite<u64, ESR_EL1::Register> for Reg {
|
||||||
|
// sys_coproc_read_raw!(u64, "ESR_EL1");
|
||||||
|
// sys_coproc_write_raw!(u64, "ESR_EL1");
|
||||||
|
|
||||||
|
// Manually unmacroed
|
||||||
|
/// Reads the raw bits of the CPU register.
|
||||||
|
#[inline]
|
||||||
|
fn get(&self) -> u64 {
|
||||||
|
match () {
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
() => {
|
||||||
|
let reg;
|
||||||
|
unsafe {
|
||||||
|
asm!(concat!("mrs", " $0, ", "ESR_EL1") : "=r"(reg) ::: "volatile");
|
||||||
|
}
|
||||||
|
reg
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "aarch64"))]
|
||||||
|
() => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes raw bits to the CPU register.
|
||||||
|
#[cfg_attr(not(target_arch = "aarch64"), allow(unused_variables))]
|
||||||
|
#[inline]
|
||||||
|
fn set(&self, value: u64) {
|
||||||
|
match () {
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
() => unsafe {
|
||||||
|
asm!(concat!("msr", " ", "ESR_EL1", ", $0") :: "r"(value) :: "volatile")
|
||||||
|
},
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "aarch64"))]
|
||||||
|
() => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static ESR_EL1: Reg = Reg {};
|
||||||
|
}
|
||||||
|
|
||||||
|
mod far_el1 {
|
||||||
|
use register::cpu::RegisterReadWrite;
|
||||||
|
|
||||||
|
pub struct Reg;
|
||||||
|
|
||||||
|
impl RegisterReadWrite<u64, ()> for Reg {
|
||||||
|
// sys_coproc_read_raw!(u64, "FAR_EL1");
|
||||||
|
// sys_coproc_write_raw!(u64, "FAR_EL1");
|
||||||
|
|
||||||
|
// Manually unmacroed
|
||||||
|
/// Reads the raw bits of the CPU register.
|
||||||
|
#[inline]
|
||||||
|
fn get(&self) -> u64 {
|
||||||
|
match () {
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
() => {
|
||||||
|
let reg;
|
||||||
|
unsafe {
|
||||||
|
asm!(concat!("mrs", " $0, ", "FAR_EL1") : "=r"(reg) ::: "volatile");
|
||||||
|
}
|
||||||
|
reg
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "aarch64"))]
|
||||||
|
() => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes raw bits to the CPU register.
|
||||||
|
#[cfg_attr(not(target_arch = "aarch64"), allow(unused_variables))]
|
||||||
|
#[inline]
|
||||||
|
fn set(&self, value: u64) {
|
||||||
|
match () {
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
() => unsafe {
|
||||||
|
asm!(concat!("msr", " ", "FAR_EL1", ", $0") :: "r"(value) :: "volatile")
|
||||||
|
},
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "aarch64"))]
|
||||||
|
() => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static FAR_EL1: Reg = Reg {};
|
||||||
|
}
|
||||||
|
|
||||||
|
use esr_el1::ESR_EL1;
|
||||||
|
use far_el1::FAR_EL1;
|
||||||
|
|
||||||
// To implement an exception handler, overwrite it by defining the respective
|
// To implement an exception handler, overwrite it by defining the respective
|
||||||
// function below.
|
// function below.
|
||||||
// Don't forget the #[no_mangle] attribute.
|
// Don't forget the #[no_mangle] attribute.
|
||||||
|
@ -107,7 +246,11 @@ unsafe extern "C" fn default_exception_handler() -> ! {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
|
unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
|
||||||
println!("[!] A synchronous exception happened.");
|
println!("[!] A synchronous exception happened.");
|
||||||
println!(" ELR_EL1: {:#010X}", e.elr_el1);
|
println!(" ESR_EL1: {:#010x} (syndrome)", ESR_EL1.get());
|
||||||
|
println!(" EC: {:#06b} (cause)", ESR_EL1.read(ESR_EL1::EC));
|
||||||
|
println!(" FAR_EL1: {:#016x} (location)", FAR_EL1.get());
|
||||||
|
println!(" ELR_EL1: {:#010x}", e.elr_el1);
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
" Incrementing ELR_EL1 by 4 now to continue with the first \
|
" Incrementing ELR_EL1 by 4 now to continue with the first \
|
||||||
instruction after the exception!"
|
instruction after the exception!"
|
||||||
|
@ -115,6 +258,6 @@ unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
|
||||||
|
|
||||||
e.elr_el1 += 4;
|
e.elr_el1 += 4;
|
||||||
|
|
||||||
println!(" ELR_EL1 modified: {:#010X}", e.elr_el1);
|
println!(" ELR_EL1 modified: {:#010x}", e.elr_el1);
|
||||||
println!(" Returning from exception...\n");
|
println!(" Returning from exception...\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue