use crate::architecture::arm::{
DapAccess, FullyQualifiedApAddress,
ap::{ApAccess, ApRegister, GenericAp, IDR},
dp::DpAddress,
};
#[tracing::instrument(skip(debug_port))]
pub(crate) fn valid_access_ports<DP>(
debug_port: &mut DP,
dp: DpAddress,
) -> Vec<FullyQualifiedApAddress>
where
DP: DapAccess,
{
valid_access_ports_allowlist(debug_port, dp, 0..=255)
}
pub fn access_port_is_valid<AP>(
debug_port: &mut AP,
access_port: &FullyQualifiedApAddress,
) -> Option<IDR>
where
AP: DapAccess,
{
let idr_result: Result<IDR, _> = debug_port
.read_raw_ap_register(access_port, IDR::ADDRESS)
.and_then(|idr| Ok(IDR::try_from(idr)?));
match idr_result {
Ok(idr) if u32::from(idr) != 0 => Some(idr),
Ok(_) => {
tracing::debug!("AP {:?} is not valid, IDR = 0", access_port.ap());
None
}
Err(e) => {
tracing::debug!(
"Error reading IDR register from AP {:?}: {}",
access_port.ap(),
e
);
None
}
}
}
#[tracing::instrument(skip(debug_port, allowed_aps))]
pub(crate) fn valid_access_ports_allowlist<DP>(
debug_port: &mut DP,
dp: DpAddress,
allowed_aps: impl IntoIterator<Item = u8>,
) -> Vec<FullyQualifiedApAddress>
where
DP: DapAccess,
{
allowed_aps
.into_iter()
.map_while(|ap| {
let ap = FullyQualifiedApAddress::v1_with_dp(dp, ap);
access_port_is_valid(debug_port, &ap).map(|_| ap)
})
.collect()
}
pub fn get_ap_by_idr<AP, P>(debug_port: &mut AP, dp: DpAddress, f: P) -> Option<GenericAp>
where
AP: ApAccess,
P: Fn(IDR) -> bool,
{
(0..=255)
.map(|ap| GenericAp::new(FullyQualifiedApAddress::v1_with_dp(dp, ap)))
.find(|ap| {
if let Ok(idr) = debug_port.read_ap_register(ap) {
f(idr)
} else {
false
}
})
}