Skip to content

Commit 40b16cd

Browse files
committed
Implement ARMv7-R MPU support
1 parent 7dc376b commit 40b16cd

File tree

12 files changed

+771
-72
lines changed

12 files changed

+771
-72
lines changed
Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
11
MIDR { implementer=0x41 variant=0x1 arch=0xf part_no=0xc15 rev=0x3 }
22
CPSR { N=0 Z=1 C=1 V=0 Q=0 J=0 E=0 A=1 I=1 F=1 T=0 MODE=Ok(Sys) }
33
PMSA-v7 MPUIR: Mpuir { iregions: 0, dregions: 16, non_unified: false }
4-
D00 0x00000000 = 00000000 00000000
5-
D01 0x00000000 = 00000000 00000000
6-
D02 0x00000000 = 00000000 00000000
7-
D03 0x00000000 = 00000000 00000000
8-
D04 0x00000000 = 00000000 00000000
9-
D05 0x00000000 = 00000000 00000000
10-
D06 0x00000000 = 00000000 00000000
11-
D07 0x00000000 = 00000000 00000000
12-
D08 0x00000000 = 00000000 00000000
13-
D09 0x00000000 = 00000000 00000000
14-
D10 0x00000000 = 00000000 00000000
15-
D11 0x00000000 = 00000000 00000000
16-
D12 0x00000000 = 00000000 00000000
17-
D13 0x00000000 = 00000000 00000000
18-
D14 0x00000000 = 00000000 00000000
19-
D15 0x00000000 = 00000000 00000000
4+
DRegion 0: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
5+
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
6+
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
7+
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
8+
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
9+
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
10+
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
11+
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
12+
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
13+
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
14+
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
15+
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
16+
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
17+
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
18+
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
19+
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
20+
DRegion 0: Region { base: 0x20000000, size: _16M, subregion_mask: 0, enabled: true, no_exec: false, mem_attr: Cacheable { outer: NonCacheable, inner: WriteThroughNoWriteAllocate, shareable: true } }
21+
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
22+
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
23+
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
24+
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
25+
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
26+
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
27+
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
28+
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
29+
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
30+
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
31+
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
32+
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
33+
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
34+
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
35+
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
2036
SCTLR { IE=0 TE=0 NMFI=0 EE=0 U=0 FI=0 DZ=0 BR=0 RR=0 V=0 I=0 Z=0 SW=0 C=0 A=0 M=0 } before setting C, I and Z
2137
SCTLR { IE=0 TE=0 NMFI=0 EE=0 U=0 FI=0 DZ=0 BR=0 RR=0 V=0 I=1 Z=1 SW=0 C=1 A=0 M=0 } after
Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
11
MIDR { implementer=0x41 variant=0x1 arch=0xf part_no=0xc15 rev=0x3 }
22
CPSR { N=0 Z=1 C=1 V=0 Q=0 J=0 E=0 A=1 I=1 F=1 T=0 MODE=Ok(Sys) }
33
PMSA-v7 MPUIR: Mpuir { iregions: 0, dregions: 16, non_unified: false }
4-
D00 0x00000000 = 00000000 00000000
5-
D01 0x00000000 = 00000000 00000000
6-
D02 0x00000000 = 00000000 00000000
7-
D03 0x00000000 = 00000000 00000000
8-
D04 0x00000000 = 00000000 00000000
9-
D05 0x00000000 = 00000000 00000000
10-
D06 0x00000000 = 00000000 00000000
11-
D07 0x00000000 = 00000000 00000000
12-
D08 0x00000000 = 00000000 00000000
13-
D09 0x00000000 = 00000000 00000000
14-
D10 0x00000000 = 00000000 00000000
15-
D11 0x00000000 = 00000000 00000000
16-
D12 0x00000000 = 00000000 00000000
17-
D13 0x00000000 = 00000000 00000000
18-
D14 0x00000000 = 00000000 00000000
19-
D15 0x00000000 = 00000000 00000000
4+
DRegion 0: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
5+
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
6+
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
7+
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
8+
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
9+
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
10+
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
11+
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
12+
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
13+
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
14+
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
15+
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
16+
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
17+
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
18+
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
19+
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
20+
DRegion 0: Region { base: 0x20000000, size: _16M, subregion_mask: 0, enabled: true, no_exec: false, mem_attr: Cacheable { outer: NonCacheable, inner: WriteThroughNoWriteAllocate, shareable: true } }
21+
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
22+
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
23+
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
24+
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
25+
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
26+
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
27+
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
28+
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
29+
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
30+
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
31+
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
32+
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
33+
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
34+
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
35+
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
2036
SCTLR { IE=0 TE=0 NMFI=0 EE=0 U=0 FI=0 DZ=0 BR=0 RR=0 V=0 I=0 Z=0 SW=0 C=0 A=0 M=0 } before setting C, I and Z
2137
SCTLR { IE=0 TE=0 NMFI=0 EE=0 U=0 FI=0 DZ=0 BR=0 RR=0 V=0 I=1 Z=1 SW=0 C=1 A=0 M=0 } after

cortex-r-examples/src/bin/registers.rs

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,54 @@ fn chip_info() {
3737

3838
#[cfg(arm_architecture = "v7-r")]
3939
fn mpu_pmsa_v7() {
40-
// No nice API for PMSAv7 at this time, so show raw register contents
41-
let mpuir = cortex_r::register::Mpuir::read();
40+
use cortex_r::{
41+
pmsav7::{CacheablePolicy, Config, MemAttr, Mpu, Region, RegionSize},
42+
register::Mpuir,
43+
};
44+
45+
// How many regions?
46+
let mpuir = Mpuir::read();
4247
println!("PMSA-v7 MPUIR: {:?}", mpuir);
43-
for iregion in 1..mpuir.iregions() {
44-
cortex_r::register::Rgnr::write(cortex_r::register::Rgnr(iregion as u32));
45-
let bar = cortex_r::register::Irbar::read();
46-
let rsr = cortex_r::register::Irsr::read();
47-
let racr = cortex_r::register::Iracr::read();
48-
println!(
49-
"I{:02} 0x{:08x} = {:08x} {:08x}",
50-
iregion, bar.0, rsr.0, racr.0
51-
);
48+
49+
// Make an MPU driver
50+
let mut mpu = unsafe { Mpu::new() };
51+
52+
// Look at the existing config
53+
for idx in 0..mpu.num_iregions() {
54+
if let Some(region) = mpu.get_iregion(idx) {
55+
println!("IRegion {}: {:?}", idx, region);
56+
}
5257
}
53-
for dregion in 0..mpuir.dregions() {
54-
cortex_r::register::Rgnr::write(cortex_r::register::Rgnr(dregion as u32));
55-
let bar = cortex_r::register::Drbar::read();
56-
let rsr = cortex_r::register::Drsr::read();
57-
let racr = cortex_r::register::Dracr::read();
58-
println!(
59-
"D{:02} 0x{:08x} = {:08x} {:08x}",
60-
dregion, bar.0, rsr.0, racr.0
61-
);
58+
for idx in 0..mpu.num_dregions() {
59+
if let Some(region) = mpu.get_dregion(idx) {
60+
println!("DRegion {}: {:?}", idx, region);
61+
}
62+
}
63+
64+
// Load a config (but don't enable it)
65+
mpu.configure(&Config {
66+
background_config: true,
67+
dregions: &[Region {
68+
base: 0x2000_0000 as *mut u8,
69+
size: RegionSize::_16M,
70+
subregion_mask: 0x00,
71+
enabled: true,
72+
no_exec: false,
73+
mem_attr: MemAttr::Cacheable {
74+
inner: CacheablePolicy::WriteThroughNoWriteAllocate,
75+
outer: CacheablePolicy::NonCacheable,
76+
shareable: true,
77+
},
78+
}],
79+
iregions: &[],
80+
})
81+
.unwrap();
82+
83+
// Look at the new config
84+
for idx in 0..mpu.num_dregions() {
85+
if let Some(region) = mpu.get_dregion(idx) {
86+
println!("DRegion {}: {:?}", idx, region);
87+
}
6288
}
6389
}
6490

cortex-r/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ pub mod asm;
1414
#[cfg(any(test, arm_architecture = "v8-r"))]
1515
pub mod pmsav8;
1616

17+
#[cfg(any(test, arm_architecture = "v7-r"))]
18+
pub mod pmsav7;
19+
1720
/// Generate an SVC call with the given argument.
1821
///
1922
/// Safe to call even in Supervisor (Svc) mode, as long as your Svc handler

0 commit comments

Comments
 (0)