use std::{mem, ops::Range};
use probe_rs::{Core, MemoryInterface};
#[derive(Debug)]
pub struct Stacked {
pub lr: u32,
pub pc: u32,
contains_fpu_regs: bool,
}
fn bounds_check(bounds: Range<u32>, start: u32, len: u32) -> Result<(), ()> {
let end = start + len;
if bounds.contains(&start) && bounds.contains(&end) {
Ok(())
} else {
Err(())
}
}
impl Stacked {
const REGISTER_SIZE: usize = mem::size_of::<u32>();
const WORDS_OFFSET: usize = 5;
const WORDS_MINIMUM: usize = 2;
const WORDS_BASIC: usize = 8;
const WORDS_EXTENDED: usize = Self::WORDS_BASIC + 17;
pub fn read(
core: &mut Core<'_>,
sp: u32,
fpu: bool,
ram_bounds: Range<u32>,
) -> anyhow::Result<Option<Self>> {
let mut storage = [0; Self::WORDS_MINIMUM];
let registers: &mut [_] = &mut storage;
let start = sp + (Self::REGISTER_SIZE * Self::WORDS_OFFSET) as u32;
if bounds_check(
ram_bounds,
start,
(registers.len() * Self::REGISTER_SIZE) as u32,
)
.is_err()
{
return Ok(None);
}
core.read_32(start.into(), registers)?;
Ok(Some(Stacked {
lr: registers[0],
pc: registers[1],
contains_fpu_regs: fpu,
}))
}
pub fn size(&self) -> u32 {
let num_words = if self.contains_fpu_regs {
Self::WORDS_EXTENDED
} else {
Self::WORDS_BASIC
};
num_words as u32 * 4
}
}