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}