components/
isolated_nonvolatile_storage.rs
1use capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage;
29use capsules_extra::nonvolatile_to_pages::NonvolatileToPages;
30use core::mem::MaybeUninit;
31use kernel::capabilities;
32use kernel::component::Component;
33use kernel::create_capability;
34use kernel::hil;
35
36pub const ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT: usize = 2048;
40
41#[macro_export]
43macro_rules! isolated_nonvolatile_storage_component_static {
44 ($F:ty, $APP_REGION_SIZE:expr $(,)?) => {{
45 let page = kernel::static_buf!(<$F as kernel::hil::flash::Flash>::Page);
46 let ntp = kernel::static_buf!(
47 capsules_extra::nonvolatile_to_pages::NonvolatileToPages<'static, $F>
48 );
49 let ns = kernel::static_buf!(
50 capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage<
51 'static,
52 $APP_REGION_SIZE,
53 >
54 );
55 let buffer =
56 kernel::static_buf!([u8; capsules_extra::isolated_nonvolatile_storage_driver::BUF_LEN]);
57
58 (page, ntp, ns, buffer)
59 };};
60}
61
62pub type IsolatedNonvolatileStorageComponentType<const APP_REGION_SIZE: usize> =
63 IsolatedNonvolatileStorage<'static, APP_REGION_SIZE>;
64
65pub struct IsolatedNonvolatileStorageComponent<
66 F: 'static + hil::flash::Flash + hil::flash::HasClient<'static, NonvolatileToPages<'static, F>>,
67 const APP_REGION_SIZE: usize,
68> {
69 board_kernel: &'static kernel::Kernel,
70 driver_num: usize,
71 flash: &'static F,
72 userspace_start: usize,
73 userspace_length: usize,
74}
75
76impl<
77 F: 'static
78 + hil::flash::Flash
79 + hil::flash::HasClient<'static, NonvolatileToPages<'static, F>>,
80 const APP_REGION_SIZE: usize,
81 > IsolatedNonvolatileStorageComponent<F, APP_REGION_SIZE>
82{
83 pub fn new(
84 board_kernel: &'static kernel::Kernel,
85 driver_num: usize,
86 flash: &'static F,
87 userspace_start: usize,
88 userspace_length: usize,
89 ) -> Self {
90 Self {
91 board_kernel,
92 driver_num,
93 flash,
94 userspace_start,
95 userspace_length,
96 }
97 }
98}
99
100impl<
101 F: 'static
102 + hil::flash::Flash
103 + hil::flash::HasClient<'static, NonvolatileToPages<'static, F>>,
104 const APP_REGION_SIZE: usize,
105 > Component for IsolatedNonvolatileStorageComponent<F, APP_REGION_SIZE>
106{
107 type StaticInput = (
108 &'static mut MaybeUninit<<F as hil::flash::Flash>::Page>,
109 &'static mut MaybeUninit<NonvolatileToPages<'static, F>>,
110 &'static mut MaybeUninit<IsolatedNonvolatileStorage<'static, APP_REGION_SIZE>>,
111 &'static mut MaybeUninit<
112 [u8; capsules_extra::isolated_nonvolatile_storage_driver::BUF_LEN],
113 >,
114 );
115 type Output = &'static IsolatedNonvolatileStorage<'static, APP_REGION_SIZE>;
116
117 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
118 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
119
120 let buffer = static_buffer
121 .3
122 .write([0; capsules_extra::isolated_nonvolatile_storage_driver::BUF_LEN]);
123
124 let flash_pagebuffer = static_buffer
125 .0
126 .write(<F as hil::flash::Flash>::Page::default());
127
128 let nv_to_page = static_buffer
129 .1
130 .write(NonvolatileToPages::new(self.flash, flash_pagebuffer));
131 hil::flash::HasClient::set_client(self.flash, nv_to_page);
132
133 let nonvolatile_storage = static_buffer.2.write(IsolatedNonvolatileStorage::new(
134 nv_to_page,
135 self.board_kernel.create_grant(self.driver_num, &grant_cap),
136 self.userspace_start, self.userspace_length, buffer,
139 ));
140 hil::nonvolatile_storage::NonvolatileStorage::set_client(nv_to_page, nonvolatile_storage);
141 nonvolatile_storage
142 }
143}