blob: 0c88c63cfec4dc990173bbc69435e23a706d4a6e [file] [log] [blame]
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +01001/*
Antonio Nino Diaza5b4c402018-01-08 17:33:34 +00002 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <bl31.h>
10#include <context_mgmt.h>
11#include <debug.h>
12#include <errno.h>
Antonio Nino Diaza5b4c402018-01-08 17:33:34 +000013#include <mm_svc.h>
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010014#include <platform.h>
15#include <runtime_svc.h>
16#include <secure_partition.h>
Antonio Nino Diaz085e80e2018-03-21 10:49:27 +000017#include <smccc.h>
18#include <smccc_helpers.h>
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010019#include <spinlock.h>
20#include <spm_svc.h>
21#include <utils.h>
22#include <xlat_tables_v2.h>
23
24#include "spm_private.h"
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010025#include "spm_shim_private.h"
26
27/* Place translation tables by default along with the ones used by BL31. */
28#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
29#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "xlat_table"
30#endif
31
32/* Allocate and initialise the translation context for the secure partitions. */
33REGISTER_XLAT_CONTEXT2(sp,
34 PLAT_SP_IMAGE_MMAP_REGIONS,
35 PLAT_SP_IMAGE_MAX_XLAT_TABLES,
36 PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
37 EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010038
39/* Lock used for SP_MEMORY_ATTRIBUTES_GET and SP_MEMORY_ATTRIBUTES_SET */
40static spinlock_t mem_attr_smc_lock;
41
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010042/* Get handle of Secure Partition translation context */
43xlat_ctx_t *spm_get_sp_xlat_context(void)
44{
45 return &sp_xlat_ctx;
46};
47
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010048/*******************************************************************************
49 * Secure Partition context information.
50 ******************************************************************************/
51static secure_partition_context_t sp_ctx;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010052
53/*******************************************************************************
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010054 * This function takes an SP context pointer and prepares the CPU to enter.
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010055 ******************************************************************************/
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010056static void spm_sp_prepare_enter(secure_partition_context_t *sp_ctx)
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010057{
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010058 assert(sp_ctx != NULL);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010059
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010060 /* Assign the context of the SP to this CPU */
61 cm_set_context(&(sp_ctx->cpu_ctx), SECURE);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010062
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010063 /* Restore the context assigned above */
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010064 cm_el1_sysregs_context_restore(SECURE);
65 cm_set_next_eret_context(SECURE);
66
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010067 /* Invalidate TLBs at EL1. */
68 tlbivmalle1();
69 dsbish();
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010070}
71
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010072/*******************************************************************************
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010073 * Enter SP after preparing it with spm_sp_prepare_enter().
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010074 ******************************************************************************/
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010075static uint64_t spm_sp_enter(secure_partition_context_t *sp_ctx)
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010076{
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010077 /* Enter Secure Partition */
78 return spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010079}
80
81/*******************************************************************************
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010082 * Jump to each Secure Partition for the first time.
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010083 ******************************************************************************/
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +010084static int32_t spm_init(void)
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010085{
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010086 uint64_t rc = 0;
87 secure_partition_context_t *ctx;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010088
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010089 INFO("Secure Partition init...\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010090
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010091 ctx = &sp_ctx;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010092
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010093 ctx->sp_init_in_progress = 1;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010094
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010095 spm_sp_prepare_enter(ctx);
96 rc |= spm_sp_enter(ctx);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +010097 assert(rc == 0);
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +010098
99 ctx->sp_init_in_progress = 0;
100
101 INFO("Secure Partition initialized.\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100102
103 return rc;
104}
105
106/*******************************************************************************
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100107 * Initialize contexts of all Secure Partitions.
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100108 ******************************************************************************/
109int32_t spm_setup(void)
110{
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100111 secure_partition_context_t *ctx;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100112
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100113 /* Disable MMU at EL1 (initialized by BL2) */
114 disable_mmu_icache_el1();
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100115
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100116 /* Initialize context of the SP */
117 INFO("Secure Partition context setup start...\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100118
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100119 ctx = &sp_ctx;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100120
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100121 /* Assign translation tables context. */
122 ctx->xlat_ctx_handle = spm_get_sp_xlat_context();
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100123
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100124 secure_partition_setup(ctx);
125
126 /* Register init function for deferred init. */
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100127 bl31_register_bl32_init(&spm_init);
128
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100129 INFO("Secure Partition setup done.\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100130
131 return 0;
132}
133
134/*
135 * Attributes are encoded using a different format in the SMC interface than in
136 * the Trusted Firmware, where the mmap_attr_t enum type is used. This function
137 * converts an attributes value from the SMC format to the mmap_attr_t format by
138 * setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and MT_EXECUTE/MT_EXECUTE_NEVER.
139 * The other fields are left as 0 because they are ignored by the function
140 * change_mem_attributes().
141 */
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100142static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100143{
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100144 unsigned int tf_attr = 0U;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100145
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000146 unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
147 >> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100148
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000149 if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100150 tf_attr |= MT_RW | MT_USER;
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000151 } else if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100152 tf_attr |= MT_RO | MT_USER;
153 } else {
154 /* Other values are reserved. */
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000155 assert(access == SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100156 /* The only requirement is that there's no access from EL0 */
157 tf_attr |= MT_RO | MT_PRIVILEGED;
158 }
159
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000160 if ((attributes & SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100161 tf_attr |= MT_EXECUTE;
162 } else {
163 tf_attr |= MT_EXECUTE_NEVER;
164 }
165
166 return tf_attr;
167}
168
169/*
170 * This function converts attributes from the Trusted Firmware format into the
171 * SMC interface format.
172 */
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100173static unsigned int smc_mmap_to_smc_attr(unsigned int attr)
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100174{
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100175 unsigned int smc_attr = 0U;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100176
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100177 unsigned int data_access;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100178
179 if ((attr & MT_USER) == 0) {
180 /* No access from EL0. */
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000181 data_access = SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100182 } else {
183 if ((attr & MT_RW) != 0) {
184 assert(MT_TYPE(attr) != MT_DEVICE);
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000185 data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RW;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100186 } else {
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000187 data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RO;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100188 }
189 }
190
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000191 smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
192 << SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100193
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100194 if ((attr & MT_EXECUTE_NEVER) != 0U) {
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000195 smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100196 }
197
198 return smc_attr;
199}
200
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100201static int32_t spm_memory_attributes_get_smc_handler(
202 secure_partition_context_t *sp_ctx,
203 uintptr_t base_va)
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100204{
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100205 uint32_t attributes;
206
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100207 spin_lock(&mem_attr_smc_lock);
208
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100209 int rc = get_mem_attributes(sp_ctx->xlat_ctx_handle,
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100210 base_va, &attributes);
211
212 spin_unlock(&mem_attr_smc_lock);
213
214 /* Convert error codes of get_mem_attributes() into SPM ones. */
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100215 assert((rc == 0) || (rc == -EINVAL));
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100216
217 if (rc == 0) {
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100218 return (int32_t) smc_mmap_to_smc_attr(attributes);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100219 } else {
220 return SPM_INVALID_PARAMETER;
221 }
222}
223
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100224static int spm_memory_attributes_set_smc_handler(
225 secure_partition_context_t *sp_ctx,
226 u_register_t page_address,
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100227 u_register_t pages_count,
228 u_register_t smc_attributes)
229{
230 uintptr_t base_va = (uintptr_t) page_address;
231 size_t size = (size_t) (pages_count * PAGE_SIZE);
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100232 uint32_t attributes = (uint32_t) smc_attributes;
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100233
234 INFO(" Start address : 0x%lx\n", base_va);
235 INFO(" Number of pages: %i (%zi bytes)\n", (int) pages_count, size);
236 INFO(" Attributes : 0x%x\n", attributes);
237
238 spin_lock(&mem_attr_smc_lock);
239
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100240 int ret = change_mem_attributes(sp_ctx->xlat_ctx_handle,
241 base_va, size,
242 smc_attr_to_mmap_attr(attributes));
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100243
244 spin_unlock(&mem_attr_smc_lock);
245
246 /* Convert error codes of change_mem_attributes() into SPM ones. */
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100247 assert((ret == 0) || (ret == -EINVAL));
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100248
249 return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
250}
251
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100252/*******************************************************************************
253 * Secure Partition Manager SMC handler.
254 ******************************************************************************/
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100255uint64_t spm_smc_handler(uint32_t smc_fid,
256 uint64_t x1,
257 uint64_t x2,
258 uint64_t x3,
259 uint64_t x4,
260 void *cookie,
261 void *handle,
262 uint64_t flags)
263{
264 cpu_context_t *ns_cpu_context;
265 unsigned int ns;
266
267 /* Determine which security state this SMC originated from */
268 ns = is_caller_non_secure(flags);
269
270 if (ns == SMC_FROM_SECURE) {
271
272 /* Handle SMCs from Secure world. */
273
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100274 assert(handle == cm_get_context(SECURE));
275
276 /* Make next ERET jump to S-EL0 instead of S-EL1. */
277 cm_set_elr_spsr_el3(SECURE, read_elr_el1(), read_spsr_el1());
278
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100279 switch (smc_fid) {
280
Sandrine Bailleux4d2787c2017-12-07 09:48:56 +0000281 case SPM_VERSION_AARCH32:
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100282 SMC_RET1(handle, SPM_VERSION_COMPILED);
283
284 case SP_EVENT_COMPLETE_AARCH64:
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100285 /* Save secure state */
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100286 cm_el1_sysregs_context_save(SECURE);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100287
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100288 if (sp_ctx.sp_init_in_progress == 1) {
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100289 /*
290 * SPM reports completion. The SPM must have
291 * initiated the original request through a
292 * synchronous entry into the secure
293 * partition. Jump back to the original C
294 * runtime context.
295 */
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100296 spm_secure_partition_exit(sp_ctx.c_rt_ctx, x1);
297
298 /* spm_secure_partition_exit doesn't return */
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100299 }
300
Antonio Nino Diaza43c85d2018-01-08 09:59:33 +0000301 /* Release the Secure Partition context */
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100302 spin_unlock(&(sp_ctx.lock));
Antonio Nino Diaza43c85d2018-01-08 09:59:33 +0000303
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100304 /*
305 * This is the result from the Secure partition of an
306 * earlier request. Copy the result into the non-secure
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100307 * context and return to the non-secure state.
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100308 */
309
310 /* Get a reference to the non-secure context */
311 ns_cpu_context = cm_get_context(NON_SECURE);
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100312 assert(ns_cpu_context != NULL);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100313
314 /* Restore non-secure state */
315 cm_el1_sysregs_context_restore(NON_SECURE);
316 cm_set_next_eret_context(NON_SECURE);
317
318 /* Return to normal world */
319 SMC_RET1(ns_cpu_context, x1);
320
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000321 case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
322 INFO("Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100323
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100324 if (sp_ctx.sp_init_in_progress == 0) {
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000325 WARN("SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100326 SMC_RET1(handle, SPM_NOT_SUPPORTED);
327 }
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100328 SMC_RET1(handle,
329 spm_memory_attributes_get_smc_handler(
330 &sp_ctx, x1));
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100331
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000332 case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
333 INFO("Received SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100334
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100335 if (sp_ctx.sp_init_in_progress == 0) {
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000336 WARN("SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100337 SMC_RET1(handle, SPM_NOT_SUPPORTED);
338 }
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100339 SMC_RET1(handle,
340 spm_memory_attributes_set_smc_handler(
341 &sp_ctx, x1, x2, x3));
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100342 default:
343 break;
344 }
345 } else {
346
347 /* Handle SMCs from Non-secure world. */
348
349 switch (smc_fid) {
350
Antonio Nino Diaza5b4c402018-01-08 17:33:34 +0000351 case MM_VERSION_AARCH32:
352 SMC_RET1(handle, MM_VERSION_COMPILED);
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100353
Sandrine Bailleux756a2a02017-12-01 09:44:21 +0000354 case MM_COMMUNICATE_AARCH32:
355 case MM_COMMUNICATE_AARCH64:
Sandrine Bailleux4d2787c2017-12-07 09:48:56 +0000356 {
357 uint64_t mm_cookie = x1;
358 uint64_t comm_buffer_address = x2;
359 uint64_t comm_size_address = x3;
360
361 /* Cookie. Reserved for future use. It must be zero. */
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100362 if (mm_cookie != 0U) {
Sandrine Bailleux4d2787c2017-12-07 09:48:56 +0000363 ERROR("MM_COMMUNICATE: cookie is not zero\n");
364 SMC_RET1(handle, SPM_INVALID_PARAMETER);
365 }
366
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100367 if (comm_buffer_address == 0U) {
Sandrine Bailleux4d2787c2017-12-07 09:48:56 +0000368 ERROR("MM_COMMUNICATE: comm_buffer_address is zero\n");
369 SMC_RET1(handle, SPM_INVALID_PARAMETER);
370 }
371
Antonio Nino Diazb3323cd2018-04-17 15:10:18 +0100372 if (comm_size_address != 0U) {
Sandrine Bailleux4d2787c2017-12-07 09:48:56 +0000373 VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
374 }
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100375
376 /* Save the Normal world context */
377 cm_el1_sysregs_context_save(NON_SECURE);
378
Antonio Nino Diaza43c85d2018-01-08 09:59:33 +0000379 /* Lock the Secure Partition context. */
380 spin_lock(&sp_ctx.lock);
381
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100382 /* Jump to the Secure Partition. */
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100383
Antonio Nino Diaz22282bb2018-05-23 11:40:46 +0100384 spm_sp_prepare_enter(&sp_ctx);
385
386 SMC_RET4(&(sp_ctx.cpu_ctx), smc_fid,
387 comm_buffer_address, comm_size_address,
388 plat_my_core_pos());
Sandrine Bailleux4d2787c2017-12-07 09:48:56 +0000389 }
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100390
Antonio Nino Diazfa0ed2b2017-12-01 14:12:43 +0000391 case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
392 case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
Antonio Nino Diaz2fccb222017-10-24 10:07:35 +0100393 /* SMC interfaces reserved for secure callers. */
394 SMC_RET1(handle, SPM_NOT_SUPPORTED);
395
396 default:
397 break;
398 }
399 }
400
401 SMC_RET1(handle, SMC_UNK);
402}