1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "tee_drv_entry.h"
13 #include <stdio.h>
14 #include <inttypes.h>
15 #include <priorities.h>
16 #include <ipclib.h>
17 #include <spawn_init.h>
18 #include <tee_log.h>
19 #include "drv_dispatch.h"
20 #include "drv_thread.h"
21 #include "drv_operations.h"
22 #include "cs.h"
23 #ifdef CRYPTO_MGR_SERVER_ENABLE
24 #include "drv_random.h"
25 #include "crypto_manager.h"
26 #endif
27
28 static taskid_t g_drv_mgr_pid;
29 static const struct tee_driver_module *g_drv_func = NULL;
30 static uint32_t g_drv_index;
31
hunt_drv_mgr_pid(taskid_t * pid)32 static int32_t hunt_drv_mgr_pid(taskid_t *pid)
33 {
34 uint32_t ret = ipc_hunt_by_name("drvmgr", pid);
35 if (ret != 0) {
36 tloge("get drv mgr pid failed\n");
37 return -1;
38 }
39
40 return 0;
41 }
42
get_drv_mgr_pid(void)43 taskid_t get_drv_mgr_pid(void)
44 {
45 return g_drv_mgr_pid;
46 }
47
get_drv_func(void)48 const struct tee_driver_module *get_drv_func(void)
49 {
50 return g_drv_func;
51 }
52
get_drv_index(void)53 uint32_t get_drv_index(void)
54 {
55 return g_drv_index;
56 }
57
send_succ_msg_to_drvmgr(void)58 static int32_t send_succ_msg_to_drvmgr(void)
59 {
60 cref_t ch = -1;
61 int32_t ret = ipc_get_ch_from_path(DRV_SPAWN_SYNC_NAME, &ch);
62 if (ret != 0) {
63 tloge("something wrong, spawn succ get sync channel fail:0x%x\n", ret);
64 return -1;
65 }
66
67 struct spawn_sync_msg msg = { 0 };
68 msg.msg_id = PROCESS_INIT_SUCC;
69
70 ret = ipc_msg_notification(ch, &msg, sizeof(msg));
71 if (ret != 0) {
72 tloge("spawn succ notify fail:0x%x\n", ret);
73 return -1;
74 }
75
76 uint32_t ipc_ret = ipc_release_from_path(DRV_SPAWN_SYNC_NAME, ch);
77 if (ipc_ret != 0)
78 tloge("spawn succ release sync channel fail:0x%x\n", ipc_ret);
79
80 return 0;
81 }
82
param_check(const struct tee_driver_module * drv_func,const char * drv_name,const struct env_param * param)83 static int32_t param_check(const struct tee_driver_module *drv_func, const char *drv_name,
84 const struct env_param *param)
85 {
86 if (drv_func == NULL || drv_name == NULL || param == NULL) {
87 tloge("invalid drv param\n");
88 return -1;
89 }
90
91 if (param->thread_limit == 0) {
92 tloge("invalid thread limit\n");
93 return -1;
94 }
95
96 if (drv_func->open == NULL || drv_func->ioctl == NULL || drv_func->close == NULL) {
97 tloge("invalid drv func\n");
98 return -1;
99 }
100
101 return 0;
102 }
103
call_drv_init_func(const char * drv_name,const struct tee_driver_module * drv_func)104 static int32_t call_drv_init_func(const char *drv_name, const struct tee_driver_module *drv_func)
105 {
106 if (drv_func->init != NULL) {
107 init_func func = drv_func->init;
108 int32_t ret = func();
109 if (ret != 0) {
110 tloge("drv:%s init fail ret:0x%x\n", drv_name, ret);
111 return -1;
112 }
113 }
114
115 return 0;
116 }
117
118 __attribute__((visibility("default"))) \
tee_drv_entry(const struct tee_driver_module * drv_func,const char * drv_name,cref_t ch,const struct env_param * param)119 void tee_drv_entry(const struct tee_driver_module *drv_func, const char *drv_name,
120 cref_t ch, const struct env_param *param)
121 {
122 static dispatch_fn_t dispatch_fns[] = {
123 [0] = driver_dispatch,
124 };
125
126 int32_t ret = param_check(drv_func, drv_name, param);
127 if (ret != 0)
128 return;
129
130 tlogi("%s begin thread_limit:%u drv_index:%u\n", drv_name, param->thread_limit, param->drv_index);
131
132 g_drv_func = drv_func;
133 g_drv_index = param->drv_index;
134
135 ret = hunt_drv_mgr_pid(&g_drv_mgr_pid);
136 if (ret != 0)
137 return;
138
139 ret = set_priority(param->priority);
140 if (ret < 0) {
141 tloge("failed to set drv server priority\n");
142 return;
143 }
144
145 ret = call_drv_init_func(drv_name, drv_func);
146 if (ret != 0)
147 return;
148
149 ret = multi_drv_framwork_init(param->thread_limit - 1, param->stack_size, ch);
150 if (ret != 0) {
151 tloge("multi drv framework init fail\n");
152 return;
153 }
154
155 ret = send_succ_msg_to_drvmgr();
156 if (ret != 0)
157 return;
158
159 tlogi("%s start server loop\n", drv_name);
160 cs_server_loop(ch, dispatch_fns, ARRAY_SIZE(dispatch_fns), NULL, NULL);
161 }
162