Skip to content

Commit 4571ff7

Browse files
committed
--wip-- [skip ci]
1 parent 4c61f95 commit 4571ff7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+3026
-2211
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A bunch of things

changelog/changed-rename-ArmProbe-to-ArmMemoryInterface.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

probe-rs-tools/src/bin/probe-rs/cmd/dap_server/peripherals/svd_cache.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::BTreeMap;
22

33
use probe_rs::debug::{get_object_reference, DebugError, ObjectRef};
4-
use probe_rs::MemoryInterface;
4+
use probe_rs::{Error, MemoryInterface};
55

66
/// VariableCache stores available `Variable`s, and provides methods to create and navigate the parent-child relationships of the Variables.
77
#[derive(Debug, Clone, PartialEq)]
@@ -189,7 +189,7 @@ impl Variable {
189189
/// Value of the variable, compatible with DAP
190190
///
191191
/// The value might be retrieved using the `MemoryInterface` to read the value from the target.
192-
pub fn get_value(&self, memory: &mut dyn MemoryInterface) -> String {
192+
pub fn get_value(&self, memory: &mut dyn MemoryInterface<Error = Error>) -> String {
193193
self.variable_kind.get_value(memory)
194194
}
195195
}
@@ -227,7 +227,7 @@ pub enum SvdVariable {
227227
}
228228

229229
impl SvdVariable {
230-
fn get_value(&self, memory: &mut dyn MemoryInterface) -> String {
230+
fn get_value(&self, memory: &mut dyn MemoryInterface<Error = Error>) -> String {
231231
match &self {
232232
SvdVariable::Root => "".to_string(),
233233
// For peripheral and peripheral group, we use the description as the value if there is one, otherwise there is no value

probe-rs-tools/src/bin/probe-rs/cmd/info.rs

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use jep106::JEP106Code;
55
use probe_rs::{
66
architecture::{
77
arm::{
8-
ap::{GenericAp, MemoryAp},
8+
ap::ApClass,
99
armv6m::Demcr,
1010
component::Scs,
1111
dp::{DebugPortId, DebugPortVersion, MinDpSupport, DLPIDR, DPIDR, TARGETID},
@@ -14,8 +14,7 @@ use probe_rs::{
1414
Component, ComponentId, CoresightComponent, PeripheralType,
1515
},
1616
sequences::DefaultArmSequence,
17-
ApInformation, ArmProbeInterface, DpAddress, FullyQualifiedApAddress,
18-
MemoryApInformation, Register,
17+
ArmProbeInterface, DpAddress, FullyQualifiedApAddress, Register,
1918
},
2019
riscv::communication_interface::RiscvCommunicationInterface,
2120
xtensa::communication_interface::{
@@ -292,36 +291,25 @@ fn show_arm_info(interface: &mut dyn ArmProbeInterface, dp: DpAddress) -> Result
292291

293292
let mut tree = Tree::new(dp_node);
294293

295-
let num_access_ports = interface.num_access_ports(dp)?;
296-
297-
for ap_index in 0..num_access_ports {
298-
let ap = FullyQualifiedApAddress::v1_with_dp(dp, ap_index as u8);
299-
let access_port = GenericAp::new(ap);
300-
301-
let ap_information = interface.ap_information(&access_port)?;
302-
303-
match ap_information {
304-
ApInformation::MemoryAp(MemoryApInformation {
305-
debug_base_address,
306-
address,
307-
device_enabled,
308-
..
309-
}) => {
310-
let mut ap_nodes = Tree::new(format!("{} MemoryAP", address.ap_v1()?));
311-
312-
if *device_enabled {
313-
match handle_memory_ap(&access_port.into(), *debug_base_address, interface) {
314-
Ok(component_tree) => ap_nodes.push(component_tree),
315-
Err(e) => ap_nodes.push(format!("Error during access: {e}")),
316-
};
317-
} else {
318-
ap_nodes.push("Access disabled".to_string());
319-
}
320-
294+
let access_ports = interface.access_ports(dp)?;
295+
println!("ARM Chip with debug port {:x?}:", dp);
296+
if access_ports.is_empty() {
297+
println!("No access ports found on this chip.");
298+
} else {
299+
for ap_address in access_ports {
300+
use probe_rs::architecture::arm::ap::IDR;
301+
let idr: IDR = interface
302+
.read_raw_ap_register(&ap_address, IDR::ADDRESS)?
303+
.try_into()?;
304+
305+
if idr.CLASS == ApClass::MemAp {
306+
let mut ap_nodes = Tree::new(format!("{} MemoryAP ({:?})", ap_address.ap_v1()?, idr.TYPE));
307+
match handle_memory_ap(interface, &ap_address) {
308+
Ok(component_tree) => ap_nodes.push(component_tree),
309+
Err(e) => ap_nodes.push(format!("Error during access: {e}")),
310+
};
321311
tree.push(ap_nodes);
322-
}
323-
324-
ApInformation::Other { address, idr } => {
312+
} else {
325313
let jep = idr.DESIGNER;
326314

327315
let ap_type = if idr.DESIGNER == JEP_ARM {
@@ -332,7 +320,7 @@ fn show_arm_info(interface: &mut dyn ArmProbeInterface, dp: DpAddress) -> Result
332320

333321
tree.push(format!(
334322
"{} Unknown AP (Designer: {}, Class: {:?}, Type: {}, Variant: {:#x}, Revision: {:#x})",
335-
address.ap_v1()?,
323+
ap_address.ap_v1()?,
336324
jep.get().unwrap_or("<unknown>"),
337325
idr.CLASS,
338326
ap_type,
@@ -341,26 +329,21 @@ fn show_arm_info(interface: &mut dyn ArmProbeInterface, dp: DpAddress) -> Result
341329
));
342330
}
343331
}
344-
}
345-
346-
println!("ARM Chip with debug port {:x?}:", dp);
347-
println!("{tree}");
348332

349-
if num_access_ports == 0 {
350-
println!("No access ports found on this chip.");
333+
println!("{tree}");
351334
}
352335
println!();
353336

354337
Ok(dp_info.version)
355338
}
356339

357340
fn handle_memory_ap(
358-
access_port: &MemoryAp,
359-
base_address: u64,
360341
interface: &mut dyn ArmProbeInterface,
342+
access_port: &FullyQualifiedApAddress,
361343
) -> Result<Tree<String>, anyhow::Error> {
362344
let component = {
363345
let mut memory = interface.memory_interface(access_port)?;
346+
let base_address = memory.base_address()?;
364347
let mut demcr = Demcr(memory.read_word_32(Demcr::get_mmio_address())?);
365348
demcr.set_dwtena(true);
366349
memory.write_word_32(Demcr::get_mmio_address(), demcr.into())?;
@@ -374,7 +357,7 @@ fn handle_memory_ap(
374357
fn coresight_component_tree(
375358
interface: &mut dyn ArmProbeInterface,
376359
component: Component,
377-
access_port: &MemoryAp,
360+
access_port: &FullyQualifiedApAddress,
378361
) -> Result<Tree<String>> {
379362
let tree = match &component {
380363
Component::GenericVerificationComponent(_) => Tree::new("Generic".to_string()),
@@ -455,7 +438,7 @@ fn process_vendor_rom_tables(
455438
interface: &mut dyn ArmProbeInterface,
456439
id: &ComponentId,
457440
_table: &RomTable,
458-
access_port: &MemoryAp,
441+
access_port: &FullyQualifiedApAddress,
459442
tree: &mut Tree<String>,
460443
) -> Result<()> {
461444
let peripheral_id = id.peripheral_id();
@@ -485,7 +468,7 @@ fn process_component_entry(
485468
interface: &mut dyn ArmProbeInterface,
486469
peripheral_id: &PeripheralID,
487470
component: &Component,
488-
access_port: &MemoryAp,
471+
access_port: &FullyQualifiedApAddress,
489472
) -> Result<()> {
490473
let Some(part) = peripheral_id.determine_part() else {
491474
return Ok(());

probe-rs/src/architecture/arm/ap/generic_ap.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
//! Generic access port
22
3-
use super::{AccessPort, ApRegister, Register};
4-
use crate::architecture::arm::{
5-
communication_interface::RegisterParseError, FullyQualifiedApAddress,
6-
};
3+
use crate::architecture::arm::communication_interface::RegisterParseError;
74

85
/// Describes the class of an access port defined in the [`ARM Debug Interface v5.2`](https://developer.arm.com/documentation/ihi0031/f/?lang=en) specification.
96
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
@@ -70,14 +67,7 @@ impl ApType {
7067
}
7168
}
7269

73-
define_ap!(
74-
/// A generic access port which implements just the register every access port has to implement
75-
/// to be compliant with the ADI 5.2 specification.
76-
GenericAp
77-
);
78-
7970
define_ap_register!(
80-
type: GenericAp,
8171
/// Identification Register
8272
///
8373
/// The identification register is used to identify
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
use crate::architecture::arm::{
2+
ap::{AccessPortType, ApAccess, ApRegAccess},
3+
communication_interface::RegisterParseError,
4+
ArmError, DapAccess, FullyQualifiedApAddress, Register,
5+
};
6+
7+
use super::{AddressIncrement, DataSize};
8+
9+
/// Memory AP
10+
///
11+
/// The memory AP can be used to access a memory-mapped
12+
/// set of debug resources of the attached system.
13+
#[derive(Debug)]
14+
pub struct AmbaAhb3 {
15+
address: FullyQualifiedApAddress,
16+
csw: CSW,
17+
cfg: super::registers::CFG,
18+
}
19+
20+
impl AmbaAhb3 {
21+
/// Creates a new AmbaAhb3 with `address` as base address.
22+
pub fn new<P: DapAccess>(
23+
probe: &mut P,
24+
address: FullyQualifiedApAddress,
25+
) -> Result<Self, ArmError> {
26+
use crate::architecture::arm::Register;
27+
let csw = probe.read_raw_ap_register(&address, CSW::ADDRESS)?;
28+
let cfg = probe.read_raw_ap_register(&address, super::registers::CFG::ADDRESS)?;
29+
let (csw, cfg) = (csw.try_into()?, cfg.try_into()?);
30+
31+
let me = Self { address, csw, cfg };
32+
let csw = CSW {
33+
AddrInc: AddressIncrement::Single,
34+
..me.csw
35+
};
36+
probe.write_ap_register(&me, csw)?;
37+
Ok(Self { csw, ..me })
38+
}
39+
}
40+
41+
impl super::MemoryApType for AmbaAhb3 {
42+
type CSW = CSW;
43+
44+
fn status<P: ApAccess + ?Sized>(&mut self, probe: &mut P) -> Result<Self::CSW, ArmError> {
45+
assert_eq!(super::registers::CSW::ADDRESS, CSW::ADDRESS);
46+
self.csw = probe.read_ap_register(self)?;
47+
Ok(self.csw)
48+
}
49+
50+
fn try_set_datasize<P: ApAccess + ?Sized>(
51+
&mut self,
52+
probe: &mut P,
53+
data_size: DataSize,
54+
) -> Result<(), ArmError> {
55+
match data_size {
56+
DataSize::U8 | DataSize::U16 | DataSize::U32 if data_size != self.csw.Size => {
57+
let csw = CSW {
58+
Size: data_size,
59+
..self.csw
60+
};
61+
probe.write_ap_register(self, csw)?;
62+
self.csw = csw;
63+
}
64+
DataSize::U64 | DataSize::U128 | DataSize::U256 => {
65+
return Err(ArmError::UnsupportedTransferWidth(
66+
data_size.to_byte_count() * 8,
67+
))
68+
}
69+
_ => {}
70+
}
71+
Ok(())
72+
}
73+
74+
fn has_large_address_extension(&self) -> bool {
75+
self.cfg.LA
76+
}
77+
78+
fn has_large_data_extension(&self) -> bool {
79+
self.cfg.LD
80+
}
81+
82+
fn supports_only_32bit_data_size(&self) -> bool {
83+
// Amba AHB3 must support word, half-word and byte size transfers.
84+
false
85+
}
86+
}
87+
88+
impl AccessPortType for AmbaAhb3 {
89+
fn ap_address(&self) -> &FullyQualifiedApAddress {
90+
&self.address
91+
}
92+
}
93+
94+
impl ApRegAccess<CSW> for AmbaAhb3 {}
95+
96+
crate::attached_regs_to_mem_ap!(memory_ap_regs => AmbaAhb3);
97+
98+
define_ap_register!(
99+
/// Control and Status Word register
100+
///
101+
/// The control and status word register (CSW) is used
102+
/// to configure memory access through the memory AP.
103+
name: CSW,
104+
address: 0x00,
105+
fields: [
106+
/// Is debug software access enabled.
107+
DbgSwEnable: bool, // [31]
108+
/// HNONSEC
109+
///
110+
/// Not formally defined.
111+
/// If implemented should be 1 at reset.
112+
/// If not implemented, should be 1 and writing 0 leads to unpredictable AHB-AP behavior.
113+
HNONSEC: bool, // [30]
114+
/// Defines which Requester ID is used on `HMASTER[3:0]` signals.
115+
///
116+
/// Support of this function is implementation defined.
117+
MasterType: bool, // [29]
118+
/// Drives `HPROT[4]`, Allocate.
119+
///
120+
/// `HPROT[4]` is an Armv5 extension to AHB. For more information, see the Arm1136JF-S™ and
121+
/// Arm1136J-S ™ Technical Reference Manual.
122+
Allocate: bool, // [28]
123+
/// `HPROT[3]`
124+
Cacheable: bool, // [27]
125+
/// `HPROT[2]`
126+
Bufferable: bool, // [26]
127+
/// `HPROT[1]`
128+
Privileged: bool, // [25]
129+
/// `HPROT[0]`
130+
Data: bool, // [24]
131+
/// Secure Debug Enabled.
132+
///
133+
/// This field has one of the following values:
134+
/// - `0b0` Secure access is disabled.
135+
/// - `0b1` Secure access is enabled.
136+
/// This field is optional, and read-only. If not implemented, the bit is RES0.
137+
/// If CSW.DeviceEn is 0b0, SPIDEN is ignored and the effective value of SPIDEN is 0b1.
138+
/// For more information, see `Enabling access to the connected debug device or memory system`
139+
/// on page C2-154.
140+
///
141+
/// Note:
142+
/// In ADIv5 and older versions of the architecture, the CSW.SPIDEN field is in the same bit
143+
/// position as CSW.SDeviceEn, and has the same meaning. From ADIv6, the name SDeviceEn is
144+
/// used to avoid confusion between this field and the SPIDEN signal on the authentication
145+
/// interface.
146+
SPIDEN: bool, // [23]
147+
/// A transfer is in progress.
148+
/// Can be used to poll whether an aborted transaction has completed.
149+
/// Read only.
150+
TrInProg: bool, // [7]
151+
/// `1` if transactions can be issued through this access port at the moment.
152+
/// Read only.
153+
DeviceEn: bool, // [6]
154+
/// The address increment on DRW access.
155+
AddrInc: AddressIncrement, // [5:4]
156+
/// The access size of this memory AP.
157+
Size: DataSize, // [2:0]
158+
/// Reserved bit, kept to preserve IMPLEMENTATION DEFINED statuses.
159+
_reserved_bits: u32 // mask
160+
],
161+
from: value => Ok(CSW {
162+
DbgSwEnable: ((value >> 31) & 0x01) != 0,
163+
HNONSEC: ((value >> 30) & 0x01) != 0,
164+
MasterType: ((value >> 29) & 0x01) != 0,
165+
Allocate: ((value >> 28) & 0x01) != 0,
166+
Cacheable: ((value >> 27) & 0x01) != 0,
167+
Bufferable: ((value >> 26) & 0x01) != 0,
168+
Privileged: ((value >> 25) & 0x01) != 0,
169+
Data: ((value >> 24) & 0x01) != 0,
170+
SPIDEN: ((value >> 23) & 0x01) != 0,
171+
TrInProg: ((value >> 7) & 0x01) != 0,
172+
DeviceEn: ((value >> 6) & 0x01) != 0,
173+
AddrInc: AddressIncrement::from_u8(((value >> 4) & 0x03) as u8).ok_or_else(|| RegisterParseError::new("CSW", value))?,
174+
Size: DataSize::try_from((value & 0x07) as u8).map_err(|_| RegisterParseError::new("CSW", value))?,
175+
_reserved_bits: value & 0x007F_FF08,
176+
}),
177+
to: value => (u32::from(value.DbgSwEnable) << 31)
178+
| (u32::from(value.HNONSEC ) << 30)
179+
| (u32::from(value.MasterType ) << 29)
180+
| (u32::from(value.Allocate ) << 28)
181+
| (u32::from(value.Cacheable ) << 27)
182+
| (u32::from(value.Bufferable ) << 26)
183+
| (u32::from(value.Privileged ) << 25)
184+
| (u32::from(value.Data ) << 24)
185+
| (u32::from(value.SPIDEN ) << 23)
186+
| (u32::from(value.TrInProg ) << 7)
187+
| (u32::from(value.DeviceEn ) << 6)
188+
| (u32::from(value.AddrInc as u8) << 4)
189+
| (value.Size as u32)
190+
| value._reserved_bits
191+
);

0 commit comments

Comments
 (0)