1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2019, Linaro Limited
4  * Copyright (c) 2020, Arm Limited
5  */
6 
7 #ifndef __LDELF_H
8 #define __LDELF_H
9 
10 #ifndef __ASSEMBLER__
11 #include <types_ext.h>
12 #include <tee_api_types.h>
13 #include <user_ta_header.h>
14 
15 /* Size of stack for TEE Core to allocate */
16 #define LDELF_STACK_SIZE	(4096 * 2)
17 
18 /*
19  * struct ldelf_arg - argument for ldelf
20  * @uuid:	  [in] UUID of TA to load
21  * @is_32bit:	  [out] 1 if a 32bit TA or 0 if a 64bit TA
22  * @flags:	  [out] Flags field of TA header
23  * @entry_func:	  [out] TA entry function
24  * @stack_ptr:	  [out] TA stack pointer
25  * @dump_entry:	  [out] Dump TA mappings and stack trace
26  * @ftrace_entry: [out] Dump TA mappings and ftrace buffer
27  * @fbuf:         [out] ftrace buffer pointer
28  * @dl_entry:     [out] Dynamic linking interface (for libdl)
29  */
30 struct ldelf_arg {
31 	TEE_UUID uuid;
32 	uint32_t is_32bit;
33 	uint32_t flags;
34 	uint64_t entry_func;
35 	uint64_t stack_ptr;
36 	uint64_t dump_entry;
37 	uint64_t ftrace_entry;
38 	uint64_t dl_entry;
39 	struct ftrace_buf *fbuf;
40 };
41 
42 #define DUMP_MAP_READ	BIT(0)
43 #define DUMP_MAP_WRITE	BIT(1)
44 #define DUMP_MAP_EXEC	BIT(2)
45 #define DUMP_MAP_SECURE	BIT(3)
46 #define DUMP_MAP_EPHEM	BIT(4)
47 #define DUMP_MAP_LDELF	BIT(7)
48 
49 /*
50  * struct dump_entry_arg - argument for ldelf_arg::dump_entry()
51  */
52 struct dump_entry_arg {
53 	union {
54 		struct {
55 			uint32_t regs[16];
56 		} arm32;
57 		struct {
58 			uint64_t fp;
59 			uint64_t sp;
60 			uint64_t pc;
61 		} arm64;
62 	};
63 	bool is_arm32;
64 	size_t num_maps;
65 	struct dump_map {
66 		vaddr_t va;
67 		paddr_t pa;
68 		size_t sz;
69 		uint32_t flags;
70 	} maps[];
71 };
72 
73 /*
74  * struct dl_entry_arg - argument for ldelf_arg::dl_entry()
75  */
76 struct dl_entry_arg {
77 	uint32_t cmd;
78 	TEE_Result ret;
79 	union {
80 		struct {
81 			TEE_UUID uuid;	/* in */
82 			uint32_t flags;	/* in */
83 		} dlopen;
84 		struct {
85 			TEE_UUID uuid;	/* in */
86 			vaddr_t val;	/* out */
87 			char symbol[];	/* in */
88 		} dlsym;
89 	};
90 };
91 
92 /*
93  * Values for dl_entry_arg::cmd
94  */
95 #define LDELF_DL_ENTRY_DLOPEN	0
96 #define LDELF_DL_ENTRY_DLSYM	1
97 
98 /*
99  * Values for dl_entry_arg::dlopen::flags
100  */
101 #define RTLD_NOW	2
102 #define RTLD_GLOBAL	0x100
103 #define RTLD_NODELETE	0x1000
104 
105 #define LDELF_MAP_FLAG_SHAREABLE	BIT32(0)
106 #define LDELF_MAP_FLAG_WRITEABLE	BIT32(1)
107 #define LDELF_MAP_FLAG_EXECUTABLE	BIT32(2)
108 #define LDELF_MAP_FLAG_BTI		BIT32(3)
109 
110 #endif /*!__ASSEMBLER__*/
111 
112 #define LDELF_RETURN		0
113 #define LDELF_LOG		1
114 #define LDELF_PANIC		2
115 #define LDELF_MAP_ZI		3
116 #define LDELF_UNMAP		4
117 #define LDELF_OPEN_BIN		5
118 #define LDELF_CLOSE_BIN		6
119 #define LDELF_MAP_BIN		7
120 #define LDELF_CP_FROM_BIN	8
121 #define LDELF_SET_PROT		9
122 #define LDELF_REMAP		10
123 #define LDELF_GEN_RND_NUM	11
124 
125 #define LDELF_SCN_MAX		11
126 
127 /*
128  * ldelf is loaded into memory by TEE Core. BSS is initialized and a
129  * stack is allocated and supplied in SP register. A struct ldelf_arg
130  * is placed in the stack and a pointer to the struct is provided in
131  * r0/x0.
132  *
133  * ldelf relocates itself to the address where it is loaded before the main
134  * C routine is called.
135  *
136  * In the main C routine the TA is loaded using the PTA System interface.
137  */
138 
139 #endif /*__LDELF_H*/
140