blob: af5219d02b11cdd84556d750741eec5226f6f172 [file] [log] [blame]
Marc Bonnici8e1a7552021-12-01 17:57:04 +00001/*
2 * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <string.h>
9
10#include <arch.h>
11#include <arch_helpers.h>
12#include <common/debug.h>
13#include <context.h>
14#include <lib/el3_runtime/context_mgmt.h>
15#include <lib/utils.h>
16#include <lib/xlat_tables/xlat_tables_v2.h>
17#include <plat/common/common_def.h>
18#include <plat/common/platform.h>
19#include <services/ffa_svc.h>
20#include "spm_common.h"
21#include "spmc.h"
22
23#include <platform_def.h>
24
25/*
26 * We are assuming that the index of the execution
27 * context used is the linear index of the current physical cpu.
28 */
29unsigned int get_ec_index(struct secure_partition_desc *sp)
30{
31 return plat_my_core_pos();
32}
33
34/* S-EL1 partition specific initialisation. */
35void spmc_el1_sp_setup(struct secure_partition_desc *sp,
36 entry_point_info_t *ep_info)
37{
38 /* Sanity check input arguments. */
39 assert(sp != NULL);
40 assert(ep_info != NULL);
41
42 /* Initialise the SPSR for S-EL1 SPs. */
43 ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
44 DISABLE_ALL_EXCEPTIONS);
45
46 /*
Marc Bonnici6fbed8c2021-12-15 18:00:50 +000047 * TF-A Implementation defined behaviour to provide the linear
48 * core ID in the x4 register.
49 */
50 ep_info->args.arg4 = (uintptr_t) plat_my_core_pos();
51
52 /*
Marc Bonnici8e1a7552021-12-01 17:57:04 +000053 * Check whether setup is being performed for the primary or a secondary
54 * execution context. In the latter case, indicate to the SP that this
55 * is a warm boot.
56 * TODO: This check would need to be reworked if the same entry point is
57 * used for both primary and secondary initialisation.
58 */
59 if (sp->secondary_ep != 0U) {
60 /*
61 * Sanity check that the secondary entry point is still what was
62 * originally set.
63 */
64 assert(sp->secondary_ep == ep_info->pc);
65 ep_info->args.arg0 = FFA_WB_TYPE_S2RAM;
66 }
67}
68
69/* Common initialisation for all SPs. */
70void spmc_sp_common_setup(struct secure_partition_desc *sp,
71 entry_point_info_t *ep_info)
72{
73 uint16_t sp_id;
74
75 /* Assign FF-A Partition ID if not already assigned. */
76 if (sp->sp_id == INV_SP_ID) {
77 sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX;
78 /*
79 * Ensure we don't clash with previously assigned partition
80 * IDs.
81 */
82 while (!is_ffa_secure_id_valid(sp_id)) {
83 sp_id++;
84
85 if (sp_id == FFA_SWD_ID_LIMIT) {
86 ERROR("Unable to determine valid SP ID.\n");
87 panic();
88 }
89 }
90 sp->sp_id = sp_id;
91 }
92
93 /*
94 * We currently only support S-EL1 partitions so ensure this is the
95 * case.
96 */
97 assert(sp->runtime_el == S_EL1);
98
99 /*
100 * Clear the general purpose registers. These should be populated as
101 * required.
102 */
103 zeromem(&ep_info->args, sizeof(ep_info->args));
104}
105
106/*
107 * Initialise the SP context now we have populated the common and EL specific
108 * entrypoint information.
109 */
110void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
111 entry_point_info_t *ep_info)
112{
113 cpu_context_t *cpu_ctx;
114
115 cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx);
116 print_entry_point_info(ep_info);
117 cm_setup_context(cpu_ctx, ep_info);
118}