Skip to content

Commit

Permalink
Merge pull request #3934 from hudson-ayers/hudson.ayers/cycle_counter
Browse files Browse the repository at this point in the history
cortex-m: Add initial dwt and dcb support, take 2
  • Loading branch information
ppannuto committed May 1, 2024
2 parents c8cce8b + 60d9f84 commit 984bc40
Show file tree
Hide file tree
Showing 10 changed files with 733 additions and 0 deletions.
100 changes: 100 additions & 0 deletions arch/cortex-m/src/dcb.rs
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);
}

0 comments on commit 984bc40

Please sign in to comment.