1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6 #include <app.h>
7 #include <assert.h>
8 #include <dev_assign_app.h>
9 #include <dev_assign_structs.h>
10
11 /* Add declaration to prevent static checker error */
12 void dev_assign_app_get_bss(uintptr_t *bss_pa, size_t *bss_size);
13
dev_assign_app_get_bss(uintptr_t * bss_pa,size_t * bss_size)14 void dev_assign_app_get_bss(uintptr_t *bss_pa, size_t *bss_size)
15 {
16 static char dev_assign_app_bss[GRANULE_SIZE * 3U] __aligned(GRANULE_SIZE);
17 *bss_pa = (uintptr_t)dev_assign_app_bss;
18 *bss_size = sizeof(dev_assign_app_bss);
19 }
20
dev_assign_app_init(struct app_data_cfg * app_data,uintptr_t granule_pas[],size_t granule_pa_count,void * granule_va_start,struct dev_assign_params * params)21 int dev_assign_app_init(struct app_data_cfg *app_data, uintptr_t granule_pas[],
22 size_t granule_pa_count, void *granule_va_start,
23 struct dev_assign_params *params)
24 {
25 int rc;
26 struct dev_assign_params *shared;
27
28
29 rc = app_init_data(app_data,
30 RMM_DEV_ASSIGN_APP_ID,
31 granule_pas,
32 granule_pa_count,
33 granule_va_start);
34 if (rc != 0) {
35 return DEV_ASSIGN_STATUS_ERROR;
36 }
37
38 app_map_shared_page(app_data);
39 assert(app_data->el2_shared_page != NULL);
40 shared = app_data->el2_shared_page;
41 (void)memcpy(shared, params, sizeof(*shared));
42
43 rc = (int)app_run(app_data, DEVICE_ASSIGN_APP_FUNC_ID_INIT,
44 app_data->heap_size, 0, 0, 0);
45 assert(app_data->exit_flag == APP_EXIT_SVC_EXIT_FLAG);
46 app_unmap_shared_page(app_data);
47
48 return rc;
49 }
50
dev_assign_dev_communicate(struct app_data_cfg * app_data,struct rmi_dev_comm_enter * comm_enter_args,struct rmi_dev_comm_exit * comm_exit_args,struct dev_obj_digest * comm_digest_ptr,int dev_cmd)51 int dev_assign_dev_communicate(struct app_data_cfg *app_data,
52 struct rmi_dev_comm_enter *comm_enter_args,
53 struct rmi_dev_comm_exit *comm_exit_args,
54 struct dev_obj_digest *comm_digest_ptr,
55 int dev_cmd)
56 {
57 int rc;
58 struct rmi_dev_comm_enter *shared;
59 struct dev_comm_exit_shared *shared_ret;
60
61 assert((dev_cmd == DEVICE_ASSIGN_APP_FUNC_ID_RESUME) ||
62 (dev_cmd == DEVICE_ASSIGN_APP_FUNC_ID_CONNECT_INIT) ||
63 (dev_cmd == DEVICE_ASSIGN_APP_FUNC_ID_STOP_CONNECTION) ||
64 (dev_cmd == DEVICE_ASSIGN_APP_FUNC_ID_SECURE_SESSION) ||
65 (dev_cmd == DEVICE_ASSIGN_APP_FUNC_ID_GET_MEASUREMENTS));
66
67 app_map_shared_page(app_data);
68 assert(app_data->el2_shared_page != NULL);
69 shared = app_data->el2_shared_page;
70 *shared = *comm_enter_args;
71
72 if (dev_cmd != DEVICE_ASSIGN_APP_FUNC_ID_RESUME) {
73 rc = (int)app_run(app_data, (unsigned long)dev_cmd,
74 0, 0, 0, 0);
75 } else {
76 rc = (int)app_resume(app_data);
77 }
78
79 if (app_data->exit_flag == APP_EXIT_SVC_YIELD_FLAG) {
80 rc = DEV_ASSIGN_STATUS_COMM_BLOCKED;
81 }
82
83 assert(app_data->el2_shared_page != NULL);
84 shared_ret = app_data->el2_shared_page;
85
86 *comm_exit_args = shared_ret->rmi_dev_comm_exit;
87
88 if (shared_ret->cached_digest.len != 0U) {
89 if (comm_digest_ptr == NULL) {
90 app_unmap_shared_page(app_data);
91 return DEV_ASSIGN_STATUS_ERROR;
92 }
93 (void)memcpy(comm_digest_ptr->value, shared_ret->cached_digest.value,
94 shared_ret->cached_digest.len);
95 comm_digest_ptr->len = shared_ret->cached_digest.len;
96 }
97
98 app_unmap_shared_page(app_data);
99
100 return rc;
101 }
102
dev_assign_abort_app_operation(struct app_data_cfg * app_data)103 int dev_assign_abort_app_operation(struct app_data_cfg *app_data)
104 {
105 unsigned long rc __unused;
106 struct rmi_dev_comm_enter *shared;
107
108 /*
109 * The app copies the enter_args from the shared page. So set the status
110 * on the shared page to error, which will result app return
111 * immediately, unwinding its stack, and returning error.
112 */
113 app_map_shared_page(app_data);
114 assert(app_data->el2_shared_page != NULL);
115 shared = app_data->el2_shared_page;
116 shared->status = (unsigned char)RMI_DEV_COMM_ENTER_STATUS_ERROR;
117 rc = app_resume(app_data);
118 assert(rc == (unsigned long)DEV_ASSIGN_STATUS_ERROR);
119 app_unmap_shared_page(app_data);
120
121 return DEV_ASSIGN_STATUS_SUCCESS;
122 }
123
dev_assign_set_public_key(struct app_data_cfg * app_data,struct rmi_public_key_params * pubkey_params)124 int dev_assign_set_public_key(struct app_data_cfg *app_data,
125 struct rmi_public_key_params *pubkey_params)
126 {
127 int rc;
128
129 app_map_shared_page(app_data);
130 assert(app_data->el2_shared_page != NULL);
131 (void)memcpy(app_data->el2_shared_page, (void *)pubkey_params,
132 sizeof(*pubkey_params));
133 rc = (int)app_run(app_data, DEVICE_ASSIGN_APP_FUNC_SET_PUBLIC_KEY,
134 pubkey_params->algo, 0, 0, 0);
135 app_unmap_shared_page(app_data);
136 return rc;
137 }
138