About this site
this is a collection of shrik3's personal sys programming and tooling cheatsheet.
Contribute or Comments:
The source (+issue tracker & mailinglist) is hosted at sourcehut Comments and patches are appreciated.
mailinglist (discussion and patches)
~shrik3/syswiki@lists.sr.ht
contributing via email
- clone the code:
git clone https://git.sr.ht/~shrik3/sys.shrik3.com
- make changes and commit
- send the patch
git send-email --to="~shrik3/syswiki@lists.sr.ht" HEAD^
learn about git send-email workflow
issue tracker (tickets)
File an issue here, or send email to
~shrik3/syswiki@todo.sr.ht
"Powered by"
This site is generated with mdbook. The site is deployed to sourcehut pages.
Licensed under
CC BY-NC 4.0
GENERAL & USEFUL RESOURCES
man pages
Noteworthy man pages (archwiki)
- ascii(7)
- boot(7)
- charsets(7)
- chmod(1)
- credentials(7)
- fstab(5)
- file-hierarchy(7)
- systemd(1)
- locale(1p), locale(5), locale(7)
- printf(3)
- proc(5)
- regex(7)
- signal(7)
- term(5), term(7)
- termcap(5)
- terminfo(5)
- utf-8(7)
USEFUL RESOURCES
aarch64 ESR, MIDR and SMCCC decoder
aarch64 register and instruction quick reference
instruction <=> hex en/decoder
x86 and aarch64 cpu timer (system counter) (WIP, explore more context)
4K Granule, 48bits OA, 40bits IPS
Table Descriptor (L0~2)
[63:59] Attributes[4:0]
-63 NSTable
-62:61 APTable (see AP)
-60 UXNTable / XNTable
-59 PXNTable
[58:51] IGNORED
[50:48] RES0
[47:12] Addr[47:12] of next level descriptor
[11:2 ] INORED
[1 ] 1 (table)
[0 ] 1 (valid)
Block Descriptor (L1 and L2)
[63:50] Upper Attributes (Block & Page)
[49:48] RES0
[47:n ] Output Address[47:n] n=30 for L1, n=21 for L2
[n-1:17] RES0
[16 ] nT (FEAT-BBM)
[15:12] RES0
[11:2 ] Lower Attributes (Block & Page)
[1 ] 0 (block)
[0 ] 1 (valid)
Page Descriptor
[63:50] Upper Attributes (Block & Page)
[49:48] RES0
[47:12] Output Address[47:n] n=30 for L1, n=21 for L2
[11:2 ] Lower Attributes (Block & Page)
[1 ] 1 (block)
[0 ] 1 (valid)
Descriptor [63:50] : Block & Page Upper Attributes
[63 ] IGNORED
[62:59] PBHA (FEAT_HPDS2)
[58:55] SW Defined
[54 ] UXN / XN
[53 ] PXN
[52 ] Contiguous
[51 ] DBM (FEAT_HAFDBS)
Descriptor [11:2] : Block & Page Lower Attributes
[11 ] NSE / NG
[10 ] AF
[9:8] SH[1:0]
[7:6] AP[1:0] (see AP)
[5 ] NS (Realm)
[4:2] AttrIdx
AP[1:0] Access Permission
EL1+ EL0
-----------------
00 RW None
01 RW RW
10 RO None
11 RO RO
Memory Type per MAIR_EL1 encoding.
AttrIdx MemType
--------------------------
000 Device nGnRnE
001 Device nGnRE
010 Device GRE
011 Normal NC
100 Normal
101 Normal_WT
110 undefined
111 undefined
MAIR_EL1, Memory Attribute Indirection Register (EL1)
Provides the memory attribute encodings corresponding to the possible AttrIndx values in a Long-descriptor format translation table entry for stage 1 translations at EL1.
Contains 8x Attr
64 56 7 0
| Attr7 | Attr6 | Attr5 | ... | Attr0 |
>>>> Following are all in binary encoding <<<
Attr meaning
---------------------------------
0b0000dd00 Device Memory
0booooiiii Normal memory
oooo != 0000
iiii != 0000
Following are NaN if FEAT_XS not implemented
0000dd01 Device Memory w. XS set to 0
10000000 Normal, Inner NC, Outer NC
10100000 Normal, Inner WT+C, Outer WT+C, RA, NWA, NT with XS=0
11110000 Normal, Tagged, Inner WB, Outer WB, RA, WA, NT;
dd meaning
---------------------------------
00 Device-nGnRnE
01 Device-nGnRE
10 Device-nGRE
11 Device-GRE
oooo meaning
---------------------------------
0000 See Attr encoding
00RW (RW not 00) Normal memory, outer write-through transient
0100 Normal memory, outer non-cacheable
01RW (RW not 00) Normal memory, outer write-back transient
10RW Normal memory, outer write-through non-transient
11RW Normal memory, outer write-back non-transient
iiii Meaning: Same for oooo, but "Inner"
-----------------------------------------------
R or W Meaning (Read-Allocate / Write-Allocate policy)
-----------------------------------------------
0 No Allocate
1 Allocate
Misc:
(N)C : Non-Cacheable
WA/WT/WB : Write Allocate/Write Through/Write Back
NT : Non-transient
(WIP)
TLB instructions
Invalidate TLB entries
TLBI <type><level>{IS} {,<Xt>}
The following code example shows a sequence for writes to translation tables backed by inner shareable memory:
<< Writes to Translation Tables >>
DSB ISHST // ensure write has completed
TLBI ALLE1 // invalidate all TLB entries
DSB ISH // ensure completion of TLB invalidation
ISB // synchronize context and ensure that no instructions are
// fetched using the old translation
For a change to a single entry, for example, use the instruction:
TLBI VAE1, X0
which invalidates an entry associated with the address specified in the register X0.
AT instr: test address translation from VA.
AT S<m>E<n><R/W><P>, <Xt>
<m> translation stage
<n> Exception Level
<R/W> R or W, for Read / Write
<P> OPTIONAL: test with PAN when implemented
<Xt> Holds virtual address
PAR_EL1 Holds result
MRS <Xt>, PAR_EL1
PAR_EL1[63:0]
[63:56] ATTR: Memory Attr, same as in MAIR_EL1
[55:52] RES0
[51:48] PA[51:48] <OPT> / RES0
[47:12] PA[47:12]
[11 ] NSE <OPT> / RES1
[10 ] impl. defined
[9 ] NS (Non Secure)
[8 : 7] SH
[6 : 1] RES0
[0 ] F (1==failure)
Memory Attr Encoding: also see this for details.
It's a 8 bits value:
Value Meaning
---------------------------------
0000dd00 Device Memory
0000dd1x NaN
ooooiiii Normal Memory (oooo!=0000, iiii!=0000)
dd Meaning
---------------------------------
00 Device nGnRnE
01 Device nGnRE
10 Device nGRE
11 Device GRE
oooo Meaning: (Outer)
---------------------------------
0000 NaN
00RW Normal Memory, outer WT Transient (RW!=00)
0100 Normal Memory, outer NC
01RW Normal Memory, outer WB Transient (RW!=00)
10RW Normal Memory, outer WT, NT
11RW Normal Memory, Outer WB, NT
iiii Meaning: Same for oooo, but "Inner"
-----------------------------------------------
R or W Meaning (Read-Allocate / Write-Allocate policy)
-----------------------------------------------
0 No Allocate
1 Allocate
SH[1:0]
00 Non Shareable
10 Outer Shareable
11 Inner Shareable
NS/NSE
// TODO
NSE NS Meaning
------------------------
0 0 Res*
0 1 Non-Secure
1 0 Root
1 1 Realm
* if secure state is implemented: Secure. Otherwise reserved.
This is obsoleted by Realm
ESR Decoder: https://esr.arm64.dev/
Aarch64 translation fault related stuffs.
ESR_EL1
/// TODO ADD ESR_EL1
ESR.EC
- 0x20 - instr abort low
- 0x21 - instr abort current
- 0x24 - data abort low
- 0x25 - data abort current
/// TODO ADD OTHER ECs /// TODO ADD DFSC AND IFSC
ESR.ISS for instr abort
BIT [xx:xx] .
BIT [24] ISV Instruction Syndrome Valid
- Following bits are only valid when isv=1
BITS[23:22] SAS Syndrome Access Size
- 0b00 : 1 x byte
- 0b01 : 2 x byte
- 0b10 : 3 x byte
- 0b11 : 4 x byte
BIT [21] SSE Syndrome Sign Extend
- 0b0 Sign ext not required
- 0b1 sign ext required
BITS[20:16] SRT Syndrome Register Transfer
- register number of Xt/Xt/Rt operands of faulting instr
BIT [15] SF Sixty Four bit general-purpsoe register transfer
- 0b0 instr loads/stores 32-bit GPR
- 0b1 instr loads/stores 64-bit GPR
BIT [14] AR Acquire/Release
BIT [13] VNCR indicates fault came from VNCR_EL2 in EL1 code
BITS[12:11] SET Synchronous Error Type
- When FEAT_RAS is implemented and DFSC == 0b010000
BITS[12:11] LST Load/Store Type
- When FEAT_LS64 is implemented and DFSC == 0b110101
BIT [10] FnV FAR not valid
- 0 FAR is valid
- 1 FAR not valid, value unknown
BIT [9] EA
BIT [8] CM
BIT [7] S1PTW
- 0 Fault NOT on stage 2
- 1 Fault on stage 2
BIT [6] WnR
BITs[5:0] DFSC Data Fault Status Code
ESR.ISS for data abort
BITs[24:13] RES0
BITS[12:11] SET Synchronous Error Type
- When FEAT_RAS is implemented and IFSC == 0b010000
BITS[12:11] LST Load/Store Type
- When FEAT_LS64 is implemented and IFSC == 0b110101
BIT [10] FnV FAR not valid
BIT [9] EA
BIT [8] RES0
BIT [7] S1PTW
BIT [6] RES0
BITs[5:0] IFSC Data Fault Status Code
ESR.ISS.IFSC / DFSC See the documents, it sucks.
PARTIALLY:
// Access Size Fault L0~3
DFSC_ASF_L0 = 0x0;
DFSC_ASF_L1 = 0x1;
DFSC_ASF_L2 = 0x2;
DFSC_ASF_L3 = 0x3;
// Translation Fault L0~3
DFSC_TF_L0 = 0x4;
DFSC_TF_L1 = 0x5;
DFSC_TF_L2 = 0x6;
DFSC_TF_L3 = 0x7;
// Access Flag Fault L0~3
DFSC_AF_L0 = 0x8; /* if FEAT_LPA2 is implmented */
DFSC_AF_L1 = 0x9;
DFSC_AF_L2 = 0xa;
DFSC_AF_L3 = 0xb;
// Permission Fault L0 ~ 3
DFSC_PF_L0 = 0xc; /* if FEAT_LPA2 is implemented */
DFSC_PF_L1 = 0xd;
DFSC_PF_L2 = 0xe;
DFSC_PF_L3 = 0xf;
// Synchronous External Abort (SEA)
// not on translation table walk
DFSC_SEA = 0x10;
// on translation table walk, L -1~3
DFSC_SEA_M1 = 0x13; /* if FEAT_LPA2 is implemented*/
DFSC_SEA_L0 = 0x14;
DFSC_SEA_L1 = 0x15;
DFSC_SEA_L2 = 0x16;
DFSC_SEA_L3 = 0x17;
// Synchronous parity or ECC error when FEAT_RAS NOT implemented.
// not on table walk
DFSC_ECC = 0x18;
// on table walk: L-1~3
DFSC_ECC_M1 = 0x1b;
DFSC_ECC_L0 = 0x1c;
DFSC_ECC_L1 = 0x1d;
DFSC_ECC_L2 = 0x1e;
DFSC_ECC_L3 = 0x1f;
pub const DFSC_ALIGN:u64 = 0x21;
// the Granule Protection Faults
// GPF on table walk, L-1~3
DFSC_GPF_M1 = 0x23;
DFSC_GPF_L0 = 0x23;
DFSC_GPF_L1 = 0x25;
DFSC_GPF_L2 = 0x26;
DFSC_GPF_L3 = 0x27;
// GPF not on table walk
pub const DFSC_GPF = 0x28;
DFSC_ASF_M1 = 0x29;
DFSC_TF_M1 = 0x2b;
DFSC_TLB_CONFLICT = 0x30;
// unsupported atomic hardware update
DFSC_UAHU = 0x31;
https://developer.arm.com/documentation/ddi0595/2021-12/AArch64-Registers/ESR-EL1--Exception-Syndrome-Register--EL1-?lang=en#fieldset_0-24_0_13
ESR_EL1 (Exception Syndrome Register (EL1)
bit range is inclusive on both ends
-----------------------------------
BITS[63:37] RES0
BITS[36:32] ISS2 < when FEAT_LS64 implemented
BITS[31:26] EC Exception Class
BIT [25] IL Instruction Length for sync exceptions
- 0 : 16bit instruction trapped
- 1 : 32bit Instruction trapped
BITS[24:0 ] ISS Instruction Specific Syndrome
EC in ESR
taken from linux/arch/arm64/include/asm/esr.h
ESR_ELx_EC_UNKNOWN (0x00)
ESR_ELx_EC_WFx (0x01)
UNALLOCATED (0x02)
ESR_ELx_EC_CP15_32 (0x03)
ESR_ELx_EC_CP15_64 (0x04)
ESR_ELx_EC_CP14_MR (0x05)
ESR_ELx_EC_CP14_LS (0x06)
ESR_ELx_EC_FP_ASIMD (0x07)
ESR_ELx_EC_CP10_ID (0x08) /* EL2 only */
ESR_ELx_EC_PAC (0x09) /* EL2 and above */
UNALLOCATED (0x0A - 0x0B)
ESR_ELx_EC_CP14_64 (0x0C)
ESR_ELx_EC_BTI (0x0D)
ESR_ELx_EC_ILL (0x0E)
UNALLOCATED (0x0F - 0x10)
ESR_ELx_EC_SVC32 (0x11)
ESR_ELx_EC_HVC32 (0x12) /* EL2 only */
ESR_ELx_EC_SMC32 (0x13) /* EL2 and above */
UNALLOCATED (0x14)
ESR_ELx_EC_SVC64 (0x15)
ESR_ELx_EC_HVC64 (0x16) /* EL2 and above */
ESR_ELx_EC_SMC64 (0x17) /* EL2 and above */
ESR_ELx_EC_SYS64 (0x18)
ESR_ELx_EC_SVE (0x19)
ESR_ELx_EC_ERET (0x1a) /* EL2 only */
UNALLOCATED (0x1B)
ESR_ELx_EC_FPAC (0x1C) /* EL1 and above */
ESR_ELx_EC_SME (0x1D)
UNALLOCATED (0x1E)
ESR_ELx_EC_IMP_DEF (0x1f) /* EL3 only */
ESR_ELx_EC_IABT_LOW (0x20)
ESR_ELx_EC_IABT_CUR (0x21)
ESR_ELx_EC_PC_ALIGN (0x22)
UNALLOCATED (0x23)
ESR_ELx_EC_DABT_LOW (0x24)
ESR_ELx_EC_DABT_CUR (0x25)
ESR_ELx_EC_SP_ALIGN (0x26)
ESR_ELx_EC_MOPS (0x27)
ESR_ELx_EC_FP_EXC32 (0x28)
UNALLOCATED (0x29 - 0x2B)
ESR_ELx_EC_FP_EXC64 (0x2C)
UNALLOCATED (0x2D - 0x2E)
ESR_ELx_EC_SERROR (0x2F)
ESR_ELx_EC_BREAKPT_LOW (0x30)
ESR_ELx_EC_BREAKPT_CUR (0x31)
ESR_ELx_EC_SOFTSTP_LOW (0x32)
ESR_ELx_EC_SOFTSTP_CUR (0x33)
ESR_ELx_EC_WATCHPT_LOW (0x34)
ESR_ELx_EC_WATCHPT_CUR (0x35)
UNALLOCATED (0x36 - 0x37)
ESR_ELx_EC_BKPT32 (0x38)
UNALLOCATED (0x39)
ESR_ELx_EC_VECTOR32 (0x3A) /* EL2 only */
UNALLOCATED (0x3B)
ESR_ELx_EC_BRK64 (0x3C)
UNALLOCATED (0x3D - 0x3F)
ESR_ELx_EC_MAX (0x3F)
ESR_ELx_EC_SHIFT (26)
ESR_ELx_EC_WIDTH (6)
ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT)
ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT)
footnotes, licenses
linux/arch/arm64/include/asm/esr.h
--------------------------------------------
SPDX-License-Identifier: GPL-2.0-only
Copyright (C) 2013 - ARM Ltd
Author: Marc Zyngier <marc.zyngier@arm.com>
each vector is aligned to 2^7 ie 0x80 bytes
TABLE_BASE
CURRENT_EL + SP0 sync // el1_t
CURRENT_EL + SP0 irq
CURRENT_EL + SP0 fiq
CURRENT_EL + SP0 serror
CURRENT_EL + SPX sync // el1_h
CURRENT_EL + SPX irq
CURRENT_EL + SPX fiq
CURRENT_EL + SPX serror
LOWWER_EL + sync // aarch64 // el0_
LOWWER_EL + irq
LOWWER_EL + fiq
LOWWER_EL + Serror
LOWWER_EL + sync // aarch32
LOWWER_EL + irq
LOWWER_EL + fiq
LOWWER_EL + Serror
arch/arm64/include/armreg.h from OpenBSD CODE. Lisence is at the end.
This is only for my own quick reference. Please look away XD
#ifndef _MACHINE_ARMREG_H_
#define _MACHINE_ARMREG_H_
#define INSN_SIZE 4
#define READ_SPECIALREG(reg) \
({ uint64_t val; \
__asm volatile("mrs %0, " __STRING(reg) : "=&r" (val)); \
val; \
})
#define WRITE_SPECIALREG(reg, val) \
__asm volatile("msr " __STRING(reg) ", %0" : : "r"((uint64_t)val))
/* CCSIDR_EL1 - Current Cache Size ID Register */
#define CCSIDR_SETS_MASK 0x0fffe000
#define CCSIDR_SETS_SHIFT 13
#define CCSIDR_SETS(reg) \
((((reg) & CCSIDR_SETS_MASK) >> CCSIDR_SETS_SHIFT) + 1)
#define CCSIDR_WAYS_MASK 0x00001ff8
#define CCSIDR_WAYS_SHIFT 3
#define CCSIDR_WAYS(reg) \
((((reg) & CCSIDR_WAYS_MASK) >> CCSIDR_WAYS_SHIFT) + 1)
#define CCSIDR_LINE_MASK 0x00000007
#define CCSIDR_LINE_SIZE(reg) (1 << (((reg) & CCSIDR_LINE_MASK) + 4))
/* CLIDR_EL1 - Cache Level ID Register */
#define CLIDR_CTYPE_MASK 0x7
#define CLIDR_CTYPE_INSN 0x1
#define CLIDR_CTYPE_DATA 0x2
#define CLIDR_CTYPE_UNIFIED 0x4
/* CNTHCTL_EL2 - Counter-timer Hypervisor Control Register */
#define CNTHCTL_EVNTI_MASK (0xf << 4) /* Bit to trigger event stream */
#define CNTHCTL_EVNTDIR (1 << 3) /* Control transition trigger bit */
#define CNTHCTL_EVNTEN (1 << 2) /* Enable event stream */
#define CNTHCTL_EL1PCEN (1 << 1) /* Allow EL0/1 physical timer access */
#define CNTHCTL_EL1PCTEN (1 << 0) /*Allow EL0/1 physical counter access*/
/* CNTKCTL_EL1 - Counter-timer Kernel Control Register */
#define CNTKCTL_EL0VCTEN (1 << 1) /* Allow EL0 virtual counter access */
/* CNTV_CTL_EL0 */
#define CNTV_CTL_ENABLE (1 << 0)
#define CNTV_CTL_IMASK (1 << 1)
#define CNTV_CTL_ISTATUS (1 << 2)
/* CPACR_EL1 */
#define CPACR_FPEN_MASK (0x3 << 20)
#define CPACR_FPEN_TRAP_ALL1 (0x0 << 20) /* Traps from EL0 and EL1 */
#define CPACR_FPEN_TRAP_EL0 (0x1 << 20) /* Traps from EL0 */
#define CPACR_FPEN_TRAP_ALL2 (0x2 << 20) /* Traps from EL0 and EL1 */
#define CPACR_FPEN_TRAP_NONE (0x3 << 20) /* No traps */
#define CPACR_TTA (0x1 << 28)
/* CSSELR_EL1 - Cache Size Selection Register */
#define CSSELR_IND (1 << 0)
#define CSSELR_LEVEL_SHIFT 1
/* CTR_EL0 - Cache Type Register */
#define CTR_DLINE_SHIFT 16
#define CTR_DLINE_MASK (0xf << CTR_DLINE_SHIFT)
#define CTR_DLINE_SIZE(reg) (((reg) & CTR_DLINE_MASK) >> CTR_DLINE_SHIFT)
#define CTR_IL1P_SHIFT 14
#define CTR_IL1P_MASK (0x3 << CTR_IL1P_SHIFT)
#define CTR_IL1P_AIVIVT (0x1 << CTR_IL1P_SHIFT)
#define CTR_IL1P_VIPT (0x2 << CTR_IL1P_SHIFT)
#define CTR_IL1P_PIPT (0x3 << CTR_IL1P_SHIFT)
#define CTR_ILINE_SHIFT 0
#define CTR_ILINE_MASK (0xf << CTR_ILINE_SHIFT)
#define CTR_ILINE_SIZE(reg) (((reg) & CTR_ILINE_MASK) >> CTR_ILINE_SHIFT)
/* MPIDR_EL1 - Multiprocessor Affinity Register */
#define MPIDR_AFF3 (0xFFULL << 32)
#define MPIDR_AFF2 (0xFFULL << 16)
#define MPIDR_AFF1 (0xFFULL << 8)
#define MPIDR_AFF0 (0xFFULL << 0)
#define MPIDR_AFF (MPIDR_AFF3|MPIDR_AFF2|MPIDR_AFF1|MPIDR_AFF0)
/* DCZID_EL0 - Data Cache Zero ID register */
#define DCZID_DZP (1 << 4) /* DC ZVA prohibited if non-0 */
#define DCZID_BS_SHIFT 0
#define DCZID_BS_MASK (0xf << DCZID_BS_SHIFT)
#define DCZID_BS_SIZE(reg) (((reg) & DCZID_BS_MASK) >> DCZID_BS_SHIFT)
/* ESR_ELx */
#define ESR_ELx_ISS_MASK 0x00ffffff
#define ISS_INSN_FnV (0x01 << 10)
#define ISS_INSN_EA (0x01 << 9)
#define ISS_INSN_S1PTW (0x01 << 7)
#define ISS_INSN_IFSC_MASK (0x1f << 0)
#define ISS_DATA_ISV (0x01 << 24)
#define ISS_DATA_SAS_MASK (0x03 << 22)
#define ISS_DATA_SSE (0x01 << 21)
#define ISS_DATA_SRT_MASK (0x1f << 16)
#define ISS_DATA_SF (0x01 << 15)
#define ISS_DATA_AR (0x01 << 14)
#define ISS_DATA_FnV (0x01 << 10)
#define ISS_DATA_EA (0x01 << 9)
#define ISS_DATA_CM (0x01 << 8)
#define ISS_INSN_S1PTW (0x01 << 7)
#define ISS_DATA_WnR (0x01 << 6)
#define ISS_DATA_DFSC_MASK (0x3f << 0)
#define ISS_DATA_DFSC_ASF_L0 (0x00 << 0)
#define ISS_DATA_DFSC_ASF_L1 (0x01 << 0)
#define ISS_DATA_DFSC_ASF_L2 (0x02 << 0)
#define ISS_DATA_DFSC_ASF_L3 (0x03 << 0)
#define ISS_DATA_DFSC_TF_L0 (0x04 << 0)
#define ISS_DATA_DFSC_TF_L1 (0x05 << 0)
#define ISS_DATA_DFSC_TF_L2 (0x06 << 0)
#define ISS_DATA_DFSC_TF_L3 (0x07 << 0)
#define ISS_DATA_DFSC_AFF_L1 (0x09 << 0)
#define ISS_DATA_DFSC_AFF_L2 (0x0a << 0)
#define ISS_DATA_DFSC_AFF_L3 (0x0b << 0)
#define ISS_DATA_DFSC_PF_L1 (0x0d << 0)
#define ISS_DATA_DFSC_PF_L2 (0x0e << 0)
#define ISS_DATA_DFSC_PF_L3 (0x0f << 0)
#define ISS_DATA_DFSC_EXT (0x10 << 0)
#define ISS_DATA_DFSC_EXT_L0 (0x14 << 0)
#define ISS_DATA_DFSC_EXT_L1 (0x15 << 0)
#define ISS_DATA_DFSC_EXT_L2 (0x16 << 0)
#define ISS_DATA_DFSC_EXT_L3 (0x17 << 0)
#define ISS_DATA_DFSC_ECC (0x18 << 0)
#define ISS_DATA_DFSC_ECC_L0 (0x1c << 0)
#define ISS_DATA_DFSC_ECC_L1 (0x1d << 0)
#define ISS_DATA_DFSC_ECC_L2 (0x1e << 0)
#define ISS_DATA_DFSC_ECC_L3 (0x1f << 0)
#define ISS_DATA_DFSC_ALIGN (0x21 << 0)
#define ISS_DATA_DFSC_TLB_CONFLICT (0x30 << 0)
#define ESR_ELx_IL (0x01 << 25)
#define ESR_ELx_EC_SHIFT 26
#define ESR_ELx_EC_MASK (0x3f << 26)
#define ESR_ELx_EXCEPTION(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT)
#define EXCP_UNKNOWN 0x00 /* Unkwn exception */
#define EXCP_FP_SIMD 0x07 /* FP/SIMD trap */
#define EXCP_BRANCH_TGT 0x0d /* Branch target exception */
#define EXCP_ILL_STATE 0x0e /* Illegal execution state */
#define EXCP_SVC 0x15 /* SVC trap */
#define EXCP_MSR 0x18 /* MSR/MRS trap */
#define EXCP_FPAC 0x1c /* Faulting PAC trap */
#define EXCP_INSN_ABORT_L 0x20 /* Instruction abort, from lower EL */
#define EXCP_INSN_ABORT 0x21 /* Instruction abort, from same EL */
#define EXCP_PC_ALIGN 0x22 /* PC alignment fault */
#define EXCP_DATA_ABORT_L 0x24 /* Data abort, from lower EL */
#define EXCP_DATA_ABORT 0x25 /* Data abort, from same EL */
#define EXCP_SP_ALIGN 0x26 /* SP alignment fault */
#define EXCP_TRAP_FP 0x2c /* Trapped FP exception */
#define EXCP_SERROR 0x2f /* SError interrupt */
#define EXCP_SOFTSTP_EL0 0x32 /* Software Step, from lower EL */
#define EXCP_SOFTSTP_EL1 0x33 /* Software Step, from same EL */
#define EXCP_WATCHPT_EL1 0x35 /* Watchpoint, from same EL */
#define EXCP_BRK 0x3c /* Breakpoint */
/* ICC_CTLR_EL1 */
#define ICC_CTLR_EL1_EOIMODE (1U << 1)
#define ICC_CTLR_EL1_PRIBITS_SHIFT 8
#define ICC_CTLR_EL1_PRIBITS_MASK (0x7UL << 8)
#define ICC_CTLR_EL1_PRIBITS(reg) \
(((reg) & ICC_CTLR_EL1_PRIBITS_MASK) >> ICC_CTLR_EL1_PRIBITS_SHIFT)
/* ICC_IAR1_EL1 */
#define ICC_IAR1_EL1_SPUR (0x03ff)
/* ICC_IGRPEN0_EL1 */
#define ICC_IGRPEN0_EL1_EN (1U << 0)
/* ICC_PMR_EL1 */
#define ICC_PMR_EL1_PRIO_MASK (0xFFUL)
/* ICC_SGI1R_EL1 */
#define ICC_SGI1R_EL1_TL_MASK 0xffffUL
#define ICC_SGI1R_EL1_AFF1_SHIFT 16
#define ICC_SGI1R_EL1_SGIID_SHIFT 24
#define ICC_SGI1R_EL1_AFF2_SHIFT 32
#define ICC_SGI1R_EL1_AFF3_SHIFT 48
#define ICC_SGI1R_EL1_SGIID_MASK 0xfUL
#define ICC_SGI1R_EL1_IRM (0x1UL << 40)
/* ICC_SRE_EL1 */
#define ICC_SRE_EL1_SRE (1U << 0)
/* ICC_SRE_EL2 */
#define ICC_SRE_EL2_SRE (1U << 0)
#define ICC_SRE_EL2_EN (1U << 3)
/* ID_AA64DFR0_EL1 */
#define ID_AA64DFR0_MASK 0x00000000f0f0ffffUL
#define ID_AA64DFR0_DEBUG_VER_SHIFT 0
#define ID_AA64DFR0_DEBUG_VER_MASK (0xf << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_DEBUG_VER(x) ((x) & ID_AA64DFR0_DEBUG_VER_MASK)
#define ID_AA64DFR0_DEBUG_VER_8 (0x6 << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_DEBUG_VER_8_VHE (0x7 << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER_SHIFT 4
#define ID_AA64DFR0_TRACE_VER_MASK (0xf << ID_AA64DFR0_TRACE_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER(x) ((x) & ID_AA64DFR0_TRACE_VER_MASK)
#define ID_AA64DFR0_TRACE_VER_NONE (0x0 << ID_AA64DFR0_TRACE_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER_IMPL (0x1 << ID_AA64DFR0_TRACE_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_SHIFT 8
#define ID_AA64DFR0_PMU_VER_MASK (0xf << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER(x) ((x) & ID_AA64DFR0_PMU_VER_MASK)
#define ID_AA64DFR0_PMU_VER_NONE (0x0 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_3 (0x1 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_3_1 (0x4 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_IMPL (0xf << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_BRPS_SHIFT 12
#define ID_AA64DFR0_BRPS_MASK (0xf << ID_AA64DFR0_BRPS_SHIFT)
#define ID_AA64DFR0_BRPS(x) \
((((x) >> ID_AA64DFR0_BRPS_SHIFT) & 0xf) + 1)
#define ID_AA64DFR0_WRPS_SHIFT 20
#define ID_AA64DFR0_WRPS_MASK (0xf << ID_AA64DFR0_WRPS_SHIFT)
#define ID_AA64DFR0_WRPS(x) \
((((x) >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) + 1)
#define ID_AA64DFR0_CTX_CMPS_SHIFT 28
#define ID_AA64DFR0_CTX_CMPS_MASK (0xf << ID_AA64DFR0_CTX_CMPS_SHIFT)
#define ID_AA64DFR0_CTX_CMPS(x) \
((((x) >> ID_AA64DFR0_CTX_CMPS_SHIFT) & 0xf) + 1)
/* ID_AA64ISAR0_EL1 */
#define ID_AA64ISAR0_MASK 0xfffffffff0fffff0ULL
#define ID_AA64ISAR0_AES_SHIFT 4
#define ID_AA64ISAR0_AES_MASK (0xf << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_AES(x) ((x) & ID_AA64ISAR0_AES_MASK)
#define ID_AA64ISAR0_AES_NONE (0x0 << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_AES_BASE (0x1 << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_AES_PMULL (0x2 << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_SHA1_SHIFT 8
#define ID_AA64ISAR0_SHA1_MASK (0xf << ID_AA64ISAR0_SHA1_SHIFT)
#define ID_AA64ISAR0_SHA1(x) ((x) & ID_AA64ISAR0_SHA1_MASK)
#define ID_AA64ISAR0_SHA1_NONE (0x0 << ID_AA64ISAR0_SHA1_SHIFT)
#define ID_AA64ISAR0_SHA1_BASE (0x1 << ID_AA64ISAR0_SHA1_SHIFT)
#define ID_AA64ISAR0_SHA2_SHIFT 12
#define ID_AA64ISAR0_SHA2_MASK (0xf << ID_AA64ISAR0_SHA2_SHIFT)
#define ID_AA64ISAR0_SHA2(x) ((x) & ID_AA64ISAR0_SHA2_MASK)
#define ID_AA64ISAR0_SHA2_NONE (0x0 << ID_AA64ISAR0_SHA2_SHIFT)
#define ID_AA64ISAR0_SHA2_BASE (0x1 << ID_AA64ISAR0_SHA2_SHIFT)
#define ID_AA64ISAR0_SHA2_512 (0x2 << ID_AA64ISAR0_SHA2_SHIFT)
#define ID_AA64ISAR0_CRC32_SHIFT 16
#define ID_AA64ISAR0_CRC32_MASK (0xf << ID_AA64ISAR0_CRC32_SHIFT)
#define ID_AA64ISAR0_CRC32(x) ((x) & ID_AA64ISAR0_CRC32_MASK)
#define ID_AA64ISAR0_CRC32_NONE (0x0 << ID_AA64ISAR0_CRC32_SHIFT)
#define ID_AA64ISAR0_CRC32_BASE (0x1 << ID_AA64ISAR0_CRC32_SHIFT)
#define ID_AA64ISAR0_ATOMIC_SHIFT 20
#define ID_AA64ISAR0_ATOMIC_MASK (0xf << ID_AA64ISAR0_ATOMIC_SHIFT)
#define ID_AA64ISAR0_ATOMIC(x) ((x) & ID_AA64ISAR0_ATOMIC_MASK)
#define ID_AA64ISAR0_ATOMIC_NONE (0x0 << ID_AA64ISAR0_ATOMIC_SHIFT)
#define ID_AA64ISAR0_ATOMIC_IMPL (0x2 << ID_AA64ISAR0_ATOMIC_SHIFT)
#define ID_AA64ISAR0_RDM_SHIFT 28
#define ID_AA64ISAR0_RDM_MASK (0xf << ID_AA64ISAR0_RDM_SHIFT)
#define ID_AA64ISAR0_RDM(x) ((x) & ID_AA64ISAR0_RDM_MASK)
#define ID_AA64ISAR0_RDM_NONE (0x0 << ID_AA64ISAR0_RDM_SHIFT)
#define ID_AA64ISAR0_RDM_IMPL (0x1 << ID_AA64ISAR0_RDM_SHIFT)
#define ID_AA64ISAR0_SHA3_SHIFT 32
#define ID_AA64ISAR0_SHA3_MASK (0xfULL << ID_AA64ISAR0_SHA3_SHIFT)
#define ID_AA64ISAR0_SHA3(x) ((x) & ID_AA64ISAR0_SHA3_MASK)
#define ID_AA64ISAR0_SHA3_NONE (0x0ULL << ID_AA64ISAR0_SHA3_SHIFT)
#define ID_AA64ISAR0_SHA3_IMPL (0x1ULL << ID_AA64ISAR0_SHA3_SHIFT)
#define ID_AA64ISAR0_SM3_SHIFT 36
#define ID_AA64ISAR0_SM3_MASK (0xfULL << ID_AA64ISAR0_SM3_SHIFT)
#define ID_AA64ISAR0_SM3(x) ((x) & ID_AA64ISAR0_SM3_MASK)
#define ID_AA64ISAR0_SM3_NONE (0x0ULL << ID_AA64ISAR0_SM3_SHIFT)
#define ID_AA64ISAR0_SM3_IMPL (0x1ULL << ID_AA64ISAR0_SM3_SHIFT)
#define ID_AA64ISAR0_SM4_SHIFT 40
#define ID_AA64ISAR0_SM4_MASK (0xfULL << ID_AA64ISAR0_SM4_SHIFT)
#define ID_AA64ISAR0_SM4(x) ((x) & ID_AA64ISAR0_SM4_MASK)
#define ID_AA64ISAR0_SM4_NONE (0x0ULL << ID_AA64ISAR0_SM4_SHIFT)
#define ID_AA64ISAR0_SM4_IMPL (0x1ULL << ID_AA64ISAR0_SM4_SHIFT)
#define ID_AA64ISAR0_DP_SHIFT 44
#define ID_AA64ISAR0_DP_MASK (0xfULL << ID_AA64ISAR0_DP_SHIFT)
#define ID_AA64ISAR0_DP(x) ((x) & ID_AA64ISAR0_DP_MASK)
#define ID_AA64ISAR0_DP_NONE (0x0ULL << ID_AA64ISAR0_DP_SHIFT)
#define ID_AA64ISAR0_DP_IMPL (0x1ULL << ID_AA64ISAR0_DP_SHIFT)
#define ID_AA64ISAR0_FHM_SHIFT 48
#define ID_AA64ISAR0_FHM_MASK (0xfULL << ID_AA64ISAR0_FHM_SHIFT)
#define ID_AA64ISAR0_FHM(x) ((x) & ID_AA64ISAR0_FHM_MASK)
#define ID_AA64ISAR0_FHM_NONE (0x0ULL << ID_AA64ISAR0_FHM_SHIFT)
#define ID_AA64ISAR0_FHM_IMPL (0x1ULL << ID_AA64ISAR0_FHM_SHIFT)
#define ID_AA64ISAR0_TS_SHIFT 52
#define ID_AA64ISAR0_TS_MASK (0xfULL << ID_AA64ISAR0_TS_SHIFT)
#define ID_AA64ISAR0_TS(x) ((x) & ID_AA64ISAR0_TS_MASK)
#define ID_AA64ISAR0_TS_NONE (0x0ULL << ID_AA64ISAR0_TS_SHIFT)
#define ID_AA64ISAR0_TS_BASE (0x1ULL << ID_AA64ISAR0_TS_SHIFT)
#define ID_AA64ISAR0_TS_AXFLAG (0x2ULL << ID_AA64ISAR0_TS_SHIFT)
#define ID_AA64ISAR0_TLB_SHIFT 56
#define ID_AA64ISAR0_TLB_MASK (0xfULL << ID_AA64ISAR0_TLB_SHIFT)
#define ID_AA64ISAR0_TLB(x) ((x) & ID_AA64ISAR0_TLB_MASK)
#define ID_AA64ISAR0_TLB_NONE (0x0ULL << ID_AA64ISAR0_TLB_SHIFT)
#define ID_AA64ISAR0_TLB_IOS (0x1ULL << ID_AA64ISAR0_TLB_SHIFT)
#define ID_AA64ISAR0_TLB_IRANGE (0x2ULL << ID_AA64ISAR0_TLB_SHIFT)
#define ID_AA64ISAR0_RNDR_SHIFT 60
#define ID_AA64ISAR0_RNDR_MASK (0xfULL << ID_AA64ISAR0_RNDR_SHIFT)
#define ID_AA64ISAR0_RNDR(x) ((x) & ID_AA64ISAR0_RNDR_MASK)
#define ID_AA64ISAR0_RNDR_NONE (0x0ULL << ID_AA64ISAR0_RNDR_SHIFT)
#define ID_AA64ISAR0_RNDR_IMPL (0x1ULL << ID_AA64ISAR0_RNDR_SHIFT)
/* ID_AA64ISAR1_EL1 */
#define ID_AA64ISAR1_MASK 0x00000fffffffffffULL
#define ID_AA64ISAR1_DPB_SHIFT 0
#define ID_AA64ISAR1_DPB_MASK (0xf << ID_AA64ISAR1_DPB_SHIFT)
#define ID_AA64ISAR1_DPB(x) ((x) & ID_AA64ISAR1_DPB_MASK)
#define ID_AA64ISAR1_DPB_NONE (0x0 << ID_AA64ISAR1_DPB_SHIFT)
#define ID_AA64ISAR1_DPB_IMPL (0x1 << ID_AA64ISAR1_DPB_SHIFT)
#define ID_AA64ISAR1_APA_SHIFT 4
#define ID_AA64ISAR1_APA_MASK (0xf << ID_AA64ISAR1_APA_SHIFT)
#define ID_AA64ISAR1_APA(x) ((x) & ID_AA64ISAR1_APA_MASK)
#define ID_AA64ISAR1_APA_NONE (0x0 << ID_AA64ISAR1_APA_SHIFT)
#define ID_AA64ISAR1_APA_BASE (0x1 << ID_AA64ISAR1_APA_SHIFT)
#define ID_AA64ISAR1_APA_PAC (0x2 << ID_AA64ISAR1_APA_SHIFT)
#define ID_AA64ISAR1_API_SHIFT 8
#define ID_AA64ISAR1_API_MASK (0xf << ID_AA64ISAR1_API_SHIFT)
#define ID_AA64ISAR1_API(x) ((x) & ID_AA64ISAR1_API_MASK)
#define ID_AA64ISAR1_API_NONE (0x0 << ID_AA64ISAR1_API_SHIFT)
#define ID_AA64ISAR1_API_BASE (0x1 << ID_AA64ISAR1_API_SHIFT)
#define ID_AA64ISAR1_API_PAC (0x2 << ID_AA64ISAR1_API_SHIFT)
#define ID_AA64ISAR1_JSCVT_SHIFT 12
#define ID_AA64ISAR1_JSCVT_MASK (0xf << ID_AA64ISAR1_JSCVT_SHIFT)
#define ID_AA64ISAR1_JSCVT(x) ((x) & ID_AA64ISAR1_JSCVT_MASK)
#define ID_AA64ISAR1_JSCVT_NONE (0x0 << ID_AA64ISAR1_JSCVT_SHIFT)
#define ID_AA64ISAR1_JSCVT_IMPL (0x1 << ID_AA64ISAR1_JSCVT_SHIFT)
#define ID_AA64ISAR1_FCMA_SHIFT 16
#define ID_AA64ISAR1_FCMA_MASK (0xf << ID_AA64ISAR1_FCMA_SHIFT)
#define ID_AA64ISAR1_FCMA(x) ((x) & ID_AA64ISAR1_FCMA_MASK)
#define ID_AA64ISAR1_FCMA_NONE (0x0 << ID_AA64ISAR1_FCMA_SHIFT)
#define ID_AA64ISAR1_FCMA_IMPL (0x1 << ID_AA64ISAR1_FCMA_SHIFT)
#define ID_AA64ISAR1_LRCPC_SHIFT 20
#define ID_AA64ISAR1_LRCPC_MASK (0xf << ID_AA64ISAR1_LRCPC_SHIFT)
#define ID_AA64ISAR1_LRCPC(x) ((x) & ID_AA64ISAR1_LRCPC_MASK)
#define ID_AA64ISAR1_LRCPC_NONE (0x0 << ID_AA64ISAR1_LRCPC_SHIFT)
#define ID_AA64ISAR1_LRCPC_BASE (0x1 << ID_AA64ISAR1_LRCPC_SHIFT)
#define ID_AA64ISAR1_LRCPC_LDAPUR (0x2 << ID_AA64ISAR1_LRCPC_SHIFT)
#define ID_AA64ISAR1_GPA_SHIFT 24
#define ID_AA64ISAR1_GPA_MASK (0xf << ID_AA64ISAR1_GPA_SHIFT)
#define ID_AA64ISAR1_GPA(x) ((x) & ID_AA64ISAR1_GPA_MASK)
#define ID_AA64ISAR1_GPA_NONE (0x0 << ID_AA64ISAR1_GPA_SHIFT)
#define ID_AA64ISAR1_GPA_IMPL (0x1 << ID_AA64ISAR1_GPA_SHIFT)
#define ID_AA64ISAR1_GPI_SHIFT 28
#define ID_AA64ISAR1_GPI_MASK (0xf << ID_AA64ISAR1_GPI_SHIFT)
#define ID_AA64ISAR1_GPI(x) ((x) & ID_AA64ISAR1_GPI_MASK)
#define ID_AA64ISAR1_GPI_NONE (0x0 << ID_AA64ISAR1_GPI_SHIFT)
#define ID_AA64ISAR1_GPI_IMPL (0x1 << ID_AA64ISAR1_GPI_SHIFT)
#define ID_AA64ISAR1_FRINTTS_SHIFT 32
#define ID_AA64ISAR1_FRINTTS_MASK (0xfULL << ID_AA64ISAR1_FRINTTS_SHIFT)
#define ID_AA64ISAR1_FRINTTS(x) ((x) & ID_AA64ISAR1_FRINTTS_MASK)
#define ID_AA64ISAR1_FRINTTS_NONE (0x0ULL << ID_AA64ISAR1_FRINTTS_SHIFT)
#define ID_AA64ISAR1_FRINTTS_IMPL (0x1ULL << ID_AA64ISAR1_FRINTTS_SHIFT)
#define ID_AA64ISAR1_SB_SHIFT 36
#define ID_AA64ISAR1_SB_MASK (0xfULL << ID_AA64ISAR1_SB_SHIFT)
#define ID_AA64ISAR1_SB(x) ((x) & ID_AA64ISAR1_SB_MASK)
#define ID_AA64ISAR1_SB_NONE (0x0ULL << ID_AA64ISAR1_SB_SHIFT)
#define ID_AA64ISAR1_SB_IMPL (0x1ULL << ID_AA64ISAR1_SB_SHIFT)
#define ID_AA64ISAR1_SPECRES_SHIFT 40
#define ID_AA64ISAR1_SPECRES_MASK (0xfULL << ID_AA64ISAR1_SPECRES_SHIFT)
#define ID_AA64ISAR1_SPECRES(x) ((x) & ID_AA64ISAR1_SPECRES_MASK)
#define ID_AA64ISAR1_SPECRES_NONE (0x0ULL << ID_AA64ISAR1_SPECRES_SHIFT)
#define ID_AA64ISAR1_SPECRES_IMPL (0x1ULL << ID_AA64ISAR1_SPECRES_SHIFT)
/* ID_AA64ISAR2_EL1 */
#define ID_AA64ISAR2_MASK 0x00000000f0000000ULL
#define ID_AA64ISAR2_CLRBHB_SHIFT 28
#define ID_AA64ISAR2_CLRBHB_MASK (0xfULL << ID_AA64ISAR2_CLRBHB_SHIFT)
#define ID_AA64ISAR2_CLRBHB(x) ((x) & ID_AA64ISAR2_CLRBHB_MASK)
#define ID_AA64ISAR2_CLRBHB_NONE (0x0ULL << ID_AA64ISAR2_CLRBHB_SHIFT)
#define ID_AA64ISAR2_CLRBHB_IMPL (0x1ULL << ID_AA64ISAR2_CLRBHB_SHIFT)
/* ID_AA64MMFR0_EL1 */
#define ID_AA64MMFR0_MASK 0x00000000ffffffffULL
#define ID_AA64MMFR0_PA_RANGE_SHIFT 0
#define ID_AA64MMFR0_PA_RANGE_MASK (0xf << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE(x) ((x) & ID_AA64MMFR0_PA_RANGE_MASK)
#define ID_AA64MMFR0_PA_RANGE_4G (0x0 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_64G (0x1 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_1T (0x2 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_4T (0x3 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_16T (0x4 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_256T (0x5 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_ASID_BITS_SHIFT 4
#define ID_AA64MMFR0_ASID_BITS_MASK (0xf << ID_AA64MMFR0_ASID_BITS_SHIFT)
#define ID_AA64MMFR0_ASID_BITS(x) ((x) & ID_AA64MMFR0_ASID_BITS_MASK)
#define ID_AA64MMFR0_ASID_BITS_8 (0x0 << ID_AA64MMFR0_ASID_BITS_SHIFT)
#define ID_AA64MMFR0_ASID_BITS_16 (0x2 << ID_AA64MMFR0_ASID_BITS_SHIFT)
#define ID_AA64MMFR0_BIGEND_SHIFT 8
#define ID_AA64MMFR0_BIGEND_MASK (0xf << ID_AA64MMFR0_BIGEND_SHIFT)
#define ID_AA64MMFR0_BIGEND(x) ((x) & ID_AA64MMFR0_BIGEND_MASK)
#define ID_AA64MMFR0_BIGEND_FIXED (0x0 << ID_AA64MMFR0_BIGEND_SHIFT)
#define ID_AA64MMFR0_BIGEND_MIXED (0x1 << ID_AA64MMFR0_BIGEND_SHIFT)
#define ID_AA64MMFR0_S_NS_MEM_SHIFT 12
#define ID_AA64MMFR0_S_NS_MEM_MASK (0xf << ID_AA64MMFR0_S_NS_MEM_SHIFT)
#define ID_AA64MMFR0_S_NS_MEM(x) ((x) & ID_AA64MMFR0_S_NS_MEM_MASK)
#define ID_AA64MMFR0_S_NS_MEM_NONE (0x0 << ID_AA64MMFR0_S_NS_MEM_SHIFT)
#define ID_AA64MMFR0_S_NS_MEM_DISTINCT (0x1 << ID_AA64MMFR0_S_NS_MEM_SHIFT)
#define ID_AA64MMFR0_BIGEND_EL0_SHIFT 16
#define ID_AA64MMFR0_BIGEND_EL0_MASK (0xf << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
#define ID_AA64MMFR0_BIGEND_EL0(x) ((x) & ID_AA64MMFR0_BIGEND_EL0_MASK)
#define ID_AA64MMFR0_BIGEND_EL0_FIXED (0x0 << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
#define ID_AA64MMFR0_BIGEND_EL0_MIXED (0x1 << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
#define ID_AA64MMFR0_TGRAN16_SHIFT 20
#define ID_AA64MMFR0_TGRAN16_MASK (0xf << ID_AA64MMFR0_TGRAN16_SHIFT)
#define ID_AA64MMFR0_TGRAN16(x) ((x) & ID_AA64MMFR0_TGRAN16_MASK)
#define ID_AA64MMFR0_TGRAN16_NONE (0x0 << ID_AA64MMFR0_TGRAN16_SHIFT)
#define ID_AA64MMFR0_TGRAN16_IMPL (0x1 << ID_AA64MMFR0_TGRAN16_SHIFT)
#define ID_AA64MMFR0_TGRAN64_SHIFT 24
#define ID_AA64MMFR0_TGRAN64_MASK (0xf << ID_AA64MMFR0_TGRAN64_SHIFT)
#define ID_AA64MMFR0_TGRAN64(x) ((x) & ID_AA64MMFR0_TGRAN64_MASK)
#define ID_AA64MMFR0_TGRAN64_IMPL (0x0 << ID_AA64MMFR0_TGRAN64_SHIFT)
#define ID_AA64MMFR0_TGRAN64_NONE (0xf << ID_AA64MMFR0_TGRAN64_SHIFT)
#define ID_AA64MMFR0_TGRAN4_SHIFT 28
#define ID_AA64MMFR0_TGRAN4_MASK (0xf << ID_AA64MMFR0_TGRAN4_SHIFT)
#define ID_AA64MMFR0_TGRAN4(x) ((x) & ID_AA64MMFR0_TGRAN4_MASK)
#define ID_AA64MMFR0_TGRAN4_IMPL (0x0 << ID_AA64MMFR0_TGRAN4_SHIFT)
#define ID_AA64MMFR0_TGRAN4_NONE (0xf << ID_AA64MMFR0_TGRAN4_SHIFT)
/* ID_AA64MMFR1_EL1 */
#define ID_AA64MMFR1_MASK 0xf0000000ffffffffULL
#define ID_AA64MMFR1_HAFDBS_SHIFT 0
#define ID_AA64MMFR1_HAFDBS_MASK (0xf << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_HAFDBS(x) ((x) & ID_AA64MMFR1_HAFDBS_MASK)
#define ID_AA64MMFR1_HAFDBS_NONE (0x0 << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_HAFDBS_AF (0x1 << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_HAFDBS_AF_DBS (0x2 << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_VMIDBITS_SHIFT 4
#define ID_AA64MMFR1_VMIDBITS_MASK (0xf << ID_AA64MMFR1_VMIDBITS_SHIFT)
#define ID_AA64MMFR1_VMIDBITS(x) ((x) & ID_AA64MMFR1_VMIDBITS_MASK)
#define ID_AA64MMFR1_VMIDBITS_8 (0x0 << ID_AA64MMFR1_VMIDBITS_SHIFT)
#define ID_AA64MMFR1_VMIDBITS_16 (0x2 << ID_AA64MMFR1_VMIDBITS_SHIFT)
#define ID_AA64MMFR1_VH_SHIFT 8
#define ID_AA64MMFR1_VH_MASK (0xf << ID_AA64MMFR1_VH_SHIFT)
#define ID_AA64MMFR1_VH(x) ((x) & ID_AA64MMFR1_VH_MASK)
#define ID_AA64MMFR1_VH_NONE (0x0 << ID_AA64MMFR1_VH_SHIFT)
#define ID_AA64MMFR1_VH_IMPL (0x1 << ID_AA64MMFR1_VH_SHIFT)
#define ID_AA64MMFR1_HPDS_SHIFT 12
#define ID_AA64MMFR1_HPDS_MASK (0xf << ID_AA64MMFR1_HPDS_SHIFT)
#define ID_AA64MMFR1_HPDS(x) ((x) & ID_AA64MMFR1_HPDS_MASK)
#define ID_AA64MMFR1_HPDS_NONE (0x0 << ID_AA64MMFR1_HPDS_SHIFT)
#define ID_AA64MMFR1_HPDS_IMPL (0x1 << ID_AA64MMFR1_HPDS_SHIFT)
#define ID_AA64MMFR1_LO_SHIFT 16
#define ID_AA64MMFR1_LO_MASK (0xf << ID_AA64MMFR1_LO_SHIFT)
#define ID_AA64MMFR1_LO(x) ((x) & ID_AA64MMFR1_LO_MASK)
#define ID_AA64MMFR1_LO_NONE (0x0 << ID_AA64MMFR1_LO_SHIFT)
#define ID_AA64MMFR1_LO_IMPL (0x1 << ID_AA64MMFR1_LO_SHIFT)
#define ID_AA64MMFR1_PAN_SHIFT 20
#define ID_AA64MMFR1_PAN_MASK (0xf << ID_AA64MMFR1_PAN_SHIFT)
#define ID_AA64MMFR1_PAN(x) ((x) & ID_AA64MMFR1_PAN_MASK)
#define ID_AA64MMFR1_PAN_NONE (0x0 << ID_AA64MMFR1_PAN_SHIFT)
#define ID_AA64MMFR1_PAN_IMPL (0x1 << ID_AA64MMFR1_PAN_SHIFT)
#define ID_AA64MMFR1_PAN_ATS1E1 (0x2 << ID_AA64MMFR1_PAN_SHIFT)
#define ID_AA64MMFR1_PAN_EPAN (0x3 << ID_AA64MMFR1_PAN_SHIFT)
#define ID_AA64MMFR1_SPECSEI_SHIFT 24
#define ID_AA64MMFR1_SPECSEI_MASK (0xf << ID_AA64MMFR1_SPECSEI_SHIFT)
#define ID_AA64MMFR1_SPECSEI(x) ((x) & ID_AA64MMFR1_SPECSEI_MASK)
#define ID_AA64MMFR1_SPECSEI_NONE (0x0 << ID_AA64MMFR1_SPECSEI_SHIFT)
#define ID_AA64MMFR1_SPECSEI_IMPL (0x1 << ID_AA64MMFR1_SPECSEI_SHIFT)
#define ID_AA64MMFR1_XNX_SHIFT 28
#define ID_AA64MMFR1_XNX_MASK (0xf << ID_AA64MMFR1_XNX_SHIFT)
#define ID_AA64MMFR1_XNX(x) ((x) & ID_AA64MMFR1_XNX_MASK)
#define ID_AA64MMFR1_XNX_NONE (0x0 << ID_AA64MMFR1_XNX_SHIFT)
#define ID_AA64MMFR1_XNX_IMPL (0x1 << ID_AA64MMFR1_XNX_SHIFT)
#define ID_AA64MMFR1_ECBHB_SHIFT 60
#define ID_AA64MMFR1_ECBHB_MASK (0xfULL << ID_AA64MMFR1_ECBHB_SHIFT)
#define ID_AA64MMFR1_ECBHB(x) ((x) & ID_AA64MMFR1_ECBHB_MASK)
#define ID_AA64MMFR1_ECBHB_NONE (0x0ULL << ID_AA64MMFR1_ECBHB_SHIFT)
#define ID_AA64MMFR1_ECBHB_IMPL (0x1ULL << ID_AA64MMFR1_ECBHB_SHIFT)
/* ID_AA64PFR0_EL1 */
#define ID_AA64PFR0_MASK 0xff0fffffffffffffULL
#define ID_AA64PFR0_EL0_SHIFT 0
#define ID_AA64PFR0_EL0_MASK (0xf << ID_AA64PFR0_EL0_SHIFT)
#define ID_AA64PFR0_EL0(x) ((x) & ID_AA64PFR0_EL0_MASK)
#define ID_AA64PFR0_EL0_64 (1 << ID_AA64PFR0_EL0_SHIFT)
#define ID_AA64PFR0_EL0_64_32 (2 << ID_AA64PFR0_EL0_SHIFT)
#define ID_AA64PFR0_EL1_SHIFT 4
#define ID_AA64PFR0_EL1_MASK (0xf << ID_AA64PFR0_EL1_SHIFT)
#define ID_AA64PFR0_EL1(x) ((x) & ID_AA64PFR0_EL1_MASK)
#define ID_AA64PFR0_EL1_64 (1 << ID_AA64PFR0_EL1_SHIFT)
#define ID_AA64PFR0_EL1_64_32 (2 << ID_AA64PFR0_EL1_SHIFT)
#define ID_AA64PFR0_EL2_SHIFT 8
#define ID_AA64PFR0_EL2_MASK (0xf << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL2(x) ((x) & ID_AA64PFR0_EL2_MASK)
#define ID_AA64PFR0_EL2_NONE (0 << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL2_64 (1 << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL2_64_32 (2 << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL3_SHIFT 12
#define ID_AA64PFR0_EL3_MASK (0xf << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_EL3(x) ((x) & ID_AA64PFR0_EL3_MASK)
#define ID_AA64PFR0_EL3_NONE (0 << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_EL3_64 (1 << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_EL3_64_32 (2 << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_FP_SHIFT 16
#define ID_AA64PFR0_FP_MASK (0xf << ID_AA64PFR0_FP_SHIFT)
#define ID_AA64PFR0_FP(x) ((x) & ID_AA64PFR0_FP_MASK)
#define ID_AA64PFR0_FP_IMPL (0x0 << ID_AA64PFR0_FP_SHIFT)
#define ID_AA64PFR0_FP_NONE (0xf << ID_AA64PFR0_FP_SHIFT)
#define ID_AA64PFR0_ADV_SIMD_SHIFT 20
#define ID_AA64PFR0_ADV_SIMD_MASK (0xf << ID_AA64PFR0_ADV_SIMD_SHIFT)
#define ID_AA64PFR0_ADV_SIMD(x) ((x) & ID_AA64PFR0_ADV_SIMD_MASK)
#define ID_AA64PFR0_ADV_SIMD_IMPL (0x0 << ID_AA64PFR0_ADV_SIMD_SHIFT)
#define ID_AA64PFR0_ADV_SIMD_NONE (0xf << ID_AA64PFR0_ADV_SIMD_SHIFT)
#define ID_AA64PFR0_GIC_BITS 0x4 /* Number of bits in GIC field */
#define ID_AA64PFR0_GIC_SHIFT 24
#define ID_AA64PFR0_GIC_MASK (0xf << ID_AA64PFR0_GIC_SHIFT)
#define ID_AA64PFR0_GIC(x) ((x) & ID_AA64PFR0_GIC_MASK)
#define ID_AA64PFR0_GIC_CPUIF_NONE (0x0 << ID_AA64PFR0_GIC_SHIFT)
#define ID_AA64PFR0_GIC_CPUIF_EN (0x1 << ID_AA64PFR0_GIC_SHIFT)
#define ID_AA64PFR0_RAS_SHIFT 28
#define ID_AA64PFR0_RAS_MASK (0xfULL << ID_AA64PFR0_RAS_SHIFT)
#define ID_AA64PFR0_RAS(x) ((x) & ID_AA64PFR0_RAS_MASK)
#define ID_AA64PFR0_RAS_NONE (0x0ULL << ID_AA64PFR0_RAS_SHIFT)
#define ID_AA64PFR0_RAS_IMPL (0x1ULL << ID_AA64PFR0_RAS_SHIFT)
#define ID_AA64PFR0_RAS_IMPL_V1P1 (0x2ULL << ID_AA64PFR0_RAS_SHIFT)
#define ID_AA64PFR0_SVE_SHIFT 32
#define ID_AA64PFR0_SVE_MASK (0xfULL << ID_AA64PFR0_SVE_SHIFT)
#define ID_AA64PFR0_SVE(x) ((x) & ID_AA64PFR0_SVE_MASK)
#define ID_AA64PFR0_SVE_NONE (0x0ULL << ID_AA64PFR0_SVE_SHIFT)
#define ID_AA64PFR0_SVE_IMPL (0x1ULL << ID_AA64PFR0_SVE_SHIFT)
#define ID_AA64PFR0_SEL2_SHIFT 36
#define ID_AA64PFR0_SEL2_MASK (0xfULL << ID_AA64PFR0_SEL2_SHIFT)
#define ID_AA64PFR0_SEL2(x) ((x) & ID_AA64PFR0_SEL2_MASK)
#define ID_AA64PFR0_SEL2_NONE (0x0ULL << ID_AA64PFR0_SEL2_SHIFT)
#define ID_AA64PFR0_SEL2_IMPL (0x1ULL << ID_AA64PFR0_SEL2_SHIFT)
#define ID_AA64PFR0_MPAM_SHIFT 40
#define ID_AA64PFR0_MPAM_MASK (0xfULL << ID_AA64PFR0_MPAM_SHIFT)
#define ID_AA64PFR0_MPAM(x) ((x) & ID_AA64PFR0_MPAM_MASK)
#define ID_AA64PFR0_MPAM_NONE (0x0ULL << ID_AA64PFR0_MPAM_SHIFT)
#define ID_AA64PFR0_MPAM_IMPL (0x1ULL << ID_AA64PFR0_MPAM_SHIFT)
#define ID_AA64PFR0_AMU_SHIFT 44
#define ID_AA64PFR0_AMU_MASK (0xfULL << ID_AA64PFR0_AMU_SHIFT)
#define ID_AA64PFR0_AMU(x) ((x) & ID_AA64PFR0_AMU_MASK)
#define ID_AA64PFR0_AMU_NONE (0x0ULL << ID_AA64PFR0_AMU_SHIFT)
#define ID_AA64PFR0_AMU_IMPL (0x1ULL << ID_AA64PFR0_AMU_SHIFT)
#define ID_AA64PFR0_DIT_SHIFT 48
#define ID_AA64PFR0_DIT_MASK (0xfULL << ID_AA64PFR0_DIT_SHIFT)
#define ID_AA64PFR0_DIT(x) ((x) & ID_AA64PFR0_DIT_MASK)
#define ID_AA64PFR0_DIT_UNKNOWN (0x0ULL << ID_AA64PFR0_DIT_SHIFT)
#define ID_AA64PFR0_DIT_IMPL (0x1ULL << ID_AA64PFR0_DIT_SHIFT)
#define ID_AA64PFR0_CSV2_SHIFT 56
#define ID_AA64PFR0_CSV2_MASK (0xfULL << ID_AA64PFR0_CSV2_SHIFT)
#define ID_AA64PFR0_CSV2(x) ((x) & ID_AA64PFR0_CSV2_MASK)
#define ID_AA64PFR0_CSV2_UNKNOWN (0x0ULL << ID_AA64PFR0_CSV2_SHIFT)
#define ID_AA64PFR0_CSV2_IMPL (0x1ULL << ID_AA64PFR0_CSV2_SHIFT)
#define ID_AA64PFR0_CSV2_SCXT (0x2ULL << ID_AA64PFR0_CSV2_SHIFT)
#define ID_AA64PFR0_CSV2_HCXT (0x3ULL << ID_AA64PFR0_CSV2_SHIFT)
#define ID_AA64PFR0_CSV3_SHIFT 60
#define ID_AA64PFR0_CSV3_MASK (0xfULL << ID_AA64PFR0_CSV3_SHIFT)
#define ID_AA64PFR0_CSV3(x) ((x) & ID_AA64PFR0_CSV3_MASK)
#define ID_AA64PFR0_CSV3_UNKNOWN (0x0ULL << ID_AA64PFR0_CSV3_SHIFT)
#define ID_AA64PFR0_CSV3_IMPL (0x1ULL << ID_AA64PFR0_CSV3_SHIFT)
/* ID_AA64PFR1_EL1 */
#define ID_AA64PFR1_MASK 0x000000000000ffffULL
#define ID_AA64PFR1_BT_SHIFT 0
#define ID_AA64PFR1_BT_MASK (0xf << ID_AA64PFR1_BT_SHIFT)
#define ID_AA64PFR1_BT(x) ((x) & ID_AA64PFR1_BT_MASK)
#define ID_AA64PFR1_BT_NONE (0 << ID_AA64PFR1_BT_SHIFT)
#define ID_AA64PFR1_BT_IMPL (1 << ID_AA64PFR1_BT_SHIFT)
#define ID_AA64PFR1_SBSS_SHIFT 4
#define ID_AA64PFR1_SBSS_MASK (0xf << ID_AA64PFR1_SBSS_SHIFT)
#define ID_AA64PFR1_SBSS(x) ((x) & ID_AA64PFR1_SBSS_MASK)
#define ID_AA64PFR1_SBSS_NONE (0 << ID_AA64PFR1_SBSS_SHIFT)
#define ID_AA64PFR1_SBSS_PSTATE (1 << ID_AA64PFR1_SBSS_SHIFT)
#define ID_AA64PFR1_SBSS_PSTATE_MSR (2 << ID_AA64PFR1_SBSS_SHIFT)
#define ID_AA64PFR1_MTE_SHIFT 8
#define ID_AA64PFR1_MTE_MASK (0xf << ID_AA64PFR1_MTE_SHIFT)
#define ID_AA64PFR1_MTE(x) ((x) & ID_AA64PFR1_MTE_MASK)
#define ID_AA64PFR1_MTE_NONE (0 << ID_AA64PFR1_MTE_SHIFT)
#define ID_AA64PFR1_MTE_IMPL (1 << ID_AA64PFR1_MTE_SHIFT)
#define ID_AA64PFR1_RAS_FRAC_SHIFT 12
#define ID_AA64PFR1_RAS_FRAC_MASK (0xf << ID_AA64PFR1_RAS_FRAC_SHIFT)
#define ID_AA64PFR1_RAS_FRAC(x) ((x) & ID_AA64PFR1_RAS_FRAC_MASK)
#define ID_AA64PFR1_RAS_FRAC_NONE (0 << ID_AA64PFR1_RAS_FRAC_SHIFT)
#define ID_AA64PFR1_RAS_FRAC_IMPL (1 << ID_AA64PFR1_RAS_FRAC_SHIFT)
/* MAIR_EL1 - Memory Attribute Indirection Register */
#define MAIR_ATTR_MASK(idx) (0xff << ((n)* 8))
#define MAIR_ATTR(attr, idx) ((attr) << ((idx) * 8))
#define MAIR_DEVICE_nGnRnE 0x00
#define MAIR_NORMAL_NC 0x44
#define MAIR_NORMAL_WT 0x88
#define MAIR_NORMAL_WB 0xff
/* PAR_EL1 - Physical Address Register */
#define PAR_F_SHIFT 0
#define PAR_F (0x1 << PAR_F_SHIFT)
#define PAR_SUCCESS(x) (((x) & PAR_F) == 0)
/* When PAR_F == 0 (success) */
#define PAR_SH_SHIFT 7
#define PAR_SH_MASK (0x3 << PAR_SH_SHIFT)
#define PAR_NS_SHIFT 9
#define PAR_NS_MASK (0x3 << PAR_NS_SHIFT)
#define PAR_PA_SHIFT 12
#define PAR_PA_MASK 0x0000fffffffff000
#define PAR_ATTR_SHIFT 56
#define PAR_ATTR_MASK (0xff << PAR_ATTR_SHIFT)
/* When PAR_F == 1 (aborted) */
#define PAR_FST_SHIFT 1
#define PAR_FST_MASK (0x3f << PAR_FST_SHIFT)
#define PAR_PTW_SHIFT 8
#define PAR_PTW_MASK (0x1 << PAR_PTW_SHIFT)
#define PAR_S_SHIFT 9
#define PAR_S_MASK (0x1 << PAR_S_SHIFT)
/* SCTLR_EL1 - System Control Register */
#define SCTLR_RES0 0xffffffffc8222400 /* Reserved, write 0 */
#define SCTLR_RES1 0x0000000030d00800 /* Reserved, write 1 */
#define SCTLR_M 0x0000000000000001
#define SCTLR_A 0x0000000000000002
#define SCTLR_C 0x0000000000000004
#define SCTLR_SA 0x0000000000000008
#define SCTLR_SA0 0x0000000000000010
#define SCTLR_CP15BEN 0x0000000000000020
#define SCTLR_THEE 0x0000000000000040
#define SCTLR_ITD 0x0000000000000080
#define SCTLR_SED 0x0000000000000100
#define SCTLR_UMA 0x0000000000000200
#define SCTLR_I 0x0000000000001000
#define SCTLR_EnDB 0x0000000000002000
#define SCTLR_DZE 0x0000000000004000
#define SCTLR_UCT 0x0000000000008000
#define SCTLR_nTWI 0x0000000000010000
#define SCTLR_nTWE 0x0000000000040000
#define SCTLR_WXN 0x0000000000080000
#define SCTLR_SPAN 0x0000000000800000
#define SCTLR_EOE 0x0000000001000000
#define SCTLR_EE 0x0000000002000000
#define SCTLR_UCI 0x0000000004000000
#define SCTLR_EnDA 0x0000000008000000
#define SCTLR_EnIB 0x0000000040000000
#define SCTLR_EnIA 0x0000000080000000
/* SPSR_EL1 */
/*
* When the exception is taken in AArch64:
* M[4] is 0 for AArch64 mode
* M[3:2] is the exception level
* M[1] is unused
* M[0] is the SP select:
* 0: always SP0
* 1: current ELs SP
*/
#define PSR_M_EL0t 0x00000000
#define PSR_M_EL1t 0x00000004
#define PSR_M_EL1h 0x00000005
#define PSR_M_EL2t 0x00000008
#define PSR_M_EL2h 0x00000009
#define PSR_M_MASK 0x0000001f
#define PSR_F 0x00000040
#define PSR_I 0x00000080
#define PSR_A 0x00000100
#define PSR_D 0x00000200
#define PSR_BTYPE 0x00000c00
#define PSR_SSBS 0x00001000
#define PSR_IL 0x00100000
#define PSR_SS 0x00200000
#define PSR_PAN 0x00400000
#define PSR_UAO 0x00800000
#define PSR_DIT 0x01000000
#define PSR_TCO 0x02000000
#define PSR_V 0x10000000
#define PSR_C 0x20000000
#define PSR_Z 0x40000000
#define PSR_N 0x80000000
/* TCR_EL1 - Translation Control Register */
#define TCR_AS (1UL << 36)
#define TCR_IPS_SHIFT 32
#define TCR_IPS_32BIT (0UL << TCR_IPS_SHIFT)
#define TCR_IPS_36BIT (1UL << TCR_IPS_SHIFT)
#define TCR_IPS_40BIT (2UL << TCR_IPS_SHIFT)
#define TCR_IPS_42BIT (3UL << TCR_IPS_SHIFT)
#define TCR_IPS_44BIT (4UL << TCR_IPS_SHIFT)
#define TCR_IPS_48BIT (5UL << TCR_IPS_SHIFT)
#define TCR_TG1_SHIFT 30
#define TCR_TG1_16K (1UL << TCR_TG1_SHIFT)
#define TCR_TG1_4K (2UL << TCR_TG1_SHIFT)
#define TCR_TG1_64K (3UL << TCR_TG1_SHIFT)
#define TCR_SH1_SHIFT 28
#define TCR_SH1_IS (0x3UL << TCR_SH1_SHIFT)
#define TCR_ORGN1_SHIFT 26
#define TCR_ORGN1_WBWA (0x1UL << TCR_ORGN1_SHIFT)
#define TCR_IRGN1_SHIFT 24
#define TCR_IRGN1_WBWA (0x1UL << TCR_IRGN1_SHIFT)
#define TCR_A1 (1UL << 22)
#define TCR_TG0_SHIFT 14
#define TCR_TG0_4K (0UL << TCR_TG0_SHIFT)
#define TCR_TG0_64K (1UL << TCR_TG0_SHIFT)
#define TCR_TG0_16K (2UL << TCR_TG0_SHIFT)
#define TCR_SH0_SHIFT 12
#define TCR_SH0_IS (0x3UL << TCR_SH0_SHIFT)
#define TCR_ORGN0_SHIFT 10
#define TCR_ORGN0_WBWA (0x1UL << TCR_ORGN0_SHIFT)
#define TCR_IRGN0_SHIFT 8
#define TCR_IRGN0_WBWA (0x1UL << TCR_IRGN0_SHIFT)
#define TCR_CACHE_ATTRS ((TCR_IRGN0_WBWA | TCR_IRGN1_WBWA) |\
(TCR_ORGN0_WBWA | TCR_ORGN1_WBWA))
#define TCR_SMP_ATTRS (TCR_SH0_IS | TCR_SH1_IS)
#define TCR_T1SZ_SHIFT 16
#define TCR_T0SZ_SHIFT 0
#define TCR_T1SZ(x) ((x) << TCR_T1SZ_SHIFT)
#define TCR_T0SZ(x) ((x) << TCR_T0SZ_SHIFT)
#define TCR_TxSZ(x) (TCR_T1SZ(x) | TCR_T0SZ(x))
/* Monitor Debug System Control Register */
#define DBG_MDSCR_SS (0x1 << 0)
#define DBG_MDSCR_TDCC (0x1 << 12)
#define DBG_MDSCR_KDE (0x1 << 13)
#define DBG_MDSCR_MDE (0x1 << 15)
/* Performance Monitoring Counters */
#define PMCR_E (1 << 0) /* Enable all counters */
#define PMCR_P (1 << 1) /* Reset all counters */
#define PMCR_C (1 << 2) /* Clock counter reset */
#define PMCR_D (1 << 3) /* CNTR counts every 64 clk cycles */
#define PMCR_X (1 << 4) /* Export to ext. monitoring (ETM) */
#define PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
#define PMCR_LC (1 << 6) /* Long cycle count enable */
#define PMCR_IMP_SHIFT 24 /* Implementer code */
#define PMCR_IMP_MASK (0xff << PMCR_IMP_SHIFT)
#define PMCR_IDCODE_SHIFT 16 /* Identification code */
#define PMCR_IDCODE_MASK (0xff << PMCR_IDCODE_SHIFT)
#define PMCR_IDCODE_CORTEX_A57 0x01
#define PMCR_IDCODE_CORTEX_A72 0x02
#define PMCR_IDCODE_CORTEX_A53 0x03
#define PMCR_N_SHIFT 11 /* Number of counters implemented */
#define PMCR_N_MASK (0x1f << PMCR_N_SHIFT)
/* Individual CPUs are probably best IDed by everything but the revision. */
#define CPU_ID_CPU_MASK 0xfffffff0
/* ARM64 CPUs */
#define CPU_ID_CORTEX_A53 0x410fd030
#define CPU_ID_CORTEX_A53_R1 0x411fd030
#define CPU_ID_CORTEX_A53_MASK 0xff0ffff0
#define CPU_ID_CORTEX_A57 0x410fd070
#define CPU_ID_CORTEX_A57_R1 0x411fd070
#define CPU_ID_CORTEX_A57_MASK 0xff0ffff0
#define CPU_ID_CORTEX_A72 0x410fd080
#define CPU_ID_CORTEX_A72_R1 0x411fd080
#define CPU_ID_CORTEX_A57_MASK 0xff0ffff0
#define I_bit (1 << 7) /* IRQ disable */
#define F_bit 0 /* FIQ disable - not actually used */
#endif /* !_MACHINE_ARMREG_H_ */
/* $OpenBSD: armreg.h,v 1.29 2023/06/10 19:30:48 kettenis Exp $ */
/*-
* Copyright (c) 2013, 2014 Andrew Turner
* Copyright (c) 2015 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Andrew Turner under
* sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: head/sys/arm64/include/armreg.h 309248 2016-11-28 14:24:07Z andrew $
*/
aarch64 PSTATE and SPSR
(only for) when exception taken from AArch64 state:
SPSR_ELx | PSTATE | NOTE |
---|---|---|
[63:32] | - | RESERVED 0 |
31 | N | |
30 | Z | |
29 | C | |
28 | V | |
[27:26] | - | RESERVED 0 |
25 | TCO | FEAT_MTE |
24 | DIT | FEAT_DIT |
23 | UAO | FEAT_UAO |
22 | PAN | FEAT_PAN |
21 | SS | |
20 | IL | |
[19:13] | N/A | RESERVED 0 |
12 | SSBS | |
[11:10] | BTYPE [1:0] | FEAT_BTI |
9 | D | |
8 | A | |
7 | I | |
6 | F | |
5 | - | RESERVED 0 |
4 | M [4] | |
[3:0] | M [3:0] |
general PSTATE bits NOTE: PSTATE is not a register. Also not all fields are preserved in the SPSR_ELx when an excaption is taken.
NAME | DESC |
---|---|
NZCV | ALU Condition {Neg, Zero, Carry, oVerflow} |
DAIF | mask bits {Debug, sError, IRQ, FIQ} |
SS | Software Step |
IL | illegal execution state |
EL(2) | exception level |
nRW | execution state (0=64, 1=32) |
SP | stack pointer selector (0=SP_EL0, 1=SP_ELn) |
feature PSTATE bits (TODO)
USEFUL RESOURCES
x86 and amd64 instruction reference
PAE paging Entry format
Intel SDM Figure 4-11
PAE paging with 1G PDPTE
+------------+
| PML4 Entry |
+------------+
0 PRESENT
1 R/W (1 == writable)
2 U/S (1 == user accessable)
3 PWD (write-through)
4 PCD (cache disable)
5 A (Accessed)
6 IGN
7 RES0
8:10 IGN
11 R (ign, or restart for HLAT paging)
M-1:12 next level table PA[M:12]
51:M RES0
62:52 IGN
63 XD (execute disable (if EFER.NXE=1)) otherwise RES0
+------------+
| PDPT ENtry | (level 3) with 1GiB Page (requires PS=1)
+------------+
0 PRESENT
1 R/W (1 == writable)
2 U/S (1 == user accessable)
3 PWD (write-through)
4 PCD (cache disable)
5 A (Accessed)
6 D (Dirty)
7 PS (must be 1)*
8 G (Global, if CR4.PGE=1), otherwise INR
10:9 IGR
11 R (ign, or restart for HLAT paging)
12 PAT (indirectly determines memory type)
29:13 RES0
M-1:30 PA[M-1:30]
51:M RES0
52:58 IGN
59:62 Protection key
63 XD (execute disable (if EFER.NXE=1)) otherwise RES0
Setting up a provisional identical mapping for long mode, using 1G huge page on PDP(PUD).
x86_64 long mode mandates paging. Here we set up a provisional identical mapping for the early booting.
Math
Each PUD entry (on the 3rd level) maps to 1G memory region. We could set up
512 GiB mapping with only one single 3rd level table (i.e. no need for page
directory or page table), this is ideal for a early boot provisional mapping.
We need:
- one PML4 table (and only 1 single entry pointing to the PUD table), that's 4KiB in size
- one PUD table, populated with 512 entries, each pointing to 1G memory region, this is another 4KiB in size.
- in total, we need to setup 2 tables and 1 + 512 = 513 entries.
assembly example
[SECTION .text]
[BITS 32]
; skipping other code.
setup_paging:
; PML4 (Page Map Level 4 / 1st level)
mov eax, pdp
or eax, 0xf
mov dword [pml4+0], eax
mov dword [pml4+4], 0
; PDPE flags
; start-address bytes bit [30:31] + flags
mov eax, 0x0 | 0x87
; start-address bytes bit [32:38]
mov ebx, 0
mov ecx, 0
fill_tables2:
; fill one single PDP table, with 1G pages,
; 512 PDPE maps to 512 GB
cmp ecx, MAX_MEM
je fill_tables2_done
; low bytes
mov dword [pdp + 8*ecx + 0], eax
; high bytes
mov dword [pdp + 8*ecx + 4], ebx
; 1G per entry
add eax, 0x40000000
; increment bit[32:38] when eax overflows
adc ebx, 0
inc ecx
ja fill_tables2
fill_tables2_done:
; set base pointer to PML4
mov eax, pml4
mov cr3, eax
ret
[SECTION .pagetables]
[GLOBAL pml4]
[GLOBAL pdp]
pml4:
resb 4096
alignb 4096
pdp:
resb 4096
alignb 4096
Note that, each entry is 64bit, but when we are setting up the page tables, we
are not in long mode yet, meaning that only 32bit registers/instructions are
available. See how the code use both eax
and ebx
to keep the address with
the carry flag (adc
).
Also make sure to link and align the pagetables section properly. e.g.
/* global page table for 64-bit long mode */
.global_pagetable ALIGN(4096) (NOLOAD) :
{
*(".global_pagetable")
}
https://wiki.osdev.org/Exceptions
https://wiki.osdev.org/Interrupts#General_IBM-PC_Compatible_Interrupt_Information
------------------------------------------------------
VectorNr. Name Type ErrorCode
------------------------------------------------------
0x0 Division Error Fault -
0x1 Debug Fault/Trap -
0x2 NMI Interrupt -
0x3 Breakpoint Trap -
0x4 Overflow Trap -
0x5 Bound Range Exceeded Fault -
0x6 Invalid Opcode Fault -
0x7 Device Not Available Fault -
0x8 Double Fault Abort Yes (zero)
0x9 Legacy (CSO) Fault -
0xA Invalid TSS Fault Yes
0xB Segment Not Present Fault Yes
0xC Stack Segment Fault Fault Yes
0xD GPF Fault Yes
0xE Page Fault Fault Yes
0xF RESERVED - -
0x10 x87 FP Exception Fault -
0x11 Alignment Check Fault Yes
0x12 Machine Check Abort -
0x13 SIMD FP Exception Fault -
0x14 Virt. Exception Fault -
0x15 Control Protection Fault Yes
0x16 RESERVED - -
0x17 RESERVED - -
0x18 RESERVED - -
0x19 RESERVED - -
0x1A RESERVED - -
0x1B RESERVED - -
0x1C Hpervisor Injection Fault -
0x1D VMM Communication Fault Yes
0x1E Security Exception Fault Yes
0x1F RESERVED
------------------------------------------------------
PIC1 (master) remapped from vector offset 0x20
------------------------------------------------------
0x20 PIT (Timer)
0x21 Keyboard
0x22 PIC internal (never raised)
0x23 COMM2 (if enabled)
0x24 COMM1 (if enabled)
0x25 LPT2 (if enabled)
0x26 Floppy Disk
0x27 LPT1 / Unreliable "spurious" interrupt (usually)
------------------------------------------------------
PIC2 (slave) remapped from vector offset 0x28
------------------------------------------------------
0x28 CMOS realtime-clock (if enabled)
0x29 Free for peripherals / SCSI / NIC
0x2A Free for peripherals / SCSI / NIC
0x2B Free for peripherals / SCSI / NIC
0x2C PS2 Mouse
0x2D FPU / Coprocessor / Inter-processor
0x2E Primary ATA Hard Disk
0x2F Secondary ATA Hard Disk
x86_64 (SysV) calling convention
https://uclibc.org/docs/psABI-x86_64.pdf
not including vector and FP registers
register usage
-----------------------------------------------------------------------
register Usage preserved across calls
-----------------------------------------------------------------------
rax 1th return value No
temp (scratch) reg
-----------------------------------------------------------------------
rbx callee saved Yes
-----------------------------------------------------------------------
rdi fn parameter 1 No
-----------------------------------------------------------------------
rsi fn parameter 2 No
-----------------------------------------------------------------------
rdx fn parameter 3 No
-----------------------------------------------------------------------
rcx fn parameter 4 No
-----------------------------------------------------------------------
r8 fn parameter 5 No
-----------------------------------------------------------------------
r9 fn parameter 6 No
-----------------------------------------------------------------------
r10 function static chain ptr No
temp (scratch) reg
-----------------------------------------------------------------------
r11 temp (scratch) reg No
-----------------------------------------------------------------------
r12~r14 callee saved Yes
-----------------------------------------------------------------------
r15 callee saved Yes
optionally GOT base pointer
-----------------------------------------------------------------------
rsp stack pointer Yes
-----------------------------------------------------------------------
rbp callee saved
optionally frame pointer Yes
-----------------------------------------------------------------------
parameter passing (integer class only)
-----------------------------------------------------------------------
the first 6 parameters (left to right) are passed though register
rdi, rsi, rdx, rcx, r8, r9
further paramters are pushed to stack (right-to-left order)
^^^^^^^^^^^^^
-----------------------------------------------------------------------
TODO returning value
USEFUL RESOURCES
Stack smashing debugging guide
Kernel module basic example: (from Linux Kernel Driver). Code from Douglas Su
hello_world.c
#include <linux/module.h>
static int __init m_init(void)
{
printk(KERN_ALERT "Hello, world!\n");
return 0;
}
static void __exit m_exit(void)
{
printk(KERN_ALERT "Bye, world!\n");
}
module_init(m_init);
module_exit(m_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Douglas Su");
MODULE_DESCRIPTION("Hello World program");
Makefile
ifneq ($(KERNELRELEASE),)
# In kbuild context
module-objs := hello_world.o
obj-m := hello_world.o
CFLAGS_hello_world.o := -DDEBUG
else
# In normal make context
KDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
.PHONY: modules
modules:
$(MAKE) -C $(KDIR) M=$(PWD) modules
.PHONY: clean
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
endif
Notes on the Makefile
-
To build a module from multiple source (/objects):
obj-m := module.o module-objs := file1.o file2.o
-
the module code can't build on its own. It must be built in the kernel tree (where a configured makefile can be found) e.g.
/lib/modules/6.6.20-1-lts/build
or
/usr/src/linux-lts
-
the module Makefile idiom
# If KERNELRELEASE is defined, we've been invoked from the # kernel build system and can use its language. ifneq ($(KERNELRELEASE),) obj-m := hello.o # Otherwise we were called directly from the command # line; invoke the kernel build system. else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif
Quick Reference (LDD)
insmod
modprobe
rmmod
User-space utilities that load modules into the running kernels and remove
them.
#include <linux/init.h>
module_init(init_function);
module_exit(cleanup_function);
Macros that designate a module’s initialization and cleanup functions.
__init
__initdata
__exit
__exitdata
Markers for functions (__init and __exit) and data (__initdata and __exitdata)
that are only used at module initialization or cleanup time. Items marked for ini-
tialization may be discarded once initialization completes; the exit items may be
discarded if module unloading has not been configured into the kernel. These
markers work by causing the relevant objects to be placed in a special ELF sec-
tion in the executable file.
#include <linux/sched.h>
One of the most important header files. This file contains definitions of much of
the kernel API used by the driver, including functions for sleeping and numer-
ous variable declarations.
struct task_struct *current;
The current process.
current->pid
current->comm
The process ID and command name for the current process.
obj-m
A makefile symbol used by the kernel build system to determine which modules
should be built in the current directory.
/sys/module
/proc/modules
/sys/module is a sysfs directory hierarchy containing information on currently-
loaded modules. /proc/modules is the older, single-file version of that informa-
tion. Entries contain the module name, the amount of memory each module
occupies, and the usage count. Extra strings are appended to each line to specify
flags that are currently active for the module.
vermagic.o
An object file from the kernel source directory that describes the environment a
module was built for.
#include <linux/module.h>
Required header. It must be included by a module source.
#include <linux/version.h>
A header file containing information on the version of the kernel being built.
LINUX_VERSION_CODE
Integer macro, useful to #ifdef version dependencies.
EXPORT_SYMBOL (symbol);
EXPORT_SYMBOL_GPL (symbol);
Macro used to export a symbol to the kernel. The second form exports without
using versioning information, and the third limits the export to GPL-licensed
modules.
MODULE_AUTHOR(author);
MODULE_DESCRIPTION(description);
MODULE_VERSION(version_string);
MODULE_DEVICE_TABLE(table_info);
MODULE_ALIAS(alternate_name);
Place documentation on the module in the object file.
module_init(init_function);
module_exit(exit_function);
Macros that declare a module’s initialization and cleanup functions.
#include <linux/moduleparam.h>
module_param(variable, type, perm);
Macro that creates a module parameter that can be adjusted by the user when
the module is loaded (or at boot time for built-in code). The type can be one of
bool, charp, int, invbool, long, short, ushort, uint, ulong, or intarray.
#include <linux/kernel.h>
int printk(const char * fmt, ...);
The analogue of printf for kernel code.
man 2 syscall
:
Arch/ABI Instruction System Ret Ret Error Notes
call # val val2
───────────────────────────────────────────────────────────────────
alpha callsys v0 v0 a4 a3 1, 6
arc trap0 r8 r0 - -
arm/OABI swi NR - r0 - - 2
arm/EABI swi 0x0 r7 r0 r1 -
arm64 svc #0 w8 x0 x1 -
blackfin excpt 0x0 P0 R0 - -
i386 int $0x80 eax eax edx -
ia64 break 0x100000 r15 r8 r9 r10 1, 6
loongarch syscall 0 a7 a0 - -
m68k trap #0 d0 d0 - -
microblaze brki r14,8 r12 r3 - -
mips syscall v0 v0 v1 a3 1, 6
nios2 trap r2 r2 - r7
parisc ble 0x100(%sr2, %r0) r20 r28 - -
powerpc sc r0 r3 - r0 1
powerpc64 sc r0 r3 - cr0.SO 1
riscv ecall a7 a0 a1 -
s390 svc 0 r1 r2 r3 - 3
s390x svc 0 r1 r2 r3 - 3
superh trapa #31 r3 r0 r1 - 4, 6
sparc/32 t 0x10 g1 o0 o1 psr/csr 1, 6
sparc/64 t 0x6d g1 o0 o1 psr/csr 1, 6
tile swint1 R10 R00 - R01 1
x86-64 syscall rax rax rdx - 5
x32 syscall rax rax rdx - 5
xtensa syscall a2 a2 - -
Virtual Memory Areas (VMAs)
view memory maps:
$ cat /proc/<PID>/maps
the results correspond partiallty to area's linux/mm_types.h::vm_area_struct
:
-------------------------------------------------------------
start~end perm offset major:minor inode image
-------------------------------------------------------------
start~end: start/end of the memory area
perm: bit mask for area R/W/X permission; p for private and s for shared
offset: offset into mapped file.
inode: inode number of mapped file. (0 for anoymous mappings)
image: file name of the mapped file. (empty for anoymous mappings)
view IO memory maps:
$ cat /proc/iomem
process memory map:
Each process has its mm_struct
that contains its list of VMAs, pagetabkes,
sync primitives, etc..
manually dumping memory w. GDB
- identify memory region start and end from
maps
- connect gdb to running process with pid
$ sudo gdb --pid <PID>
- dump memory in gdb
$ dump memory <PATH-TO-DUMP-FILE> <START_ADDR> <END_ADDR>
- the dump can be viewed with e.g.
hexdump
get_user_pages
Understanding the Linux Kernel, Chapter 11 Signals, Daniel P. Bovet & Marco Cesati, 3rd Edition, O'Reilly
man 7 signal (Linux manual page)
Standard signals
"P1990" : POSIX.1-1990 standard
"P2001" : the signal was added in SUSv2 and POSIX.1-2001.
NOTE: Numbers for X86/ARM and most others;
For {Alpha/SPARC, MIPS, PARISC} they would be different)
────────────────────────────────────────────────────────────────────────
Signal Standard Action Comment
────────────────────────────────────────────────────────────────────────
1 SIGHUP P1990 Term Hangup detected on controlling terminal
or death of controlling process
2 SIGINT P1990 Term Interrupt from keyboard
3 SIGQUIT P1990 Core Quit from keyboard
4 SIGILL P1990 Core Illegal Instruction
5 SIGTRAP P2001 Core Trace/breakpoint trap
6 SIGABRT P1990 Core Abort signal from abort(3)
6 SIGIOT - Core IOT trap. A synonym for SIGABRT
7 SIGBUS P2001 Core Bus error (bad memory access)
8 SIGFPE P1990 Core Floating-point exception
9 SIGKILL P1990 Term Kill signal
10 SIGUSR1 P1990 Term User-defined signal 1
11 SIGSEGV P1990 Core Invalid memory reference
12 SIGUSR2 P1990 Term User-defined signal 2
13 SIGPIPE P1990 Term Broken pipe: write to pipe with no
14 SIGALRM P1990 Term Timer signal from alarm(2)
15 SIGTERM P1990 Term Termination signal
16 SIGSTKFLT - Term Stack fault on coprocessor (unused)
16 UNUSED ----- ---- (in some cases..)
17 SIGCHLD P1990 Ign Child stopped or terminated
SIGCLD - Ign A synonym for SIGCHLD
18 SIGCONT P1990 Cont Continue if stopped
19 SIGSTOP P1990 Stop Stop process
20 SIGTSTP P1990 Stop Stop typed at terminal
21 SIGTTIN P1990 Stop Terminal input for background process
22 SIGTTOU P1990 Stop Terminal output for background process
23 SIGURG P2001 Ign Urgent condition on socket (4.2BSD)
24 SIGXCPU P2001 Core CPU time limit exceeded (4.2BSD);
25 SIGXFSZ P2001 Core File size limit exceeded (4.2BSD);
see setrlimit(2)
26 SIGVTALRM P2001 Term Virtual alarm clock (4.2BSD)
27 SIGPROF P2001 Term Profiling timer expired
28 SIGWINCH - Ign Window resize signal (4.3BSD, Sun)
29 SIGIO - Term I/O now possible (4.2BSD)
29 SIGPOLL P2001 Term Pollable event (Sys V);
synonym for SIGIO
30 SIGPWR - Term Power failure (System V)
30 SIGINFO - A synonym for SIGPWR
31 SIGSYS P2001 Core Bad system call (SVr4);
see also seccomp(2)
SIGUNUSED - Core Synonymous with SIGSYS
- SIGEMT - Term Emulator trap
SIGLOST - Term File lock lost (unused)
────────────────────────────────────────────────────────────────────────
The signals SIGKILL and SIGSTOP cannot be caught, blocked, or
ignored.
Up to and including Linux 2.2, the default behavior for SIGSYS,
SIGXCPU, SIGXFSZ, and (on architectures other than SPARC and
MIPS) SIGBUS was to terminate the process (without a core dump).
(On some other UNIX systems the default action for SIGXCPU and
SIGXFSZ is to terminate the process without a core dump.) Linux
2.4 conforms to the POSIX.1-2001 requirements for these signals,
terminating the process with a core dump.
SIGEMT is not specified in POSIX.1-2001, but nevertheless appears
on most other UNIX systems, where its default action is typically
to terminate the process with a core dump.
SIGPWR (which is not specified in POSIX.1-2001) is typically
ignored by default on those other UNIX systems where it appears.
SIGIO (which is not specified in POSIX.1-2001) is ignored by
default on several other UNIX systems.
POSIX Errno
from /include/linux/errno.h
No | ERR | Desc | Note |
---|---|---|---|
1 | EPERM | Operation not permitted | |
2 | ENOENT | No such file or directory | |
3 | ESRCH | No such process | |
4 | EINTR | Interrupted system call | |
5 | EIO | Input/output error | |
6 | ENXIO | No such device or address | |
7 | E2BIG | Argument list too long | |
8 | ENOEXEC | Exec format error | |
9 | EBADF | Bad file descriptor | |
10 | ECHILD | No child processes | |
11 | EAGAIN | Resource temporarily unavailable | |
12 | ENOMEM | Cannot allocate memory | |
13 | EACCES | Permission denied | |
14 | EFAULT | Bad address | |
15 | ENOTBLK | Block device required | |
16 | EBUSY | Device or resource busy | |
17 | EEXIST | File exists | |
18 | EXDEV | Invalid cross-device link | |
19 | ENODEV | No such device | |
20 | ENOTDIR | Not a directory | |
21 | EISDIR | Is a directory | |
22 | EINVAL | Invalid argument | |
23 | ENFILE | Too many open files in system | |
24 | EMFILE | Too many open files | |
25 | ENOTTY | Inappropriate ioctl for device | |
26 | ETXTBSY | Text file busy | |
27 | EFBIG | File too large | |
28 | ENOSPC | No space left on device | |
29 | ESPIPE | Illegal seek | |
30 | EROFS | Read-only file system | |
31 | EMLINK | Too many links | |
32 | EPIPE | Broken pipe | |
33 | EDOM | Numerical argument out of domain | |
34 | ERANGE | Numerical result out of range | |
35 | EDEADLK | Resource deadlock avoided | |
36 | ENAMETOOLONG | File name too long | |
37 | ENOLCK | No locks available | |
38 | ENOSYS | Function not implemented | |
39 | ENOTEMPTY | Directory not empty | |
40 | ELOOP | Too many levels of symbolic links | |
41 | EWOULDBLOCK | Operation would block | Non POSIX |
42 | ENOMSG | No message of desired type | |
43 | EIDRM | Identifier removed | |
44 | ECHRNG | Channel number out of range | |
45 | EL2NSYNC | Level 2 not synchronized | |
46 | EL3HLT | Level 3 halted | |
47 | EL3RST | Level 3 reset | |
48 | ELNRNG | Link number out of range | |
49 | EUNATCH | Protocol driver not attached | |
50 | ENOCSI | No CSI structure available | |
51 | EL2HLT | Level 2 halted | |
52 | EBADE | Invalid exchange | |
53 | EBADR | Invalid request descriptor | |
54 | EXFULL | Exchange full | |
55 | ENOANO | No anode | |
56 | EBADRQC | Invalid request code | |
57 | EBADSLT | Invalid slot | |
58 | EDEADLOCK | File locking deadlock error | Non POSIX |
59 | EBFONT | Bad font file format | |
60 | ENOSTR | Device not a stream | |
61 | ENODATA | No data available | |
62 | ETIME | Timer expired | |
63 | ENOSR | Out of streams resources | |
64 | ENONET | Machine is not on the network | |
65 | ENOPKG | Package not installed | |
66 | EREMOTE | Object is remote | |
67 | ENOLINK | Link has been severed | |
68 | EADV | Advertise error | |
69 | ESRMNT | Srmount error | |
70 | ECOMM | Communication error on send | |
71 | EPROTO | Protocol error | |
72 | EMULTIHOP | Multihop attempted | |
73 | EDOTDOT | RFS specific error | |
74 | EBADMSG | Bad message | |
75 | EOVERFLOW | Value too large for defined data type | |
76 | ENOTUNIQ | Name not unique on network | |
77 | EBADFD | File descriptor in bad state | |
78 | EREMCHG | Remote address changed | |
79 | ELIBACC | Can not access a needed shared library | |
80 | ELIBBAD | Accessing a corrupted shared library | |
81 | ELIBSCN | .lib section in a.out corrupted | |
82 | ELIBMAX | Attempting to link in too many shared libraries | |
83 | ELIBEXEC | Cannot exec a shared library directly | |
84 | EILSEQ | Invalid or incomplete multibyte or wide character | |
85 | ERESTART | Interrupted system call should be restarted | |
86 | ESTRPIPE | Streams pipe error | |
87 | EUSERS | Too many users | |
88 | ENOTSOCK | Socket operation on non-socket | |
89 | EDESTADDRREQ | Destination address required | |
90 | EMSGSIZE | Message too long | |
91 | EPROTOTYPE | Protocol wrong type for socket | |
92 | ENOPROTOOPT | Protocol not available | |
93 | EPROTONOSUPPORT | Protocol not supported | |
94 | ESOCKTNOSUPPORT | Socket type not supported | |
95 | EOPNOTSUPP | Operation not supported | |
96 | EPFNOSUPPORT | Protocol family not supported | |
97 | EAFNOSUPPORT | Address family not supported by protocol | |
98 | EADDRINUSE | Address already in use | |
99 | EADDRNOTAVAIL | Cannot assign requested address | |
100 | ENETDOWN | Network is down | |
101 | ENETUNREACH | Network is unreachable | |
102 | ENETRESET | Network dropped connection on reset | |
103 | ECONNABORTED | Software caused connection abort | |
104 | ECONNRESET | Connection reset by peer | |
105 | ENOBUFS | No buffer space available | |
106 | EISCONN | Transport endpoint is already connected | |
107 | ENOTCONN | Transport endpoint is not connected | |
108 | ESHUTDOWN | Cannot send after transport endpoint shutdown | |
109 | ETOOMANYREFS | Too many references: cannot splice | |
110 | ETIMEDOUT | Connection timed out | |
111 | ECONNREFUSED | Connection refused | |
112 | EHOSTDOWN | Host is down | |
113 | EHOSTUNREACH | No route to host | |
114 | EALREADY | Operation already in progress | |
115 | EINPROGRESS | Operation now in progress | |
116 | ESTALE | Stale file handle | |
117 | EUCLEAN | Structure needs cleaning | |
118 | ENOTNAM | Not a XENIX named type file | |
119 | ENAVAIL | No XENIX semaphores available | |
120 | EISNAM | Is a named type file | |
121 | EREMOTEIO | Remote I/O error | |
122 | EDQUOT | Disk quota exceeded | |
123 | ENOMEDIUM | No medium found | |
124 | EMEDIUMTYPE | Wrong medium type | |
125 | ECANCELED | Operation canceled | |
126 | ENOKEY | Required key not available | |
127 | EKEYEXPIRED | Key has expired | |
128 | EKEYREVOKED | Key has been revoked | |
129 | EKEYREJECTED | Key was rejected by service | |
130 | EOWNERDEAD | Owner died | |
131 | ENOTRECOVERABLE | State not recoverable | |
135 | ERFKILL | Operation not possible due to RF-kill | |
133 | EHWPOISON | Memory page has hardware error |
USEFUL RESOURCES
USEFUL RESOURCES
rustlings (tutorials and exercises)
rust programming language (official "the Book")
Crust of Rust (advanced) by Jon Gjengset
In this series we seek to understand intermediate Rust concepts by diving into real examples and working code, often by re-implementing functionality from the standard library.
the rustonomicon (unsafe rust)
(WIP)
https://doc.rust-lang.org/std/fmt/
https://doc.rust-lang.org/alloc/
https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/the-stack-and-the-heap.html
crate ::alloc::
- Provides: smart pointer and heap management
use alloc::*
with#![no_std]
Pointers
Box the smart pointer type (to objects in the heap):
- there can only be one owner of Box
- Owner can decide to mutate the content.
- Restrive inherited mutability
Rc the reference counted pointer
- reference counter is NOT THREAD SAFE, is meant for intra-thread sharing.
- Rc wraps type
T
, only allows access to&T
- Often paired with
Cell
orRefCell
Arc the atomic reference counted pointer
- threadsafe equivalent of
Rc
type
Heap interfaces
alloc::alloc Memory allocation APIs
#![allow(unused)] fn main() { // trait GlobalAlloc // Register memory allocator as std's default. #[global_allocator] pub static GLOBAL_ALLOCATOR: MyAllocator = MyAllocator::New(); impl GlobalAlloc for MyAllocator { // Required methods unsafe fn alloc(&self, layout: Layout) -> *mut u8; unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout); // Provided methods unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { ... } unsafe fn realloc( &self, ptr: *mut u8, layout: Layout, new_size: usize ) -> *mut u8 { ... } } }
Enum into/from primitive types : with num_enum
[dependencies.num_enum]
version = "0.7.2"
default-features = false # to disable std feature
#![allow(unused)] fn main() { use num_enum::{IntoPrimitive, TryFromPrimitive}; #[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq)] #[repr(u8)] enum Status { OUTB = 0x01, INPB = 0x02, AUXB = 0x20, // this may be wrong here. } // ... if let Ok(s) = Status::try_from(var_uint8) { // deal with s::Status } else { // deal with conversion error } ``` ### bitflags https://docs.rs/bitflags/latest/bitflags/ https://docs.rs/bitflags/latest/bitflags/trait.Flags.html **Cautions** - **Flags with no bits set should be avoided!!!*** Interact strangely with Flags:: contains and Flags::intersects. A zero-bit flag is always contained but never intersected. The names of zero-bit flags are never formatted. - **Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag** **Usage** Cargo.toml ``` [dependencies.bitflags] version = "2.4.2" ``` ```rust // basic use bitflags::bitflags; bitflags! { #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Flags: u32 { const A = 0b00000001; const B = 0b00000010; const C = 0b00000100; // specify ALL bits as known bits. // use this for externally defined flags const _ = !0; } } // with custom methods: impl Flags { pub fn as_u64(&self) -> u64 { self.bits() as u64 } } // using: let ab = Flags::A | Flags::B; // union let a = ab & Flags::A; // intersection let b = ab - Flags::A; // difference let c = !ab; // complement ``` Derives: - Debug, Clone, Copy, PartialEq, Eq, Hash ... **Terminology** ``` bitflags! { struct FlagsType: u8 { | |_ Bits type | +------- Flags type const A = 1; |____ Flag } } let flag = FlagsType::A; |___ Flags value ``` **Known and unknown bits** Defined bits are 'known bits', otherwise 'unknown bits'. Operators may **unset** any unknown bits they encounter. ```rust bitflags! { struct Flags: u8 { const A = 1; const B = 1 << 1; const C = 1 << 2; } } // known bits: 0b0000_0111 // unknown bits: 0b1111_1000 ``` }
https://google.github.io/comprehensive-rust/
https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
TODO :
- automatic dereference
- concurrency
- smart pointer
Cheatsheet
&T &mut T Type: shared / mutable reference to type T
& &mut Operator: make a (mutable) reference value
* Operator: dereferences
*const T Raw pointer to immutable T
*mut T Raw pointer to mutable T
Reference
#![allow(unused)] fn main() { /// reference provides way to access another value without takine responsibility /// for the value aka. borrowing. Shared references are read-only and the /// referenced data cannot change. fn shared_references() { let a = 'A'; let b = 'B'; let mut r: &char = &a; println!("r: {}", *r); r = &b; // a mutable reference be changed to point to other data // but the refrenced data itself cannot change in this case. // DIFFERENT than C++ !! // shared reference does NOT allow modifying the value it refers to, // EVEN IF the value is mutable println!("r: {}", *r); // auto dereferences: use *r or r are the same. println!("r: {}", r); } /// exclusive aka mutable references, allow changing the value they refer to. /// they have type &mut T /// differentiate the two: /// let mut x_coord: &i32 /// let mut x_coord: &mut i32 fn exclusive_references() { // &mut T a exclusive (mutable) reference to type T // NO other (shared or exclusive) reference can exist at the same time // the referenced value cannot be accessed while the exclusive reference // exists let mut point = (1, 2); let x_coord = &mut point.0; *x_coord = 20; // point.0 = 0; // this is illegal while x_coord is alive println!("point: {point:?}"); } }
Smart Pointers
TODO finish this
Raw Pointers
#![allow(unused)] fn main() { fn raw_pointer() { let mut num:i32 = 5; // declaring raw pointers is safe. let ptr1 = &mut num as *mut i32; let ptr2 = &mut num as *mut i32; // both are valid pointer to // dereferencing raw pointers is unsafe unsafe { *ptr1 += 1; *ptr2 += 1; } println!("{}", num); // 7 let num:i32 = 5; // illegal because num is not mutable let ptr3 = &mut num as *mut i32; // illegal because the different type let ptr3 = &num as *const u32; // "legal" cast with indirection let ptr = &(r as u32) as *const u32; // casting and reading is legal let ptr_mut = ptr as *mut u32; // but dereferencing is illega even in unsafe // TODO learn UnsafeCell unsafe{ println!("{}", *ptr_mut); *ptr_mut ++; println!("{}", *ptr_mut); } // cast raw value into raw pointer: let addr:usize = 0xffff40; let wtf = unsafe{*(addr as *const u64)}; println!("{}", wtf); // segfault // TODO I think it's hackable to cast an address to usize, // then cast it to whatever you want. But it turns out that // &T as usize is illegal... are there other hacks? } }
https://doc.rust-lang.org/book/ch05-01-defining-structs.html
// Define struct User { field1: <type>, field2: <type>, // ... } // Use: fn main() { let user1 = User {field1: value1, field2: value2, // ... } } // init fn fn build_user(f1: <type>, f2: <type>, ...) -> User { User { field1: f1, field2: f2, // ... } } // Field Init shorthand: field names and parameter names are exactly the same fn build_user(fleld1: <type>, fleld2: <type>, ...) -> User { User { field1, field2, ...} } // create instance from struct update (from another instance) fn main() { // --snip-- let user2 = User { email: String::from("another@example.com"), ..user1 }; }
methods
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}
auto dereferencing
Rust doesn’t have an equivalent to the -> operator; instead, Rust has a feature
called automatic referencing and dereferencing. Calling methods is one of the
few places in Rust that has this behavior.
Here’s how it works: when you call a method with object.something(), Rust automatically adds in &, &mut, or * so object matches the signature of the method. In other words, the following are the same:
p1.distance(&p2);
(&p1).distance(&p2);
Option and Result
Takeaways from ...
code snippets from Logan Smith:
https://www.youtube.com/watch?v=s5S2Ed5T-dc
enum Result<T, E> {
Ok(T),
Err(E)
}
enum Option<T> {
Some(T),
None
}
Result
is a generalization ofOption
.- For
Result
there is a custome TypeE
if the value is not valid. ForOption
there is only one represented byNone
(i.e. there is only one obvious reason that this function could fail)
result.ok()
------------------------->
Result<T, E> Option<T>
<-------------------------
opt.ok_or(e)
opt.ok_or_else(|| f(x))
Operand?
match operand {
Ok(x) => x,
Err(e) => return Err(From::from(e)),
}
example:
#![allow(unused)] fn main() { struct W(String, String); fn fallible(_: u8) -> Result<String, E> { todo!(); } impl W { fn new(x: u8, y:u8) -> Result<Self, E> { // short circuit the function and returns the error // if either fallible() fails let x = fallible(x)?; let y = fallible(y)?; Ok(Self(x, y)) } // does the same thing fn new_v2(x: u8, y:u8) -> Result<Self, E> { Ok(Self(fallible(x)?, fallible(y)?)) } } // general: struct W(Vec<String>); impl W { fn new(v:&[u8]) -> Result<Self, E> { let v = v.iter() .map( |&x| fallible(x)) .collect::<Result<Vec<_>, _>>(); Ok(Self(v?)) } } }
Example 2:
#![allow(unused)] fn main() { #[derive(Debug)] struct Node { /**/ } #[derive(Debug)] enum GrandparentError{ NoParent, NoGrandparent } // the derive_more::From allows to convert Either GrandparentError // or IOError into LogGpError // optionally use thiserror::Error #[derive(Debug, derive_more::From)] enum LogGpError { GrandparentError(GE), IOError(io::Error), } impl Node { fn parent(&self) -> Option<&Node> { todo!(); } fn grandparent(n: &Node) -> Result<&Node, GrandparentError> { Ok( n.parent().ok_or(GrandparentError::NoParent)? .parent().ok_or(GrandparentError::NoGrandparent)? ) } fn log_gp(n: &Node) -> Result<(), LogGpError> { let g = grandparent(n)?; // may throw GrandparentError fs::write(/**/)?; // may throw IOError } // anyhow::Result - dynamically works with any error type... // (with a cost ... with its own vtable) fn log_gp(n: &Node) -> anyhow::Result<()> { let g = grandparent(n)?; // may throw GrandparentError fs::write(/**/)?; // may throw IOError } } }
Infallible
#![allow(unused)] fn main() { // e.g. enum Result<bool, Infallible> { Ok(bool), // 2 possible values Err(Infallible), // ZERO possible value } // e.g. impl FromStr for Wrapper { type Err = Infallible; // CAN NOT FAIL! fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(Self(s.into())) } } }
References
Study of std::io::Error
https://www.youtube.com/watch?v=s5S2Ed5T-dc
USEFUL RESOURCES
git rebase in depth
Git branching - Rebasing
email + git workflow
How do I resolve merge conflicts in a Git repository?
Conventional Commits
most upvoted git questions on stackoverflow
Trivial question needs trivial solution
How to check out a pull (github) request locally
git fetch <remote> pull/<id>/head:<local branch>
git checkout <local branch>
# For example, to fetch the PR `#1234` from `origin` into local branch `test_pr_1234`
git fetch origin pull/1234/head:test_pr_1234
git checkout test_pr_11234
How do I delete a Git branch locally and remotely
git branch -d <branchname>
git push -d <remote> <branchname>
How can i rename a local Git branch
git branch -m <oldname (optional)> <newname>
Remove a file from a Git repository without deleting it from the local filesystem
How do I make Git forget about a file that was tracked, but is nore in .gitignore?
git rm --cached <file> # use `-r` for directory
How do I change the URI (URL) for a remote Git repository?
git remote set-url <remote> <url>
git rm <path-to-submodule> # newer git version
Make an existing Git branch track a remote branch?
git branch -u <remote>/<remote_branch_name> <local_branch_name (optional)>
How do I discard unstaged changes in Git?
git restore <path-to-file or .> # newer git
git checkout -- <path-to-file or .> # older git
How do I clone all remote branches?
How can I delete a remote tag?
How do I remove local (untracked) files from the current Git working tree? (git clean)
Don't attempt to run before you learn to walk
How do I update or sync a forked repository on GitHub?
How do I checkout out a remote Git branch?
How to modify existing, unpushed commit messages?
How do I push a new local branch to a remote Git repository and track it too?
Interesting?
How do I find and restore a deleted file in a Git repository?
Move existing, uncommitted work to a new branch in Git
Move the most recent commit(s) to a new branch with Git
How do I add an empty directory to a Git repository?
Perhaps not the best thing to do
How do I delete a commit from a branch?
Understanding the concepts
What is the difference between 'git pull' and 'git fetch'?
What does cherry-picking a commit with Git mean?
Oops I fucked up
How do I undo the most recent local commits in Git
How do I undo 'git add' before commit?
How do I force 'git pull' to overwrite local files?
How do I revert a Git repository to a previous commit?
Undoing a git rebase
How can I reset or revert a file to a specific revision?
Reset local repository branch to be just like remote repository HEAD
Undo a Git merge that hasn't been pushed yet
Basic setup for git send-email
git config
Substitute *@email.provider
with your own. Not that the sendemail.smtpuser
,
sendemail.from
and user.email
does not necessarily have to be the same. Note
the differencenet.
git config --edit --global
[sendemail]
verify = off
annotate = yes
smtpserver = smtp.email.provider
smtpuser = your_account@email.provider
smtpencryption = ssl
smtpserverport = 465
from = you@email.provider
git send-email and options
[COMMAND]
git send-email --to="rec@email" <REF>
[REF]
e.g. HEAD~ , HEAD^2, <commit id>
[EMAIL OPTS]
-v<n> patch version (in the subject)
--subject-prefix=<str> e.g. "PATCH v4"
-l<n> log e.g. -l4 (changes since v1 etc..)
--cc/--bcc=<addr>
--from=<addr>
--reply-to=<addr>
--compose: invoke editor
--reply-to=<addr>
--in-reply-to=<id>
--subject=<str>
--to option, among others can be specified multiple times
clients (WIP)
(mutt): launch (neomutt) in the repo, select the patch from inbox, type
| git am
to apply the patch.
Comman gpg commands
Generate Keypair:
gpg --full-gen-key
generate revoke certificate:
gpg --gen-revoke [USER-ID]
list keys:
gpg --list-keys
option:
--keyid-format short/long
delete key:
gpg --delete-key [USER-ID]
output key:
gpg --armor --output public-key.txt --export [USER-ID]
upload key:
gpg --send-keys [USER-ID] --keyserver hkp://sybkeys.pgp.net
fingerprint:
gpg --fingerprint [USER-ID]
import key:
gpg --import [key-file]
search on server for key:
gpg --keyserver hkp://sybkeys.pgp.net --search-keys [USER-ID]
encrypt for someone:
gpg -r some@mail.x -e file
decrypt:
gpg -d file.gpg
sign data:
gpg --sign file
gpg --clearsign file
gpg --detach-sign file
gpg --armor --detach-sign file
verify sig:
gpg --verify [signature file] [file]
encrypt and sign:
gpg --local-user [sender id] --recipient [receiver id] --armor --sign --encrypt file
add additional email address:
gpg --edit-key [kei/user-id]
> adduid (and follow instructions)
> trust (optional)
private key export and import:
gpg --export-secret-keys --armor <USER-ID> privkey.asc
gpg --import privkey.asc
export subkeys:
gpg --list-secret-keys --with-subkey-fingerprint
gpg -a --export-secret-subkeys [subkey_id]! > /tmp/subkey.gpg
edit key:
gpg --edit-key <user-id>
edit key commands:
passwd #change passphrase
clean #compact any user id that is no longer usable (revoked or expired)
revkey #revoke a key
addkey #add a subkey
expire #change expiration time
addduid # add additional names
addphoto # add photo to key
save # save change and quit
Fix gpg signing failed: Inappropriate ioctl for device
export GPG_TTY=$(tty)
ref https://github.com/keybase/keybase-issues/issues/2798
I mean, wtf is this error message???
The Lost Art of Structure Packing by Eric S. Raymond
http://www.catb.org/esr/structure-packing/
https://www.gnu.org/software/grub/manual/multiboot/multiboot.txt
+-------------------+
0 | flags | (required)
+-------------------+
4 | mem_lower | (present if flags[0] is set)
8 | mem_upper | (present if flags[0] is set)
+-------------------+
12 | boot_device | (present if flags[1] is set)
+-------------------+
16 | cmdline | (present if flags[2] is set)
+-------------------+
20 | mods_count | (present if flags[3] is set)
24 | mods_addr | (present if flags[3] is set)
+-------------------+
28 - 40 | syms | (present if flags[4] or
| | flags[5] is set)
+-------------------+
44 | mmap_length | (present if flags[6] is set)
48 | mmap_addr | (present if flags[6] is set)
+-------------------+
52 | drives_length | (present if flags[7] is set)
56 | drives_addr | (present if flags[7] is set)
+-------------------+
60 | config_table | (present if flags[8] is set)
+-------------------+
64 | boot_loader_name | (present if flags[9] is set)
+-------------------+
68 | apm_table | (present if flags[10] is set)
+-------------------+
72 | vbe_control_info | (present if flags[11] is set)
76 | vbe_mode_info |
80 | vbe_mode |
82 | vbe_interface_seg |
84 | vbe_interface_off |
86 | vbe_interface_len |
+-------------------+
88 | framebuffer_addr | (present if flags[12] is set)
96 | framebuffer_pitch |
100 | framebuffer_width |
104 | framebuffer_height|
108 | framebuffer_bpp |
109 | framebuffer_type |
110-115 | color_info |
+-------------------+
An elf (PL: elves) is a type of humanoid supernatural being in Germanic folklore....ah I mean ELF the Executable and Linkable Format.
The structure:
+---------------------+
| ELF Header |
+---------------------+
| Prog Header Table |
+---------------------+
| LOAD SECTIONS... |
+---------------------+
| LOAD SECTIONS... |
+---------------------+
| LOAD SECTIONS... |
+---------------------+
| Section header Table|
+---------------------+
The ELF header is 64 bytes in length for 64 bits programs and 52 for 32 bits.
ELF file header
$ hexdump -C -n64 /usr/bin/ls
# hexdump of first 64 bytes
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 03 00 3e 00 01 00 00 00 a0 5f 00 00 00 00 00 00 |..>......_......|
00000020 40 00 00 00 00 00 00 00 b8 13 02 00 00 00 00 00 |@...............|
00000030 00 00 00 00 40 00 38 00 0d 00 40 00 1b 00 1a 00 |....@.8...@.....|
00000040
(64b ver.)
Bit-offset size Field Purpose
----------------------------------------------------------------- Elf Ident.
0x00 4 MAG The Magic number 0x7F E L F
0x04 1 CLASS Format: 1 - 32bit 2 - 64bit
0x05 1 DATA Endianness: 1 - LE 2 - BE
0x06 1 VERSION Current version of ELF 1
0x07 1 OSABI Target OS ABI (see appendix)
0x08 1 ABIVERSION linux ignores it *
0x09 7 PAD Padding , 0s
-----------------------------------------------------------------
0x10 2 type type of object file REL/EXEC/DYN/etc..
0x12 2 machine ISA
0x14 4 version 1
----------------------------------------------------------------- 8/4 bytes
0x18 8(4) entry Entry point
0x20 8(4) phoff offset of program header, usually 64 or 52
0x28 8(4) shoff offset of section header table
------------------------------------------------------------------
0x30 4 flags Depends on architecture
0x34 2 ehsize size of this header, normally 64 or 52
0x36 2 phentsize size of a program header entry
0x38 2 phnum numbers of program header entries
0x3A 2 shentsize size of section header entry
0x3C 2 shnum humber of section header entries
0x3E 2 shstrndx index of section header table entry
that contains the section names
0x40 -----------------END OF ELF FILE HEADER----------------
Program header table
(64b ver.)
Bit-offset size Field Purpose
-----------------------------------------------------------------
0x00 4 type See appendix
0x04 4 flags 1-X 2-W 4-R
0x08 8 offset offset of the segment in the file
0x10 8 vaddr VA of the segment in memory
0x18 8 paddr PA of segment - where applicable
0x20 8 filesz size of segment in file (bytes)
0x28 8 memsz size of segment in memory (bytes)
0x30 8 align 0 and 1 - no align. Otherwise power of 2
0x38 ------------------------END OF PROGRAM HEADER ----(56)---
Let's use this example:
$ readelf -l /usr/bin/ls
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000003638 0x0000000000003638 R 0x1000
.....
$ hexdump -C /usr/bin/ls
# Size of program header entry is 0x38 = 56
00000000 |
... | First 64 bytes ELF File header
----------------------------------------------------------
00000040 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 |........@.......|
00000050 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |@.......@.......|
00000060 d8 02 00 00 00 00 00 00 d8 02 00 00 00 00 00 00 |................|
00000070 08 00 00 00 00 00 00 00 -- -- -- -- -- -- -- -- |........
-split-- -- -- -- -- -- -- -- -- 03 00 00 00 04 00 00 00 ........|
00000080 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00 |................|
00000090 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 |................|
000000a0 1c 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
000000b0 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 38 36 00 00 00 00 00 00 38 36 00 00 00 00 00 00 |86......86......|
000000e0 00 10 00 00 00 00 00 00 01 00 00 00 05 00 00 00 |................|
000000f0 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 |.@.......@......|
Note that this thing if little endian. The first program header
[40, 4]
: Type is 6, this is PHDR[44, 4]
: Flags is 4, this is read only[48, 8]
: Offset is 0x40, this offset in file, i.e. THIS TABLE[50, 16]
: vaddr and paddr, they are the same : 0x40;[60, 8]
: filesz == 0x2d8 == 728. Here 728 == phnum * phentsize = 13 * 56. i.e.[68, 8]
: memsz == 0x2d8 == filesz, implying there is no BSS in this seg. the size of the program header table.[70, 8]
: align = 0x8 , i.e. 2^8 = 256 bytes
Appendix
EL_OSABI OS
--------------------------------------------
0x00 System V
0x01 HP-UX
0x02 NetBSD
0x03 Linux
0x04 GNU Hurd
0x06 Solaris
0x07 AIX
0x08 IRIX
0x09 FreeBSD
0x0A Tru64
0x0B Novell ModestoA
0x0C OpenBSD
0x0D OpenVMS
0x0E NonStop Kernel
0x0F AROS
0x10 FnixOS
0x11 Nuxi CloudABI
0x12 Stratus Technologies OpenVOS
Types of Program Headers:
TYPE [0:3] Name Meaning
--------------------------------------------
0x0 NULL program header table unused
0x1 LOAD loadable segment
0x2 DYNAMIC Dyn. linking info
0x3 INTERP interpreter info
0x4 NOTE Aux. info
0x5 SHLIB Reserved
0x6 PHDR Segment containing PH table itself
0x7 TLS Thread-local storage template
0x60000000 LOOS reserved inclusive range OS Specific
0x6FFFFFFF HIOS |_
0x70000000 LOPROC reserved inclusive range Processor Specific
0x7FFFFFFF HIPROC |_
ABIVERSION: ABIVERSION is ignored for statically-linked executables.
Takeaways taken from the kernel's coding style guide. This is only for my own
reference. Please read the original article instead.
https://www.kernel.org/doc/html/v4.10/process/coding-style.html
Indentation:
- Tabs are Tabs, don't expand them into spaces.
- Tabs are 8 characters.
- No more than 3 levels of indentation should be necessary.
switch
andcase
labels on the same level- Don’t put multiple statements on a single line
Breaking long lines and strings:
- Textwidth = 80 chars
- Never break user-visible strings such as printk messages, because that breaks the ability to grep for them.
Braces and Spaces:
- For non function blocks put the opening brace last on the line, and put the closing brace first
- For function blocks opening brace at the beginning of the next line, thus:
- the closing brace is empty on a line of its own, except in the cases where it is followed by a continuation of the same statement
- Do not unnecessarily use braces where a single statement will do.
- The above DOES NOT apply if only one branch is a single statement.
- Use a space after keywords:
if, switch, case, for, do, while
- No space after
sizeof, __attribute__
etc. because they look like functions. - Do not add spaces around (inside) parenthesized expressions.
*
for pointers attach to the data name or function name, not to the type name.- One space around most binary and ternary operators:
= + - < > * / % | & ^ <= >= == != ? :
- No space after unary operators:
& * + - ~ ! sizeof typeof alignof __attribute__ defined
- No space before the postfix/prefix increment & decrement unary operators:
++ --
- No space around the
.
and->
structure member operators. - No trailing whitespace at end of lines.
Naming
- Do not encode type of a function into the name (Hungarian notation) - the compiler knows the types anyways.
- GLOBAL variables need to have descriptive names, as do global functions.
- LOCAL variable names should be short, and to the point
Typedefs
- It’s a mistake to use typedef for structures and pointers. (let
struct
bestruct
and let pointers be pointers) - NEVER use a typedef UNLESS one of the following applies
- totally opaque objects (where the typedef is actively used to hide what
the object is). e.t.
pte_t
- Clear integer types, where the abstraction helps avoid confusion whether it is int or long.
- when you use sparse to literally create a new type for type-checking.
- New types which are identical to standard C99 types, in certain exceptional circumstances.
- Types safe for use in userspace. e.t.
__u32
- totally opaque objects (where the typedef is actively used to hide what
the object is). e.t.
Functions
- In function prototypes, include parameter names with their data types.
- In source files, separate functions with one blank line. If the function is exported, the EXPORT macro for it should follow immediately after the closing function brace line.
more like "you should" than "you must":
- Functions should be short and sweet, and do just one thing (but it’s OK to have a longer function).
- Use helper functions with descriptive names (you can ask the compiler to in-line them if you think it’s performance-critical)
- the number of local variables. They shouldn’t exceed 5-10, or you’re doing something wrong.
Function return values and names
- Don't mix the two practice:
- error-code integer (-Exxx = failure, 0 = success) and
- succeeded boolean (0 = failure, non-zero = success)
- Convention:
- error-code integer for action or imperative command (e.g.
work()
) - boolean for predicate (e.g.
pci_dev_present()
)
- error-code integer for action or imperative command (e.g.
- All EXPORTed and public functions must respect this convention
If the name of a function is an action or an imperative command, the function should return an error-code integer. If the name is a predicate, the function should return a "succeeded" boolean. [...] Functions whose return value is the actual result of a computation, rather than an indication of whether the computation succeeded, are not subject to this rule.
Centralized exiting of functions
- just keep using
goto
s... - The goto statement comes in handy when a function exits from multiple locations and some common work such as cleanup has to be done. If there is no cleanup needed then just return directly.
- Choose label names which say what the goto does or why the goto exists.
Commenting
- Don't over-comment
- NEVER try to explain HOW your code works in a comment.
- Put the comments at the head of the function, telling people what it does, and possibly WHY it does it. NOT HOW.
- Avoid putting comments inside a function body.
- You can make small comments to note or warn about something particularly. clever (or ugly), but try to avoid excess.
- Kernel-doc format for kernel API functions
- Comment data, whether they are basic types or derived types.
Macros, Enums and RTL
- Names of macros defining constants and labels in enums are capitalized.
- CAPITALIZED macro names are appreciated but macros resembling functions may be named in lower case.
- Generally, inline functions are preferable to macros resembling functions.
- Macros with multiple statements should be enclosed in a do - while block:
- macros defining constants using expressions must enclose the expression in parentheses. Beware of similar issues with macros using parameters.
- Things to avoid when using macros:
- macros that affect control flow:
- macros that depend on having a local variable with a magic name:
#define FOO(val) bar(index, val)
- macros with arguments that are used as l-values:
FOO(x) = y;
will bite you if somebody e.g. turnsFOO
into an inline function. - namespace collisions when defining local variables in macros resembling functions:
- Don’t re-invent the kernel macros (check
include/linux/kernel.h
).
inline asm
- Don't use when C can do the same.
- Large, non-trivial assembly functions should go in .S files, with corresponding C prototypes defined in C header files. The C prototypes for assembly functions should use asmlinkage.
- mark asm statement as volatile, to prevent GCC from removing it if GCC does not notice any side effects. (not always necessarily)
- each instruction on a separate line in a separate quoted string; end each string except the last with nt to properly indent the next instruction in the assembly output:
The inline disease
do not abuse inline
- it's often not appropriate and it makes bigger program.
- Bigger icache footprint
- less memory available for pagecache.
A reasonable rule of thumb is to not put inline at functions that have more than 3 lines of code in them. An exception to this rule are the cases where a parameter is known to be a compiletime constant, and as a result of this constantness you know the compiler will be able to optimize most of your function away at compile time. For a good example of this later case, see the kmalloc() inline function.
Conditional Compilation
- Wherever possible, don’t use preprocessor conditionals (#if, #ifdef) in .c files;
Instead, use such conditionals in a header file defining functions for use in those .c files, providing no-op stub versions in the #else case, and then call those functions unconditionally from .c files.
- Prefer to compile out entire functions, rather than portions of functions or portions of expressions.
- Rather than putting an ifdef in an expression, factor out part or all of the expression into a separate helper function and apply the conditional to that function.
- mark variables
__maybe_unused
that go unused in a particular configuration. - where possible, use the IS_ENABLED macro to convert a Kconfig symbol into a C boolean expression, and use it in a normal C conditional:
- close non-trivial #if and #ifdef block with comments:
#ifdef CONFIG_SOMETHING
...
#endif /* CONFIG_SOMETHING */
Not included here:
- Kconfig
- Data structures
- Printing kernel messages
- Allocating memory (TODO)
Snippets
Switch/case:
switch (suffix) {
case 'G':
case 'g':
mem <<= 30;
break;
case 'K':
case 'k':
mem <<= 10;
/* fall through */
default:
break;
}
Non-function block:
if (x) {
// do ...
}
Non-function block w. addition terms:
if (x == y) {
// ..
} else if (x > y) {
// ...
} else {
// ....
}
Function block:
int function(int x)
{
// body of function
}
Single branch cond, no brakckets:
if (condition)
action();
Multi branch cond, some are not single stmt:
if (condition) {
do_this();
do_that();
} else {
otherwise();
}
Do not add spaces around (inside) parenthesized expressions. This is bad practice:
s = sizeof( struct file );
Export a function w. Macro:
int system_is_up(void)
{
return system_state == SYSTEM_RUNNING;
}
EXPORT_SYMBOL(system_is_up);
Macros with multiple statements should be enclosed in a do - while block:
#define macrofun(a, b, c) \
do { \
if (a == 5) \
do_this(b, c); \
} while (0)
macros that affect control flow: BELOW IS BAD
#define FOO(x) \
do { \
if (blah(x) < 0) \
return -EBUGGERED; \
} while (0)
enclose the expression (in macros) in parentheses:
#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)
namespace collisions when defining local variables in macros resembling
functions: ret is a common name for a local variable - __foo_ret
is less
likely to collide with an existing variable.:
#define FOO(x) \
({ \
typeof(x) ret; \
ret = calc_ret(x); \
(ret); \
})
multi-line inline asm example:
asm ("magic %reg1, #42\n\t"
"more_magic %reg2, %reg3"
: /* outputs */ : /* inputs */ : /* clobbers */);
where possible, use the IS_ENABLED macro to convert a Kconfig symbol into a C boolean expression, and use it in a normal C conditional. The compiler will constant-fold the conditional away, and include or exclude the block of code just as with an #ifdef, so this will not add any runtime overhead.
if (IS_ENABLED(CONFIG_SOMETHING)) {
...
}
MISC resources regarding licensing.
List of SPDX License Identifiers
https://spdx.org/licenses/
Re-using free software via writefreesoftware.org
https://writefreesoftware.org/learn/participate/derived-works/
Chossing a license via writefreesoftware.org
https://writefreesoftware.org/learn/participate/choose-a-license/
REUSE Specifications
https://reuse.software/
Intra-GPL compatibility matrix via gnu.org
https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility