1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <stdbool.h> 9*91f16700Schasinglulu #include <string.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <platform_def.h> 12*91f16700Schasinglulu 13*91f16700Schasinglulu #include <arch.h> 14*91f16700Schasinglulu #include <arch_features.h> 15*91f16700Schasinglulu #include <arch_helpers.h> 16*91f16700Schasinglulu #include <common/bl_common.h> 17*91f16700Schasinglulu #include <context.h> 18*91f16700Schasinglulu #include <lib/el3_runtime/context_mgmt.h> 19*91f16700Schasinglulu #include <lib/extensions/amu.h> 20*91f16700Schasinglulu #include <lib/extensions/pmuv3.h> 21*91f16700Schasinglulu #include <lib/extensions/sys_reg_trace.h> 22*91f16700Schasinglulu #include <lib/extensions/trf.h> 23*91f16700Schasinglulu #include <lib/utils.h> 24*91f16700Schasinglulu 25*91f16700Schasinglulu /******************************************************************************* 26*91f16700Schasinglulu * Context management library initialisation routine. This library is used by 27*91f16700Schasinglulu * runtime services to share pointers to 'cpu_context' structures for the secure 28*91f16700Schasinglulu * and non-secure states. Management of the structures and their associated 29*91f16700Schasinglulu * memory is not done by the context management library e.g. the PSCI service 30*91f16700Schasinglulu * manages the cpu context used for entry from and exit to the non-secure state. 31*91f16700Schasinglulu * The Secure payload manages the context(s) corresponding to the secure state. 32*91f16700Schasinglulu * It also uses this library to get access to the non-secure 33*91f16700Schasinglulu * state cpu context pointers. 34*91f16700Schasinglulu ******************************************************************************/ 35*91f16700Schasinglulu void cm_init(void) 36*91f16700Schasinglulu { 37*91f16700Schasinglulu /* 38*91f16700Schasinglulu * The context management library has only global data to initialize, but 39*91f16700Schasinglulu * that will be done when the BSS is zeroed out 40*91f16700Schasinglulu */ 41*91f16700Schasinglulu } 42*91f16700Schasinglulu 43*91f16700Schasinglulu /******************************************************************************* 44*91f16700Schasinglulu * The following function initializes the cpu_context 'ctx' for 45*91f16700Schasinglulu * first use, and sets the initial entrypoint state as specified by the 46*91f16700Schasinglulu * entry_point_info structure. 47*91f16700Schasinglulu * 48*91f16700Schasinglulu * The security state to initialize is determined by the SECURE attribute 49*91f16700Schasinglulu * of the entry_point_info. 50*91f16700Schasinglulu * 51*91f16700Schasinglulu * The EE and ST attributes are used to configure the endianness and secure 52*91f16700Schasinglulu * timer availability for the new execution context. 53*91f16700Schasinglulu * 54*91f16700Schasinglulu * To prepare the register state for entry call cm_prepare_el3_exit() and 55*91f16700Schasinglulu * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to 56*91f16700Schasinglulu * cm_el1_sysregs_context_restore(). 57*91f16700Schasinglulu ******************************************************************************/ 58*91f16700Schasinglulu void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) 59*91f16700Schasinglulu { 60*91f16700Schasinglulu unsigned int security_state; 61*91f16700Schasinglulu uint32_t scr, sctlr; 62*91f16700Schasinglulu regs_t *reg_ctx; 63*91f16700Schasinglulu 64*91f16700Schasinglulu assert(ctx != NULL); 65*91f16700Schasinglulu 66*91f16700Schasinglulu security_state = GET_SECURITY_STATE(ep->h.attr); 67*91f16700Schasinglulu 68*91f16700Schasinglulu /* Clear any residual register values from the context */ 69*91f16700Schasinglulu zeromem(ctx, sizeof(*ctx)); 70*91f16700Schasinglulu 71*91f16700Schasinglulu reg_ctx = get_regs_ctx(ctx); 72*91f16700Schasinglulu 73*91f16700Schasinglulu /* 74*91f16700Schasinglulu * Base the context SCR on the current value, adjust for entry point 75*91f16700Schasinglulu * specific requirements 76*91f16700Schasinglulu */ 77*91f16700Schasinglulu scr = read_scr(); 78*91f16700Schasinglulu scr &= ~(SCR_NS_BIT | SCR_HCE_BIT); 79*91f16700Schasinglulu 80*91f16700Schasinglulu if (security_state != SECURE) 81*91f16700Schasinglulu scr |= SCR_NS_BIT; 82*91f16700Schasinglulu 83*91f16700Schasinglulu if (security_state != SECURE) { 84*91f16700Schasinglulu /* 85*91f16700Schasinglulu * Set up SCTLR for the Non-secure context. 86*91f16700Schasinglulu * 87*91f16700Schasinglulu * SCTLR.EE: Endianness is taken from the entrypoint attributes. 88*91f16700Schasinglulu * 89*91f16700Schasinglulu * SCTLR.M, SCTLR.C and SCTLR.I: These fields must be zero (as 90*91f16700Schasinglulu * required by PSCI specification) 91*91f16700Schasinglulu * 92*91f16700Schasinglulu * Set remaining SCTLR fields to their architecturally defined 93*91f16700Schasinglulu * values. Some fields reset to an IMPLEMENTATION DEFINED value: 94*91f16700Schasinglulu * 95*91f16700Schasinglulu * SCTLR.TE: Set to zero so that exceptions to an Exception 96*91f16700Schasinglulu * Level executing at PL1 are taken to A32 state. 97*91f16700Schasinglulu * 98*91f16700Schasinglulu * SCTLR.V: Set to zero to select the normal exception vectors 99*91f16700Schasinglulu * with base address held in VBAR. 100*91f16700Schasinglulu */ 101*91f16700Schasinglulu assert(((ep->spsr >> SPSR_E_SHIFT) & SPSR_E_MASK) == 102*91f16700Schasinglulu (EP_GET_EE(ep->h.attr) >> EP_EE_SHIFT)); 103*91f16700Schasinglulu 104*91f16700Schasinglulu sctlr = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0U; 105*91f16700Schasinglulu sctlr |= (SCTLR_RESET_VAL & ~(SCTLR_TE_BIT | SCTLR_V_BIT)); 106*91f16700Schasinglulu write_ctx_reg(reg_ctx, CTX_NS_SCTLR, sctlr); 107*91f16700Schasinglulu } 108*91f16700Schasinglulu 109*91f16700Schasinglulu /* 110*91f16700Schasinglulu * The target exception level is based on the spsr mode requested. If 111*91f16700Schasinglulu * execution is requested to hyp mode, HVC is enabled via SCR.HCE. 112*91f16700Schasinglulu */ 113*91f16700Schasinglulu if (GET_M32(ep->spsr) == MODE32_hyp) 114*91f16700Schasinglulu scr |= SCR_HCE_BIT; 115*91f16700Schasinglulu 116*91f16700Schasinglulu /* 117*91f16700Schasinglulu * Store the initialised values for SCTLR and SCR in the cpu_context. 118*91f16700Schasinglulu * The Hyp mode registers are not part of the saved context and are 119*91f16700Schasinglulu * set-up in cm_prepare_el3_exit(). 120*91f16700Schasinglulu */ 121*91f16700Schasinglulu write_ctx_reg(reg_ctx, CTX_SCR, scr); 122*91f16700Schasinglulu write_ctx_reg(reg_ctx, CTX_LR, ep->pc); 123*91f16700Schasinglulu write_ctx_reg(reg_ctx, CTX_SPSR, ep->spsr); 124*91f16700Schasinglulu 125*91f16700Schasinglulu /* 126*91f16700Schasinglulu * Store the r0-r3 value from the entrypoint into the context 127*91f16700Schasinglulu * Use memcpy as we are in control of the layout of the structures 128*91f16700Schasinglulu */ 129*91f16700Schasinglulu memcpy((void *)reg_ctx, (void *)&ep->args, sizeof(aapcs32_params_t)); 130*91f16700Schasinglulu } 131*91f16700Schasinglulu 132*91f16700Schasinglulu /******************************************************************************* 133*91f16700Schasinglulu * Enable architecture extensions on first entry to Non-secure world. 134*91f16700Schasinglulu * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise 135*91f16700Schasinglulu * it is zero. 136*91f16700Schasinglulu ******************************************************************************/ 137*91f16700Schasinglulu static void enable_extensions_nonsecure(bool el2_unused) 138*91f16700Schasinglulu { 139*91f16700Schasinglulu #if IMAGE_BL32 140*91f16700Schasinglulu if (is_feat_amu_supported()) { 141*91f16700Schasinglulu amu_enable(el2_unused); 142*91f16700Schasinglulu } 143*91f16700Schasinglulu 144*91f16700Schasinglulu if (is_feat_sys_reg_trace_supported()) { 145*91f16700Schasinglulu sys_reg_trace_init_el3(); 146*91f16700Schasinglulu } 147*91f16700Schasinglulu 148*91f16700Schasinglulu if (is_feat_trf_supported()) { 149*91f16700Schasinglulu trf_init_el3(); 150*91f16700Schasinglulu } 151*91f16700Schasinglulu 152*91f16700Schasinglulu /* 153*91f16700Schasinglulu * Also applies to PMU < v3. The PMU is only disabled for EL3 and Secure 154*91f16700Schasinglulu * state execution. This does not affect lower NS ELs. 155*91f16700Schasinglulu */ 156*91f16700Schasinglulu pmuv3_init_el3(); 157*91f16700Schasinglulu #endif /* IMAGE_BL32 */ 158*91f16700Schasinglulu } 159*91f16700Schasinglulu 160*91f16700Schasinglulu /******************************************************************************* 161*91f16700Schasinglulu * The following function initializes the cpu_context for a CPU specified by 162*91f16700Schasinglulu * its `cpu_idx` for first use, and sets the initial entrypoint state as 163*91f16700Schasinglulu * specified by the entry_point_info structure. 164*91f16700Schasinglulu ******************************************************************************/ 165*91f16700Schasinglulu void cm_init_context_by_index(unsigned int cpu_idx, 166*91f16700Schasinglulu const entry_point_info_t *ep) 167*91f16700Schasinglulu { 168*91f16700Schasinglulu cpu_context_t *ctx; 169*91f16700Schasinglulu ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr)); 170*91f16700Schasinglulu cm_setup_context(ctx, ep); 171*91f16700Schasinglulu } 172*91f16700Schasinglulu 173*91f16700Schasinglulu /******************************************************************************* 174*91f16700Schasinglulu * The following function initializes the cpu_context for the current CPU 175*91f16700Schasinglulu * for first use, and sets the initial entrypoint state as specified by the 176*91f16700Schasinglulu * entry_point_info structure. 177*91f16700Schasinglulu ******************************************************************************/ 178*91f16700Schasinglulu void cm_init_my_context(const entry_point_info_t *ep) 179*91f16700Schasinglulu { 180*91f16700Schasinglulu cpu_context_t *ctx; 181*91f16700Schasinglulu ctx = cm_get_context(GET_SECURITY_STATE(ep->h.attr)); 182*91f16700Schasinglulu cm_setup_context(ctx, ep); 183*91f16700Schasinglulu } 184*91f16700Schasinglulu 185*91f16700Schasinglulu /******************************************************************************* 186*91f16700Schasinglulu * Prepare the CPU system registers for first entry into secure or normal world 187*91f16700Schasinglulu * 188*91f16700Schasinglulu * If execution is requested to hyp mode, HSCTLR is initialized 189*91f16700Schasinglulu * If execution is requested to non-secure PL1, and the CPU supports 190*91f16700Schasinglulu * HYP mode then HYP mode is disabled by configuring all necessary HYP mode 191*91f16700Schasinglulu * registers. 192*91f16700Schasinglulu ******************************************************************************/ 193*91f16700Schasinglulu void cm_prepare_el3_exit(uint32_t security_state) 194*91f16700Schasinglulu { 195*91f16700Schasinglulu uint32_t hsctlr, scr; 196*91f16700Schasinglulu cpu_context_t *ctx = cm_get_context(security_state); 197*91f16700Schasinglulu bool el2_unused = false; 198*91f16700Schasinglulu 199*91f16700Schasinglulu assert(ctx != NULL); 200*91f16700Schasinglulu 201*91f16700Schasinglulu if (security_state == NON_SECURE) { 202*91f16700Schasinglulu scr = read_ctx_reg(get_regs_ctx(ctx), CTX_SCR); 203*91f16700Schasinglulu if ((scr & SCR_HCE_BIT) != 0U) { 204*91f16700Schasinglulu /* Use SCTLR value to initialize HSCTLR */ 205*91f16700Schasinglulu hsctlr = read_ctx_reg(get_regs_ctx(ctx), 206*91f16700Schasinglulu CTX_NS_SCTLR); 207*91f16700Schasinglulu hsctlr |= HSCTLR_RES1; 208*91f16700Schasinglulu /* Temporarily set the NS bit to access HSCTLR */ 209*91f16700Schasinglulu write_scr(read_scr() | SCR_NS_BIT); 210*91f16700Schasinglulu /* 211*91f16700Schasinglulu * Make sure the write to SCR is complete so that 212*91f16700Schasinglulu * we can access HSCTLR 213*91f16700Schasinglulu */ 214*91f16700Schasinglulu isb(); 215*91f16700Schasinglulu write_hsctlr(hsctlr); 216*91f16700Schasinglulu isb(); 217*91f16700Schasinglulu 218*91f16700Schasinglulu write_scr(read_scr() & ~SCR_NS_BIT); 219*91f16700Schasinglulu isb(); 220*91f16700Schasinglulu } else if ((read_id_pfr1() & 221*91f16700Schasinglulu (ID_PFR1_VIRTEXT_MASK << ID_PFR1_VIRTEXT_SHIFT)) != 0U) { 222*91f16700Schasinglulu el2_unused = true; 223*91f16700Schasinglulu 224*91f16700Schasinglulu /* 225*91f16700Schasinglulu * Set the NS bit to access NS copies of certain banked 226*91f16700Schasinglulu * registers 227*91f16700Schasinglulu */ 228*91f16700Schasinglulu write_scr(read_scr() | SCR_NS_BIT); 229*91f16700Schasinglulu isb(); 230*91f16700Schasinglulu 231*91f16700Schasinglulu /* 232*91f16700Schasinglulu * Hyp / PL2 present but unused, need to disable safely. 233*91f16700Schasinglulu * HSCTLR can be ignored in this case. 234*91f16700Schasinglulu * 235*91f16700Schasinglulu * Set HCR to its architectural reset value so that 236*91f16700Schasinglulu * Non-secure operations do not trap to Hyp mode. 237*91f16700Schasinglulu */ 238*91f16700Schasinglulu write_hcr(HCR_RESET_VAL); 239*91f16700Schasinglulu 240*91f16700Schasinglulu /* 241*91f16700Schasinglulu * Set HCPTR to its architectural reset value so that 242*91f16700Schasinglulu * Non-secure access from EL1 or EL0 to trace and to 243*91f16700Schasinglulu * Advanced SIMD and floating point functionality does 244*91f16700Schasinglulu * not trap to Hyp mode. 245*91f16700Schasinglulu */ 246*91f16700Schasinglulu write_hcptr(HCPTR_RESET_VAL); 247*91f16700Schasinglulu 248*91f16700Schasinglulu /* 249*91f16700Schasinglulu * Initialise CNTHCTL. All fields are architecturally 250*91f16700Schasinglulu * UNKNOWN on reset and are set to zero except for 251*91f16700Schasinglulu * field(s) listed below. 252*91f16700Schasinglulu * 253*91f16700Schasinglulu * CNTHCTL.PL1PCEN: Disable traps to Hyp mode of 254*91f16700Schasinglulu * Non-secure EL0 and EL1 accessed to the physical 255*91f16700Schasinglulu * timer registers. 256*91f16700Schasinglulu * 257*91f16700Schasinglulu * CNTHCTL.PL1PCTEN: Disable traps to Hyp mode of 258*91f16700Schasinglulu * Non-secure EL0 and EL1 accessed to the physical 259*91f16700Schasinglulu * counter registers. 260*91f16700Schasinglulu */ 261*91f16700Schasinglulu write_cnthctl(CNTHCTL_RESET_VAL | 262*91f16700Schasinglulu PL1PCEN_BIT | PL1PCTEN_BIT); 263*91f16700Schasinglulu 264*91f16700Schasinglulu /* 265*91f16700Schasinglulu * Initialise CNTVOFF to zero as it resets to an 266*91f16700Schasinglulu * IMPLEMENTATION DEFINED value. 267*91f16700Schasinglulu */ 268*91f16700Schasinglulu write64_cntvoff(0); 269*91f16700Schasinglulu 270*91f16700Schasinglulu /* 271*91f16700Schasinglulu * Set VPIDR and VMPIDR to match MIDR_EL1 and MPIDR 272*91f16700Schasinglulu * respectively. 273*91f16700Schasinglulu */ 274*91f16700Schasinglulu write_vpidr(read_midr()); 275*91f16700Schasinglulu write_vmpidr(read_mpidr()); 276*91f16700Schasinglulu 277*91f16700Schasinglulu /* 278*91f16700Schasinglulu * Initialise VTTBR, setting all fields rather than 279*91f16700Schasinglulu * relying on the hw. Some fields are architecturally 280*91f16700Schasinglulu * UNKNOWN at reset. 281*91f16700Schasinglulu * 282*91f16700Schasinglulu * VTTBR.VMID: Set to zero which is the architecturally 283*91f16700Schasinglulu * defined reset value. Even though EL1&0 stage 2 284*91f16700Schasinglulu * address translation is disabled, cache maintenance 285*91f16700Schasinglulu * operations depend on the VMID. 286*91f16700Schasinglulu * 287*91f16700Schasinglulu * VTTBR.BADDR: Set to zero as EL1&0 stage 2 address 288*91f16700Schasinglulu * translation is disabled. 289*91f16700Schasinglulu */ 290*91f16700Schasinglulu write64_vttbr(VTTBR_RESET_VAL & 291*91f16700Schasinglulu ~((VTTBR_VMID_MASK << VTTBR_VMID_SHIFT) 292*91f16700Schasinglulu | (VTTBR_BADDR_MASK << VTTBR_BADDR_SHIFT))); 293*91f16700Schasinglulu 294*91f16700Schasinglulu /* 295*91f16700Schasinglulu * Initialise HDCR, setting all the fields rather than 296*91f16700Schasinglulu * relying on hw. 297*91f16700Schasinglulu * 298*91f16700Schasinglulu * HDCR.HPMN: Set to value of PMCR.N which is the 299*91f16700Schasinglulu * architecturally-defined reset value. 300*91f16700Schasinglulu * 301*91f16700Schasinglulu * HDCR.HLP: Set to one so that event counter 302*91f16700Schasinglulu * overflow, that is recorded in PMOVSCLR[0-30], 303*91f16700Schasinglulu * occurs on the increment that changes 304*91f16700Schasinglulu * PMEVCNTR<n>[63] from 1 to 0, when ARMv8.5-PMU is 305*91f16700Schasinglulu * implemented. This bit is RES0 in versions of the 306*91f16700Schasinglulu * architecture earlier than ARMv8.5, setting it to 1 307*91f16700Schasinglulu * doesn't have any effect on them. 308*91f16700Schasinglulu * This bit is Reserved, UNK/SBZP in ARMv7. 309*91f16700Schasinglulu * 310*91f16700Schasinglulu * HDCR.HPME: Set to zero to disable EL2 Event 311*91f16700Schasinglulu * counters. 312*91f16700Schasinglulu */ 313*91f16700Schasinglulu #if (ARM_ARCH_MAJOR > 7) 314*91f16700Schasinglulu write_hdcr((HDCR_RESET_VAL | HDCR_HLP_BIT | 315*91f16700Schasinglulu ((read_pmcr() & PMCR_N_BITS) >> 316*91f16700Schasinglulu PMCR_N_SHIFT)) & ~HDCR_HPME_BIT); 317*91f16700Schasinglulu #else 318*91f16700Schasinglulu write_hdcr((HDCR_RESET_VAL | 319*91f16700Schasinglulu ((read_pmcr() & PMCR_N_BITS) >> 320*91f16700Schasinglulu PMCR_N_SHIFT)) & ~HDCR_HPME_BIT); 321*91f16700Schasinglulu #endif 322*91f16700Schasinglulu /* 323*91f16700Schasinglulu * Set HSTR to its architectural reset value so that 324*91f16700Schasinglulu * access to system registers in the cproc=1111 325*91f16700Schasinglulu * encoding space do not trap to Hyp mode. 326*91f16700Schasinglulu */ 327*91f16700Schasinglulu write_hstr(HSTR_RESET_VAL); 328*91f16700Schasinglulu /* 329*91f16700Schasinglulu * Set CNTHP_CTL to its architectural reset value to 330*91f16700Schasinglulu * disable the EL2 physical timer and prevent timer 331*91f16700Schasinglulu * interrupts. Some fields are architecturally UNKNOWN 332*91f16700Schasinglulu * on reset and are set to zero. 333*91f16700Schasinglulu */ 334*91f16700Schasinglulu write_cnthp_ctl(CNTHP_CTL_RESET_VAL); 335*91f16700Schasinglulu isb(); 336*91f16700Schasinglulu 337*91f16700Schasinglulu write_scr(read_scr() & ~SCR_NS_BIT); 338*91f16700Schasinglulu isb(); 339*91f16700Schasinglulu } 340*91f16700Schasinglulu enable_extensions_nonsecure(el2_unused); 341*91f16700Schasinglulu } 342*91f16700Schasinglulu } 343*91f16700Schasinglulu 344*91f16700Schasinglulu /******************************************************************************* 345*91f16700Schasinglulu * This function is used to exit to Non-secure world. It simply calls the 346*91f16700Schasinglulu * cm_prepare_el3_exit function for AArch32. 347*91f16700Schasinglulu ******************************************************************************/ 348*91f16700Schasinglulu void cm_prepare_el3_exit_ns(void) 349*91f16700Schasinglulu { 350*91f16700Schasinglulu cm_prepare_el3_exit(NON_SECURE); 351*91f16700Schasinglulu } 352