cortexm/dcb.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.
//! ARM Debug Control Block
//!
//! <https://developer.arm.com/documentation/ddi0403/latest>
//! Implementation matches `ARM DDI 0403E.e`
use kernel::utilities::registers::interfaces::ReadWriteable;
use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite, WriteOnly};
use kernel::utilities::StaticRef;
register_structs! {
DcbRegisters {
/// Debug Halting Control and Status Register
(0x00 => dhcsr: ReadWrite<u32, DebugHaltingControlAndStatus::Register>),
/// Debug Core Register Selector Register
(0x04 => dcrsr: WriteOnly<u32, DebugCoreRegisterSelector::Register>),
/// Debug Core Register Data Register
(0x08 => dcrdr: ReadWrite<u32, DebugCoreRegisterData::Register>),
/// Debug Exception and Monitor Control Register
(0xC => demcr: ReadWrite<u32, DebugExceptionAndMonitorControl::Register>),
(0x10 => @END),
}
}
register_bitfields![u32,
DebugHaltingControlAndStatus [
/// Debug key. 0xA05F must be written to enable write access to bits 15 through 0.
/// WO.
DBGKEY OFFSET(16) NUMBITS(16),
/// Is 1 if at least one reset happend since last read of this register. Is cleared to 0 on
/// read.
/// RO.
S_RESET_ST OFFSET(25) NUMBITS(1),
/// Is 1 if at least one instruction was retired since last read of this register.
/// It is cleared to 0 after a read of this register.
/// RO.
S_RETIRE_ST OFFSET(24) NUMBITS(1),
/// Is 1 when the processor is locked up doe tu an unrecoverable instruction.
/// RO.
S_LOCKUP OFFSET(20) NUMBITS(4),
/// Is 1 if processor is in debug state.
/// RO.
S_SLEEP OFFSET(18) NUMBITS(1),
/// Is used as a handshake flag for transfers through DCRDR. Writing to DCRSR clears this
/// bit to 0. Is 0 if there is a transfer that has not completed and 1 on completion of the DCRSR transfer.
///
/// RW.
S_REGREADY OFFSET(16) NUMBITS(1),
],
DebugCoreRegisterSelector [
DBGTMP OFFSET(0) NUMBITS(32)
],
DebugCoreRegisterData [
DBGTMP OFFSET(0) NUMBITS(32)
],
DebugExceptionAndMonitorControl [
/// Write 1 to globally enable all DWT and ITM features.
TRCENA OFFSET(24) NUMBITS(1),
/// Debug monitor semaphore bit.
/// Monitor software defined.
MON_REQ OFFSET(19) NUMBITS(1),
/// Write 1 to make step request pending.
MON_STEP OFFSET(18) NUMBITS(1),
/// Write 0 to clear the pending state of the DebugMonitor exception.
/// Writing 1 pends the exception.
MON_PEND OFFSET(17) NUMBITS(1),
/// Write 1 to enable DebugMonitor exception.
MON_EN OFFSET(16) NUMBITS(1),
],
];
const DCB: StaticRef<DcbRegisters> = unsafe { StaticRef::new(0xE000EDF0 as *const DcbRegisters) };
/// Enable the Debug and Trace unit `DWT`
/// This has to be enabled before using any feature of the `DWT`
pub fn enable_debug_and_trace() {
DCB.demcr
.modify(DebugExceptionAndMonitorControl::TRCENA::SET);
}
/// Disable the Debug and Trace unit `DWT`
pub fn disable_debug_and_trace() {
DCB.demcr
.modify(DebugExceptionAndMonitorControl::TRCENA::CLEAR);
}