blob: eae5d16f369179ffad360076b26e4cc9d0a4a49a [file] [log] [blame]
Ken Liuf39d8eb2021-10-07 12:55:33 +08001/*
Mingyang Sunbb4a42a2021-12-14 15:18:52 +08002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Chris Brand30106ba2022-01-13 13:48:50 -08003 * Copyright (c) 2022, Cypress Semiconductor Corporation. All rights reserved.
Ken Liuf39d8eb2021-10-07 12:55:33 +08004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 */
8
9#include <stdint.h>
10#include "compiler_ext_defs.h"
11#include "current.h"
Kevin Peng43160d52022-02-11 13:35:56 +080012#include "runtime_defs.h"
Kevin Pengb288c522021-09-26 16:18:23 +080013#include "tfm_hal_platform.h"
Ken Liuf39d8eb2021-10-07 12:55:33 +080014#include "ffm/backend.h"
Chris Brand30106ba2022-01-13 13:48:50 -080015#include "ffm/stack_watermark.h"
Ken Liuf39d8eb2021-10-07 12:55:33 +080016#include "load/partition_defs.h"
17#include "load/service_defs.h"
18#include "load/spm_load_api.h"
19#include "psa/error.h"
20#include "psa/service.h"
21#include "spm_ipc.h"
22
23/* SFN Partition state */
24#define SFN_PARTITION_STATE_NOT_INITED 0
25#define SFN_PARTITION_STATE_INITED 1
26
Ken Liuf39d8eb2021-10-07 12:55:33 +080027/* Declare the global component list */
28struct partition_head_t partition_listhead;
29
Sherry Zhang049733e2022-04-20 21:37:51 +080030/* Current running partition. */
31struct partition_t *p_current_partition;
32
Ken Liuf39d8eb2021-10-07 12:55:33 +080033/*
34 * Send message and wake up the SP who is waiting on message queue, block the
35 * current component state and activate the next component.
36 */
37static psa_status_t sfn_messaging(struct service_t *service,
Mingyang Suna09adda2022-02-16 18:11:33 +080038 struct conn_handle_t *handle)
Ken Liuf39d8eb2021-10-07 12:55:33 +080039{
40 struct partition_t *p_target;
41 psa_status_t status;
42
Mingyang Suna09adda2022-02-16 18:11:33 +080043 if (!handle || !service || !service->p_ldinf || !service->partition) {
Mingyang Sunbb4a42a2021-12-14 15:18:52 +080044 return PSA_ERROR_PROGRAMMER_ERROR;
Ken Liuf39d8eb2021-10-07 12:55:33 +080045 }
46
Mingyang Suna09adda2022-02-16 18:11:33 +080047 handle->sfn_magic = TFM_MSG_MAGIC_SFN;
Ken Liuf39d8eb2021-10-07 12:55:33 +080048 p_target = service->partition;
Mingyang Suna09adda2022-02-16 18:11:33 +080049 p_target->p_handles = handle;
Ken Liuf39d8eb2021-10-07 12:55:33 +080050
51 SET_CURRENT_COMPONENT(p_target);
52
53 if (p_target->state == SFN_PARTITION_STATE_NOT_INITED) {
54 if (p_target->p_ldinf->entry != 0) {
55 status = ((sfn_init_fn_t)p_target->p_ldinf->entry)();
56 /* Negative value indicates errors. */
57 if (status < PSA_SUCCESS) {
Mingyang Sunbb4a42a2021-12-14 15:18:52 +080058 return PSA_ERROR_PROGRAMMER_ERROR;
Ken Liuf39d8eb2021-10-07 12:55:33 +080059 }
60 }
61 p_target->state = SFN_PARTITION_STATE_INITED;
62 }
63
Mingyang Suna09adda2022-02-16 18:11:33 +080064 status = ((service_fn_t)service->p_ldinf->sfn)(&handle->msg);
Ken Liuf39d8eb2021-10-07 12:55:33 +080065
Mingyang Sunaeca8e02022-02-24 14:47:56 +080066 handle->status = TFM_HANDLE_STATUS_ACTIVE;
67
Ken Liuf39d8eb2021-10-07 12:55:33 +080068 return status;
69}
70
Mingyang Suna09adda2022-02-16 18:11:33 +080071static psa_status_t sfn_replying(struct conn_handle_t *handle, int32_t status)
Ken Liuf39d8eb2021-10-07 12:55:33 +080072{
Mingyang Suna09adda2022-02-16 18:11:33 +080073 SET_CURRENT_COMPONENT(handle->p_client);
Ken Liuf39d8eb2021-10-07 12:55:33 +080074
75 /*
76 * Returning a value here is necessary, because 'psa_reply' is absent
77 * for SFN clients, the 'reply' method is performed by SPM internally
78 * when SFN case, to forward the 'status' to the caller.
79 *
80 * For example:
81 * 'status' MAY contain a 'psa_handle_t' returned by SPM 'connect' and
82 * SPM needs to 'reply' it back to the caller. Treat 'psa_handle_t' value
83 * as SPM specific return value and represnent it as 'psa_status_t'.
84 */
85 return status;
86}
87
Ken Liuef229a22022-02-11 11:15:43 +080088static void spm_thread_fn(void)
Ken Liuf39d8eb2021-10-07 12:55:33 +080089{
90 struct partition_t *p_part, *p_curr;
91
92 p_curr = GET_CURRENT_COMPONENT();
93 /* Call partition initialization routine one by one. */
Ken Liu5a28da32022-01-19 14:37:05 +080094 UNI_LIST_FOREACH(p_part, PARTITION_LIST_ADDR, next) {
Kevin Peng56c571e2022-01-10 14:06:05 +080095 if (IS_PARTITION_IPC_MODEL(p_part->p_ldinf)) {
Ken Liuf39d8eb2021-10-07 12:55:33 +080096 continue;
97 }
98
99 if (p_part->state == SFN_PARTITION_STATE_INITED) {
100 continue;
101 }
102
103 SET_CURRENT_COMPONENT(p_part);
104
105 if (p_part->p_ldinf->entry != 0) {
106 if (((sfn_init_fn_t)p_part->p_ldinf->entry)() < PSA_SUCCESS) {
107 tfm_core_panic();
108 }
109 }
110
111 p_part->state = SFN_PARTITION_STATE_INITED;
112 }
113
114 SET_CURRENT_COMPONENT(p_curr);
Ken Liuef229a22022-02-11 11:15:43 +0800115}
Ken Liuf39d8eb2021-10-07 12:55:33 +0800116
Ken Liuef229a22022-02-11 11:15:43 +0800117/* Parameters are treated as assuredly */
118void sfn_comp_init_assuredly(struct partition_t *p_pt, uint32_t service_set)
119{
120 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
Sherry Zhang049733e2022-04-20 21:37:51 +0800121 struct context_ctrl_t ns_agent_ctrl;
Ken Liuef229a22022-02-11 11:15:43 +0800122 p_pt->p_handles = NULL;
123 p_pt->state = SFN_PARTITION_STATE_NOT_INITED;
124
Chris Brand30106ba2022-01-13 13:48:50 -0800125 watermark_stack(p_pt);
126
Ken Liuef229a22022-02-11 11:15:43 +0800127 /*
128 * Built-in partitions still have thread instances: NS Agent (TZ) and
129 * IDLE partition, and NS Agent (TZ) needs to be specific cared here.
130 */
131 if (p_pldi->pid == TFM_SP_NON_SECURE_ID) {
Sherry Zhang049733e2022-04-20 21:37:51 +0800132 ARCH_CTXCTRL_INIT(&ns_agent_ctrl,
133 LOAD_ALLOCED_STACK_ADDR(p_pldi),
134 p_pldi->stack_size);
135 tfm_arch_init_context(&ns_agent_ctrl, (uintptr_t)spm_thread_fn,
136 NULL, p_pldi->entry);
137 tfm_arch_refresh_hardware_context(&ns_agent_ctrl);
138 SET_CURRENT_COMPONENT(p_pt);
Ken Liuef229a22022-02-11 11:15:43 +0800139 }
Ken Liuf39d8eb2021-10-07 12:55:33 +0800140}
141
142uint32_t sfn_system_run(void)
143{
Sherry Zhang049733e2022-04-20 21:37:51 +0800144 return EXC_RETURN_THREAD_S_PSP;
Ken Liuf39d8eb2021-10-07 12:55:33 +0800145}
146
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800147static psa_signal_t sfn_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
Kevin Pengdef92de2021-11-10 16:14:48 +0800148{
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800149 while (!(p_pt->signals_asserted & signal_mask))
Kevin Pengdef92de2021-11-10 16:14:48 +0800150 ;
151
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800152 return p_pt->signals_asserted & signal_mask;
Kevin Pengdef92de2021-11-10 16:14:48 +0800153}
154
Mingyang Sun09328bd2022-03-25 11:55:13 +0800155static void sfn_wake_up(struct partition_t *p_pt)
Kevin Pengdef92de2021-11-10 16:14:48 +0800156{
157 (void)p_pt;
Kevin Pengdef92de2021-11-10 16:14:48 +0800158}
159
Ken Liuf39d8eb2021-10-07 12:55:33 +0800160const struct backend_ops_t backend_instance = {
161 .comp_init_assuredly = sfn_comp_init_assuredly,
162 .system_run = sfn_system_run,
163 .messaging = sfn_messaging,
Kevin Pengdef92de2021-11-10 16:14:48 +0800164 .replying = sfn_replying,
165 .wait = sfn_wait,
166 .wake_up = sfn_wake_up,
Ken Liuf39d8eb2021-10-07 12:55:33 +0800167};