From aa9ae898353a86f71abdb6ebff2da61afc3581b9 Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Thu, 18 Oct 2018 14:54:57 +0100 Subject: SPM: Implement global response buffer helpers This buffer is where all the responses from Secure Partitions are stored until they are requested. Change-Id: Iafeb8f0848c5ff6f3e187060cd3a47702484dc45 Signed-off-by: Antonio Nino Diaz --- services/std_svc/spm/spm.mk | 1 + services/std_svc/spm/spm_buffers.c | 108 +++++++++++++++++++++++++++++++++++++ services/std_svc/spm/spm_private.h | 6 +++ 3 files changed, 115 insertions(+) create mode 100644 services/std_svc/spm/spm_buffers.c (limited to 'services') diff --git a/services/std_svc/spm/spm.mk b/services/std_svc/spm/spm.mk index a191f6ff..b52292d6 100644 --- a/services/std_svc/spm/spm.mk +++ b/services/std_svc/spm/spm.mk @@ -19,6 +19,7 @@ SPM_SOURCES := $(addprefix services/std_svc/spm/, \ sp_setup.c \ sp_xlat.c \ spci.c \ + spm_buffers.c \ spm_main.c \ sprt.c) \ ${SPRT_LIB_SOURCES} diff --git a/services/std_svc/spm/spm_buffers.c b/services/std_svc/spm/spm_buffers.c new file mode 100644 index 00000000..747337af --- /dev/null +++ b/services/std_svc/spm/spm_buffers.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/******************************************************************************* + * Secure Service response global array. All the responses to the requests done + * to the Secure Partition are stored here. They are removed from the array as + * soon as their value is read. + ******************************************************************************/ +struct sprt_response { + int is_valid; + uint32_t token; + uint16_t client_id, handle; + u_register_t x1, x2, x3; +}; + +static struct sprt_response responses[PLAT_SPM_RESPONSES_MAX]; + +static spinlock_t responses_lock; + +/* Add response to the global response buffer. Returns 0 on success else -1. */ +int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token, + u_register_t x1, u_register_t x2, u_register_t x3) +{ + spin_lock(&responses_lock); + + /* Make sure that there isn't any other response with the same token. */ + for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) { + struct sprt_response *resp = &(responses[i]); + + if ((resp->is_valid == 1) && (resp->token == token)) { + return -1; + } + } + + for (int i = 0; i < ARRAY_SIZE(responses); i++) { + struct sprt_response *resp = &(responses[i]); + + if (resp->is_valid == 0) { + resp->token = token; + resp->client_id = client_id; + resp->handle = handle; + resp->x1 = x1; + resp->x2 = x2; + resp->x3 = x3; + + dmbish(); + + resp->is_valid = 1; + + spin_unlock(&responses_lock); + + return 0; + } + } + + spin_unlock(&responses_lock); + + return -1; +} + +/* + * Returns a response from the requests array and removes it from it. Returns 0 + * on success, -1 if it wasn't found. + */ +int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token, + u_register_t *x1, u_register_t *x2, u_register_t *x3) +{ + spin_lock(&responses_lock); + + for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) { + struct sprt_response *resp = &(responses[i]); + + /* Ignore invalid entries */ + if (resp->is_valid == 0) { + continue; + } + + /* Make sure that all the information matches the stored one */ + if ((resp->token != token) || (resp->client_id != client_id) || + (resp->handle != handle)) { + continue; + } + + *x1 = resp->x1; + *x2 = resp->x2; + *x3 = resp->x3; + + dmbish(); + + resp->is_valid = 0; + + spin_unlock(&responses_lock); + + return 0; + } + + spin_unlock(&responses_lock); + + return -1; +} diff --git a/services/std_svc/spm/spm_private.h b/services/std_svc/spm/spm_private.h index a7bd760b..7216003b 100644 --- a/services/std_svc/spm/spm_private.h +++ b/services/std_svc/spm/spm_private.h @@ -104,6 +104,12 @@ void spm_cpu_set_sp_ctx(unsigned int linear_id, sp_context_t *sp_ctx); sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id); sp_context_t *spm_sp_get_by_uuid(const uint32_t (*svc_uuid)[4]); +/* Functions to manipulate response and requests buffers */ +int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token, + u_register_t x1, u_register_t x2, u_register_t x3); +int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token, + u_register_t *x1, u_register_t *x2, u_register_t *x3); + #endif /* __ASSEMBLY__ */ #endif /* SPM_PRIVATE_H */ -- cgit v1.2.3