/* * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include #include #include #include #include #include #include #include #include "spm_common.h" #include "spmc.h" #include /* * 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); /* * 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); }