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