/******************************************************************************* * This function takes an SP context pointer and performs a synchronous entry * into it. ******************************************************************************/ uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx, int can_preempt) { uint64_t rc; unsigned int linear_id = plat_my_core_pos(); assert(sp_ctx != NULL); /* Assign the context of the SP to this CPU */ spm_cpu_set_sp_ctx(linear_id, sp_ctx); cm_set_context(&(sp_ctx->cpu_ctx), SECURE); /* Restore the context assigned above */ cm_el1_sysregs_context_restore(SECURE); cm_set_next_eret_context(SECURE); /* Invalidate TLBs at EL1. */ tlbivmalle1(); dsbish(); if (can_preempt == 1) { enable_intr_rm_local(INTR_TYPE_NS, SECURE); } else { disable_intr_rm_local(INTR_TYPE_NS, SECURE); } /* Enter Secure Partition */ rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx); /* Save secure state */ cm_el1_sysregs_context_save(SECURE); return rc; }
/******************************************************************************* * Given a secure payload entrypoint, register width, cpu id & pointer to a * context data structure, this function will create a secure context ready for * programming an entry into the secure payload. ******************************************************************************/ void tlkd_init_tlk_ep_state(struct entry_point_info *tlk_entry_point, uint32_t rw, uint64_t pc, tlk_context_t *tlk_ctx) { uint32_t ep_attr, spsr; /* Passing a NULL context is a critical programming error */ assert(tlk_ctx); assert(tlk_entry_point); assert(pc); /* Associate this context with the cpu specified */ tlk_ctx->mpidr = read_mpidr_el1(); clr_std_smc_active_flag(tlk_ctx->state); cm_set_context(&tlk_ctx->cpu_ctx, SECURE); if (rw == SP_AARCH64) spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); else spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, read_sctlr_el3() & SCTLR_EE_BIT, DISABLE_ALL_EXCEPTIONS); /* initialise an entrypoint to set up the CPU context */ ep_attr = SECURE | EP_ST_ENABLE; if (read_sctlr_el3() & SCTLR_EE_BIT) ep_attr |= EP_EE_BIG; SET_PARAM_HEAD(tlk_entry_point, PARAM_EP, VERSION_1, ep_attr); tlk_entry_point->pc = pc; tlk_entry_point->spsr = spsr; }
static int32_t tbase_init_secure_context(tbase_context *tbase_ctx) { uint32_t sctlr = read_sctlr_el3(); el1_sys_regs_t *el1_state; uint64_t mpidr = read_mpidr(); /* Passing a NULL context is a critical programming error */ assert(tbase_ctx); DBG_PRINTF("tbase_init_secure_context\n\r"); memset(tbase_ctx, 0, sizeof(*tbase_ctx)); /* Get a pointer to the S-EL1 context memory */ el1_state = get_sysregs_ctx(&tbase_ctx->cpu_ctx); // Program the sctlr for S-EL1 execution with caches and mmu off sctlr &= SCTLR_EE_BIT; sctlr |= SCTLR_EL1_RES1; write_ctx_reg(el1_state, CTX_SCTLR_EL1, sctlr); /* Set this context as ready to be initialised i.e OFF */ tbase_ctx->state = TBASE_STATE_OFF; /* Associate this context with the cpu specified */ tbase_ctx->mpidr = mpidr; // Set up cm context for this core cm_set_context(mpidr, &tbase_ctx->cpu_ctx, SECURE); // cm_init_exception_stack(mpidr, SECURE); return 0; }
/******************************************************************************* * Given a secure payload entrypoint info pointer, entry point PC, register * width, cpu id & pointer to a context data structure, this function will * initialize tsp context and entry point info for the secure payload ******************************************************************************/ void tspd_init_tsp_ep_state(struct entry_point_info *tsp_entry_point, uint32_t rw, uint64_t pc, tsp_context_t *tsp_ctx) { uint32_t ep_attr; /* Passing a NULL context is a critical programming error */ assert(tsp_ctx); assert(tsp_entry_point); assert(pc); /* * We support AArch64 TSP for now. * TODO: Add support for AArch32 TSP */ assert(rw == TSP_AARCH64); /* Associate this context with the cpu specified */ tsp_ctx->mpidr = read_mpidr_el1(); tsp_ctx->state = 0; set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF); clr_yield_smc_active_flag(tsp_ctx->state); cm_set_context(&tsp_ctx->cpu_ctx, SECURE); /* initialise an entrypoint to set up the CPU context */ ep_attr = SECURE | EP_ST_ENABLE; if (read_sctlr_el3() & SCTLR_EE_BIT) ep_attr |= EP_EE_BIG; SET_PARAM_HEAD(tsp_entry_point, PARAM_EP, VERSION_1, ep_attr); tsp_entry_point->pc = pc; tsp_entry_point->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); zeromem(&tsp_entry_point->args, sizeof(tsp_entry_point->args)); }