aboutsummaryrefslogtreecommitdiff
path: root/core/arch/arm/include/arm64.h
blob: 2981806c25ebaa7352971db7ce4d837ddf791020 (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
/* SPDX-License-Identifier: BSD-2-Clause */
/*
 * Copyright (c) 2015, Linaro Limited
 */
#ifndef ARM64_H
#define ARM64_H

#include <sys/cdefs.h>
#include <stdint.h>
#include <util.h>

#define SCTLR_M		BIT32(0)
#define SCTLR_A		BIT32(1)
#define SCTLR_C		BIT32(2)
#define SCTLR_SA	BIT32(3)
#define SCTLR_I		BIT32(12)
#define SCTLR_WXN	BIT32(19)

#define TTBR_ASID_MASK		0xff
#define TTBR_ASID_SHIFT		48

#define CLIDR_LOUIS_SHIFT	21
#define CLIDR_LOC_SHIFT		24
#define CLIDR_FIELD_WIDTH	3

#define CSSELR_LEVEL_SHIFT	1

#define DAIFBIT_FIQ			BIT32(0)
#define DAIFBIT_IRQ			BIT32(1)
#define DAIFBIT_ABT			BIT32(2)
#define DAIFBIT_DBG			BIT32(3)
#define DAIFBIT_ALL			(DAIFBIT_FIQ | DAIFBIT_IRQ | \
					 DAIFBIT_ABT | DAIFBIT_DBG)

#define DAIF_F_SHIFT		6
#define DAIF_F			BIT32(6)
#define DAIF_I			BIT32(7)
#define DAIF_A			BIT32(8)
#define DAIF_D			BIT32(9)
#define DAIF_AIF		(DAIF_A | DAIF_I | DAIF_F)

#define SPSR_MODE_RW_SHIFT	4
#define SPSR_MODE_RW_MASK	0x1
#define SPSR_MODE_RW_64		0x0
#define SPSR_MODE_RW_32		0x1

#define SPSR_64_MODE_SP_SHIFT	0
#define SPSR_64_MODE_SP_MASK	0x1
#define SPSR_64_MODE_SP_EL0	0x0
#define SPSR_64_MODE_SP_ELX	0x1

#define SPSR_64_MODE_EL_SHIFT	2
#define SPSR_64_MODE_EL_MASK	0x3
#define SPSR_64_MODE_EL1	0x1
#define SPSR_64_MODE_EL0	0x0

#define SPSR_64_DAIF_SHIFT	6
#define SPSR_64_DAIF_MASK	0xf

#define SPSR_32_AIF_SHIFT	6
#define SPSR_32_AIF_MASK	0x7

#define SPSR_32_E_SHIFT		9
#define SPSR_32_E_MASK		0x1
#define SPSR_32_E_LITTLE	0x0
#define SPSR_32_E_BIG		0x1

#define SPSR_32_T_SHIFT		5
#define SPSR_32_T_MASK		0x1
#define SPSR_32_T_ARM		0x0
#define SPSR_32_T_THUMB		0x1

#define SPSR_32_MODE_SHIFT	0
#define SPSR_32_MODE_MASK	0xf
#define SPSR_32_MODE_USR	0x0


#define SPSR_64(el, sp, daif)						\
	(SPSR_MODE_RW_64 << SPSR_MODE_RW_SHIFT |			\
	((el) & SPSR_64_MODE_EL_MASK) << SPSR_64_MODE_EL_SHIFT |	\
	((sp) & SPSR_64_MODE_SP_MASK) << SPSR_64_MODE_SP_SHIFT |	\
	((daif) & SPSR_64_DAIF_MASK) << SPSR_64_DAIF_SHIFT)

#define SPSR_32(mode, isa, aif)						\
	(SPSR_MODE_RW_32 << SPSR_MODE_RW_SHIFT |			\
	SPSR_32_E_LITTLE << SPSR_32_E_SHIFT |				\
	((mode) & SPSR_32_MODE_MASK) << SPSR_32_MODE_SHIFT |		\
	((isa) & SPSR_32_T_MASK) << SPSR_32_T_SHIFT |			\
	((aif) & SPSR_32_AIF_MASK) << SPSR_32_AIF_SHIFT)


#define TCR_T0SZ_SHIFT		0
#define TCR_EPD0		BIT32(7)
#define TCR_IRGN0_SHIFT		8
#define TCR_ORGN0_SHIFT		10
#define TCR_SH0_SHIFT		12
#define TCR_T1SZ_SHIFT		16
#define TCR_A1			BIT32(22)
#define TCR_EPD1		BIT32(23)
#define TCR_IRGN1_SHIFT		24
#define TCR_ORGN1_SHIFT		26
#define TCR_SH1_SHIFT		28
#define TCR_EL1_IPS_SHIFT	32
#define TCR_EL1_IPS_MASK	UINT64_C(0x7)
#define TCR_TG1_4KB		SHIFT_U32(2, 30)
#define TCR_RES1		BIT32(31)


/* Normal memory, Inner/Outer Non-cacheable */
#define TCR_XRGNX_NC		0x0
/* Normal memory, Inner/Outer Write-Back Write-Allocate Cacheable */
#define TCR_XRGNX_WB		0x1
/* Normal memory, Inner/Outer Write-Through Cacheable */
#define TCR_XRGNX_WT		0x2
/* Normal memory, Inner/Outer Write-Back no Write-Allocate Cacheable */
#define TCR_XRGNX_WBWA	0x3

/* Non-shareable */
#define TCR_SHX_NSH		0x0
/* Outer Shareable */
#define TCR_SHX_OSH		0x2
/* Inner Shareable */
#define TCR_SHX_ISH		0x3

#define ESR_EC_SHIFT		26
#define ESR_EC_MASK		0x3f

#define ESR_EC_UNKNOWN		0x00
#define ESR_EC_WFI		0x01
#define ESR_EC_AARCH32_CP15_32	0x03
#define ESR_EC_AARCH32_CP15_64	0x04
#define ESR_EC_AARCH32_CP14_MR	0x05
#define ESR_EC_AARCH32_CP14_LS	0x06
#define ESR_EC_FP_ASIMD		0x07
#define ESR_EC_AARCH32_CP10_ID	0x08
#define ESR_EC_AARCH32_CP14_64	0x0c
#define ESR_EC_ILLEGAL		0x0e
#define ESR_EC_AARCH32_SVC	0x11
#define ESR_EC_AARCH64_SVC	0x15
#define ESR_EC_AARCH64_SYS	0x18
#define ESR_EC_IABT_EL0		0x20
#define ESR_EC_IABT_EL1		0x21
#define ESR_EC_PC_ALIGN		0x22
#define ESR_EC_DABT_EL0		0x24
#define ESR_EC_DABT_EL1		0x25
#define ESR_EC_SP_ALIGN		0x26
#define ESR_EC_AARCH32_FP	0x28
#define ESR_EC_AARCH64_FP	0x2c
#define ESR_EC_SERROR		0x2f
#define ESR_EC_BREAKPT_EL0	0x30
#define ESR_EC_BREAKPT_EL1	0x31
#define ESR_EC_SOFTSTP_EL0	0x32
#define ESR_EC_SOFTSTP_EL1	0x33
#define ESR_EC_WATCHPT_EL0	0x34
#define ESR_EC_WATCHPT_EL1	0x35
#define ESR_EC_AARCH32_BKPT	0x38
#define ESR_EC_AARCH64_BRK	0x3c

/* Combined defines for DFSC and IFSC */
#define ESR_FSC_MASK		0x3f
#define ESR_FSC_SIZE_L0		0x00
#define ESR_FSC_SIZE_L1		0x01
#define ESR_FSC_SIZE_L2		0x02
#define ESR_FSC_SIZE_L3		0x03
#define ESR_FSC_TRANS_L0	0x04
#define ESR_FSC_TRANS_L1	0x05
#define ESR_FSC_TRANS_L2	0x06
#define ESR_FSC_TRANS_L3	0x07
#define ESR_FSC_ACCF_L1		0x09
#define ESR_FSC_ACCF_L2		0x0a
#define ESR_FSC_ACCF_L3		0x0b
#define ESR_FSC_PERMF_L1	0x0d
#define ESR_FSC_PERMF_L2	0x0e
#define ESR_FSC_PERMF_L3	0x0f
#define ESR_FSC_ALIGN		0x21

/* WnR for DABT and RES0 for IABT */
#define ESR_ABT_WNR		BIT32(6)

#define CPACR_EL1_FPEN_SHIFT	20
#define CPACR_EL1_FPEN_MASK	0x3
#define CPACR_EL1_FPEN_NONE	0x0
#define CPACR_EL1_FPEN_EL1	0x1
#define CPACR_EL1_FPEN_EL0EL1	0x3
#define CPACR_EL1_FPEN(x)	((x) >> CPACR_EL1_FPEN_SHIFT \
				      & CPACR_EL1_FPEN_MASK)


#define PAR_F			BIT32(0)
#define PAR_PA_SHIFT		12
#define PAR_PA_MASK		(BIT64(36) - 1)

#define TLBI_MVA_SHIFT		12
#define TLBI_ASID_SHIFT		48
#define TLBI_ASID_MASK		0xff

#ifndef ASM
static inline void isb(void)
{
	asm volatile ("isb");
}

static inline void dsb(void)
{
	asm volatile ("dsb sy");
}

static inline void dsb_ish(void)
{
	asm volatile ("dsb ish");
}

static inline void dsb_ishst(void)
{
	asm volatile ("dsb ishst");
}

static inline void write_at_s1e1r(uint64_t va)
{
	asm volatile ("at	S1E1R, %0" : : "r" (va));
}

static __always_inline uint64_t read_pc(void)
{
	uint64_t val;

	asm volatile ("adr %0, ." : "=r" (val));
	return val;
}

static __always_inline uint64_t read_fp(void)
{
	uint64_t val;

	asm volatile ("mov %0, x29" : "=r" (val));
	return val;
}

static inline uint64_t read_pmu_ccnt(void)
{
	uint64_t val;

	asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(val));
	return val;
}

static inline void tlbi_vaae1is(uint64_t mva)
{
	asm volatile ("tlbi	vaae1is, %0" : : "r" (mva));
}

/*
 * Templates for register read/write functions based on mrs/msr
 */

#define DEFINE_REG_READ_FUNC_(reg, type, asmreg)	\
static inline type read_##reg(void)			\
{							\
	type val;					\
							\
	asm volatile("mrs %0, " #asmreg : "=r" (val));	\
	return val;					\
}

#define DEFINE_REG_WRITE_FUNC_(reg, type, asmreg)		\
static inline void write_##reg(type val)			\
{								\
	asm volatile("msr " #asmreg ", %0" : : "r" (val));	\
}

#define DEFINE_U32_REG_READ_FUNC(reg) \
		DEFINE_REG_READ_FUNC_(reg, uint32_t, reg)

#define DEFINE_U32_REG_WRITE_FUNC(reg) \
		DEFINE_REG_WRITE_FUNC_(reg, uint32_t, reg)

#define DEFINE_U32_REG_READWRITE_FUNCS(reg)	\
		DEFINE_U32_REG_READ_FUNC(reg)	\
		DEFINE_U32_REG_WRITE_FUNC(reg)

#define DEFINE_U64_REG_READ_FUNC(reg) \
		DEFINE_REG_READ_FUNC_(reg, uint64_t, reg)

#define DEFINE_U64_REG_WRITE_FUNC(reg) \
		DEFINE_REG_WRITE_FUNC_(reg, uint64_t, reg)

#define DEFINE_U64_REG_READWRITE_FUNCS(reg)	\
		DEFINE_U64_REG_READ_FUNC(reg)	\
		DEFINE_U64_REG_WRITE_FUNC(reg)

/*
 * Define register access functions
 */

DEFINE_U32_REG_READWRITE_FUNCS(cpacr_el1)
DEFINE_U32_REG_READWRITE_FUNCS(daif)
DEFINE_U32_REG_READWRITE_FUNCS(fpcr)
DEFINE_U32_REG_READWRITE_FUNCS(fpsr)

DEFINE_U32_REG_READ_FUNC(contextidr_el1)
DEFINE_U32_REG_READ_FUNC(sctlr_el1)

/* ARM Generic timer functions */
DEFINE_REG_READ_FUNC_(cntfrq, uint32_t, cntfrq_el0)
DEFINE_REG_READ_FUNC_(cntpct, uint64_t, cntpct_el0)
DEFINE_REG_READ_FUNC_(cntkctl, uint32_t, cntkctl_el1)
DEFINE_REG_WRITE_FUNC_(cntkctl, uint32_t, cntkctl_el1)

DEFINE_U64_REG_READWRITE_FUNCS(ttbr0_el1)
DEFINE_U64_REG_READWRITE_FUNCS(ttbr1_el1)
DEFINE_U64_REG_READWRITE_FUNCS(tcr_el1)

DEFINE_U64_REG_READ_FUNC(esr_el1)
DEFINE_U64_REG_READ_FUNC(far_el1)
DEFINE_U64_REG_READ_FUNC(mpidr_el1)
DEFINE_U64_REG_READ_FUNC(midr_el1)
/* Alias for reading this register to avoid ifdefs in code */
#define read_midr() read_midr_el1()
DEFINE_U64_REG_READ_FUNC(par_el1)

DEFINE_U64_REG_WRITE_FUNC(mair_el1)

/* Register read/write functions for GICC registers by using system interface */
DEFINE_REG_READ_FUNC_(icc_ctlr, uint32_t, S3_0_C12_C12_4)
DEFINE_REG_WRITE_FUNC_(icc_ctlr, uint32_t, S3_0_C12_C12_4)
DEFINE_REG_WRITE_FUNC_(icc_pmr, uint32_t, S3_0_C4_C6_0)
DEFINE_REG_READ_FUNC_(icc_iar0, uint32_t, S3_0_c12_c8_0)
DEFINE_REG_WRITE_FUNC_(icc_eoir0, uint32_t, S3_0_c12_c8_1)
#endif /*ASM*/

#endif /*ARM64_H*/