@@ -118,6 +118,49 @@ const fn mair(attr: u64, mt: u64) -> u64 {
118118#[ cfg( feature = "smp" ) ]
119119pub ( crate ) static TTBR0 : AtomicPtr < u8 > = AtomicPtr :: new ( core:: ptr:: null_mut ( ) ) ;
120120
121+ // Prepare system control register (SCTRL)
122+ //
123+ // UCI [26] Enables EL0 access in AArch64 for DC CVAU, DC CIVAC,
124+ // DC CVAC and IC IVAU instructions
125+ // EE [25] Explicit data accesses at EL1 and Stage 1 translation
126+ // table walks at EL1 & EL0 are little-endian
127+ // EOE [24] Explicit data accesses at EL0 are little-endian
128+ // WXN [19] Regions with write permission are not forced to XN
129+ // nTWE [18] WFE instructions are executed as normal
130+ // nTWI [16] WFI instructions are executed as normal
131+ // UCT [15] Enables EL0 access in AArch64 to the CTR_EL0 register
132+ // DZE [14] Execution of the DC ZVA instruction is allowed at EL0
133+ // I [12] Instruction caches enabled at EL0 and EL1
134+ // UMA [9] Disable access to the interrupt masks from EL0
135+ // SED [8] The SETEND instruction is available
136+ // ITD [7] The IT instruction functionality is available
137+ // THEE [6] ThumbEE is disabled
138+ // CP15BEN [5] CP15 barrier operations disabled
139+ // SA0 [4] Stack Alignment check for EL0 enabled
140+ // SA [3] Stack Alignment check enabled
141+ // C [2] Data and unified enabled
142+ // A [1] Alignment fault checking disabled
143+ // M [0] MMU enable
144+ #[ cfg( all( feature = "smp" , target_endian = "little" ) ) ]
145+ static SCTLR_EL1 : u64 = 0b100_0000_0101_1101_0000_0001_1101 ;
146+ // The same, but EE and EOE are set to 1 for big endian.
147+ #[ cfg( all( feature = "smp" , target_endian = "big" ) ) ]
148+ static SCTLR_EL1 : u64 = 0b111_0000_0101_1101_0000_0001_1101 ;
149+
150+ #[ cfg( all( feature = "smp" , target_endian = "little" ) ) ]
151+ macro_rules! configure_endianness {
152+ ( ) => {
153+ "bic x2, x2, #(1 << 24 | 1 << 25)"
154+ } ;
155+ }
156+
157+ #[ cfg( all( feature = "smp" , target_endian = "big" ) ) ]
158+ macro_rules! configure_endianness {
159+ ( ) => {
160+ "orr x2, x2, #(1 << 24 | 1 << 25)"
161+ } ;
162+ }
163+
121164#[ cfg( feature = "smp" ) ]
122165#[ unsafe( naked) ]
123166pub ( crate ) unsafe extern "C" fn smp_start ( ) -> ! {
@@ -132,10 +175,12 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
132175 "msr tpidr_el0, xzr" ,
133176 "msr tpidr_el1, xzr" ,
134177
135- // Disable the MMU
178+ // Disable the MMU and set the correct endianness
179+ // by either clearing or setting bits 25 and 24 (EE and EOE)
136180 "dsb sy" ,
137181 "mrs x2, sctlr_el1" ,
138182 "bic x2, x2, #0x1" ,
183+ configure_endianness!( ) ,
139184 "msr sctlr_el1, x2" ,
140185 "isb" ,
141186
@@ -189,31 +234,8 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
189234 "ldr x5, [x8, #:lo12:{ttbr0}]" ,
190235 "msr ttbr0_el1, x5" ,
191236
192- // Prepare system control register (SCTRL)
193- //
194- // UCI [26] Enables EL0 access in AArch64 for DC CVAU, DC CIVAC,
195- // DC CVAC and IC IVAU instructions
196- // EE [25] Explicit data accesses at EL1 and Stage 1 translation
197- // table walks at EL1 & EL0 are little-endian
198- // EOE [24] Explicit data accesses at EL0 are little-endian
199- // WXN [19] Regions with write permission are not forced to XN
200- // nTWE [18] WFE instructions are executed as normal
201- // nTWI [16] WFI instructions are executed as normal
202- // UCT [15] Enables EL0 access in AArch64 to the CTR_EL0 register
203- // DZE [14] Execution of the DC ZVA instruction is allowed at EL0
204- // I [12] Instruction caches enabled at EL0 and EL1
205- // UMA [9] Disable access to the interrupt masks from EL0
206- // SED [8] The SETEND instruction is available
207- // ITD [7] The IT instruction functionality is available
208- // THEE [6] ThumbEE is disabled
209- // CP15BEN [5] CP15 barrier operations disabled
210- // SA0 [4] Stack Alignment check for EL0 enabled
211- // SA [3] Stack Alignment check enabled
212- // C [2] Data and unified enabled
213- // A [1] Alignment fault checking disabled
214- // M [0] MMU enable
215- "ldr x0, =0x405d01d" ,
216- "msr sctlr_el1, x0" ,
237+ "ldr x0, ={sctlr_el1}" ,
238+ "msr sctlr_el1, x0" ,
217239
218240 // initialize argument for pre_init
219241 "mov x0, xzr" ,
@@ -227,6 +249,7 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
227249 tcr_bits = const tcr_size( VA_BITS ) | TCR_TG1_4K | TCR_FLAGS ,
228250 stack_top_offset = const KERNEL_STACK_SIZE - TaskStacks :: MARKER_SIZE ,
229251 current_stack_address = sym super :: CURRENT_STACK_ADDRESS ,
252+ sctlr_el1 = const SCTLR_EL1 ,
230253 ttbr0 = sym TTBR0 ,
231254 pre_init = sym pre_init,
232255 )
0 commit comments