Skip to content
Snippets Groups Projects
Commit 5c2b72ce authored by Julien Cretin's avatar Julien Cretin
Browse files

Move storage bound checking to driver

parent 88920035
No related branches found
No related tags found
No related merge requests found
......@@ -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 5abd2d84..5a726fdb 100644
index 60fc2da8..77e7423d 100644
--- a/chips/nrf52/src/nvmc.rs
+++ b/chips/nrf52/src/nvmc.rs
@@ -3,6 +3,7 @@
......@@ -62,7 +62,7 @@ index 5abd2d84..5a726fdb 100644
use crate::deferred_call_tasks::DeferredCallTask;
@@ -141,7 +142,13 @@ register_bitfields! [u32,
@@ -141,7 +142,33 @@ register_bitfields! [u32,
static DEFERRED_CALL: DeferredCall<DeferredCallTask> =
unsafe { DeferredCall::new(DeferredCallTask::Nvmc) };
......@@ -73,10 +73,30 @@ index 5abd2d84..5a726fdb 100644
+const MAX_PAGE_ERASES: usize = 10000;
+const WORD_MASK: usize = WORD_SIZE - 1;
+const PAGE_MASK: usize = PAGE_SIZE - 1;
+
+// The storage is currently static and readable by all processes. This will be fixed once Tock
+// supports persistent storage outside the application flash (i.e. not the current writeable flash
+// regions support).
+const STORAGE_PTR: usize = 0xc0000;
+const STORAGE_LEN: usize = 0x40000;
+
+fn in_storage(ptr: usize, len: usize) -> bool {
+ // We want to check the 2 following inequalities:
+ // (1) `STORAGE_PTR <= ptr`
+ // (2) `ptr + len <= STORAGE_PTR + STORAGE_LEN`
+ // However, the second one may overflow written as is. We introduce a third
+ // inequality to solve this issue:
+ // (3) `len <= STORAGE_LEN`
+ // Using this third inequality, we can rewrite the second one as:
+ // (4) `ptr - STORAGE_PTR <= STORAGE_LEN - len`
+ // This fourth inequality is equivalent to the second one but doesn't overflow when
+ // the first and third inequalities hold.
+ STORAGE_PTR <= ptr && len <= STORAGE_LEN && ptr - STORAGE_PTR <= STORAGE_LEN - len
+}
/// This is a wrapper around a u8 array that is sized to a single page for the
/// nrf. Users of this module must pass an object of this type to use the
@@ -215,6 +222,11 @@ impl Nvmc {
@@ -215,6 +242,11 @@ impl Nvmc {
}
}
......@@ -88,7 +108,7 @@ index 5abd2d84..5a726fdb 100644
/// Configure the NVMC to allow writes to flash.
pub fn configure_writeable(&self) {
let regs = &*self.registers;
@@ -230,7 +242,7 @@ impl Nvmc {
@@ -230,7 +262,7 @@ impl Nvmc {
let regs = &*self.registers;
regs.config.write(Configuration::WEN::Een);
while !self.is_ready() {}
......@@ -97,7 +117,7 @@ index 5abd2d84..5a726fdb 100644
while !self.is_ready() {}
}
@@ -314,7 +326,7 @@ impl Nvmc {
@@ -322,7 +354,7 @@ impl Nvmc {
// Put the NVMC in write mode.
regs.config.write(Configuration::WEN::Wen);
......@@ -106,7 +126,7 @@ index 5abd2d84..5a726fdb 100644
let word: u32 = (data[i + 0] as u32) << 0
| (data[i + 1] as u32) << 8
| (data[i + 2] as u32) << 16
@@ -374,3 +386,170 @@ impl hil::flash::Flash for Nvmc {
@@ -390,3 +422,178 @@ impl hil::flash::Flash for Nvmc {
self.erase_page(page_number)
}
}
......@@ -189,7 +209,11 @@ index 5abd2d84..5a726fdb 100644
+ /// Fails with `EINVAL` if any of the following conditions does not hold:
+ /// - `ptr` must be word-aligned.
+ /// - `slice.len()` must be word-aligned.
+ /// - The slice starting at `ptr` of length `slice.len()` must fit in the storage.
+ fn write_slice(&self, ptr: usize, slice: &[u8]) -> ReturnCode {
+ if !in_storage(ptr, slice.len()) {
+ return ReturnCode::EINVAL;
+ }
+ if ptr & WORD_MASK != 0 || slice.len() & WORD_MASK != 0 {
+ return ReturnCode::EINVAL;
+ }
......@@ -213,7 +237,11 @@ index 5abd2d84..5a726fdb 100644
+ ///
+ /// Fails with `EINVAL` if any of the following conditions does not hold:
+ /// - `ptr` must be page-aligned.
+ /// - The slice starting at `ptr` of length `PAGE_SIZE` must fit in the storage.
+ fn erase_page(&self, ptr: usize) -> ReturnCode {
+ if !in_storage(ptr, PAGE_SIZE) {
+ return ReturnCode::EINVAL;
+ }
+ if ptr & PAGE_MASK != 0 {
+ return ReturnCode::EINVAL;
+ }
......@@ -278,14 +306,16 @@ index 5abd2d84..5a726fdb 100644
+ }
+}
diff --git a/kernel/src/process.rs b/kernel/src/process.rs
index eb00f274..35c19d15 100644
index eb00f274..663c2422 100644
--- a/kernel/src/process.rs
+++ b/kernel/src/process.rs
@@ -1604,6 +1604,31 @@ impl<C: 'static + Chip> Process<'a, C> {
@@ -1604,6 +1604,33 @@ impl<C: 'static + Chip> Process<'a, C> {
return Ok((None, 0));
}
+ // Allocate MPU region for storage.
+ // Allocate MPU region for storage. The storage is currently static and readable by all
+ // processes. This will be fixed once Tock supports persistent storage outside the
+ // application flash (i.e. not the current writeable flash regions support).
+ const STORAGE_PTR: usize = 0xc0000;
+ const STORAGE_LEN: usize = 0x40000;
+ if chip
......
......@@ -145,7 +145,6 @@ const PAGE_SIZE: usize = 0x1000;
// 0xc0000-0xfffff: Store
#[cfg(not(any(test, feature = "ram_storage")))]
const STORE_ADDR: usize = 0xC0000;
const STORE_SIZE_LIMIT: usize = 0x40000;
const STORE_SIZE: usize = NUM_PAGES * PAGE_SIZE;
impl PersistentStore {
......@@ -155,8 +154,6 @@ impl PersistentStore {
///
/// This should be at most one instance of persistent store per program lifetime.
pub fn new(rng: &mut impl Rng256) -> PersistentStore {
// This should ideally be a compile-time assert, but Rust doesn't have native support.
assert!(STORE_SIZE <= STORE_SIZE_LIMIT);
#[cfg(not(any(test, feature = "ram_storage")))]
let storage = PersistentStore::new_prod_storage();
#[cfg(any(test, feature = "ram_storage"))]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment