Skip to content

Commit a2a8fca

Browse files
Merge pull request #186 from rikyborg/region-access-perms
Region access perms
2 parents eeb569f + 36c3184 commit a2a8fca

7 files changed

Lines changed: 200 additions & 132 deletions

File tree

aarch32-cpu/src/pmsav7.rs

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ impl Mpu {
6969
};
7070

7171
let mem_attr = mem_attr_bits.decode()?;
72+
let access_perms = AccessPerms::from_bits(racr.ap())?;
7273

7374
Some(Region {
7475
base,
@@ -77,6 +78,7 @@ impl Mpu {
7778
enabled: rsr.enabled(),
7879
no_exec: racr.nx(),
7980
mem_attr,
81+
access_perms,
8082
})
8183
}
8284

@@ -97,6 +99,7 @@ impl Mpu {
9799
s: racr.s(),
98100
};
99101
let mem_attr = mem_attr_bits.decode()?;
102+
let access_perms = AccessPerms::from_bits(racr.ap())?;
100103

101104
Some(Region {
102105
base,
@@ -105,6 +108,7 @@ impl Mpu {
105108
enabled: rsr.enabled(),
106109
no_exec: racr.nx(),
107110
mem_attr,
111+
access_perms,
108112
})
109113
}
110114

@@ -137,7 +141,7 @@ impl Mpu {
137141
out.set_b(mem_attr_bits.b);
138142
out.set_s(mem_attr_bits.s);
139143
out.set_nx(region.no_exec);
140-
// out.with_ap(region.access_perms);
144+
out.set_ap(region.access_perms.to_bits());
141145
out
142146
});
143147
}
@@ -162,7 +166,7 @@ impl Mpu {
162166
out.set_b(mem_attr_bits.b);
163167
out.set_s(mem_attr_bits.s);
164168
out.set_nx(region.no_exec);
165-
// out.with_ap(region.access_perms);
169+
out.set_ap(region.access_perms.to_bits());
166170
out
167171
});
168172
}
@@ -226,6 +230,8 @@ pub struct Region {
226230
pub no_exec: bool,
227231
/// Attributes for this region
228232
pub mem_attr: MemAttr,
233+
/// Access permissions for this region
234+
pub access_perms: AccessPerms,
229235
}
230236

231237
// Creating a static Region is fine - the pointers within it
@@ -403,6 +409,66 @@ pub enum CachePolicy {
403409
WriteBackNoWriteAlloc = 0b11,
404410
}
405411

412+
/// Describes the access permissions of a memory region
413+
///
414+
/// Access permission bits control read and write access to the corresponding memory region.
415+
/// Permissions are specified for priviledged accesses (PL1) and for user accesses (PL0).
416+
/// Accesses to a memory region without the required permissions generate a Permission fault.
417+
///
418+
/// Note that the execute-never (XN) attribute provides an additional permission check on memory
419+
/// regions, see [Region::no_exec].
420+
#[derive(Debug, Clone, PartialEq, Eq)]
421+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
422+
pub enum AccessPerms {
423+
/// All accesses generate a Permission fault
424+
/// - PL1: No access
425+
/// - PL0: No access
426+
NoAccess,
427+
/// All write accesses generate Permission faults
428+
/// - PL1: Read-only
429+
/// - PL0: Read-only
430+
ReadOnly,
431+
/// Full access
432+
/// - PL1: Read/Write
433+
/// - PL0: Read/Write
434+
ReadWrite,
435+
/// PL1 read-only, all other accesses generate Permission faults
436+
/// - PL1: Read-only
437+
/// - PL0: No access
438+
PrivReadOnly,
439+
/// All unprivileged accesses generate Permission faults
440+
/// - PL1: Read/Write
441+
/// - PL0: No access
442+
PrivReadWrite,
443+
/// User mode write accesses generate Permission faults
444+
/// - PL1: Read/Write
445+
/// - PL0: Read-only
446+
PrivReadWriteUserReadOnly,
447+
}
448+
impl AccessPerms {
449+
const fn to_bits(&self) -> u3 {
450+
u3::new(match self {
451+
Self::NoAccess => 0b000,
452+
Self::PrivReadWrite => 0b001,
453+
Self::PrivReadWriteUserReadOnly => 0b010,
454+
Self::ReadWrite => 0b011,
455+
Self::PrivReadOnly => 0b101,
456+
Self::ReadOnly => 0b110,
457+
})
458+
}
459+
const fn from_bits(ap: u3) -> Option<Self> {
460+
match ap.value() {
461+
0b000 => Some(Self::NoAccess),
462+
0b001 => Some(Self::PrivReadWrite),
463+
0b010 => Some(Self::PrivReadWriteUserReadOnly),
464+
0b011 => Some(Self::ReadWrite),
465+
0b101 => Some(Self::PrivReadOnly),
466+
0b110 => Some(Self::ReadOnly),
467+
_ => None,
468+
}
469+
}
470+
}
471+
406472
#[cfg(test)]
407473
mod test {
408474
use super::*;

examples/mps3-an536/src/bin/registers.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fn chip_info() {
3636
#[cfg(arm_architecture = "v7-r")]
3737
fn mpu_pmsa_v7() {
3838
use aarch32_cpu::{
39-
pmsav7::{Cacheable, Config, MemAttr, Mpu, Region, RegionSize},
39+
pmsav7::{AccessPerms, Cacheable, Config, MemAttr, Mpu, Region, RegionSize},
4040
register::Mpuir,
4141
};
4242

@@ -73,6 +73,7 @@ fn mpu_pmsa_v7() {
7373
outer: Cacheable::NonCacheable,
7474
shareable: true,
7575
},
76+
access_perms: AccessPerms::ReadWrite,
7677
}],
7778
iregions: &[],
7879
})

examples/versatileab/reference/registers-armv7r-none-eabi.out

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,35 @@ Mpidr(c0000000)
44
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=1 A=0 M=0 } before setting C, I and Z
55
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
66
PMSA-v7 MPUIR: Mpuir { iregions: 0, dregions: 16, non_unified: false }
7-
DRegion 0: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
8-
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
9-
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
10-
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
11-
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
12-
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
13-
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
14-
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
15-
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
16-
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
17-
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
18-
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
19-
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
20-
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
21-
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
22-
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
23-
DRegion 0: Region { base: 0x20000000, size: _16M, subregion_mask: 0, enabled: true, no_exec: false, mem_attr: Cacheable { outer: NonCacheable, inner: WriteThroughNoWriteAlloc, shareable: true } }
24-
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
25-
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
26-
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
27-
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
28-
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
29-
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
30-
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
31-
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
32-
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
33-
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
34-
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
35-
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
36-
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
37-
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
38-
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered }
7+
DRegion 0: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
8+
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
9+
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
10+
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
11+
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
12+
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
13+
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
14+
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
15+
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
16+
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
17+
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
18+
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
19+
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
20+
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
21+
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
22+
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
23+
DRegion 0: Region { base: 0x20000000, size: _16M, subregion_mask: 0, enabled: true, no_exec: false, mem_attr: Cacheable { outer: NonCacheable, inner: WriteThroughNoWriteAlloc, shareable: true }, access_perms: ReadWrite }
24+
DRegion 1: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
25+
DRegion 2: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
26+
DRegion 3: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
27+
DRegion 4: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
28+
DRegion 5: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
29+
DRegion 6: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
30+
DRegion 7: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
31+
DRegion 8: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
32+
DRegion 9: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
33+
DRegion 10: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
34+
DRegion 11: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
35+
DRegion 12: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
36+
DRegion 13: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
37+
DRegion 14: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }
38+
DRegion 15: Region { base: 0x0, size: Invalid, subregion_mask: 0, enabled: false, no_exec: false, mem_attr: StronglyOrdered, access_perms: NoAccess }

0 commit comments

Comments
 (0)