use serde::{Deserialize, Serialize};
use crate::{
CoreStatus, HaltReason,
core::{BreakpointCause, RegisterValue},
memory_mapped_bitfield_register,
semihosting::SemihostingCommand,
};
use super::memory::ArmMemoryInterface;
pub mod armv6m;
pub mod armv7a;
pub mod armv7m;
pub mod armv8a;
pub mod armv8m;
pub(crate) mod armv7a_debug_regs;
pub(crate) mod armv8a_debug_regs;
pub(crate) mod cortex_m;
pub(crate) mod instructions;
pub mod registers;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Dump {
pub regs: [u32; 16],
stack_addr: u32,
stack: Vec<u8>,
}
impl Dump {
pub fn new(stack_addr: u32, stack: Vec<u8>) -> Dump {
Dump {
regs: [0u32; 16],
stack_addr,
stack,
}
}
}
memory_mapped_bitfield_register! {
pub struct Dfsr(u32);
0xE000_ED30, "DFSR",
pub external, set_external: 4;
pub vcatch, set_vcatch: 3;
pub dwttrap, set_dwttrap: 2;
pub bkpt, set_bkpt: 1;
pub halted, set_halted: 0;
}
impl Dfsr {
fn clear_all() -> Self {
Dfsr(0b11111)
}
pub(crate) fn halt_reason(&self) -> HaltReason {
if self.0 == 0 {
HaltReason::Unknown
} else if self.0.count_ones() > 1 {
tracing::debug!("DFSR: {:?}", self);
if self.bkpt() {
HaltReason::Breakpoint(BreakpointCause::Unknown)
} else {
HaltReason::Multiple
}
} else if self.bkpt() {
HaltReason::Breakpoint(BreakpointCause::Unknown)
} else if self.external() {
HaltReason::External
} else if self.dwttrap() {
HaltReason::Watchpoint
} else if self.halted() {
HaltReason::Request
} else if self.vcatch() {
HaltReason::Exception
} else {
panic!("This should not happen. Please open a bug report.")
}
}
}
impl From<u32> for Dfsr {
fn from(val: u32) -> Self {
Dfsr(val & 0b11111)
}
}
impl From<Dfsr> for u32 {
fn from(register: Dfsr) -> Self {
register.0
}
}
#[derive(Debug)]
pub struct CortexMState {
initialized: bool,
hw_breakpoints_enabled: bool,
current_state: CoreStatus,
fp_present: bool,
semihosting_command: Option<SemihostingCommand>,
}
impl CortexMState {
pub(crate) fn new() -> Self {
Self {
initialized: false,
hw_breakpoints_enabled: false,
current_state: CoreStatus::Unknown,
fp_present: false,
semihosting_command: None,
}
}
fn initialize(&mut self) {
self.initialized = true;
}
fn initialized(&self) -> bool {
self.initialized
}
}
#[derive(Debug)]
pub struct CortexAState {
initialized: bool,
current_state: CoreStatus,
is_64_bit: bool,
register_cache: Vec<Option<(RegisterValue, bool)>>,
fp_reg_count: usize,
}
impl CortexAState {
pub(crate) fn new() -> Self {
Self {
initialized: false,
current_state: CoreStatus::Unknown,
is_64_bit: false,
register_cache: vec![],
fp_reg_count: 0,
}
}
fn initialize(&mut self) {
self.initialized = true;
}
fn initialized(&self) -> bool {
self.initialized
}
}
pub fn update_core_status<P: ArmMemoryInterface + ?Sized, T: core::ops::DerefMut<Target = P>>(
probe: &mut T,
current_status: &mut CoreStatus,
new_status: CoreStatus,
) {
if *current_status != new_status {
probe.deref_mut().update_core_status(new_status);
}
*current_status = new_status;
}