@@ -118,6 +118,49 @@ const fn mair(attr: u64, mt: u64) -> u64 {
118
118
#[ cfg( feature = "smp" ) ]
119
119
pub ( crate ) static TTBR0 : AtomicPtr < u8 > = AtomicPtr :: new ( core:: ptr:: null_mut ( ) ) ;
120
120
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
+
121
164
#[ cfg( feature = "smp" ) ]
122
165
#[ unsafe( naked) ]
123
166
pub ( crate ) unsafe extern "C" fn smp_start ( ) -> ! {
@@ -132,10 +175,12 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
132
175
"msr tpidr_el0, xzr" ,
133
176
"msr tpidr_el1, xzr" ,
134
177
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)
136
180
"dsb sy" ,
137
181
"mrs x2, sctlr_el1" ,
138
182
"bic x2, x2, #0x1" ,
183
+ configure_endianness!( ) ,
139
184
"msr sctlr_el1, x2" ,
140
185
"isb" ,
141
186
@@ -189,31 +234,8 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
189
234
"ldr x5, [x8, #:lo12:{ttbr0}]" ,
190
235
"msr ttbr0_el1, x5" ,
191
236
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" ,
217
239
218
240
// initialize argument for pre_init
219
241
"mov x0, xzr" ,
@@ -227,6 +249,7 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
227
249
tcr_bits = const tcr_size( VA_BITS ) | TCR_TG1_4K | TCR_FLAGS ,
228
250
stack_top_offset = const KERNEL_STACK_SIZE - TaskStacks :: MARKER_SIZE ,
229
251
current_stack_address = sym super :: CURRENT_STACK_ADDRESS ,
252
+ sctlr_el1 = const SCTLR_EL1 ,
230
253
ttbr0 = sym TTBR0 ,
231
254
pre_init = sym pre_init,
232
255
)
0 commit comments