Skip to content

Commit 1c9d36e

Browse files
bors[bot]cbiffle
andauthored
Merge #225 #226
225: Initial ARMv8-M MPU support. r=adamgreig a=cbiffle The v8-M MPU is entirely different from, and incompatible with, the earlier PMSA MPU. And so this commit does two things: 1. Makes the old RegisterBlock depend on armv6m (for M0+) and armv7m. 2. Defines a new RegisterBlock containing the right layout for v8m. The hack for documenting fields by opting in x86-64 means the v8m version won't appear in the docs. 226: Expose the orphaned ICTR/ACTLR registers. r=adamgreig a=cbiffle 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. Co-authored-by: Cliff L. Biffle <[email protected]>
3 parents b725dfb + 1c198a1 + a06010e commit 1c9d36e

File tree

3 files changed

+113
-2
lines changed

3 files changed

+113
-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: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
//!
5656
//! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3
5757
58-
// TODO stand-alone registers: ICTR, ACTLR and STIR
58+
// TODO stand-alone register: STIR
5959

6060
use core::marker::PhantomData;
6161
use core::ops;
@@ -72,6 +72,7 @@ pub mod fpb;
7272
// NOTE(target_arch) is for documentation purposes
7373
#[cfg(any(has_fpu, target_arch = "x86_64"))]
7474
pub mod fpu;
75+
pub mod icb;
7576
#[cfg(all(not(armv6m), not(armv8m_base)))]
7677
pub mod itm;
7778
pub mod mpu;
@@ -112,6 +113,12 @@ pub struct Peripherals {
112113
/// Floating Point Unit.
113114
pub FPU: FPU,
114115

116+
/// Implementation Control Block.
117+
///
118+
/// The name is from the v8-M spec, but the block existed in earlier
119+
/// revisions, without a name.
120+
pub ICB: ICB,
121+
115122
/// Instrumentation Trace Macrocell.
116123
/// Not available on Armv6-M and Armv8-M Baseline.
117124
pub ITM: ITM,
@@ -182,6 +189,9 @@ impl Peripherals {
182189
FPU: FPU {
183190
_marker: PhantomData,
184191
},
192+
ICB: ICB {
193+
_marker: PhantomData,
194+
},
185195
ITM: ITM {
186196
_marker: PhantomData,
187197
},
@@ -365,6 +375,42 @@ impl ops::Deref for FPU {
365375
}
366376
}
367377

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

src/peripheral/mpu.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
use volatile_register::{RO, RW};
44

5-
/// Register block
5+
/// Register block for ARMv7-M
6+
#[cfg(any(armv6m, armv7m, target_arch = "x86_64"))] // x86-64 is for rustdoc
67
#[repr(C)]
78
pub struct RegisterBlock {
89
/// Type
@@ -28,3 +29,37 @@ pub struct RegisterBlock {
2829
/// Alias 3 of RSAR
2930
pub rsar_a3: RW<u32>,
3031
}
32+
33+
/// Register block for ARMv8-M
34+
#[cfg(armv8m)]
35+
#[repr(C)]
36+
pub struct RegisterBlock {
37+
/// Type
38+
pub _type: RO<u32>,
39+
/// Control
40+
pub ctrl: RW<u32>,
41+
/// Region Number
42+
pub rnr: RW<u32>,
43+
/// Region Base Address
44+
pub rbar: RW<u32>,
45+
/// Region Limit Address
46+
pub rlar: RW<u32>,
47+
/// Alias 1 of RBAR
48+
pub rbar_a1: RW<u32>,
49+
/// Alias 1 of RLAR
50+
pub rlar_a1: RW<u32>,
51+
/// Alias 2 of RBAR
52+
pub rbar_a2: RW<u32>,
53+
/// Alias 2 of RLAR
54+
pub rlar_a2: RW<u32>,
55+
/// Alias 3 of RBAR
56+
pub rbar_a3: RW<u32>,
57+
/// Alias 3 of RLAR
58+
pub rlar_a3: RW<u32>,
59+
60+
// Reserved word at offset 0xBC
61+
_reserved: u32,
62+
63+
/// Memory Attribute Indirection register 0 and 1
64+
pub mair: [RW<u32>; 2],
65+
}

0 commit comments

Comments
 (0)