moa_archreg 0.1.4

架构系统寄存器与异常编码常量定义
Documentation
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
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
//! aarch64 架构常量定义

/// 从 `ESR_ELx` 取出异常类别(EC)字段。
pub const fn esr_elx_ec(esr: usize) -> usize {
    ((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT
}

/// 构造 `BRK #imm`(64 位)对应的 `ESR_ELx` 值。
pub const fn esr_elx_val_brk64(imm: usize) -> usize {
    (ESR_ELx_EC_BRK64 << ESR_ELx_EC_SHIFT) | ESR_ELx_IL | ((imm) & 0xffff)
}

/// 由 `(op0,op1,op2,crn,crm)` 拼出 `SYS64` 陷阱的 ISS 系统寄存器编码。
pub const fn esr_elx_sys64_iss_sys_val(
    op0: usize,
    op1: usize,
    op2: usize,
    crn: usize,
    crm: usize,
) -> usize {
    ((op0) << ESR_ELx_SYS64_ISS_OP0_SHIFT)
        | ((op1) << ESR_ELx_SYS64_ISS_OP1_SHIFT)
        | ((op2) << ESR_ELx_SYS64_ISS_OP2_SHIFT)
        | ((crn) << ESR_ELx_SYS64_ISS_CRN_SHIFT)
        | ((crm) << ESR_ELx_SYS64_ISS_CRM_SHIFT)
}

/// 从 `SYS64` 陷阱的 ISS 取出目标寄存器号(Rt)。
pub const fn esr_elx_sys64_iss_rt(esr: usize) -> usize {
    ((esr) & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT
}

/// 把 `SYS64` 陷阱 ISS 还原为 [`sys_reg`] 系统寄存器编码。
pub const fn esr_sys64_to_sysreg(e: usize) -> usize {
    sys_reg(
        ((e) & ESR_ELx_SYS64_ISS_OP0_MASK) >> ESR_ELx_SYS64_ISS_OP0_SHIFT,
        ((e) & ESR_ELx_SYS64_ISS_OP1_MASK) >> ESR_ELx_SYS64_ISS_OP1_SHIFT,
        ((e) & ESR_ELx_SYS64_ISS_CRN_MASK) >> ESR_ELx_SYS64_ISS_CRN_SHIFT,
        ((e) & ESR_ELx_SYS64_ISS_CRM_MASK) >> ESR_ELx_SYS64_ISS_CRM_SHIFT,
        ((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >> ESR_ELx_SYS64_ISS_OP2_SHIFT,
    )
}

/// 把 `CP15`(32 位)陷阱 ISS 还原为 [`sys_reg`] 系统寄存器编码(op0 固定为 3)。
pub const fn esr_cp15_to_sysreg(e: usize) -> usize {
    sys_reg(
        3,
        ((e) & ESR_ELx_SYS64_ISS_OP1_MASK) >> ESR_ELx_SYS64_ISS_OP1_SHIFT,
        ((e) & ESR_ELx_SYS64_ISS_CRN_MASK) >> ESR_ELx_SYS64_ISS_CRN_SHIFT,
        ((e) & ESR_ELx_SYS64_ISS_CRM_MASK) >> ESR_ELx_SYS64_ISS_CRM_SHIFT,
        ((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >> ESR_ELx_SYS64_ISS_OP2_SHIFT,
    )
}

/// 由 `(op1,op2,crn,crm)` 拼出 `CP15`(32 位)陷阱的 ISS 系统寄存器编码。
pub const fn esr_elx_cp15_32_iss_sys_val(op1: usize, op2: usize, crn: usize, crm: usize) -> usize {
    ((op1) << ESR_ELx_CP15_32_ISS_OP1_SHIFT)
        | ((op2) << ESR_ELx_CP15_32_ISS_OP2_SHIFT)
        | ((crn) << ESR_ELx_CP15_32_ISS_CRN_SHIFT)
        | ((crm) << ESR_ELx_CP15_32_ISS_CRM_SHIFT)
}

/// 由 `(op1,crm)` 拼出 `CP15`(64 位)陷阱的 ISS 系统寄存器编码。
pub const fn esr_elx_cp15_64_iss_sys_val(op1: usize, crm: usize) -> usize {
    ((op1) << ESR_ELx_CP15_64_ISS_OP1_SHIFT) | ((crm) << ESR_ELx_CP15_64_ISS_CRM_SHIFT)
}

/// 判断 `ESR_ELx` 是否为数据中止(low/current EL 任一)。
pub const fn esr_is_data_abort(esr: usize) -> bool {
    let ec = esr_elx_ec(esr);
    ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR
}

/// 由 `(op0,op1,crn,crm,op2)` 拼出 `MRS/MSR` 系统寄存器编码。
pub const fn sys_reg(op0: usize, op1: usize, crn: usize, crm: usize, op2: usize) -> usize {
    ((op0) << Op0_shift)
        | ((op1) << Op1_shift)
        | ((crn) << CRn_shift)
        | ((crm) << CRm_shift)
        | ((op2) << Op2_shift)
}

// ---------------------------------------------------------------------------
// 架构常量
// ---------------------------------------------------------------------------

// ---- EL 配置 ----

pub const CurrentEL_EL2: usize = 2 << 2;
/// `HCR_EL2.RW` — EL1 使用 `AArch64`
pub const HCR_RW: usize = 1 << 31;
/// `CPTR_EL2` 默认值:不 trap 任何 FP/SIMD/SVE 访问
pub const CPTR_EL2_DEFAULT: usize = 0x33FF;
/// `CNTHCTL_EL2.EL1PCTEN` — 允许 EL1 访问物理计数器
pub const CNTHCTL_EL1PCTEN: usize = 1 << 0;
/// `CNTHCTL_EL2.EL1PCEN` — 允许 EL1 访问物理 timer
pub const CNTHCTL_EL1PCEN: usize = 1 << 1;
pub const SCTLR_EL1_RES1: usize = 1 << 11 | 1 << 20 | 1 << 22 | 1 << 28 | 1 << 29;
pub const SCTLR_EL2_RES1: usize =
    1 << 4 | 1 << 5 | 1 << 11 | 1 << 16 | 1 << 18 | 1 << 22 | 1 << 23 | 1 << 28 | 1 << 29;
/// 小端(值为 0)
pub const ENDIAN_SET_EL1: usize = 0;
/// 小端(值为 0)
pub const ENDIAN_SET_EL2: usize = 0;
pub const BOOT_CPU_MODE_EL1: usize = 0xe11;
pub const BOOT_CPU_MODE_EL2: usize = 0xe12;

// ---- PSR ----

pub const PSR_F_BIT: usize = 0x00000040;
pub const PSR_I_BIT: usize = 0x00000080;
pub const PSR_A_BIT: usize = 0x00000100;
pub const PSR_D_BIT: usize = 0x00000200;
pub const PSR_MODE_EL0t: usize = 0x00000000;
pub const PSR_MODE_EL1t: usize = 0x00000004;
pub const PSR_MODE_EL1h: usize = 0x00000005;
pub const PSR_MODE_EL2t: usize = 0x00000008;
pub const PSR_MODE_EL2h: usize = 0x00000009;
pub const PSR_MODE_EL3t: usize = 0x0000000c;
pub const PSR_MODE_EL3h: usize = 0x0000000d;
pub const PSR_MODE_MASK: usize = 0x0000000f;
pub const PSR_MODE32_BIT: usize = 0x00000010;

// ---- SCTLR ----

pub const SCTLR_ELx_DSSBS: usize = 1 << 44;
pub const SCTLR_ELx_ENIA: usize = 1 << 31;
pub const SCTLR_ELx_ENIB: usize = 1 << 30;
pub const SCTLR_ELx_ENDA: usize = 1 << 27;
pub const SCTLR_ELx_EE: usize = 1 << 25;
pub const SCTLR_ELx_IESB: usize = 1 << 21;
pub const SCTLR_ELx_WXN: usize = 1 << 19;
pub const SCTLR_ELx_ENDB: usize = 1 << 13;
pub const SCTLR_ELx_I: usize = 1 << 12;
pub const SCTLR_ELx_SA: usize = 1 << 3;
pub const SCTLR_ELx_C: usize = 1 << 2;
pub const SCTLR_ELx_A: usize = 1 << 1;
pub const SCTLR_ELx_M: usize = 1 << 0;
pub const SCTLR_EL1_UCI: usize = 1 << 26;
pub const SCTLR_EL1_E0E: usize = 1 << 24;
pub const SCTLR_EL1_SPAN: usize = 1 << 23;
pub const SCTLR_EL1_NTWE: usize = 1 << 18;
pub const SCTLR_EL1_NTWI: usize = 1 << 16;
pub const SCTLR_EL1_UCT: usize = 1 << 15;
pub const SCTLR_EL1_DZE: usize = 1 << 14;
pub const SCTLR_EL1_UMA: usize = 1 << 9;
pub const SCTLR_EL1_SED: usize = 1 << 8;
pub const SCTLR_EL1_ITD: usize = 1 << 7;
pub const SCTLR_EL1_CP15BEN: usize = 1 << 5;
pub const SCTLR_EL1_SA0: usize = 1 << 4;
/// 内核启用 MMU 时写入 `SCTLR_EL1` 的位集合
pub const SCTLR_EL1_SET: usize = SCTLR_ELx_M
    | SCTLR_ELx_C
    | SCTLR_ELx_SA
    | SCTLR_EL1_SA0
    | SCTLR_EL1_SED
    | SCTLR_ELx_I
    | SCTLR_EL1_DZE
    | SCTLR_EL1_UCT
    | SCTLR_EL1_NTWE
    | SCTLR_ELx_IESB
    | SCTLR_EL1_SPAN
    | ENDIAN_SET_EL1
    | SCTLR_EL1_UCI
    | SCTLR_EL1_RES1;

// ---- TCR ----

pub const TCR_T0SZ_OFFSET: usize = 0;
pub const TCR_T1SZ_OFFSET: usize = 16;
pub const TCR_T0SZ: usize = (64 - moa_vmem::VA_BITS) << TCR_T0SZ_OFFSET;
pub const TCR_T1SZ: usize = (64 - moa_vmem::VA_BITS) << TCR_T1SZ_OFFSET;
pub const TCR_TxSZ: usize = TCR_T0SZ | TCR_T1SZ;
pub const TCR_TxSZ_WIDTH: usize = 6;
pub const TCR_IRGN0_SHIFT: usize = 8;
pub const TCR_IRGN1_SHIFT: usize = 24;
pub const TCR_IRGN0_WBWA: usize = 1 << TCR_IRGN0_SHIFT;
pub const TCR_IRGN1_WBWA: usize = 1 << TCR_IRGN1_SHIFT;
pub const TCR_IRGN_WBWA: usize = TCR_IRGN0_WBWA | TCR_IRGN1_WBWA;
pub const TCR_ORGN0_SHIFT: usize = 10;
pub const TCR_ORGN1_SHIFT: usize = 26;
pub const TCR_ORGN0_WBWA: usize = 1 << TCR_ORGN0_SHIFT;
pub const TCR_ORGN1_WBWA: usize = 1 << TCR_ORGN1_SHIFT;
pub const TCR_ORGN_WBWA: usize = TCR_ORGN0_WBWA | TCR_ORGN1_WBWA;
pub const TCR_SH0_SHIFT: usize = 12;
pub const TCR_SH1_SHIFT: usize = 28;
pub const TCR_SH0_INNER: usize = 3 << TCR_SH0_SHIFT;
pub const TCR_SH1_INNER: usize = 3 << TCR_SH1_SHIFT;
pub const TCR_SHARED: usize = TCR_SH0_INNER | TCR_SH1_INNER;
pub const TCR_TG0_SHIFT: usize = 14;
pub const TCR_TG1_SHIFT: usize = 30;
pub const TCR_TG0_4K: usize = 0 << TCR_TG0_SHIFT;
pub const TCR_TG1_4K: usize = 2 << TCR_TG1_SHIFT;
pub const TCR_CACHE_FLAGS: usize = TCR_IRGN_WBWA | TCR_ORGN_WBWA;
pub const TCR_SMP_FLAGS: usize = TCR_SHARED;
pub const TCR_TG_FLAGS: usize = TCR_TG0_4K | TCR_TG1_4K;
pub const TCR_A1: usize = 1 << 22;
pub const TCR_ASID16: usize = 1 << 36;
pub const TCR_TBI0: usize = 1 << 37;

// ---- ID_AA64MMFR0 ----

pub const ID_AA64MMFR0_PARANGE_48: usize = 0x5;
pub const ID_AA64MMFR0_PARANGE_MAX: usize = ID_AA64MMFR0_PARANGE_48;
pub const ID_AA64MMFR0_PARANGE_SHIFT: usize = 0;
pub const TCR_IPS_SHIFT: usize = 32;
pub const ID_AA64MMFR0_TGRAN4_SHIFT: usize = 28;
pub const ID_AA64MMFR0_TGRAN4_SUPPORTED: usize = 0;
pub const ID_AA64MMFR0_TGRAN_SHIFT: usize = ID_AA64MMFR0_TGRAN4_SHIFT;
pub const ID_AA64MMFR0_TGRAN_SUPPORTED: usize = ID_AA64MMFR0_TGRAN4_SUPPORTED;

// ---- ESR ----

pub const ESR_ELx_EC_UNKNOWN: usize = 0x00;
pub const ESR_ELx_EC_WFx: usize = 0x01;
// Unallocated EC: 0x02
pub const ESR_ELx_EC_CP15_32: usize = 0x03;
pub const ESR_ELx_EC_CP15_64: usize = 0x04;
pub const ESR_ELx_EC_CP14_MR: usize = 0x05;
pub const ESR_ELx_EC_CP14_LS: usize = 0x06;
pub const ESR_ELx_EC_FP_ASIMD: usize = 0x07;
pub const ESR_ELx_EC_CP10_ID: usize = 0x08;
pub const ESR_ELx_EC_PAC: usize = 0x09;
// Unallocated EC: 0x0A - 0x0B
pub const ESR_ELx_EC_CP14_64: usize = 0x0C;
// Unallocated EC: 0x0d
pub const ESR_ELx_EC_ILL: usize = 0x0E;
// Unallocated EC: 0x0F - 0x10
pub const ESR_ELx_EC_SVC32: usize = 0x11;
pub const ESR_ELx_EC_HVC32: usize = 0x12;
pub const ESR_ELx_EC_SMC32: usize = 0x13;
// Unallocated EC: 0x14
pub const ESR_ELx_EC_SVC64: usize = 0x15;
pub const ESR_ELx_EC_HVC64: usize = 0x16;
pub const ESR_ELx_EC_SMC64: usize = 0x17;
pub const ESR_ELx_EC_SYS64: usize = 0x18;
pub const ESR_ELx_EC_SVE: usize = 0x19;
// Unallocated EC: 0x1A - 0x1E
pub const ESR_ELx_EC_IMP_DEF: usize = 0x1f;
pub const ESR_ELx_EC_IABT_LOW: usize = 0x20;
pub const ESR_ELx_EC_IABT_CUR: usize = 0x21;
pub const ESR_ELx_EC_PC_ALIGN: usize = 0x22;
// Unallocated EC: 0x23
pub const ESR_ELx_EC_DABT_LOW: usize = 0x24;
pub const ESR_ELx_EC_DABT_CUR: usize = 0x25;
pub const ESR_ELx_EC_SP_ALIGN: usize = 0x26;
// Unallocated EC: 0x27
pub const ESR_ELx_EC_FP_EXC32: usize = 0x28;
// Unallocated EC: 0x29 - 0x2B
pub const ESR_ELx_EC_FP_EXC64: usize = 0x2C;
// Unallocated EC: 0x2D - 0x2E
pub const ESR_ELx_EC_SERROR: usize = 0x2F;
pub const ESR_ELx_EC_BREAKPT_LOW: usize = 0x30;
pub const ESR_ELx_EC_BREAKPT_CUR: usize = 0x31;
pub const ESR_ELx_EC_SOFTSTP_LOW: usize = 0x32;
pub const ESR_ELx_EC_SOFTSTP_CUR: usize = 0x33;
pub const ESR_ELx_EC_WATCHPT_LOW: usize = 0x34;
pub const ESR_ELx_EC_WATCHPT_CUR: usize = 0x35;
// Unallocated EC: 0x36 - 0x37
pub const ESR_ELx_EC_BKPT32: usize = 0x38;
// Unallocated EC: 0x39
pub const ESR_ELx_EC_VECTOR32: usize = 0x3A;
// Unallocted EC: 0x3B
pub const ESR_ELx_EC_BRK64: usize = 0x3C;
// Unallocated EC: 0x3D - 0x3F
pub const ESR_ELx_EC_MAX: usize = 0x3F;

pub const ESR_ELx_EC_SHIFT: usize = 26;
pub const ESR_ELx_EC_MASK: usize = (0x3F) << ESR_ELx_EC_SHIFT;

pub const ESR_ELx_IL_SHIFT: usize = 25;
pub const ESR_ELx_IL: usize = (1) << ESR_ELx_IL_SHIFT;
pub const ESR_ELx_ISS_MASK: usize = ESR_ELx_IL - 1;

// ISS field definitions shared by different classes
pub const ESR_ELx_WNR_SHIFT: usize = 6;
pub const ESR_ELx_WNR: usize = (1) << ESR_ELx_WNR_SHIFT;

// Asynchronous Error Type
pub const ESR_ELx_IDS_SHIFT: usize = 24;
pub const ESR_ELx_IDS: usize = (1) << ESR_ELx_IDS_SHIFT;
pub const ESR_ELx_AET_SHIFT: usize = 10;
pub const ESR_ELx_AET: usize = (0x7) << ESR_ELx_AET_SHIFT;

pub const ESR_ELx_AET_UC: usize = (0) << ESR_ELx_AET_SHIFT;
pub const ESR_ELx_AET_UEU: usize = (1) << ESR_ELx_AET_SHIFT;
pub const ESR_ELx_AET_UEO: usize = (2) << ESR_ELx_AET_SHIFT;
pub const ESR_ELx_AET_UER: usize = (3) << ESR_ELx_AET_SHIFT;
pub const ESR_ELx_AET_CE: usize = (6) << ESR_ELx_AET_SHIFT;

// Shared ISS field definitions for Data/Instruction aborts
pub const ESR_ELx_SET_SHIFT: usize = 11;
pub const ESR_ELx_SET_MASK: usize = (3) << ESR_ELx_SET_SHIFT;
pub const ESR_ELx_FnV_SHIFT: usize = 10;
pub const ESR_ELx_FnV: usize = (1) << ESR_ELx_FnV_SHIFT;
pub const ESR_ELx_EA_SHIFT: usize = 9;
pub const ESR_ELx_EA: usize = (1) << ESR_ELx_EA_SHIFT;
pub const ESR_ELx_S1PTW_SHIFT: usize = 7;
pub const ESR_ELx_S1PTW: usize = (1) << ESR_ELx_S1PTW_SHIFT;

// Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts
pub const ESR_ELx_FSC: usize = 0x3F;
pub const ESR_ELx_FSC_TYPE: usize = 0x3C;
pub const ESR_ELx_FSC_EXTABT: usize = 0x10;
pub const ESR_ELx_FSC_SERROR: usize = 0x11;
pub const ESR_ELx_FSC_ACCESS: usize = 0x08;
pub const ESR_ELx_FSC_FAT: usize = 0x04;
pub const ESR_ELx_FSC_PERM: usize = 0x0C;

// ISS field definitions for Data Aborts
pub const ESR_ELx_ISV_SHIFT: usize = 24;
pub const ESR_ELx_ISV: usize = (1) << ESR_ELx_ISV_SHIFT;
pub const ESR_ELx_SAS_SHIFT: usize = 22;
pub const ESR_ELx_SAS: usize = (3) << ESR_ELx_SAS_SHIFT;
pub const ESR_ELx_SSE_SHIFT: usize = 21;
pub const ESR_ELx_SSE: usize = (1) << ESR_ELx_SSE_SHIFT;
pub const ESR_ELx_SRT_SHIFT: usize = 16;
pub const ESR_ELx_SRT_MASK: usize = (0x1F) << ESR_ELx_SRT_SHIFT;
pub const ESR_ELx_SF_SHIFT: usize = 15;
pub const ESR_ELx_SF: usize = (1) << ESR_ELx_SF_SHIFT;
pub const ESR_ELx_AR_SHIFT: usize = 14;
pub const ESR_ELx_AR: usize = (1) << ESR_ELx_AR_SHIFT;
pub const ESR_ELx_CM_SHIFT: usize = 8;
pub const ESR_ELx_CM: usize = (1) << ESR_ELx_CM_SHIFT;

// ISS field definitions for exceptions taken in to Hyp
pub const ESR_ELx_CV: usize = (1) << 24;
pub const ESR_ELx_COND_SHIFT: usize = 20;
pub const ESR_ELx_COND_MASK: usize = (0xF) << ESR_ELx_COND_SHIFT;
pub const ESR_ELx_WFx_ISS_TI: usize = (1) << 0;
pub const ESR_ELx_WFx_ISS_WFI: usize = 0;
pub const ESR_ELx_WFx_ISS_WFE: usize = (1) << 0;
pub const ESR_ELx_xVC_IMM_MASK: usize = (1 << 16) - 1;

pub const DISR_EL1_IDS: usize = (1) << 24;
pub const DISR_EL1_ESR_MASK: usize = ESR_ELx_AET | ESR_ELx_EA | ESR_ELx_FSC;

// ESR value templates for specific events
pub const ESR_ELx_WFx_MASK: usize = ESR_ELx_EC_MASK | ESR_ELx_WFx_ISS_TI;
pub const ESR_ELx_WFx_WFI_VAL: usize = (ESR_ELx_EC_WFx << ESR_ELx_EC_SHIFT) | ESR_ELx_WFx_ISS_WFI;

// ISS field definitions for System instruction traps
pub const ESR_ELx_SYS64_ISS_RES0_SHIFT: usize = 22;
pub const ESR_ELx_SYS64_ISS_RES0_MASK: usize = (0x7) << ESR_ELx_SYS64_ISS_RES0_SHIFT;
pub const ESR_ELx_SYS64_ISS_DIR_MASK: usize = 0x1;
pub const ESR_ELx_SYS64_ISS_DIR_READ: usize = 0x1;
pub const ESR_ELx_SYS64_ISS_DIR_WRITE: usize = 0x0;

pub const ESR_ELx_SYS64_ISS_RT_SHIFT: usize = 5;
pub const ESR_ELx_SYS64_ISS_RT_MASK: usize = (0x1f) << ESR_ELx_SYS64_ISS_RT_SHIFT;
pub const ESR_ELx_SYS64_ISS_CRM_SHIFT: usize = 1;
pub const ESR_ELx_SYS64_ISS_CRM_MASK: usize = (0xf) << ESR_ELx_SYS64_ISS_CRM_SHIFT;
pub const ESR_ELx_SYS64_ISS_CRN_SHIFT: usize = 10;
pub const ESR_ELx_SYS64_ISS_CRN_MASK: usize = (0xf) << ESR_ELx_SYS64_ISS_CRN_SHIFT;
pub const ESR_ELx_SYS64_ISS_OP1_SHIFT: usize = 14;
pub const ESR_ELx_SYS64_ISS_OP1_MASK: usize = (0x7) << ESR_ELx_SYS64_ISS_OP1_SHIFT;
pub const ESR_ELx_SYS64_ISS_OP2_SHIFT: usize = 17;
pub const ESR_ELx_SYS64_ISS_OP2_MASK: usize = (0x7) << ESR_ELx_SYS64_ISS_OP2_SHIFT;
pub const ESR_ELx_SYS64_ISS_OP0_SHIFT: usize = 20;
pub const ESR_ELx_SYS64_ISS_OP0_MASK: usize = (0x3) << ESR_ELx_SYS64_ISS_OP0_SHIFT;
pub const ESR_ELx_SYS64_ISS_SYS_MASK: usize = ESR_ELx_SYS64_ISS_OP0_MASK
    | ESR_ELx_SYS64_ISS_OP1_MASK
    | ESR_ELx_SYS64_ISS_OP2_MASK
    | ESR_ELx_SYS64_ISS_CRN_MASK
    | ESR_ELx_SYS64_ISS_CRM_MASK;

pub const ESR_ELx_SYS64_ISS_SYS_OP_MASK: usize =
    ESR_ELx_SYS64_ISS_SYS_MASK | ESR_ELx_SYS64_ISS_DIR_MASK;

// User space cache operations
pub const ESR_ELx_SYS64_ISS_CRM_DC_CIVAC: usize = 14;
pub const ESR_ELx_SYS64_ISS_CRM_DC_CVAP: usize = 12;
pub const ESR_ELx_SYS64_ISS_CRM_DC_CVAU: usize = 11;
pub const ESR_ELx_SYS64_ISS_CRM_DC_CVAC: usize = 10;
pub const ESR_ELx_SYS64_ISS_CRM_IC_IVAU: usize = 5;

pub const ESR_ELx_SYS64_ISS_EL0_CACHE_OP_MASK: usize = ESR_ELx_SYS64_ISS_OP0_MASK
    | ESR_ELx_SYS64_ISS_OP1_MASK
    | ESR_ELx_SYS64_ISS_OP2_MASK
    | ESR_ELx_SYS64_ISS_CRN_MASK
    | ESR_ELx_SYS64_ISS_DIR_MASK;
pub const ESR_ELx_SYS64_ISS_EL0_CACHE_OP_VAL: usize =
    esr_elx_sys64_iss_sys_val(1, 3, 1, 7, 0) | ESR_ELx_SYS64_ISS_DIR_WRITE;

// User space MRS operations
pub const ESR_ELx_SYS64_ISS_SYS_MRS_OP_MASK: usize = ESR_ELx_SYS64_ISS_OP0_MASK
    | ESR_ELx_SYS64_ISS_OP1_MASK
    | ESR_ELx_SYS64_ISS_CRN_MASK
    | ESR_ELx_SYS64_ISS_DIR_MASK;
pub const ESR_ELx_SYS64_ISS_SYS_MRS_OP_VAL: usize =
    esr_elx_sys64_iss_sys_val(3, 0, 0, 0, 0) | ESR_ELx_SYS64_ISS_DIR_READ;

pub const ESR_ELx_SYS64_ISS_SYS_CTR: usize = esr_elx_sys64_iss_sys_val(3, 3, 1, 0, 0);
pub const ESR_ELx_SYS64_ISS_SYS_CTR_READ: usize =
    ESR_ELx_SYS64_ISS_SYS_CTR | ESR_ELx_SYS64_ISS_DIR_READ;

pub const ESR_ELx_SYS64_ISS_SYS_CNTVCT: usize =
    esr_elx_sys64_iss_sys_val(3, 3, 2, 14, 0) | ESR_ELx_SYS64_ISS_DIR_READ;

pub const ESR_ELx_SYS64_ISS_SYS_CNTFRQ: usize =
    esr_elx_sys64_iss_sys_val(3, 3, 0, 14, 0) | ESR_ELx_SYS64_ISS_DIR_READ;

// ISS field definitions for floating-point exception traps
pub const ESR_ELx_FP_EXC_TFV: usize = (1) << 23;

// ISS field definitions for CP15 accesses
pub const ESR_ELx_CP15_32_ISS_DIR_MASK: usize = 0x1;
pub const ESR_ELx_CP15_32_ISS_DIR_READ: usize = 0x1;
pub const ESR_ELx_CP15_32_ISS_DIR_WRITE: usize = 0x0;

pub const ESR_ELx_CP15_32_ISS_RT_SHIFT: usize = 5;
pub const ESR_ELx_CP15_32_ISS_RT_MASK: usize = (0x1f) << ESR_ELx_CP15_32_ISS_RT_SHIFT;
pub const ESR_ELx_CP15_32_ISS_CRM_SHIFT: usize = 1;
pub const ESR_ELx_CP15_32_ISS_CRM_MASK: usize = (0xf) << ESR_ELx_CP15_32_ISS_CRM_SHIFT;
pub const ESR_ELx_CP15_32_ISS_CRN_SHIFT: usize = 10;
pub const ESR_ELx_CP15_32_ISS_CRN_MASK: usize = (0xf) << ESR_ELx_CP15_32_ISS_CRN_SHIFT;
pub const ESR_ELx_CP15_32_ISS_OP1_SHIFT: usize = 14;
pub const ESR_ELx_CP15_32_ISS_OP1_MASK: usize = (0x7) << ESR_ELx_CP15_32_ISS_OP1_SHIFT;
pub const ESR_ELx_CP15_32_ISS_OP2_SHIFT: usize = 17;
pub const ESR_ELx_CP15_32_ISS_OP2_MASK: usize = (0x7) << ESR_ELx_CP15_32_ISS_OP2_SHIFT;

pub const ESR_ELx_CP15_32_ISS_SYS_MASK: usize = ESR_ELx_CP15_32_ISS_OP1_MASK
    | ESR_ELx_CP15_32_ISS_OP2_MASK
    | ESR_ELx_CP15_32_ISS_CRN_MASK
    | ESR_ELx_CP15_32_ISS_CRM_MASK
    | ESR_ELx_CP15_32_ISS_DIR_MASK;

pub const ESR_ELx_CP15_64_ISS_DIR_MASK: usize = 0x1;
pub const ESR_ELx_CP15_64_ISS_DIR_READ: usize = 0x1;
pub const ESR_ELx_CP15_64_ISS_DIR_WRITE: usize = 0x0;

pub const ESR_ELx_CP15_64_ISS_RT_SHIFT: usize = 5;
pub const ESR_ELx_CP15_64_ISS_RT_MASK: usize = (0x1f) << ESR_ELx_CP15_64_ISS_RT_SHIFT;

pub const ESR_ELx_CP15_64_ISS_RT2_SHIFT: usize = 10;
pub const ESR_ELx_CP15_64_ISS_RT2_MASK: usize = (0x1f) << ESR_ELx_CP15_64_ISS_RT2_SHIFT;

pub const ESR_ELx_CP15_64_ISS_OP1_SHIFT: usize = 16;
pub const ESR_ELx_CP15_64_ISS_OP1_MASK: usize = (0xf) << ESR_ELx_CP15_64_ISS_OP1_SHIFT;
pub const ESR_ELx_CP15_64_ISS_CRM_SHIFT: usize = 1;
pub const ESR_ELx_CP15_64_ISS_CRM_MASK: usize = (0xf) << ESR_ELx_CP15_64_ISS_CRM_SHIFT;

pub const ESR_ELx_CP15_64_ISS_SYS_MASK: usize =
    ESR_ELx_CP15_64_ISS_OP1_MASK | ESR_ELx_CP15_64_ISS_CRM_MASK | ESR_ELx_CP15_64_ISS_DIR_MASK;

pub const ESR_ELx_CP15_64_ISS_SYS_CNTVCT: usize =
    esr_elx_cp15_64_iss_sys_val(1, 14) | ESR_ELx_CP15_64_ISS_DIR_READ;

pub const ESR_ELx_CP15_32_ISS_SYS_CNTFRQ: usize =
    esr_elx_cp15_32_iss_sys_val(0, 0, 14, 0) | ESR_ELx_CP15_32_ISS_DIR_READ;

// ---- 系统寄存器编码 ----

pub const Op0_shift: usize = 19;
pub const Op0_mask: usize = 0x3;
pub const Op1_shift: usize = 16;
pub const Op1_mask: usize = 0x7;
pub const CRn_shift: usize = 12;
pub const CRn_mask: usize = 0xf;
pub const CRm_shift: usize = 8;
pub const CRm_mask: usize = 0xf;
pub const Op2_shift: usize = 5;
pub const Op2_mask: usize = 0x7;