@@ -20,10 +20,15 @@ pub enum AccessPermissions {
20
20
}
21
21
22
22
impl 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
+
23
28
/// AP bit for the given access permission.
24
29
#[ 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 )
27
32
}
28
33
29
34
/// APX bit for the given access permission.
@@ -152,49 +157,46 @@ pub struct SectionAttributes {
152
157
}
153
158
154
159
impl 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
-
171
160
/// Extract the section attributes from a raw L1 section entry.
172
161
#[ inline]
173
- pub fn from_raw ( raw : u32 ) -> Result < Self , InvalidL1EntryType > {
162
+ fn from_raw ( raw : u32 ) -> Result < Self , InvalidL1EntryType > {
174
163
let section_type = L1EntryType :: new_with_raw_value ( u2:: new ( ( raw & 0b11 ) as u8 ) ) ;
175
164
if section_type != L1EntryType :: Section {
176
165
return Err ( InvalidL1EntryType ( section_type) ) ;
177
166
}
178
167
Ok ( Self :: from_raw_unchecked ( raw) )
179
168
}
180
169
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
+
181
188
/// Extract the section attributes without checking the entry type bits.
182
189
#[ 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) ;
184
192
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 ( ) ,
198
200
}
199
201
}
200
202
}
@@ -203,14 +205,14 @@ impl SectionAttributes {
203
205
///
204
206
/// The ARM Cortex-A architecture programmers manual chapter 9.4 (p.163) specifies these attributes
205
207
/// in more detail.
206
- #[ bitbybit:: bitfield( u32 ) ]
208
+ #[ bitbybit:: bitfield( u32 , default = 0x00 ) ]
207
209
#[ derive( PartialEq , Eq ) ]
208
210
pub struct L1Section {
209
211
/// Section base address.
210
212
#[ bits( 20 ..=31 , rw) ]
211
213
base_addr : u12 ,
212
214
/// Non-global bit.
213
- #[ bit( 16 , rw) ]
215
+ #[ bit( 17 , rw) ]
214
216
ng : bool ,
215
217
/// Shareable bit.
216
218
#[ bit( 16 , rw) ]
@@ -265,12 +267,25 @@ impl L1Section {
265
267
/// # Panics
266
268
///
267
269
/// 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 {
269
271
// Must be aligned to 1 MB
270
272
if phys_addr & 0x000F_FFFF != 0 {
271
273
panic ! ( "physical base address for L1 section must be aligned to 1 MB" ) ;
272
274
}
273
275
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 ( ) ;
275
290
}
276
291
}
0 commit comments