Move storage bound checking to driver
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user