powerpc/mm: Avoid calling arch_enter/leave_lazy_mmu() in set_ptes
[platform/kernel/linux-starfive.git] / arch / loongarch / include / asm / elf.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4  */
5 #ifndef _ASM_ELF_H
6 #define _ASM_ELF_H
7
8 #include <linux/auxvec.h>
9 #include <linux/fs.h>
10 #include <uapi/linux/elf.h>
11
12 #include <asm/current.h>
13 #include <asm/vdso.h>
14
15 /* The ABI of a file. */
16 #define EF_LOONGARCH_ABI_LP64_SOFT_FLOAT        0x1
17 #define EF_LOONGARCH_ABI_LP64_SINGLE_FLOAT      0x2
18 #define EF_LOONGARCH_ABI_LP64_DOUBLE_FLOAT      0x3
19
20 #define EF_LOONGARCH_ABI_ILP32_SOFT_FLOAT       0x5
21 #define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT     0x6
22 #define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT     0x7
23
24 /* LoongArch relocation types used by the dynamic linker */
25 #define R_LARCH_NONE                            0
26 #define R_LARCH_32                              1
27 #define R_LARCH_64                              2
28 #define R_LARCH_RELATIVE                        3
29 #define R_LARCH_COPY                            4
30 #define R_LARCH_JUMP_SLOT                       5
31 #define R_LARCH_TLS_DTPMOD32                    6
32 #define R_LARCH_TLS_DTPMOD64                    7
33 #define R_LARCH_TLS_DTPREL32                    8
34 #define R_LARCH_TLS_DTPREL64                    9
35 #define R_LARCH_TLS_TPREL32                     10
36 #define R_LARCH_TLS_TPREL64                     11
37 #define R_LARCH_IRELATIVE                       12
38 #define R_LARCH_MARK_LA                         20
39 #define R_LARCH_MARK_PCREL                      21
40 #define R_LARCH_SOP_PUSH_PCREL                  22
41 #define R_LARCH_SOP_PUSH_ABSOLUTE               23
42 #define R_LARCH_SOP_PUSH_DUP                    24
43 #define R_LARCH_SOP_PUSH_GPREL                  25
44 #define R_LARCH_SOP_PUSH_TLS_TPREL              26
45 #define R_LARCH_SOP_PUSH_TLS_GOT                27
46 #define R_LARCH_SOP_PUSH_TLS_GD                 28
47 #define R_LARCH_SOP_PUSH_PLT_PCREL              29
48 #define R_LARCH_SOP_ASSERT                      30
49 #define R_LARCH_SOP_NOT                         31
50 #define R_LARCH_SOP_SUB                         32
51 #define R_LARCH_SOP_SL                          33
52 #define R_LARCH_SOP_SR                          34
53 #define R_LARCH_SOP_ADD                         35
54 #define R_LARCH_SOP_AND                         36
55 #define R_LARCH_SOP_IF_ELSE                     37
56 #define R_LARCH_SOP_POP_32_S_10_5               38
57 #define R_LARCH_SOP_POP_32_U_10_12              39
58 #define R_LARCH_SOP_POP_32_S_10_12              40
59 #define R_LARCH_SOP_POP_32_S_10_16              41
60 #define R_LARCH_SOP_POP_32_S_10_16_S2           42
61 #define R_LARCH_SOP_POP_32_S_5_20               43
62 #define R_LARCH_SOP_POP_32_S_0_5_10_16_S2       44
63 #define R_LARCH_SOP_POP_32_S_0_10_10_16_S2      45
64 #define R_LARCH_SOP_POP_32_U                    46
65 #define R_LARCH_ADD8                            47
66 #define R_LARCH_ADD16                           48
67 #define R_LARCH_ADD24                           49
68 #define R_LARCH_ADD32                           50
69 #define R_LARCH_ADD64                           51
70 #define R_LARCH_SUB8                            52
71 #define R_LARCH_SUB16                           53
72 #define R_LARCH_SUB24                           54
73 #define R_LARCH_SUB32                           55
74 #define R_LARCH_SUB64                           56
75 #define R_LARCH_GNU_VTINHERIT                   57
76 #define R_LARCH_GNU_VTENTRY                     58
77 #define R_LARCH_B16                             64
78 #define R_LARCH_B21                             65
79 #define R_LARCH_B26                             66
80 #define R_LARCH_ABS_HI20                        67
81 #define R_LARCH_ABS_LO12                        68
82 #define R_LARCH_ABS64_LO20                      69
83 #define R_LARCH_ABS64_HI12                      70
84 #define R_LARCH_PCALA_HI20                      71
85 #define R_LARCH_PCALA_LO12                      72
86 #define R_LARCH_PCALA64_LO20                    73
87 #define R_LARCH_PCALA64_HI12                    74
88 #define R_LARCH_GOT_PC_HI20                     75
89 #define R_LARCH_GOT_PC_LO12                     76
90 #define R_LARCH_GOT64_PC_LO20                   77
91 #define R_LARCH_GOT64_PC_HI12                   78
92 #define R_LARCH_GOT_HI20                        79
93 #define R_LARCH_GOT_LO12                        80
94 #define R_LARCH_GOT64_LO20                      81
95 #define R_LARCH_GOT64_HI12                      82
96 #define R_LARCH_TLS_LE_HI20                     83
97 #define R_LARCH_TLS_LE_LO12                     84
98 #define R_LARCH_TLS_LE64_LO20                   85
99 #define R_LARCH_TLS_LE64_HI12                   86
100 #define R_LARCH_TLS_IE_PC_HI20                  87
101 #define R_LARCH_TLS_IE_PC_LO12                  88
102 #define R_LARCH_TLS_IE64_PC_LO20                89
103 #define R_LARCH_TLS_IE64_PC_HI12                90
104 #define R_LARCH_TLS_IE_HI20                     91
105 #define R_LARCH_TLS_IE_LO12                     92
106 #define R_LARCH_TLS_IE64_LO20                   93
107 #define R_LARCH_TLS_IE64_HI12                   94
108 #define R_LARCH_TLS_LD_PC_HI20                  95
109 #define R_LARCH_TLS_LD_HI20                     96
110 #define R_LARCH_TLS_GD_PC_HI20                  97
111 #define R_LARCH_TLS_GD_HI20                     98
112 #define R_LARCH_32_PCREL                        99
113 #define R_LARCH_RELAX                           100
114
115 #ifndef ELF_ARCH
116
117 /* ELF register definitions */
118
119 /*
120  * General purpose have the following registers:
121  *      Register        Number
122  *      GPRs            32
123  *      ORIG_A0         1
124  *      ERA             1
125  *      BADVADDR        1
126  *      CRMD            1
127  *      PRMD            1
128  *      EUEN            1
129  *      ECFG            1
130  *      ESTAT           1
131  *      Reserved        5
132  */
133 #define ELF_NGREG       45
134
135 /*
136  * Floating point have the following registers:
137  *      Register        Number
138  *      FPR             32
139  *      FCC             1
140  *      FCSR            1
141  */
142 #define ELF_NFPREG      34
143
144 typedef unsigned long elf_greg_t;
145 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
146
147 typedef double elf_fpreg_t;
148 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
149
150 void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs);
151
152 #ifdef CONFIG_32BIT
153 /*
154  * This is used to ensure we don't load something for the wrong architecture.
155  */
156 #define elf_check_arch elf32_check_arch
157
158 /*
159  * These are used to set parameters in the core dumps.
160  */
161 #define ELF_CLASS       ELFCLASS32
162
163 #define ELF_CORE_COPY_REGS(dest, regs) \
164         loongarch_dump_regs32((u32 *)&(dest), (regs));
165
166 #endif /* CONFIG_32BIT */
167
168 #ifdef CONFIG_64BIT
169 /*
170  * This is used to ensure we don't load something for the wrong architecture.
171  */
172 #define elf_check_arch elf64_check_arch
173
174 /*
175  * These are used to set parameters in the core dumps.
176  */
177 #define ELF_CLASS       ELFCLASS64
178
179 #define ELF_CORE_COPY_REGS(dest, regs) \
180         loongarch_dump_regs64((u64 *)&(dest), (regs));
181
182 #endif /* CONFIG_64BIT */
183
184 /*
185  * These are used to set parameters in the core dumps.
186  */
187 #define ELF_DATA        ELFDATA2LSB
188 #define ELF_ARCH        EM_LOONGARCH
189
190 #endif /* !defined(ELF_ARCH) */
191
192 #define loongarch_elf_check_machine(x) ((x)->e_machine == EM_LOONGARCH)
193
194 #define vmcore_elf32_check_arch loongarch_elf_check_machine
195 #define vmcore_elf64_check_arch loongarch_elf_check_machine
196
197 /*
198  * Return non-zero if HDR identifies an 32bit ELF binary.
199  */
200 #define elf32_check_arch(hdr)                                           \
201 ({                                                                      \
202         int __res = 1;                                                  \
203         struct elfhdr *__h = (hdr);                                     \
204                                                                         \
205         if (!loongarch_elf_check_machine(__h))                          \
206                 __res = 0;                                              \
207         if (__h->e_ident[EI_CLASS] != ELFCLASS32)                       \
208                 __res = 0;                                              \
209                                                                         \
210         __res;                                                          \
211 })
212
213 /*
214  * Return non-zero if HDR identifies an 64bit ELF binary.
215  */
216 #define elf64_check_arch(hdr)                                           \
217 ({                                                                      \
218         int __res = 1;                                                  \
219         struct elfhdr *__h = (hdr);                                     \
220                                                                         \
221         if (!loongarch_elf_check_machine(__h))                          \
222                 __res = 0;                                              \
223         if (__h->e_ident[EI_CLASS] != ELFCLASS64)                       \
224                 __res = 0;                                              \
225                                                                         \
226         __res;                                                          \
227 })
228
229 #ifdef CONFIG_32BIT
230
231 #define SET_PERSONALITY2(ex, state)                                     \
232 do {                                                                    \
233         current->thread.vdso = &vdso_info;                              \
234                                                                         \
235         loongarch_set_personality_fcsr(state);                          \
236                                                                         \
237         if (personality(current->personality) != PER_LINUX)             \
238                 set_personality(PER_LINUX);                             \
239 } while (0)
240
241 #endif /* CONFIG_32BIT */
242
243 #ifdef CONFIG_64BIT
244
245 #define SET_PERSONALITY2(ex, state)                                     \
246 do {                                                                    \
247         unsigned int p;                                                 \
248                                                                         \
249         clear_thread_flag(TIF_32BIT_REGS);                              \
250         clear_thread_flag(TIF_32BIT_ADDR);                              \
251                                                                         \
252         current->thread.vdso = &vdso_info;                              \
253         loongarch_set_personality_fcsr(state);                          \
254                                                                         \
255         p = personality(current->personality);                          \
256         if (p != PER_LINUX32 && p != PER_LINUX)                         \
257                 set_personality(PER_LINUX);                             \
258 } while (0)
259
260 #endif /* CONFIG_64BIT */
261
262 #define CORE_DUMP_USE_REGSET
263 #define ELF_EXEC_PAGESIZE       PAGE_SIZE
264
265 /*
266  * This yields a mask that user programs can use to figure out what
267  * instruction set this cpu supports. This could be done in userspace,
268  * but it's not easy, and we've already done it here.
269  */
270
271 #define ELF_HWCAP       (elf_hwcap)
272 extern unsigned int elf_hwcap;
273 #include <asm/hwcap.h>
274
275 /*
276  * This yields a string that ld.so will use to load implementation
277  * specific libraries for optimization.  This is more specific in
278  * intent than poking at uname or /proc/cpuinfo.
279  */
280
281 #define ELF_PLATFORM  __elf_platform
282 extern const char *__elf_platform;
283
284 #define ELF_PLAT_INIT(_r, load_addr)    do { \
285         _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0;      \
286         _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0;      \
287         _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0;   \
288         _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0;  \
289         _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0;  \
290         _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0;  \
291         _r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0;  \
292         _r->regs[29] = _r->regs[30] = _r->regs[31] = 0;                 \
293 } while (0)
294
295 /*
296  * This is the location that an ET_DYN program is loaded if exec'ed. Typical
297  * use of this is to invoke "./ld.so someprog" to test out a new version of
298  * the loader. We need to make sure that it is out of the way of the program
299  * that it will "exec", and that there is sufficient room for the brk.
300  */
301
302 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
303
304 /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
305 #define ARCH_DLINFO                                                     \
306 do {                                                                    \
307         NEW_AUX_ENT(AT_SYSINFO_EHDR,                                    \
308                     (unsigned long)current->mm->context.vdso);          \
309 } while (0)
310
311 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
312 struct linux_binprm;
313 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
314                                        int uses_interp);
315
316 struct arch_elf_state {
317         int fp_abi;
318         int interp_fp_abi;
319 };
320
321 #define LOONGARCH_ABI_FP_ANY    (0)
322
323 #define INIT_ARCH_ELF_STATE {                   \
324         .fp_abi = LOONGARCH_ABI_FP_ANY,         \
325         .interp_fp_abi = LOONGARCH_ABI_FP_ANY,  \
326 }
327
328 extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
329                             bool is_interp, struct arch_elf_state *state);
330
331 extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr,
332                           struct arch_elf_state *state);
333
334 extern void loongarch_set_personality_fcsr(struct arch_elf_state *state);
335
336 #endif /* _ASM_ELF_H */