148 lines
2.7 KiB
Plaintext
148 lines
2.7 KiB
Plaintext
#include <lib/macros.aarch64_asm.h>
|
|
|
|
.set tpl_booted_flag, -64
|
|
.set tpl_hhdm_offset, -56
|
|
.set tpl_ttbr0, -48
|
|
.set tpl_ttbr1, -40
|
|
.set tpl_mair, -32
|
|
.set tpl_tcr, -24
|
|
.set tpl_sctlr, -16
|
|
.set tpl_info_struct, -8
|
|
|
|
.section .text
|
|
|
|
.global smp_trampoline_start
|
|
smp_trampoline_start:
|
|
bl .L_entry
|
|
.L_entry:
|
|
// Mask IRQs
|
|
msr daifset, #0b1111
|
|
|
|
// Address to next page (since our offsets into the boot data are negative)
|
|
add x1, x30, #0xFFC
|
|
|
|
ldr x0, [x1, tpl_info_struct]
|
|
ldr x2, [x1, tpl_sctlr]
|
|
ldr x3, [x1, tpl_mair]
|
|
ldr x4, [x1, tpl_tcr]
|
|
ldr x5, [x1, tpl_ttbr0]
|
|
ldr x6, [x1, tpl_ttbr1]
|
|
ldr x7, [x1, tpl_hhdm_offset]
|
|
|
|
PICK_EL x8, 1f, 0f
|
|
0:
|
|
// Configure EL2-specific state for EL1
|
|
|
|
// Configure EL1 page tables
|
|
msr mair_el1, x3
|
|
msr tcr_el1, x4
|
|
msr ttbr0_el1, x5
|
|
msr ttbr1_el1, x6
|
|
msr sctlr_el1, x2
|
|
isb
|
|
dsb sy
|
|
isb
|
|
|
|
// Don't trap counters to EL2
|
|
mrs x8, cnthctl_el2
|
|
orr x8, x8, #3
|
|
msr cnthctl_el2, x8
|
|
msr cntvoff_el2, xzr
|
|
|
|
// Enable AArch64 in EL1
|
|
mov x8, xzr
|
|
orr x8, x8, #(1 << 31)
|
|
orr x8, x8, #(1 << 1)
|
|
msr hcr_el2, x8
|
|
|
|
// Don't trap FP/SIMD to EL2
|
|
mov x8, #0x33FF
|
|
msr cptr_el2, x8
|
|
msr hstr_el2, xzr
|
|
|
|
// Run rest of trampoline in EL1
|
|
mov x8, #0x3c4
|
|
msr spsr_el2, x8
|
|
adrp x8, 3f
|
|
add x8, x8, :lo12:2f
|
|
add x8, x8, x7 // Add HHDM offset
|
|
msr elr_el2, x8
|
|
|
|
eret
|
|
|
|
1:
|
|
msr spsel, #0
|
|
|
|
// Switch to the new page tables
|
|
|
|
// Point the EL1t handler to the continuation, such that after we page fault,
|
|
// execution continues as expected.
|
|
adrp x8, 2f
|
|
add x8, x8, #:lo12:2f
|
|
add x8, x8, x7
|
|
msr vbar_el1, x8
|
|
isb
|
|
dsb sy
|
|
isb
|
|
|
|
// Switch the page table registers
|
|
msr mair_el1, x3
|
|
msr tcr_el1, x4
|
|
msr ttbr0_el1, x5
|
|
msr ttbr1_el1, x6
|
|
msr sctlr_el1, x2
|
|
isb
|
|
dsb sy
|
|
isb
|
|
|
|
// Jump to the higher half mapping in case we didn't immediately crash
|
|
br x8
|
|
|
|
// Alignment required by VBAR register
|
|
.align 11
|
|
2:
|
|
// Zero out VBAR to avoid confusion
|
|
msr vbar_el1, xzr
|
|
|
|
3:
|
|
// Add HHDM offset to data pointer
|
|
add x1, x1, x7
|
|
|
|
// Notify BSP we are alive
|
|
mov x8, #1
|
|
add x9, x1, tpl_booted_flag
|
|
stlr x8, [x9]
|
|
|
|
// Wait for BSP to tell us where to go
|
|
// Add HHDM offset to our info struct pointer
|
|
add x0, x0, x7
|
|
add x9, x0, #24
|
|
4:
|
|
ldar x8, [x9]
|
|
cbnz x8, 5f
|
|
yield
|
|
b 4b
|
|
|
|
5:
|
|
msr elr_el1, x8
|
|
|
|
msr spsel, #0
|
|
ldr x8, [x0, #16]
|
|
mov sp, x8
|
|
|
|
// Enter kernel
|
|
mov x8, #0x3c4
|
|
msr spsr_el1, x8
|
|
|
|
ZERO_REGS_EXCEPT_X0
|
|
|
|
eret
|
|
|
|
smp_trampoline_end:
|
|
|
|
.section .rodata
|
|
|
|
.global smp_trampoline_size
|
|
smp_trampoline_size:
|
|
.quad smp_trampoline_end - smp_trampoline_start
|