Skip to content

Commit e1e7ada

Browse files
committed
Move EL2 MPU registers to bitfields
1 parent 5ff05d8 commit e1e7ada

File tree

5 files changed

+130
-30
lines changed

5 files changed

+130
-30
lines changed

cortex-ar/src/register/armv8r/hmpuir.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
use crate::register::{SysReg, SysRegRead};
44

55
/// HMPUIR (*Hyp MPU Type Register*)
6-
pub struct Hmpuir(pub u32);
6+
#[bitbybit::bitfield(u32)]
7+
pub struct Hmpuir {
8+
/// The number of EL2 MPU regions implemented
9+
#[bits(0..=7, r)]
10+
region: u8,
11+
}
12+
713
impl SysReg for Hmpuir {
814
const CP: u32 = 15;
915
const CRN: u32 = 0;
@@ -16,6 +22,6 @@ impl Hmpuir {
1622
#[inline]
1723
/// Reads HMPUIR (*Hyp MPU Type Register*)
1824
pub fn read() -> Hmpuir {
19-
unsafe { Self(<Self as SysRegRead>::read_raw()) }
25+
unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
2026
}
2127
}
Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,54 @@
11
//! Code for managing HPRBAR (*Hyp Protection Region Base Address Register*)
22
3+
use arbitrary_int::u26;
4+
35
use crate::register::{SysReg, SysRegRead, SysRegWrite};
46

7+
/// Shareability for an MPU Region
8+
#[derive(Debug, PartialEq, Eq)]
9+
#[bitbybit::bitenum(u2, exhaustive = true)]
10+
pub enum Shareability {
11+
/// Non-shareable
12+
NonShareable = 0b00,
13+
/// Reserved
14+
Reserved = 0b01,
15+
/// Outer-Shareable
16+
OuterShareable = 0b10,
17+
/// Inner-Shareable
18+
InnerShareable = 0b11,
19+
}
20+
21+
/// Access Permissions for an MPU Region
22+
#[derive(Debug, PartialEq, Eq)]
23+
#[bitbybit::bitenum(u2, exhaustive = true)]
24+
pub enum AccessPerms {
25+
/// Read-Write at EL2, No access at EL1/0
26+
ReadWriteNoEL10 = 0b00,
27+
/// Read-Write at EL2, EL1, and EL0
28+
ReadWrite = 0b01,
29+
/// Read-Only at EL2, No access at EL1/0
30+
ReadOnlyNoEL10 = 0b10,
31+
/// Read-Only at EL2, EL1, and EL0
32+
ReadOnly = 0b11,
33+
}
34+
535
/// HPRBAR (*Hyp Protection Region Base Address Register*)
6-
pub struct Hprbar(pub u32);
36+
#[bitbybit::bitfield(u32)]
37+
pub struct Hprbar {
38+
/// Base Address
39+
#[bits(6..=31, rw)]
40+
base: u26,
41+
/// Shareability
42+
#[bits(3..=4, rw)]
43+
shareability: Shareability,
44+
/// Access Permissions
45+
#[bits(1..=2, rw)]
46+
access_perms: AccessPerms,
47+
/// Execute Never
48+
#[bits(0..=0, rw)]
49+
nx: bool,
50+
}
51+
752
impl SysReg for Hprbar {
853
const CP: u32 = 15;
954
const CRN: u32 = 6;
@@ -16,20 +61,16 @@ impl Hprbar {
1661
#[inline]
1762
/// Reads HPRBAR (*Hyp Protection Region Base Address Register*)
1863
pub fn read() -> Hprbar {
19-
unsafe { Self(<Self as SysRegRead>::read_raw()) }
64+
unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
2065
}
2166
}
2267
impl crate::register::SysRegWrite for Hprbar {}
2368
impl Hprbar {
2469
#[inline]
2570
/// Writes HPRBAR (*Hyp Protection Region Base Address Register*)
26-
///
27-
/// # Safety
28-
///
29-
/// Ensure that this value is appropriate for this register
30-
pub unsafe fn write(value: Self) {
71+
pub fn write(value: Self) {
3172
unsafe {
32-
<Self as SysRegWrite>::write_raw(value.0);
73+
<Self as SysRegWrite>::write_raw(value.raw_value());
3374
}
3475
}
3576
}
Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
//! Code for managing HPRLAR (*Hyp Protection Region Limit Address Register*)
22
3+
use arbitrary_int::{u26, u3};
4+
35
use crate::register::{SysReg, SysRegRead, SysRegWrite};
46

57
/// HPRLAR (*Hyp Protection Region Limit Address Register*)
6-
pub struct Hprlar(pub u32);
8+
#[bitbybit::bitfield(u32)]
9+
pub struct Hprlar {
10+
/// Length of region
11+
#[bits(6..=31, rw)]
12+
limit: u26,
13+
/// Which HMAIR attribute to use
14+
#[bits(1..=3, rw)]
15+
mair: u3,
16+
/// Is region enabled?
17+
#[bits(0..=0, rw)]
18+
enabled: bool,
19+
}
20+
721
impl SysReg for Hprlar {
822
const CP: u32 = 15;
923
const CRN: u32 = 6;
@@ -16,20 +30,16 @@ impl Hprlar {
1630
#[inline]
1731
/// Reads HPRLAR (*Hyp Protection Region Limit Address Register*)
1832
pub fn read() -> Hprlar {
19-
unsafe { Self(<Self as SysRegRead>::read_raw()) }
33+
unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
2034
}
2135
}
2236
impl crate::register::SysRegWrite for Hprlar {}
2337
impl Hprlar {
2438
#[inline]
2539
/// Writes HPRLAR (*Hyp Protection Region Limit Address Register*)
26-
///
27-
/// # Safety
28-
///
29-
/// Ensure that this value is appropriate for this register
30-
pub unsafe fn write(value: Self) {
40+
pub fn write(value: Self) {
3141
unsafe {
32-
<Self as SysRegWrite>::write_raw(value.0);
42+
<Self as SysRegWrite>::write_raw(value.raw_value());
3343
}
3444
}
3545
}

cortex-ar/src/register/armv8r/hprselr.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@ impl Hprselr {
2424
#[inline]
2525
/// Writes HPRSELR (*Hyp Protection Region Selection Register*)
2626
///
27-
/// # Safety
28-
///
29-
/// Ensure that this value is appropriate for this register
30-
pub unsafe fn write(value: Self) {
27+
/// Controls what appears in HPRLAR and HPRBAR
28+
pub fn write(value: Self) {
3129
unsafe {
3230
<Self as SysRegWrite>::write_raw(value.0);
3331
}

cortex-ar/src/register/armv8r/hsctlr.rs

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,46 @@
33
use crate::register::{SysReg, SysRegRead, SysRegWrite};
44

55
/// HSCTLR (*Hyp System Control Register*)
6-
pub struct Hsctlr(pub u32);
6+
#[bitbybit::bitfield(u32)]
7+
pub struct Hsctlr {
8+
/// T32 Exception Enable. Controls whether exceptions to EL2 are taken to A32 or T32 state
9+
#[bits(30..=30, rw)]
10+
te: bool,
11+
/// Exception Endianness. The value of the PSTATE.E bit on entry to Hyp mode
12+
#[bits(25..=25, rw)]
13+
ee: bool,
14+
/// Fast Interrupts enable
15+
#[bits(21..=21, rw)]
16+
fi: bool,
17+
/// Write permission implies XN (Execute-never)
18+
#[bits(19..=19, rw)]
19+
wxn: bool,
20+
/// Background Region enable for EL2
21+
#[bits(17..=17, rw)]
22+
br: bool,
23+
/// Instruction access Cacheability control, for accesses at EL2
24+
#[bits(12..=12, rw)]
25+
i: bool,
26+
/// SETEND instruction disable. Disables SETEND instructions at EL2
27+
#[bits(8..=8, rw)]
28+
sed: bool,
29+
/// IT Disable. Disables some uses of IT instructions at EL2
30+
#[bits(7..=7, rw)]
31+
itd: bool,
32+
/// System instruction memory barrier enable
33+
#[bits(5..=5, rw)]
34+
cp15ben: bool,
35+
/// Cacheability control, for data accesses at EL2
36+
#[bits(2..=2, rw)]
37+
c: bool,
38+
/// Alignment check enable
39+
#[bits(1..=1, rw)]
40+
a: bool,
41+
/// MPU enable for the EL2 MPU
42+
#[bits(0..=0, rw)]
43+
m: bool,
44+
}
45+
746
impl SysReg for Hsctlr {
847
const CP: u32 = 15;
948
const CRN: u32 = 1;
@@ -16,20 +55,26 @@ impl Hsctlr {
1655
#[inline]
1756
/// Reads HSCTLR (*Hyp System Control Register*)
1857
pub fn read() -> Hsctlr {
19-
unsafe { Self(<Self as SysRegRead>::read_raw()) }
58+
unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
2059
}
2160
}
2261
impl crate::register::SysRegWrite for Hsctlr {}
2362
impl Hsctlr {
2463
#[inline]
2564
/// Writes HSCTLR (*Hyp System Control Register*)
26-
///
27-
/// # Safety
28-
///
29-
/// Ensure that this value is appropriate for this register
30-
pub unsafe fn write(value: Self) {
65+
pub fn write(value: Self) {
3166
unsafe {
32-
<Self as SysRegWrite>::write_raw(value.0);
67+
<Self as SysRegWrite>::write_raw(value.raw_value());
3368
}
3469
}
70+
/// Read-modify-write this register
71+
#[inline]
72+
pub fn modify<F>(f: F)
73+
where
74+
F: FnOnce(&mut Self),
75+
{
76+
let mut val = Self::read();
77+
f(&mut val);
78+
Self::write(val);
79+
}
3580
}

0 commit comments

Comments
 (0)