Skip to content

Commit 196d496

Browse files
cbiffleadamgreig
authored andcommitted
Expose the orphaned ICTR/ACTLR registers.
In ARMv7-M these were floating alone in system control space, without a unifying name. As a result, they weren't exposed in earlier versions of this crate. In ARMv8-M they have been given a name, the Implementation Control Block, and more registers have been added. I've used that name for all architecture revisions.
1 parent 6df528a commit 196d496

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

src/peripheral/icb.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! Implementation Control Block
2+
3+
use volatile_register::{RO, RW};
4+
5+
/// Register block
6+
#[repr(C)]
7+
pub struct RegisterBlock {
8+
/// Interrupt Controller Type Register
9+
///
10+
/// The bottom four bits of this register give the number of implemented
11+
/// interrupt lines, divided by 32. So a value of `0b0010` indicates 64
12+
/// interrupts.
13+
#[cfg(any(armv7m, armv8m, target_arch = "x86_64"))]
14+
pub ictr: RO<u32>,
15+
16+
/// The ICTR is not defined in the ARMv6-M Architecture Reference manual, so
17+
/// we replace it with this.
18+
#[cfg(not(any(armv7m, armv8m, target_arch = "x86_64")))]
19+
_reserved: u32,
20+
21+
/// Auxiliary Control Register
22+
///
23+
/// This register is entirely implementation defined -- the standard gives
24+
/// it an address, but does not define its role or contents.
25+
pub actlr: RW<u32>,
26+
27+
/// Coprocessor Power Control Register
28+
#[cfg(armv8m)]
29+
pub cppwr: RW<u32>,
30+
}

src/peripheral/mod.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
//!
6969
//! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3
7070
71-
// TODO stand-alone registers: ICTR, ACTLR and STIR
71+
// TODO stand-alone register: STIR
7272

7373

7474
use core::marker::PhantomData;
@@ -86,6 +86,7 @@ pub mod fpb;
8686
// NOTE(target_arch) is for documentation purposes
8787
#[cfg(any(has_fpu, target_arch = "x86_64"))]
8888
pub mod fpu;
89+
pub mod icb;
8990
#[cfg(not(armv6m))]
9091
pub mod itm;
9192
pub mod mpu;
@@ -122,7 +123,14 @@ pub struct Peripherals {
122123
/// Floating Point Unit (only present on `thumbv7em-none-eabihf`)
123124
pub FPU: FPU,
124125

125-
/// Instrumentation Trace Macrocell (not present on Cortex-M0 variants)
126+
/// Implementation Control Block.
127+
///
128+
/// The name is from the v8-M spec, but the block existed in earlier
129+
/// revisions, without a name.
130+
pub ICB: ICB,
131+
132+
/// Instrumentation Trace Macrocell.
133+
/// Not available on Armv6-M and Armv8-M Baseline.
126134
pub ITM: ITM,
127135

128136
/// Memory Protection Unit
@@ -183,6 +191,9 @@ impl Peripherals {
183191
FPU: FPU {
184192
_marker: PhantomData,
185193
},
194+
ICB: ICB {
195+
_marker: PhantomData,
196+
},
186197
ITM: ITM {
187198
_marker: PhantomData,
188199
},
@@ -362,6 +373,42 @@ impl ops::Deref for FPU {
362373
}
363374
}
364375

376+
/// Implementation Control Block.
377+
///
378+
/// This block contains implementation-defined registers like `ictr` and
379+
/// `actlr`. It's called the "implementation control block" in the ARMv8-M
380+
/// standard, but earlier standards contained the registers, just without a
381+
/// name.
382+
pub struct ICB {
383+
_marker: PhantomData<*const ()>,
384+
}
385+
386+
unsafe impl Send for ICB {}
387+
388+
impl ICB {
389+
/// Returns a pointer to the register block
390+
#[inline(always)]
391+
pub fn ptr() -> *mut icb::RegisterBlock {
392+
0xE000_E004 as *mut _
393+
}
394+
}
395+
396+
impl ops::Deref for ICB {
397+
type Target = self::icb::RegisterBlock;
398+
399+
#[inline(always)]
400+
fn deref(&self) -> &Self::Target {
401+
unsafe { &*Self::ptr() }
402+
}
403+
}
404+
405+
impl ops::DerefMut for ICB {
406+
#[inline(always)]
407+
fn deref_mut(&mut self) -> &mut Self::Target {
408+
unsafe { &mut *Self::ptr() }
409+
}
410+
}
411+
365412
/// Instrumentation Trace Macrocell
366413
pub struct ITM {
367414
_marker: PhantomData<*const ()>,

0 commit comments

Comments
 (0)