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