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