1532ed618SSoby Mathew /* 232f0d3c6SDouglas Raillard * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. 3532ed618SSoby Mathew * 4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5532ed618SSoby Mathew */ 6532ed618SSoby Mathew 7532ed618SSoby Mathew #include <arch.h> 8532ed618SSoby Mathew #include <arch_helpers.h> 9532ed618SSoby Mathew #include <assert.h> 10532ed618SSoby Mathew #include <bl_common.h> 11532ed618SSoby Mathew #include <context.h> 12532ed618SSoby Mathew #include <context_mgmt.h> 13532ed618SSoby Mathew #include <interrupt_mgmt.h> 14532ed618SSoby Mathew #include <platform.h> 15532ed618SSoby Mathew #include <platform_def.h> 16532ed618SSoby Mathew #include <smcc_helpers.h> 17532ed618SSoby Mathew #include <string.h> 1832f0d3c6SDouglas Raillard #include <utils.h> 19532ed618SSoby Mathew 20532ed618SSoby Mathew 21532ed618SSoby Mathew /******************************************************************************* 22532ed618SSoby Mathew * Context management library initialisation routine. This library is used by 23532ed618SSoby Mathew * runtime services to share pointers to 'cpu_context' structures for the secure 24532ed618SSoby Mathew * and non-secure states. Management of the structures and their associated 25532ed618SSoby Mathew * memory is not done by the context management library e.g. the PSCI service 26532ed618SSoby Mathew * manages the cpu context used for entry from and exit to the non-secure state. 27532ed618SSoby Mathew * The Secure payload dispatcher service manages the context(s) corresponding to 28532ed618SSoby Mathew * the secure state. It also uses this library to get access to the non-secure 29532ed618SSoby Mathew * state cpu context pointers. 30532ed618SSoby Mathew * Lastly, this library provides the api to make SP_EL3 point to the cpu context 31532ed618SSoby Mathew * which will used for programming an entry into a lower EL. The same context 32532ed618SSoby Mathew * will used to save state upon exception entry from that EL. 33532ed618SSoby Mathew ******************************************************************************/ 34532ed618SSoby Mathew void cm_init(void) 35532ed618SSoby Mathew { 36532ed618SSoby Mathew /* 37532ed618SSoby Mathew * The context management library has only global data to intialize, but 38532ed618SSoby Mathew * that will be done when the BSS is zeroed out 39532ed618SSoby Mathew */ 40532ed618SSoby Mathew } 41532ed618SSoby Mathew 42532ed618SSoby Mathew /******************************************************************************* 43532ed618SSoby Mathew * The following function initializes the cpu_context 'ctx' for 44532ed618SSoby Mathew * first use, and sets the initial entrypoint state as specified by the 45532ed618SSoby Mathew * entry_point_info structure. 46532ed618SSoby Mathew * 47532ed618SSoby Mathew * The security state to initialize is determined by the SECURE attribute 48532ed618SSoby Mathew * of the entry_point_info. The function returns a pointer to the initialized 49532ed618SSoby Mathew * context and sets this as the next context to return to. 50532ed618SSoby Mathew * 51532ed618SSoby Mathew * The EE and ST attributes are used to configure the endianess and secure 52532ed618SSoby Mathew * timer availability for the new execution context. 53532ed618SSoby Mathew * 54532ed618SSoby Mathew * To prepare the register state for entry call cm_prepare_el3_exit() and 55532ed618SSoby Mathew * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to 56532ed618SSoby Mathew * cm_e1_sysreg_context_restore(). 57532ed618SSoby Mathew ******************************************************************************/ 58532ed618SSoby Mathew static void cm_init_context_common(cpu_context_t *ctx, const entry_point_info_t *ep) 59532ed618SSoby Mathew { 60532ed618SSoby Mathew unsigned int security_state; 61532ed618SSoby Mathew uint32_t scr_el3; 62532ed618SSoby Mathew el3_state_t *state; 63532ed618SSoby Mathew gp_regs_t *gp_regs; 64532ed618SSoby Mathew unsigned long sctlr_elx; 65532ed618SSoby Mathew 66532ed618SSoby Mathew assert(ctx); 67532ed618SSoby Mathew 68532ed618SSoby Mathew security_state = GET_SECURITY_STATE(ep->h.attr); 69532ed618SSoby Mathew 70532ed618SSoby Mathew /* Clear any residual register values from the context */ 7132f0d3c6SDouglas Raillard zeromem(ctx, sizeof(*ctx)); 72532ed618SSoby Mathew 73532ed618SSoby Mathew /* 74532ed618SSoby Mathew * Base the context SCR on the current value, adjust for entry point 75532ed618SSoby Mathew * specific requirements and set trap bits from the IMF 76532ed618SSoby Mathew * TODO: provide the base/global SCR bits using another mechanism? 77532ed618SSoby Mathew */ 78532ed618SSoby Mathew scr_el3 = read_scr(); 79532ed618SSoby Mathew scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT | 80532ed618SSoby Mathew SCR_ST_BIT | SCR_HCE_BIT); 81532ed618SSoby Mathew 82532ed618SSoby Mathew if (security_state != SECURE) 83532ed618SSoby Mathew scr_el3 |= SCR_NS_BIT; 84532ed618SSoby Mathew 85532ed618SSoby Mathew if (GET_RW(ep->spsr) == MODE_RW_64) 86532ed618SSoby Mathew scr_el3 |= SCR_RW_BIT; 87532ed618SSoby Mathew 88532ed618SSoby Mathew if (EP_GET_ST(ep->h.attr)) 89532ed618SSoby Mathew scr_el3 |= SCR_ST_BIT; 90532ed618SSoby Mathew 91532ed618SSoby Mathew #ifndef HANDLE_EA_EL3_FIRST 92532ed618SSoby Mathew /* Explicitly stop to trap aborts from lower exception levels. */ 93532ed618SSoby Mathew scr_el3 &= ~SCR_EA_BIT; 94532ed618SSoby Mathew #endif 95532ed618SSoby Mathew 963d8256b2SMasahiro Yamada #ifdef IMAGE_BL31 97532ed618SSoby Mathew /* 98532ed618SSoby Mathew * IRQ/FIQ bits only need setting if interrupt routing 99532ed618SSoby Mathew * model has been set up for BL31. 100532ed618SSoby Mathew */ 101532ed618SSoby Mathew scr_el3 |= get_scr_el3_from_routing_model(security_state); 102532ed618SSoby Mathew #endif 103532ed618SSoby Mathew 104532ed618SSoby Mathew /* 105532ed618SSoby Mathew * Set up SCTLR_ELx for the target exception level: 106532ed618SSoby Mathew * EE bit is taken from the entrypoint attributes 107532ed618SSoby Mathew * M, C and I bits must be zero (as required by PSCI specification) 108532ed618SSoby Mathew * 109532ed618SSoby Mathew * The target exception level is based on the spsr mode requested. 110532ed618SSoby Mathew * If execution is requested to EL2 or hyp mode, HVC is enabled 111532ed618SSoby Mathew * via SCR_EL3.HCE. 112532ed618SSoby Mathew * 113532ed618SSoby Mathew * Always compute the SCTLR_EL1 value and save in the cpu_context 114532ed618SSoby Mathew * - the EL2 registers are set up by cm_preapre_ns_entry() as they 115532ed618SSoby Mathew * are not part of the stored cpu_context 116532ed618SSoby Mathew * 117532ed618SSoby Mathew * TODO: In debug builds the spsr should be validated and checked 118532ed618SSoby Mathew * against the CPU support, security state, endianess and pc 119532ed618SSoby Mathew */ 120532ed618SSoby Mathew sctlr_elx = EP_GET_EE(ep->h.attr) ? SCTLR_EE_BIT : 0; 121532ed618SSoby Mathew if (GET_RW(ep->spsr) == MODE_RW_64) 122532ed618SSoby Mathew sctlr_elx |= SCTLR_EL1_RES1; 123b7b0787dSSoby Mathew else { 124532ed618SSoby Mathew sctlr_elx |= SCTLR_AARCH32_EL1_RES1; 125b7b0787dSSoby Mathew /* 126b7b0787dSSoby Mathew * If lower non-secure EL is AArch32, enable the CP15BEN, nTWI 127b7b0787dSSoby Mathew * & nTWI bits. This aligns with SCTLR initialization on 128b7b0787dSSoby Mathew * systems with an AArch32 EL3, where these bits 129b7b0787dSSoby Mathew * architecturally reset to 1. 130b7b0787dSSoby Mathew */ 131b7b0787dSSoby Mathew if (security_state != SECURE) 132b7b0787dSSoby Mathew sctlr_elx |= SCTLR_CP15BEN_BIT | SCTLR_NTWI_BIT 133b7b0787dSSoby Mathew | SCTLR_NTWE_BIT; 134b7b0787dSSoby Mathew } 135b7b0787dSSoby Mathew 136532ed618SSoby Mathew write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx); 137532ed618SSoby Mathew 138532ed618SSoby Mathew if ((GET_RW(ep->spsr) == MODE_RW_64 139532ed618SSoby Mathew && GET_EL(ep->spsr) == MODE_EL2) 140532ed618SSoby Mathew || (GET_RW(ep->spsr) != MODE_RW_64 141532ed618SSoby Mathew && GET_M32(ep->spsr) == MODE32_hyp)) { 142532ed618SSoby Mathew scr_el3 |= SCR_HCE_BIT; 143532ed618SSoby Mathew } 144532ed618SSoby Mathew 145532ed618SSoby Mathew /* Populate EL3 state so that we've the right context before doing ERET */ 146532ed618SSoby Mathew state = get_el3state_ctx(ctx); 147532ed618SSoby Mathew write_ctx_reg(state, CTX_SCR_EL3, scr_el3); 148532ed618SSoby Mathew write_ctx_reg(state, CTX_ELR_EL3, ep->pc); 149532ed618SSoby Mathew write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr); 150532ed618SSoby Mathew 151532ed618SSoby Mathew /* 152532ed618SSoby Mathew * Store the X0-X7 value from the entrypoint into the context 153532ed618SSoby Mathew * Use memcpy as we are in control of the layout of the structures 154532ed618SSoby Mathew */ 155532ed618SSoby Mathew gp_regs = get_gpregs_ctx(ctx); 156532ed618SSoby Mathew memcpy(gp_regs, (void *)&ep->args, sizeof(aapcs64_params_t)); 157532ed618SSoby Mathew } 158532ed618SSoby Mathew 159532ed618SSoby Mathew /******************************************************************************* 160532ed618SSoby Mathew * The following function initializes the cpu_context for a CPU specified by 161532ed618SSoby Mathew * its `cpu_idx` for first use, and sets the initial entrypoint state as 162532ed618SSoby Mathew * specified by the entry_point_info structure. 163532ed618SSoby Mathew ******************************************************************************/ 164532ed618SSoby Mathew void cm_init_context_by_index(unsigned int cpu_idx, 165532ed618SSoby Mathew const entry_point_info_t *ep) 166532ed618SSoby Mathew { 167532ed618SSoby Mathew cpu_context_t *ctx; 168532ed618SSoby Mathew ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr)); 169532ed618SSoby Mathew cm_init_context_common(ctx, ep); 170532ed618SSoby Mathew } 171532ed618SSoby Mathew 172532ed618SSoby Mathew /******************************************************************************* 173532ed618SSoby Mathew * The following function initializes the cpu_context for the current CPU 174532ed618SSoby Mathew * for first use, and sets the initial entrypoint state as specified by the 175532ed618SSoby Mathew * entry_point_info structure. 176532ed618SSoby Mathew ******************************************************************************/ 177532ed618SSoby Mathew void cm_init_my_context(const entry_point_info_t *ep) 178532ed618SSoby Mathew { 179532ed618SSoby Mathew cpu_context_t *ctx; 180532ed618SSoby Mathew ctx = cm_get_context(GET_SECURITY_STATE(ep->h.attr)); 181532ed618SSoby Mathew cm_init_context_common(ctx, ep); 182532ed618SSoby Mathew } 183532ed618SSoby Mathew 184532ed618SSoby Mathew /******************************************************************************* 185532ed618SSoby Mathew * Prepare the CPU system registers for first entry into secure or normal world 186532ed618SSoby Mathew * 187532ed618SSoby Mathew * If execution is requested to EL2 or hyp mode, SCTLR_EL2 is initialized 188532ed618SSoby Mathew * If execution is requested to non-secure EL1 or svc mode, and the CPU supports 189532ed618SSoby Mathew * EL2 then EL2 is disabled by configuring all necessary EL2 registers. 190532ed618SSoby Mathew * For all entries, the EL1 registers are initialized from the cpu_context 191532ed618SSoby Mathew ******************************************************************************/ 192532ed618SSoby Mathew void cm_prepare_el3_exit(uint32_t security_state) 193532ed618SSoby Mathew { 194532ed618SSoby Mathew uint32_t sctlr_elx, scr_el3, cptr_el2; 195532ed618SSoby Mathew cpu_context_t *ctx = cm_get_context(security_state); 196532ed618SSoby Mathew 197532ed618SSoby Mathew assert(ctx); 198532ed618SSoby Mathew 199532ed618SSoby Mathew if (security_state == NON_SECURE) { 200532ed618SSoby Mathew scr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3); 201532ed618SSoby Mathew if (scr_el3 & SCR_HCE_BIT) { 202532ed618SSoby Mathew /* Use SCTLR_EL1.EE value to initialise sctlr_el2 */ 203532ed618SSoby Mathew sctlr_elx = read_ctx_reg(get_sysregs_ctx(ctx), 204532ed618SSoby Mathew CTX_SCTLR_EL1); 205532ed618SSoby Mathew sctlr_elx &= ~SCTLR_EE_BIT; 206532ed618SSoby Mathew sctlr_elx |= SCTLR_EL2_RES1; 207532ed618SSoby Mathew write_sctlr_el2(sctlr_elx); 208532ed618SSoby Mathew } else if (read_id_aa64pfr0_el1() & 209532ed618SSoby Mathew (ID_AA64PFR0_ELX_MASK << ID_AA64PFR0_EL2_SHIFT)) { 210532ed618SSoby Mathew /* EL2 present but unused, need to disable safely */ 211532ed618SSoby Mathew 212532ed618SSoby Mathew /* HCR_EL2 = 0, except RW bit set to match SCR_EL3 */ 213532ed618SSoby Mathew write_hcr_el2((scr_el3 & SCR_RW_BIT) ? HCR_RW_BIT : 0); 214532ed618SSoby Mathew 215532ed618SSoby Mathew /* SCTLR_EL2 : can be ignored when bypassing */ 216532ed618SSoby Mathew 217532ed618SSoby Mathew /* CPTR_EL2 : disable all traps TCPAC, TTA, TFP */ 218532ed618SSoby Mathew cptr_el2 = read_cptr_el2(); 219532ed618SSoby Mathew cptr_el2 &= ~(TCPAC_BIT | TTA_BIT | TFP_BIT); 220532ed618SSoby Mathew write_cptr_el2(cptr_el2); 221532ed618SSoby Mathew 222532ed618SSoby Mathew /* Enable EL1 access to timer */ 223532ed618SSoby Mathew write_cnthctl_el2(EL1PCEN_BIT | EL1PCTEN_BIT); 224532ed618SSoby Mathew 225532ed618SSoby Mathew /* Reset CNTVOFF_EL2 */ 226532ed618SSoby Mathew write_cntvoff_el2(0); 227532ed618SSoby Mathew 228532ed618SSoby Mathew /* Set VPIDR, VMPIDR to match MIDR, MPIDR */ 229532ed618SSoby Mathew write_vpidr_el2(read_midr_el1()); 230532ed618SSoby Mathew write_vmpidr_el2(read_mpidr_el1()); 231532ed618SSoby Mathew 232532ed618SSoby Mathew /* 233532ed618SSoby Mathew * Reset VTTBR_EL2. 234532ed618SSoby Mathew * Needed because cache maintenance operations depend on 235532ed618SSoby Mathew * the VMID even when non-secure EL1&0 stage 2 address 236532ed618SSoby Mathew * translation are disabled. 237532ed618SSoby Mathew */ 238532ed618SSoby Mathew write_vttbr_el2(0); 239495f3d3cSDavid Cunado /* 240495f3d3cSDavid Cunado * Avoid unexpected debug traps in case where MDCR_EL2 241495f3d3cSDavid Cunado * is not completely reset by the hardware - set 242495f3d3cSDavid Cunado * MDCR_EL2.HPMN to PMCR_EL0.N and zero the remaining 243495f3d3cSDavid Cunado * bits. 244495f3d3cSDavid Cunado * MDCR_EL2.HPMN and PMCR_EL0.N fields are the same size 245495f3d3cSDavid Cunado * (5 bits) and HPMN is at offset zero within MDCR_EL2. 246495f3d3cSDavid Cunado */ 247495f3d3cSDavid Cunado write_mdcr_el2((read_pmcr_el0() & PMCR_EL0_N_BITS) 248495f3d3cSDavid Cunado >> PMCR_EL0_N_SHIFT); 249939f66d6SDavid Cunado /* 250939f66d6SDavid Cunado * Avoid unexpected traps of non-secure access to 251939f66d6SDavid Cunado * certain system registers at EL1 or lower where 252939f66d6SDavid Cunado * HSTR_EL2 is not completely reset to zero by the 253939f66d6SDavid Cunado * hardware - zero the entire register. 254939f66d6SDavid Cunado */ 255939f66d6SDavid Cunado write_hstr_el2(0); 256939f66d6SDavid Cunado /* 257939f66d6SDavid Cunado * Reset CNTHP_CTL_EL2 to disable the EL2 physical timer 258939f66d6SDavid Cunado * and therefore prevent timer interrupts. 259939f66d6SDavid Cunado */ 260939f66d6SDavid Cunado write_cnthp_ctl_el2(0); 261532ed618SSoby Mathew } 262532ed618SSoby Mathew } 263532ed618SSoby Mathew 264532ed618SSoby Mathew el1_sysregs_context_restore(get_sysregs_ctx(ctx)); 265532ed618SSoby Mathew 266532ed618SSoby Mathew cm_set_next_context(ctx); 267532ed618SSoby Mathew } 268532ed618SSoby Mathew 269532ed618SSoby Mathew /******************************************************************************* 270532ed618SSoby Mathew * The next four functions are used by runtime services to save and restore 271532ed618SSoby Mathew * EL1 context on the 'cpu_context' structure for the specified security 272532ed618SSoby Mathew * state. 273532ed618SSoby Mathew ******************************************************************************/ 274532ed618SSoby Mathew void cm_el1_sysregs_context_save(uint32_t security_state) 275532ed618SSoby Mathew { 276532ed618SSoby Mathew cpu_context_t *ctx; 277532ed618SSoby Mathew 278532ed618SSoby Mathew ctx = cm_get_context(security_state); 279532ed618SSoby Mathew assert(ctx); 280532ed618SSoby Mathew 281532ed618SSoby Mathew el1_sysregs_context_save(get_sysregs_ctx(ctx)); 282532ed618SSoby Mathew } 283532ed618SSoby Mathew 284532ed618SSoby Mathew void cm_el1_sysregs_context_restore(uint32_t security_state) 285532ed618SSoby Mathew { 286532ed618SSoby Mathew cpu_context_t *ctx; 287532ed618SSoby Mathew 288532ed618SSoby Mathew ctx = cm_get_context(security_state); 289532ed618SSoby Mathew assert(ctx); 290532ed618SSoby Mathew 291532ed618SSoby Mathew el1_sysregs_context_restore(get_sysregs_ctx(ctx)); 292532ed618SSoby Mathew } 293532ed618SSoby Mathew 294532ed618SSoby Mathew /******************************************************************************* 295532ed618SSoby Mathew * This function populates ELR_EL3 member of 'cpu_context' pertaining to the 296532ed618SSoby Mathew * given security state with the given entrypoint 297532ed618SSoby Mathew ******************************************************************************/ 298532ed618SSoby Mathew void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint) 299532ed618SSoby Mathew { 300532ed618SSoby Mathew cpu_context_t *ctx; 301532ed618SSoby Mathew el3_state_t *state; 302532ed618SSoby Mathew 303532ed618SSoby Mathew ctx = cm_get_context(security_state); 304532ed618SSoby Mathew assert(ctx); 305532ed618SSoby Mathew 306532ed618SSoby Mathew /* Populate EL3 state so that ERET jumps to the correct entry */ 307532ed618SSoby Mathew state = get_el3state_ctx(ctx); 308532ed618SSoby Mathew write_ctx_reg(state, CTX_ELR_EL3, entrypoint); 309532ed618SSoby Mathew } 310532ed618SSoby Mathew 311532ed618SSoby Mathew /******************************************************************************* 312532ed618SSoby Mathew * This function populates ELR_EL3 and SPSR_EL3 members of 'cpu_context' 313532ed618SSoby Mathew * pertaining to the given security state 314532ed618SSoby Mathew ******************************************************************************/ 315532ed618SSoby Mathew void cm_set_elr_spsr_el3(uint32_t security_state, 316532ed618SSoby Mathew uintptr_t entrypoint, uint32_t spsr) 317532ed618SSoby Mathew { 318532ed618SSoby Mathew cpu_context_t *ctx; 319532ed618SSoby Mathew el3_state_t *state; 320532ed618SSoby Mathew 321532ed618SSoby Mathew ctx = cm_get_context(security_state); 322532ed618SSoby Mathew assert(ctx); 323532ed618SSoby Mathew 324532ed618SSoby Mathew /* Populate EL3 state so that ERET jumps to the correct entry */ 325532ed618SSoby Mathew state = get_el3state_ctx(ctx); 326532ed618SSoby Mathew write_ctx_reg(state, CTX_ELR_EL3, entrypoint); 327532ed618SSoby Mathew write_ctx_reg(state, CTX_SPSR_EL3, spsr); 328532ed618SSoby Mathew } 329532ed618SSoby Mathew 330532ed618SSoby Mathew /******************************************************************************* 331532ed618SSoby Mathew * This function updates a single bit in the SCR_EL3 member of the 'cpu_context' 332532ed618SSoby Mathew * pertaining to the given security state using the value and bit position 333532ed618SSoby Mathew * specified in the parameters. It preserves all other bits. 334532ed618SSoby Mathew ******************************************************************************/ 335532ed618SSoby Mathew void cm_write_scr_el3_bit(uint32_t security_state, 336532ed618SSoby Mathew uint32_t bit_pos, 337532ed618SSoby Mathew uint32_t value) 338532ed618SSoby Mathew { 339532ed618SSoby Mathew cpu_context_t *ctx; 340532ed618SSoby Mathew el3_state_t *state; 341532ed618SSoby Mathew uint32_t scr_el3; 342532ed618SSoby Mathew 343532ed618SSoby Mathew ctx = cm_get_context(security_state); 344532ed618SSoby Mathew assert(ctx); 345532ed618SSoby Mathew 346532ed618SSoby Mathew /* Ensure that the bit position is a valid one */ 347532ed618SSoby Mathew assert((1 << bit_pos) & SCR_VALID_BIT_MASK); 348532ed618SSoby Mathew 349532ed618SSoby Mathew /* Ensure that the 'value' is only a bit wide */ 350532ed618SSoby Mathew assert(value <= 1); 351532ed618SSoby Mathew 352532ed618SSoby Mathew /* 353532ed618SSoby Mathew * Get the SCR_EL3 value from the cpu context, clear the desired bit 354532ed618SSoby Mathew * and set it to its new value. 355532ed618SSoby Mathew */ 356532ed618SSoby Mathew state = get_el3state_ctx(ctx); 357532ed618SSoby Mathew scr_el3 = read_ctx_reg(state, CTX_SCR_EL3); 358532ed618SSoby Mathew scr_el3 &= ~(1 << bit_pos); 359532ed618SSoby Mathew scr_el3 |= value << bit_pos; 360532ed618SSoby Mathew write_ctx_reg(state, CTX_SCR_EL3, scr_el3); 361532ed618SSoby Mathew } 362532ed618SSoby Mathew 363532ed618SSoby Mathew /******************************************************************************* 364532ed618SSoby Mathew * This function retrieves SCR_EL3 member of 'cpu_context' pertaining to the 365532ed618SSoby Mathew * given security state. 366532ed618SSoby Mathew ******************************************************************************/ 367532ed618SSoby Mathew uint32_t cm_get_scr_el3(uint32_t security_state) 368532ed618SSoby Mathew { 369532ed618SSoby Mathew cpu_context_t *ctx; 370532ed618SSoby Mathew el3_state_t *state; 371532ed618SSoby Mathew 372532ed618SSoby Mathew ctx = cm_get_context(security_state); 373532ed618SSoby Mathew assert(ctx); 374532ed618SSoby Mathew 375532ed618SSoby Mathew /* Populate EL3 state so that ERET jumps to the correct entry */ 376532ed618SSoby Mathew state = get_el3state_ctx(ctx); 377532ed618SSoby Mathew return read_ctx_reg(state, CTX_SCR_EL3); 378532ed618SSoby Mathew } 379532ed618SSoby Mathew 380532ed618SSoby Mathew /******************************************************************************* 381532ed618SSoby Mathew * This function is used to program the context that's used for exception 382532ed618SSoby Mathew * return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for 383532ed618SSoby Mathew * the required security state 384532ed618SSoby Mathew ******************************************************************************/ 385532ed618SSoby Mathew void cm_set_next_eret_context(uint32_t security_state) 386532ed618SSoby Mathew { 387532ed618SSoby Mathew cpu_context_t *ctx; 388532ed618SSoby Mathew 389532ed618SSoby Mathew ctx = cm_get_context(security_state); 390532ed618SSoby Mathew assert(ctx); 391532ed618SSoby Mathew 392532ed618SSoby Mathew cm_set_next_context(ctx); 393532ed618SSoby Mathew } 394