use crate::{
interrupt::InterruptHandler,
pac,
peripherals::{ASSIST_DEBUG, Interrupt},
};
pub struct DebugAssist<'d> {
debug_assist: ASSIST_DEBUG<'d>,
}
impl<'d> DebugAssist<'d> {
pub fn new(debug_assist: ASSIST_DEBUG<'d>) -> Self {
DebugAssist { debug_assist }
}
#[instability::unstable]
pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
for core in crate::system::Cpu::other() {
crate::interrupt::disable(core, Interrupt::ASSIST_DEBUG);
}
crate::interrupt::bind_handler(Interrupt::ASSIST_DEBUG, handler);
}
fn regs(&self) -> &pac::assist_debug::RegisterBlock {
self.debug_assist.register_block()
}
}
impl crate::private::Sealed for DebugAssist<'_> {}
#[instability::unstable]
impl crate::interrupt::InterruptConfigurable for DebugAssist<'_> {
fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
self.set_interrupt_handler(handler);
}
}
#[cfg(assist_debug_has_sp_monitor)]
impl DebugAssist<'_> {
pub fn internal_sp_monitor(&mut self, cpu: usize, lower_bound: u32, upper_bound: u32) {
let regs = self.regs().cpu(cpu);
regs.sp_min()
.write(|w| unsafe { w.sp_min().bits(lower_bound) });
regs.sp_max()
.write(|w| unsafe { w.sp_max().bits(upper_bound) });
regs.montr_ena().modify(|_, w| {
w.sp_spill_min_ena().set_bit();
w.sp_spill_max_ena().set_bit()
});
regs.intr_clr().write(|w| {
w.sp_spill_max_clr().set_bit();
w.sp_spill_min_clr().set_bit()
});
regs.intr_ena().modify(|_, w| {
w.sp_spill_max_intr_ena().set_bit();
w.sp_spill_min_intr_ena().set_bit()
});
}
fn internal_disable_sp_monitor(&mut self, cpu: usize) {
let regs = self.regs().cpu(cpu);
regs.intr_ena().modify(|_, w| {
w.sp_spill_max_intr_ena().clear_bit();
w.sp_spill_min_intr_ena().clear_bit()
});
regs.montr_ena().modify(|_, w| {
w.sp_spill_min_ena().clear_bit();
w.sp_spill_max_ena().clear_bit()
});
}
fn internal_clear_sp_monitor_interrupt(&mut self, cpu: usize) {
self.regs().cpu(cpu).intr_clr().write(|w| {
w.sp_spill_max_clr().set_bit();
w.sp_spill_min_clr().set_bit()
});
}
fn internal_is_sp_monitor_interrupt_set(&self, cpu: usize) -> bool {
let regs = self.regs().cpu(cpu);
let intrs = regs.intr_raw().read();
intrs.sp_spill_max_raw().bit_is_set() || intrs.sp_spill_min_raw().bit_is_set()
}
fn internal_sp_monitor_pc(&self, cpu: usize) -> u32 {
self.regs().cpu(cpu).sp_pc().read().sp_pc().bits()
}
pub fn enable_sp_monitor(&mut self, lower_bound: u32, upper_bound: u32) {
self.internal_sp_monitor(0, lower_bound, upper_bound);
}
pub fn disable_sp_monitor(&mut self) {
self.internal_disable_sp_monitor(0)
}
pub fn clear_sp_monitor_interrupt(&mut self) {
self.internal_clear_sp_monitor_interrupt(0)
}
pub fn is_sp_monitor_interrupt_set(&self) -> bool {
self.internal_is_sp_monitor_interrupt_set(0)
}
pub fn sp_monitor_pc(&self) -> u32 {
self.internal_sp_monitor_pc(0)
}
}
#[cfg(all(assist_debug_has_sp_monitor, multi_core))]
impl<'d> DebugAssist<'d> {
pub fn enable_core1_sp_monitor(&mut self, lower_bound: u32, upper_bound: u32) {
self.internal_sp_monitor(1, lower_bound, upper_bound);
}
pub fn disable_core1_sp_monitor(&mut self) {
self.internal_disable_sp_monitor(1)
}
pub fn clear_core1_sp_monitor_interrupt(&mut self) {
self.internal_clear_sp_monitor_interrupt(1)
}
pub fn is_core1_sp_monitor_interrupt_set(&self) -> bool {
self.internal_is_sp_monitor_interrupt_set(1)
}
pub fn core1_sp_monitor_pc(&self) -> u32 {
self.internal_sp_monitor_pc(1)
}
}
#[cfg(assist_debug_has_region_monitor)]
impl DebugAssist<'_> {
fn internal_enable_region0_monitor(
&mut self,
cpu: usize,
lower_bound: u32,
upper_bound: u32,
reads: bool,
writes: bool,
) {
let regs = self.regs().cpu(cpu);
regs.area_dram0_0_min()
.write(|w| unsafe { w.area_dram0_0_min().bits(lower_bound) });
regs.area_dram0_0_max()
.write(|w| unsafe { w.area_dram0_0_max().bits(upper_bound) });
regs.montr_ena().modify(|_, w| {
w.area_dram0_0_rd_ena().bit(reads);
w.area_dram0_0_wr_ena().bit(writes)
});
regs.intr_clr().write(|w| {
w.area_dram0_0_rd_clr().set_bit();
w.area_dram0_0_wr_clr().set_bit()
});
regs.intr_ena().modify(|_, w| {
w.area_dram0_0_rd_intr_ena().set_bit();
w.area_dram0_0_wr_intr_ena().set_bit()
});
}
fn internal_disable_region0_monitor(&mut self, cpu: usize) {
let regs = self.regs().cpu(cpu);
regs.intr_ena().modify(|_, w| {
w.area_dram0_0_rd_intr_ena().clear_bit();
w.area_dram0_0_wr_intr_ena().clear_bit()
});
regs.montr_ena().modify(|_, w| {
w.area_dram0_0_rd_ena().clear_bit();
w.area_dram0_0_wr_ena().clear_bit()
});
}
fn internal_clear_region0_monitor_interrupt(&mut self, cpu: usize) {
self.regs().cpu(cpu).intr_clr().write(|w| {
w.area_dram0_0_rd_clr().set_bit();
w.area_dram0_0_wr_clr().set_bit()
});
}
fn internal_is_region0_monitor_interrupt_set(&self, cpu: usize) -> bool {
let regs = self.regs().cpu(cpu);
let intrs = regs.intr_raw().read();
intrs.area_dram0_0_rd_raw().bit_is_set() || intrs.area_dram0_0_wr_raw().bit_is_set()
}
fn internal_enable_region1_monitor(
&mut self,
cpu: usize,
lower_bound: u32,
upper_bound: u32,
reads: bool,
writes: bool,
) {
let regs = self.regs().cpu(cpu);
regs.area_dram0_1_min()
.write(|w| unsafe { w.area_dram0_1_min().bits(lower_bound) });
regs.area_dram0_1_max()
.write(|w| unsafe { w.area_dram0_1_max().bits(upper_bound) });
regs.montr_ena().modify(|_, w| {
w.area_dram0_1_rd_ena().bit(reads);
w.area_dram0_1_wr_ena().bit(writes)
});
regs.intr_clr().write(|w| {
w.area_dram0_1_rd_clr().set_bit();
w.area_dram0_1_wr_clr().set_bit()
});
regs.intr_ena().modify(|_, w| {
w.area_dram0_1_rd_intr_ena().set_bit();
w.area_dram0_1_wr_intr_ena().set_bit()
});
}
fn internal_disable_region1_monitor(&mut self, cpu: usize) {
let regs = self.regs().cpu(cpu);
regs.intr_ena().modify(|_, w| {
w.area_dram0_1_rd_intr_ena().clear_bit();
w.area_dram0_1_wr_intr_ena().clear_bit()
});
regs.montr_ena().modify(|_, w| {
w.area_dram0_1_rd_ena().clear_bit();
w.area_dram0_1_wr_ena().clear_bit()
});
}
fn internal_clear_region1_monitor_interrupt(&mut self, cpu: usize) {
self.regs().cpu(cpu).intr_clr().write(|w| {
w.area_dram0_1_rd_clr().set_bit();
w.area_dram0_1_wr_clr().set_bit()
});
}
fn internal_is_region1_monitor_interrupt_set(&self, cpu: usize) -> bool {
let regs = self.regs().cpu(cpu);
let intrs = regs.intr_raw().read();
intrs.area_dram0_1_rd_raw().bit_is_set() || intrs.area_dram0_1_wr_raw().bit_is_set()
}
fn internal_region_monitor_pc(&self, cpu: usize) -> u32 {
self.regs().cpu(cpu).area_pc().read().area_pc().bits()
}
pub fn enable_region0_monitor(
&mut self,
lower_bound: u32,
upper_bound: u32,
reads: bool,
writes: bool,
) {
self.internal_enable_region0_monitor(0, lower_bound, upper_bound, reads, writes)
}
pub fn disable_region0_monitor(&mut self) {
self.internal_disable_region0_monitor(0)
}
pub fn clear_region0_monitor_interrupt(&mut self) {
self.internal_clear_region0_monitor_interrupt(0)
}
pub fn is_region0_monitor_interrupt_set(&self) -> bool {
self.internal_is_region0_monitor_interrupt_set(0)
}
pub fn enable_region1_monitor(
&mut self,
lower_bound: u32,
upper_bound: u32,
reads: bool,
writes: bool,
) {
self.internal_enable_region1_monitor(0, lower_bound, upper_bound, reads, writes)
}
pub fn disable_region1_monitor(&mut self) {
self.internal_disable_region1_monitor(0)
}
pub fn clear_region1_monitor_interrupt(&mut self) {
self.internal_clear_region1_monitor_interrupt(0)
}
pub fn is_region1_monitor_interrupt_set(&self) -> bool {
self.internal_is_region1_monitor_interrupt_set(0)
}
pub fn region_monitor_pc(&self) -> u32 {
self.internal_region_monitor_pc(0)
}
}
#[cfg(all(assist_debug_has_region_monitor, multi_core))]
impl DebugAssist<'_> {
pub fn enable_core1_region0_monitor(
&mut self,
lower_bound: u32,
upper_bound: u32,
reads: bool,
writes: bool,
) {
self.internal_enable_region0_monitor(1, lower_bound, upper_bound, reads, writes)
}
pub fn disable_core1_region0_monitor(&mut self) {
self.internal_disable_region0_monitor(1)
}
pub fn clear_core1_region0_monitor_interrupt(&mut self) {
self.internal_clear_region0_monitor_interrupt(1)
}
pub fn is_core1_region0_monitor_interrupt_set(&self) -> bool {
self.internal_is_region0_monitor_interrupt_set(1)
}
pub fn enable_core1_region1_monitor(
&mut self,
lower_bound: u32,
upper_bound: u32,
reads: bool,
writes: bool,
) {
self.internal_enable_region1_monitor(1, lower_bound, upper_bound, reads, writes)
}
pub fn disable_core1_region1_monitor(&mut self) {
self.internal_disable_region1_monitor(1)
}
pub fn clear_core1_region1_monitor_interrupt(&mut self) {
self.internal_clear_region1_monitor_interrupt(1)
}
pub fn is_core1_region1_monitor_interrupt_set(&self) -> bool {
self.internal_is_region1_monitor_interrupt_set(1)
}
pub fn core1_region_monitor_pc(&self) -> u32 {
self.internal_region_monitor_pc(1)
}
}