1use crate::{
2 Core, CoreType, Error, Target,
3 architecture::{
4 arm::{
5 ApV2Address, ArmDebugInterface, FullyQualifiedApAddress,
6 core::{CortexAState, CortexMState},
7 dp::DpAddress,
8 },
9 riscv::{RiscvCoreState, communication_interface::RiscvCommunicationInterface},
10 xtensa::{XtensaCoreState, communication_interface::XtensaCommunicationInterface},
11 },
12};
13
14use super::ResolvedCoreOptions;
15
16#[derive(Debug)]
17pub(crate) struct CombinedCoreState {
18 pub(crate) core_state: CoreState,
19
20 pub(crate) specific_state: SpecificCoreState,
21
22 pub(crate) id: usize,
23}
24
25impl CombinedCoreState {
26 pub fn id(&self) -> usize {
27 self.id
28 }
29
30 pub fn core_type(&self) -> CoreType {
31 self.specific_state.core_type()
32 }
33
34 pub fn jtag_tap_index(&self) -> usize {
35 self.core_state.core_access_options.jtag_tap_index()
36 }
37
38 pub(crate) fn attach_arm<'probe>(
39 &'probe mut self,
40 target: &'probe Target,
41 arm_interface: &'probe mut Box<dyn ArmDebugInterface>,
42 ) -> Result<Core<'probe>, Error> {
43 let name = &target.cores[self.id].name;
44
45 let memory = arm_interface.memory_interface(&self.arm_memory_ap())?;
46
47 let ResolvedCoreOptions::Arm { options, sequence } = &self.core_state.core_access_options
48 else {
49 unreachable!(
50 "The stored core state is not compatible with the ARM architecture. \
51 This should never happen. Please file a bug if it does."
52 );
53 };
54 let debug_sequence = sequence.clone();
55
56 Ok(match &mut self.specific_state {
57 SpecificCoreState::Armv6m(s) => Core::new(
58 self.id,
59 name,
60 target,
61 crate::architecture::arm::armv6m::Armv6m::new(memory, s, debug_sequence)?,
62 ),
63 SpecificCoreState::Armv7a(s) => Core::new(
64 self.id,
65 name,
66 target,
67 crate::architecture::arm::armv7a::Armv7a::new(
68 memory,
69 s,
70 options.debug_base.expect("base_address not specified"),
71 debug_sequence,
72 )?,
73 ),
74 SpecificCoreState::Armv7m(s) | SpecificCoreState::Armv7em(s) => Core::new(
75 self.id,
76 name,
77 target,
78 crate::architecture::arm::armv7m::Armv7m::new(memory, s, debug_sequence)?,
79 ),
80 SpecificCoreState::Armv8a(s) => Core::new(
81 self.id,
82 name,
83 target,
84 crate::architecture::arm::armv8a::Armv8a::new(
85 memory,
86 s,
87 options.debug_base.expect("base_address not specified"),
88 options.cti_base.expect("cti_address not specified"),
89 debug_sequence,
90 )?,
91 ),
92 SpecificCoreState::Armv8m(s) => Core::new(
93 self.id,
94 name,
95 target,
96 crate::architecture::arm::armv8m::Armv8m::new(memory, s, debug_sequence)?,
97 ),
98 _ => {
99 unreachable!(
100 "The stored core state is not compatible with the ARM architecture. \
101 This should never happen. Please file a bug if it does."
102 );
103 }
104 })
105 }
106
107 pub(crate) fn enable_arm_debug(
108 &self,
109 interface: &mut dyn ArmDebugInterface,
110 ) -> Result<(), Error> {
111 let ResolvedCoreOptions::Arm { sequence, options } = &self.core_state.core_access_options
112 else {
113 unreachable!(
114 "The stored core state is not compatible with the ARM architecture. \
115 This should never happen. Please file a bug if it does."
116 );
117 };
118
119 tracing::debug_span!("debug_core_start", id = self.id()).in_scope(|| {
120 sequence.debug_core_start(
122 interface,
123 &self.arm_memory_ap(),
124 self.core_type(),
125 options.debug_base,
126 options.cti_base,
127 )
128 })?;
129
130 Ok(())
131 }
132
133 pub(crate) fn arm_reset_catch_set(
134 &self,
135 interface: &mut dyn ArmDebugInterface,
136 ) -> Result<(), Error> {
137 let ResolvedCoreOptions::Arm { sequence, options } = &self.core_state.core_access_options
138 else {
139 unreachable!(
140 "The stored core state is not compatible with the ARM architecture. \
141 This should never happen. Please file a bug if it does."
142 );
143 };
144
145 let mut memory_interface = interface.memory_interface(&self.arm_memory_ap())?;
146
147 let reset_catch_span = tracing::debug_span!("reset_catch_set", id = self.id()).entered();
148 sequence.reset_catch_set(&mut *memory_interface, self.core_type(), options.debug_base)?;
149
150 drop(reset_catch_span);
151
152 Ok(())
153 }
154
155 pub(crate) fn attach_riscv<'probe>(
156 &'probe mut self,
157 target: &'probe Target,
158 mut interface: RiscvCommunicationInterface<'probe>,
159 ) -> Result<Core<'probe>, Error> {
160 let name = &target.cores[self.id].name;
161
162 let ResolvedCoreOptions::Riscv { options, sequence } = &self.core_state.core_access_options
163 else {
164 unreachable!(
165 "The stored core state is not compatible with the RISC-V architecture. \
166 This should never happen. Please file a bug if it does."
167 );
168 };
169 let debug_sequence = sequence.clone();
170
171 let SpecificCoreState::Riscv(s) = &mut self.specific_state else {
172 unreachable!(
173 "The stored core state is not compatible with the RISC-V architecture. \
174 This should never happen. Please file a bug if it does."
175 );
176 };
177
178 let hart = options.hart_id.unwrap_or_default();
179 interface.select_hart(hart)?;
180
181 Ok(Core::new(
182 self.id,
183 name,
184 target,
185 crate::architecture::riscv::Riscv32::new(interface, s, debug_sequence)?,
186 ))
187 }
188
189 pub(crate) fn attach_xtensa<'probe>(
190 &'probe mut self,
191 target: &'probe Target,
192 interface: XtensaCommunicationInterface<'probe>,
193 ) -> Result<Core<'probe>, Error> {
194 let name = &target.cores[self.id].name;
195
196 let ResolvedCoreOptions::Xtensa { sequence, .. } = &self.core_state.core_access_options
197 else {
198 unreachable!(
199 "The stored core state is not compatible with the Xtensa architecture. \
200 This should never happen. Please file a bug if it does."
201 );
202 };
203 let debug_sequence = sequence.clone();
204
205 let SpecificCoreState::Xtensa(s) = &mut self.specific_state else {
206 unreachable!(
207 "The stored core state is not compatible with the Xtensa architecture. \
208 This should never happen. Please file a bug if it does."
209 );
210 };
211
212 Ok(Core::new(
213 self.id,
214 name,
215 target,
216 crate::architecture::xtensa::Xtensa::new(interface, s, debug_sequence)?,
217 ))
218 }
219
220 pub(crate) fn arm_memory_ap(&self) -> FullyQualifiedApAddress {
226 self.core_state.memory_ap()
227 }
228}
229
230#[derive(Debug)]
232pub struct CoreState {
233 core_access_options: ResolvedCoreOptions,
235}
236
237impl CoreState {
238 pub fn new(core_access_options: ResolvedCoreOptions) -> Self {
240 Self {
241 core_access_options,
242 }
243 }
244
245 pub(crate) fn memory_ap(&self) -> FullyQualifiedApAddress {
246 let ResolvedCoreOptions::Arm { options, .. } = &self.core_access_options else {
247 unreachable!(
248 "The stored core state is not compatible with the ARM architecture. \
249 This should never happen. Please file a bug if it does."
250 );
251 };
252
253 let dp = match options.targetsel {
254 None => DpAddress::Default,
255 Some(x) => DpAddress::Multidrop(x),
256 };
257 match &options.ap {
258 probe_rs_target::ApAddress::V1(ap) => FullyQualifiedApAddress::v1_with_dp(dp, *ap),
259 probe_rs_target::ApAddress::V2(ap) => {
260 FullyQualifiedApAddress::v2_with_dp(dp, ApV2Address::new(*ap))
261 }
262 }
263 }
264}
265
266#[derive(Debug)]
268pub enum SpecificCoreState {
269 Armv6m(CortexMState),
271 Armv7a(CortexAState),
273 Armv7m(CortexMState),
275 Armv7em(CortexMState),
277 Armv8a(CortexAState),
279 Armv8m(CortexMState),
281 Riscv(RiscvCoreState),
283 Xtensa(XtensaCoreState),
285}
286
287impl SpecificCoreState {
288 pub(crate) fn from_core_type(typ: CoreType) -> Self {
289 match typ {
290 CoreType::Armv6m => SpecificCoreState::Armv6m(CortexMState::new()),
291 CoreType::Armv7a => SpecificCoreState::Armv7a(CortexAState::new()),
292 CoreType::Armv7m => SpecificCoreState::Armv7m(CortexMState::new()),
293 CoreType::Armv7em => SpecificCoreState::Armv7m(CortexMState::new()),
294 CoreType::Armv8a => SpecificCoreState::Armv8a(CortexAState::new()),
295 CoreType::Armv8m => SpecificCoreState::Armv8m(CortexMState::new()),
296 CoreType::Riscv => SpecificCoreState::Riscv(RiscvCoreState::new()),
297 CoreType::Xtensa => SpecificCoreState::Xtensa(XtensaCoreState::new()),
298 }
299 }
300
301 pub(crate) fn core_type(&self) -> CoreType {
302 match self {
303 SpecificCoreState::Armv6m(_) => CoreType::Armv6m,
304 SpecificCoreState::Armv7a(_) => CoreType::Armv7a,
305 SpecificCoreState::Armv7m(_) => CoreType::Armv7m,
306 SpecificCoreState::Armv7em(_) => CoreType::Armv7em,
307 SpecificCoreState::Armv8a(_) => CoreType::Armv8a,
308 SpecificCoreState::Armv8m(_) => CoreType::Armv8m,
309 SpecificCoreState::Riscv(_) => CoreType::Riscv,
310 SpecificCoreState::Xtensa(_) => CoreType::Xtensa,
311 }
312 }
313}