mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-31 01:24:12 +02:00
Unlike CPACR_EL1 whose reserved bits are solely RES0, CPTR_EL2 has some RES1 bits, and so we should not clear them unless we know what they mean. For example, when SVE was introduced, CPACR_EL1.ZEN occupied a RES0 field and thus 0 means trap (which is what we get at EL1), but CPTR_EL2.TZ occupied a RES1 field and thus 1 means trap, but we set it to 0, so the environment is inconsistent between EDK2 and EL1 and EL2. Another concrete case is for Morello, where the CEN/TC fields similarly gate access to capability register state, but also alter exception delivery and return, such that VBAR_ELx and ELR_ELx become capabilities. So long as software adheres to RES0/1 this is backwards-compatible, but since EDK2 does not do so here it inadvertently enables capability-based exception delivery and return and thus, when run at EL2, gets stuck in a trap loop when taking its first interrupt, but works just fine at EL1. Fix this by setting all the RES1 fields in CPTR_EL2, following the pattern for CPACR_EL1's non-zero initial value (due to setting FPEN so as to not trap on SIMD/FP use), tested by running ArmVirtQemu-AARCH64 (DEBUG) on Morello QEMU with EL2 enabled. Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
46 lines
1.6 KiB
ArmAsm
46 lines
1.6 KiB
ArmAsm
#========================================================================================
|
|
# Copyright (c) 2011-2017, ARM Limited. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
#
|
|
#=======================================================================================
|
|
|
|
#include <AsmMacroLib.h>
|
|
#include <AArch64/AArch64.h>
|
|
|
|
// Setup EL1 while in EL1
|
|
ASM_FUNC(SetupExceptionLevel1)
|
|
mov x5, x30 // Save LR
|
|
|
|
mov x0, #CPACR_DEFAULT
|
|
bl ASM_PFX(ArmWriteCpacr) // Enable architectural features
|
|
|
|
ret x5
|
|
|
|
// Setup EL2 while in EL2
|
|
ASM_FUNC(SetupExceptionLevel2)
|
|
msr sctlr_el2, xzr
|
|
mrs x0, hcr_el2 // Read EL2 Hypervisor configuration Register
|
|
|
|
// Send all interrupts to their respective Exception levels for EL2
|
|
orr x0, x0, #(1 << 3) // Enable EL2 FIQ
|
|
orr x0, x0, #(1 << 4) // Enable EL2 IRQ
|
|
orr x0, x0, #(1 << 5) // Enable EL2 SError and Abort
|
|
msr hcr_el2, x0 // Write back our settings
|
|
|
|
// NB: We assume that we have not been entered on VHE systems with
|
|
// HCR_EL2.E2H set.
|
|
mov x0, #AARCH64_CPTR_DEFAULT
|
|
msr cptr_el2, x0 // Enable architectural features
|
|
|
|
// Enable Timer access for non-secure EL1 and EL0
|
|
// The cnthctl_el2 register bits are architecturally
|
|
// UNKNOWN on reset.
|
|
// Disable event stream as it is not in use at this stage
|
|
mov x0, #(CNTHCTL_EL2_EL1PCTEN | CNTHCTL_EL2_EL1PCEN)
|
|
msr cnthctl_el2, x0
|
|
|
|
ret
|
|
|
|
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|