summaryrefslogtreecommitdiffstats
path: root/src/arch/arm64/include/armv8/arch/lib_helpers.h
blob: 0afbf82a238679854f262ab392624f17f73f33ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
/*
 * This file is part of the coreboot project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of
 * the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * lib_helpers.h: All library function prototypes and macros are defined in this
 * file.
 */

#ifndef __ARCH_LIB_HELPERS_H__
#define __ARCH_LIB_HELPERS_H__

#define EL0               0
#define EL1               1
#define EL2               2
#define EL3               3

#define CURRENT_EL_MASK   0x3
#define CURRENT_EL_SHIFT  2

#define SPSR_USE_L           0
#define SPSR_USE_H           1
#define SPSR_L_H_MASK        1
#define SPSR_M_SHIFT         4
#define SPSR_ERET_32         (1 << SPSR_M_SHIFT)
#define SPSR_ERET_64         (0 << SPSR_M_SHIFT)
#define SPSR_FIQ             (1 << 6)
#define SPSR_IRQ             (1 << 7)
#define SPSR_SERROR          (1 << 8)
#define SPSR_DEBUG           (1 << 9)
#define SPSR_EXCEPTION_MASK  (SPSR_FIQ | SPSR_IRQ | SPSR_SERROR | SPSR_DEBUG)

#define SCR_NS_SHIFT         0
#define SCR_NS_MASK          (1 << SCR_NS_SHIFT)
#define SCR_NS_ENABLE        (1 << SCR_NS_SHIFT)
#define SCR_NS_DISABLE       (0 << SCR_NS_SHIFT)
#define SCR_NS               SCR_NS_ENABLE
#define SCR_RES1             (0x3 << 4)
#define SCR_IRQ_SHIFT        2
#define SCR_IRQ_MASK         (1 << SCR_IRQ_SHIFT)
#define SCR_IRQ_ENABLE       (1 << SCR_IRQ_SHIFT)
#define SCR_IRQ_DISABLE      (0 << SCR_IRQ_SHIFT)
#define SCR_FIQ_SHIFT        2
#define SCR_FIQ_MASK         (1 << SCR_FIQ_SHIFT)
#define SCR_FIQ_ENABLE       (1 << SCR_FIQ_SHIFT)
#define SCR_FIQ_DISABLE      (0 << SCR_FIQ_SHIFT)
#define SCR_EA_SHIFT         3
#define SCR_EA_MASK          (1 << SCR_EA_SHIFT)
#define SCR_EA_ENABLE        (1 << SCR_EA_SHIFT)
#define SCR_EA_DISABLE       (0 << SCR_EA_SHIFT)
#define SCR_SMD_SHIFT        7
#define SCR_SMD_MASK         (1 << SCR_SMD_SHIFT)
#define SCR_SMD_DISABLE      (1 << SCR_SMD_SHIFT)
#define SCR_SMD_ENABLE       (0 << SCR_SMD_SHIFT)
#define SCR_HVC_SHIFT        8
#define SCR_HVC_MASK         (1 << SCR_HVC_SHIFT)
#define SCR_HVC_DISABLE      (0 << SCR_HVC_SHIFT)
#define SCR_HVC_ENABLE       (1 << SCR_HVC_SHIFT)
#define SCR_SIF_SHIFT        9
#define SCR_SIF_MASK         (1 << SCR_SIF_SHIFT)
#define SCR_SIF_ENABLE       (1 << SCR_SIF_SHIFT)
#define SCR_SIF_DISABLE      (0 << SCR_SIF_SHIFT)
#define SCR_RW_SHIFT         10
#define SCR_RW_MASK          (1 << SCR_RW_SHIFT)
#define SCR_LOWER_AARCH64    (1 << SCR_RW_SHIFT)
#define SCR_LOWER_AARCH32    (0 << SCR_RW_SHIFT)
#define SCR_ST_SHIFT         11
#define SCR_ST_MASK          (1 << SCR_ST_SHIFT)
#define SCR_ST_ENABLE        (1 << SCR_ST_SHIFT)
#define SCR_ST_DISABLE       (0 << SCR_ST_SHIFT)
#define SCR_TWI_SHIFT        12
#define SCR_TWI_MASK         (1 << SCR_TWI_SHIFT)
#define SCR_TWI_ENABLE       (1 << SCR_TWI_SHIFT)
#define SCR_TWI_DISABLE      (0 << SCR_TWI_SHIFT)
#define SCR_TWE_SHIFT        13
#define SCR_TWE_MASK         (1 << SCR_TWE_SHIFT)
#define SCR_TWE_ENABLE       (1 << SCR_TWE_SHIFT)
#define SCR_TWE_DISABLE      (0 << SCR_TWE_SHIFT)

#define HCR_RW_SHIFT         31
#define HCR_LOWER_AARCH64    (1 << HCR_RW_SHIFT)
#define HCR_LOWER_AARCH32    (0 << HCR_RW_SHIFT)

#define SCTLR_MMU_ENABLE     1
#define SCTLR_MMU_DISABLE    0
#define SCTLR_ACE_SHIFT      1
#define SCTLR_ACE_ENABLE     (1 << SCTLR_ACE_SHIFT)
#define SCTLR_ACE_DISABLE    (0 << SCTLR_ACE_SHIFT)
#define SCTLR_CACHE_SHIFT    2
#define SCTLR_CACHE_ENABLE   (1 << SCTLR_CACHE_SHIFT)
#define SCTLR_CACHE_DISABLE  (0 << SCTLR_CACHE_SHIFT)
#define SCTLR_SAE_SHIFT      3
#define SCTLR_SAE_ENABLE     (1 << SCTLR_SAE_SHIFT)
#define SCTLR_SAE_DISABLE    (0 << SCTLR_SAE_SHIFT)
#define SCTLR_RES1           ((0x3 << 4) | (0x1 << 11) | (0x1 << 16) |	\
			      (0x1 << 18) | (0x3 << 22) | (0x3 << 28))
#define SCTLR_ICE_SHIFT      12
#define SCTLR_ICE_ENABLE     (1 << SCTLR_ICE_SHIFT)
#define SCTLR_ICE_DISABLE    (0 << SCTLR_ICE_SHIFT)
#define SCTLR_WXN_SHIFT      19
#define SCTLR_WXN_ENABLE     (1 << SCTLR_WXN_SHIFT)
#define SCTLR_WXN_DISABLE    (0 << SCTLR_WXN_SHIFT)
#define SCTLR_ENDIAN_SHIFT   25
#define SCTLR_LITTLE_END     (0 << SCTLR_ENDIAN_SHIFT)
#define SCTLR_BIG_END        (1 << SCTLR_ENDIAN_SHIFT)

#define CPTR_EL3_TCPAC_SHIFT	(31)
#define CPTR_EL3_TTA_SHIFT	(20)
#define CPTR_EL3_TFP_SHIFT	(10)
#define CPTR_EL3_TCPAC_DISABLE	(0 << CPTR_EL3_TCPAC_SHIFT)
#define CPTR_EL3_TCPAC_ENABLE	(1 << CPTR_EL3_TCPAC_SHIFT)
#define CPTR_EL3_TTA_DISABLE	(0 << CPTR_EL3_TTA_SHIFT)
#define CPTR_EL3_TTA_ENABLE	(1 << CPTR_EL3_TTA_SHIFT)
#define CPTR_EL3_TFP_DISABLE	(0 << CPTR_EL3_TFP_SHIFT)
#define CPTR_EL3_TFP_ENABLE	(1 << CPTR_EL3_TFP_SHIFT)

#define CPACR_TTA_SHIFT	(28)
#define CPACR_TTA_ENABLE	(1 << CPACR_TTA_SHIFT)
#define CPACR_TTA_DISABLE	(0 << CPACR_TTA_SHIFT)
#define CPACR_FPEN_SHIFT	(20)
/*
 * ARMv8-A spec: Values 0b00 and 0b10 both seem to enable traps from el0 and el1
 * for fp reg access.
 */
#define CPACR_TRAP_FP_EL0_EL1	(0 << CPACR_FPEN_SHIFT)
#define CPACR_TRAP_FP_EL0	(1 << CPACR_FPEN_SHIFT)
#define CPACR_TRAP_FP_DISABLE	(3 << CPACR_FPEN_SHIFT)

#define DAIF_DBG_BIT      (1<<3)
#define DAIF_ABT_BIT      (1<<2)
#define DAIF_IRQ_BIT      (1<<1)
#define DAIF_FIQ_BIT      (1<<0)

#ifndef __ASSEMBLER__

#include <stdint.h>

#define MAKE_REGISTER_ACCESSORS(reg) \
	static inline uint64_t raw_read_##reg(void) \
	{ \
		uint64_t value; \
		__asm__ __volatile__("mrs %0, " #reg "\n\t" \
				     : "=r" (value) : : "memory"); \
		return value; \
	} \
	static inline void raw_write_##reg(uint64_t value) \
	{ \
		__asm__ __volatile__("msr " #reg ", %0\n\t" \
				     : : "r" (value) : "memory"); \
	}

#define MAKE_REGISTER_ACCESSORS_EL123(reg) \
	MAKE_REGISTER_ACCESSORS(reg##_el1) \
	MAKE_REGISTER_ACCESSORS(reg##_el2) \
	MAKE_REGISTER_ACCESSORS(reg##_el3)

/* Architectural register accessors */
MAKE_REGISTER_ACCESSORS_EL123(actlr)
MAKE_REGISTER_ACCESSORS_EL123(afsr0)
MAKE_REGISTER_ACCESSORS_EL123(afsr1)
MAKE_REGISTER_ACCESSORS(aidr_el1)
MAKE_REGISTER_ACCESSORS_EL123(amair)
MAKE_REGISTER_ACCESSORS(ccsidr_el1)
MAKE_REGISTER_ACCESSORS(clidr_el1)
MAKE_REGISTER_ACCESSORS(cntfrq_el0)
MAKE_REGISTER_ACCESSORS(cnthctl_el2)
MAKE_REGISTER_ACCESSORS(cnthp_ctl_el2)
MAKE_REGISTER_ACCESSORS(cnthp_cval_el2)
MAKE_REGISTER_ACCESSORS(cnthp_tval_el2)
MAKE_REGISTER_ACCESSORS(cntkctl_el1)
MAKE_REGISTER_ACCESSORS(cntp_ctl_el0)
MAKE_REGISTER_ACCESSORS(cntp_cval_el0)
MAKE_REGISTER_ACCESSORS(cntp_tval_el0)
MAKE_REGISTER_ACCESSORS(cntpct_el0)
MAKE_REGISTER_ACCESSORS(cntps_ctl_el1)
MAKE_REGISTER_ACCESSORS(cntps_cval_el1)
MAKE_REGISTER_ACCESSORS(cntps_tval_el1)
MAKE_REGISTER_ACCESSORS(cntv_ctl_el0)
MAKE_REGISTER_ACCESSORS(cntv_cval_el0)
MAKE_REGISTER_ACCESSORS(cntv_tval_el0)
MAKE_REGISTER_ACCESSORS(cntvct_el0)
MAKE_REGISTER_ACCESSORS(cntvoff_el2)
MAKE_REGISTER_ACCESSORS(contextidr_el1)
MAKE_REGISTER_ACCESSORS(cpacr_el1)
MAKE_REGISTER_ACCESSORS(cptr_el2)
MAKE_REGISTER_ACCESSORS(cptr_el3)
MAKE_REGISTER_ACCESSORS(csselr_el1)
MAKE_REGISTER_ACCESSORS(ctr_el0)
MAKE_REGISTER_ACCESSORS(currentel)
MAKE_REGISTER_ACCESSORS(daif)
MAKE_REGISTER_ACCESSORS(dczid_el0)
MAKE_REGISTER_ACCESSORS_EL123(elr)
MAKE_REGISTER_ACCESSORS_EL123(esr)
MAKE_REGISTER_ACCESSORS_EL123(far)
MAKE_REGISTER_ACCESSORS(fpcr)
MAKE_REGISTER_ACCESSORS(fpsr)
MAKE_REGISTER_ACCESSORS(hacr_el2)
MAKE_REGISTER_ACCESSORS(hcr_el2)
MAKE_REGISTER_ACCESSORS(hpfar_el2)
MAKE_REGISTER_ACCESSORS(hstr_el2)
MAKE_REGISTER_ACCESSORS(isr_el1)
MAKE_REGISTER_ACCESSORS_EL123(mair)
MAKE_REGISTER_ACCESSORS_EL123(mdcr)
MAKE_REGISTER_ACCESSORS(mdscr)
MAKE_REGISTER_ACCESSORS(midr_el1)
MAKE_REGISTER_ACCESSORS(mpidr_el1)
MAKE_REGISTER_ACCESSORS(nzcv)
MAKE_REGISTER_ACCESSORS(oslar_el1)
MAKE_REGISTER_ACCESSORS(oslsr_el1)
MAKE_REGISTER_ACCESSORS(par_el1)
MAKE_REGISTER_ACCESSORS(revdir_el1)
MAKE_REGISTER_ACCESSORS_EL123(rmr)
MAKE_REGISTER_ACCESSORS_EL123(rvbar)
MAKE_REGISTER_ACCESSORS(scr_el3)
MAKE_REGISTER_ACCESSORS_EL123(sctlr)
MAKE_REGISTER_ACCESSORS(sp_el0)
MAKE_REGISTER_ACCESSORS(sp_el1)
MAKE_REGISTER_ACCESSORS(sp_el2)
MAKE_REGISTER_ACCESSORS(spsel)
MAKE_REGISTER_ACCESSORS_EL123(spsr)
MAKE_REGISTER_ACCESSORS(spsr_abt)
MAKE_REGISTER_ACCESSORS(spsr_fiq)
MAKE_REGISTER_ACCESSORS(spsr_irq)
MAKE_REGISTER_ACCESSORS(spsr_und)
MAKE_REGISTER_ACCESSORS_EL123(tcr)
MAKE_REGISTER_ACCESSORS_EL123(tpidr)
MAKE_REGISTER_ACCESSORS_EL123(ttbr0)
MAKE_REGISTER_ACCESSORS(ttbr1_el1)
MAKE_REGISTER_ACCESSORS_EL123(vbar)
MAKE_REGISTER_ACCESSORS(vmpidr_el2)
MAKE_REGISTER_ACCESSORS(vpidr_el2)
MAKE_REGISTER_ACCESSORS(vtcr_el2)
MAKE_REGISTER_ACCESSORS(vttbr_el2)

/* Special DAIF accessor functions */
static inline void enable_debug_exceptions(void)
{
	__asm__ __volatile__("msr DAIFClr, %0\n\t"
			     : : "i" (DAIF_DBG_BIT)  : "memory");
}

static inline void enable_serror_exceptions(void)
{
	__asm__ __volatile__("msr DAIFClr, %0\n\t"
			     : : "i" (DAIF_ABT_BIT)  : "memory");
}

static inline void enable_irq(void)
{
	__asm__ __volatile__("msr DAIFClr, %0\n\t"
			     : : "i" (DAIF_IRQ_BIT)  : "memory");
}

static inline void enable_fiq(void)
{
	__asm__ __volatile__("msr DAIFClr, %0\n\t"
			     : : "i" (DAIF_FIQ_BIT)  : "memory");
}

static inline void disable_debug_exceptions(void)
{
	__asm__ __volatile__("msr DAIFSet, %0\n\t"
			     : : "i" (DAIF_DBG_BIT)  : "memory");
}

static inline void disable_serror_exceptions(void)
{
	__asm__ __volatile__("msr DAIFSet, %0\n\t"
			     : : "i" (DAIF_ABT_BIT)  : "memory");
}

static inline void disable_irq(void)
{
	__asm__ __volatile__("msr DAIFSet, %0\n\t"
			     : : "i" (DAIF_IRQ_BIT)  : "memory");
}

static inline void disable_fiq(void)
{
	__asm__ __volatile__("msr DAIFSet, %0\n\t"
			     : : "i" (DAIF_FIQ_BIT)  : "memory");
}

/* Cache maintenance system instructions */
static inline void dccisw(uint64_t cisw)
{
	__asm__ __volatile__("dc cisw, %0\n\t" : : "r" (cisw) : "memory");
}

static inline void dccivac(uint64_t civac)
{
	__asm__ __volatile__("dc civac, %0\n\t" : : "r" (civac) : "memory");
}

static inline void dccsw(uint64_t csw)
{
	__asm__ __volatile__("dc csw, %0\n\t" : : "r" (csw) : "memory");
}

static inline void dccvac(uint64_t cvac)
{
	__asm__ __volatile__("dc cvac, %0\n\t" : : "r" (cvac) : "memory");
}

static inline void dccvau(uint64_t cvau)
{
	__asm__ __volatile__("dc cvau, %0\n\t" : : "r" (cvau) : "memory");
}

static inline void dcisw(uint64_t isw)
{
	__asm__ __volatile__("dc isw, %0\n\t" : : "r" (isw) : "memory");
}

static inline void dcivac(uint64_t ivac)
{
	__asm__ __volatile__("dc ivac, %0\n\t" : : "r" (ivac) : "memory");
}

static inline void dczva(uint64_t zva)
{
	__asm__ __volatile__("dc zva, %0\n\t" : : "r" (zva) : "memory");
}

static inline void iciallu(void)
{
	__asm__ __volatile__("ic iallu\n\t" : : : "memory");
}

static inline void icialluis(void)
{
	__asm__ __volatile__("ic ialluis\n\t" : : : "memory");
}

static inline void icivau(uint64_t ivau)
{
	__asm__ __volatile__("ic ivau, %0\n\t" : : "r" (ivau) : "memory");
}

/* TLB maintenance instructions */
static inline void tlbiall_el1(void)
{
	__asm__ __volatile__("tlbi alle1\n\t" : : : "memory");
}

static inline void tlbiall_el2(void)
{
	__asm__ __volatile__("tlbi alle2\n\t" : : : "memory");
}

static inline void tlbiall_el3(void)
{
	__asm__ __volatile__("tlbi alle3\n\t" : : : "memory");
}

static inline void tlbiallis_el1(void)
{
	__asm__ __volatile__("tlbi alle1is\n\t" : : : "memory");
}

static inline void tlbiallis_el2(void)
{
	__asm__ __volatile__("tlbi alle2is\n\t" : : : "memory");
}

static inline void tlbiallis_el3(void)
{
	__asm__ __volatile__("tlbi alle3is\n\t" : : : "memory");
}

static inline void tlbivaa_el1(uint64_t va)
{
	__asm__ __volatile__("tlbi vaae1, %0\n\t" : : "r" (va) : "memory");
}

#endif /* __ASSEMBLER__ */

#endif /* __ARCH_LIB_HELPERS_H__ */