@@ -20,10 +20,15 @@ pub enum AccessPermissions {
2020}
2121
2222impl AccessPermissions {
23+ #[ inline]
24+ pub const fn new ( apx : bool , ap : u2 ) -> Self {
25+ Self :: new_with_raw_value ( u3:: new ( ( ( apx as u8 ) << 2 ) | ap. value ( ) ) )
26+ }
27+
2328 /// AP bit for the given access permission.
2429 #[ inline]
25- pub const fn ap ( & self ) -> u8 {
26- ( * self as u8 ) & 0b11
30+ pub const fn ap ( & self ) -> u2 {
31+ u2 :: new ( ( * self as u8 ) & 0b11 )
2732 }
2833
2934 /// APX bit for the given access permission.
@@ -152,49 +157,46 @@ pub struct SectionAttributes {
152157}
153158
154159impl SectionAttributes {
155- /// Lower 18 bits of the L1 section entry.
156- #[ inline]
157- pub const fn raw ( & self ) -> u32 {
158- ( ( self . non_global as u32 ) << 17 )
159- | ( ( self . shareable as u32 ) << 16 )
160- | ( ( self . access . apx ( ) as u32 ) << 15 )
161- | ( ( self . memory_attrs . type_extensions . value ( ) as u32 ) << 12 )
162- | ( ( self . access . ap ( ) as u32 ) << 10 )
163- | ( ( self . p_bit as u32 ) << 9 )
164- | ( ( self . domain . value ( ) as u32 ) << 5 )
165- | ( ( self . execute_never as u32 ) << 4 )
166- | ( ( self . memory_attrs . c as u32 ) << 3 )
167- | ( ( self . memory_attrs . b as u32 ) << 2 )
168- | L1EntryType :: Section as u32
169- }
170-
171160 /// Extract the section attributes from a raw L1 section entry.
172161 #[ inline]
173- pub fn from_raw ( raw : u32 ) -> Result < Self , InvalidL1EntryType > {
162+ fn from_raw ( raw : u32 ) -> Result < Self , InvalidL1EntryType > {
174163 let section_type = L1EntryType :: new_with_raw_value ( u2:: new ( ( raw & 0b11 ) as u8 ) ) ;
175164 if section_type != L1EntryType :: Section {
176165 return Err ( InvalidL1EntryType ( section_type) ) ;
177166 }
178167 Ok ( Self :: from_raw_unchecked ( raw) )
179168 }
180169
170+ /// Retrieves the corresponding L1 section part without the section base address being set.
171+ const fn l1_section_part ( & self ) -> L1Section {
172+ L1Section :: builder ( )
173+ . with_base_addr ( u12:: new ( 0 ) )
174+ . with_ng ( self . non_global )
175+ . with_s ( self . shareable )
176+ . with_apx ( self . access . apx ( ) )
177+ . with_tex ( self . memory_attrs . type_extensions )
178+ . with_ap ( self . access . ap ( ) )
179+ . with_p_bit ( self . p_bit )
180+ . with_domain ( self . domain )
181+ . with_xn ( self . execute_never )
182+ . with_c ( self . memory_attrs . c )
183+ . with_b ( self . memory_attrs . b )
184+ . with_entry_type ( L1EntryType :: Section )
185+ . build ( )
186+ }
187+
181188 /// Extract the section attributes without checking the entry type bits.
182189 #[ inline]
183- pub const fn from_raw_unchecked ( raw : u32 ) -> Self {
190+ const fn from_raw_unchecked ( raw : u32 ) -> Self {
191+ let l1 = L1Section :: new_with_raw_value ( raw) ;
184192 Self {
185- non_global : ( raw >> 17 ) & 0x1 != 0 ,
186- shareable : ( raw >> 16 ) & 0x1 != 0 ,
187- p_bit : ( raw >> 9 ) & 0x1 != 0 ,
188- access : AccessPermissions :: new_with_raw_value ( u3:: new (
189- ( ( ( ( raw >> 15 ) & 0b1 ) as u8 ) << 2 ) | ( ( ( raw >> 10 ) & 0b11 ) as u8 ) ,
190- ) ) ,
191- memory_attrs : MemoryRegionAttributesRaw :: new (
192- u3:: new ( ( ( raw >> 12 ) & 0b111 ) as u8 ) ,
193- ( ( raw >> 3 ) & 0b1 ) != 0 ,
194- ( ( raw >> 2 ) & 0b1 ) as u8 != 0 ,
195- ) ,
196- domain : u4:: new ( ( ( raw >> 5 ) & 0b1111 ) as u8 ) ,
197- execute_never : ( ( raw >> 4 ) & 0b1 ) != 0 ,
193+ non_global : l1. ng ( ) ,
194+ shareable : l1. s ( ) ,
195+ p_bit : l1. p_bit ( ) ,
196+ access : AccessPermissions :: new ( l1. apx ( ) , l1. ap ( ) ) ,
197+ memory_attrs : MemoryRegionAttributesRaw :: new ( l1. tex ( ) , l1. c ( ) , l1. b ( ) ) ,
198+ domain : l1. domain ( ) ,
199+ execute_never : l1. xn ( ) ,
198200 }
199201 }
200202}
@@ -203,14 +205,14 @@ impl SectionAttributes {
203205///
204206/// The ARM Cortex-A architecture programmers manual chapter 9.4 (p.163) specifies these attributes
205207/// in more detail.
206- #[ bitbybit:: bitfield( u32 ) ]
208+ #[ bitbybit:: bitfield( u32 , default = 0x00 ) ]
207209#[ derive( PartialEq , Eq ) ]
208210pub struct L1Section {
209211 /// Section base address.
210212 #[ bits( 20 ..=31 , rw) ]
211213 base_addr : u12 ,
212214 /// Non-global bit.
213- #[ bit( 16 , rw) ]
215+ #[ bit( 17 , rw) ]
214216 ng : bool ,
215217 /// Shareable bit.
216218 #[ bit( 16 , rw) ]
@@ -265,12 +267,25 @@ impl L1Section {
265267 /// # Panics
266268 ///
267269 /// Physcal address not aligned to 1 MB.
268- pub const fn new ( phys_addr : u32 , section_attrs : SectionAttributes ) -> Self {
270+ pub const fn new_with_addr_and_attrs ( phys_addr : u32 , section_attrs : SectionAttributes ) -> Self {
269271 // Must be aligned to 1 MB
270272 if phys_addr & 0x000F_FFFF != 0 {
271273 panic ! ( "physical base address for L1 section must be aligned to 1 MB" ) ;
272274 }
273275 let higher_bits = phys_addr >> 20 ;
274- Self :: new_with_raw_value ( ( higher_bits << 20 ) | section_attrs. raw ( ) )
276+ Self :: new_with_raw_value ( ( higher_bits << 20 ) | section_attrs. l1_section_part ( ) . raw_value ( ) )
277+ }
278+
279+ /// Retrieve the section attributes.
280+ #[ inline]
281+ pub fn section_attrs ( & self ) -> Result < SectionAttributes , InvalidL1EntryType > {
282+ SectionAttributes :: from_raw ( self . raw_value ( ) )
283+ }
284+
285+ /// Set the section attributes without changing the address.
286+ #[ inline]
287+ pub const fn set_section_attrs ( & mut self , section_attrs : SectionAttributes ) {
288+ self . raw_value =
289+ ( ( self . base_addr ( ) . value ( ) as u32 ) << 20 ) | section_attrs. l1_section_part ( ) . raw_value ( ) ;
275290 }
276291}
0 commit comments