xref: /rk3399_ARM-atf/lib/el3_runtime/aarch64/context_mgmt.c (revision 2bbad1d126248435e26f9d0d9f5920d8806148d7)
1532ed618SSoby Mathew /*
2*2bbad1d1SZelalem Aweke  * Copyright (c) 2013-2022, 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>
23dc78e62dSjohpow01 #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 
32dc78e62dSjohpow01 static void manage_extensions_secure(cpu_context_t *ctx);
33532ed618SSoby Mathew 
34*2bbad1d1SZelalem Aweke /******************************************************************************
35*2bbad1d1SZelalem Aweke  * This function performs initializations that are specific to SECURE state
36*2bbad1d1SZelalem Aweke  * and updates the cpu context specified by 'ctx'.
37*2bbad1d1SZelalem Aweke  *****************************************************************************/
38*2bbad1d1SZelalem Aweke static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_info *ep)
39532ed618SSoby Mathew {
40*2bbad1d1SZelalem Aweke 	u_register_t scr_el3;
41*2bbad1d1SZelalem Aweke 	el3_state_t *state;
42*2bbad1d1SZelalem Aweke 
43*2bbad1d1SZelalem Aweke 	state = get_el3state_ctx(ctx);
44*2bbad1d1SZelalem Aweke 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
45*2bbad1d1SZelalem Aweke 
46*2bbad1d1SZelalem Aweke #if defined(IMAGE_BL31) && !defined(SPD_spmd)
47532ed618SSoby Mathew 	/*
48*2bbad1d1SZelalem Aweke 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
49*2bbad1d1SZelalem Aweke 	 * indicated by the interrupt routing model for BL31.
50532ed618SSoby Mathew 	 */
51*2bbad1d1SZelalem Aweke 	scr_el3 |= get_scr_el3_from_routing_model(SECURE);
52*2bbad1d1SZelalem Aweke #endif
53*2bbad1d1SZelalem Aweke 
54*2bbad1d1SZelalem Aweke #if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
55*2bbad1d1SZelalem Aweke 	/* Get Memory Tagging Extension support level */
56*2bbad1d1SZelalem Aweke 	unsigned int mte = get_armv8_5_mte_support();
57*2bbad1d1SZelalem Aweke #endif
58*2bbad1d1SZelalem Aweke 	/*
59*2bbad1d1SZelalem Aweke 	 * Allow access to Allocation Tags when CTX_INCLUDE_MTE_REGS
60*2bbad1d1SZelalem Aweke 	 * is set, or when MTE is only implemented at EL0.
61*2bbad1d1SZelalem Aweke 	 */
62*2bbad1d1SZelalem Aweke #if CTX_INCLUDE_MTE_REGS
63*2bbad1d1SZelalem Aweke 	assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY));
64*2bbad1d1SZelalem Aweke 	scr_el3 |= SCR_ATA_BIT;
65*2bbad1d1SZelalem Aweke #else
66*2bbad1d1SZelalem Aweke 	if (mte == MTE_IMPLEMENTED_EL0) {
67*2bbad1d1SZelalem Aweke 		scr_el3 |= SCR_ATA_BIT;
68*2bbad1d1SZelalem Aweke 	}
69*2bbad1d1SZelalem Aweke #endif /* CTX_INCLUDE_MTE_REGS */
70*2bbad1d1SZelalem Aweke 
71*2bbad1d1SZelalem Aweke 	/* Enable S-EL2 if the next EL is EL2 and S-EL2 is present */
72*2bbad1d1SZelalem Aweke 	if ((GET_EL(ep->spsr) == MODE_EL2) && is_armv8_4_sel2_present()) {
73*2bbad1d1SZelalem Aweke 		if (GET_RW(ep->spsr) != MODE_RW_64) {
74*2bbad1d1SZelalem Aweke 			ERROR("S-EL2 can not be used in AArch32\n.");
75*2bbad1d1SZelalem Aweke 			panic();
76*2bbad1d1SZelalem Aweke 		}
77*2bbad1d1SZelalem Aweke 
78*2bbad1d1SZelalem Aweke 		scr_el3 |= SCR_EEL2_BIT;
79*2bbad1d1SZelalem Aweke 	}
80*2bbad1d1SZelalem Aweke 
81*2bbad1d1SZelalem Aweke 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
82*2bbad1d1SZelalem Aweke 
83*2bbad1d1SZelalem Aweke 	manage_extensions_secure(ctx);
84*2bbad1d1SZelalem Aweke }
85*2bbad1d1SZelalem Aweke 
86*2bbad1d1SZelalem Aweke #if ENABLE_RME
87*2bbad1d1SZelalem Aweke /******************************************************************************
88*2bbad1d1SZelalem Aweke  * This function performs initializations that are specific to REALM state
89*2bbad1d1SZelalem Aweke  * and updates the cpu context specified by 'ctx'.
90*2bbad1d1SZelalem Aweke  *****************************************************************************/
91*2bbad1d1SZelalem Aweke static void setup_realm_context(cpu_context_t *ctx, const struct entry_point_info *ep)
92*2bbad1d1SZelalem Aweke {
93*2bbad1d1SZelalem Aweke 	u_register_t scr_el3;
94*2bbad1d1SZelalem Aweke 	el3_state_t *state;
95*2bbad1d1SZelalem Aweke 
96*2bbad1d1SZelalem Aweke 	state = get_el3state_ctx(ctx);
97*2bbad1d1SZelalem Aweke 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
98*2bbad1d1SZelalem Aweke 
99*2bbad1d1SZelalem Aweke 	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
100*2bbad1d1SZelalem Aweke 
101*2bbad1d1SZelalem Aweke 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
102*2bbad1d1SZelalem Aweke }
103*2bbad1d1SZelalem Aweke #endif /* ENABLE_RME */
104*2bbad1d1SZelalem Aweke 
105*2bbad1d1SZelalem Aweke /******************************************************************************
106*2bbad1d1SZelalem Aweke  * This function performs initializations that are specific to NON-SECURE state
107*2bbad1d1SZelalem Aweke  * and updates the cpu context specified by 'ctx'.
108*2bbad1d1SZelalem Aweke  *****************************************************************************/
109*2bbad1d1SZelalem Aweke static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *ep)
110*2bbad1d1SZelalem Aweke {
111*2bbad1d1SZelalem Aweke 	u_register_t scr_el3;
112*2bbad1d1SZelalem Aweke 	el3_state_t *state;
113*2bbad1d1SZelalem Aweke 
114*2bbad1d1SZelalem Aweke 	state = get_el3state_ctx(ctx);
115*2bbad1d1SZelalem Aweke 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
116*2bbad1d1SZelalem Aweke 
117*2bbad1d1SZelalem Aweke 	/* SCR_NS: Set the NS bit */
118*2bbad1d1SZelalem Aweke 	scr_el3 |= SCR_NS_BIT;
119*2bbad1d1SZelalem Aweke 
120*2bbad1d1SZelalem Aweke #if !CTX_INCLUDE_PAUTH_REGS
121*2bbad1d1SZelalem Aweke 	/*
122*2bbad1d1SZelalem Aweke 	 * If the pointer authentication registers aren't saved during world
123*2bbad1d1SZelalem Aweke 	 * switches the value of the registers can be leaked from the Secure to
124*2bbad1d1SZelalem Aweke 	 * the Non-secure world. To prevent this, rather than enabling pointer
125*2bbad1d1SZelalem Aweke 	 * authentication everywhere, we only enable it in the Non-secure world.
126*2bbad1d1SZelalem Aweke 	 *
127*2bbad1d1SZelalem Aweke 	 * If the Secure world wants to use pointer authentication,
128*2bbad1d1SZelalem Aweke 	 * CTX_INCLUDE_PAUTH_REGS must be set to 1.
129*2bbad1d1SZelalem Aweke 	 */
130*2bbad1d1SZelalem Aweke 	scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
131*2bbad1d1SZelalem Aweke #endif /* !CTX_INCLUDE_PAUTH_REGS */
132*2bbad1d1SZelalem Aweke 
133*2bbad1d1SZelalem Aweke 	/* Allow access to Allocation Tags when MTE is implemented. */
134*2bbad1d1SZelalem Aweke 	scr_el3 |= SCR_ATA_BIT;
135*2bbad1d1SZelalem Aweke 
136*2bbad1d1SZelalem Aweke #ifdef IMAGE_BL31
137*2bbad1d1SZelalem Aweke 	/*
138*2bbad1d1SZelalem Aweke 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
139*2bbad1d1SZelalem Aweke 	 *  indicated by the interrupt routing model for BL31.
140*2bbad1d1SZelalem Aweke 	 */
141*2bbad1d1SZelalem Aweke 	scr_el3 |= get_scr_el3_from_routing_model(NON_SECURE);
142*2bbad1d1SZelalem Aweke #endif
143*2bbad1d1SZelalem Aweke 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
144532ed618SSoby Mathew }
145532ed618SSoby Mathew 
146532ed618SSoby Mathew /*******************************************************************************
147*2bbad1d1SZelalem Aweke  * The following function performs initialization of the cpu_context 'ctx'
148*2bbad1d1SZelalem Aweke  * for first use that is common to all security states, and sets the
149*2bbad1d1SZelalem Aweke  * initial entrypoint state as specified by the entry_point_info structure.
150532ed618SSoby Mathew  *
1518aabea33SPaul Beesley  * The EE and ST attributes are used to configure the endianness and secure
152532ed618SSoby Mathew  * timer availability for the new execution context.
153532ed618SSoby Mathew  ******************************************************************************/
154*2bbad1d1SZelalem Aweke static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep)
155532ed618SSoby Mathew {
156f1be00daSLouis Mayencourt 	u_register_t scr_el3;
157532ed618SSoby Mathew 	el3_state_t *state;
158532ed618SSoby Mathew 	gp_regs_t *gp_regs;
159eeb5a7b5SDeepika Bhavnani 	u_register_t sctlr_elx, actlr_elx;
160532ed618SSoby Mathew 
161532ed618SSoby Mathew 	/* Clear any residual register values from the context */
16232f0d3c6SDouglas Raillard 	zeromem(ctx, sizeof(*ctx));
163532ed618SSoby Mathew 
164532ed618SSoby Mathew 	/*
16518f2efd6SDavid Cunado 	 * SCR_EL3 was initialised during reset sequence in macro
16618f2efd6SDavid Cunado 	 * el3_arch_init_common. This code modifies the SCR_EL3 fields that
16718f2efd6SDavid Cunado 	 * affect the next EL.
16818f2efd6SDavid Cunado 	 *
16918f2efd6SDavid Cunado 	 * The following fields are initially set to zero and then updated to
17018f2efd6SDavid Cunado 	 * the required value depending on the state of the SPSR_EL3 and the
17118f2efd6SDavid Cunado 	 * Security state and entrypoint attributes of the next EL.
172532ed618SSoby Mathew 	 */
173f1be00daSLouis Mayencourt 	scr_el3 = read_scr();
174532ed618SSoby Mathew 	scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
175*2bbad1d1SZelalem Aweke 			SCR_ST_BIT | SCR_HCE_BIT | SCR_NSE_BIT);
176c5ea4f8aSZelalem Aweke 
17718f2efd6SDavid Cunado 	/*
17818f2efd6SDavid Cunado 	 * SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next
17918f2efd6SDavid Cunado 	 *  Exception level as specified by SPSR.
18018f2efd6SDavid Cunado 	 */
181c5ea4f8aSZelalem Aweke 	if (GET_RW(ep->spsr) == MODE_RW_64) {
182532ed618SSoby Mathew 		scr_el3 |= SCR_RW_BIT;
183c5ea4f8aSZelalem Aweke 	}
184*2bbad1d1SZelalem Aweke 
18518f2efd6SDavid Cunado 	/*
18618f2efd6SDavid Cunado 	 * SCR_EL3.ST: Traps Secure EL1 accesses to the Counter-timer Physical
18718f2efd6SDavid Cunado 	 *  Secure timer registers to EL3, from AArch64 state only, if specified
18818f2efd6SDavid Cunado 	 *  by the entrypoint attributes.
18918f2efd6SDavid Cunado 	 */
190c5ea4f8aSZelalem Aweke 	if (EP_GET_ST(ep->h.attr) != 0U) {
191532ed618SSoby Mathew 		scr_el3 |= SCR_ST_BIT;
192c5ea4f8aSZelalem Aweke 	}
193532ed618SSoby Mathew 
194cb4ec47bSjohpow01 	/*
195cb4ec47bSjohpow01 	 * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting
196cb4ec47bSjohpow01 	 * SCR_EL3.HXEn.
197cb4ec47bSjohpow01 	 */
198cb4ec47bSjohpow01 #if ENABLE_FEAT_HCX
199cb4ec47bSjohpow01 	scr_el3 |= SCR_HXEn_BIT;
200cb4ec47bSjohpow01 #endif
201cb4ec47bSjohpow01 
202fbc44bd1SVarun Wadekar #if RAS_TRAP_LOWER_EL_ERR_ACCESS
203fbc44bd1SVarun Wadekar 	/*
204fbc44bd1SVarun Wadekar 	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
205fbc44bd1SVarun Wadekar 	 * and RAS ERX registers from EL1 and EL2 are trapped to EL3.
206fbc44bd1SVarun Wadekar 	 */
207fbc44bd1SVarun Wadekar 	scr_el3 |= SCR_TERR_BIT;
208fbc44bd1SVarun Wadekar #endif
209fbc44bd1SVarun Wadekar 
21024f671f3SJulius Werner #if !HANDLE_EA_EL3_FIRST
21118f2efd6SDavid Cunado 	/*
21218f2efd6SDavid Cunado 	 * SCR_EL3.EA: Do not route External Abort and SError Interrupt External
21318f2efd6SDavid Cunado 	 * to EL3 when executing at a lower EL. When executing at EL3, External
21418f2efd6SDavid Cunado 	 * Aborts are taken to EL3.
21518f2efd6SDavid Cunado 	 */
216532ed618SSoby Mathew 	scr_el3 &= ~SCR_EA_BIT;
217532ed618SSoby Mathew #endif
218532ed618SSoby Mathew 
2191a7c1cfeSJeenu Viswambharan #if FAULT_INJECTION_SUPPORT
2201a7c1cfeSJeenu Viswambharan 	/* Enable fault injection from lower ELs */
2211a7c1cfeSJeenu Viswambharan 	scr_el3 |= SCR_FIEN_BIT;
2221a7c1cfeSJeenu Viswambharan #endif
2231a7c1cfeSJeenu Viswambharan 
2245283962eSAntonio Nino Diaz 	/*
225*2bbad1d1SZelalem Aweke 	 * CPTR_EL3 was initialized out of reset, copy that value to the
226*2bbad1d1SZelalem Aweke 	 * context register.
2275283962eSAntonio Nino Diaz 	 */
22868ac5ed0SArunachalam Ganapathy 	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, read_cptr_el3());
229532ed618SSoby Mathew 
230532ed618SSoby Mathew 	/*
23118f2efd6SDavid Cunado 	 * SCR_EL3.HCE: Enable HVC instructions if next execution state is
23218f2efd6SDavid Cunado 	 * AArch64 and next EL is EL2, or if next execution state is AArch32 and
23318f2efd6SDavid Cunado 	 * next mode is Hyp.
234110ee433SJimmy Brisson 	 * SCR_EL3.FGTEn: Enable Fine Grained Virtualization Traps under the
235110ee433SJimmy Brisson 	 * same conditions as HVC instructions and when the processor supports
236110ee433SJimmy Brisson 	 * ARMv8.6-FGT.
23729d0ee54SJimmy Brisson 	 * SCR_EL3.ECVEn: Enable Enhanced Counter Virtualization (ECV)
23829d0ee54SJimmy Brisson 	 * CNTPOFF_EL2 register under the same conditions as HVC instructions
23929d0ee54SJimmy Brisson 	 * and when the processor supports ECV.
240532ed618SSoby Mathew 	 */
241a0fee747SAntonio Nino Diaz 	if (((GET_RW(ep->spsr) == MODE_RW_64) && (GET_EL(ep->spsr) == MODE_EL2))
242a0fee747SAntonio Nino Diaz 	    || ((GET_RW(ep->spsr) != MODE_RW_64)
243a0fee747SAntonio Nino Diaz 		&& (GET_M32(ep->spsr) == MODE32_hyp))) {
244532ed618SSoby Mathew 		scr_el3 |= SCR_HCE_BIT;
245110ee433SJimmy Brisson 
246110ee433SJimmy Brisson 		if (is_armv8_6_fgt_present()) {
247110ee433SJimmy Brisson 			scr_el3 |= SCR_FGTEN_BIT;
248110ee433SJimmy Brisson 		}
24929d0ee54SJimmy Brisson 
25029d0ee54SJimmy Brisson 		if (get_armv8_6_ecv_support()
25129d0ee54SJimmy Brisson 		    == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH) {
25229d0ee54SJimmy Brisson 			scr_el3 |= SCR_ECVEN_BIT;
25329d0ee54SJimmy Brisson 		}
254532ed618SSoby Mathew 	}
255532ed618SSoby Mathew 
25618f2efd6SDavid Cunado 	/*
257873d4241Sjohpow01 	 * FEAT_AMUv1p1 virtual offset registers are only accessible from EL3
258873d4241Sjohpow01 	 * and EL2, when clear, this bit traps accesses from EL2 so we set it
259873d4241Sjohpow01 	 * to 1 when EL2 is present.
260873d4241Sjohpow01 	 */
261873d4241Sjohpow01 	if (is_armv8_6_feat_amuv1p1_present() &&
262873d4241Sjohpow01 		(el_implemented(2) != EL_IMPL_NONE)) {
263873d4241Sjohpow01 		scr_el3 |= SCR_AMVOFFEN_BIT;
264873d4241Sjohpow01 	}
265873d4241Sjohpow01 
266873d4241Sjohpow01 	/*
26718f2efd6SDavid Cunado 	 * Initialise SCTLR_EL1 to the reset value corresponding to the target
26818f2efd6SDavid Cunado 	 * execution state setting all fields rather than relying of the hw.
26918f2efd6SDavid Cunado 	 * Some fields have architecturally UNKNOWN reset values and these are
27018f2efd6SDavid Cunado 	 * set to zero.
27118f2efd6SDavid Cunado 	 *
27218f2efd6SDavid Cunado 	 * SCTLR.EE: Endianness is taken from the entrypoint attributes.
27318f2efd6SDavid Cunado 	 *
27418f2efd6SDavid Cunado 	 * SCTLR.M, SCTLR.C and SCTLR.I: These fields must be zero (as
27518f2efd6SDavid Cunado 	 *  required by PSCI specification)
27618f2efd6SDavid Cunado 	 */
277a0fee747SAntonio Nino Diaz 	sctlr_elx = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0U;
278c5ea4f8aSZelalem Aweke 	if (GET_RW(ep->spsr) == MODE_RW_64) {
27918f2efd6SDavid Cunado 		sctlr_elx |= SCTLR_EL1_RES1;
280c5ea4f8aSZelalem Aweke 	} else {
28118f2efd6SDavid Cunado 		/*
28218f2efd6SDavid Cunado 		 * If the target execution state is AArch32 then the following
28318f2efd6SDavid Cunado 		 * fields need to be set.
28418f2efd6SDavid Cunado 		 *
28518f2efd6SDavid Cunado 		 * SCTRL_EL1.nTWE: Set to one so that EL0 execution of WFE
28618f2efd6SDavid Cunado 		 *  instructions are not trapped to EL1.
28718f2efd6SDavid Cunado 		 *
28818f2efd6SDavid Cunado 		 * SCTLR_EL1.nTWI: Set to one so that EL0 execution of WFI
28918f2efd6SDavid Cunado 		 *  instructions are not trapped to EL1.
29018f2efd6SDavid Cunado 		 *
29118f2efd6SDavid Cunado 		 * SCTLR_EL1.CP15BEN: Set to one to enable EL0 execution of the
29218f2efd6SDavid Cunado 		 *  CP15DMB, CP15DSB, and CP15ISB instructions.
29318f2efd6SDavid Cunado 		 */
29418f2efd6SDavid Cunado 		sctlr_elx |= SCTLR_AARCH32_EL1_RES1 | SCTLR_CP15BEN_BIT
29518f2efd6SDavid Cunado 					| SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
29618f2efd6SDavid Cunado 	}
29718f2efd6SDavid Cunado 
2985f5d1ed7SLouis Mayencourt #if ERRATA_A75_764081
2995f5d1ed7SLouis Mayencourt 	/*
3005f5d1ed7SLouis Mayencourt 	 * If workaround of errata 764081 for Cortex-A75 is used then set
3015f5d1ed7SLouis Mayencourt 	 * SCTLR_EL1.IESB to enable Implicit Error Synchronization Barrier.
3025f5d1ed7SLouis Mayencourt 	 */
3035f5d1ed7SLouis Mayencourt 	sctlr_elx |= SCTLR_IESB_BIT;
3045f5d1ed7SLouis Mayencourt #endif
3055f5d1ed7SLouis Mayencourt 
3066cac724dSjohpow01 	/* Enable WFE trap delay in SCR_EL3 if supported and configured */
3076cac724dSjohpow01 	if (is_armv8_6_twed_present()) {
3086cac724dSjohpow01 		uint32_t delay = plat_arm_set_twedel_scr_el3();
3096cac724dSjohpow01 
3106cac724dSjohpow01 		if (delay != TWED_DISABLED) {
3116cac724dSjohpow01 			/* Make sure delay value fits */
3126cac724dSjohpow01 			assert((delay & ~SCR_TWEDEL_MASK) == 0U);
3136cac724dSjohpow01 
3146cac724dSjohpow01 			/* Set delay in SCR_EL3 */
3156cac724dSjohpow01 			scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
3166cac724dSjohpow01 			scr_el3 |= ((delay & SCR_TWEDEL_MASK)
3176cac724dSjohpow01 					<< SCR_TWEDEL_SHIFT);
3186cac724dSjohpow01 
3196cac724dSjohpow01 			/* Enable WFE delay */
3206cac724dSjohpow01 			scr_el3 |= SCR_TWEDEn_BIT;
3216cac724dSjohpow01 		}
3226cac724dSjohpow01 	}
3236cac724dSjohpow01 
32418f2efd6SDavid Cunado 	/*
32518f2efd6SDavid Cunado 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
3262e61d687SOlivier Deprez 	 * and other EL2 registers are set up by cm_prepare_el3_exit() as they
32718f2efd6SDavid Cunado 	 * are not part of the stored cpu_context.
32818f2efd6SDavid Cunado 	 */
3292825946eSMax Shvetsov 	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
33018f2efd6SDavid Cunado 
3312ab9617eSVarun Wadekar 	/*
3322ab9617eSVarun Wadekar 	 * Base the context ACTLR_EL1 on the current value, as it is
3332ab9617eSVarun Wadekar 	 * implementation defined. The context restore process will write
3342ab9617eSVarun Wadekar 	 * the value from the context to the actual register and can cause
3352ab9617eSVarun Wadekar 	 * problems for processor cores that don't expect certain bits to
3362ab9617eSVarun Wadekar 	 * be zero.
3372ab9617eSVarun Wadekar 	 */
3382ab9617eSVarun Wadekar 	actlr_elx = read_actlr_el1();
3392825946eSMax Shvetsov 	write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
3402ab9617eSVarun Wadekar 
3413e61b2b5SDavid Cunado 	/*
342e290a8fcSAlexei Fedorov 	 * Populate EL3 state so that we've the right context
343e290a8fcSAlexei Fedorov 	 * before doing ERET
3443e61b2b5SDavid Cunado 	 */
345532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
346532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
347532ed618SSoby Mathew 	write_ctx_reg(state, CTX_ELR_EL3, ep->pc);
348532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr);
349532ed618SSoby Mathew 
350532ed618SSoby Mathew 	/*
351532ed618SSoby Mathew 	 * Store the X0-X7 value from the entrypoint into the context
352532ed618SSoby Mathew 	 * Use memcpy as we are in control of the layout of the structures
353532ed618SSoby Mathew 	 */
354532ed618SSoby Mathew 	gp_regs = get_gpregs_ctx(ctx);
355532ed618SSoby Mathew 	memcpy(gp_regs, (void *)&ep->args, sizeof(aapcs64_params_t));
356532ed618SSoby Mathew }
357532ed618SSoby Mathew 
358532ed618SSoby Mathew /*******************************************************************************
359*2bbad1d1SZelalem Aweke  * Context management library initialization routine. This library is used by
360*2bbad1d1SZelalem Aweke  * runtime services to share pointers to 'cpu_context' structures for secure
361*2bbad1d1SZelalem Aweke  * non-secure and realm states. Management of the structures and their associated
362*2bbad1d1SZelalem Aweke  * memory is not done by the context management library e.g. the PSCI service
363*2bbad1d1SZelalem Aweke  * manages the cpu context used for entry from and exit to the non-secure state.
364*2bbad1d1SZelalem Aweke  * The Secure payload dispatcher service manages the context(s) corresponding to
365*2bbad1d1SZelalem Aweke  * the secure state. It also uses this library to get access to the non-secure
366*2bbad1d1SZelalem Aweke  * state cpu context pointers.
367*2bbad1d1SZelalem Aweke  * Lastly, this library provides the API to make SP_EL3 point to the cpu context
368*2bbad1d1SZelalem Aweke  * which will be used for programming an entry into a lower EL. The same context
369*2bbad1d1SZelalem Aweke  * will be used to save state upon exception entry from that EL.
370*2bbad1d1SZelalem Aweke  ******************************************************************************/
371*2bbad1d1SZelalem Aweke void __init cm_init(void)
372*2bbad1d1SZelalem Aweke {
373*2bbad1d1SZelalem Aweke 	/*
374*2bbad1d1SZelalem Aweke 	 * The context management library has only global data to intialize, but
375*2bbad1d1SZelalem Aweke 	 * that will be done when the BSS is zeroed out.
376*2bbad1d1SZelalem Aweke 	 */
377*2bbad1d1SZelalem Aweke }
378*2bbad1d1SZelalem Aweke 
379*2bbad1d1SZelalem Aweke /*******************************************************************************
380*2bbad1d1SZelalem Aweke  * This is the high-level function used to initialize the cpu_context 'ctx' for
381*2bbad1d1SZelalem Aweke  * first use. It performs initializations that are common to all security states
382*2bbad1d1SZelalem Aweke  * and initializations specific to the security state specified in 'ep'
383*2bbad1d1SZelalem Aweke  ******************************************************************************/
384*2bbad1d1SZelalem Aweke void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
385*2bbad1d1SZelalem Aweke {
386*2bbad1d1SZelalem Aweke 	unsigned int security_state;
387*2bbad1d1SZelalem Aweke 
388*2bbad1d1SZelalem Aweke 	assert(ctx != NULL);
389*2bbad1d1SZelalem Aweke 
390*2bbad1d1SZelalem Aweke 	/*
391*2bbad1d1SZelalem Aweke 	 * Perform initializations that are common
392*2bbad1d1SZelalem Aweke 	 * to all security states
393*2bbad1d1SZelalem Aweke 	 */
394*2bbad1d1SZelalem Aweke 	setup_context_common(ctx, ep);
395*2bbad1d1SZelalem Aweke 
396*2bbad1d1SZelalem Aweke 	security_state = GET_SECURITY_STATE(ep->h.attr);
397*2bbad1d1SZelalem Aweke 
398*2bbad1d1SZelalem Aweke 	/* Perform security state specific initializations */
399*2bbad1d1SZelalem Aweke 	switch (security_state) {
400*2bbad1d1SZelalem Aweke 	case SECURE:
401*2bbad1d1SZelalem Aweke 		setup_secure_context(ctx, ep);
402*2bbad1d1SZelalem Aweke 		break;
403*2bbad1d1SZelalem Aweke #if ENABLE_RME
404*2bbad1d1SZelalem Aweke 	case REALM:
405*2bbad1d1SZelalem Aweke 		setup_realm_context(ctx, ep);
406*2bbad1d1SZelalem Aweke 		break;
407*2bbad1d1SZelalem Aweke #endif
408*2bbad1d1SZelalem Aweke 	case NON_SECURE:
409*2bbad1d1SZelalem Aweke 		setup_ns_context(ctx, ep);
410*2bbad1d1SZelalem Aweke 		break;
411*2bbad1d1SZelalem Aweke 	default:
412*2bbad1d1SZelalem Aweke 		ERROR("Invalid security state\n");
413*2bbad1d1SZelalem Aweke 		panic();
414*2bbad1d1SZelalem Aweke 		break;
415*2bbad1d1SZelalem Aweke 	}
416*2bbad1d1SZelalem Aweke }
417*2bbad1d1SZelalem Aweke 
418*2bbad1d1SZelalem Aweke /*******************************************************************************
4190fd0f222SDimitris Papastamos  * Enable architecture extensions on first entry to Non-secure world.
4200fd0f222SDimitris Papastamos  * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
4210fd0f222SDimitris Papastamos  * it is zero.
4220fd0f222SDimitris Papastamos  ******************************************************************************/
423dc78e62dSjohpow01 static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
4240fd0f222SDimitris Papastamos {
4250fd0f222SDimitris Papastamos #if IMAGE_BL31
426281a08ccSDimitris Papastamos #if ENABLE_SPE_FOR_LOWER_ELS
427281a08ccSDimitris Papastamos 	spe_enable(el2_unused);
428281a08ccSDimitris Papastamos #endif
429380559c1SDimitris Papastamos 
430380559c1SDimitris Papastamos #if ENABLE_AMU
43168ac5ed0SArunachalam Ganapathy 	amu_enable(el2_unused, ctx);
43268ac5ed0SArunachalam Ganapathy #endif
43368ac5ed0SArunachalam Ganapathy 
434dc78e62dSjohpow01 #if ENABLE_SME_FOR_NS
435dc78e62dSjohpow01 	/* Enable SME, SVE, and FPU/SIMD for non-secure world. */
436dc78e62dSjohpow01 	sme_enable(ctx);
437dc78e62dSjohpow01 #elif ENABLE_SVE_FOR_NS
438dc78e62dSjohpow01 	/* Enable SVE and FPU/SIMD for non-secure world. */
43968ac5ed0SArunachalam Ganapathy 	sve_enable(ctx);
440380559c1SDimitris Papastamos #endif
4411a853370SDavid Cunado 
4425f835918SJeenu Viswambharan #if ENABLE_MPAM_FOR_LOWER_ELS
4435f835918SJeenu Viswambharan 	mpam_enable(el2_unused);
4445f835918SJeenu Viswambharan #endif
445813524eaSManish V Badarkhe 
446813524eaSManish V Badarkhe #if ENABLE_TRBE_FOR_NS
447813524eaSManish V Badarkhe 	trbe_enable();
448813524eaSManish V Badarkhe #endif /* ENABLE_TRBE_FOR_NS */
449813524eaSManish V Badarkhe 
450d4582d30SManish V Badarkhe #if ENABLE_SYS_REG_TRACE_FOR_NS
451d4582d30SManish V Badarkhe 	sys_reg_trace_enable(ctx);
452d4582d30SManish V Badarkhe #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
453d4582d30SManish V Badarkhe 
4548fcd3d96SManish V Badarkhe #if ENABLE_TRF_FOR_NS
4558fcd3d96SManish V Badarkhe 	trf_enable();
4568fcd3d96SManish V Badarkhe #endif /* ENABLE_TRF_FOR_NS */
4570fd0f222SDimitris Papastamos #endif
4580fd0f222SDimitris Papastamos }
4590fd0f222SDimitris Papastamos 
4600fd0f222SDimitris Papastamos /*******************************************************************************
46168ac5ed0SArunachalam Ganapathy  * Enable architecture extensions on first entry to Secure world.
46268ac5ed0SArunachalam Ganapathy  ******************************************************************************/
463dc78e62dSjohpow01 static void manage_extensions_secure(cpu_context_t *ctx)
46468ac5ed0SArunachalam Ganapathy {
46568ac5ed0SArunachalam Ganapathy #if IMAGE_BL31
466dc78e62dSjohpow01  #if ENABLE_SME_FOR_NS
467dc78e62dSjohpow01   #if ENABLE_SME_FOR_SWD
468dc78e62dSjohpow01 	/*
469dc78e62dSjohpow01 	 * Enable SME, SVE, FPU/SIMD in secure context, secure manager must
470dc78e62dSjohpow01 	 * ensure SME, SVE, and FPU/SIMD context properly managed.
471dc78e62dSjohpow01 	 */
472dc78e62dSjohpow01 	sme_enable(ctx);
473dc78e62dSjohpow01   #else /* ENABLE_SME_FOR_SWD */
474dc78e62dSjohpow01 	/*
475dc78e62dSjohpow01 	 * Disable SME, SVE, FPU/SIMD in secure context so non-secure world can
476dc78e62dSjohpow01 	 * safely use the associated registers.
477dc78e62dSjohpow01 	 */
478dc78e62dSjohpow01 	sme_disable(ctx);
479dc78e62dSjohpow01   #endif /* ENABLE_SME_FOR_SWD */
480dc78e62dSjohpow01  #elif ENABLE_SVE_FOR_NS
48168ac5ed0SArunachalam Ganapathy   #if ENABLE_SVE_FOR_SWD
482dc78e62dSjohpow01 	/*
483dc78e62dSjohpow01 	 * Enable SVE and FPU in secure context, secure manager must ensure that
484dc78e62dSjohpow01 	 * the SVE and FPU register contexts are properly managed.
485dc78e62dSjohpow01 	 */
48668ac5ed0SArunachalam Ganapathy 	sve_enable(ctx);
487dc78e62dSjohpow01  #else /* ENABLE_SVE_FOR_SWD */
488dc78e62dSjohpow01 	/*
489dc78e62dSjohpow01 	 * Disable SVE and FPU in secure context so non-secure world can safely
490dc78e62dSjohpow01 	 * use them.
491dc78e62dSjohpow01 	 */
492dc78e62dSjohpow01 	sve_disable(ctx);
493dc78e62dSjohpow01   #endif /* ENABLE_SVE_FOR_SWD */
494dc78e62dSjohpow01  #endif /* ENABLE_SVE_FOR_NS */
495dc78e62dSjohpow01 #endif /* IMAGE_BL31 */
49668ac5ed0SArunachalam Ganapathy }
49768ac5ed0SArunachalam Ganapathy 
49868ac5ed0SArunachalam Ganapathy /*******************************************************************************
499532ed618SSoby Mathew  * The following function initializes the cpu_context for a CPU specified by
500532ed618SSoby Mathew  * its `cpu_idx` for first use, and sets the initial entrypoint state as
501532ed618SSoby Mathew  * specified by the entry_point_info structure.
502532ed618SSoby Mathew  ******************************************************************************/
503532ed618SSoby Mathew void cm_init_context_by_index(unsigned int cpu_idx,
504532ed618SSoby Mathew 			      const entry_point_info_t *ep)
505532ed618SSoby Mathew {
506532ed618SSoby Mathew 	cpu_context_t *ctx;
507532ed618SSoby Mathew 	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
5081634cae8SAntonio Nino Diaz 	cm_setup_context(ctx, ep);
509532ed618SSoby Mathew }
510532ed618SSoby Mathew 
511532ed618SSoby Mathew /*******************************************************************************
512532ed618SSoby Mathew  * The following function initializes the cpu_context for the current CPU
513532ed618SSoby Mathew  * for first use, and sets the initial entrypoint state as specified by the
514532ed618SSoby Mathew  * entry_point_info structure.
515532ed618SSoby Mathew  ******************************************************************************/
516532ed618SSoby Mathew void cm_init_my_context(const entry_point_info_t *ep)
517532ed618SSoby Mathew {
518532ed618SSoby Mathew 	cpu_context_t *ctx;
519532ed618SSoby Mathew 	ctx = cm_get_context(GET_SECURITY_STATE(ep->h.attr));
5201634cae8SAntonio Nino Diaz 	cm_setup_context(ctx, ep);
521532ed618SSoby Mathew }
522532ed618SSoby Mathew 
523532ed618SSoby Mathew /*******************************************************************************
524c5ea4f8aSZelalem Aweke  * Prepare the CPU system registers for first entry into realm, secure, or
525c5ea4f8aSZelalem Aweke  * normal world.
526532ed618SSoby Mathew  *
527532ed618SSoby Mathew  * If execution is requested to EL2 or hyp mode, SCTLR_EL2 is initialized
528532ed618SSoby Mathew  * If execution is requested to non-secure EL1 or svc mode, and the CPU supports
529532ed618SSoby Mathew  * EL2 then EL2 is disabled by configuring all necessary EL2 registers.
530532ed618SSoby Mathew  * For all entries, the EL1 registers are initialized from the cpu_context
531532ed618SSoby Mathew  ******************************************************************************/
532532ed618SSoby Mathew void cm_prepare_el3_exit(uint32_t security_state)
533532ed618SSoby Mathew {
534f1be00daSLouis Mayencourt 	u_register_t sctlr_elx, scr_el3, mdcr_el2;
535532ed618SSoby Mathew 	cpu_context_t *ctx = cm_get_context(security_state);
53640daecc1SAntonio Nino Diaz 	bool el2_unused = false;
537a0fee747SAntonio Nino Diaz 	uint64_t hcr_el2 = 0U;
538532ed618SSoby Mathew 
539a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
540532ed618SSoby Mathew 
541532ed618SSoby Mathew 	if (security_state == NON_SECURE) {
542f1be00daSLouis Mayencourt 		scr_el3 = read_ctx_reg(get_el3state_ctx(ctx),
543a0fee747SAntonio Nino Diaz 						 CTX_SCR_EL3);
544a0fee747SAntonio Nino Diaz 		if ((scr_el3 & SCR_HCE_BIT) != 0U) {
545532ed618SSoby Mathew 			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
5462825946eSMax Shvetsov 			sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
547532ed618SSoby Mathew 							   CTX_SCTLR_EL1);
5482e09d4f8SKen Kuang 			sctlr_elx &= SCTLR_EE_BIT;
549532ed618SSoby Mathew 			sctlr_elx |= SCTLR_EL2_RES1;
5505f5d1ed7SLouis Mayencourt #if ERRATA_A75_764081
5515f5d1ed7SLouis Mayencourt 			/*
5525f5d1ed7SLouis Mayencourt 			 * If workaround of errata 764081 for Cortex-A75 is used
5535f5d1ed7SLouis Mayencourt 			 * then set SCTLR_EL2.IESB to enable Implicit Error
5545f5d1ed7SLouis Mayencourt 			 * Synchronization Barrier.
5555f5d1ed7SLouis Mayencourt 			 */
5565f5d1ed7SLouis Mayencourt 			sctlr_elx |= SCTLR_IESB_BIT;
5575f5d1ed7SLouis Mayencourt #endif
558532ed618SSoby Mathew 			write_sctlr_el2(sctlr_elx);
559a0fee747SAntonio Nino Diaz 		} else if (el_implemented(2) != EL_IMPL_NONE) {
56040daecc1SAntonio Nino Diaz 			el2_unused = true;
5610fd0f222SDimitris Papastamos 
56218f2efd6SDavid Cunado 			/*
56318f2efd6SDavid Cunado 			 * EL2 present but unused, need to disable safely.
56418f2efd6SDavid Cunado 			 * SCTLR_EL2 can be ignored in this case.
56518f2efd6SDavid Cunado 			 *
5663ff4aaacSJeenu Viswambharan 			 * Set EL2 register width appropriately: Set HCR_EL2
5673ff4aaacSJeenu Viswambharan 			 * field to match SCR_EL3.RW.
56818f2efd6SDavid Cunado 			 */
569a0fee747SAntonio Nino Diaz 			if ((scr_el3 & SCR_RW_BIT) != 0U)
5703ff4aaacSJeenu Viswambharan 				hcr_el2 |= HCR_RW_BIT;
5713ff4aaacSJeenu Viswambharan 
5723ff4aaacSJeenu Viswambharan 			/*
5733ff4aaacSJeenu Viswambharan 			 * For Armv8.3 pointer authentication feature, disable
5743ff4aaacSJeenu Viswambharan 			 * traps to EL2 when accessing key registers or using
5753ff4aaacSJeenu Viswambharan 			 * pointer authentication instructions from lower ELs.
5763ff4aaacSJeenu Viswambharan 			 */
5773ff4aaacSJeenu Viswambharan 			hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
5783ff4aaacSJeenu Viswambharan 
5793ff4aaacSJeenu Viswambharan 			write_hcr_el2(hcr_el2);
580532ed618SSoby Mathew 
58118f2efd6SDavid Cunado 			/*
58218f2efd6SDavid Cunado 			 * Initialise CPTR_EL2 setting all fields rather than
58318f2efd6SDavid Cunado 			 * relying on the hw. All fields have architecturally
58418f2efd6SDavid Cunado 			 * UNKNOWN reset values.
58518f2efd6SDavid Cunado 			 *
58618f2efd6SDavid Cunado 			 * CPTR_EL2.TCPAC: Set to zero so that Non-secure EL1
58718f2efd6SDavid Cunado 			 *  accesses to the CPACR_EL1 or CPACR from both
58818f2efd6SDavid Cunado 			 *  Execution states do not trap to EL2.
58918f2efd6SDavid Cunado 			 *
59018f2efd6SDavid Cunado 			 * CPTR_EL2.TTA: Set to zero so that Non-secure System
59118f2efd6SDavid Cunado 			 *  register accesses to the trace registers from both
59218f2efd6SDavid Cunado 			 *  Execution states do not trap to EL2.
593d4582d30SManish V Badarkhe 			 *  If PE trace unit System registers are not implemented
594d4582d30SManish V Badarkhe 			 *  then this bit is reserved, and must be set to zero.
59518f2efd6SDavid Cunado 			 *
59618f2efd6SDavid Cunado 			 * CPTR_EL2.TFP: Set to zero so that Non-secure accesses
59718f2efd6SDavid Cunado 			 *  to SIMD and floating-point functionality from both
59818f2efd6SDavid Cunado 			 *  Execution states do not trap to EL2.
59918f2efd6SDavid Cunado 			 */
60018f2efd6SDavid Cunado 			write_cptr_el2(CPTR_EL2_RESET_VAL &
60118f2efd6SDavid Cunado 					~(CPTR_EL2_TCPAC_BIT | CPTR_EL2_TTA_BIT
60218f2efd6SDavid Cunado 					| CPTR_EL2_TFP_BIT));
603532ed618SSoby Mathew 
60418f2efd6SDavid Cunado 			/*
6058aabea33SPaul Beesley 			 * Initialise CNTHCTL_EL2. All fields are
60618f2efd6SDavid Cunado 			 * architecturally UNKNOWN on reset and are set to zero
60718f2efd6SDavid Cunado 			 * except for field(s) listed below.
60818f2efd6SDavid Cunado 			 *
609c5ea4f8aSZelalem Aweke 			 * CNTHCTL_EL2.EL1PTEN: Set to one to disable traps to
61018f2efd6SDavid Cunado 			 *  Hyp mode of Non-secure EL0 and EL1 accesses to the
61118f2efd6SDavid Cunado 			 *  physical timer registers.
61218f2efd6SDavid Cunado 			 *
61318f2efd6SDavid Cunado 			 * CNTHCTL_EL2.EL1PCTEN: Set to one to disable traps to
61418f2efd6SDavid Cunado 			 *  Hyp mode of  Non-secure EL0 and EL1 accesses to the
61518f2efd6SDavid Cunado 			 *  physical counter registers.
61618f2efd6SDavid Cunado 			 */
61718f2efd6SDavid Cunado 			write_cnthctl_el2(CNTHCTL_RESET_VAL |
61818f2efd6SDavid Cunado 						EL1PCEN_BIT | EL1PCTEN_BIT);
619532ed618SSoby Mathew 
62018f2efd6SDavid Cunado 			/*
62118f2efd6SDavid Cunado 			 * Initialise CNTVOFF_EL2 to zero as it resets to an
62218f2efd6SDavid Cunado 			 * architecturally UNKNOWN value.
62318f2efd6SDavid Cunado 			 */
624532ed618SSoby Mathew 			write_cntvoff_el2(0);
625532ed618SSoby Mathew 
62618f2efd6SDavid Cunado 			/*
62718f2efd6SDavid Cunado 			 * Set VPIDR_EL2 and VMPIDR_EL2 to match MIDR_EL1 and
62818f2efd6SDavid Cunado 			 * MPIDR_EL1 respectively.
62918f2efd6SDavid Cunado 			 */
630532ed618SSoby Mathew 			write_vpidr_el2(read_midr_el1());
631532ed618SSoby Mathew 			write_vmpidr_el2(read_mpidr_el1());
632532ed618SSoby Mathew 
633532ed618SSoby Mathew 			/*
63418f2efd6SDavid Cunado 			 * Initialise VTTBR_EL2. All fields are architecturally
63518f2efd6SDavid Cunado 			 * UNKNOWN on reset.
63618f2efd6SDavid Cunado 			 *
63718f2efd6SDavid Cunado 			 * VTTBR_EL2.VMID: Set to zero. Even though EL1&0 stage
63818f2efd6SDavid Cunado 			 *  2 address translation is disabled, cache maintenance
63918f2efd6SDavid Cunado 			 *  operations depend on the VMID.
64018f2efd6SDavid Cunado 			 *
64118f2efd6SDavid Cunado 			 * VTTBR_EL2.BADDR: Set to zero as EL1&0 stage 2 address
64218f2efd6SDavid Cunado 			 *  translation is disabled.
643532ed618SSoby Mathew 			 */
64418f2efd6SDavid Cunado 			write_vttbr_el2(VTTBR_RESET_VAL &
64518f2efd6SDavid Cunado 				~((VTTBR_VMID_MASK << VTTBR_VMID_SHIFT)
64618f2efd6SDavid Cunado 				| (VTTBR_BADDR_MASK << VTTBR_BADDR_SHIFT)));
64718f2efd6SDavid Cunado 
648495f3d3cSDavid Cunado 			/*
64918f2efd6SDavid Cunado 			 * Initialise MDCR_EL2, setting all fields rather than
65018f2efd6SDavid Cunado 			 * relying on hw. Some fields are architecturally
65118f2efd6SDavid Cunado 			 * UNKNOWN on reset.
65218f2efd6SDavid Cunado 			 *
653e290a8fcSAlexei Fedorov 			 * MDCR_EL2.HLP: Set to one so that event counter
654e290a8fcSAlexei Fedorov 			 *  overflow, that is recorded in PMOVSCLR_EL0[0-30],
655e290a8fcSAlexei Fedorov 			 *  occurs on the increment that changes
656e290a8fcSAlexei Fedorov 			 *  PMEVCNTR<n>_EL0[63] from 1 to 0, when ARMv8.5-PMU is
657e290a8fcSAlexei Fedorov 			 *  implemented. This bit is RES0 in versions of the
658e290a8fcSAlexei Fedorov 			 *  architecture earlier than ARMv8.5, setting it to 1
659e290a8fcSAlexei Fedorov 			 *  doesn't have any effect on them.
660e290a8fcSAlexei Fedorov 			 *
661e290a8fcSAlexei Fedorov 			 * MDCR_EL2.TTRF: Set to zero so that access to Trace
662e290a8fcSAlexei Fedorov 			 *  Filter Control register TRFCR_EL1 at EL1 is not
663e290a8fcSAlexei Fedorov 			 *  trapped to EL2. This bit is RES0 in versions of
664e290a8fcSAlexei Fedorov 			 *  the architecture earlier than ARMv8.4.
665e290a8fcSAlexei Fedorov 			 *
666e290a8fcSAlexei Fedorov 			 * MDCR_EL2.HPMD: Set to one so that event counting is
667e290a8fcSAlexei Fedorov 			 *  prohibited at EL2. This bit is RES0 in versions of
668e290a8fcSAlexei Fedorov 			 *  the architecture earlier than ARMv8.1, setting it
669e290a8fcSAlexei Fedorov 			 *  to 1 doesn't have any effect on them.
670e290a8fcSAlexei Fedorov 			 *
671e290a8fcSAlexei Fedorov 			 * MDCR_EL2.TPMS: Set to zero so that accesses to
672e290a8fcSAlexei Fedorov 			 *  Statistical Profiling control registers from EL1
673e290a8fcSAlexei Fedorov 			 *  do not trap to EL2. This bit is RES0 when SPE is
674e290a8fcSAlexei Fedorov 			 *  not implemented.
675e290a8fcSAlexei Fedorov 			 *
67618f2efd6SDavid Cunado 			 * MDCR_EL2.TDRA: Set to zero so that Non-secure EL0 and
67718f2efd6SDavid Cunado 			 *  EL1 System register accesses to the Debug ROM
67818f2efd6SDavid Cunado 			 *  registers are not trapped to EL2.
67918f2efd6SDavid Cunado 			 *
68018f2efd6SDavid Cunado 			 * MDCR_EL2.TDOSA: Set to zero so that Non-secure EL1
68118f2efd6SDavid Cunado 			 *  System register accesses to the powerdown debug
68218f2efd6SDavid Cunado 			 *  registers are not trapped to EL2.
68318f2efd6SDavid Cunado 			 *
68418f2efd6SDavid Cunado 			 * MDCR_EL2.TDA: Set to zero so that System register
68518f2efd6SDavid Cunado 			 *  accesses to the debug registers do not trap to EL2.
68618f2efd6SDavid Cunado 			 *
68718f2efd6SDavid Cunado 			 * MDCR_EL2.TDE: Set to zero so that debug exceptions
68818f2efd6SDavid Cunado 			 *  are not routed to EL2.
68918f2efd6SDavid Cunado 			 *
69018f2efd6SDavid Cunado 			 * MDCR_EL2.HPME: Set to zero to disable EL2 Performance
69118f2efd6SDavid Cunado 			 *  Monitors.
69218f2efd6SDavid Cunado 			 *
69318f2efd6SDavid Cunado 			 * MDCR_EL2.TPM: Set to zero so that Non-secure EL0 and
69418f2efd6SDavid Cunado 			 *  EL1 accesses to all Performance Monitors registers
69518f2efd6SDavid Cunado 			 *  are not trapped to EL2.
69618f2efd6SDavid Cunado 			 *
69718f2efd6SDavid Cunado 			 * MDCR_EL2.TPMCR: Set to zero so that Non-secure EL0
69818f2efd6SDavid Cunado 			 *  and EL1 accesses to the PMCR_EL0 or PMCR are not
69918f2efd6SDavid Cunado 			 *  trapped to EL2.
70018f2efd6SDavid Cunado 			 *
70118f2efd6SDavid Cunado 			 * MDCR_EL2.HPMN: Set to value of PMCR_EL0.N which is the
70218f2efd6SDavid Cunado 			 *  architecturally-defined reset value.
70340ff9074SManish V Badarkhe 			 *
70440ff9074SManish V Badarkhe 			 * MDCR_EL2.E2TB: Set to zero so that the trace Buffer
70540ff9074SManish V Badarkhe 			 *  owning exception level is NS-EL1 and, tracing is
70640ff9074SManish V Badarkhe 			 *  prohibited at NS-EL2. These bits are RES0 when
70740ff9074SManish V Badarkhe 			 *  FEAT_TRBE is not implemented.
708495f3d3cSDavid Cunado 			 */
709e290a8fcSAlexei Fedorov 			mdcr_el2 = ((MDCR_EL2_RESET_VAL | MDCR_EL2_HLP |
710e290a8fcSAlexei Fedorov 				     MDCR_EL2_HPMD) |
71118f2efd6SDavid Cunado 				   ((read_pmcr_el0() & PMCR_EL0_N_BITS)
71218f2efd6SDavid Cunado 				   >> PMCR_EL0_N_SHIFT)) &
713e290a8fcSAlexei Fedorov 				   ~(MDCR_EL2_TTRF | MDCR_EL2_TPMS |
714e290a8fcSAlexei Fedorov 				     MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT |
715e290a8fcSAlexei Fedorov 				     MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT |
716e290a8fcSAlexei Fedorov 				     MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT |
71740ff9074SManish V Badarkhe 				     MDCR_EL2_TPMCR_BIT |
71840ff9074SManish V Badarkhe 				     MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
719d832aee9Sdp-arm 
720d832aee9Sdp-arm 			write_mdcr_el2(mdcr_el2);
721d832aee9Sdp-arm 
722939f66d6SDavid Cunado 			/*
72318f2efd6SDavid Cunado 			 * Initialise HSTR_EL2. All fields are architecturally
72418f2efd6SDavid Cunado 			 * UNKNOWN on reset.
72518f2efd6SDavid Cunado 			 *
72618f2efd6SDavid Cunado 			 * HSTR_EL2.T<n>: Set all these fields to zero so that
72718f2efd6SDavid Cunado 			 *  Non-secure EL0 or EL1 accesses to System registers
72818f2efd6SDavid Cunado 			 *  do not trap to EL2.
729939f66d6SDavid Cunado 			 */
73018f2efd6SDavid Cunado 			write_hstr_el2(HSTR_EL2_RESET_VAL & ~(HSTR_EL2_T_MASK));
731939f66d6SDavid Cunado 			/*
73218f2efd6SDavid Cunado 			 * Initialise CNTHP_CTL_EL2. All fields are
73318f2efd6SDavid Cunado 			 * architecturally UNKNOWN on reset.
73418f2efd6SDavid Cunado 			 *
73518f2efd6SDavid Cunado 			 * CNTHP_CTL_EL2:ENABLE: Set to zero to disable the EL2
73618f2efd6SDavid Cunado 			 *  physical timer and prevent timer interrupts.
737939f66d6SDavid Cunado 			 */
73818f2efd6SDavid Cunado 			write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
73918f2efd6SDavid Cunado 						~(CNTHP_CTL_ENABLE_BIT));
740532ed618SSoby Mathew 		}
741dc78e62dSjohpow01 		manage_extensions_nonsecure(el2_unused, ctx);
742532ed618SSoby Mathew 	}
743532ed618SSoby Mathew 
74417b4c0ddSDimitris Papastamos 	cm_el1_sysregs_context_restore(security_state);
74517b4c0ddSDimitris Papastamos 	cm_set_next_eret_context(security_state);
746532ed618SSoby Mathew }
747532ed618SSoby Mathew 
74828f39f02SMax Shvetsov #if CTX_INCLUDE_EL2_REGS
74928f39f02SMax Shvetsov /*******************************************************************************
75028f39f02SMax Shvetsov  * Save EL2 sysreg context
75128f39f02SMax Shvetsov  ******************************************************************************/
75228f39f02SMax Shvetsov void cm_el2_sysregs_context_save(uint32_t security_state)
75328f39f02SMax Shvetsov {
75428f39f02SMax Shvetsov 	u_register_t scr_el3 = read_scr();
75528f39f02SMax Shvetsov 
75628f39f02SMax Shvetsov 	/*
757c5ea4f8aSZelalem Aweke 	 * Always save the non-secure and realm EL2 context, only save the
75828f39f02SMax Shvetsov 	 * S-EL2 context if S-EL2 is enabled.
75928f39f02SMax Shvetsov 	 */
760c5ea4f8aSZelalem Aweke 	if ((security_state != SECURE) ||
7616b704da3SRuari Phipps 	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
76228f39f02SMax Shvetsov 		cpu_context_t *ctx;
76328f39f02SMax Shvetsov 
76428f39f02SMax Shvetsov 		ctx = cm_get_context(security_state);
76528f39f02SMax Shvetsov 		assert(ctx != NULL);
76628f39f02SMax Shvetsov 
7672825946eSMax Shvetsov 		el2_sysregs_context_save(get_el2_sysregs_ctx(ctx));
76828f39f02SMax Shvetsov 	}
76928f39f02SMax Shvetsov }
77028f39f02SMax Shvetsov 
77128f39f02SMax Shvetsov /*******************************************************************************
77228f39f02SMax Shvetsov  * Restore EL2 sysreg context
77328f39f02SMax Shvetsov  ******************************************************************************/
77428f39f02SMax Shvetsov void cm_el2_sysregs_context_restore(uint32_t security_state)
77528f39f02SMax Shvetsov {
77628f39f02SMax Shvetsov 	u_register_t scr_el3 = read_scr();
77728f39f02SMax Shvetsov 
77828f39f02SMax Shvetsov 	/*
779c5ea4f8aSZelalem Aweke 	 * Always restore the non-secure and realm EL2 context, only restore the
78028f39f02SMax Shvetsov 	 * S-EL2 context if S-EL2 is enabled.
78128f39f02SMax Shvetsov 	 */
782c5ea4f8aSZelalem Aweke 	if ((security_state != SECURE) ||
7836b704da3SRuari Phipps 	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
78428f39f02SMax Shvetsov 		cpu_context_t *ctx;
78528f39f02SMax Shvetsov 
78628f39f02SMax Shvetsov 		ctx = cm_get_context(security_state);
78728f39f02SMax Shvetsov 		assert(ctx != NULL);
78828f39f02SMax Shvetsov 
7892825946eSMax Shvetsov 		el2_sysregs_context_restore(get_el2_sysregs_ctx(ctx));
79028f39f02SMax Shvetsov 	}
79128f39f02SMax Shvetsov }
79228f39f02SMax Shvetsov #endif /* CTX_INCLUDE_EL2_REGS */
79328f39f02SMax Shvetsov 
794532ed618SSoby Mathew /*******************************************************************************
795532ed618SSoby Mathew  * The next four functions are used by runtime services to save and restore
796532ed618SSoby Mathew  * EL1 context on the 'cpu_context' structure for the specified security
797532ed618SSoby Mathew  * state.
798532ed618SSoby Mathew  ******************************************************************************/
799532ed618SSoby Mathew void cm_el1_sysregs_context_save(uint32_t security_state)
800532ed618SSoby Mathew {
801532ed618SSoby Mathew 	cpu_context_t *ctx;
802532ed618SSoby Mathew 
803532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
804a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
805532ed618SSoby Mathew 
8062825946eSMax Shvetsov 	el1_sysregs_context_save(get_el1_sysregs_ctx(ctx));
80717b4c0ddSDimitris Papastamos 
80817b4c0ddSDimitris Papastamos #if IMAGE_BL31
80917b4c0ddSDimitris Papastamos 	if (security_state == SECURE)
81017b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_exited_secure_world);
81117b4c0ddSDimitris Papastamos 	else
81217b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_exited_normal_world);
81317b4c0ddSDimitris Papastamos #endif
814532ed618SSoby Mathew }
815532ed618SSoby Mathew 
816532ed618SSoby Mathew void cm_el1_sysregs_context_restore(uint32_t security_state)
817532ed618SSoby Mathew {
818532ed618SSoby Mathew 	cpu_context_t *ctx;
819532ed618SSoby Mathew 
820532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
821a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
822532ed618SSoby Mathew 
8232825946eSMax Shvetsov 	el1_sysregs_context_restore(get_el1_sysregs_ctx(ctx));
82417b4c0ddSDimitris Papastamos 
82517b4c0ddSDimitris Papastamos #if IMAGE_BL31
82617b4c0ddSDimitris Papastamos 	if (security_state == SECURE)
82717b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_entering_secure_world);
82817b4c0ddSDimitris Papastamos 	else
82917b4c0ddSDimitris Papastamos 		PUBLISH_EVENT(cm_entering_normal_world);
83017b4c0ddSDimitris Papastamos #endif
831532ed618SSoby Mathew }
832532ed618SSoby Mathew 
833532ed618SSoby Mathew /*******************************************************************************
834532ed618SSoby Mathew  * This function populates ELR_EL3 member of 'cpu_context' pertaining to the
835532ed618SSoby Mathew  * given security state with the given entrypoint
836532ed618SSoby Mathew  ******************************************************************************/
837532ed618SSoby Mathew void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint)
838532ed618SSoby Mathew {
839532ed618SSoby Mathew 	cpu_context_t *ctx;
840532ed618SSoby Mathew 	el3_state_t *state;
841532ed618SSoby Mathew 
842532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
843a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
844532ed618SSoby Mathew 
845532ed618SSoby Mathew 	/* Populate EL3 state so that ERET jumps to the correct entry */
846532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
847532ed618SSoby Mathew 	write_ctx_reg(state, CTX_ELR_EL3, entrypoint);
848532ed618SSoby Mathew }
849532ed618SSoby Mathew 
850532ed618SSoby Mathew /*******************************************************************************
851532ed618SSoby Mathew  * This function populates ELR_EL3 and SPSR_EL3 members of 'cpu_context'
852532ed618SSoby Mathew  * pertaining to the given security state
853532ed618SSoby Mathew  ******************************************************************************/
854532ed618SSoby Mathew void cm_set_elr_spsr_el3(uint32_t security_state,
855532ed618SSoby Mathew 			uintptr_t entrypoint, uint32_t spsr)
856532ed618SSoby Mathew {
857532ed618SSoby Mathew 	cpu_context_t *ctx;
858532ed618SSoby Mathew 	el3_state_t *state;
859532ed618SSoby Mathew 
860532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
861a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
862532ed618SSoby Mathew 
863532ed618SSoby Mathew 	/* Populate EL3 state so that ERET jumps to the correct entry */
864532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
865532ed618SSoby Mathew 	write_ctx_reg(state, CTX_ELR_EL3, entrypoint);
866532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SPSR_EL3, spsr);
867532ed618SSoby Mathew }
868532ed618SSoby Mathew 
869532ed618SSoby Mathew /*******************************************************************************
870532ed618SSoby Mathew  * This function updates a single bit in the SCR_EL3 member of the 'cpu_context'
871532ed618SSoby Mathew  * pertaining to the given security state using the value and bit position
872532ed618SSoby Mathew  * specified in the parameters. It preserves all other bits.
873532ed618SSoby Mathew  ******************************************************************************/
874532ed618SSoby Mathew void cm_write_scr_el3_bit(uint32_t security_state,
875532ed618SSoby Mathew 			  uint32_t bit_pos,
876532ed618SSoby Mathew 			  uint32_t value)
877532ed618SSoby Mathew {
878532ed618SSoby Mathew 	cpu_context_t *ctx;
879532ed618SSoby Mathew 	el3_state_t *state;
880f1be00daSLouis Mayencourt 	u_register_t scr_el3;
881532ed618SSoby Mathew 
882532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
883a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
884532ed618SSoby Mathew 
885532ed618SSoby Mathew 	/* Ensure that the bit position is a valid one */
886d7b5f408SJimmy Brisson 	assert(((1UL << bit_pos) & SCR_VALID_BIT_MASK) != 0U);
887532ed618SSoby Mathew 
888532ed618SSoby Mathew 	/* Ensure that the 'value' is only a bit wide */
889a0fee747SAntonio Nino Diaz 	assert(value <= 1U);
890532ed618SSoby Mathew 
891532ed618SSoby Mathew 	/*
892532ed618SSoby Mathew 	 * Get the SCR_EL3 value from the cpu context, clear the desired bit
893532ed618SSoby Mathew 	 * and set it to its new value.
894532ed618SSoby Mathew 	 */
895532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
896f1be00daSLouis Mayencourt 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
897d7b5f408SJimmy Brisson 	scr_el3 &= ~(1UL << bit_pos);
898f1be00daSLouis Mayencourt 	scr_el3 |= (u_register_t)value << bit_pos;
899532ed618SSoby Mathew 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
900532ed618SSoby Mathew }
901532ed618SSoby Mathew 
902532ed618SSoby Mathew /*******************************************************************************
903532ed618SSoby Mathew  * This function retrieves SCR_EL3 member of 'cpu_context' pertaining to the
904532ed618SSoby Mathew  * given security state.
905532ed618SSoby Mathew  ******************************************************************************/
906f1be00daSLouis Mayencourt u_register_t cm_get_scr_el3(uint32_t security_state)
907532ed618SSoby Mathew {
908532ed618SSoby Mathew 	cpu_context_t *ctx;
909532ed618SSoby Mathew 	el3_state_t *state;
910532ed618SSoby Mathew 
911532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
912a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
913532ed618SSoby Mathew 
914532ed618SSoby Mathew 	/* Populate EL3 state so that ERET jumps to the correct entry */
915532ed618SSoby Mathew 	state = get_el3state_ctx(ctx);
916f1be00daSLouis Mayencourt 	return read_ctx_reg(state, CTX_SCR_EL3);
917532ed618SSoby Mathew }
918532ed618SSoby Mathew 
919532ed618SSoby Mathew /*******************************************************************************
920532ed618SSoby Mathew  * This function is used to program the context that's used for exception
921532ed618SSoby Mathew  * return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for
922532ed618SSoby Mathew  * the required security state
923532ed618SSoby Mathew  ******************************************************************************/
924532ed618SSoby Mathew void cm_set_next_eret_context(uint32_t security_state)
925532ed618SSoby Mathew {
926532ed618SSoby Mathew 	cpu_context_t *ctx;
927532ed618SSoby Mathew 
928532ed618SSoby Mathew 	ctx = cm_get_context(security_state);
929a0fee747SAntonio Nino Diaz 	assert(ctx != NULL);
930532ed618SSoby Mathew 
931532ed618SSoby Mathew 	cm_set_next_context(ctx);
932532ed618SSoby Mathew }
933