Skip to content

Commit 1819c7b

Browse files
committed
feat(aarch64): Initialize secondary cores with target endianness
Signed-off-by: Jens Reidel <[email protected]>
1 parent 52584b1 commit 1819c7b

File tree

1 file changed

+49
-26
lines changed

1 file changed

+49
-26
lines changed

src/arch/aarch64/kernel/start.rs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,49 @@ const fn mair(attr: u64, mt: u64) -> u64 {
118118
#[cfg(feature = "smp")]
119119
pub(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)]
123166
pub(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

Comments
 (0)