/*******************************************************************************
 * 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;
}
Exemple #3
0
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));
}