11//! Physical memory protection configuration
22
3+ use crate :: result:: { Error , Result } ;
4+
35/// Permission enum contains all possible permission modes for pmp registers
46#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
57pub enum Permission {
@@ -13,6 +15,28 @@ pub enum Permission {
1315 RWX = 0b111 ,
1416}
1517
18+ impl TryFrom < u8 > for Permission {
19+ type Error = Error ;
20+
21+ fn try_from ( val : u8 ) -> Result < Self > {
22+ match val {
23+ 0b000 => Ok ( Self :: NONE ) ,
24+ 0b001 => Ok ( Self :: R ) ,
25+ 0b010 => Ok ( Self :: W ) ,
26+ 0b011 => Ok ( Self :: RW ) ,
27+ 0b100 => Ok ( Self :: X ) ,
28+ 0b101 => Ok ( Self :: RX ) ,
29+ 0b110 => Ok ( Self :: WX ) ,
30+ 0b111 => Ok ( Self :: RWX ) ,
31+ _ => Err ( Error :: InvalidValue {
32+ field : "permission" ,
33+ value : val as usize ,
34+ bitmask : 0b111 ,
35+ } ) ,
36+ }
37+ }
38+ }
39+
1640/// Range enum contains all possible addressing modes for pmp registers
1741#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
1842pub enum Range {
@@ -22,6 +46,24 @@ pub enum Range {
2246 NAPOT = 0b11 ,
2347}
2448
49+ impl TryFrom < u8 > for Range {
50+ type Error = Error ;
51+
52+ fn try_from ( val : u8 ) -> Result < Self > {
53+ match val {
54+ 0b00 => Ok ( Self :: OFF ) ,
55+ 0b01 => Ok ( Self :: TOR ) ,
56+ 0b10 => Ok ( Self :: NA4 ) ,
57+ 0b11 => Ok ( Self :: NAPOT ) ,
58+ _ => Err ( Error :: InvalidValue {
59+ field : "range" ,
60+ value : val as usize ,
61+ bitmask : 0b11 ,
62+ } ) ,
63+ }
64+ }
65+ }
66+
2567/// Pmp struct holds a high-level representation of a single pmp configuration
2668#[ derive( Clone , Copy , Debug ) ]
2769pub struct Pmp {
@@ -76,6 +118,37 @@ impl Pmpcsr {
76118 locked : ( byte & ( 1 << 7 ) ) != 0 ,
77119 }
78120 }
121+
122+ /// Attempts to take the register contents, and translate into a Pmp configuration struct.
123+ #[ inline]
124+ pub fn try_into_config ( & self , index : usize ) -> Result < Pmp > {
125+ let max = if cfg ! ( riscv32) {
126+ Ok ( 4usize )
127+ } else if cfg ! ( riscv64) {
128+ Ok ( 8usize )
129+ } else {
130+ Err ( Error :: Unimplemented )
131+ } ?;
132+
133+ if index < max {
134+ let byte = ( self . bits >> ( 8 * index) ) as u8 ; // move config to LSB and drop the rest
135+ let permission = byte & 0x7 ; // bits 0-2
136+ let range = ( byte >> 3 ) & 0x3 ; // bits 3-4
137+
138+ Ok ( Pmp {
139+ byte,
140+ permission : permission. try_into ( ) ?,
141+ range : range. try_into ( ) ?,
142+ locked : ( byte & ( 1 << 7 ) ) != 0 ,
143+ } )
144+ } else {
145+ Err ( Error :: OutOfBounds {
146+ index,
147+ min : 0 ,
148+ max : max - 1 ,
149+ } )
150+ }
151+ }
79152}
80153
81154/// Physical memory protection configuration
0 commit comments