Skip to content

Commit 0adf671

Browse files
nk3xn: Read out PRINCE configuration after boot
Instead of assuming that PRINCE is always disabled for the firmware region, this patch reads out the PRINCE configuration at boot and uses it as a baseline when enabling or disabling encryption of the filesystem region.
1 parent a139403 commit 0adf671

File tree

3 files changed

+100
-20
lines changed

3 files changed

+100
-20
lines changed

components/boards/src/nk3xn/prince.rs

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use lpc55_hal::{
1616
traits::flash::WriteErase,
1717
typestates::init_state::Enabled,
1818
};
19+
use lpc55_pac::PRINCE;
1920

2021
use super::MEMORY_REGIONS;
2122

@@ -64,7 +65,7 @@ pub const BLOCK_COUNT: usize = {
6465

6566
const PRINCE_REGION2_START: usize = 0x80_000;
6667
const PRINCE_SUBREGION_SIZE: usize = 8 * 1024;
67-
const PRINCE_REGION2_ENABLE: u32 = {
68+
const PRINCE_REGION2_MASK: u32 = {
6869
// FS must be placed in PRINCE Region 2
6970
assert!(FS_START >= PRINCE_REGION2_START);
7071
let offset = FS_START - PRINCE_REGION2_START;
@@ -80,33 +81,60 @@ const PRINCE_REGION2_ENABLE: u32 = {
8081
// --> disable subregion_count subregions, enable the remaining ones
8182
0xffffffff << subregion_count
8283
};
83-
const PRINCE_REGION2_DISABLE: u32 = 0;
8484

85-
pub fn enable(prince: &mut Prince<Enabled>) {
86-
prince.set_region_enable(Region::Region2, PRINCE_REGION2_ENABLE);
85+
pub struct PrinceConfig {
86+
sr_enable2: u32,
8787
}
8888

89-
pub fn disable(prince: &mut Prince<Enabled>) {
90-
prince.set_region_enable(Region::Region2, PRINCE_REGION2_DISABLE);
91-
}
89+
impl PrinceConfig {
90+
pub fn new(prince: &PRINCE) -> Self {
91+
Self {
92+
sr_enable2: prince.sr_enable2.read().bits(),
93+
}
94+
}
95+
96+
fn sr_enable2(&self, filesystem: bool) -> u32 {
97+
if filesystem {
98+
// enable the default regions and the filesystem regions
99+
self.sr_enable2 | PRINCE_REGION2_MASK
100+
} else {
101+
// enable the default regions without the filesystem regions
102+
self.sr_enable2 & !PRINCE_REGION2_MASK
103+
}
104+
}
105+
106+
pub fn enable_filesystem(&self, prince: &mut Prince<Enabled>) {
107+
prince.set_region_enable(Region::Region2, self.sr_enable2(true));
108+
}
92109

93-
pub fn with_enabled<T>(prince: &mut Prince<Enabled>, mut f: impl FnMut() -> T) -> T {
94-
enable(prince);
95-
let result = f();
96-
disable(prince);
97-
result
110+
pub fn disable_filesystem(&self, prince: &mut Prince<Enabled>) {
111+
prince.set_region_enable(Region::Region2, self.sr_enable2(false));
112+
}
113+
114+
pub fn with_filesystem<F: FnMut() -> T, T>(&self, prince: &mut Prince<Enabled>, mut f: F) -> T {
115+
self.enable_filesystem(prince);
116+
let result = f();
117+
self.disable_filesystem(prince);
118+
result
119+
}
98120
}
99121

100122
pub struct InternalFilesystem {
101123
flash_gordon: FlashGordon,
102124
prince: Prince<Enabled>,
125+
prince_config: PrinceConfig,
103126
}
104127

105128
impl InternalFilesystem {
106-
pub fn new(flash_gordon: FlashGordon, prince: Prince<Enabled>) -> Self {
129+
pub fn new(
130+
flash_gordon: FlashGordon,
131+
prince: Prince<Enabled>,
132+
prince_config: PrinceConfig,
133+
) -> Self {
107134
Self {
108135
flash_gordon,
109136
prince,
137+
prince_config,
110138
}
111139
}
112140
}
@@ -123,7 +151,7 @@ impl Storage for InternalFilesystem {
123151
type LOOKAHEAD_SIZE = littlefs_params::LOOKAHEAD_SIZE;
124152

125153
fn read(&mut self, off: usize, buf: &mut [u8]) -> Result<usize> {
126-
with_enabled(&mut self.prince, || {
154+
self.prince_config.with_filesystem(&mut self.prince, || {
127155
let flash: *const u8 = (FS_START + off) as *const u8;
128156
#[allow(clippy::needless_range_loop)]
129157
for i in 0..buf.len() {
@@ -135,7 +163,8 @@ impl Storage for InternalFilesystem {
135163

136164
fn write(&mut self, off: usize, data: &[u8]) -> Result<usize> {
137165
let ret = self.prince.write_encrypted(|prince| {
138-
with_enabled(prince, || self.flash_gordon.write(FS_START + off, data))
166+
self.prince_config
167+
.with_filesystem(prince, || self.flash_gordon.write(FS_START + off, data))
139168
});
140169
ret.map(|_| data.len()).map_err(|_| Error::IO)
141170
}
@@ -152,3 +181,43 @@ impl Storage for InternalFilesystem {
152181
Ok(BLOCK_SIZE * pages)
153182
}
154183
}
184+
185+
#[cfg(test)]
186+
mod tests {
187+
use super::*;
188+
189+
#[test]
190+
fn test_prince_sr_enable2() {
191+
// currently, the first 9 regions are used for the firmware, so the first 9 bits should
192+
// stay the same. the rest should be 0 if the filesystem is disabled or 1 if it is
193+
// enabled.
194+
195+
let none = 0;
196+
let all = u32::MAX;
197+
let firmware = 0b1_11111111;
198+
let filesystem = 0b11111111_11111111_11111110_00000000;
199+
200+
assert_eq!(PRINCE_REGION2_MASK, filesystem);
201+
assert_eq!(firmware ^ filesystem, all);
202+
203+
let config = PrinceConfig { sr_enable2: none };
204+
assert_eq!(config.sr_enable2(false), none);
205+
assert_eq!(config.sr_enable2(true), filesystem);
206+
207+
let config = PrinceConfig { sr_enable2: all };
208+
assert_eq!(config.sr_enable2(false), firmware);
209+
assert_eq!(config.sr_enable2(true), all);
210+
211+
let config = PrinceConfig { sr_enable2: firmware };
212+
assert_eq!(config.sr_enable2(false),firmware);
213+
assert_eq!(config.sr_enable2(true), all);
214+
215+
let config = PrinceConfig { sr_enable2: 1 };
216+
assert_eq!(config.sr_enable2(false), 1);
217+
assert_eq!(config.sr_enable2(true), 0b11111111_11111111_11111110_00000001);
218+
219+
let config = PrinceConfig { sr_enable2: 0x3fff };
220+
assert_eq!(config.sr_enable2(false), firmware);
221+
assert_eq!(config.sr_enable2(true), all);
222+
}
223+
}

runners/embedded/src/nk3xn.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
pub mod init;
22

3-
use boards::{init::Resources, nk3xn::NK3xN};
3+
use boards::{
4+
init::Resources,
5+
nk3xn::{prince::PrinceConfig, NK3xN},
6+
};
47

58
use crate::{VERSION, VERSION_STRING};
69

@@ -13,6 +16,7 @@ pub fn init(
1316

1417
boards::init::init_logger::<NK3xN>(VERSION_STRING);
1518

19+
let prince_config = PrinceConfig::new(&device_peripherals.PRINCE);
1620
let hal = lpc55_hal::Peripherals::from((device_peripherals, core_peripherals));
1721

1822
let require_prince = cfg!(not(feature = "no-encrypted-storage"));
@@ -41,7 +45,7 @@ pub fn init(
4145
hal.pint,
4246
nfc_enabled,
4347
)
44-
.next(hal.rng, hal.prince, hal.flash)
48+
.next(hal.rng, hal.prince, hal.flash, prince_config)
4549
.next(&mut resources.store)
4650
.next(hal.rtc)
4751
.next(&mut resources.usb, hal.usbhs)

runners/embedded/src/nk3xn/init.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use boards::{
1111
button::ThreeButtons,
1212
led::RgbLed,
1313
nfc::{self, NfcChip},
14-
prince,
14+
prince::PrinceConfig,
1515
spi::{self, FlashCs, FlashCsPin, Spi, SpiConfig},
1616
ButtonsTimer, InternalFlashStorage, NK3xN, PwmTimer, I2C,
1717
},
@@ -97,6 +97,7 @@ struct Flash {
9797
#[allow(unused)]
9898
prince: Prince<Enabled>,
9999
rng: Rng<Enabled>,
100+
prince_config: PrinceConfig,
100101
}
101102

102103
pub struct Stage0 {
@@ -494,6 +495,7 @@ impl Stage3 {
494495
rng: Rng<Unknown>,
495496
prince: Prince<Unknown>,
496497
flash: hal::peripherals::flash::Flash<Unknown>,
498+
prince_config: PrinceConfig,
497499
) -> Stage4 {
498500
info_now!("making flash");
499501
let syscon = &mut self.peripherals.syscon;
@@ -502,14 +504,15 @@ impl Stage3 {
502504
let mut rng = rng.enabled(syscon);
503505

504506
let mut prince = prince.enabled(&rng);
505-
prince::disable(&mut prince);
507+
prince_config.disable_filesystem(&mut prince);
506508

507509
let flash_gordon = FlashGordon::new(flash.enabled(syscon));
508510

509511
let flash = Flash {
510512
flash_gordon,
511513
prince,
512514
rng,
515+
prince_config,
513516
};
514517
Stage4 {
515518
status: self.status,
@@ -579,7 +582,11 @@ impl Stage4 {
579582
#[cfg(feature = "write-undefined-flash")]
580583
initialize_fs_flash(&mut self.flash.flash_gordon, &mut self.flash.prince);
581584

582-
InternalFlashStorage::new(self.flash.flash_gordon, self.flash.prince)
585+
InternalFlashStorage::new(
586+
self.flash.flash_gordon,
587+
self.flash.prince,
588+
self.flash.prince_config,
589+
)
583590
};
584591

585592
#[cfg(feature = "no-encrypted-storage")]

0 commit comments

Comments
 (0)