cortexm/
dcb.rs

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