use libcortex_a9::mmu::{AccessPermissions, L1_PAGE_SIZE, L1Table}; /// Symbols defined by the linker script extern "C" { static __text_start: usize; static __text_end: usize; static __rodata_start: usize; static __rodata_end: usize; } /// Apply basic memory protection to the regions defined by the linker /// script for the runtime on core 0. /// /// Therefore these regions need to be aligned to 1 MB. pub fn setup_core0() { let text_start = unsafe { &__text_start as *const _ as usize }; let text_end = unsafe { &__text_end as *const _ as usize }; let rodata_start = unsafe { &__rodata_start as *const _ as usize }; let rodata_end = unsafe { &__rodata_end as *const _ as usize }; let l1table = L1Table::get(); for addr in (0..0xFFFF_FFFF).step_by(L1_PAGE_SIZE) { l1table.update(addr as *const usize, |l1section| { if addr >= text_start && addr < text_end { // Code: R-X l1section.access = AccessPermissions::ReadOnly; l1section.exec = true; } else if addr >= rodata_start && addr < rodata_end { // Data: R-- l1section.access = AccessPermissions::ReadOnly; l1section.exec = false; } else { // Everything else: RW- l1section.access = AccessPermissions::FullAccess; l1section.exec = false; } }); } } pub fn setup_core1(kernel_data: &[u8]) { let kernel_start = (&kernel_data[0] as *const _ as usize) & !(L1_PAGE_SIZE - 1); let kernel_end = ((&kernel_data[kernel_data.len() - 1] as *const _ as usize) | (L1_PAGE_SIZE - 1)) + 1; let text_start = unsafe { &__text_start as *const _ as usize }; let text_end = unsafe { &__text_end as *const _ as usize }; let rodata_start = unsafe { &__rodata_start as *const _ as usize }; let rodata_end = unsafe { &__rodata_end as *const _ as usize }; let l1table = L1Table::get(); for addr in (0..0xFFFF_FFFF).step_by(L1_PAGE_SIZE) { l1table.update(addr as *const usize, |l1section| { if addr >= kernel_start && addr < kernel_end { // Kernel code/data: RWX l1section.access = AccessPermissions::FullAccess; l1section.exec = true; } else if addr >= text_start && addr < text_end { // Runtime code: R-X l1section.access = AccessPermissions::ReadOnly; l1section.exec = true; } else if addr >= rodata_start && addr < rodata_end { // Data: R-- l1section.access = AccessPermissions::ReadOnly; l1section.exec = false; } else { // Everything else: RW- l1section.access = AccessPermissions::FullAccess; l1section.exec = false; } }); } }