xref: /rk3399_ARM-atf/lib/el3_runtime/aarch64/context_mgmt.c (revision dc78e62d80e64bf4fe5d5bf4844a7bd1696b7c92)
1532ed618SSoby Mathew /*
2873d4241Sjohpow01  * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
3532ed618SSoby Mathew  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5532ed618SSoby Mathew  */
6532ed618SSoby Mathew 
7532ed618SSoby Mathew #include <assert.h>
840daecc1SAntonio Nino Diaz #include <stdbool.h>
9532ed618SSoby Mathew #include <string.h>
1009d40e0eSAntonio Nino Diaz 
1109d40e0eSAntonio Nino Diaz #include <platform_def.h>
1209d40e0eSAntonio Nino Diaz 
1309d40e0eSAntonio Nino Diaz #include <arch.h>
1409d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
15b7e398d6SSoby Mathew #include <arch_features.h>
1609d40e0eSAntonio Nino Diaz #include <bl31/interrupt_mgmt.h>
1709d40e0eSAntonio Nino Diaz #include <common/bl_common.h>
1809d40e0eSAntonio Nino Diaz #include <context.h>
1909d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/context_mgmt.h>
2009d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/pubsub_events.h>
2109d40e0eSAntonio Nino Diaz #include <lib/extensions/amu.h>
2209d40e0eSAntonio Nino Diaz #include <lib/extensions/mpam.h>
23*dc78e62dSjohpow01 #include <lib/extensions/sme.h>
2409d40e0eSAntonio Nino Diaz #include <lib/extensions/spe.h>
2509d40e0eSAntonio Nino Diaz #include <lib/extensions/sve.h>
26d4582d30SManish V Badarkhe #include <lib/extensions/sys_reg_trace.h>
27813524eaSManish V Badarkhe #include <lib/extensions/trbe.h>
288fcd3d96SManish V Badarkhe #include <lib/extensions/trf.h>
296cac724dSjohpow01 #include <lib/extensions/twed.h>
3009d40e0eSAntonio Nino Diaz #include <lib/utils.h>
31532ed618SSoby Mathew 
32*dc78e62dSjohpow01 static void manage_extensions_secure(cpu_context_t *ctx);
33532ed618SSoby Mathew 
34532ed618SSoby Mathew /*******************************************************************************
35532ed618SSoby Mathew  * Context management library initialisation routine. This library is used by
36532ed618SSoby Mathew  * runtime services to share pointers to 'cpu_context' structures for the secure
37532ed618SSoby Mathew  * and non-secure states. Management of the structures and their associated
38532ed618SSoby Mathew  * memory is not done by the context management library e.g. the PSCI service
39532ed618SSoby Mathew  * manages the cpu context used for entry from and exit to the non-secure state.
40532ed618SSoby Mathew  * The Secure payload dispatcher service manages the context(s) corresponding to
41532ed618SSoby Mathew  * the secure state. It also uses this library to get access to the non-secure
42532ed618SSoby Mathew  * state cpu context pointers.
43532ed618SSoby Mathew  * Lastly, this library provides the api to make SP_EL3 point to the cpu context
44532ed618SSoby Mathew  * which will used for programming an entry into a lower EL. The same context
45532ed618SSoby Mathew  * will used to save state upon exception entry from that EL.
46532ed618SSoby Mathew  ******************************************************************************/
4787c85134SDaniel Boulby void __init cm_init(void)
48532ed618SSoby Mathew {
49532ed618SSoby Mathew 	/*
50532ed618SSoby Mathew 	 * The context management library has only global data to intialize, but
51532ed618SSoby Mathew 	 * that will be done when the BSS is zeroed out
52532ed618SSoby Mathew 	 */
53532ed618SSoby Mathew }
54532ed618SSoby Mathew 
55532ed618SSoby Mathew /*******************************************************************************
56532ed618SSoby Mathew  * The following function initializes the cpu_context 'ctx' for
57532ed618SSoby Mathew  * first use, and sets the initial entrypoint state as specified by the
58532ed618SSoby Mathew  * entry_point_info structure.
59532ed618SSoby Mathew  *
60532ed618SSoby Mathew  * The security state to initialize is determined by the SECURE attribute
611634cae8SAntonio Nino Diaz  * of the entry_point_info.
62532ed618SSoby Mathew  *
638aabea33SPaul Beesley  * The EE and ST attributes are used to configure the endianness and secure
64532ed618SSoby Mathew  * timer availability for the new execution context.
65532ed618SSoby Mathew  *
66532ed618SSoby Mathew  * To prepare the register state for entry call cm_prepare_el3_exit() and
67532ed618SSoby Mathew  * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to
682e61d687SOlivier Deprez  * cm_el1_sysregs_context_restore().
69532ed618SSoby Mathew  ******************************************************************************/
701634cae8SAntonio Nino Diaz void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
71532ed618SSoby Mathew {
72532ed618SSoby Mathew 	unsigned int security_state;
73f1be00daSLouis Mayencourt 	u_register_t scr_el3;
74532ed618SSoby Mathew 	el3_state_t *state;
75532ed618SSoby Mathew 	gp_regs_t *gp_regs;
76eeb5a7b5SDeepika Bhavnani 	u_register_t sctlr_elx, actlr_elx;
77532ed618SSoby Mathew 
78a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
79532ed618SSoby Mathew 
80532ed618SSoby Mathew 	security_state = GET_SECURITY_STATE(ep->h.attr);
81532ed618SSoby Mathew 
82532ed618SSoby Mathew 	/* Clear any residual register values from the context */
8332f0d3c6SDouglas Raillard 	zeromem(ctx, sizeof(*ctx));
84532ed618SSoby Mathew 
85532ed618SSoby Mathew 	/*
8618f2efd6SDavid Cunado 	 * SCR_EL3 was initialised during reset sequence in macro
8718f2efd6SDavid Cunado 	 * el3_arch_init_common. This code modifies the SCR_EL3 fields that
8818f2efd6SDavid Cunado 	 * affect the next EL.
8918f2efd6SDavid Cunado 	 *
9018f2efd6SDavid Cunado 	 * The following fields are initially set to zero and then updated to
9118f2efd6SDavid Cunado 	 * the required value depending on the state of the SPSR_EL3 and the
9218f2efd6SDavid Cunado 	 * Security state and entrypoint attributes of the next EL.
93532ed618SSoby Mathew 	 */
94f1be00daSLouis Mayencourt 	scr_el3 = read_scr();
95532ed618SSoby Mathew 	scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
96532ed618SSoby Mathew 			SCR_ST_BIT | SCR_HCE_BIT);
97c5ea4f8aSZelalem Aweke 
98c5ea4f8aSZelalem Aweke #if ENABLE_RME
99c5ea4f8aSZelalem Aweke 	/* When RME support is enabled, clear the NSE bit as well. */
100c5ea4f8aSZelalem Aweke 	scr_el3 &= ~SCR_NSE_BIT;
101c5ea4f8aSZelalem Aweke #endif /* ENABLE_RME */
102c5ea4f8aSZelalem Aweke 
10318f2efd6SDavid Cunado 	/*
10418f2efd6SDavid Cunado 	 * SCR_NS: Set the security state of the next EL.
10518f2efd6SDavid Cunado 	 */
106c5ea4f8aSZelalem Aweke 	if (security_state == NON_SECURE) {
107532ed618SSoby Mathew 		scr_el3 |= SCR_NS_BIT;
108c5ea4f8aSZelalem Aweke 	}
109c5ea4f8aSZelalem Aweke 
110c5ea4f8aSZelalem Aweke #if ENABLE_RME
111c5ea4f8aSZelalem Aweke 	/* Check for realm state if RME support enabled. */
112c5ea4f8aSZelalem Aweke 	if (security_state == REALM) {
113c5ea4f8aSZelalem Aweke 		scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
114c5ea4f8aSZelalem Aweke 	}
115c5ea4f8aSZelalem Aweke #endif /* ENABLE_RME */
116c5ea4f8aSZelalem Aweke 
11718f2efd6SDavid Cunado 	/*
11818f2efd6SDavid Cunado 	 * SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next
11918f2efd6SDavid Cunado 	 *  Exception level as specified by SPSR.
12018f2efd6SDavid Cunado 	 */
121c5ea4f8aSZelalem Aweke 	if (GET_RW(ep->spsr) == MODE_RW_64) {
122532ed618SSoby Mathew 		scr_el3 |= SCR_RW_BIT;
123c5ea4f8aSZelalem Aweke 	}
12418f2efd6SDavid Cunado 	/*
12518f2efd6SDavid Cunado 	 * SCR_EL3.ST: Traps Secure EL1 accesses to the Counter-timer Physical
12618f2efd6SDavid Cunado 	 *  Secure timer registers to EL3, from AArch64 state only, if specified
12718f2efd6SDavid Cunado 	 *  by the entrypoint attributes.
12818f2efd6SDavid Cunado 	 */
129c5ea4f8aSZelalem Aweke 	if (EP_GET_ST(ep->h.attr) != 0U) {
130532ed618SSoby Mathew 		scr_el3 |= SCR_ST_BIT;
131c5ea4f8aSZelalem Aweke 	}
132532ed618SSoby Mathew 
133cb4ec47bSjohpow01 	/*
134cb4ec47bSjohpow01 	 * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting
135cb4ec47bSjohpow01 	 * SCR_EL3.HXEn.
136cb4ec47bSjohpow01 	 */
137cb4ec47bSjohpow01 #if ENABLE_FEAT_HCX
138cb4ec47bSjohpow01 	scr_el3 |= SCR_HXEn_BIT;
139cb4ec47bSjohpow01 #endif
140cb4ec47bSjohpow01 
141fbc44bd1SVarun Wadekar #if RAS_TRAP_LOWER_EL_ERR_ACCESS
142fbc44bd1SVarun Wadekar 	/*
143fbc44bd1SVarun Wadekar 	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
144fbc44bd1SVarun Wadekar 	 * and RAS ERX registers from EL1 and EL2 are trapped to EL3.
145fbc44bd1SVarun Wadekar 	 */
146fbc44bd1SVarun Wadekar 	scr_el3 |= SCR_TERR_BIT;
147fbc44bd1SVarun Wadekar #endif
148fbc44bd1SVarun Wadekar 
14924f671f3SJulius Werner #if !HANDLE_EA_EL3_FIRST
15018f2efd6SDavid Cunado 	/*
15118f2efd6SDavid Cunado 	 * SCR_EL3.EA: Do not route External Abort and SError Interrupt External
15218f2efd6SDavid Cunado 	 *  to EL3 when executing at a lower EL. When executing at EL3, External
15318f2efd6SDavid Cunado 	 *  Aborts are taken to EL3.
15418f2efd6SDavid Cunado 	 */
155532ed618SSoby Mathew 	scr_el3 &= ~SCR_EA_BIT;
156532ed618SSoby Mathew #endif
157532ed618SSoby Mathew 
1581a7c1cfeSJeenu Viswambharan #if FAULT_INJECTION_SUPPORT
1591a7c1cfeSJeenu Viswambharan 	/* Enable fault injection from lower ELs */
1601a7c1cfeSJeenu Viswambharan 	scr_el3 |= SCR_FIEN_BIT;
1611a7c1cfeSJeenu Viswambharan #endif
1621a7c1cfeSJeenu Viswambharan 
1635283962eSAntonio Nino Diaz #if !CTX_INCLUDE_PAUTH_REGS
1645283962eSAntonio Nino Diaz 	/*
1655283962eSAntonio Nino Diaz 	 * If the pointer authentication registers aren't saved during world
1665283962eSAntonio Nino Diaz 	 * switches the value of the registers can be leaked from the Secure to
1675283962eSAntonio Nino Diaz 	 * the Non-secure world. To prevent this, rather than enabling pointer
1685283962eSAntonio Nino Diaz 	 * authentication everywhere, we only enable it in the Non-secure world.
1695283962eSAntonio Nino Diaz 	 *
1705283962eSAntonio Nino Diaz 	 * If the Secure world wants to use pointer authentication,
1715283962eSAntonio Nino Diaz 	 * CTX_INCLUDE_PAUTH_REGS must be set to 1.
1725283962eSAntonio Nino Diaz 	 */
173c5ea4f8aSZelalem Aweke 	if (security_state == NON_SECURE) {
1745283962eSAntonio Nino Diaz 		scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
175c5ea4f8aSZelalem Aweke 	}
1765283962eSAntonio Nino Diaz #endif /* !CTX_INCLUDE_PAUTH_REGS */
1775283962eSAntonio Nino Diaz 
1780563ab08SAlexei Fedorov #if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
1790563ab08SAlexei Fedorov 	/* Get Memory Tagging Extension support level */
1800563ab08SAlexei Fedorov 	unsigned int mte = get_armv8_5_mte_support();
1810563ab08SAlexei Fedorov #endif
182b7e398d6SSoby Mathew 	/*
1839dd94382SJustin Chadwell 	 * Enable MTE support. Support is enabled unilaterally for the normal
1849dd94382SJustin Chadwell 	 * world, and only for the secure world when CTX_INCLUDE_MTE_REGS is
1859dd94382SJustin Chadwell 	 * set.
186b7e398d6SSoby Mathew 	 */
1879dd94382SJustin Chadwell #if CTX_INCLUDE_MTE_REGS
1880563ab08SAlexei Fedorov 	assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY));
1899dd94382SJustin Chadwell 	scr_el3 |= SCR_ATA_BIT;
1909dd94382SJustin Chadwell #else
1919dd94382SJustin Chadwell 	/*
1920563ab08SAlexei Fedorov 	 * When MTE is only implemented at EL0, it can be enabled
1930563ab08SAlexei Fedorov 	 * across both worlds as no MTE registers are used.
1949dd94382SJustin Chadwell 	 */
1950563ab08SAlexei Fedorov 	if ((mte == MTE_IMPLEMENTED_EL0) ||
1969dd94382SJustin Chadwell 	/*
1970563ab08SAlexei Fedorov 	 * When MTE is implemented at all ELs, it can be only enabled
1980563ab08SAlexei Fedorov 	 * in Non-Secure world without register saving.
1999dd94382SJustin Chadwell 	 */
2000563ab08SAlexei Fedorov 	  (((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY)) &&
2010563ab08SAlexei Fedorov 	    (security_state == NON_SECURE))) {
202b7e398d6SSoby Mathew 		scr_el3 |= SCR_ATA_BIT;
203b7e398d6SSoby Mathew 	}
2040563ab08SAlexei Fedorov #endif	/* CTX_INCLUDE_MTE_REGS */
205b7e398d6SSoby Mathew 
2063d8256b2SMasahiro Yamada #ifdef IMAGE_BL31
207532ed618SSoby Mathew 	/*
2088aabea33SPaul Beesley 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
20918f2efd6SDavid Cunado 	 *  indicated by the interrupt routing model for BL31.
210c5ea4f8aSZelalem Aweke 	 *
211c5ea4f8aSZelalem Aweke 	 * TODO: The interrupt routing model code is not updated for REALM
212c5ea4f8aSZelalem Aweke 	 * state. Use the default values of IRQ = FIQ = 0 for REALM security
213c5ea4f8aSZelalem Aweke 	 * state for now.
214532ed618SSoby Mathew 	 */
215c5ea4f8aSZelalem Aweke 	if (security_state != REALM) {
216532ed618SSoby Mathew 		scr_el3 |= get_scr_el3_from_routing_model(security_state);
217c5ea4f8aSZelalem Aweke 	}
2180c5e7d1cSMax Shvetsov #endif
21968ac5ed0SArunachalam Ganapathy 
22068ac5ed0SArunachalam Ganapathy 	/* Save the initialized value of CPTR_EL3 register */
22168ac5ed0SArunachalam Ganapathy 	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, read_cptr_el3());
2220c5e7d1cSMax Shvetsov 	if (security_state == SECURE) {
223*dc78e62dSjohpow01 		manage_extensions_secure(ctx);
2240c5e7d1cSMax Shvetsov 	}
225532ed618SSoby Mathew 
226532ed618SSoby Mathew 	/*
22718f2efd6SDavid Cunado 	 * SCR_EL3.HCE: Enable HVC instructions if next execution state is
22818f2efd6SDavid Cunado 	 * AArch64 and next EL is EL2, or if next execution state is AArch32 and
22918f2efd6SDavid Cunado 	 * next mode is Hyp.
230110ee433SJimmy Brisson 	 * SCR_EL3.FGTEn: Enable Fine Grained Virtualization Traps under the
231110ee433SJimmy Brisson 	 * same conditions as HVC instructions and when the processor supports
232110ee433SJimmy Brisson 	 * ARMv8.6-FGT.
23329d0ee54SJimmy Brisson 	 * SCR_EL3.ECVEn: Enable Enhanced Counter Virtualization (ECV)
23429d0ee54SJimmy Brisson 	 * CNTPOFF_EL2 register under the same conditions as HVC instructions
23529d0ee54SJimmy Brisson 	 * and when the processor supports ECV.
236532ed618SSoby Mathew 	 */
237a0fee747SAntonio Nino Diaz 	if (((GET_RW(ep->spsr) == MODE_RW_64) && (GET_EL(ep->spsr) == MODE_EL2))
238a0fee747SAntonio Nino Diaz 	    || ((GET_RW(ep->spsr) != MODE_RW_64)
239a0fee747SAntonio Nino Diaz 		&& (GET_M32(ep->spsr) == MODE32_hyp))) {
240532ed618SSoby Mathew 		scr_el3 |= SCR_HCE_BIT;
241110ee433SJimmy Brisson 
242110ee433SJimmy Brisson 		if (is_armv8_6_fgt_present()) {
243110ee433SJimmy Brisson 			scr_el3 |= SCR_FGTEN_BIT;
244110ee433SJimmy Brisson 		}
24529d0ee54SJimmy Brisson 
24629d0ee54SJimmy Brisson 		if (get_armv8_6_ecv_support()
24729d0ee54SJimmy Brisson 		    == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH) {
24829d0ee54SJimmy Brisson 			scr_el3 |= SCR_ECVEN_BIT;
24929d0ee54SJimmy Brisson 		}
250532ed618SSoby Mathew 	}
251532ed618SSoby Mathew 
2520376e7c4SAchin Gupta 	/* Enable S-EL2 if the next EL is EL2 and security state is secure */
253db3ae853SArtsem Artsemenka 	if ((security_state == SECURE) && (GET_EL(ep->spsr) == MODE_EL2)) {
254db3ae853SArtsem Artsemenka 		if (GET_RW(ep->spsr) != MODE_RW_64) {
255db3ae853SArtsem Artsemenka 			ERROR("S-EL2 can not be used in AArch32.");
256db3ae853SArtsem Artsemenka 			panic();
257db3ae853SArtsem Artsemenka 		}
258db3ae853SArtsem Artsemenka 
2590376e7c4SAchin Gupta 		scr_el3 |= SCR_EEL2_BIT;
260db3ae853SArtsem Artsemenka 	}
2610376e7c4SAchin Gupta 
26218f2efd6SDavid Cunado 	/*
263873d4241Sjohpow01 	 * FEAT_AMUv1p1 virtual offset registers are only accessible from EL3
264873d4241Sjohpow01 	 * and EL2, when clear, this bit traps accesses from EL2 so we set it
265873d4241Sjohpow01 	 * to 1 when EL2 is present.
266873d4241Sjohpow01 	 */
267873d4241Sjohpow01 	if (is_armv8_6_feat_amuv1p1_present() &&
268873d4241Sjohpow01 		(el_implemented(2) != EL_IMPL_NONE)) {
269873d4241Sjohpow01 		scr_el3 |= SCR_AMVOFFEN_BIT;
270873d4241Sjohpow01 	}
271873d4241Sjohpow01 
272873d4241Sjohpow01 	/*
27318f2efd6SDavid Cunado 	 * Initialise SCTLR_EL1 to the reset value corresponding to the target
27418f2efd6SDavid Cunado 	 * execution state setting all fields rather than relying of the hw.
27518f2efd6SDavid Cunado 	 * Some fields have architecturally UNKNOWN reset values and these are
27618f2efd6SDavid Cunado 	 * set to zero.
27718f2efd6SDavid Cunado 	 *
27818f2efd6SDavid Cunado 	 * SCTLR.EE: Endianness is taken from the entrypoint attributes.
27918f2efd6SDavid Cunado 	 *
28018f2efd6SDavid Cunado 	 * SCTLR.M, SCTLR.C and SCTLR.I: These fields must be zero (as
28118f2efd6SDavid Cunado 	 *  required by PSCI specification)
28218f2efd6SDavid Cunado 	 */
283a0fee747SAntonio Nino Diaz 	sctlr_elx = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0U;
284c5ea4f8aSZelalem Aweke 	if (GET_RW(ep->spsr) == MODE_RW_64) {
28518f2efd6SDavid Cunado 		sctlr_elx |= SCTLR_EL1_RES1;
286c5ea4f8aSZelalem Aweke 	} else {
28718f2efd6SDavid Cunado 		/*
28818f2efd6SDavid Cunado 		 * If the target execution state is AArch32 then the following
28918f2efd6SDavid Cunado 		 * fields need to be set.
29018f2efd6SDavid Cunado 		 *
29118f2efd6SDavid Cunado 		 * SCTRL_EL1.nTWE: Set to one so that EL0 execution of WFE
29218f2efd6SDavid Cunado 		 *  instructions are not trapped to EL1.
29318f2efd6SDavid Cunado 		 *
29418f2efd6SDavid Cunado 		 * SCTLR_EL1.nTWI: Set to one so that EL0 execution of WFI
29518f2efd6SDavid Cunado 		 *  instructions are not trapped to EL1.
29618f2efd6SDavid Cunado 		 *
29718f2efd6SDavid Cunado 		 * SCTLR_EL1.CP15BEN: Set to one to enable EL0 execution of the
29818f2efd6SDavid Cunado 		 *  CP15DMB, CP15DSB, and CP15ISB instructions.
29918f2efd6SDavid Cunado 		 */
30018f2efd6SDavid Cunado 		sctlr_elx |= SCTLR_AARCH32_EL1_RES1 | SCTLR_CP15BEN_BIT
30118f2efd6SDavid Cunado 					| SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
30218f2efd6SDavid Cunado 	}
30318f2efd6SDavid Cunado 
3045f5d1ed7SLouis Mayencourt #if ERRATA_A75_764081
3055f5d1ed7SLouis Mayencourt 	/*
3065f5d1ed7SLouis Mayencourt 	 * If workaround of errata 764081 for Cortex-A75 is used then set
3075f5d1ed7SLouis Mayencourt 	 * SCTLR_EL1.IESB to enable Implicit Error Synchronization Barrier.
3085f5d1ed7SLouis Mayencourt 	 */
3095f5d1ed7SLouis Mayencourt 	sctlr_elx |= SCTLR_IESB_BIT;
3105f5d1ed7SLouis Mayencourt #endif
3115f5d1ed7SLouis Mayencourt 
3126cac724dSjohpow01 	/* Enable WFE trap delay in SCR_EL3 if supported and configured */
3136cac724dSjohpow01 	if (is_armv8_6_twed_present()) {
3146cac724dSjohpow01 		uint32_t delay = plat_arm_set_twedel_scr_el3();
3156cac724dSjohpow01 
3166cac724dSjohpow01 		if (delay != TWED_DISABLED) {
3176cac724dSjohpow01 			/* Make sure delay value fits */
3186cac724dSjohpow01 			assert((delay & ~SCR_TWEDEL_MASK) == 0U);
3196cac724dSjohpow01 
3206cac724dSjohpow01 			/* Set delay in SCR_EL3 */
3216cac724dSjohpow01 			scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
3226cac724dSjohpow01 			scr_el3 |= ((delay & SCR_TWEDEL_MASK)
3236cac724dSjohpow01 					<< SCR_TWEDEL_SHIFT);
3246cac724dSjohpow01 
3256cac724dSjohpow01 			/* Enable WFE delay */
3266cac724dSjohpow01 			scr_el3 |= SCR_TWEDEn_BIT;
3276cac724dSjohpow01 		}
3286cac724dSjohpow01 	}
3296cac724dSjohpow01 
33018f2efd6SDavid Cunado 	/*
33118f2efd6SDavid Cunado 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
3322e61d687SOlivier Deprez 	 * and other EL2 registers are set up by cm_prepare_el3_exit() as they
33318f2efd6SDavid Cunado 	 * are not part of the stored cpu_context.
33418f2efd6SDavid Cunado 	 */
3352825946eSMax Shvetsov 	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
33618f2efd6SDavid Cunado 
3372ab9617eSVarun Wadekar 	/*
3382ab9617eSVarun Wadekar 	 * Base the context ACTLR_EL1 on the current value, as it is
3392ab9617eSVarun Wadekar 	 * implementation defined. The context restore process will write
3402ab9617eSVarun Wadekar 	 * the value from the context to the actual register and can cause
3412ab9617eSVarun Wadekar 	 * problems for processor cores that don't expect certain bits to
3422ab9617eSVarun Wadekar 	 * be zero.
3432ab9617eSVarun Wadekar 	 */
3442ab9617eSVarun Wadekar 	actlr_elx = read_actlr_el1();
3452825946eSMax Shvetsov 	write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
3462ab9617eSVarun Wadekar 
3473e61b2b5SDavid Cunado 	/*
348e290a8fcSAlexei Fedorov 	 * Populate EL3 state so that we've the right context
349e290a8fcSAlexei Fedorov 	 * before doing ERET
3503e61b2b5SDavid Cunado 	 */
351532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
352532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
353532ed618SSoby Mathew 	write_ctx_reg(state, CTX_ELR_EL3, ep->pc);
354532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr);
355532ed618SSoby Mathew 
356532ed618SSoby Mathew 	/*
357532ed618SSoby Mathew 	 * Store the X0-X7 value from the entrypoint into the context
358532ed618SSoby Mathew 	 * Use memcpy as we are in control of the layout of the structures
359532ed618SSoby Mathew 	 */
360532ed618SSoby Mathew 	gp_regs = get_gpregs_ctx(ctx);
361532ed618SSoby Mathew 	memcpy(gp_regs, (void *)&ep->args, sizeof(aapcs64_params_t));
362532ed618SSoby Mathew }
363532ed618SSoby Mathew 
364532ed618SSoby Mathew /*******************************************************************************
3650fd0f222SDimitris Papastamos  * Enable architecture extensions on first entry to Non-secure world.
3660fd0f222SDimitris Papastamos  * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
3670fd0f222SDimitris Papastamos  * it is zero.
3680fd0f222SDimitris Papastamos  ******************************************************************************/
369*dc78e62dSjohpow01 static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
3700fd0f222SDimitris Papastamos {
3710fd0f222SDimitris Papastamos #if IMAGE_BL31
372281a08ccSDimitris Papastamos #if ENABLE_SPE_FOR_LOWER_ELS
373281a08ccSDimitris Papastamos 	spe_enable(el2_unused);
374281a08ccSDimitris Papastamos #endif
375380559c1SDimitris Papastamos 
376380559c1SDimitris Papastamos #if ENABLE_AMU
37768ac5ed0SArunachalam Ganapathy 	amu_enable(el2_unused, ctx);
37868ac5ed0SArunachalam Ganapathy #endif
37968ac5ed0SArunachalam Ganapathy 
380*dc78e62dSjohpow01 #if ENABLE_SME_FOR_NS
381*dc78e62dSjohpow01 	/* Enable SME, SVE, and FPU/SIMD for non-secure world. */
382*dc78e62dSjohpow01 	sme_enable(ctx);
383*dc78e62dSjohpow01 #elif ENABLE_SVE_FOR_NS
384*dc78e62dSjohpow01 	/* Enable SVE and FPU/SIMD for non-secure world. */
38568ac5ed0SArunachalam Ganapathy 	sve_enable(ctx);
386380559c1SDimitris Papastamos #endif
3871a853370SDavid Cunado 
3885f835918SJeenu Viswambharan #if ENABLE_MPAM_FOR_LOWER_ELS
3895f835918SJeenu Viswambharan 	mpam_enable(el2_unused);
3905f835918SJeenu Viswambharan #endif
391813524eaSManish V Badarkhe 
392813524eaSManish V Badarkhe #if ENABLE_TRBE_FOR_NS
393813524eaSManish V Badarkhe 	trbe_enable();
394813524eaSManish V Badarkhe #endif /* ENABLE_TRBE_FOR_NS */
395813524eaSManish V Badarkhe 
396d4582d30SManish V Badarkhe #if ENABLE_SYS_REG_TRACE_FOR_NS
397d4582d30SManish V Badarkhe 	sys_reg_trace_enable(ctx);
398d4582d30SManish V Badarkhe #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
399d4582d30SManish V Badarkhe 
4008fcd3d96SManish V Badarkhe #if ENABLE_TRF_FOR_NS
4018fcd3d96SManish V Badarkhe 	trf_enable();
4028fcd3d96SManish V Badarkhe #endif /* ENABLE_TRF_FOR_NS */
4030fd0f222SDimitris Papastamos #endif
4040fd0f222SDimitris Papastamos }
4050fd0f222SDimitris Papastamos 
4060fd0f222SDimitris Papastamos /*******************************************************************************
40768ac5ed0SArunachalam Ganapathy  * Enable architecture extensions on first entry to Secure world.
40868ac5ed0SArunachalam Ganapathy  ******************************************************************************/
409*dc78e62dSjohpow01 static void manage_extensions_secure(cpu_context_t *ctx)
41068ac5ed0SArunachalam Ganapathy {
41168ac5ed0SArunachalam Ganapathy #if IMAGE_BL31
412*dc78e62dSjohpow01  #if ENABLE_SME_FOR_NS
413*dc78e62dSjohpow01   #if ENABLE_SME_FOR_SWD
414*dc78e62dSjohpow01 	/*
415*dc78e62dSjohpow01 	 * Enable SME, SVE, FPU/SIMD in secure context, secure manager must
416*dc78e62dSjohpow01 	 * ensure SME, SVE, and FPU/SIMD context properly managed.
417*dc78e62dSjohpow01 	 */
418*dc78e62dSjohpow01 	sme_enable(ctx);
419*dc78e62dSjohpow01   #else /* ENABLE_SME_FOR_SWD */
420*dc78e62dSjohpow01 	/*
421*dc78e62dSjohpow01 	 * Disable SME, SVE, FPU/SIMD in secure context so non-secure world can
422*dc78e62dSjohpow01 	 * safely use the associated registers.
423*dc78e62dSjohpow01 	 */
424*dc78e62dSjohpow01 	sme_disable(ctx);
425*dc78e62dSjohpow01   #endif /* ENABLE_SME_FOR_SWD */
426*dc78e62dSjohpow01  #elif ENABLE_SVE_FOR_NS
42768ac5ed0SArunachalam Ganapathy   #if ENABLE_SVE_FOR_SWD
428*dc78e62dSjohpow01 	/*
429*dc78e62dSjohpow01 	 * Enable SVE and FPU in secure context, secure manager must ensure that
430*dc78e62dSjohpow01 	 * the SVE and FPU register contexts are properly managed.
431*dc78e62dSjohpow01 	 */
43268ac5ed0SArunachalam Ganapathy 	sve_enable(ctx);
433*dc78e62dSjohpow01  #else /* ENABLE_SVE_FOR_SWD */
434*dc78e62dSjohpow01 	/*
435*dc78e62dSjohpow01 	 * Disable SVE and FPU in secure context so non-secure world can safely
436*dc78e62dSjohpow01 	 * use them.
437*dc78e62dSjohpow01 	 */
438*dc78e62dSjohpow01 	sve_disable(ctx);
439*dc78e62dSjohpow01   #endif /* ENABLE_SVE_FOR_SWD */
440*dc78e62dSjohpow01  #endif /* ENABLE_SVE_FOR_NS */
441*dc78e62dSjohpow01 #endif /* IMAGE_BL31 */
44268ac5ed0SArunachalam Ganapathy }
44368ac5ed0SArunachalam Ganapathy 
44468ac5ed0SArunachalam Ganapathy /*******************************************************************************
445532ed618SSoby Mathew  * The following function initializes the cpu_context for a CPU specified by
446532ed618SSoby Mathew  * its `cpu_idx` for first use, and sets the initial entrypoint state as
447532ed618SSoby Mathew  * specified by the entry_point_info structure.
448532ed618SSoby Mathew  ******************************************************************************/
449532ed618SSoby Mathew void cm_init_context_by_index(unsigned int cpu_idx,
450532ed618SSoby Mathew 			      const entry_point_info_t *ep)
451532ed618SSoby Mathew {
452532ed618SSoby Mathew 	cpu_context_t *ctx;
453532ed618SSoby Mathew 	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
4541634cae8SAntonio Nino Diaz 	cm_setup_context(ctx, ep);
455532ed618SSoby Mathew }
456532ed618SSoby Mathew 
457532ed618SSoby Mathew /*******************************************************************************
458532ed618SSoby Mathew  * The following function initializes the cpu_context for the current CPU
459532ed618SSoby Mathew  * for first use, and sets the initial entrypoint state as specified by the
460532ed618SSoby Mathew  * entry_point_info structure.
461532ed618SSoby Mathew  ******************************************************************************/
462532ed618SSoby Mathew void cm_init_my_context(const entry_point_info_t *ep)
463532ed618SSoby Mathew {
464532ed618SSoby Mathew 	cpu_context_t *ctx;
465532ed618SSoby Mathew 	ctx = cm_get_context(GET_SECURITY_STATE(ep->h.attr));
4661634cae8SAntonio Nino Diaz 	cm_setup_context(ctx, ep);
467532ed618SSoby Mathew }
468532ed618SSoby Mathew 
469532ed618SSoby Mathew /*******************************************************************************
470c5ea4f8aSZelalem Aweke  * Prepare the CPU system registers for first entry into realm, secure, or
471c5ea4f8aSZelalem Aweke  * normal world.
472532ed618SSoby Mathew  *
473532ed618SSoby Mathew  * If execution is requested to EL2 or hyp mode, SCTLR_EL2 is initialized
474532ed618SSoby Mathew  * If execution is requested to non-secure EL1 or svc mode, and the CPU supports
475532ed618SSoby Mathew  * EL2 then EL2 is disabled by configuring all necessary EL2 registers.
476532ed618SSoby Mathew  * For all entries, the EL1 registers are initialized from the cpu_context
477532ed618SSoby Mathew  ******************************************************************************/
478532ed618SSoby Mathew void cm_prepare_el3_exit(uint32_t security_state)
479532ed618SSoby Mathew {
480f1be00daSLouis Mayencourt 	u_register_t sctlr_elx, scr_el3, mdcr_el2;
481532ed618SSoby Mathew 	cpu_context_t *ctx = cm_get_context(security_state);
48240daecc1SAntonio Nino Diaz 	bool el2_unused = false;
483a0fee747SAntonio Nino Diaz 	uint64_t hcr_el2 = 0U;
484532ed618SSoby Mathew 
485a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
486532ed618SSoby Mathew 
487532ed618SSoby Mathew 	if (security_state == NON_SECURE) {
488f1be00daSLouis Mayencourt 		scr_el3 = read_ctx_reg(get_el3state_ctx(ctx),
489a0fee747SAntonio Nino Diaz 						 CTX_SCR_EL3);
490a0fee747SAntonio Nino Diaz 		if ((scr_el3 & SCR_HCE_BIT) != 0U) {
491532ed618SSoby Mathew 			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
4922825946eSMax Shvetsov 			sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
493532ed618SSoby Mathew 							   CTX_SCTLR_EL1);
4942e09d4f8SKen Kuang 			sctlr_elx &= SCTLR_EE_BIT;
495532ed618SSoby Mathew 			sctlr_elx |= SCTLR_EL2_RES1;
4965f5d1ed7SLouis Mayencourt #if ERRATA_A75_764081
4975f5d1ed7SLouis Mayencourt 			/*
4985f5d1ed7SLouis Mayencourt 			 * If workaround of errata 764081 for Cortex-A75 is used
4995f5d1ed7SLouis Mayencourt 			 * then set SCTLR_EL2.IESB to enable Implicit Error
5005f5d1ed7SLouis Mayencourt 			 * Synchronization Barrier.
5015f5d1ed7SLouis Mayencourt 			 */
5025f5d1ed7SLouis Mayencourt 			sctlr_elx |= SCTLR_IESB_BIT;
5035f5d1ed7SLouis Mayencourt #endif
504532ed618SSoby Mathew 			write_sctlr_el2(sctlr_elx);
505a0fee747SAntonio Nino Diaz 		} else if (el_implemented(2) != EL_IMPL_NONE) {
50640daecc1SAntonio Nino Diaz 			el2_unused = true;
5070fd0f222SDimitris Papastamos 
50818f2efd6SDavid Cunado 			/*
50918f2efd6SDavid Cunado 			 * EL2 present but unused, need to disable safely.
51018f2efd6SDavid Cunado 			 * SCTLR_EL2 can be ignored in this case.
51118f2efd6SDavid Cunado 			 *
5123ff4aaacSJeenu Viswambharan 			 * Set EL2 register width appropriately: Set HCR_EL2
5133ff4aaacSJeenu Viswambharan 			 * field to match SCR_EL3.RW.
51418f2efd6SDavid Cunado 			 */
515a0fee747SAntonio Nino Diaz 			if ((scr_el3 & SCR_RW_BIT) != 0U)
5163ff4aaacSJeenu Viswambharan 				hcr_el2 |= HCR_RW_BIT;
5173ff4aaacSJeenu Viswambharan 
5183ff4aaacSJeenu Viswambharan 			/*
5193ff4aaacSJeenu Viswambharan 			 * For Armv8.3 pointer authentication feature, disable
5203ff4aaacSJeenu Viswambharan 			 * traps to EL2 when accessing key registers or using
5213ff4aaacSJeenu Viswambharan 			 * pointer authentication instructions from lower ELs.
5223ff4aaacSJeenu Viswambharan 			 */
5233ff4aaacSJeenu Viswambharan 			hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
5243ff4aaacSJeenu Viswambharan 
5253ff4aaacSJeenu Viswambharan 			write_hcr_el2(hcr_el2);
526532ed618SSoby Mathew 
52718f2efd6SDavid Cunado 			/*
52818f2efd6SDavid Cunado 			 * Initialise CPTR_EL2 setting all fields rather than
52918f2efd6SDavid Cunado 			 * relying on the hw. All fields have architecturally
53018f2efd6SDavid Cunado 			 * UNKNOWN reset values.
53118f2efd6SDavid Cunado 			 *
53218f2efd6SDavid Cunado 			 * CPTR_EL2.TCPAC: Set to zero so that Non-secure EL1
53318f2efd6SDavid Cunado 			 *  accesses to the CPACR_EL1 or CPACR from both
53418f2efd6SDavid Cunado 			 *  Execution states do not trap to EL2.
53518f2efd6SDavid Cunado 			 *
53618f2efd6SDavid Cunado 			 * CPTR_EL2.TTA: Set to zero so that Non-secure System
53718f2efd6SDavid Cunado 			 *  register accesses to the trace registers from both
53818f2efd6SDavid Cunado 			 *  Execution states do not trap to EL2.
539d4582d30SManish V Badarkhe 			 *  If PE trace unit System registers are not implemented
540d4582d30SManish V Badarkhe 			 *  then this bit is reserved, and must be set to zero.
54118f2efd6SDavid Cunado 			 *
54218f2efd6SDavid Cunado 			 * CPTR_EL2.TFP: Set to zero so that Non-secure accesses
54318f2efd6SDavid Cunado 			 *  to SIMD and floating-point functionality from both
54418f2efd6SDavid Cunado 			 *  Execution states do not trap to EL2.
54518f2efd6SDavid Cunado 			 */
54618f2efd6SDavid Cunado 			write_cptr_el2(CPTR_EL2_RESET_VAL &
54718f2efd6SDavid Cunado 					~(CPTR_EL2_TCPAC_BIT | CPTR_EL2_TTA_BIT
54818f2efd6SDavid Cunado 					| CPTR_EL2_TFP_BIT));
549532ed618SSoby Mathew 
55018f2efd6SDavid Cunado 			/*
5518aabea33SPaul Beesley 			 * Initialise CNTHCTL_EL2. All fields are
55218f2efd6SDavid Cunado 			 * architecturally UNKNOWN on reset and are set to zero
55318f2efd6SDavid Cunado 			 * except for field(s) listed below.
55418f2efd6SDavid Cunado 			 *
555c5ea4f8aSZelalem Aweke 			 * CNTHCTL_EL2.EL1PTEN: Set to one to disable traps to
55618f2efd6SDavid Cunado 			 *  Hyp mode of Non-secure EL0 and EL1 accesses to the
55718f2efd6SDavid Cunado 			 *  physical timer registers.
55818f2efd6SDavid Cunado 			 *
55918f2efd6SDavid Cunado 			 * CNTHCTL_EL2.EL1PCTEN: Set to one to disable traps to
56018f2efd6SDavid Cunado 			 *  Hyp mode of  Non-secure EL0 and EL1 accesses to the
56118f2efd6SDavid Cunado 			 *  physical counter registers.
56218f2efd6SDavid Cunado 			 */
56318f2efd6SDavid Cunado 			write_cnthctl_el2(CNTHCTL_RESET_VAL |
56418f2efd6SDavid Cunado 						EL1PCEN_BIT | EL1PCTEN_BIT);
565532ed618SSoby Mathew 
56618f2efd6SDavid Cunado 			/*
56718f2efd6SDavid Cunado 			 * Initialise CNTVOFF_EL2 to zero as it resets to an
56818f2efd6SDavid Cunado 			 * architecturally UNKNOWN value.
56918f2efd6SDavid Cunado 			 */
570532ed618SSoby Mathew 			write_cntvoff_el2(0);
571532ed618SSoby Mathew 
57218f2efd6SDavid Cunado 			/*
57318f2efd6SDavid Cunado 			 * Set VPIDR_EL2 and VMPIDR_EL2 to match MIDR_EL1 and
57418f2efd6SDavid Cunado 			 * MPIDR_EL1 respectively.
57518f2efd6SDavid Cunado 			 */
576532ed618SSoby Mathew 			write_vpidr_el2(read_midr_el1());
577532ed618SSoby Mathew 			write_vmpidr_el2(read_mpidr_el1());
578532ed618SSoby Mathew 
579532ed618SSoby Mathew 			/*
58018f2efd6SDavid Cunado 			 * Initialise VTTBR_EL2. All fields are architecturally
58118f2efd6SDavid Cunado 			 * UNKNOWN on reset.
58218f2efd6SDavid Cunado 			 *
58318f2efd6SDavid Cunado 			 * VTTBR_EL2.VMID: Set to zero. Even though EL1&0 stage
58418f2efd6SDavid Cunado 			 *  2 address translation is disabled, cache maintenance
58518f2efd6SDavid Cunado 			 *  operations depend on the VMID.
58618f2efd6SDavid Cunado 			 *
58718f2efd6SDavid Cunado 			 * VTTBR_EL2.BADDR: Set to zero as EL1&0 stage 2 address
58818f2efd6SDavid Cunado 			 *  translation is disabled.
589532ed618SSoby Mathew 			 */
59018f2efd6SDavid Cunado 			write_vttbr_el2(VTTBR_RESET_VAL &
59118f2efd6SDavid Cunado 				~((VTTBR_VMID_MASK << VTTBR_VMID_SHIFT)
59218f2efd6SDavid Cunado 				| (VTTBR_BADDR_MASK << VTTBR_BADDR_SHIFT)));
59318f2efd6SDavid Cunado 
594495f3d3cSDavid Cunado 			/*
59518f2efd6SDavid Cunado 			 * Initialise MDCR_EL2, setting all fields rather than
59618f2efd6SDavid Cunado 			 * relying on hw. Some fields are architecturally
59718f2efd6SDavid Cunado 			 * UNKNOWN on reset.
59818f2efd6SDavid Cunado 			 *
599e290a8fcSAlexei Fedorov 			 * MDCR_EL2.HLP: Set to one so that event counter
600e290a8fcSAlexei Fedorov 			 *  overflow, that is recorded in PMOVSCLR_EL0[0-30],
601e290a8fcSAlexei Fedorov 			 *  occurs on the increment that changes
602e290a8fcSAlexei Fedorov 			 *  PMEVCNTR<n>_EL0[63] from 1 to 0, when ARMv8.5-PMU is
603e290a8fcSAlexei Fedorov 			 *  implemented. This bit is RES0 in versions of the
604e290a8fcSAlexei Fedorov 			 *  architecture earlier than ARMv8.5, setting it to 1
605e290a8fcSAlexei Fedorov 			 *  doesn't have any effect on them.
606e290a8fcSAlexei Fedorov 			 *
607e290a8fcSAlexei Fedorov 			 * MDCR_EL2.TTRF: Set to zero so that access to Trace
608e290a8fcSAlexei Fedorov 			 *  Filter Control register TRFCR_EL1 at EL1 is not
609e290a8fcSAlexei Fedorov 			 *  trapped to EL2. This bit is RES0 in versions of
610e290a8fcSAlexei Fedorov 			 *  the architecture earlier than ARMv8.4.
611e290a8fcSAlexei Fedorov 			 *
612e290a8fcSAlexei Fedorov 			 * MDCR_EL2.HPMD: Set to one so that event counting is
613e290a8fcSAlexei Fedorov 			 *  prohibited at EL2. This bit is RES0 in versions of
614e290a8fcSAlexei Fedorov 			 *  the architecture earlier than ARMv8.1, setting it
615e290a8fcSAlexei Fedorov 			 *  to 1 doesn't have any effect on them.
616e290a8fcSAlexei Fedorov 			 *
617e290a8fcSAlexei Fedorov 			 * MDCR_EL2.TPMS: Set to zero so that accesses to
618e290a8fcSAlexei Fedorov 			 *  Statistical Profiling control registers from EL1
619e290a8fcSAlexei Fedorov 			 *  do not trap to EL2. This bit is RES0 when SPE is
620e290a8fcSAlexei Fedorov 			 *  not implemented.
621e290a8fcSAlexei Fedorov 			 *
62218f2efd6SDavid Cunado 			 * MDCR_EL2.TDRA: Set to zero so that Non-secure EL0 and
62318f2efd6SDavid Cunado 			 *  EL1 System register accesses to the Debug ROM
62418f2efd6SDavid Cunado 			 *  registers are not trapped to EL2.
62518f2efd6SDavid Cunado 			 *
62618f2efd6SDavid Cunado 			 * MDCR_EL2.TDOSA: Set to zero so that Non-secure EL1
62718f2efd6SDavid Cunado 			 *  System register accesses to the powerdown debug
62818f2efd6SDavid Cunado 			 *  registers are not trapped to EL2.
62918f2efd6SDavid Cunado 			 *
63018f2efd6SDavid Cunado 			 * MDCR_EL2.TDA: Set to zero so that System register
63118f2efd6SDavid Cunado 			 *  accesses to the debug registers do not trap to EL2.
63218f2efd6SDavid Cunado 			 *
63318f2efd6SDavid Cunado 			 * MDCR_EL2.TDE: Set to zero so that debug exceptions
63418f2efd6SDavid Cunado 			 *  are not routed to EL2.
63518f2efd6SDavid Cunado 			 *
63618f2efd6SDavid Cunado 			 * MDCR_EL2.HPME: Set to zero to disable EL2 Performance
63718f2efd6SDavid Cunado 			 *  Monitors.
63818f2efd6SDavid Cunado 			 *
63918f2efd6SDavid Cunado 			 * MDCR_EL2.TPM: Set to zero so that Non-secure EL0 and
64018f2efd6SDavid Cunado 			 *  EL1 accesses to all Performance Monitors registers
64118f2efd6SDavid Cunado 			 *  are not trapped to EL2.
64218f2efd6SDavid Cunado 			 *
64318f2efd6SDavid Cunado 			 * MDCR_EL2.TPMCR: Set to zero so that Non-secure EL0
64418f2efd6SDavid Cunado 			 *  and EL1 accesses to the PMCR_EL0 or PMCR are not
64518f2efd6SDavid Cunado 			 *  trapped to EL2.
64618f2efd6SDavid Cunado 			 *
64718f2efd6SDavid Cunado 			 * MDCR_EL2.HPMN: Set to value of PMCR_EL0.N which is the
64818f2efd6SDavid Cunado 			 *  architecturally-defined reset value.
64940ff9074SManish V Badarkhe 			 *
65040ff9074SManish V Badarkhe 			 * MDCR_EL2.E2TB: Set to zero so that the trace Buffer
65140ff9074SManish V Badarkhe 			 *  owning exception level is NS-EL1 and, tracing is
65240ff9074SManish V Badarkhe 			 *  prohibited at NS-EL2. These bits are RES0 when
65340ff9074SManish V Badarkhe 			 *  FEAT_TRBE is not implemented.
654495f3d3cSDavid Cunado 			 */
655e290a8fcSAlexei Fedorov 			mdcr_el2 = ((MDCR_EL2_RESET_VAL | MDCR_EL2_HLP |
656e290a8fcSAlexei Fedorov 				     MDCR_EL2_HPMD) |
65718f2efd6SDavid Cunado 				   ((read_pmcr_el0() & PMCR_EL0_N_BITS)
65818f2efd6SDavid Cunado 				   >> PMCR_EL0_N_SHIFT)) &
659e290a8fcSAlexei Fedorov 				   ~(MDCR_EL2_TTRF | MDCR_EL2_TPMS |
660e290a8fcSAlexei Fedorov 				     MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT |
661e290a8fcSAlexei Fedorov 				     MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT |
662e290a8fcSAlexei Fedorov 				     MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT |
66340ff9074SManish V Badarkhe 				     MDCR_EL2_TPMCR_BIT |
66440ff9074SManish V Badarkhe 				     MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
665d832aee9Sdp-arm 
666d832aee9Sdp-arm 			write_mdcr_el2(mdcr_el2);
667d832aee9Sdp-arm 
668939f66d6SDavid Cunado 			/*
66918f2efd6SDavid Cunado 			 * Initialise HSTR_EL2. All fields are architecturally
67018f2efd6SDavid Cunado 			 * UNKNOWN on reset.
67118f2efd6SDavid Cunado 			 *
67218f2efd6SDavid Cunado 			 * HSTR_EL2.T<n>: Set all these fields to zero so that
67318f2efd6SDavid Cunado 			 *  Non-secure EL0 or EL1 accesses to System registers
67418f2efd6SDavid Cunado 			 *  do not trap to EL2.
675939f66d6SDavid Cunado 			 */
67618f2efd6SDavid Cunado 			write_hstr_el2(HSTR_EL2_RESET_VAL & ~(HSTR_EL2_T_MASK));
677939f66d6SDavid Cunado 			/*
67818f2efd6SDavid Cunado 			 * Initialise CNTHP_CTL_EL2. All fields are
67918f2efd6SDavid Cunado 			 * architecturally UNKNOWN on reset.
68018f2efd6SDavid Cunado 			 *
68118f2efd6SDavid Cunado 			 * CNTHP_CTL_EL2:ENABLE: Set to zero to disable the EL2
68218f2efd6SDavid Cunado 			 *  physical timer and prevent timer interrupts.
683939f66d6SDavid Cunado 			 */
68418f2efd6SDavid Cunado 			write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
68518f2efd6SDavid Cunado 						~(CNTHP_CTL_ENABLE_BIT));
686532ed618SSoby Mathew 		}
687*dc78e62dSjohpow01 		manage_extensions_nonsecure(el2_unused, ctx);
688532ed618SSoby Mathew 	}
689532ed618SSoby Mathew 
69017b4c0ddSDimitris Papastamos 	cm_el1_sysregs_context_restore(security_state);
69117b4c0ddSDimitris Papastamos 	cm_set_next_eret_context(security_state);
692532ed618SSoby Mathew }
693532ed618SSoby Mathew 
69428f39f02SMax Shvetsov #if CTX_INCLUDE_EL2_REGS
69528f39f02SMax Shvetsov /*******************************************************************************
69628f39f02SMax Shvetsov  * Save EL2 sysreg context
69728f39f02SMax Shvetsov  ******************************************************************************/
69828f39f02SMax Shvetsov void cm_el2_sysregs_context_save(uint32_t security_state)
69928f39f02SMax Shvetsov {
70028f39f02SMax Shvetsov 	u_register_t scr_el3 = read_scr();
70128f39f02SMax Shvetsov 
70228f39f02SMax Shvetsov 	/*
703c5ea4f8aSZelalem Aweke 	 * Always save the non-secure and realm EL2 context, only save the
70428f39f02SMax Shvetsov 	 * S-EL2 context if S-EL2 is enabled.
70528f39f02SMax Shvetsov 	 */
706c5ea4f8aSZelalem Aweke 	if ((security_state != SECURE) ||
7076b704da3SRuari Phipps 	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
70828f39f02SMax Shvetsov 		cpu_context_t *ctx;
70928f39f02SMax Shvetsov 
71028f39f02SMax Shvetsov 		ctx = cm_get_context(security_state);
71128f39f02SMax Shvetsov 		assert(ctx != NULL);
71228f39f02SMax Shvetsov 
7132825946eSMax Shvetsov 		el2_sysregs_context_save(get_el2_sysregs_ctx(ctx));
71428f39f02SMax Shvetsov 	}
71528f39f02SMax Shvetsov }
71628f39f02SMax Shvetsov 
71728f39f02SMax Shvetsov /*******************************************************************************
71828f39f02SMax Shvetsov  * Restore EL2 sysreg context
71928f39f02SMax Shvetsov  ******************************************************************************/
72028f39f02SMax Shvetsov void cm_el2_sysregs_context_restore(uint32_t security_state)
72128f39f02SMax Shvetsov {
72228f39f02SMax Shvetsov 	u_register_t scr_el3 = read_scr();
72328f39f02SMax Shvetsov 
72428f39f02SMax Shvetsov 	/*
725c5ea4f8aSZelalem Aweke 	 * Always restore the non-secure and realm EL2 context, only restore the
72628f39f02SMax Shvetsov 	 * S-EL2 context if S-EL2 is enabled.
72728f39f02SMax Shvetsov 	 */
728c5ea4f8aSZelalem Aweke 	if ((security_state != SECURE) ||
7296b704da3SRuari Phipps 	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
73028f39f02SMax Shvetsov 		cpu_context_t *ctx;
73128f39f02SMax Shvetsov 
73228f39f02SMax Shvetsov 		ctx = cm_get_context(security_state);
73328f39f02SMax Shvetsov 		assert(ctx != NULL);
73428f39f02SMax Shvetsov 
7352825946eSMax Shvetsov 		el2_sysregs_context_restore(get_el2_sysregs_ctx(ctx));
73628f39f02SMax Shvetsov 	}
73728f39f02SMax Shvetsov }
73828f39f02SMax Shvetsov #endif /* CTX_INCLUDE_EL2_REGS */
73928f39f02SMax Shvetsov 
740532ed618SSoby Mathew /*******************************************************************************
741532ed618SSoby Mathew  * The next four functions are used by runtime services to save and restore
742532ed618SSoby Mathew  * EL1 context on the 'cpu_context' structure for the specified security
743532ed618SSoby Mathew  * state.
744532ed618SSoby Mathew  ******************************************************************************/
745532ed618SSoby Mathew void cm_el1_sysregs_context_save(uint32_t security_state)
746532ed618SSoby Mathew {
747532ed618SSoby Mathew 	cpu_context_t *ctx;
748532ed618SSoby Mathew 
749532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
750a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
751532ed618SSoby Mathew 
7522825946eSMax Shvetsov 	el1_sysregs_context_save(get_el1_sysregs_ctx(ctx));
75317b4c0ddSDimitris Papastamos 
75417b4c0ddSDimitris Papastamos #if IMAGE_BL31
75517b4c0ddSDimitris Papastamos 	if (security_state == SECURE)
75617b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_exited_secure_world);
75717b4c0ddSDimitris Papastamos 	else
75817b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_exited_normal_world);
75917b4c0ddSDimitris Papastamos #endif
760532ed618SSoby Mathew }
761532ed618SSoby Mathew 
762532ed618SSoby Mathew void cm_el1_sysregs_context_restore(uint32_t security_state)
763532ed618SSoby Mathew {
764532ed618SSoby Mathew 	cpu_context_t *ctx;
765532ed618SSoby Mathew 
766532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
767a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
768532ed618SSoby Mathew 
7692825946eSMax Shvetsov 	el1_sysregs_context_restore(get_el1_sysregs_ctx(ctx));
77017b4c0ddSDimitris Papastamos 
77117b4c0ddSDimitris Papastamos #if IMAGE_BL31
77217b4c0ddSDimitris Papastamos 	if (security_state == SECURE)
77317b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_entering_secure_world);
77417b4c0ddSDimitris Papastamos 	else
77517b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_entering_normal_world);
77617b4c0ddSDimitris Papastamos #endif
777532ed618SSoby Mathew }
778532ed618SSoby Mathew 
779532ed618SSoby Mathew /*******************************************************************************
780532ed618SSoby Mathew  * This function populates ELR_EL3 member of 'cpu_context' pertaining to the
781532ed618SSoby Mathew  * given security state with the given entrypoint
782532ed618SSoby Mathew  ******************************************************************************/
783532ed618SSoby Mathew void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint)
784532ed618SSoby Mathew {
785532ed618SSoby Mathew 	cpu_context_t *ctx;
786532ed618SSoby Mathew 	el3_state_t *state;
787532ed618SSoby Mathew 
788532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
789a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
790532ed618SSoby Mathew 
791532ed618SSoby Mathew 	/* Populate EL3 state so that ERET jumps to the correct entry */
792532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
793532ed618SSoby Mathew 	write_ctx_reg(state, CTX_ELR_EL3, entrypoint);
794532ed618SSoby Mathew }
795532ed618SSoby Mathew 
796532ed618SSoby Mathew /*******************************************************************************
797532ed618SSoby Mathew  * This function populates ELR_EL3 and SPSR_EL3 members of 'cpu_context'
798532ed618SSoby Mathew  * pertaining to the given security state
799532ed618SSoby Mathew  ******************************************************************************/
800532ed618SSoby Mathew void cm_set_elr_spsr_el3(uint32_t security_state,
801532ed618SSoby Mathew 			uintptr_t entrypoint, uint32_t spsr)
802532ed618SSoby Mathew {
803532ed618SSoby Mathew 	cpu_context_t *ctx;
804532ed618SSoby Mathew 	el3_state_t *state;
805532ed618SSoby Mathew 
806532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
807a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
808532ed618SSoby Mathew 
809532ed618SSoby Mathew 	/* Populate EL3 state so that ERET jumps to the correct entry */
810532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
811532ed618SSoby Mathew 	write_ctx_reg(state, CTX_ELR_EL3, entrypoint);
812532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SPSR_EL3, spsr);
813532ed618SSoby Mathew }
814532ed618SSoby Mathew 
815532ed618SSoby Mathew /*******************************************************************************
816532ed618SSoby Mathew  * This function updates a single bit in the SCR_EL3 member of the 'cpu_context'
817532ed618SSoby Mathew  * pertaining to the given security state using the value and bit position
818532ed618SSoby Mathew  * specified in the parameters. It preserves all other bits.
819532ed618SSoby Mathew  ******************************************************************************/
820532ed618SSoby Mathew void cm_write_scr_el3_bit(uint32_t security_state,
821532ed618SSoby Mathew 			  uint32_t bit_pos,
822532ed618SSoby Mathew 			  uint32_t value)
823532ed618SSoby Mathew {
824532ed618SSoby Mathew 	cpu_context_t *ctx;
825532ed618SSoby Mathew 	el3_state_t *state;
826f1be00daSLouis Mayencourt 	u_register_t scr_el3;
827532ed618SSoby Mathew 
828532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
829a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
830532ed618SSoby Mathew 
831532ed618SSoby Mathew 	/* Ensure that the bit position is a valid one */
832d7b5f408SJimmy Brisson 	assert(((1UL << bit_pos) & SCR_VALID_BIT_MASK) != 0U);
833532ed618SSoby Mathew 
834532ed618SSoby Mathew 	/* Ensure that the 'value' is only a bit wide */
835a0fee747SAntonio Nino Diaz 	assert(value <= 1U);
836532ed618SSoby Mathew 
837532ed618SSoby Mathew 	/*
838532ed618SSoby Mathew 	 * Get the SCR_EL3 value from the cpu context, clear the desired bit
839532ed618SSoby Mathew 	 * and set it to its new value.
840532ed618SSoby Mathew 	 */
841532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
842f1be00daSLouis Mayencourt 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
843d7b5f408SJimmy Brisson 	scr_el3 &= ~(1UL << bit_pos);
844f1be00daSLouis Mayencourt 	scr_el3 |= (u_register_t)value << bit_pos;
845532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
846532ed618SSoby Mathew }
847532ed618SSoby Mathew 
848532ed618SSoby Mathew /*******************************************************************************
849532ed618SSoby Mathew  * This function retrieves SCR_EL3 member of 'cpu_context' pertaining to the
850532ed618SSoby Mathew  * given security state.
851532ed618SSoby Mathew  ******************************************************************************/
852f1be00daSLouis Mayencourt u_register_t cm_get_scr_el3(uint32_t security_state)
853532ed618SSoby Mathew {
854532ed618SSoby Mathew 	cpu_context_t *ctx;
855532ed618SSoby Mathew 	el3_state_t *state;
856532ed618SSoby Mathew 
857532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
858a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
859532ed618SSoby Mathew 
860532ed618SSoby Mathew 	/* Populate EL3 state so that ERET jumps to the correct entry */
861532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
862f1be00daSLouis Mayencourt 	return read_ctx_reg(state, CTX_SCR_EL3);
863532ed618SSoby Mathew }
864532ed618SSoby Mathew 
865532ed618SSoby Mathew /*******************************************************************************
866532ed618SSoby Mathew  * This function is used to program the context that's used for exception
867532ed618SSoby Mathew  * return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for
868532ed618SSoby Mathew  * the required security state
869532ed618SSoby Mathew  ******************************************************************************/
870532ed618SSoby Mathew void cm_set_next_eret_context(uint32_t security_state)
871532ed618SSoby Mathew {
872532ed618SSoby Mathew 	cpu_context_t *ctx;
873532ed618SSoby Mathew 
874532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
875a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
876532ed618SSoby Mathew 
877532ed618SSoby Mathew 	cm_set_next_context(ctx);
878532ed618SSoby Mathew }
879