1use crate::{
27 interrupt::InterruptHandler,
28 pac,
29 peripherals::{ASSIST_DEBUG, Interrupt},
30};
31
32pub struct DebugAssist<'d> {
34 debug_assist: ASSIST_DEBUG<'d>,
35}
36
37impl<'d> DebugAssist<'d> {
38 pub fn new(debug_assist: ASSIST_DEBUG<'d>) -> Self {
40 DebugAssist { debug_assist }
44 }
45
46 #[instability::unstable]
51 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
52 for core in crate::system::Cpu::other() {
53 crate::interrupt::disable(core, Interrupt::ASSIST_DEBUG);
54 }
55 crate::interrupt::bind_handler(Interrupt::ASSIST_DEBUG, handler);
56 }
57
58 fn regs(&self) -> &pac::assist_debug::RegisterBlock {
59 self.debug_assist.register_block()
60 }
61}
62
63impl crate::private::Sealed for DebugAssist<'_> {}
64
65#[instability::unstable]
66impl crate::interrupt::InterruptConfigurable for DebugAssist<'_> {
67 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
68 self.set_interrupt_handler(handler);
69 }
70}
71
72#[cfg(assist_debug_has_sp_monitor)]
73impl DebugAssist<'_> {
74 pub fn internal_sp_monitor(&mut self, cpu: usize, lower_bound: u32, upper_bound: u32) {
78 let regs = self.regs().cpu(cpu);
79
80 regs.sp_min()
81 .write(|w| unsafe { w.sp_min().bits(lower_bound) });
82
83 regs.sp_max()
84 .write(|w| unsafe { w.sp_max().bits(upper_bound) });
85
86 regs.montr_ena().modify(|_, w| {
87 w.sp_spill_min_ena().set_bit();
88 w.sp_spill_max_ena().set_bit()
89 });
90
91 regs.intr_clr().write(|w| {
92 w.sp_spill_max_clr().set_bit();
93 w.sp_spill_min_clr().set_bit()
94 });
95
96 regs.intr_ena().modify(|_, w| {
97 w.sp_spill_max_intr_ena().set_bit();
98 w.sp_spill_min_intr_ena().set_bit()
99 });
100 }
101
102 fn internal_disable_sp_monitor(&mut self, cpu: usize) {
103 let regs = self.regs().cpu(cpu);
104
105 regs.intr_ena().modify(|_, w| {
106 w.sp_spill_max_intr_ena().clear_bit();
107 w.sp_spill_min_intr_ena().clear_bit()
108 });
109
110 regs.montr_ena().modify(|_, w| {
111 w.sp_spill_min_ena().clear_bit();
112 w.sp_spill_max_ena().clear_bit()
113 });
114 }
115
116 fn internal_clear_sp_monitor_interrupt(&mut self, cpu: usize) {
117 self.regs().cpu(cpu).intr_clr().write(|w| {
118 w.sp_spill_max_clr().set_bit();
119 w.sp_spill_min_clr().set_bit()
120 });
121 }
122
123 fn internal_is_sp_monitor_interrupt_set(&self, cpu: usize) -> bool {
124 let regs = self.regs().cpu(cpu);
125 let intrs = regs.intr_raw().read();
126
127 intrs.sp_spill_max_raw().bit_is_set() || intrs.sp_spill_min_raw().bit_is_set()
128 }
129
130 fn internal_sp_monitor_pc(&self, cpu: usize) -> u32 {
131 self.regs().cpu(cpu).sp_pc().read().sp_pc().bits()
132 }
133
134 pub fn enable_sp_monitor(&mut self, lower_bound: u32, upper_bound: u32) {
138 self.internal_sp_monitor(0, lower_bound, upper_bound);
139 }
140
141 pub fn disable_sp_monitor(&mut self) {
143 self.internal_disable_sp_monitor(0)
144 }
145
146 pub fn clear_sp_monitor_interrupt(&mut self) {
148 self.internal_clear_sp_monitor_interrupt(0)
149 }
150
151 pub fn is_sp_monitor_interrupt_set(&self) -> bool {
153 self.internal_is_sp_monitor_interrupt_set(0)
154 }
155
156 pub fn sp_monitor_pc(&self) -> u32 {
158 self.internal_sp_monitor_pc(0)
159 }
160}
161
162#[cfg(all(assist_debug_has_sp_monitor, multi_core))]
163impl<'d> DebugAssist<'d> {
164 pub fn enable_core1_sp_monitor(&mut self, lower_bound: u32, upper_bound: u32) {
168 self.internal_sp_monitor(1, lower_bound, upper_bound);
169 }
170
171 pub fn disable_core1_sp_monitor(&mut self) {
173 self.internal_disable_sp_monitor(1)
174 }
175
176 pub fn clear_core1_sp_monitor_interrupt(&mut self) {
178 self.internal_clear_sp_monitor_interrupt(1)
179 }
180
181 pub fn is_core1_sp_monitor_interrupt_set(&self) -> bool {
183 self.internal_is_sp_monitor_interrupt_set(1)
184 }
185
186 pub fn core1_sp_monitor_pc(&self) -> u32 {
188 self.internal_sp_monitor_pc(1)
189 }
190}
191
192#[cfg(assist_debug_has_region_monitor)]
193impl DebugAssist<'_> {
194 fn internal_enable_region0_monitor(
195 &mut self,
196 cpu: usize,
197 lower_bound: u32,
198 upper_bound: u32,
199 reads: bool,
200 writes: bool,
201 ) {
202 let regs = self.regs().cpu(cpu);
203
204 regs.area_dram0_0_min()
205 .write(|w| unsafe { w.area_dram0_0_min().bits(lower_bound) });
206
207 regs.area_dram0_0_max()
208 .write(|w| unsafe { w.area_dram0_0_max().bits(upper_bound) });
209
210 regs.montr_ena().modify(|_, w| {
211 w.area_dram0_0_rd_ena().bit(reads);
212 w.area_dram0_0_wr_ena().bit(writes)
213 });
214
215 regs.intr_clr().write(|w| {
216 w.area_dram0_0_rd_clr().set_bit();
217 w.area_dram0_0_wr_clr().set_bit()
218 });
219
220 regs.intr_ena().modify(|_, w| {
221 w.area_dram0_0_rd_intr_ena().set_bit();
222 w.area_dram0_0_wr_intr_ena().set_bit()
223 });
224 }
225
226 fn internal_disable_region0_monitor(&mut self, cpu: usize) {
227 let regs = self.regs().cpu(cpu);
228
229 regs.intr_ena().modify(|_, w| {
230 w.area_dram0_0_rd_intr_ena().clear_bit();
231 w.area_dram0_0_wr_intr_ena().clear_bit()
232 });
233
234 regs.montr_ena().modify(|_, w| {
235 w.area_dram0_0_rd_ena().clear_bit();
236 w.area_dram0_0_wr_ena().clear_bit()
237 });
238 }
239
240 fn internal_clear_region0_monitor_interrupt(&mut self, cpu: usize) {
241 self.regs().cpu(cpu).intr_clr().write(|w| {
242 w.area_dram0_0_rd_clr().set_bit();
243 w.area_dram0_0_wr_clr().set_bit()
244 });
245 }
246
247 fn internal_is_region0_monitor_interrupt_set(&self, cpu: usize) -> bool {
248 let regs = self.regs().cpu(cpu);
249 let intrs = regs.intr_raw().read();
250
251 intrs.area_dram0_0_rd_raw().bit_is_set() || intrs.area_dram0_0_wr_raw().bit_is_set()
252 }
253
254 fn internal_enable_region1_monitor(
255 &mut self,
256 cpu: usize,
257 lower_bound: u32,
258 upper_bound: u32,
259 reads: bool,
260 writes: bool,
261 ) {
262 let regs = self.regs().cpu(cpu);
263
264 regs.area_dram0_1_min()
265 .write(|w| unsafe { w.area_dram0_1_min().bits(lower_bound) });
266
267 regs.area_dram0_1_max()
268 .write(|w| unsafe { w.area_dram0_1_max().bits(upper_bound) });
269
270 regs.montr_ena().modify(|_, w| {
271 w.area_dram0_1_rd_ena().bit(reads);
272 w.area_dram0_1_wr_ena().bit(writes)
273 });
274
275 regs.intr_clr().write(|w| {
276 w.area_dram0_1_rd_clr().set_bit();
277 w.area_dram0_1_wr_clr().set_bit()
278 });
279
280 regs.intr_ena().modify(|_, w| {
281 w.area_dram0_1_rd_intr_ena().set_bit();
282 w.area_dram0_1_wr_intr_ena().set_bit()
283 });
284 }
285
286 fn internal_disable_region1_monitor(&mut self, cpu: usize) {
287 let regs = self.regs().cpu(cpu);
288
289 regs.intr_ena().modify(|_, w| {
290 w.area_dram0_1_rd_intr_ena().clear_bit();
291 w.area_dram0_1_wr_intr_ena().clear_bit()
292 });
293
294 regs.montr_ena().modify(|_, w| {
295 w.area_dram0_1_rd_ena().clear_bit();
296 w.area_dram0_1_wr_ena().clear_bit()
297 });
298 }
299
300 fn internal_clear_region1_monitor_interrupt(&mut self, cpu: usize) {
301 self.regs().cpu(cpu).intr_clr().write(|w| {
302 w.area_dram0_1_rd_clr().set_bit();
303 w.area_dram0_1_wr_clr().set_bit()
304 });
305 }
306
307 fn internal_is_region1_monitor_interrupt_set(&self, cpu: usize) -> bool {
308 let regs = self.regs().cpu(cpu);
309 let intrs = regs.intr_raw().read();
310
311 intrs.area_dram0_1_rd_raw().bit_is_set() || intrs.area_dram0_1_wr_raw().bit_is_set()
312 }
313
314 fn internal_region_monitor_pc(&self, cpu: usize) -> u32 {
315 self.regs().cpu(cpu).area_pc().read().area_pc().bits()
316 }
317
318 pub fn enable_region0_monitor(
323 &mut self,
324 lower_bound: u32,
325 upper_bound: u32,
326 reads: bool,
327 writes: bool,
328 ) {
329 self.internal_enable_region0_monitor(0, lower_bound, upper_bound, reads, writes)
330 }
331
332 pub fn disable_region0_monitor(&mut self) {
334 self.internal_disable_region0_monitor(0)
335 }
336
337 pub fn clear_region0_monitor_interrupt(&mut self) {
339 self.internal_clear_region0_monitor_interrupt(0)
340 }
341
342 pub fn is_region0_monitor_interrupt_set(&self) -> bool {
344 self.internal_is_region0_monitor_interrupt_set(0)
345 }
346
347 pub fn enable_region1_monitor(
351 &mut self,
352 lower_bound: u32,
353 upper_bound: u32,
354 reads: bool,
355 writes: bool,
356 ) {
357 self.internal_enable_region1_monitor(0, lower_bound, upper_bound, reads, writes)
358 }
359
360 pub fn disable_region1_monitor(&mut self) {
362 self.internal_disable_region1_monitor(0)
363 }
364
365 pub fn clear_region1_monitor_interrupt(&mut self) {
367 self.internal_clear_region1_monitor_interrupt(0)
368 }
369
370 pub fn is_region1_monitor_interrupt_set(&self) -> bool {
372 self.internal_is_region1_monitor_interrupt_set(0)
373 }
374
375 pub fn region_monitor_pc(&self) -> u32 {
377 self.internal_region_monitor_pc(0)
378 }
379}
380
381#[cfg(all(assist_debug_has_region_monitor, multi_core))]
382impl DebugAssist<'_> {
383 pub fn enable_core1_region0_monitor(
387 &mut self,
388 lower_bound: u32,
389 upper_bound: u32,
390 reads: bool,
391 writes: bool,
392 ) {
393 self.internal_enable_region0_monitor(1, lower_bound, upper_bound, reads, writes)
394 }
395
396 pub fn disable_core1_region0_monitor(&mut self) {
398 self.internal_disable_region0_monitor(1)
399 }
400
401 pub fn clear_core1_region0_monitor_interrupt(&mut self) {
403 self.internal_clear_region0_monitor_interrupt(1)
404 }
405
406 pub fn is_core1_region0_monitor_interrupt_set(&self) -> bool {
408 self.internal_is_region0_monitor_interrupt_set(1)
409 }
410
411 pub fn enable_core1_region1_monitor(
415 &mut self,
416 lower_bound: u32,
417 upper_bound: u32,
418 reads: bool,
419 writes: bool,
420 ) {
421 self.internal_enable_region1_monitor(1, lower_bound, upper_bound, reads, writes)
422 }
423
424 pub fn disable_core1_region1_monitor(&mut self) {
426 self.internal_disable_region1_monitor(1)
427 }
428
429 pub fn clear_core1_region1_monitor_interrupt(&mut self) {
431 self.internal_clear_region1_monitor_interrupt(1)
432 }
433
434 pub fn is_core1_region1_monitor_interrupt_set(&self) -> bool {
436 self.internal_is_region1_monitor_interrupt_set(1)
437 }
438
439 pub fn core1_region_monitor_pc(&self) -> u32 {
441 self.internal_region_monitor_pc(1)
442 }
443}