mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-05 19:51:45 +00:00
a00e68e94a
...merge start.cold.s and start.warm.s, other changes, etc.
148 lines
4.1 KiB
ArmAsm
148 lines
4.1 KiB
ArmAsm
.macro ERRATUM_INVALIDATE_BTB_AT_BOOT
|
|
/* Nintendo copy-pasted https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/nvidia/tegra/common/aarch64/tegra_helpers.S#L312 */
|
|
/*
|
|
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
/* The following comments are mine. */
|
|
/* mask all interrupts */
|
|
msr daifset, 0b1111
|
|
|
|
/*
|
|
Enable invalidates of branch target buffer, then flush
|
|
the entire instruction cache at the local level, and
|
|
with the reg change, the branch target buffer, then disable
|
|
invalidates of the branch target buffer again.
|
|
*/
|
|
mrs x0, cpuactlr_el1
|
|
orr x0, x0, #1
|
|
msr cpuactlr_el1, x0
|
|
|
|
dsb sy
|
|
isb
|
|
ic iallu
|
|
dsb sy
|
|
isb
|
|
|
|
mrs x0, cpuactlr_el1
|
|
bic x0, x0, #1
|
|
msr cpuactlr_el1, x0
|
|
|
|
.rept 7
|
|
nop /* wait long enough for the write to cpuactlr_el1 to have completed */
|
|
.endr
|
|
|
|
/* if the OS lock is set, disable it and request a warm reset */
|
|
mrs x0, oslsr_el1
|
|
ands x0, x0, #2
|
|
b.eq _set_lock_and_sp
|
|
mov x0, xzr
|
|
msr oslar_el1, x0
|
|
|
|
mov x0, #(1 << 63)
|
|
msr cpuactlr_el1, x0 /* disable regional clock gating */
|
|
isb
|
|
mov x0, #3
|
|
msr rmr_el3, x0
|
|
isb
|
|
dsb sy
|
|
/* Nintendo forgot to copy-paste the branch instruction below. */
|
|
_reset_wfi:
|
|
wfi
|
|
b _reset_wfi
|
|
.rept 65
|
|
nop /* guard against speculative excecution */
|
|
.endr
|
|
|
|
_set_lock_and_sp:
|
|
/* set the OS lock */
|
|
mov x0, #1
|
|
msr oslar_el1, x0
|
|
.endm
|
|
|
|
.align 6
|
|
.section .text.cold.start, "ax", %progbits
|
|
.global __start_cold
|
|
__start_cold:
|
|
ERRATUM_INVALIDATE_BTB_AT_BOOT
|
|
|
|
msr spsel, #0
|
|
bl get_coldboot_crt0_stack_address /* should be optimized so it doesn't make function calls */
|
|
mov sp, x0
|
|
bl coldboot_init
|
|
ldr x16, =__jump_to_main_cold
|
|
br x16
|
|
|
|
.align 6
|
|
.section .text.warm.start, "ax", %progbits
|
|
.global __start_warm
|
|
__start_warm:
|
|
ERRATUM_INVALIDATE_BTB_AT_BOOT
|
|
|
|
/* For some reasons, Nintendo uses spsel, #1 here, causing issues if an exception occurs */
|
|
msr spsel, #0
|
|
bl get_warmboot_crt0_stack_address /* should be optimized so it doesn't make function calls */
|
|
mov sp, x0
|
|
bl warmboot_init
|
|
ldr x16, =__jump_to_main_warm
|
|
br x16
|
|
|
|
.section .text.__jump_to_main_cold, "ax", %progbits
|
|
__jump_to_main_cold:
|
|
bl __set_exception_entry_stack_pointer
|
|
|
|
bl get_pk2ldr_stack_address
|
|
mov sp, x0
|
|
bl load_package2
|
|
|
|
mov w0, #3 /* use core3 stack temporarily */
|
|
bl get_exception_entry_stack_address
|
|
mov sp, x0
|
|
b coldboot_main
|
|
|
|
.section .text.__jump_to_main_warm, "ax", %progbits
|
|
__jump_to_main_warm:
|
|
/* Nintendo doesn't do that here, causing issues if an exception occurs */
|
|
bl __set_exception_entry_stack_pointer
|
|
|
|
bl get_pk2ldr_stack_address
|
|
mov sp, x0
|
|
bl load_package2
|
|
|
|
mov w0, #3 /* use core0,1,2 stack bottom + 0x800 (VA of warmboot crt0 sp) temporarily */
|
|
bl get_exception_entry_stack_address
|
|
add sp, x0, #0x800
|
|
b warmboot_main
|
|
|
|
.section .text.__set_exception_entry_stack, "ax", %progbits
|
|
.type __set_exception_entry_stack, %function
|
|
.global __set_exception_entry_stack
|
|
__set_exception_entry_stack_pointer:
|
|
/* If SPSel == 1 on entry, make sure your function doesn't use stack variables! */
|
|
mov x16, lr
|
|
mrs x17, spsel
|
|
msr x0, mpidr_el1
|
|
and w0, w0, #3
|
|
bl get_exception_entry_stack_address /* should be optimized so it doesn't make function calls */
|
|
msr spsel, #1
|
|
mov sp, x0
|
|
msr spsel, x17
|
|
mov lr, x16
|
|
ret
|
|
|
|
.section .text.__jump_to_lower_el, "ax", %progbits
|
|
.global __jump_to_lower_el
|
|
.type __jump_to_lower_el, %function
|
|
__jump_to_lower_el:
|
|
/* x0: arg (context ID), x1: entrypoint, w2: exception level */
|
|
msr elr_el3, x1
|
|
|
|
mov x1, #((0b1111 << 6) | 1) /* DAIF set and SP = SP_ELx*/
|
|
orr x1, w2, lsl#2
|
|
msr spsr_el3, x1
|
|
|
|
bl __set_exception_entry_stack_pointer
|
|
|
|
isb
|
|
eret
|