bern_arch/
memory_protection.rs

1//! Memory Protection.
2
3use bern_units::memory_size::Byte;
4
5/// Memory Protection.
6///
7/// # Implementation
8/// In addition to the trait the following features have to be implemented:
9///
10/// ## Memory Protection Exception
11/// A violation of a memory rule will trigger an exception. The exception must
12/// call `memory_protection_exception()` to notify the kernel, i.e.:
13/// ```ignore
14/// extern "Rust" {
15///     pub fn memory_protection_exception();
16/// }
17///
18/// #[allow(non_snake_case)]
19/// #[exception]
20/// fn MemoryManagement() -> () {
21///     unsafe {
22///         memory_protection_exception();
23///     }
24/// }
25/// ```
26///
27/// ## Size and Alignment
28/// Different memory protection implementation have different requirements in
29/// terms of sizes and alignment.
30/// A hardware implementation must provide
31/// - Alignment structs for all available alignments with naming convention
32///   `A<size number><unit prefix (_,K,M,G)>`, i.e.
33///   ```ignore
34///   #[repr(align(4_096))]
35///   pub struct A4K;
36///   ```
37/// - A macro `alignment_from_size!()` that returns valid alignment for given
38///   memory size, i.e.
39///   ```ignore
40///   #[macro_export]
41///   macro_rules! alignment_from_size {
42///       (4_096) => { $crate::arch::memory_protection::A4K };
43///       ($x:expr) => {
44///           compile_error!("Size does not meet alignment requirements from the MPU. \
45///           Compatible sizes are: 4KB");
46///        };
47///   }
48///   ```
49///
50/// - A macro `size_from_raw!()` that returns a valid size type from raw number,
51///   i.e.
52///   ```ignore
53///   #[macro_export]
54///   macro_rules! size_from_raw {
55///       (4_096) => { $crate::arch::memory_protection::Size::S4K };
56///       ($x:expr) => {
57///           compile_error!("Size cannot be protected by MPU. \
58///           Compatible sizes are: 4KB");
59///        };
60///   }
61///   ```
62pub trait IMemoryProtection {
63    /// Precalculated memory region configuration.
64    type MemoryRegion;
65
66    /// Enable memory protection hardware.
67    fn enable_memory_protection();
68    /// Disable memory protection hardware.
69    fn disable_memory_protection();
70    /// Setup and enable one memory region.
71    ///
72    /// # Example
73    /// Protect all flash memory from write access, instruction fetch allowed.
74    /// ```ignore
75    /// Arch::enable_memory_region(
76    ///    0,
77    ///    Config {
78    ///         addr: 0x0800_0000 as *const _,
79    ///         memory: Type::Flash,
80    ///         size: Size::S512K,
81    ///         access: Access { user: Permission::ReadOnly, system: Permission::ReadOnly },
82    ///         executable: true
83    /// });
84    /// ```
85    fn enable_memory_region(region: u8, config: Config);
86    /// Disable one memory region.
87    fn disable_memory_region(region: u8);
88    /// Compile register values from configuration and store in `MemoryRegion`.
89    ///
90    /// Same as [`Self::enable_memory_region()`] but return the register configuration
91    /// instead of applying it to the actual registers.
92    fn prepare_memory_region(region: u8, config: Config) -> Self::MemoryRegion;
93    /// Compile register values for an unused memory region.
94    fn prepare_unused_region(region: u8) -> Self::MemoryRegion;
95    /// Apply 3 precompiled memory regions.
96    fn apply_regions(memory_regions: &[Self::MemoryRegion; 3]);
97    /// Minimal region size that can be protected.
98    fn min_region_size() -> Byte;
99    /// Returns the number of memory regions.
100    fn n_memory_regions() -> u8;
101}
102
103/// Access Permission
104pub enum Permission {
105    /// Access not permitted
106    NoAccess,
107    /// Can only be read
108    ReadOnly,
109    /// Full access, can be read and written
110    ReadWrite,
111}
112
113/// Access configuration
114pub struct Access {
115    /// Permission in user mode (i.e. tasks)
116    pub user: Permission,
117    /// Permission in system mode (i.e. ISR, kernel)
118    pub system: Permission,
119}
120
121/// Type of memory
122pub enum Type {
123    /// SRAM in the microcontroller
124    SramInternal,
125    /// SRAM attach to the microcontroller externally
126    SramExternal,
127    /// Internal flash memory
128    Flash,
129    /// Microcontroller peripherals
130    Peripheral,
131}
132
133/// Memory region configurations
134pub struct Config {
135    /// Region base address
136    pub addr: *const usize,
137    /// Memory type
138    pub memory: Type,
139    /// Size of region
140    pub size: Byte,
141    /// Permissions
142    pub access: Access,
143    /// Memory region can be used to fetch instructions
144    pub executable: bool,
145}