probe_rs_target/
chip.rs

1use std::collections::HashMap;
2
3use super::memory::MemoryRegion;
4use crate::{CoreType, serialize::hex_option};
5use serde::{Deserialize, Serialize};
6
7/// Represents a DAP scan chain element.
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub struct ScanChainElement {
10    /// Unique name of the DAP
11    pub name: Option<String>,
12    /// Specifies the IR length of the DAP (default value: 4).
13    pub ir_len: Option<u8>,
14}
15
16impl ScanChainElement {
17    /// Returns the IR length, or 4 if not specified.
18    pub fn ir_len(&self) -> u8 {
19        self.ir_len.unwrap_or(4)
20    }
21}
22
23/// Configuration for JTAG tunneling.
24///
25/// This JTAG tunnel wraps JTAG IR and DR accesses as DR access to a specific instruction. For
26/// example, this can be used to access a Risc-V core in an FPGA using the same JTAG cable that
27/// configures the FPGA.
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
29pub struct RiscvJtagTunnel {
30    /// JTAG instruction used to tunnel
31    pub ir_id: u32,
32
33    /// Width of tunneled JTAG instruction register
34    pub ir_width: u32,
35}
36
37/// Configuration for JTAG probes.
38#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
39pub struct Jtag {
40    /// Describes the scan chain
41    ///
42    /// ref: `<https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/sdf_pg.html#sdf_element_scanchain>`
43    #[serde(default)]
44    pub scan_chain: Option<Vec<ScanChainElement>>,
45
46    /// Describes JTAG tunnel for Risc-V
47    #[serde(default)]
48    pub riscv_tunnel: Option<RiscvJtagTunnel>,
49}
50
51/// A single chip variant.
52///
53/// This describes an exact chip variant, including the cores, flash and memory size. For example,
54/// the `nRF52832` chip has two variants, `nRF52832_xxAA` and `nRF52832_xxBB`. For this case,
55/// the struct will correspond to one of the variants, e.g. `nRF52832_xxAA`.
56#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(deny_unknown_fields)]
58pub struct Chip {
59    /// This is the name of the chip in base form.
60    /// E.g. `nRF52832`.
61    pub name: String,
62    /// The `PART` register of the chip.
63    /// This value can be determined via the `cli info` command.
64    pub part: Option<u16>,
65    /// An URL to the SVD file for this chip.
66    pub svd: Option<String>,
67    /// Documentation URLs associated with this chip.
68    #[serde(default)]
69    pub documentation: HashMap<String, url::Url>,
70    /// The package variants available for this chip.
71    ///
72    /// If empty, the chip is assumed to have only one package variant.
73    #[serde(default)]
74    pub package_variants: Vec<String>,
75    /// The cores available on the chip.
76    #[serde(default)]
77    pub cores: Vec<Core>,
78    /// The memory regions available on the chip.
79    pub memory_map: Vec<MemoryRegion>,
80    /// Names of all flash algorithms available for this chip.
81    ///
82    /// This can be used to look up the flash algorithm in the
83    /// [`ChipFamily::flash_algorithms`] field.
84    ///
85    /// [`ChipFamily::flash_algorithms`]: crate::ChipFamily::flash_algorithms
86    #[serde(default)]
87    pub flash_algorithms: Vec<String>,
88    /// Specific memory ranges to search for a dynamic RTT header for code
89    /// running on this chip.
90    ///
91    /// This need not be specified for most chips because the default is
92    /// to search all RAM regions specified in `memory_map`. However,
93    /// that behavior isn't appropriate for some chips, such as those which
94    /// have a very large amount of RAM that would be time-consuming to
95    /// scan exhaustively.
96    ///
97    /// If specified then this is a list of zero or more address ranges to
98    /// scan. Each address range must be enclosed in exactly one RAM region
99    /// from `memory_map`. An empty list disables automatic scanning
100    /// altogether, in which case RTT will be enabled only when using an
101    /// executable image that includes the `_SEGGER_RTT` symbol pointing
102    /// to the exact address of the RTT header.
103    pub rtt_scan_ranges: Option<Vec<std::ops::Range<u64>>>,
104    /// JTAG-specific options
105    #[serde(default)]
106    pub jtag: Option<Jtag>,
107    /// The default binary format for this chip
108    // TODO: rename to default_platform
109    #[serde(default)]
110    pub default_binary_format: Option<String>,
111}
112
113impl Chip {
114    /// Create a generic chip with the given name, a single core,
115    /// and no flash algorithm or memory map. Used to create
116    /// generic targets.
117    pub fn generic_arm(name: &str, core_type: CoreType) -> Self {
118        Chip {
119            name: name.to_string(),
120            part: None,
121            svd: None,
122            documentation: HashMap::new(),
123            package_variants: vec![],
124            cores: vec![Core {
125                name: "main".to_string(),
126                core_type,
127                core_access_options: CoreAccessOptions::Arm(ArmCoreAccessOptions::default()),
128            }],
129            memory_map: vec![],
130            flash_algorithms: vec![],
131            rtt_scan_ranges: None,
132            jtag: None,
133            default_binary_format: None,
134        }
135    }
136
137    /// Returns the package variants for this chip.
138    pub fn package_variants(&self) -> impl Iterator<Item = &String> {
139        std::slice::from_ref(&self.name)
140            .iter()
141            .chain(self.package_variants.iter())
142    }
143}
144
145/// An individual core inside a chip
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct Core {
148    /// The core name.
149    pub name: String,
150
151    /// The core type.
152    /// E.g. `M0` or `M4`.
153    #[serde(rename = "type")]
154    pub core_type: CoreType,
155
156    /// The AP number to access the core
157    pub core_access_options: CoreAccessOptions,
158}
159
160/// The data required to access a core
161#[derive(Debug, Clone, Serialize, Deserialize)]
162pub enum CoreAccessOptions {
163    /// ARM specific options
164    Arm(ArmCoreAccessOptions),
165    /// RISC-V specific options
166    Riscv(RiscvCoreAccessOptions),
167    /// Xtensa specific options
168    Xtensa(XtensaCoreAccessOptions),
169}
170
171/// An address for AP accesses
172#[derive(Debug, Clone, Serialize, Deserialize)]
173pub enum ApAddress {
174    /// References an address for an APv1 access, which is part of the ADIv5 specification.
175    #[serde(rename = "v1")]
176    V1(u8),
177    /// References an address for an APv2 access, which is part of the ADIv6 specification.
178    ///
179    /// # Note
180    /// This represents a base address within the root DP memory space.
181    #[serde(rename = "v2")]
182    V2(u64),
183}
184
185impl Default for ApAddress {
186    fn default() -> Self {
187        ApAddress::V1(0)
188    }
189}
190
191/// The data required to access an ARM core
192#[derive(Debug, Clone, Serialize, Deserialize, Default)]
193#[serde(deny_unknown_fields)]
194pub struct ArmCoreAccessOptions {
195    /// The access port number to access the core
196    pub ap: ApAddress,
197    /// The TARGETSEL value used to access the core
198    #[serde(serialize_with = "hex_option")]
199    pub targetsel: Option<u32>,
200    /// The base address of the debug registers for the core.
201    /// Required for Cortex-A, optional for Cortex-M
202    #[serde(serialize_with = "hex_option")]
203    pub debug_base: Option<u64>,
204    /// The base address of the cross trigger interface (CTI) for the core.
205    /// Required in ARMv8-A
206    #[serde(serialize_with = "hex_option")]
207    pub cti_base: Option<u64>,
208
209    /// The JTAG TAP index of the core's debug module
210    pub jtag_tap: Option<usize>,
211}
212
213/// The data required to access a Risc-V core
214#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct RiscvCoreAccessOptions {
216    /// The hart id
217    pub hart_id: Option<u32>,
218
219    /// The JTAG TAP index of the core's debug module
220    pub jtag_tap: Option<usize>,
221}
222
223/// The data required to access an Xtensa core
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct XtensaCoreAccessOptions {
226    /// The JTAG TAP index of the core's debug module
227    pub jtag_tap: Option<usize>,
228}