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}