forked from tock/tock
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cortex-m: Add initial dwt and dcb support
The DWT and DCB peripherals are used to access various debug functionality in the chip, such as various counters. This commits adds register descriptions for most of DWT and all of the DCB. It also adds a very simple capsule that allows starting, stopping, reading, and resetting the cycle counter from userspace.
- Loading branch information
1 parent
dacf18b
commit 83518e4
Showing
9 changed files
with
719 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,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); | ||
} |
Oops, something went wrong.