use crate::result::{Error, Result};
csr_field_enum! {
Permission {
default: NONE,
NONE = 0b000,
R = 0b001,
W = 0b010,
RW = 0b011,
X = 0b100,
RX = 0b101,
WX = 0b110,
RWX = 0b111,
}
}
impl TryFrom<u8> for Permission {
type Error = Error;
fn try_from(val: u8) -> Result<Self> {
Self::from_usize(val as usize)
}
}
csr_field_enum! {
Range {
default: OFF,
OFF = 0b00,
TOR = 0b01,
NA4 = 0b10,
NAPOT = 0b11,
}
}
impl TryFrom<u8> for Range {
type Error = Error;
fn try_from(val: u8) -> Result<Self> {
Self::from_usize(val as usize)
}
}
#[derive(Clone, Copy, Debug)]
pub struct Pmp {
pub byte: u8,
pub permission: Permission,
pub range: Range,
pub locked: bool,
}
pub struct Pmpcsr {
pub bits: usize,
}
impl Pmpcsr {
#[inline]
pub fn into_config(&self, index: usize) -> Pmp {
self.try_into_config(index).unwrap()
}
#[inline]
pub fn try_into_config(&self, index: usize) -> Result<Pmp> {
let max = match () {
#[cfg(target_arch = "riscv32")]
() => Ok(4usize),
#[cfg(target_arch = "riscv64")]
() => Ok(8usize),
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => Err(Error::Unimplemented),
}?;
if index < max {
let byte = (self.bits >> (8 * index)) as u8; let permission = byte & 0x7; let range = (byte >> 3) & 0x3;
Ok(Pmp {
byte,
permission: permission.try_into()?,
range: range.try_into()?,
locked: (byte & (1 << 7)) != 0,
})
} else {
Err(Error::IndexOutOfBounds {
index,
min: 0,
max: max - 1,
})
}
}
}
pub mod pmpcfg0 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A0);
write_csr_as_usize!(0x3A0);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg1 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A1);
write_csr_as_usize_rv32!(0x3A1);
set_pmp!();
clear_pmp!();
}
pub mod pmpcfg2 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A2);
write_csr_as_usize!(0x3A2);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg3 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A3);
write_csr_as_usize_rv32!(0x3A3);
set_pmp!();
clear_pmp!();
}
pub mod pmpcfg4 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A4);
write_csr_as_usize!(0x3A4);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg5 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A5);
write_csr_as_usize_rv32!(0x3A5);
set_pmp!();
clear_pmp!();
}
pub mod pmpcfg6 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A6);
write_csr_as_usize!(0x3A6);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg7 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A7);
write_csr_as_usize_rv32!(0x3A7);
set_pmp!();
clear_pmp!();
}
pub mod pmpcfg8 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A8);
write_csr_as_usize!(0x3A8);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg9 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3A9);
write_csr_as_usize_rv32!(0x3A9);
set_pmp!();
clear_pmp!();
}
pub mod pmpcfg10 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3AA);
write_csr_as_usize!(0x3AA);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg11 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3AB);
write_csr_as_usize_rv32!(0x3AB);
set_pmp!();
clear_pmp!();
}
pub mod pmpcfg12 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3AC);
write_csr_as_usize!(0x3AC);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg13 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3AD);
write_csr_as_usize_rv32!(0x3AD);
set_pmp!();
clear_pmp!();
}
pub mod pmpcfg14 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3AE);
write_csr_as_usize!(0x3AE);
set_pmp!();
clear_pmp!();
}
#[cfg(target_arch = "riscv32")]
pub mod pmpcfg15 {
use super::{Permission, Pmpcsr, Range};
read_csr_as!(Pmpcsr, 0x3AF);
write_csr_as_usize_rv32!(0x3AF);
set_pmp!();
clear_pmp!();
}