Skip to content

Expose the orphaned ICTR/ACTLR registers. #226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/peripheral/icb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! Implementation Control Block

use volatile_register::{RO, RW};

/// Register block
#[repr(C)]
pub struct RegisterBlock {
/// Interrupt Controller Type Register
///
/// The bottom four bits of this register give the number of implemented
/// interrupt lines, divided by 32. So a value of `0b0010` indicates 64
/// interrupts.
#[cfg(any(armv7m, armv8m, target_arch = "x86_64"))]
pub ictr: RO<u32>,

/// The ICTR is not defined in the ARMv6-M Architecture Reference manual, so
/// we replace it with this.
#[cfg(not(any(armv7m, armv8m, target_arch = "x86_64")))]
_reserved: u32,

/// Auxiliary Control Register
///
/// This register is entirely implementation defined -- the standard gives
/// it an address, but does not define its role or contents.
pub actlr: RW<u32>,

/// Coprocessor Power Control Register
#[cfg(armv8m)]
pub cppwr: RW<u32>,
}
48 changes: 47 additions & 1 deletion src/peripheral/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
//!
//! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3

// TODO stand-alone registers: ICTR, ACTLR and STIR
// TODO stand-alone register: STIR

use core::marker::PhantomData;
use core::ops;
Expand All @@ -72,6 +72,7 @@ pub mod fpb;
// NOTE(target_arch) is for documentation purposes
#[cfg(any(has_fpu, target_arch = "x86_64"))]
pub mod fpu;
pub mod icb;
#[cfg(all(not(armv6m), not(armv8m_base)))]
pub mod itm;
pub mod mpu;
Expand Down Expand Up @@ -112,6 +113,12 @@ pub struct Peripherals {
/// Floating Point Unit.
pub FPU: FPU,

/// Implementation Control Block.
///
/// The name is from the v8-M spec, but the block existed in earlier
/// revisions, without a name.
pub ICB: ICB,

/// Instrumentation Trace Macrocell.
/// Not available on Armv6-M and Armv8-M Baseline.
pub ITM: ITM,
Expand Down Expand Up @@ -182,6 +189,9 @@ impl Peripherals {
FPU: FPU {
_marker: PhantomData,
},
ICB: ICB {
_marker: PhantomData,
},
ITM: ITM {
_marker: PhantomData,
},
Expand Down Expand Up @@ -365,6 +375,42 @@ impl ops::Deref for FPU {
}
}

/// Implementation Control Block.
///
/// This block contains implementation-defined registers like `ictr` and
/// `actlr`. It's called the "implementation control block" in the ARMv8-M
/// standard, but earlier standards contained the registers, just without a
/// name.
pub struct ICB {
_marker: PhantomData<*const ()>,
}

unsafe impl Send for ICB {}

impl ICB {
/// Returns a pointer to the register block
#[inline(always)]
pub fn ptr() -> *mut icb::RegisterBlock {
0xE000_E004 as *mut _
}
}

impl ops::Deref for ICB {
type Target = self::icb::RegisterBlock;

#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*Self::ptr() }
}
}

impl ops::DerefMut for ICB {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *Self::ptr() }
}
}

/// Instrumentation Trace Macrocell
pub struct ITM {
_marker: PhantomData<*const ()>,
Expand Down