Skip to content

Commit

Permalink
Replace store statics
Browse files Browse the repository at this point in the history
This patch moves the statics storing the various storage components into
the local resources for the init tasks.  This makes them sound and safe
to use.  Unfortunately, this leads to a significant increase in binary
size.
  • Loading branch information
robin-nitrokey committed Apr 17, 2024
1 parent b9b1b64 commit 7a9b52b
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 186 deletions.
8 changes: 6 additions & 2 deletions components/boards/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use apps::Dispatch;
#[cfg(feature = "se050")]
use embedded_hal::blocking::delay::DelayUs;
use littlefs2::{
driver::Storage,
fs::{Allocation, Filesystem},
io::Result as LfsResult,
};
Expand All @@ -34,17 +35,20 @@ use trussed::{client::Syscall, Platform};

use crate::{
soc::{Soc, Uuid},
store::{RunnerStore, StoragePointers},
store::RunnerStore,
ui::{buttons::UserPresence, rgb_led::RgbLed, UserInterface},
};

pub type Trussed<B> =
trussed::Service<RunnerPlatform<B>, Dispatch<<B as Board>::Twi, <B as Board>::Se050Timer>>;
pub type Apps<B> = apps::Apps<Runner<B>>;

pub trait Board: StoragePointers {
pub trait Board {
type Soc: Soc;

type InternalStorage: Storage + 'static;
type ExternalStorage: Storage + 'static;

type NfcDevice: NfcDevice;
type Buttons: UserPresence;
type Led: RgbLed;
Expand Down
10 changes: 3 additions & 7 deletions components/boards/src/nk3am.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use nrf52840_pac::{FICR, GPIOTE, P0, P1, POWER, PWM0, PWM1, PWM2, SPIM3, TIMER1,
use crate::{
flash::ExtFlashStorage,
soc::nrf52::{flash::FlashStorage, rtic_monotonic::RtcMonotonic, Nrf52},
store::impl_storage_pointers,
ui::UserInterface,
Board,
};
Expand All @@ -38,6 +37,9 @@ pub struct NK3AM;
impl Board for NK3AM {
type Soc = Nrf52;

type InternalStorage = InternalFlashStorage;
type ExternalStorage = ExternalFlashStorage;

type NfcDevice = DummyNfc;
type Buttons = HardwareButtons;
type Led = RgbLed;
Expand Down Expand Up @@ -102,12 +104,6 @@ pub type InternalFlashStorage =
FlashStorage<{ MEMORY_REGIONS.filesystem.start }, { MEMORY_REGIONS.filesystem.end }>;
pub type ExternalFlashStorage = ExtFlashStorage<Spim<SPIM3>, OutPin>;

impl_storage_pointers!(
NK3AM,
Internal = InternalFlashStorage,
External = ExternalFlashStorage,
);

pub struct DummyNfc;

impl NfcDevice for DummyNfc {
Expand Down
11 changes: 4 additions & 7 deletions components/boards/src/nk3xn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use lpc55_hal::{
use memory_regions::MemoryRegions;
use utils::OptionalStorage;

use crate::{flash::ExtFlashStorage, soc::lpc55::Lpc55, store::impl_storage_pointers, Board};
use crate::{flash::ExtFlashStorage, soc::lpc55::Lpc55, Board};

pub mod button;
pub mod led;
Expand Down Expand Up @@ -59,6 +59,9 @@ pub struct NK3xN;
impl Board for NK3xN {
type Soc = Lpc55;

type InternalStorage = InternalFlashStorage;
type ExternalStorage = ExternalFlashStorage;

type NfcDevice = NfcChip;
type Buttons = button::ThreeButtons;
type Led = led::RgbLed;
Expand All @@ -79,12 +82,6 @@ impl Board for NK3xN {
pub type InternalFlashStorage = InternalFilesystem;
pub type ExternalFlashStorage = OptionalStorage<ExtFlashStorage<Spi, FlashCs>>;

impl_storage_pointers!(
NK3xN,
Internal = InternalFlashStorage,
External = ExternalFlashStorage,
);

#[cfg(feature = "se050")]
pub struct TimerDelay<T>(pub T);

Expand Down
10 changes: 3 additions & 7 deletions components/boards/src/nkpk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use super::nk3am::{
};
use crate::{
soc::nrf52::{flash::FlashStorage, Nrf52},
store::impl_storage_pointers,
Board,
};

Expand All @@ -22,6 +21,9 @@ pub struct NKPK;
impl Board for NKPK {
type Soc = Nrf52;

type InternalStorage = InternalFlashStorage;
type ExternalStorage = ExternalFlashStorage;

type NfcDevice = DummyNfc;
type Buttons = HardwareButtons;
type Led = RgbLed;
Expand Down Expand Up @@ -52,9 +54,3 @@ pub type InternalFlashStorage =
FlashStorage<{ MEMORY_REGIONS.filesystem.start }, { MEMORY_REGIONS.filesystem.end }>;
// TODO: Do we want to mirror the NK3AM EFS?
pub type ExternalFlashStorage = RamStorage<nk3am::ExternalFlashStorage, 256>;

impl_storage_pointers!(
NKPK,
Internal = InternalFlashStorage,
External = ExternalFlashStorage,
);
219 changes: 70 additions & 149 deletions components/boards/src/store.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use core::{
marker::PhantomData,
mem::MaybeUninit,
sync::atomic::{AtomicBool, Ordering},
};
Expand Down Expand Up @@ -36,154 +35,78 @@ const_ram_storage!(
// FIXME: document safety
#[allow(clippy::missing_safety_doc)]
#[cfg(feature = "provisioner")]
pub unsafe fn steal_internal_storage<S: StoragePointers>() -> &'static mut S::InternalStorage {
S::ifs_storage().as_mut().unwrap()
pub unsafe fn steal_internal_storage<B: Board>() -> &'static mut S::InternalStorage {
B::ifs().storage.as_mut().unwrap()
}

// FIXME: document safety
#[allow(clippy::missing_safety_doc)]
pub trait StoragePointers: 'static {
type InternalStorage: Storage;
type ExternalStorage: Storage;

unsafe fn ifs_storage() -> &'static mut Option<Self::InternalStorage>;
unsafe fn ifs_alloc() -> &'static mut Option<Allocation<Self::InternalStorage>>;
unsafe fn ifs() -> &'static mut Option<Filesystem<'static, Self::InternalStorage>>;
unsafe fn ifs_ptr() -> *mut Fs<Self::InternalStorage>;

unsafe fn efs_storage() -> &'static mut Option<Self::ExternalStorage>;
unsafe fn efs_alloc() -> &'static mut Option<Allocation<Self::ExternalStorage>>;
unsafe fn efs() -> &'static mut Option<Filesystem<'static, Self::ExternalStorage>>;
unsafe fn efs_ptr() -> *mut Fs<Self::ExternalStorage>;
pub struct StoreResources<B: Board> {
ifs: StorageResources<B::InternalStorage>,
efs: StorageResources<B::ExternalStorage>,
vfs: StorageResources<VolatileStorage>,
}

#[cfg_attr(
not(any(feature = "board-nk3am", feature = "board-nk3xn")),
allow(unused)
)]
macro_rules! impl_storage_pointers {
($name:ident, Internal = $I:ty, External = $E:ty,) => {
impl $crate::store::StoragePointers for $name {
type InternalStorage = $I;
type ExternalStorage = $E;

unsafe fn ifs_storage() -> &'static mut Option<Self::InternalStorage> {
static mut IFS_STORAGE: Option<$I> = None;
#[allow(static_mut_refs)]
&mut IFS_STORAGE
}

unsafe fn ifs_alloc(
) -> &'static mut Option<::littlefs2::fs::Allocation<Self::InternalStorage>> {
static mut IFS_ALLOC: Option<::littlefs2::fs::Allocation<$I>> = None;
#[allow(static_mut_refs)]
&mut IFS_ALLOC
}

unsafe fn ifs(
) -> &'static mut Option<::littlefs2::fs::Filesystem<'static, Self::InternalStorage>>
{
static mut IFS: Option<::littlefs2::fs::Filesystem<$I>> = None;
#[allow(static_mut_refs)]
&mut IFS
}

unsafe fn ifs_ptr() -> *mut ::trussed::store::Fs<Self::InternalStorage> {
use ::core::mem::MaybeUninit;
static mut IFS: MaybeUninit<::trussed::store::Fs<$I>> = MaybeUninit::uninit();
IFS.as_mut_ptr()
}

unsafe fn efs_storage() -> &'static mut Option<Self::ExternalStorage> {
static mut EFS_STORAGE: Option<$E> = None;
#[allow(static_mut_refs)]
&mut EFS_STORAGE
}

unsafe fn efs_alloc(
) -> &'static mut Option<::littlefs2::fs::Allocation<Self::ExternalStorage>> {
static mut EFS_ALLOC: Option<::littlefs2::fs::Allocation<$E>> = None;
#[allow(static_mut_refs)]
&mut EFS_ALLOC
}

unsafe fn efs(
) -> &'static mut Option<::littlefs2::fs::Filesystem<'static, Self::ExternalStorage>>
{
static mut EFS: Option<::littlefs2::fs::Filesystem<$E>> = None;
#[allow(static_mut_refs)]
&mut EFS
}

unsafe fn efs_ptr() -> *mut ::trussed::store::Fs<Self::ExternalStorage> {
use ::core::mem::MaybeUninit;
static mut EFS: MaybeUninit<::trussed::store::Fs<$E>> = MaybeUninit::uninit();
EFS.as_mut_ptr()
}
impl<B: Board> StoreResources<B> {
pub const fn new() -> Self {
Self {
ifs: StorageResources::new(),
efs: StorageResources::new(),
vfs: StorageResources::new(),
}
};
}
}

#[cfg_attr(
not(any(feature = "board-nk3am", feature = "board-nk3xn")),
allow(unused)
)]
pub(crate) use impl_storage_pointers;

pub struct RunnerStore<S> {
_marker: PhantomData<*mut S>,
struct StorageResources<S: Storage + 'static> {
storage: Option<S>,
alloc: Option<Allocation<S>>,
fs: Option<Filesystem<'static, S>>,
fs_ptr: MaybeUninit<Fs<S>>,
}

impl<S: StoragePointers> RunnerStore<S> {
fn new(
ifs: &'static Filesystem<'static, S::InternalStorage>,
efs: &'static Filesystem<'static, S::ExternalStorage>,
vfs: &'static Filesystem<'static, VolatileStorage>,
) -> Self {
unsafe {
S::ifs_ptr().write(Fs::new(ifs));
S::efs_ptr().write(Fs::new(efs));
Self::vfs_ptr().write(Fs::new(vfs));
}

impl<S: Storage + 'static> StorageResources<S> {
const fn new() -> Self {
Self {
_marker: Default::default(),
storage: None,
alloc: None,
fs: None,
fs_ptr: MaybeUninit::uninit(),
}
}
}

unsafe fn vfs_ptr() -> *mut Fs<VolatileStorage> {
static mut VFS: MaybeUninit<Fs<VolatileStorage>> = MaybeUninit::uninit();
VFS.as_mut_ptr()
}
pub struct RunnerStore<B: Board> {
ifs: &'static Fs<B::InternalStorage>,
efs: &'static Fs<B::ExternalStorage>,
vfs: &'static Fs<VolatileStorage>,
}

impl<S> Clone for RunnerStore<S> {
impl<B: Board> Clone for RunnerStore<B> {
fn clone(&self) -> Self {
*self
}
}

impl<S> Copy for RunnerStore<S> {}
impl<B: Board> Copy for RunnerStore<B> {}

unsafe impl<S: StoragePointers> Store for RunnerStore<S> {
type I = S::InternalStorage;
type E = S::ExternalStorage;
unsafe impl<B: Board> Store for RunnerStore<B> {
type I = B::InternalStorage;
type E = B::ExternalStorage;
type V = VolatileStorage;

fn ifs(self) -> &'static Fs<Self::I> {
unsafe { &*S::ifs_ptr() }
self.ifs
}

fn efs(self) -> &'static Fs<Self::E> {
unsafe { &*S::efs_ptr() }
self.efs
}

fn vfs(self) -> &'static Fs<Self::V> {
unsafe { &*Self::vfs_ptr() }
self.vfs
}
}

pub fn init_store<B: Board>(
resources: &'static mut StoreResources<B>,
int_flash: B::InternalStorage,
ext_flash: B::ExternalStorage,
simulated_efs: bool,
Expand All @@ -194,44 +117,42 @@ pub fn init_store<B: Board>(
.compare_exchange_weak(false, true, Ordering::AcqRel, Ordering::Acquire)
.expect("multiple instances of RunnerStore are not allowed");

static mut VOLATILE_STORAGE: Option<VolatileStorage> = None;
static mut VOLATILE_FS_ALLOC: Option<Allocation<VolatileStorage>> = None;
static mut VOLATILE_FS: Option<Filesystem<VolatileStorage>> = None;

unsafe {
let ifs_storage = B::ifs_storage().insert(int_flash);
let ifs_alloc = B::ifs_alloc().insert(Filesystem::allocate());
let efs_storage = B::efs_storage().insert(ext_flash);
let efs_alloc = B::efs_alloc().insert(Filesystem::allocate());
let vfs_storage = VOLATILE_STORAGE.insert(VolatileStorage::new());
let vfs_alloc = VOLATILE_FS_ALLOC.insert(Filesystem::allocate());
let ifs_storage = resources.ifs.storage.insert(int_flash);
let ifs_alloc = resources.ifs.alloc.insert(Filesystem::allocate());
let efs_storage = resources.efs.storage.insert(ext_flash);
let efs_alloc = resources.efs.alloc.insert(Filesystem::allocate());
let vfs_storage = resources.vfs.storage.insert(VolatileStorage::new());
let vfs_alloc = resources.vfs.alloc.insert(Filesystem::allocate());

let ifs = match init_ifs::<B>(ifs_storage, ifs_alloc, efs_storage, status) {
Ok(ifs) => resources.ifs.fs.insert(ifs),
Err(_e) => {
error!("IFS Mount Error {:?}", _e);
panic!("IFS");
}
};

let ifs = match init_ifs::<B>(ifs_storage, ifs_alloc, efs_storage, status) {
Ok(ifs) => B::ifs().insert(ifs),
Err(_e) => {
error!("IFS Mount Error {:?}", _e);
panic!("IFS");
}
};
let efs = match init_efs::<B>(efs_storage, efs_alloc, simulated_efs, status) {
Ok(efs) => resources.efs.fs.insert(efs),
Err(_e) => {
error!("EFS Mount Error {:?}", _e);
panic!("EFS");
}
};

let efs = match init_efs::<B>(efs_storage, efs_alloc, simulated_efs, status) {
Ok(efs) => B::efs().insert(efs),
Err(_e) => {
error!("EFS Mount Error {:?}", _e);
panic!("EFS");
}
};
let vfs = match init_vfs(vfs_storage, vfs_alloc) {
Ok(vfs) => resources.vfs.fs.insert(vfs),
Err(_e) => {
error!("VFS Mount Error {:?}", _e);
panic!("VFS");
}
};

let vfs = match init_vfs(vfs_storage, vfs_alloc) {
Ok(vfs) => VOLATILE_FS.insert(vfs),
Err(_e) => {
error!("VFS Mount Error {:?}", _e);
panic!("VFS");
}
};
let ifs = resources.ifs.fs_ptr.write(Fs::new(ifs));
let efs = resources.efs.fs_ptr.write(Fs::new(efs));
let vfs = resources.vfs.fs_ptr.write(Fs::new(vfs));

RunnerStore::new(ifs, efs, vfs)
}
RunnerStore { ifs, efs, vfs }
}

#[inline(always)]
Expand Down
Loading

0 comments on commit 7a9b52b

Please sign in to comment.