#[doc(hidden)]
pub(crate) mod mock;
use super::{APAccess, APRegister, AccessPort, GenericAP, Register};
use crate::DebugProbeError;
use enum_primitive_derive::Primitive;
use num_traits::{FromPrimitive, ToPrimitive};
define_ap!(MemoryAP);
impl MemoryAP {
pub fn base_address<A>(&self, interface: &mut A) -> Result<u64, DebugProbeError>
where
A: APAccess<MemoryAP, BASE, Error = DebugProbeError>
+ APAccess<MemoryAP, BASE2, Error = DebugProbeError>,
{
let base_register = interface.read_ap_register(self.port_number(), BASE::default())?;
let mut base_address = if BaseaddrFormat::ADIv5 == base_register.Format {
let base2 = interface.read_ap_register(self.port_number(), BASE2::default())?;
u64::from(base2.BASEADDR) << 32
} else {
0
};
base_address |= u64::from(base_register.BASEADDR << 12);
Ok(base_address)
}
}
impl From<GenericAP> for MemoryAP {
fn from(other: GenericAP) -> Self {
MemoryAP {
port_number: other.port_number(),
}
}
}
#[derive(Debug, Primitive, Clone, Copy, PartialEq)]
pub enum DataSize {
U8 = 0b000,
U16 = 0b001,
U32 = 0b010,
U64 = 0b011,
U128 = 0b100,
U256 = 0b101,
}
impl DataSize {
pub fn from_bytes(bytes: u8) -> Self {
if bytes == 1 {
DataSize::U8
} else if bytes == 2 {
DataSize::U16
} else if bytes == 4 {
DataSize::U32
} else if bytes == 8 {
DataSize::U64
} else if bytes == 16 {
DataSize::U128
} else if bytes == 32 {
DataSize::U256
} else {
DataSize::U32
}
}
}
impl Default for DataSize {
fn default() -> Self {
DataSize::U32
}
}
#[derive(Debug, Primitive, Clone, Copy, PartialEq)]
pub enum AddressIncrement {
Off = 0b00,
Single = 0b01,
Packed = 0b10,
}
impl Default for AddressIncrement {
fn default() -> Self {
AddressIncrement::Single
}
}
#[derive(Debug, PartialEq, Primitive, Clone, Copy)]
pub enum BaseaddrFormat {
Legacy = 0,
ADIv5 = 1,
}
impl Default for BaseaddrFormat {
fn default() -> Self {
BaseaddrFormat::Legacy
}
}
#[derive(Debug, Primitive, Clone, Copy, PartialEq)]
pub enum DebugEntryState {
NotPresent = 0,
Present = 1,
}
impl Default for DebugEntryState {
fn default() -> Self {
DebugEntryState::NotPresent
}
}
define_ap_register!(
MemoryAP,
BASE,
0xF8,
[
(BASEADDR: u32),
(_RES0: u8),
(Format: BaseaddrFormat),
(present: bool),
],
value,
BASE {
BASEADDR: (value & 0xFFFF_F000) >> 12,
_RES0: 0,
Format: match ((value >> 1) & 0x01) as u8 {
0 => BaseaddrFormat::Legacy,
1 => BaseaddrFormat::ADIv5,
_ => panic!("This is a bug. Please report it."),
},
present: match (value & 0x01) as u8 {
0 => false,
1 => true,
_ => panic!("This is a bug. Please report it."),
},
},
(value.BASEADDR << 12)
| (u32::from(value.Format as u8 ) << 1)
| (if value.present { 1 } else { 0 })
);
define_ap_register!(
MemoryAP,
BASE2,
0xF0,
[(BASEADDR: u32),],
value,
BASE2 { BASEADDR: value },
value.BASEADDR
);
define_ap_register!(
MemoryAP,
BD0,
0x10,
[(data: u32),],
value,
BD0 { data: value },
value.data
);
define_ap_register!(
MemoryAP,
BD1,
0x14,
[(data: u32),],
value,
BD1 { data: value },
value.data
);
define_ap_register!(
MemoryAP,
BD2,
0x18,
[(data: u32),],
value,
BD2 { data: value },
value.data
);
define_ap_register!(
MemoryAP,
BD3,
0x1C,
[(data: u32),],
value,
BD3 { data: value },
value.data
);
define_ap_register!(
MemoryAP,
CFG,
0xF4,
[(LD: u8), (LA: u8), (BE: u8),],
value,
CFG {
LD: ((value >> 2) & 0x01) as u8,
LA: ((value >> 1) & 0x01) as u8,
BE: (value & 0x01) as u8,
},
u32::from((value.LD << 2) | (value.LA << 1) | value.BE)
);
define_ap_register!(
MemoryAP,
CSW,
0x00,
[
(DbgSwEnable: u8),
(PROT: u8),
(CACHE: u8),
(SPIDEN: u8),
(_RES0: u8),
(Type: u8),
(Mode: u8),
(TrinProg: u8),
(DeviceEn: u8),
(AddrInc: AddressIncrement),
(_RES1: u8),
(SIZE: DataSize),
],
value,
CSW {
DbgSwEnable: ((value >> 31) & 0x01) as u8,
PROT: ((value >> 28) & 0x07) as u8,
CACHE: ((value >> 24) & 0x0F) as u8,
SPIDEN: ((value >> 23) & 0x01) as u8,
_RES0: 0,
Type: ((value >> 12) & 0x0F) as u8,
Mode: ((value >> 8) & 0x0F) as u8,
TrinProg: ((value >> 7) & 0x01) as u8,
DeviceEn: ((value >> 6) & 0x01) as u8,
AddrInc: AddressIncrement::from_u8(((value >> 4) & 0x03) as u8).unwrap(),
_RES1: 0,
SIZE: DataSize::from_u8((value & 0x07) as u8).unwrap(),
},
(u32::from(value.DbgSwEnable) << 31)
| (u32::from(value.PROT ) << 28)
| (u32::from(value.CACHE ) << 24)
| (u32::from(value.SPIDEN ) << 23)
| (u32::from(value.Type ) << 12)
| (u32::from(value.Mode ) << 8)
| (u32::from(value.TrinProg ) << 7)
| (u32::from(value.DeviceEn ) << 6)
| (u32::from(value.AddrInc as u8) << 4)
| value.SIZE.to_u32().unwrap()
);
define_ap_register!(
MemoryAP,
DRW,
0x0C,
[(data: u32),],
value,
DRW { data: value },
value.data
);
define_ap_register!(
MemoryAP,
MBT,
0x20,
[(data: u32)],
value,
MBT { data: value },
value.data
);
define_ap_register!(
MemoryAP,
TAR,
0x04,
[(address: u32),],
value,
TAR { address: value },
value.address
);