diff options
author | Ken Liu <ken.liu@arm.com> | 2018-06-26 16:50:53 +0800 |
---|---|---|
committer | Edison Ai <edison.ai@arm.com> | 2018-12-17 19:54:48 +0800 |
commit | 94e1321d91799d010fc810995fa89cb53dbe3e74 (patch) | |
tree | dde26db01f063146cb998b27f148012930d4d205 | |
parent | 92afd6b67fe12c07a9eccdea5d316c6180542868 (diff) | |
download | trusted-firmware-m-94e1321d91799d010fc810995fa89cb53dbe3e74.tar.gz |
Core: first draft for PSA service APIs
Draft PSA servie APIs. A global based message queue,
and necessary APIs for first IPC Service Partition.
Change-Id: Ifd46eaa13eb5ba2a62584f1335e438db3b2738d9
Signed-off-by: Ken Liu <ken.liu@arm.com>
-rw-r--r-- | secure_fw/core/CMakeLists.inc | 2 | ||||
-rw-r--r-- | secure_fw/core/psa_api.c | 80 | ||||
-rw-r--r-- | secure_fw/core/tfm_core.c | 11 | ||||
-rw-r--r-- | secure_fw/core/tfm_queue.c | 104 | ||||
-rw-r--r-- | secure_fw/core/tfm_queue.h | 35 |
5 files changed, 232 insertions, 0 deletions
diff --git a/secure_fw/core/CMakeLists.inc b/secure_fw/core/CMakeLists.inc index 868fbbe845..00ee316752 100644 --- a/secure_fw/core/CMakeLists.inc +++ b/secure_fw/core/CMakeLists.inc @@ -44,6 +44,8 @@ if (NOT DEFINED TFM_PSA_API) elseif (TFM_PSA_API) list(APPEND SS_CORE_C_SRC "${SS_CORE_DIR}/tfm_psa_api_client.c" "${SS_CORE_DIR}/tfm_thread.c" + "${SS_CORE_DIR}/tfm_queue.c" + "${SS_CORE_DIR}/psa_api.c" ) endif() diff --git a/secure_fw/core/psa_api.c b/secure_fw/core/psa_api.c new file mode 100644 index 0000000000..d0a19840d3 --- /dev/null +++ b/secure_fw/core/psa_api.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include <inttypes.h> +#include <stdio.h> +#include "psa_client.h" +#include "psa_service.h" +#include "tfm_thread.h" +#include "tfm_queue.h" +#include "secure_utilities.h" + +/* Service APIs */ + +/* FixMe: Initial prototype. */ +uint32_t psa_wait_any(uint32_t timeout) +{ + uint32_t msg_signals = 0; + + while (1) { + msg_signals = tfm_queue_get_msg_signal(); + + if (msg_signals == 0 && timeout == PSA_BLOCK) { + tfm_thread_schedule(); + } else { + break; + } + } + return msg_signals; +} + +void psa_get(psa_signal_t signal, psa_msg_t *msg) +{ + if (msg) { + tfm_queue_get_msg_body(msg); + } +} + +void psa_end(psa_handle_t msg_handle, psa_error_t retval) +{ + struct tfm_msg_queue_item *q_msg = (struct tfm_msg_queue_item *)msg_handle; + + q_msg->msg.handle = (psa_handle_t)0; +} + +size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, + void *buffer, size_t num_bytes) +{ + size_t bytes; + struct tfm_msg_queue_item *q_msg = (struct tfm_msg_queue_item *)msg_handle; + + if (invec_idx >= PSA_MAX_IOVEC) { + return 0; + } + + bytes = num_bytes > q_msg->invec[invec_idx].len ? + q_msg->invec[invec_idx].len : num_bytes; + + memcpy_m(buffer, q_msg->invec[invec_idx].base, bytes); + + return bytes; +} + +void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, + const void *buffer, size_t num_bytes) +{ + size_t bytes; + struct tfm_msg_queue_item *q_msg = (struct tfm_msg_queue_item *)msg_handle; + + if (outvec_idx >= PSA_MAX_IOVEC) { + return; + } + + bytes = num_bytes > q_msg->outvec[outvec_idx].len ? + q_msg->outvec[outvec_idx].len : num_bytes; + + memcpy_m(q_msg->outvec[outvec_idx].base, (void *)buffer, bytes); +} diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c index 81eeccde6b..d9f2199692 100644 --- a/secure_fw/core/tfm_core.c +++ b/secure_fw/core/tfm_core.c @@ -15,6 +15,12 @@ #include "secure_utilities.h" #include "secure_fw/spm/spm_api.h" #include "secure_fw/include/tfm_spm_services_api.h" +#ifdef TFM_PSA_API +#include "psa_client.h" +#include "psa_service.h" +#include "tfm_thread.h" +#include "tfm_queue.h" +#endif /* * Avoids the semihosting issue @@ -170,6 +176,11 @@ int main(void) LOG_MSG("Jumping to non-secure code..."); #endif +#ifdef TFM_PSA_API + tfm_queue_init(); + tfm_thread_init(); +#endif + /* We close the TFM_SP_CORE_ID partition, because its only purpose is * to be able to pass the state checks for the tests started from secure. */ diff --git a/secure_fw/core/tfm_queue.c b/secure_fw/core/tfm_queue.c new file mode 100644 index 0000000000..4a07aed117 --- /dev/null +++ b/secure_fw/core/tfm_queue.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include <inttypes.h> +#include <stdio.h> +#include "psa_client.h" +#include "psa_service.h" +#include "tfm_queue.h" +#include "secure_utilities.h" + +/* + * Message queue + */ +static struct tfm_msg_queue_item msg_queue[TFM_MSG_QUEUE_DEPTH]; +static struct tfm_msg_queue_item *q_used, *q_avail; + +#define QUEUE_EMPTY() (q_used->msg.handle == (psa_handle_t)0) +#define QUEUE_FULL() (q_avail->msg.handle != (psa_handle_t)0) + +void tfm_queue_init(void) +{ + struct tfm_msg_queue_item *p_item = msg_queue; + uint32_t i; + + for (i = 0; i < TFM_MSG_QUEUE_DEPTH; i++) { + p_item[i].msg.handle = (psa_handle_t)0; + p_item[i].next = &p_item[(i + 1) % TFM_MSG_QUEUE_DEPTH]; + p_item[i].prev = &p_item[(i + TFM_MSG_QUEUE_DEPTH - 1) % + TFM_MSG_QUEUE_DEPTH]; + } + + q_used = p_item; + q_avail = p_item; +} + +uint32_t tfm_queue_get_msg_signal(void) +{ + if (QUEUE_EMPTY()) { + return 0; + } + + return q_used->signal; +} + +psa_error_t tfm_queue_put_msg(psa_signal_t signal, uint32_t type, + psa_invec *invec, size_t in_len, + psa_outvec *outvec, size_t out_len) +{ + uint32_t i; + + /* FixMe: need to be clarified */ + if (QUEUE_FULL()) { + return TFM_QUEUE_ERROR_GENERIC; + } + + if ((!invec && in_len != 0) || (!outvec && out_len != 0)) { + ERROR_MSG("parameters error.\r\n"); + return TFM_QUEUE_ERROR_GENERIC; + } + + /* copy contents */ + q_avail->signal = signal; + + q_avail->msg.type = type; + + q_avail->invec = invec; + q_avail->outvec = outvec; + + for (i = 0; i < in_len; i++) { + q_avail->msg.in_size[i] = invec[i].len; + } + + for (i = 0; i < out_len; i++) { + q_avail->msg.out_size[i] = outvec[i].len; + } + + q_avail->msg.handle = (psa_handle_t)q_avail; + + q_avail = q_avail->next; + + return TFM_QUEUE_SUCCESS; +} + +/* Utils */ +void *memcpy_m(void *dst, const void *src, uint32_t size) +{ + uint8_t *dst_8 = (uint8_t *)dst; + uint8_t *src_8 = (uint8_t *)src; + + while (size--) { + *dst_8++ = *src_8++; + } + + return dst; +} + +void tfm_queue_get_msg_body(psa_msg_t *msg) +{ + memcpy_m(msg, &q_used->msg, sizeof(*msg)); + q_used = q_used->next; +} diff --git a/secure_fw/core/tfm_queue.h b/secure_fw/core/tfm_queue.h new file mode 100644 index 0000000000..9711addaff --- /dev/null +++ b/secure_fw/core/tfm_queue.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef __TFM_QUEUE_H__ +#define __TFM_QUEUE_H__ + +#define TFM_MSG_QUEUE_DEPTH 5 + +struct tfm_msg_queue_item { + psa_msg_t msg; + uint32_t signal; + /* Put in/out vectors in msg body */ + psa_invec *invec; + psa_outvec *outvec; + /* List opearators */ + struct tfm_msg_queue_item *prev; + struct tfm_msg_queue_item *next; +}; + +/* internal error codes */ +#define TFM_QUEUE_SUCCESS 0 +#define TFM_QUEUE_ERROR_GENERIC (INT32_MIN) + +void tfm_queue_init(void); +uint32_t tfm_queue_get_msg_signal(void); +psa_error_t tfm_queue_put_msg(psa_signal_t signal, uint32_t type, + psa_invec *invec, size_t in_len, + psa_outvec *outvec, size_t out_len); +void tfm_queue_get_msg_body(psa_msg_t *msg); +void *memcpy_m(void *dst, const void *src, uint32_t size); + +#endif |