use crate::{
MemoryInterface,
architecture::arm::{
ApV2Address, ArmDebugInterface, ArmError, FullyQualifiedApAddress,
dp::{BASEPTR0, BASEPTR1, DpAccess, DpAddress},
memory::ArmMemoryInterface,
},
probe::DebugProbeError,
};
pub struct RootMemoryInterface<'iface, API> {
iface: &'iface mut API,
dp: DpAddress,
}
impl<'iface, ADI: ArmDebugInterface> RootMemoryInterface<'iface, ADI> {
pub fn new(iface: &'iface mut ADI, dp: DpAddress) -> Result<Self, ArmError> {
Ok(Self { iface, dp })
}
}
impl<ADI: ArmDebugInterface> MemoryInterface<ArmError> for RootMemoryInterface<'_, ADI> {
fn supports_native_64bit_access(&mut self) -> bool {
false
}
fn read_64(&mut self, _address: u64, _data: &mut [u64]) -> Result<(), ArmError> {
unimplemented!("The DPv3 only supports 32bit accesses")
}
fn read_32(&mut self, address: u64, data: &mut [u32]) -> Result<(), ArmError> {
for (i, d) in data.iter_mut().enumerate() {
let addr = address + (i as u64) * 4;
let fqa = FullyQualifiedApAddress::v2_with_dp(self.dp, ApV2Address::root());
*d = self.iface.read_raw_ap_register(&fqa, addr)?;
}
Ok(())
}
fn read_16(&mut self, _address: u64, _data: &mut [u16]) -> Result<(), ArmError> {
unimplemented!("The DPv3 only supports 32bit accesses")
}
fn read_8(&mut self, _address: u64, _data: &mut [u8]) -> Result<(), ArmError> {
unimplemented!("The DPv3 only supports 32bit accesses")
}
fn write_64(&mut self, _address: u64, _data: &[u64]) -> Result<(), ArmError> {
unimplemented!("The DPv3 only supports 32bit accesses")
}
fn write_32(&mut self, address: u64, data: &[u32]) -> Result<(), ArmError> {
for (i, d) in data.iter().enumerate() {
let addr = address + (i as u64) * 4;
let fqa = FullyQualifiedApAddress::v2_with_dp(self.dp, ApV2Address::root());
self.iface.write_raw_ap_register(&fqa, addr, *d)?;
}
Ok(())
}
fn write_16(&mut self, _address: u64, _data: &[u16]) -> Result<(), ArmError> {
unimplemented!("The DPv3 only supports 32bit accesses")
}
fn write_8(&mut self, _address: u64, _data: &[u8]) -> Result<(), ArmError> {
unimplemented!("The DPv3 only supports 32bit accesses")
}
fn supports_8bit_transfers(&self) -> Result<bool, ArmError> {
Ok(false)
}
fn flush(&mut self) -> Result<(), ArmError> {
Ok(())
}
}
impl<ADI: ArmDebugInterface> ArmMemoryInterface for RootMemoryInterface<'_, ADI> {
fn fully_qualified_address(&self) -> FullyQualifiedApAddress {
FullyQualifiedApAddress::v2_with_dp(self.dp, ApV2Address::root())
}
fn base_address(&mut self) -> Result<u64, ArmError> {
let base_ptr0: BASEPTR0 = self.iface.read_dp_register(self.dp)?;
let base_ptr1: BASEPTR1 = self.iface.read_dp_register(self.dp)?;
let base = base_ptr0
.valid()
.then(|| u64::from(base_ptr1.ptr()) | u64::from(base_ptr0.ptr() << 12))
.ok_or_else(|| ArmError::Other("DP has no valid base address defined.".into()))?;
Ok(base)
}
fn get_arm_debug_interface(&mut self) -> Result<&mut dyn ArmDebugInterface, DebugProbeError> {
Ok(self.iface)
}
fn generic_status(&mut self) -> Result<crate::architecture::arm::ap::CSW, ArmError> {
unimplemented!()
}
}