pub mod ap;
pub(crate) mod communication_interface;
pub mod component;
pub(crate) mod core;
pub mod dp;
pub mod memory;
pub mod sequences;
pub mod swo;
mod traits;
pub use self::core::{armv6m, armv7a, armv7m, armv8a, armv8m, Dump};
use self::{
ap::{AccessPort, AccessPortError},
communication_interface::RegisterParseError,
dp::DebugPortError,
memory::romtable::RomTableError,
sequences::ArmDebugSequenceError,
{armv7a::Armv7aError, armv8a::Armv8aError},
};
use crate::probe::DebugProbeError;
pub use communication_interface::{
ApInformation, ArmChipInfo, ArmCommunicationInterface, ArmProbeInterface, DapError,
MemoryApInformation, Register,
};
pub use swo::{SwoAccess, SwoConfig, SwoMode, SwoReader};
pub use traits::*;
#[derive(Debug, thiserror::Error)]
#[error("An ARM specific error occurred.")]
pub enum ArmError {
#[error("The operation requires one of the following architectures: {0:?}")]
ArchitectureRequired(&'static [&'static str]),
#[error("Timeout occurred during operation.")]
Timeout,
#[error("Address is not in 32 bit address space.")]
AddressOutOf32BitAddressSpace,
#[error("Target device is not an ARM device.")]
NoArmTarget,
#[error("Error using access port")]
AccessPort {
address: ApAddress,
source: AccessPortError,
},
#[error("Error using a debug port.")]
DebugPort(#[from] DebugPortError),
#[error("The core needs to be halted for this operation but was not.")]
CoreNotHalted,
#[error("Probe and device internal state mismatch. A probe re-attach is required")]
ReAttachRequired,
#[error("An operation could not be performed because it lacked the permission to do so: {0}")]
MissingPermissions(String),
#[error("An error occurred in the communication with an access port or debug port.")]
Dap(#[from] DapError),
#[error("The debug probe encountered an error.")]
Probe(#[from] DebugProbeError),
#[error("Failed to access address 0x{address:08x} as it is not aligned to the requirement of {alignment} bytes for this platform and API call.")]
MemoryNotAligned {
address: u64,
alignment: usize,
},
#[error("Out of bounds access")]
OutOfBounds,
#[error("{0} bit is not a supported memory transfer width on the current core")]
UnsupportedTransferWidth(usize),
#[error("The AP with address {0:?} does not exist.")]
ApDoesNotExist(ApAddress),
WrongApType,
#[error("Unable to create a breakpoint at address {0:#010X}. Hardware breakpoints are only supported at addresses < 0x2000'0000.")]
UnsupportedBreakpointAddress(u32),
Armv8a(#[from] Armv8aError),
Armv7a(#[from] Armv7aError),
DebugSequence(#[from] ArmDebugSequenceError),
TracingUnconfigured,
RegisterParse(#[from] RegisterParseError),
RomTable(#[source] RomTableError),
ChipEraseFailed,
#[error("The operation requires the following extension(s): {0:?}")]
ExtensionRequired(&'static [&'static str]),
Other(#[from] anyhow::Error),
}
impl ArmError {
pub fn from_access_port(err: AccessPortError, ap: impl AccessPort) -> Self {
ArmError::AccessPort {
address: ap.ap_address(),
source: err,
}
}
pub fn alignment_error(address: u64, alignment: usize) -> Self {
ArmError::MemoryNotAligned { address, alignment }
}
}
impl From<RomTableError> for ArmError {
fn from(value: RomTableError) -> Self {
match value {
RomTableError::Memory(err) => *err,
other => ArmError::RomTable(other),
}
}
}
pub fn valid_32bit_arm_address(address: u64) -> Result<u32, ArmError> {
address
.try_into()
.map_err(|_| ArmError::AddressOutOf32BitAddressSpace)
}