blob: 4b2f8a28557d2f0c567933e79c9ae005abb988b2 [file] [log] [blame]
Mingyang Sundeae45d2021-09-06 15:31:07 +08001/*
2 * Copyright (c) 2021, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stdint.h>
9#include "spm_ipc.h"
10#include "tfm_rpc.h"
11#include "tfm_spm_hal.h" /* To be checked */
12#include "ffm/backend.h"
13#include "load/partition_defs.h"
14#include "load/service_defs.h"
15#include "load/spm_load_api.h"
16#include "psa/error.h"
17
18/* Declare the global component list */
19struct partition_head_t partition_listhead;
20
21/*
22 * Send message and wake up the SP who is waiting on message queue, block the
23 * current thread and triggere scheduler.
24 */
25static psa_status_t ipc_messaging(struct service_t *service,
26 struct tfm_msg_body_t *msg)
27{
28 struct partition_t *p_owner = NULL;
29 psa_signal_t signal = 0;
30
31 if (!msg || !service || !service->p_ldinf || !service->partition) {
32 tfm_core_panic();
33 }
34
35 p_owner = service->partition;
36 signal = service->p_ldinf->signal;
37
38 /* Add message to partition message list tail */
39 BI_LIST_INSERT_BEFORE(&p_owner->msg_list, &msg->msg_node);
40
41 /* Messages put. Update signals */
42 p_owner->signals_asserted |= signal;
43
44 if (p_owner->signals_waiting & signal) {
45 thrd_wake_up(&p_owner->waitobj,
46 (p_owner->signals_asserted & p_owner->signals_waiting));
47 p_owner->signals_waiting &= ~signal;
48 }
49
50 /*
51 * If it is a NS request via RPC, it is unnecessary to block current
52 * thread.
53 */
54
55 if (!is_tfm_rpc_msg(msg)) {
56 thrd_wait_on(&msg->ack_evnt, CURRENT_THREAD);
57 }
58
59 return PSA_SUCCESS;
60}
61
62/* Parameters are treated as assuredly */
63static void ipc_comp_init_assuredly(struct partition_t *p_pt,
64 uint32_t service_setting)
65{
66 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
67 void *p_param = NULL;
68
69 p_pt->signals_allowed |= PSA_DOORBELL | service_setting;
70
71 THRD_SYNC_INIT(&p_pt->waitobj);
72 BI_LIST_INIT_NODE(&p_pt->msg_list);
73
74 THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
75 TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
76
77 if (p_pldi->pid == TFM_SP_NON_SECURE_ID) {
78 p_param = (void *)tfm_spm_hal_get_ns_entry_point();
79 }
80
81 thrd_start(&p_pt->thrd,
82 POSITION_TO_ENTRY(p_pldi->entry, thrd_fn_t), p_param,
83 LOAD_ALLOCED_STACK_ADDR(p_pldi),
84 LOAD_ALLOCED_STACK_ADDR(p_pldi) + p_pldi->stack_size);
85}
86
87static uint32_t ipc_system_run(void)
88{
89 return thrd_start_scheduler(&CURRENT_THREAD);
90}
91
92const struct backend_ops_t backend_instance = {
93 .comp_init_assuredly = ipc_comp_init_assuredly,
94 .system_run = ipc_system_run,
95 .messaging = ipc_messaging,
96};