-
-
Save dkhayes117/926f26687e9821820b830af46fb9e797 to your computer and use it in GitHub Desktop.
PMP Address APIs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// All possible errors for this crate | |
#[derive(Debug)] | |
pub enum Error<E> { | |
MisalignedAddress, | |
IncorrectGranularity | |
} | |
pub trait PmpAddressEncoding<E> { | |
fn into_range_encoding(self) -> Result<Pmprange, Error<E>>; | |
} | |
/// Determines the granularity of a given pmp address value | |
pub fn get_granularity(value: usize) -> usize { | |
use core::mem; | |
assert!(value > 0); | |
let mut index = 0; | |
for i in 0..mem::size_of::<usize>() { | |
if ((value >> i) & 0x1) == 1 { | |
index = i; | |
break | |
} | |
} | |
1 << (index + 3) | |
} | |
/// addr is the memory address that forms the top of the memory range | |
/// | |
/// Must be 4-byte aligned | |
pub fn encode_as_tor<E>(addr: usize) -> Result<usize, Error<E>> { | |
if addr % 4 > 0 { | |
return Err(Error::MisalignedAddress); | |
} | |
Ok(addr >> 2) | |
} | |
/// base is the starting address for the range, base + size is the top of that range | |
/// | |
/// Must be 4-byte aligned | |
pub fn encode_as_napot<E>(base: usize, size: usize) -> Result<usize, Error<E>> { | |
if (base % 4 > 0) | (size % 4 > 0) { | |
return Err(Error::MisalignedAddress); | |
} | |
let napot_size = (size / 2) - 1; | |
Ok((base + napot_size) >> 2) | |
} | |
/// Defines a 4-byte address range, and must be 4 byte aligned | |
/// | |
/// Must be 4-byte aligned | |
pub fn encode_as_na4<E>(addr: usize) -> Result<usize, Error<E>> { | |
let value = addr >> 2; | |
if get_granularity(value) > 4 { | |
return Err(Error::IncorrectGranularity); | |
} | |
Ok(value) | |
} | |
/// Testing code for PmpAddr1 | |
pub struct Pmprange { | |
/// The base address of the configuration | |
base: usize, | |
/// Size of the range | |
size:usize | |
} | |
pub struct Pmpaddr { | |
/// Holds the raw contents of a Pmpaddr Register | |
bits:usize | |
} | |
pub mod pmpaddr0{ | |
use super::{Pmpaddr,Pmprange, Error}; | |
use register::PmpAddressEncoding; | |
read_csr_as!(Pmpaddr, 0x3B0, __read_pmpaddr0); | |
write_csr_as_usize!(0x3B0, __write_pmpaddr0); | |
impl <E> PmpAddressEncoding<E> for Pmpaddr { | |
fn into_range_encoding(self) -> Result<Pmprange, Error<E>> { | |
if self.bits == 0 {Err(Error::MisalignedAddress)} | |
Ok(Pmprange{ | |
base: self.bits << 2, | |
size: self.bits << 2 | |
}) | |
} | |
} | |
} | |
//reg!(0x3B0, pmpaddr0, __read_pmpaddr0, __write_pmpaddr0); | |
reg!(0x3B1, pmpaddr1, __read_pmpaddr1, __write_pmpaddr1); | |
reg!(0x3B2, pmpaddr2, __read_pmpaddr2, __write_pmpaddr2); | |
reg!(0x3B3, pmpaddr3, __read_pmpaddr3, __write_pmpaddr3); | |
reg!(0x3B4, pmpaddr4, __read_pmpaddr4, __write_pmpaddr4); | |
reg!(0x3B5, pmpaddr5, __read_pmpaddr5, __write_pmpaddr5); | |
reg!(0x3B6, pmpaddr6, __read_pmpaddr6, __write_pmpaddr6); | |
reg!(0x3B7, pmpaddr7, __read_pmpaddr7, __write_pmpaddr7); | |
reg!(0x3B8, pmpaddr8, __read_pmpaddr8, __write_pmpaddr8); | |
reg!(0x3B9, pmpaddr9, __read_pmpaddr9, __write_pmpaddr9); | |
reg!(0x3BA, pmpaddr10, __read_pmpaddr10, __write_pmpaddr10); | |
reg!(0x3BB, pmpaddr11, __read_pmpaddr11, __write_pmpaddr11); | |
reg!(0x3BC, pmpaddr12, __read_pmpaddr12, __write_pmpaddr12); | |
reg!(0x3BD, pmpaddr13, __read_pmpaddr13, __write_pmpaddr13); | |
reg!(0x3BE, pmpaddr14, __read_pmpaddr14, __write_pmpaddr14); | |
reg!(0x3BF, pmpaddr15, __read_pmpaddr15, __write_pmpaddr15); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment