blob: 9218afc1cee9ae4eea89921bc9bcf60f2b7b5330 [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
Ken Liuf39d8eb2021-10-07 12:55:33 +080030/*
31 * Send message and wake up the SP who is waiting on message queue, block the
32 * current component state and activate the next component.
33 */
34static psa_status_t sfn_messaging(struct service_t *service,
Mingyang Suna09adda2022-02-16 18:11:33 +080035 struct conn_handle_t *handle)
Ken Liuf39d8eb2021-10-07 12:55:33 +080036{
37 struct partition_t *p_target;
38 psa_status_t status;
39
Mingyang Suna09adda2022-02-16 18:11:33 +080040 if (!handle || !service || !service->p_ldinf || !service->partition) {
Mingyang Sunbb4a42a2021-12-14 15:18:52 +080041 return PSA_ERROR_PROGRAMMER_ERROR;
Ken Liuf39d8eb2021-10-07 12:55:33 +080042 }
43
Mingyang Suna09adda2022-02-16 18:11:33 +080044 handle->sfn_magic = TFM_MSG_MAGIC_SFN;
Ken Liuf39d8eb2021-10-07 12:55:33 +080045 p_target = service->partition;
Mingyang Suna09adda2022-02-16 18:11:33 +080046 p_target->p_handles = handle;
Ken Liuf39d8eb2021-10-07 12:55:33 +080047
48 SET_CURRENT_COMPONENT(p_target);
49
50 if (p_target->state == SFN_PARTITION_STATE_NOT_INITED) {
51 if (p_target->p_ldinf->entry != 0) {
52 status = ((sfn_init_fn_t)p_target->p_ldinf->entry)();
53 /* Negative value indicates errors. */
54 if (status < PSA_SUCCESS) {
Mingyang Sunbb4a42a2021-12-14 15:18:52 +080055 return PSA_ERROR_PROGRAMMER_ERROR;
Ken Liuf39d8eb2021-10-07 12:55:33 +080056 }
57 }
58 p_target->state = SFN_PARTITION_STATE_INITED;
59 }
60
Mingyang Suna09adda2022-02-16 18:11:33 +080061 status = ((service_fn_t)service->p_ldinf->sfn)(&handle->msg);
Ken Liuf39d8eb2021-10-07 12:55:33 +080062
Mingyang Sunaeca8e02022-02-24 14:47:56 +080063 handle->status = TFM_HANDLE_STATUS_ACTIVE;
64
Ken Liuf39d8eb2021-10-07 12:55:33 +080065 return status;
66}
67
Mingyang Suna09adda2022-02-16 18:11:33 +080068static psa_status_t sfn_replying(struct conn_handle_t *handle, int32_t status)
Ken Liuf39d8eb2021-10-07 12:55:33 +080069{
Mingyang Suna09adda2022-02-16 18:11:33 +080070 SET_CURRENT_COMPONENT(handle->p_client);
Ken Liuf39d8eb2021-10-07 12:55:33 +080071
72 /*
73 * Returning a value here is necessary, because 'psa_reply' is absent
74 * for SFN clients, the 'reply' method is performed by SPM internally
75 * when SFN case, to forward the 'status' to the caller.
76 *
77 * For example:
78 * 'status' MAY contain a 'psa_handle_t' returned by SPM 'connect' and
79 * SPM needs to 'reply' it back to the caller. Treat 'psa_handle_t' value
80 * as SPM specific return value and represnent it as 'psa_status_t'.
81 */
82 return status;
83}
84
Ken Liuef229a22022-02-11 11:15:43 +080085static void spm_thread_fn(void)
Ken Liuf39d8eb2021-10-07 12:55:33 +080086{
87 struct partition_t *p_part, *p_curr;
88
89 p_curr = GET_CURRENT_COMPONENT();
90 /* Call partition initialization routine one by one. */
Ken Liu5a28da32022-01-19 14:37:05 +080091 UNI_LIST_FOREACH(p_part, PARTITION_LIST_ADDR, next) {
Kevin Peng56c571e2022-01-10 14:06:05 +080092 if (IS_PARTITION_IPC_MODEL(p_part->p_ldinf)) {
Ken Liuf39d8eb2021-10-07 12:55:33 +080093 continue;
94 }
95
96 if (p_part->state == SFN_PARTITION_STATE_INITED) {
97 continue;
98 }
99
100 SET_CURRENT_COMPONENT(p_part);
101
102 if (p_part->p_ldinf->entry != 0) {
103 if (((sfn_init_fn_t)p_part->p_ldinf->entry)() < PSA_SUCCESS) {
104 tfm_core_panic();
105 }
106 }
107
108 p_part->state = SFN_PARTITION_STATE_INITED;
109 }
110
111 SET_CURRENT_COMPONENT(p_curr);
Ken Liuef229a22022-02-11 11:15:43 +0800112}
Ken Liuf39d8eb2021-10-07 12:55:33 +0800113
Ken Liuef229a22022-02-11 11:15:43 +0800114/* Parameters are treated as assuredly */
115void sfn_comp_init_assuredly(struct partition_t *p_pt, uint32_t service_set)
116{
117 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
Ken Liuf39d8eb2021-10-07 12:55:33 +0800118
Ken Liuef229a22022-02-11 11:15:43 +0800119 p_pt->p_handles = NULL;
120 p_pt->state = SFN_PARTITION_STATE_NOT_INITED;
121
122 THRD_SYNC_INIT(&p_pt->waitobj);
123
124 ARCH_CTXCTRL_INIT(&p_pt->ctx_ctrl,
125 LOAD_ALLOCED_STACK_ADDR(p_pldi),
126 p_pldi->stack_size);
127
Chris Brand30106ba2022-01-13 13:48:50 -0800128 watermark_stack(p_pt);
129
Ken Liuef229a22022-02-11 11:15:43 +0800130 /*
131 * Built-in partitions still have thread instances: NS Agent (TZ) and
132 * IDLE partition, and NS Agent (TZ) needs to be specific cared here.
133 */
134 if (p_pldi->pid == TFM_SP_NON_SECURE_ID) {
135 THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
136 TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
137
138 thrd_start(&p_pt->thrd,
139 POSITION_TO_ENTRY(spm_thread_fn, thrd_fn_t),
140 POSITION_TO_ENTRY(p_pldi->entry, thrd_fn_t));
141 }
Ken Liuf39d8eb2021-10-07 12:55:33 +0800142}
143
144uint32_t sfn_system_run(void)
145{
Ken Liuf39d8eb2021-10-07 12:55:33 +0800146 return thrd_start_scheduler(&CURRENT_THREAD);
147}
148
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800149static psa_signal_t sfn_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
Kevin Pengdef92de2021-11-10 16:14:48 +0800150{
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800151 while (!(p_pt->signals_asserted & signal_mask))
Kevin Pengdef92de2021-11-10 16:14:48 +0800152 ;
153
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800154 return p_pt->signals_asserted & signal_mask;
Kevin Pengdef92de2021-11-10 16:14:48 +0800155}
156
Mingyang Sun09328bd2022-03-25 11:55:13 +0800157static void sfn_wake_up(struct partition_t *p_pt)
Kevin Pengdef92de2021-11-10 16:14:48 +0800158{
159 (void)p_pt;
Kevin Pengdef92de2021-11-10 16:14:48 +0800160}
161
Ken Liuf39d8eb2021-10-07 12:55:33 +0800162const struct backend_ops_t backend_instance = {
163 .comp_init_assuredly = sfn_comp_init_assuredly,
164 .system_run = sfn_system_run,
165 .messaging = sfn_messaging,
Kevin Pengdef92de2021-11-10 16:14:48 +0800166 .replying = sfn_replying,
167 .wait = sfn_wait,
168 .wake_up = sfn_wake_up,
Ken Liuf39d8eb2021-10-07 12:55:33 +0800169};