arch_helpers.h 19.1 KB
Newer Older
1
/*
2
 * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
 */

7
8
#ifndef ARCH_HELPERS_H
#define ARCH_HELPERS_H
9

10
#include <cdefs.h>
11
#include <stdbool.h>
12
#include <stdint.h>
13
#include <string.h>
14

15
16
#include <arch.h>

17
18
19
20
21
/**********************************************************************
 * Macros which create inline functions to read or write CPU system
 * registers
 *********************************************************************/

22
#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name)		\
23
static inline u_register_t read_ ## _name(void)			\
24
{								\
25
	u_register_t v;						\
26
27
	__asm__ volatile ("mrs %0, " #_reg_name : "=r" (v));	\
	return v;						\
28
29
}

30
#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)			\
31
static inline void write_ ## _name(u_register_t v)			\
32
33
{									\
	__asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v));	\
34
35
}

Roberto Vargas's avatar
Roberto Vargas committed
36
37
#define SYSREG_WRITE_CONST(reg_name, v)				\
	__asm__ volatile ("msr " #reg_name ", %0" : : "i" (v))
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

/* Define read function for system register */
#define DEFINE_SYSREG_READ_FUNC(_name) 			\
	_DEFINE_SYSREG_READ_FUNC(_name, _name)

/* Define read & write function for system register */
#define DEFINE_SYSREG_RW_FUNCS(_name)			\
	_DEFINE_SYSREG_READ_FUNC(_name, _name)		\
	_DEFINE_SYSREG_WRITE_FUNC(_name, _name)

/* Define read & write function for renamed system register */
#define DEFINE_RENAME_SYSREG_RW_FUNCS(_name, _reg_name)	\
	_DEFINE_SYSREG_READ_FUNC(_name, _reg_name)	\
	_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)

53
54
55
56
57
58
59
60
/* Define read function for renamed system register */
#define DEFINE_RENAME_SYSREG_READ_FUNC(_name, _reg_name)	\
	_DEFINE_SYSREG_READ_FUNC(_name, _reg_name)

/* Define write function for renamed system register */
#define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name)	\
	_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)

61
62
63
64
65
66
/**********************************************************************
 * Macros to create inline functions for system instructions
 *********************************************************************/

/* Define function for simple system instruction */
#define DEFINE_SYSOP_FUNC(_op)				\
67
static inline void _op(void)				\
68
69
70
71
{							\
	__asm__ (#_op);					\
}

72
73
74
75
76
77
78
/* Define function for system instruction with register parameter */
#define DEFINE_SYSOP_PARAM_FUNC(_op)			\
static inline void _op(uint64_t v)			\
{							\
	 __asm__ (#_op "  %0" : : "r" (v));		\
}

79
80
/* Define function for system instruction with type specifier */
#define DEFINE_SYSOP_TYPE_FUNC(_op, _type)		\
81
static inline void _op ## _type(void)			\
82
{							\
83
	__asm__ (#_op " " #_type : : : "memory");			\
84
85
86
87
88
89
90
91
}

/* Define function for system instruction with register parameter */
#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type)	\
static inline void _op ## _type(uint64_t v)		\
{							\
	 __asm__ (#_op " " #_type ", %0" : : "r" (v));	\
}
92
93
94
95

/*******************************************************************************
 * TLB maintenance accessor prototypes
 ******************************************************************************/
96

97
#if ERRATA_A57_813419 || ERRATA_A76_1286807
98
99
/*
 * Define function for TLBI instruction with type specifier that implements
100
101
 * the workaround for errata 813419 of Cortex-A57 or errata 1286807 of
 * Cortex-A76.
102
 */
103
#define DEFINE_TLBIOP_ERRATA_TYPE_FUNC(_type)\
104
105
106
107
108
109
110
111
112
static inline void tlbi ## _type(void)			\
{							\
	__asm__("tlbi " #_type "\n"			\
		"dsb ish\n"				\
		"tlbi " #_type);			\
}

/*
 * Define function for TLBI instruction with register parameter that implements
113
114
 * the workaround for errata 813419 of Cortex-A57 or errata 1286807 of
 * Cortex-A76.
115
 */
116
#define DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(_type)	\
117
118
119
120
121
122
123
124
static inline void tlbi ## _type(uint64_t v)			\
{								\
	__asm__("tlbi " #_type ", %0\n"				\
		"dsb ish\n"					\
		"tlbi " #_type ", %0" : : "r" (v));		\
}
#endif /* ERRATA_A57_813419 */

125
126
127
128
129
130
131
132
133
134
135
136
#if ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319
/*
 * Define function for DC instruction with register parameter that enables
 * the workaround for errata 819472, 824069 and 827319 of Cortex-A53.
 */
#define DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(_name, _type)	\
static inline void dc ## _name(uint64_t v)			\
{								\
	__asm__("dc " #_type ", %0" : : "r" (v));		\
}
#endif /* ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319 */

137
#if ERRATA_A57_813419
138
139
140
141
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1)
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is)
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2)
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is)
142
143
144
145
146
147
148
149
150
151
152
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3)
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3is)
DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1)
#elif ERRATA_A76_1286807
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle1)
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle1is)
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle2)
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle2is)
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3)
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3is)
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(vmalle1)
153
#else
154
155
156
157
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1)
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is)
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2)
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is)
158
159
160
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3)
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3is)
DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1)
161
#endif
162

163
#if ERRATA_A57_813419
164
165
166
167
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaae1is)
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaale1is)
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae2is)
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale2is)
168
169
170
171
172
173
174
175
176
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vae3is)
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vale3is)
#elif ERRATA_A76_1286807
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vaae1is)
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vaale1is)
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vae2is)
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vale2is)
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vae3is)
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vale3is)
177
#else
178
179
180
181
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaae1is)
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaale1is)
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae2is)
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale2is)
182
183
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae3is)
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale3is)
184
#endif
185

186
187
188
/*******************************************************************************
 * Cache maintenance accessor prototypes
 ******************************************************************************/
189
190
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, isw)
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cisw)
191
192
193
#if ERRATA_A53_827319
DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(csw, cisw)
#else
194
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, csw)
195
196
197
198
#endif
#if ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319
DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(cvac, civac)
#else
199
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvac)
200
#endif
201
202
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, ivac)
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac)
203
204
205
#if ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319
DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(cvau, civac)
#else
206
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau)
207
#endif
208
209
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva)

210
211
212
213
214
215
216
/*******************************************************************************
 * Address translation accessor prototypes
 ******************************************************************************/
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w)
217
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r)
218
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r)
219
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r)
220

221
222
223
224
225
/*******************************************************************************
 * Strip Pointer Authentication Code
 ******************************************************************************/
DEFINE_SYSOP_PARAM_FUNC(xpaci)

226
227
228
void flush_dcache_range(uintptr_t addr, size_t size);
void clean_dcache_range(uintptr_t addr, size_t size);
void inv_dcache_range(uintptr_t addr, size_t size);
229
bool is_dcache_enabled(void);
230
231
232

void dcsw_op_louis(u_register_t op_type);
void dcsw_op_all(u_register_t op_type);
233

234
void disable_mmu_el1(void);
235
void disable_mmu_el3(void);
236
void disable_mmu_icache_el1(void);
237
void disable_mmu_icache_el3(void);
238

239
240
241
/*******************************************************************************
 * Misc. accessor prototypes
 ******************************************************************************/
242

Roberto Vargas's avatar
Roberto Vargas committed
243
244
#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
245

246
DEFINE_SYSREG_RW_FUNCS(par_el1)
247
DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
248
DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1)
249
DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
250
DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
251
DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1)
252
DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
253
DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
254
DEFINE_SYSREG_READ_FUNC(CurrentEl)
255
DEFINE_SYSREG_READ_FUNC(ctr_el0)
256
257
258
259
260
261
262
DEFINE_SYSREG_RW_FUNCS(daif)
DEFINE_SYSREG_RW_FUNCS(spsr_el1)
DEFINE_SYSREG_RW_FUNCS(spsr_el2)
DEFINE_SYSREG_RW_FUNCS(spsr_el3)
DEFINE_SYSREG_RW_FUNCS(elr_el1)
DEFINE_SYSREG_RW_FUNCS(elr_el2)
DEFINE_SYSREG_RW_FUNCS(elr_el3)
263
264
265
DEFINE_SYSREG_RW_FUNCS(mdccsr_el0)
DEFINE_SYSREG_RW_FUNCS(dbgdtrrx_el0)
DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0)
266
267
268
269
270

DEFINE_SYSOP_FUNC(wfi)
DEFINE_SYSOP_FUNC(wfe)
DEFINE_SYSOP_FUNC(sev)
DEFINE_SYSOP_TYPE_FUNC(dsb, sy)
271
DEFINE_SYSOP_TYPE_FUNC(dmb, sy)
272
273
DEFINE_SYSOP_TYPE_FUNC(dmb, st)
DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
274
DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
275
DEFINE_SYSOP_TYPE_FUNC(dsb, nsh)
276
DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
277
278
279
280
281
282
283
DEFINE_SYSOP_TYPE_FUNC(dmb, oshld)
DEFINE_SYSOP_TYPE_FUNC(dmb, oshst)
DEFINE_SYSOP_TYPE_FUNC(dmb, osh)
DEFINE_SYSOP_TYPE_FUNC(dmb, nshld)
DEFINE_SYSOP_TYPE_FUNC(dmb, nshst)
DEFINE_SYSOP_TYPE_FUNC(dmb, nsh)
DEFINE_SYSOP_TYPE_FUNC(dmb, ishld)
284
DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
285
DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
286
287
DEFINE_SYSOP_FUNC(isb)

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
static inline void enable_irq(void)
{
	/*
	 * The compiler memory barrier will prevent the compiler from
	 * scheduling non-volatile memory access after the write to the
	 * register.
	 *
	 * This could happen if some initialization code issues non-volatile
	 * accesses to an area used by an interrupt handler, in the assumption
	 * that it is safe as the interrupts are disabled at the time it does
	 * that (according to program order). However, non-volatile accesses
	 * are not necessarily in program order relatively with volatile inline
	 * assembly statements (and volatile accesses).
	 */
	COMPILER_BARRIER();
	write_daifclr(DAIF_IRQ_BIT);
	isb();
}

static inline void enable_fiq(void)
{
	COMPILER_BARRIER();
	write_daifclr(DAIF_FIQ_BIT);
	isb();
}

static inline void enable_serror(void)
{
	COMPILER_BARRIER();
	write_daifclr(DAIF_ABT_BIT);
	isb();
}

static inline void enable_debug_exceptions(void)
{
	COMPILER_BARRIER();
	write_daifclr(DAIF_DBG_BIT);
	isb();
}

static inline void disable_irq(void)
{
	COMPILER_BARRIER();
	write_daifset(DAIF_IRQ_BIT);
	isb();
}

static inline void disable_fiq(void)
{
	COMPILER_BARRIER();
	write_daifset(DAIF_FIQ_BIT);
	isb();
}

static inline void disable_serror(void)
{
	COMPILER_BARRIER();
	write_daifset(DAIF_ABT_BIT);
	isb();
}

static inline void disable_debug_exceptions(void)
{
	COMPILER_BARRIER();
	write_daifset(DAIF_DBG_BIT);
	isb();
}

356
357
void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
		 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7);
358
359
360
361

/*******************************************************************************
 * System register accessor prototypes
 ******************************************************************************/
362
363
DEFINE_SYSREG_READ_FUNC(midr_el1)
DEFINE_SYSREG_READ_FUNC(mpidr_el1)
364
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)
johpow01's avatar
johpow01 committed
365
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1)
366

367
368
DEFINE_SYSREG_RW_FUNCS(scr_el3)
DEFINE_SYSREG_RW_FUNCS(hcr_el2)
369

370
371
372
DEFINE_SYSREG_RW_FUNCS(vbar_el1)
DEFINE_SYSREG_RW_FUNCS(vbar_el2)
DEFINE_SYSREG_RW_FUNCS(vbar_el3)
373

374
375
376
DEFINE_SYSREG_RW_FUNCS(sctlr_el1)
DEFINE_SYSREG_RW_FUNCS(sctlr_el2)
DEFINE_SYSREG_RW_FUNCS(sctlr_el3)
377

378
379
380
DEFINE_SYSREG_RW_FUNCS(actlr_el1)
DEFINE_SYSREG_RW_FUNCS(actlr_el2)
DEFINE_SYSREG_RW_FUNCS(actlr_el3)
381

382
383
384
DEFINE_SYSREG_RW_FUNCS(esr_el1)
DEFINE_SYSREG_RW_FUNCS(esr_el2)
DEFINE_SYSREG_RW_FUNCS(esr_el3)
385

386
387
388
DEFINE_SYSREG_RW_FUNCS(afsr0_el1)
DEFINE_SYSREG_RW_FUNCS(afsr0_el2)
DEFINE_SYSREG_RW_FUNCS(afsr0_el3)
389

390
391
392
DEFINE_SYSREG_RW_FUNCS(afsr1_el1)
DEFINE_SYSREG_RW_FUNCS(afsr1_el2)
DEFINE_SYSREG_RW_FUNCS(afsr1_el3)
393

394
395
396
DEFINE_SYSREG_RW_FUNCS(far_el1)
DEFINE_SYSREG_RW_FUNCS(far_el2)
DEFINE_SYSREG_RW_FUNCS(far_el3)
397

398
399
400
DEFINE_SYSREG_RW_FUNCS(mair_el1)
DEFINE_SYSREG_RW_FUNCS(mair_el2)
DEFINE_SYSREG_RW_FUNCS(mair_el3)
401

402
403
404
DEFINE_SYSREG_RW_FUNCS(amair_el1)
DEFINE_SYSREG_RW_FUNCS(amair_el2)
DEFINE_SYSREG_RW_FUNCS(amair_el3)
405

406
407
408
DEFINE_SYSREG_READ_FUNC(rvbar_el1)
DEFINE_SYSREG_READ_FUNC(rvbar_el2)
DEFINE_SYSREG_READ_FUNC(rvbar_el3)
409

410
411
412
DEFINE_SYSREG_RW_FUNCS(rmr_el1)
DEFINE_SYSREG_RW_FUNCS(rmr_el2)
DEFINE_SYSREG_RW_FUNCS(rmr_el3)
413

414
415
416
DEFINE_SYSREG_RW_FUNCS(tcr_el1)
DEFINE_SYSREG_RW_FUNCS(tcr_el2)
DEFINE_SYSREG_RW_FUNCS(tcr_el3)
417

418
419
420
DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
421

422
DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
423

424
425
DEFINE_SYSREG_RW_FUNCS(vttbr_el2)

426
427
DEFINE_SYSREG_RW_FUNCS(cptr_el2)
DEFINE_SYSREG_RW_FUNCS(cptr_el3)
428

429
430
DEFINE_SYSREG_RW_FUNCS(cpacr_el1)
DEFINE_SYSREG_RW_FUNCS(cntfrq_el0)
431
432
433
DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)
DEFINE_SYSREG_RW_FUNCS(cnthp_tval_el2)
DEFINE_SYSREG_RW_FUNCS(cnthp_cval_el2)
434
435
436
DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1)
DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1)
DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1)
437
438
439
DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0)
DEFINE_SYSREG_RW_FUNCS(cntp_tval_el0)
DEFINE_SYSREG_RW_FUNCS(cntp_cval_el0)
440
441
DEFINE_SYSREG_READ_FUNC(cntpct_el0)
DEFINE_SYSREG_RW_FUNCS(cnthctl_el2)
442

443
444
445
446
447
448
449
450
451
452
453
454
455
#define get_cntp_ctl_enable(x)  (((x) >> CNTP_CTL_ENABLE_SHIFT) & \
					CNTP_CTL_ENABLE_MASK)
#define get_cntp_ctl_imask(x)   (((x) >> CNTP_CTL_IMASK_SHIFT) & \
					CNTP_CTL_IMASK_MASK)
#define get_cntp_ctl_istatus(x) (((x) >> CNTP_CTL_ISTATUS_SHIFT) & \
					CNTP_CTL_ISTATUS_MASK)

#define set_cntp_ctl_enable(x)  ((x) |= (U(1) << CNTP_CTL_ENABLE_SHIFT))
#define set_cntp_ctl_imask(x)   ((x) |= (U(1) << CNTP_CTL_IMASK_SHIFT))

#define clr_cntp_ctl_enable(x)  ((x) &= ~(U(1) << CNTP_CTL_ENABLE_SHIFT))
#define clr_cntp_ctl_imask(x)   ((x) &= ~(U(1) << CNTP_CTL_IMASK_SHIFT))

456
DEFINE_SYSREG_RW_FUNCS(tpidr_el3)
457

458
459
DEFINE_SYSREG_RW_FUNCS(cntvoff_el2)

460
461
462
DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)

463
464
DEFINE_SYSREG_READ_FUNC(isr_el1)

465
DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
466
DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
467
DEFINE_SYSREG_RW_FUNCS(hstr_el2)
468
DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
469

470
471
/* GICv3 System Registers */

472
473
474
475
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1)
476
DEFINE_RENAME_SYSREG_READ_FUNC(icc_rpr_el1, ICC_RPR_EL1)
477
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el3, ICC_IGRPEN1_EL3)
478
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1_EL1)
479
480
481
482
483
484
485
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el1, ICC_HPPIR1_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar0_el1, ICC_IAR0_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar1_el1, ICC_IAR1_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
486
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
487
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R)
488

489
490
DEFINE_RENAME_SYSREG_READ_FUNC(amcfgr_el0, AMCFGR_EL0)
DEFINE_RENAME_SYSREG_READ_FUNC(amcgcr_el0, AMCGCR_EL0)
491
492
DEFINE_RENAME_SYSREG_READ_FUNC(amcg1idr_el0, AMCG1IDR_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcr_el0, AMCR_EL0)
493
494
495
496
497
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)

498
499
500
501
502
DEFINE_RENAME_SYSREG_READ_FUNC(mpamidr_el1, MPAMIDR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(mpam2_el2, MPAM2_EL2)
DEFINE_RENAME_SYSREG_RW_FUNCS(mpamhcr_el2, MPAMHCR_EL2)

503
DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
504

David Cunado's avatar
David Cunado committed
505
506
507
DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2)

508
509
510
511
512
513
514
515
516
517
DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(errselr_el1, ERRSELR_EL1)

DEFINE_RENAME_SYSREG_READ_FUNC(erxfr_el1, ERXFR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(erxctlr_el1, ERXCTLR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(erxstatus_el1, ERXSTATUS_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(erxaddr_el1, ERXADDR_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)

518
519
520
/* Armv8.2 Registers */
DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)

521
/* Armv8.3 Pointer Authentication Registers */
522
523
DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeyhi_el1, APIAKeyHi_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeylo_el1, APIAKeyLo_EL1)
524

525
526
527
528
529
530
/* Armv8.5 MTE Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(tfsre0_el1, TFSRE0_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1)

531
532
533
534
/* Armv8.5 FEAT_RNG Registers */
DEFINE_SYSREG_READ_FUNC(rndr)
DEFINE_SYSREG_READ_FUNC(rndrrs)

535
536
537
/* DynamIQ Shared Unit power management */
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)

538
539
#define IS_IN_EL(x) \
	(GET_EL(read_CurrentEl()) == MODE_EL##x)
540

541
#define IS_IN_EL1() IS_IN_EL(1)
542
#define IS_IN_EL2() IS_IN_EL(2)
543
544
545
546
547
548
#define IS_IN_EL3() IS_IN_EL(3)

static inline unsigned int get_current_el(void)
{
	return GET_EL(read_CurrentEl());
}
549

550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
static inline unsigned int get_current_el_maybe_constant(void)
{
#if defined(IMAGE_AT_EL1)
	return 1;
#elif defined(IMAGE_AT_EL2)
	return 2;	/* no use-case in TF-A */
#elif defined(IMAGE_AT_EL3)
	return 3;
#else
	/*
	 * If we do not know which exception level this is being built for
	 * (e.g. built for library), fall back to run-time detection.
	 */
	return get_current_el();
#endif
}

567
/*
568
 * Check if an EL is implemented from AA64PFR0 register fields.
569
 */
570
571
572
573
574
575
576
577
578
579
580
static inline uint64_t el_implemented(unsigned int el)
{
	if (el > 3U) {
		return EL_IMPL_NONE;
	} else {
		unsigned int shift = ID_AA64PFR0_EL1_SHIFT * el;

		return (read_id_aa64pfr0_el1() >> shift) & ID_AA64PFR0_ELX_MASK;
	}
}

581
/* Previously defined accesor functions with incomplete register names  */
582

583
#define read_current_el()	read_CurrentEl()
584

585
#define dsb()			dsbsy()
586

587
588
589
590
591
592
593
594
595
596
597
598
#define read_midr()		read_midr_el1()

#define read_mpidr()		read_mpidr_el1()

#define read_scr()		read_scr_el3()
#define write_scr(_v)		write_scr_el3(_v)

#define read_hcr()		read_hcr_el2()
#define write_hcr(_v)		write_hcr_el2(_v)

#define read_cpacr()		read_cpacr_el1()
#define write_cpacr(_v)		write_cpacr_el1(_v)
599

600
601
602
#define read_clusterpwrdn()	read_clusterpwrdn_el1()
#define write_clusterpwrdn(_v)	write_clusterpwrdn_el1(_v)

603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
#if ERRATA_SPECULATIVE_AT
/*
 * Assuming SCTLR.M bit is already enabled
 * 1. Enable page table walk by clearing TCR_EL1.EPDx bits
 * 2. Execute AT instruction for lower EL1/0
 * 3. Disable page table walk by setting TCR_EL1.EPDx bits
 */
#define AT(_at_inst, _va)	\
{	\
	assert((read_sctlr_el1() & SCTLR_M_BIT) != 0ULL);	\
	write_tcr_el1(read_tcr_el1() & ~(TCR_EPD0_BIT | TCR_EPD1_BIT));	\
	isb();	\
	_at_inst(_va);	\
	write_tcr_el1(read_tcr_el1() | (TCR_EPD0_BIT | TCR_EPD1_BIT));	\
	isb();	\
}
#else
#define AT(_at_inst, _va)	_at_inst(_va);
#endif

623
#endif /* ARCH_HELPERS_H */