master
h 812 lines 24.1 KB
Raw
1 /*
2 * QEMU ARM CPU -- syndrome functions and types
3 *
4 * Copyright (c) 2014 Linaro Ltd
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see
18 * <http://www.gnu.org/licenses/gpl-2.0.html>
19 *
20 * This header defines functions, types, etc which need to be shared
21 * between different source files within target/arm/ but which are
22 * private to it and not required by the rest of QEMU.
23 */
24
25 #ifndef TARGET_ARM_SYNDROME_H
26 #define TARGET_ARM_SYNDROME_H
27
28 #include "hw/core/registerfields.h"
29
30 /* Valid Syndrome Register EC field values */
31 enum arm_exception_class {
32 EC_UNCATEGORIZED = 0x00,
33 EC_WFX_TRAP = 0x01,
34 EC_CP15RTTRAP = 0x03,
35 EC_CP15RRTTRAP = 0x04,
36 EC_CP14RTTRAP = 0x05,
37 EC_CP14DTTRAP = 0x06,
38 EC_ADVSIMDFPACCESSTRAP = 0x07,
39 EC_FPIDTRAP = 0x08,
40 EC_PACTRAP = 0x09,
41 EC_BXJTRAP = 0x0a,
42 EC_CP14RRTTRAP = 0x0c,
43 EC_BTITRAP = 0x0d,
44 EC_ILLEGALSTATE = 0x0e,
45 EC_AA32_SVC = 0x11,
46 EC_AA32_HVC = 0x12,
47 EC_AA32_SMC = 0x13,
48 EC_AA64_SVC = 0x15,
49 EC_AA64_HVC = 0x16,
50 EC_AA64_SMC = 0x17,
51 EC_SYSTEMREGISTERTRAP = 0x18,
52 EC_SVEACCESSTRAP = 0x19,
53 EC_ERETTRAP = 0x1a,
54 EC_PACFAIL = 0x1c,
55 EC_SMETRAP = 0x1d,
56 EC_GPC = 0x1e,
57 EC_INSNABORT = 0x20,
58 EC_INSNABORT_SAME_EL = 0x21,
59 EC_PCALIGNMENT = 0x22,
60 EC_DATAABORT = 0x24,
61 EC_DATAABORT_SAME_EL = 0x25,
62 EC_SPALIGNMENT = 0x26,
63 EC_MOP = 0x27,
64 EC_AA32_FPTRAP = 0x28,
65 EC_AA64_FPTRAP = 0x2c,
66 EC_GCS = 0x2d,
67 EC_SERROR = 0x2f,
68 EC_BREAKPOINT = 0x30,
69 EC_BREAKPOINT_SAME_EL = 0x31,
70 EC_SOFTWARESTEP = 0x32,
71 EC_SOFTWARESTEP_SAME_EL = 0x33,
72 EC_WATCHPOINT = 0x34,
73 EC_WATCHPOINT_SAME_EL = 0x35,
74 EC_AA32_BKPT = 0x38,
75 EC_VECTORCATCH = 0x3a,
76 EC_AA64_BKPT = 0x3c,
77 };
78
79 /* Generic syndrome encoding layout for HSR and lower 32 bits of ESR_EL2 */
80 FIELD(SYNDROME, EC, 26, 6)
81 FIELD(SYNDROME, IL, 25, 1) /* IL=1 for 32 bit instructions */
82 FIELD(SYNDROME, ISS, 0, 25)
83
84 typedef enum {
85 SME_ET_AccessTrap,
86 SME_ET_Streaming,
87 SME_ET_NotStreaming,
88 SME_ET_InactiveZA,
89 SME_ET_InaccessibleZT0,
90 } SMEExceptionType;
91
92 typedef enum {
93 GCS_ET_DataCheck,
94 GCS_ET_EXLOCK,
95 GCS_ET_GCSSTR_GCSSTTR,
96 } GCSExceptionType;
97
98 typedef enum {
99 GCS_IT_RET_nPauth = 0,
100 GCS_IT_GCSPOPM = 1,
101 GCS_IT_RET_PauthA = 2,
102 GCS_IT_RET_PauthB = 3,
103 GCS_IT_GCSSS1 = 4,
104 GCS_IT_GCSSS2 = 5,
105 GCS_IT_GCSPOPCX = 8,
106 GCS_IT_GCSPOPX = 9,
107 } GCSInstructionType;
108
109 static inline uint32_t syn_get_ec(uint32_t syn)
110 {
111 return FIELD_EX32(syn, SYNDROME, EC);
112 }
113
114 static inline uint32_t syn_set_ec(uint32_t syn, uint32_t ec)
115 {
116 return FIELD_DP32(syn, SYNDROME, EC, ec);
117 }
118
119 /*
120 * Utility functions for constructing various kinds of syndrome value.
121 * Note that in general we follow the AArch64 syndrome values; in a
122 * few cases the value in HSR for exceptions taken to AArch32 Hyp
123 * mode differs slightly, and we fix this up when populating HSR in
124 * arm_cpu_do_interrupt_aarch32_hyp().
125 * The exception is FP/SIMD access traps -- these report extra information
126 * when taking an exception to AArch32. For those we include the extra coproc
127 * and TA fields, and mask them out when taking the exception to AArch64.
128 */
129 static inline uint32_t syn_uncategorized(void)
130 {
131 uint32_t res = syn_set_ec(0, EC_UNCATEGORIZED);
132 res = FIELD_DP32(res, SYNDROME, IL, 1);
133 return res;
134 }
135
136 FIELD(ISS_IMM16, IMM16, 0, 16)
137
138 static inline uint32_t syn_aa64_svc(uint32_t imm16)
139 {
140 uint32_t res = syn_set_ec(0, EC_AA64_SVC);
141 res = FIELD_DP32(res, SYNDROME, IL, 1);
142 res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
143 return res;
144 }
145
146 static inline uint32_t syn_aa64_hvc(uint32_t imm16)
147 {
148 uint32_t res = syn_set_ec(0, EC_AA64_HVC);
149 res = FIELD_DP32(res, SYNDROME, IL, 1);
150 res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
151 return res;
152 }
153
154 static inline uint32_t syn_aa64_smc(uint32_t imm16)
155 {
156 uint32_t res = syn_set_ec(0, EC_AA64_SMC);
157 res = FIELD_DP32(res, SYNDROME, IL, 1);
158 res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
159 return res;
160 }
161
162 static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
163 {
164 uint32_t res = syn_set_ec(0, EC_AA32_SVC);
165 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
166 res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
167 return res;
168 }
169
170 static inline uint32_t syn_aa32_hvc(uint32_t imm16)
171 {
172 uint32_t res = syn_set_ec(0, EC_AA32_HVC);
173 res = FIELD_DP32(res, SYNDROME, IL, 1);
174 res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
175 return res;
176 }
177
178 static inline uint32_t syn_aa32_smc(void)
179 {
180 uint32_t res = syn_set_ec(0, EC_AA32_SMC);
181 res = FIELD_DP32(res, SYNDROME, IL, 1);
182 return res;
183 }
184
185 static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
186 {
187 uint32_t res = syn_set_ec(0, EC_AA64_BKPT);
188 res = FIELD_DP32(res, SYNDROME, IL, 1);
189 res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
190 return res;
191 }
192
193 static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
194 {
195 uint32_t res = syn_set_ec(0, EC_AA32_BKPT);
196 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
197 res = FIELD_DP32(res, ISS_IMM16, IMM16, imm16);
198 return res;
199 }
200
201 /*
202 * ISS encoding for an exception from MSR, MRS, or System instruction
203 * in AArch64 state.
204 */
205 FIELD(SYSREG_ISS, ISREAD, 0, 1) /* Direction, 1 is read */
206 FIELD(SYSREG_ISS, CRM, 1, 4)
207 FIELD(SYSREG_ISS, RT, 5, 5)
208 FIELD(SYSREG_ISS, CRN, 10, 4)
209 FIELD(SYSREG_ISS, OP1, 14, 3)
210 FIELD(SYSREG_ISS, OP2, 17, 3)
211 FIELD(SYSREG_ISS, OP0, 20, 2)
212
213 static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
214 int crn, int crm, int rt,
215 int isread)
216 {
217 uint32_t res = syn_set_ec(0, EC_SYSTEMREGISTERTRAP);
218 res = FIELD_DP32(res, SYNDROME, IL, 1);
219
220 res = FIELD_DP32(res, SYSREG_ISS, OP0, op0);
221 res = FIELD_DP32(res, SYSREG_ISS, OP2, op2);
222 res = FIELD_DP32(res, SYSREG_ISS, OP1, op1);
223 res = FIELD_DP32(res, SYSREG_ISS, CRN, crn);
224 res = FIELD_DP32(res, SYSREG_ISS, RT, rt);
225 res = FIELD_DP32(res, SYSREG_ISS, CRM, crm);
226 res = FIELD_DP32(res, SYSREG_ISS, ISREAD, isread);
227
228 return res;
229 }
230
231 /*
232 * ISS encoding for an exception from an MCR or MRC access
233 * (move to/from co-processor)
234 */
235 FIELD(COPROC_ISS, ISREAD, 0, 1)
236 FIELD(COPROC_ISS, CRM, 1, 4)
237 FIELD(COPROC_ISS, RT, 5, 5)
238 FIELD(COPROC_ISS, CRN, 10, 4)
239 FIELD(COPROC_ISS, OP1, 14, 3)
240 FIELD(COPROC_ISS, OP2, 17, 3)
241 FIELD(COPROC_ISS, COND, 20, 4)
242 FIELD(COPROC_ISS, CV, 24, 1)
243
244 static inline uint32_t syn_cp10_rt_trap(int cv, int cond, int opc1,
245 int crn, int rt, int isread)
246 {
247 uint32_t res = syn_set_ec(0, EC_FPIDTRAP);
248 res = FIELD_DP32(res, SYNDROME, IL, 1);
249
250 res = FIELD_DP32(res, COPROC_ISS, CV, cv);
251 res = FIELD_DP32(res, COPROC_ISS, COND, cond);
252 res = FIELD_DP32(res, COPROC_ISS, OP1, opc1);
253 res = FIELD_DP32(res, COPROC_ISS, CRN, crn);
254 res = FIELD_DP32(res, COPROC_ISS, RT, rt);
255 res = FIELD_DP32(res, COPROC_ISS, ISREAD, isread);
256
257 return res;
258 }
259
260 static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
261 int crn, int crm, int rt, int isread,
262 bool is_16bit)
263 {
264 uint32_t res = syn_set_ec(0, EC_CP14RTTRAP);
265 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
266
267 res = FIELD_DP32(res, COPROC_ISS, CV, cv);
268 res = FIELD_DP32(res, COPROC_ISS, COND, cond);
269 res = FIELD_DP32(res, COPROC_ISS, OP2, opc2);
270 res = FIELD_DP32(res, COPROC_ISS, OP1, opc1);
271 res = FIELD_DP32(res, COPROC_ISS, CRN, crn);
272 res = FIELD_DP32(res, COPROC_ISS, RT, rt);
273 res = FIELD_DP32(res, COPROC_ISS, CRM, crm);
274 res = FIELD_DP32(res, COPROC_ISS, ISREAD, isread);
275
276 return res;
277 }
278
279 static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
280 int crn, int crm, int rt, int isread,
281 bool is_16bit)
282 {
283 uint32_t res = syn_set_ec(0, EC_CP15RTTRAP);
284 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
285
286 res = FIELD_DP32(res, COPROC_ISS, CV, cv);
287 res = FIELD_DP32(res, COPROC_ISS, COND, cond);
288 res = FIELD_DP32(res, COPROC_ISS, OP2, opc2);
289 res = FIELD_DP32(res, COPROC_ISS, OP1, opc1);
290 res = FIELD_DP32(res, COPROC_ISS, CRN, crn);
291 res = FIELD_DP32(res, COPROC_ISS, RT, rt);
292 res = FIELD_DP32(res, COPROC_ISS, CRM, crm);
293 res = FIELD_DP32(res, COPROC_ISS, ISREAD, isread);
294
295 return res;
296 }
297
298 /*
299 * ISS encoding for an exception from an MCRR or MRRC access
300 * (move to/from co-processor with 2 regs)
301 */
302 FIELD(COPROC_R2_ISS, ISREAD, 0, 1)
303 FIELD(COPROC_R2_ISS, CRM, 1, 4)
304 FIELD(COPROC_R2_ISS, RT, 5, 5)
305 FIELD(COPROC_R2_ISS, RT2, 10, 5)
306 FIELD(COPROC_R2_ISS, OP1, 16, 4)
307 FIELD(COPROC_R2_ISS, COND, 20, 4)
308 FIELD(COPROC_R2_ISS, CV, 24, 1)
309
310 static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
311 int rt, int rt2, int isread,
312 bool is_16bit)
313 {
314 uint32_t res = syn_set_ec(0, EC_CP14RRTTRAP);
315 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
316
317 res = FIELD_DP32(res, COPROC_R2_ISS, CV, cv);
318 res = FIELD_DP32(res, COPROC_R2_ISS, COND, cond);
319 res = FIELD_DP32(res, COPROC_R2_ISS, OP1, opc1);
320 res = FIELD_DP32(res, COPROC_R2_ISS, RT2, rt2);
321 res = FIELD_DP32(res, COPROC_R2_ISS, RT, rt);
322 res = FIELD_DP32(res, COPROC_R2_ISS, CRM, crm);
323 res = FIELD_DP32(res, COPROC_R2_ISS, ISREAD, isread);
324
325 return res;
326 }
327
328 static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
329 int rt, int rt2, int isread,
330 bool is_16bit)
331 {
332 uint32_t res = syn_set_ec(0, EC_CP15RRTTRAP);
333 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
334
335 res = FIELD_DP32(res, COPROC_R2_ISS, CV, cv);
336 res = FIELD_DP32(res, COPROC_R2_ISS, COND, cond);
337 res = FIELD_DP32(res, COPROC_R2_ISS, OP1, opc1);
338 res = FIELD_DP32(res, COPROC_R2_ISS, RT2, rt2);
339 res = FIELD_DP32(res, COPROC_R2_ISS, RT, rt);
340 res = FIELD_DP32(res, COPROC_R2_ISS, CRM, crm);
341 res = FIELD_DP32(res, COPROC_R2_ISS, ISREAD, isread);
342
343 return res;
344 }
345
346 /*
347 * ISS encoding for an exception from an access to a register of
348 * instruction resulting from the FPEN or TFP traps. Note that
349 * the TA and COPROC fields are only valid when an AArch32 insn
350 * traps to AArch32 EL2; they are RES0 for traps to AArch64.
351 */
352 FIELD(FP_ISS, COPROC, 0, 4)
353 FIELD(FP_ISS, TA, 5, 1)
354 FIELD(FP_ISS, COND, 20, 4)
355 FIELD(FP_ISS, CV, 24, 1)
356
357 static inline uint32_t syn_a64_fp_access_trap(int cv, int cond)
358 {
359 /* AArch64 FP/SIMD trap: TA and coproc are RES0, insn is 64 bits */
360 uint32_t res = syn_set_ec(0, EC_ADVSIMDFPACCESSTRAP);
361 res = FIELD_DP32(res, SYNDROME, IL, 1);
362
363 res = FIELD_DP32(res, FP_ISS, CV, cv);
364 res = FIELD_DP32(res, FP_ISS, COND, cond);
365
366 return res;
367 }
368
369 static inline uint32_t syn_a32_fp_access_trap(int cv, int cond,
370 int ta, int coproc)
371 {
372 /* AArch32 VFP or Neon trap: TA and coproc valid, insn is 64 bits */
373 uint32_t res = syn_set_ec(0, EC_ADVSIMDFPACCESSTRAP);
374 res = FIELD_DP32(res, SYNDROME, IL, 1);
375
376 res = FIELD_DP32(res, FP_ISS, CV, cv);
377 res = FIELD_DP32(res, FP_ISS, COND, cond);
378 res = FIELD_DP32(res, FP_ISS, TA, ta);
379 res = FIELD_DP32(res, FP_ISS, COPROC, coproc);
380
381 return res;
382 }
383
384 static inline uint32_t syn_sve_access_trap(void)
385 {
386 uint32_t res = syn_set_ec(0, EC_SVEACCESSTRAP);
387 res = FIELD_DP32(res, SYNDROME, IL, 1);
388 return res;
389 }
390
391 /*
392 * ISS encoding for an exception from an ERET, ERETAA or ERETAB
393 * instructions.
394 *
395 * eret_op is bits [1:0] of the ERET instruction, so:
396 * 0 for ERET, 2 for ERETAA, 3 for ERETAB.
397 */
398 FIELD(ERET_ISS, OP, 0, 2)
399
400 static inline uint32_t syn_erettrap(int eret_op)
401 {
402 uint32_t res = syn_set_ec(0, EC_ERETTRAP);
403 res = FIELD_DP32(res, SYNDROME, IL, 1);
404 res = FIELD_DP32(res, ERET_ISS, OP, eret_op);
405
406 return res;
407 }
408
409 /*
410 * ISS encoding for an exception due to SME functionality
411 */
412 FIELD(SME_ISS, SMTC, 0, 2)
413
414 static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
415 {
416 uint32_t res = syn_set_ec(0, EC_SMETRAP);
417 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
418 res = FIELD_DP32(res, SME_ISS, SMTC, etype);
419
420 return res;
421 }
422
423 /*
424 * ISS encoding for a PAC Fail exceptions
425 */
426 FIELD(PACFAIL_ISS, BnA, 0, 1) /* B key or A key */
427 FIELD(PACFAIL_ISS, DnI, 1, 1) /* Data or Instruction */
428
429 static inline uint32_t syn_pacfail(bool data, int keynumber)
430 {
431 uint32_t res = syn_set_ec(0, EC_PACFAIL);
432 res = FIELD_DP32(res, SYNDROME, IL, 1);
433
434 res = FIELD_DP32(res, PACFAIL_ISS, DnI, data);
435 res = FIELD_DP32(res, PACFAIL_ISS, BnA, keynumber);
436
437 return res;
438 }
439
440 /*
441 * ISS encoding for an exception from a trapped Pointer
442 * Authentication instruction is RES0
443 */
444 static inline uint32_t syn_pactrap(void)
445 {
446 uint32_t res = syn_set_ec(0, EC_PACTRAP);
447 res = FIELD_DP32(res, SYNDROME, IL, 1);
448 return res;
449 }
450
451 /*
452 * ISS encoding for an exception from a Branch Target Identification
453 * instruction.
454 */
455 FIELD(BTI_ISS, BTYPE, 0, 2)
456
457 static inline uint32_t syn_btitrap(int btype)
458 {
459 uint32_t res = syn_set_ec(0, EC_BTITRAP);
460 res = FIELD_DP32(res, SYNDROME, IL, 1);
461 res = FIELD_DP32(res, BTI_ISS, BTYPE, btype);
462 return res;
463 }
464
465 /*
466 * ISS encoding for trapped BXJ execution
467 *
468 * This is an Armv7 encoding.
469 */
470 FIELD(BXJ_ISS, RM, 0, 4)
471 /* bits 4:19 are Reserved, UNK/SBZP */
472 FIELD(BXJ_ISS, COND, 20, 4)
473 FIELD(BXJ_ISS, CV, 24, 1)
474
475 static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
476 {
477 uint32_t res = syn_set_ec(0, EC_BXJTRAP);
478 res = FIELD_DP32(res, SYNDROME, IL, 1);
479
480 res = FIELD_DP32(res, BXJ_ISS, CV, cv);
481 res = FIELD_DP32(res, BXJ_ISS, COND, cond);
482 res = FIELD_DP32(res, BXJ_ISS, RM, rm);
483
484 return res;
485 }
486
487 /*
488 * ISS encoding for a Granule Protection Check exception
489 *
490 * These are only reported to EL3
491 */
492 FIELD(GPC_ISS, xFSC, 0, 6)
493 FIELD(GPC_ISS, WnR, 6, 1) /* Write not Read */
494 FIELD(GPC_ISS, S1PTW, 7, 1)
495 FIELD(GPC_ISS, CM, 8, 1)
496 FIELD(GPC_ISS, VNCR, 13, 1)
497 FIELD(GPC_ISS, GPCSC, 14, 6)
498 FIELD(GPC_ISS, InD, 20, 1) /* Instruction not Data access */
499 FIELD(GPC_ISS, S2PTW, 21, 1)
500
501 static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc, int vncr,
502 int cm, int s1ptw, int wnr, int fsc)
503 {
504 uint32_t res = syn_set_ec(0, EC_GPC);
505 res = FIELD_DP32(res, SYNDROME, IL, 1);
506
507 res = FIELD_DP32(res, GPC_ISS, S2PTW, s2ptw);
508 res = FIELD_DP32(res, GPC_ISS, InD, ind);
509 res = FIELD_DP32(res, GPC_ISS, GPCSC, gpcsc);
510 res = FIELD_DP32(res, GPC_ISS, VNCR, vncr);
511 res = FIELD_DP32(res, GPC_ISS, CM, cm);
512 res = FIELD_DP32(res, GPC_ISS, S1PTW, s1ptw);
513 res = FIELD_DP32(res, GPC_ISS, WnR, wnr);
514 res = FIELD_DP32(res, GPC_ISS, xFSC, fsc);
515
516 return res;
517 }
518
519 /*
520 * ISS encoding for an exception from an Instruction Abort
521 *
522 * (aka instruction abort)
523 */
524 FIELD(IABORT_ISS, IFSC, 0, 6)
525 FIELD(IABORT_ISS, S1PTW, 7, 1)
526 FIELD(IABORT_ISS, EA, 9, 1)
527 FIELD(IABORT_ISS, FnV, 10, 1) /* FAR not Valid */
528 FIELD(IABORT_ISS, SET, 11, 2)
529 FIELD(IABORT_ISS, PFV, 14, 1)
530 FIELD(IABORT_ISS, TopLevel, 21, 1) /* FEAT_THE */
531
532 static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
533 {
534 uint32_t res = syn_set_ec(0, EC_INSNABORT + same_el);
535 res = FIELD_DP32(res, SYNDROME, IL, 1);
536
537 res = FIELD_DP32(res, IABORT_ISS, EA, ea);
538 res = FIELD_DP32(res, IABORT_ISS, S1PTW, s1ptw);
539 res = FIELD_DP32(res, IABORT_ISS, IFSC, fsc);
540
541 return res;
542 }
543
544 /*
545 * ISS encoding for an exception from a Data Abort
546 */
547 FIELD(DABORT_ISS, DFSC, 0, 6)
548 FIELD(DABORT_ISS, WNR, 6, 1)
549 FIELD(DABORT_ISS, S1PTW, 7, 1)
550 FIELD(DABORT_ISS, CM, 8, 1)
551 FIELD(DABORT_ISS, EA, 9, 1)
552 FIELD(DABORT_ISS, FnV, 10, 1)
553 FIELD(DABORT_ISS, LST, 11, 2)
554 FIELD(DABORT_ISS, VNCR, 13, 1)
555 FIELD(DABORT_ISS, AR, 14, 1)
556 FIELD(DABORT_ISS, SF, 15, 1)
557 FIELD(DABORT_ISS, SRT, 16, 5)
558 FIELD(DABORT_ISS, SSE, 21, 1)
559 FIELD(DABORT_ISS, SAS, 22, 2)
560 FIELD(DABORT_ISS, ISV, 24, 1)
561
562 static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
563 int ea, int cm, int s1ptw,
564 int wnr, int fsc)
565 {
566 uint32_t res = syn_set_ec(0, EC_DATAABORT + same_el);
567 res = FIELD_DP32(res, SYNDROME, IL, 1);
568
569 res = FIELD_DP32(res, DABORT_ISS, FnV, fnv);
570 res = FIELD_DP32(res, DABORT_ISS, EA, ea);
571 res = FIELD_DP32(res, DABORT_ISS, CM, cm);
572 res = FIELD_DP32(res, DABORT_ISS, S1PTW, s1ptw);
573 res = FIELD_DP32(res, DABORT_ISS, WNR, wnr);
574 res = FIELD_DP32(res, DABORT_ISS, DFSC, fsc);
575
576 return res;
577 }
578
579 static inline uint32_t syn_data_abort_with_iss(int same_el,
580 int sas, int sse, int srt,
581 int sf, int ar,
582 int ea, int cm, int s1ptw,
583 int wnr, int fsc,
584 bool is_16bit)
585 {
586 uint32_t res = syn_set_ec(0, EC_DATAABORT + same_el);
587 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
588
589 res = FIELD_DP32(res, DABORT_ISS, ISV, 1);
590 res = FIELD_DP32(res, DABORT_ISS, SAS, sas);
591 res = FIELD_DP32(res, DABORT_ISS, SSE, sse);
592 res = FIELD_DP32(res, DABORT_ISS, SRT, srt);
593 res = FIELD_DP32(res, DABORT_ISS, SF, sf);
594 res = FIELD_DP32(res, DABORT_ISS, AR, ar);
595 res = FIELD_DP32(res, DABORT_ISS, EA, ea);
596 res = FIELD_DP32(res, DABORT_ISS, CM, cm);
597 res = FIELD_DP32(res, DABORT_ISS, S1PTW, s1ptw);
598 res = FIELD_DP32(res, DABORT_ISS, WNR, wnr);
599 res = FIELD_DP32(res, DABORT_ISS, DFSC, fsc);
600
601 return res;
602 }
603
604 /*
605 * Faults due to FEAT_NV2 VNCR_EL2-based accesses report as same-EL
606 * Data Aborts with the VNCR bit set.
607 */
608 static inline uint32_t syn_data_abort_vncr(int ea, int wnr, int fsc)
609 {
610 uint32_t res = syn_set_ec(0, EC_DATAABORT_SAME_EL);
611 res = FIELD_DP32(res, SYNDROME, IL, 1);
612
613 res = FIELD_DP32(res, DABORT_ISS, VNCR, 1);
614 res = FIELD_DP32(res, DABORT_ISS, WNR, wnr);
615 res = FIELD_DP32(res, DABORT_ISS, DFSC, fsc);
616
617 return res;
618 }
619
620 /*
621 * ISS encoding for an exception from a Software Step exception.
622 */
623 FIELD(SOFTSTEP_ISS, IFSC, 0, 6)
624 FIELD(SOFTSTEP_ISS, EX, 6, 1)
625 FIELD(SOFTSTEP_ISS, ISV, 24, 1)
626
627 static inline uint32_t syn_swstep(int same_el, int isv, int ex)
628 {
629 uint32_t res = syn_set_ec(0, EC_SOFTWARESTEP + same_el);
630 res = FIELD_DP32(res, SYNDROME, IL, 1);
631
632 res = FIELD_DP32(res, SOFTSTEP_ISS, ISV, isv);
633 res = FIELD_DP32(res, SOFTSTEP_ISS, EX, ex);
634 res = FIELD_DP32(res, SOFTSTEP_ISS, IFSC, 0x22);
635
636 return res;
637 }
638
639 /*
640 * ISS encoding for an exception from a Watchpoint exception
641 */
642 FIELD(WATCHPOINT_ISS, DFSC, 0, 6)
643 FIELD(WATCHPOINT_ISS, WNR, 6, 1)
644 FIELD(WATCHPOINT_ISS, CM, 8, 1)
645 FIELD(WATCHPOINT_ISS, FnV, 10, 1)
646 FIELD(WATCHPOINT_ISS, VNCR, 13, 1) /* FEAT_NV2 */
647 FIELD(WATCHPOINT_ISS, FnP, 15, 1)
648 FIELD(WATCHPOINT_ISS, WPF, 16, 1)
649 /* bellow mandatory from FEAT_Debugv8p9 */
650 FIELD(WATCHPOINT_ISS, WPTV, 17, 1) /* FEAT_Debugv8p2 - WPT valid */
651 FIELD(WATCHPOINT_ISS, WPT, 18, 6) /* FEAT_Debugv8p2 - missing WP number */
652
653 static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
654 {
655 uint32_t res = syn_set_ec(0, EC_WATCHPOINT + same_el);
656 res = FIELD_DP32(res, SYNDROME, IL, 1);
657
658 res = FIELD_DP32(res, WATCHPOINT_ISS, CM, cm);
659 res = FIELD_DP32(res, WATCHPOINT_ISS, WNR, wnr);
660 res = FIELD_DP32(res, WATCHPOINT_ISS, DFSC, 0x22);
661
662 return res;
663 }
664
665 /*
666 * ISS encoding for an exception from a Breakpoint or a Vector Catch
667 * debug exception.
668 */
669 FIELD(BREAKPOINT_ISS, IFSC, 0, 6)
670
671 static inline uint32_t syn_breakpoint(int same_el)
672 {
673 uint32_t res = syn_set_ec(0, EC_BREAKPOINT + same_el);
674 res = FIELD_DP32(res, SYNDROME, IL, 1);
675 res = FIELD_DP32(res, BREAKPOINT_ISS, IFSC, 0x22);
676
677 return res;
678 }
679
680 /*
681 * ISS encoding for an exception from a WF* instruction
682 */
683 FIELD(WFX_ISS, TI, 0, 2)
684 FIELD(WFX_ISS, RV, 2, 1)
685 FIELD(WFX_ISS, RN, 5, 5)
686 FIELD(WFX_ISS, COND, 20, 4)
687 FIELD(WFX_ISS, CV, 24, 1)
688
689 typedef enum {
690 WFI = 0b00,
691 WFE = 0b01,
692 WFIT = 0b10,
693 WFET = 0b11
694 } wfx_ti;
695
696 static inline uint32_t syn_wfx(int cv, int cond, int rn, bool rv, wfx_ti ti, bool is_16bit)
697 {
698 uint32_t res = syn_set_ec(0, EC_WFX_TRAP);
699 res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
700
701 res = FIELD_DP32(res, WFX_ISS, CV, cv);
702 res = FIELD_DP32(res, WFX_ISS, COND, cond);
703 res = FIELD_DP32(res, WFX_ISS, TI, ti);
704 res = FIELD_DP32(res, WFX_ISS, RN, rn);
705 res = FIELD_DP32(res, WFX_ISS, RV, rv);
706
707 return res;
708 }
709
710 static inline uint32_t syn_illegalstate(void)
711 {
712 uint32_t res = syn_set_ec(0, EC_ILLEGALSTATE);
713 res = FIELD_DP32(res, SYNDROME, IL, 1);
714 return res;
715 }
716
717 static inline uint32_t syn_pcalignment(void)
718 {
719 uint32_t res = syn_set_ec(0, EC_PCALIGNMENT);
720 res = FIELD_DP32(res, SYNDROME, IL, 1);
721 return res;
722 }
723
724 /*
725 * ISS encoding for a GCS exception
726 *
727 * Field validity depends on EXTYPE
728 */
729 FIELD(GCS_ISS, IT, 0, 5)
730 FIELD(GCS_ISS, RN, 5, 5) /* only for non EXLOCK exceptions */
731 FIELD(GCS_ISS, RADDR, 10, 5) /* only for GCSSTR/GCSSTTR traps */
732 FIELD(GCS_ISS, EXTYPE, 20, 4)
733
734 static inline uint32_t syn_gcs_data_check(GCSInstructionType it, int rn)
735 {
736 uint32_t res = syn_set_ec(0, EC_GCS);
737 res = FIELD_DP32(res, SYNDROME, IL, 1);
738
739 res = FIELD_DP32(res, GCS_ISS, EXTYPE, GCS_ET_DataCheck);
740 res = FIELD_DP32(res, GCS_ISS, RN, rn);
741 res = FIELD_DP32(res, GCS_ISS, IT, it);
742
743 return res;
744 }
745
746 static inline uint32_t syn_gcs_exlock(void)
747 {
748 uint32_t res = syn_set_ec(0, EC_GCS);
749 res = FIELD_DP32(res, SYNDROME, IL, 1);
750
751 res = FIELD_DP32(res, GCS_ISS, EXTYPE, GCS_ET_EXLOCK);
752
753 return res;
754 }
755
756 static inline uint32_t syn_gcs_gcsstr(int raddr, int rn)
757 {
758 uint32_t res = syn_set_ec(0, EC_GCS);
759 res = FIELD_DP32(res, SYNDROME, IL, 1);
760
761 res = FIELD_DP32(res, GCS_ISS, EXTYPE, GCS_ET_GCSSTR_GCSSTTR);
762 res = FIELD_DP32(res, GCS_ISS, RADDR, raddr);
763 res = FIELD_DP32(res, GCS_ISS, RN, rn);
764
765 return res;
766 }
767
768 static inline uint32_t syn_serror(uint32_t extra)
769 {
770 uint32_t res = syn_set_ec(0, EC_SERROR);
771 res = FIELD_DP32(res, SYNDROME, IL, 1);
772 res = FIELD_DP32(res, SYNDROME, ISS, extra);
773 return res;
774 }
775
776 /*
777 * ISS encoding for an exception from the Memory Copy and Memory Set
778 * instructions.
779 */
780 FIELD(MOP_ISS, SIZEREG, 0, 5)
781 FIELD(MOP_ISS, SRCREG, 5, 5)
782 FIELD(MOP_ISS, DESTREG, 10, 5)
783 FIELD(MOP_ISS, FORMATOPT, 16, 2)
784 FIELD(MOP_ISS, OPT_A, 16, 1)
785 FIELD(MOP_ISS, WRONG_OPT, 17, 1)
786 FIELD(MOP_ISS, EPILOGUE, 18, 1)
787 FIELD(MOP_ISS, OPTIONS, 19, 4)
788 FIELD(MOP_ISS, IS_SETG, 23, 1)
789 FIELD(MOP_ISS, MEMINST, 24, 1)
790
791 static inline uint32_t syn_mop(bool is_set, bool is_setg, int options,
792 bool epilogue, bool wrong_option, bool option_a,
793 int destreg, int srcreg, int sizereg)
794 {
795 uint32_t res = syn_set_ec(0, EC_MOP);
796 res = FIELD_DP32(res, SYNDROME, IL, 1);
797
798 res = FIELD_DP32(res, MOP_ISS, MEMINST, is_set);
799 res = FIELD_DP32(res, MOP_ISS, IS_SETG, is_setg);
800 res = FIELD_DP32(res, MOP_ISS, OPTIONS, options);
801 res = FIELD_DP32(res, MOP_ISS, EPILOGUE, epilogue);
802 res = FIELD_DP32(res, MOP_ISS, WRONG_OPT, wrong_option);
803 res = FIELD_DP32(res, MOP_ISS, OPT_A, option_a);
804 res = FIELD_DP32(res, MOP_ISS, DESTREG, destreg);
805 res = FIELD_DP32(res, MOP_ISS, SRCREG, srcreg);
806 res = FIELD_DP32(res, MOP_ISS, SIZEREG, sizereg);
807
808 return res;
809 }
810
811
812 #endif /* TARGET_ARM_SYNDROME_H */