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