blob: af5219d02b11cdd84556d750741eec5226f6f172 [file] [log] [blame]
/*
* Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <string.h>
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <services/ffa_svc.h>
#include "spm_common.h"
#include "spmc.h"
#include <platform_def.h>
/*
* We are assuming that the index of the execution
* context used is the linear index of the current physical cpu.
*/
unsigned int get_ec_index(struct secure_partition_desc *sp)
{
return plat_my_core_pos();
}
/* S-EL1 partition specific initialisation. */
void spmc_el1_sp_setup(struct secure_partition_desc *sp,
entry_point_info_t *ep_info)
{
/* Sanity check input arguments. */
assert(sp != NULL);
assert(ep_info != NULL);
/* Initialise the SPSR for S-EL1 SPs. */
ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
/*
* TF-A Implementation defined behaviour to provide the linear
* core ID in the x4 register.
*/
ep_info->args.arg4 = (uintptr_t) plat_my_core_pos();
/*
* Check whether setup is being performed for the primary or a secondary
* execution context. In the latter case, indicate to the SP that this
* is a warm boot.
* TODO: This check would need to be reworked if the same entry point is
* used for both primary and secondary initialisation.
*/
if (sp->secondary_ep != 0U) {
/*
* Sanity check that the secondary entry point is still what was
* originally set.
*/
assert(sp->secondary_ep == ep_info->pc);
ep_info->args.arg0 = FFA_WB_TYPE_S2RAM;
}
}
/* Common initialisation for all SPs. */
void spmc_sp_common_setup(struct secure_partition_desc *sp,
entry_point_info_t *ep_info)
{
uint16_t sp_id;
/* Assign FF-A Partition ID if not already assigned. */
if (sp->sp_id == INV_SP_ID) {
sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX;
/*
* Ensure we don't clash with previously assigned partition
* IDs.
*/
while (!is_ffa_secure_id_valid(sp_id)) {
sp_id++;
if (sp_id == FFA_SWD_ID_LIMIT) {
ERROR("Unable to determine valid SP ID.\n");
panic();
}
}
sp->sp_id = sp_id;
}
/*
* We currently only support S-EL1 partitions so ensure this is the
* case.
*/
assert(sp->runtime_el == S_EL1);
/*
* Clear the general purpose registers. These should be populated as
* required.
*/
zeromem(&ep_info->args, sizeof(ep_info->args));
}
/*
* Initialise the SP context now we have populated the common and EL specific
* entrypoint information.
*/
void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
entry_point_info_t *ep_info)
{
cpu_context_t *cpu_ctx;
cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx);
print_entry_point_info(ep_info);
cm_setup_context(cpu_ctx, ep_info);
}