Only store the storage location in the Kernel

This commit is contained in:
Julien Cretin
2020-05-08 17:00:59 +02:00
parent 3edb387615
commit ecf02eb6ce
3 changed files with 34 additions and 62 deletions

View File

@@ -42,7 +42,7 @@ index fe493727..105f7120 100644
platform.pconsole.start();
diff --git a/chips/nrf52/src/nvmc.rs b/chips/nrf52/src/nvmc.rs
index 60fc2da8..77e7423d 100644
index 60fc2da8..45c75f89 100644
--- a/chips/nrf52/src/nvmc.rs
+++ b/chips/nrf52/src/nvmc.rs
@@ -3,6 +3,7 @@
@@ -126,7 +126,7 @@ index 60fc2da8..77e7423d 100644
let word: u32 = (data[i + 0] as u32) << 0
| (data[i + 1] as u32) << 8
| (data[i + 2] as u32) << 16
@@ -390,3 +422,178 @@ impl hil::flash::Flash for Nvmc {
@@ -390,3 +422,186 @@ impl hil::flash::Flash for Nvmc {
self.erase_page(page_number)
}
}
@@ -158,6 +158,8 @@ index 60fc2da8..77e7423d 100644
+/// - COMMAND(1, 2): Get the maximum number of word writes between page erasures (always 2).
+/// - COMMAND(1, 3): Get the maximum number page erasures in the lifetime of the flash (always
+/// 10000).
+/// - COMMAND(1, 4): Get the storage address (page-aligned).
+/// - COMMAND(1, 5): Get the storage length (page-aligned).
+/// - COMMAND(2, ptr): Write the allow slice to the flash region starting at `ptr`.
+/// - `ptr` must be word-aligned.
+/// - The allow slice length must be word aligned.
@@ -268,6 +270,12 @@ index 60fc2da8..77e7423d 100644
+ (1, 3) => ReturnCode::SuccessWithValue {
+ value: MAX_PAGE_ERASES,
+ },
+ (1, 4) => ReturnCode::SuccessWithValue {
+ value: STORAGE_PTR,
+ },
+ (1, 5) => ReturnCode::SuccessWithValue {
+ value: STORAGE_LEN,
+ },
+ (1, _) => ReturnCode::EINVAL,
+
+ (2, ptr) => self

View File

@@ -133,20 +133,6 @@ pub struct PersistentStore {
store: embedded_flash::Store<Storage, Config>,
}
#[cfg(feature = "ram_storage")]
const PAGE_SIZE: usize = 0x100;
#[cfg(not(feature = "ram_storage"))]
const PAGE_SIZE: usize = 0x1000;
// We have the following layout:
// 0x00000-0x2ffff: Tock
// 0x30000-0x3ffff: Padding
// 0x40000-0xbffff: App
// 0xc0000-0xfffff: Store
#[cfg(not(any(test, feature = "ram_storage")))]
const STORE_ADDR: usize = 0xC0000;
const STORE_SIZE: usize = NUM_PAGES * PAGE_SIZE;
impl PersistentStore {
/// Gives access to the persistent store.
///
@@ -167,19 +153,16 @@ impl PersistentStore {
#[cfg(not(any(test, feature = "ram_storage")))]
fn new_prod_storage() -> Storage {
let store = unsafe {
// Safety: The store cannot alias because this function is called only once.
core::slice::from_raw_parts_mut(STORE_ADDR as *mut u8, STORE_SIZE)
};
unsafe {
// Safety: The store is in a writeable flash region.
Storage::new(store).unwrap()
}
Storage::new(NUM_PAGES).unwrap()
}
#[cfg(any(test, feature = "ram_storage"))]
fn new_test_storage() -> Storage {
let store = vec![0xff; STORE_SIZE].into_boxed_slice();
#[cfg(not(test))]
const PAGE_SIZE: usize = 0x100;
#[cfg(test)]
const PAGE_SIZE: usize = 0x1000;
let store = vec![0xff; NUM_PAGES * PAGE_SIZE].into_boxed_slice();
let options = embedded_flash::BufferOptions {
word_size: 4,
page_size: PAGE_SIZE,

View File

@@ -24,6 +24,8 @@ mod command_nr {
pub const PAGE_SIZE: usize = 1;
pub const MAX_WORD_WRITES: usize = 2;
pub const MAX_PAGE_ERASES: usize = 3;
pub const STORAGE_PTR: usize = 4;
pub const STORAGE_LEN: usize = 5;
}
pub const WRITE_SLICE: usize = 2;
pub const ERASE_PAGE: usize = 3;
@@ -53,46 +55,31 @@ pub struct SyscallStorage {
impl SyscallStorage {
/// Provides access to the embedded flash if available.
///
/// # Safety
///
/// The `storage` must be readable.
///
/// # Errors
///
/// Returns `BadFlash` if any of the following conditions do not hold:
/// - The word size is not a power of two.
/// - The page size is not a power of two.
/// - The page size is not a multiple of the word size.
/// - The word size is a power of two.
/// - The page size is a power of two.
/// - The page size is a multiple of the word size.
/// - The storage is page-aligned.
///
/// Returns `NotAligned` if any of the following conditions do not hold:
/// - `storage` is page-aligned.
/// - `storage.len()` is a multiple of the page size.
///
/// # Examples
///
/// ```rust
/// # extern crate ctap2;
/// # use ctap2::embedded_flash::SyscallStorage;
/// # use ctap2::embedded_flash::StorageResult;
/// # const STORAGE_ADDR: usize = 0x1000;
/// # const STORAGE_SIZE: usize = 0x1000;
/// # fn foo() -> StorageResult<SyscallStorage> {
/// // This is safe because we create and use `storage` only once in the whole program.
/// let storage = unsafe {
/// core::slice::from_raw_parts_mut(STORAGE_ADDR as *mut u8, STORAGE_SIZE)
/// };
/// // This is safe because `storage` is readable.
/// unsafe { SyscallStorage::new(storage) }
/// # }
/// ```
pub unsafe fn new(storage: &'static mut [u8]) -> StorageResult<SyscallStorage> {
/// Returns `OutOfBounds` the number of pages does not fit in the storage.
pub fn new(num_pages: usize) -> StorageResult<SyscallStorage> {
let word_size = get_info(command_nr::get_info_nr::WORD_SIZE)?;
let page_size = get_info(command_nr::get_info_nr::PAGE_SIZE)?;
let max_word_writes = get_info(command_nr::get_info_nr::MAX_WORD_WRITES)?;
let max_page_erases = get_info(command_nr::get_info_nr::MAX_PAGE_ERASES)?;
let storage_ptr = get_info(command_nr::get_info_nr::STORAGE_PTR)?;
let max_storage_len = get_info(command_nr::get_info_nr::STORAGE_LEN)?;
if !word_size.is_power_of_two() || !page_size.is_power_of_two() {
return Err(StorageError::BadFlash);
}
let storage_len = num_pages * page_size;
if storage_len > max_storage_len {
return Err(StorageError::OutOfBounds);
}
let storage =
unsafe { core::slice::from_raw_parts_mut(storage_ptr as *mut u8, storage_len) };
let syscall = SyscallStorage {
word_size,
page_size,
@@ -100,16 +87,10 @@ impl SyscallStorage {
max_page_erases,
storage,
};
if !syscall.is_word_aligned(page_size) {
if !syscall.is_word_aligned(page_size) || !syscall.is_page_aligned(storage_ptr) {
return Err(StorageError::BadFlash);
}
if syscall.is_page_aligned(syscall.storage.as_ptr() as usize)
&& syscall.is_page_aligned(syscall.storage.len())
{
Ok(syscall)
} else {
Err(StorageError::NotAligned)
}
Ok(syscall)
}
fn is_word_aligned(&self, x: usize) -> bool {