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