|
@@ -4,6 +4,7 @@ pub mod dynamic;
|
|
|
pub mod payload;
|
|
|
|
|
|
use core::arch::asm;
|
|
|
+use core::ops::Range;
|
|
|
use riscv::register::mstatus;
|
|
|
|
|
|
pub struct BootInfo {
|
|
@@ -21,9 +22,13 @@ pub use dynamic::{get_boot_hart, get_boot_info};
|
|
|
#[cfg(feature = "payload")]
|
|
|
pub use payload::{get_boot_hart, get_boot_info};
|
|
|
|
|
|
-pub fn set_pmp() {
|
|
|
- // TODO: PMP configuration needs to be obtained through the memory range in the device tree
|
|
|
+pub fn set_pmp(memory_range: &Range<usize>) {
|
|
|
unsafe {
|
|
|
+ // [0..memory_range.start] RW
|
|
|
+ // [memory_range.start..sbi_start] RWX
|
|
|
+ // [sbi_start..sbi_end] NONE
|
|
|
+ // [sbi_end..memory_range.end] RWX
|
|
|
+ // [memory_range.end..INF] RW
|
|
|
use riscv::register::*;
|
|
|
let mut sbi_start_address: usize;
|
|
|
let mut sbi_end_address: usize;
|
|
@@ -31,11 +36,15 @@ pub fn set_pmp() {
|
|
|
asm!("la {}, sbi_end", out(reg) sbi_end_address, options(nomem));
|
|
|
pmpcfg0::set_pmp(0, Range::OFF, Permission::NONE, false);
|
|
|
pmpaddr0::write(0);
|
|
|
- pmpcfg0::set_pmp(1, Range::TOR, Permission::RWX, false);
|
|
|
- pmpaddr1::write(sbi_start_address >> 2);
|
|
|
- pmpcfg0::set_pmp(2, Range::TOR, Permission::NONE, false);
|
|
|
- pmpaddr2::write(sbi_end_address >> 2);
|
|
|
- pmpcfg0::set_pmp(3, Range::TOR, Permission::RWX, false);
|
|
|
- pmpaddr3::write(usize::MAX >> 2);
|
|
|
+ pmpcfg0::set_pmp(1, Range::TOR, Permission::RW, false);
|
|
|
+ pmpaddr1::write(memory_range.start >> 2);
|
|
|
+ pmpcfg0::set_pmp(2, Range::TOR, Permission::RWX, false);
|
|
|
+ pmpaddr2::write(sbi_start_address >> 2);
|
|
|
+ pmpcfg0::set_pmp(3, Range::TOR, Permission::NONE, false);
|
|
|
+ pmpaddr3::write(sbi_end_address >> 2);
|
|
|
+ pmpcfg0::set_pmp(4, Range::TOR, Permission::RWX, false);
|
|
|
+ pmpaddr4::write(memory_range.end >> 2);
|
|
|
+ pmpcfg0::set_pmp(5, Range::TOR, Permission::RW, false);
|
|
|
+ pmpaddr5::write(usize::MAX >> 2);
|
|
|
}
|
|
|
}
|