1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2023 ProvenRun SAS
4 */
5
6 #include <drivers/versal_pm.h>
7 #include <kernel/pseudo_ta.h>
8 #include <malloc.h>
9 #include <mm/core_memprot.h>
10 #include <platform_config.h>
11 #include <pta_versal_loader.h>
12 #include <string.h>
13 #include <tee/cache.h>
14
15 #define PTA_NAME "versal-loader.pta"
16
pta_versal_loader_subsys(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])17 static TEE_Result pta_versal_loader_subsys(uint32_t param_types,
18 TEE_Param params[TEE_NUM_PARAMS])
19 {
20 TEE_Result ret = TEE_SUCCESS;
21 uint8_t *buf = NULL;
22 size_t bufsize = 0;
23 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
24 TEE_PARAM_TYPE_NONE,
25 TEE_PARAM_TYPE_NONE,
26 TEE_PARAM_TYPE_NONE);
27
28 if (param_types != exp_param_types)
29 return TEE_ERROR_BAD_PARAMETERS;
30
31 if (!params[0].memref.size)
32 return TEE_ERROR_BAD_PARAMETERS;
33
34 if (ROUNDUP_OVERFLOW(params[0].memref.size, CACHELINE_LEN, &bufsize))
35 return TEE_ERROR_BAD_PARAMETERS;
36
37 buf = memalign(CACHELINE_LEN, bufsize);
38 if (!buf)
39 return TEE_ERROR_OUT_OF_MEMORY;
40
41 memset(buf, 0, bufsize);
42 memcpy(buf, params[0].memref.buffer, params[0].memref.size);
43 cache_operation(TEE_CACHEFLUSH, buf, bufsize);
44
45 ret = versal_write_fpga(virt_to_phys(buf));
46
47 free(buf);
48
49 return ret;
50 }
51
invoke_command(void * sess_ctx __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])52 static TEE_Result invoke_command(void *sess_ctx __unused,
53 uint32_t cmd_id,
54 uint32_t param_types,
55 TEE_Param params[TEE_NUM_PARAMS])
56 {
57 switch (cmd_id) {
58 case PTA_VERSAL_LOADER_SUBSYS:
59 return pta_versal_loader_subsys(param_types, params);
60 default:
61 return TEE_ERROR_NOT_SUPPORTED;
62 }
63 }
64
65 pseudo_ta_register(.uuid = PTA_VERSAL_LOADER_UUID, .name = PTA_NAME,
66 .flags = PTA_DEFAULT_FLAGS,
67 .invoke_command_entry_point = invoke_command);
68