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 (IA32) MSR LIST
FROM:
https://sites.uclouvain.be/SystInfo/usr/include/asm/msr-index.h.html
#ifndef _ASM_X86_MSR_INDEX_H
#define _ASM_X86_MSR_INDEX_H
/* CPU model specific register (MSR) numbers */
/* x86-64 specific MSRs */
#define MSR_EFER 0xc0000080 /* extended feature register */
#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */
#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */
#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target */
#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */
#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */
#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */
#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */
/* EFER bits: */
#define _EFER_SCE 0 /* SYSCALL/SYSRET */
#define _EFER_LME 8 /* Long mode enable */
#define _EFER_LMA 10 /* Long mode active (read-only) */
#define _EFER_NX 11 /* No execute enable */
#define _EFER_SVME 12 /* Enable virtualization */
#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */
#define EFER_SCE (1<<_EFER_SCE)
#define EFER_LME (1<<_EFER_LME)
#define EFER_LMA (1<<_EFER_LMA)
#define EFER_NX (1<<_EFER_NX)
#define EFER_SVME (1<<_EFER_SVME)
#define EFER_FFXSR (1<<_EFER_FFXSR)
/* Intel MSRs. Some also available on other CPUs */
#define MSR_IA32_PERFCTR0 0x000000c1
#define MSR_IA32_PERFCTR1 0x000000c2
#define MSR_FSB_FREQ 0x000000cd
#define MSR_MTRRcap 0x000000fe
#define MSR_IA32_BBL_CR_CTL 0x00000119
#define MSR_IA32_SYSENTER_CS 0x00000174
#define MSR_IA32_SYSENTER_ESP 0x00000175
#define MSR_IA32_SYSENTER_EIP 0x00000176
#define MSR_IA32_MCG_CAP 0x00000179
#define MSR_IA32_MCG_STATUS 0x0000017a
#define MSR_IA32_MCG_CTL 0x0000017b
#define MSR_IA32_PEBS_ENABLE 0x000003f1
#define MSR_IA32_DS_AREA 0x00000600
#define MSR_IA32_PERF_CAPABILITIES 0x00000345
#define MSR_MTRRfix64K_00000 0x00000250
#define MSR_MTRRfix16K_80000 0x00000258
#define MSR_MTRRfix16K_A0000 0x00000259
#define MSR_MTRRfix4K_C0000 0x00000268
#define MSR_MTRRfix4K_C8000 0x00000269
#define MSR_MTRRfix4K_D0000 0x0000026a
#define MSR_MTRRfix4K_D8000 0x0000026b
#define MSR_MTRRfix4K_E0000 0x0000026c
#define MSR_MTRRfix4K_E8000 0x0000026d
#define MSR_MTRRfix4K_F0000 0x0000026e
#define MSR_MTRRfix4K_F8000 0x0000026f
#define MSR_MTRRdefType 0x000002ff
#define MSR_IA32_CR_PAT 0x00000277
#define MSR_IA32_DEBUGCTLMSR 0x000001d9
#define MSR_IA32_LASTBRANCHFROMIP 0x000001db
#define MSR_IA32_LASTBRANCHTOIP 0x000001dc
#define MSR_IA32_LASTINTFROMIP 0x000001dd
#define MSR_IA32_LASTINTTOIP 0x000001de
/* DEBUGCTLMSR bits (others vary by model): */
#define _DEBUGCTLMSR_LBR 0 /* last branch recording */
#define _DEBUGCTLMSR_BTF 1 /* single-step on branches */
#define DEBUGCTLMSR_LBR (1UL << _DEBUGCTLMSR_LBR)
#define DEBUGCTLMSR_BTF (1UL << _DEBUGCTLMSR_BTF)
#define MSR_IA32_MC0_CTL 0x00000400
#define MSR_IA32_MC0_STATUS 0x00000401
#define MSR_IA32_MC0_ADDR 0x00000402
#define MSR_IA32_MC0_MISC 0x00000403
#define MSR_AMD64_MC0_MASK 0xc0010044
#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x))
#define MSR_IA32_MCx_STATUS(x) (MSR_IA32_MC0_STATUS + 4*(x))
#define MSR_IA32_MCx_ADDR(x) (MSR_IA32_MC0_ADDR + 4*(x))
#define MSR_IA32_MCx_MISC(x) (MSR_IA32_MC0_MISC + 4*(x))
#define MSR_AMD64_MCx_MASK(x) (MSR_AMD64_MC0_MASK + (x))
/* These are consecutive and not in the normal 4er MCE bank block */
#define MSR_IA32_MC0_CTL2 0x00000280
#define MSR_IA32_MCx_CTL2(x) (MSR_IA32_MC0_CTL2 + (x))
#define CMCI_EN (1ULL << 30)
#define CMCI_THRESHOLD_MASK 0xffffULL
#define MSR_P6_PERFCTR0 0x000000c1
#define MSR_P6_PERFCTR1 0x000000c2
#define MSR_P6_EVNTSEL0 0x00000186
#define MSR_P6_EVNTSEL1 0x00000187
/* AMD64 MSRs. Not complete. See the architecture manual for a more
complete list. */
#define MSR_AMD64_PATCH_LEVEL 0x0000008b
#define MSR_AMD64_NB_CFG 0xc001001f
#define MSR_AMD64_PATCH_LOADER 0xc0010020
#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
#define MSR_AMD64_OSVW_STATUS 0xc0010141
#define MSR_AMD64_DC_CFG 0xc0011022
#define MSR_AMD64_IBSFETCHCTL 0xc0011030
#define MSR_AMD64_IBSFETCHLINAD 0xc0011031
#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032
#define MSR_AMD64_IBSOPCTL 0xc0011033
#define MSR_AMD64_IBSOPRIP 0xc0011034
#define MSR_AMD64_IBSOPDATA 0xc0011035
#define MSR_AMD64_IBSOPDATA2 0xc0011036
#define MSR_AMD64_IBSOPDATA3 0xc0011037
#define MSR_AMD64_IBSDCLINAD 0xc0011038
#define MSR_AMD64_IBSDCPHYSAD 0xc0011039
#define MSR_AMD64_IBSCTL 0xc001103a
/* Fam 10h MSRs */
#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
#define FAM10H_MMIO_CONF_ENABLE (1<<0)
#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf
#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff
#define FAM10H_MMIO_CONF_BASE_SHIFT 20
#define MSR_FAM10H_NODE_ID 0xc001100c
/* K8 MSRs */
#define MSR_K8_TOP_MEM1 0xc001001a
#define MSR_K8_TOP_MEM2 0xc001001d
#define MSR_K8_SYSCFG 0xc0010010
#define MSR_K8_INT_PENDING_MSG 0xc0010055
/* C1E active bits in int pending message */
#define K8_INTP_C1E_ACTIVE_MASK 0x18000000
#define MSR_K8_TSEG_ADDR 0xc0010112
#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */
#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */
#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */
/* K7 MSRs */
#define MSR_K7_EVNTSEL0 0xc0010000
#define MSR_K7_PERFCTR0 0xc0010004
#define MSR_K7_EVNTSEL1 0xc0010001
#define MSR_K7_PERFCTR1 0xc0010005
#define MSR_K7_EVNTSEL2 0xc0010002
#define MSR_K7_PERFCTR2 0xc0010006
#define MSR_K7_EVNTSEL3 0xc0010003
#define MSR_K7_PERFCTR3 0xc0010007
#define MSR_K7_CLK_CTL 0xc001001b
#define MSR_K7_HWCR 0xc0010015
#define MSR_K7_FID_VID_CTL 0xc0010041
#define MSR_K7_FID_VID_STATUS 0xc0010042
/* K6 MSRs */
#define MSR_K6_EFER 0xc0000080
#define MSR_K6_STAR 0xc0000081
#define MSR_K6_WHCR 0xc0000082
#define MSR_K6_UWCCR 0xc0000085
#define MSR_K6_EPMR 0xc0000086
#define MSR_K6_PSOR 0xc0000087
#define MSR_K6_PFIR 0xc0000088
/* Centaur-Hauls/IDT defined MSRs. */
#define MSR_IDT_FCR1 0x00000107
#define MSR_IDT_FCR2 0x00000108
#define MSR_IDT_FCR3 0x00000109
#define MSR_IDT_FCR4 0x0000010a
#define MSR_IDT_MCR0 0x00000110
#define MSR_IDT_MCR1 0x00000111
#define MSR_IDT_MCR2 0x00000112
#define MSR_IDT_MCR3 0x00000113
#define MSR_IDT_MCR4 0x00000114
#define MSR_IDT_MCR5 0x00000115
#define MSR_IDT_MCR6 0x00000116
#define MSR_IDT_MCR7 0x00000117
#define MSR_IDT_MCR_CTRL 0x00000120
/* VIA Cyrix defined MSRs*/
#define MSR_VIA_FCR 0x00001107
#define MSR_VIA_LONGHAUL 0x0000110a
#define MSR_VIA_RNG 0x0000110b
#define MSR_VIA_BCR2 0x00001147
/* Transmeta defined MSRs */
#define MSR_TMTA_LONGRUN_CTRL 0x80868010
#define MSR_TMTA_LONGRUN_FLAGS 0x80868011
#define MSR_TMTA_LRTI_READOUT 0x80868018
#define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a
/* Intel defined MSRs. */
#define MSR_IA32_P5_MC_ADDR 0x00000000
#define MSR_IA32_P5_MC_TYPE 0x00000001
#define MSR_IA32_TSC 0x00000010
#define MSR_IA32_PLATFORM_ID 0x00000017
#define MSR_IA32_EBL_CR_POWERON 0x0000002a
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define FEATURE_CONTROL_LOCKED (1<<0)
#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1)
#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2)
#define MSR_IA32_APICBASE 0x0000001b
#define MSR_IA32_APICBASE_BSP (1<<8)
#define MSR_IA32_APICBASE_ENABLE (1<<11)
#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
#define MSR_IA32_UCODE_WRITE 0x00000079
#define MSR_IA32_UCODE_REV 0x0000008b
#define MSR_IA32_PERF_STATUS 0x00000198
#define MSR_IA32_PERF_CTL 0x00000199
#define MSR_IA32_MPERF 0x000000e7
#define MSR_IA32_APERF 0x000000e8
#define MSR_IA32_THERM_CONTROL 0x0000019a
#define MSR_IA32_THERM_INTERRUPT 0x0000019b
#define THERM_INT_LOW_ENABLE (1 << 0)
#define THERM_INT_HIGH_ENABLE (1 << 1)
#define MSR_IA32_THERM_STATUS 0x0000019c
#define THERM_STATUS_PROCHOT (1 << 0)
#define MSR_THERM2_CTL 0x0000019d
#define MSR_THERM2_CTL_TM_SELECT (1ULL << 16)
#define MSR_IA32_MISC_ENABLE 0x000001a0
/* MISC_ENABLE bits: architectural */
#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0)
#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1)
#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7)
#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11)
#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12)
#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16)
#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18)
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22)
#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23)
#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34)
/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */
#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2)
#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3)
#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4)
#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6)
#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8)
#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9)
#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10)
#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10)
#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13)
#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19)
#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20)
#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24)
#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37)
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38)
#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39)
/* P4/Xeon+ specific */
#define MSR_IA32_MCG_EAX 0x00000180
#define MSR_IA32_MCG_EBX 0x00000181
#define MSR_IA32_MCG_ECX 0x00000182
#define MSR_IA32_MCG_EDX 0x00000183
#define MSR_IA32_MCG_ESI 0x00000184
#define MSR_IA32_MCG_EDI 0x00000185
#define MSR_IA32_MCG_EBP 0x00000186
#define MSR_IA32_MCG_ESP 0x00000187
#define MSR_IA32_MCG_EFLAGS 0x00000188
#define MSR_IA32_MCG_EIP 0x00000189
#define MSR_IA32_MCG_RESERVED 0x0000018a
/* Pentium IV performance counter MSRs */
#define MSR_P4_BPU_PERFCTR0 0x00000300
#define MSR_P4_BPU_PERFCTR1 0x00000301
#define MSR_P4_BPU_PERFCTR2 0x00000302
#define MSR_P4_BPU_PERFCTR3 0x00000303
#define MSR_P4_MS_PERFCTR0 0x00000304
#define MSR_P4_MS_PERFCTR1 0x00000305
#define MSR_P4_MS_PERFCTR2 0x00000306
#define MSR_P4_MS_PERFCTR3 0x00000307
#define MSR_P4_FLAME_PERFCTR0 0x00000308
#define MSR_P4_FLAME_PERFCTR1 0x00000309
#define MSR_P4_FLAME_PERFCTR2 0x0000030a
#define MSR_P4_FLAME_PERFCTR3 0x0000030b
#define MSR_P4_IQ_PERFCTR0 0x0000030c
#define MSR_P4_IQ_PERFCTR1 0x0000030d
#define MSR_P4_IQ_PERFCTR2 0x0000030e
#define MSR_P4_IQ_PERFCTR3 0x0000030f
#define MSR_P4_IQ_PERFCTR4 0x00000310
#define MSR_P4_IQ_PERFCTR5 0x00000311
#define MSR_P4_BPU_CCCR0 0x00000360
#define MSR_P4_BPU_CCCR1 0x00000361
#define MSR_P4_BPU_CCCR2 0x00000362
#define MSR_P4_BPU_CCCR3 0x00000363
#define MSR_P4_MS_CCCR0 0x00000364
#define MSR_P4_MS_CCCR1 0x00000365
#define MSR_P4_MS_CCCR2 0x00000366
#define MSR_P4_MS_CCCR3 0x00000367
#define MSR_P4_FLAME_CCCR0 0x00000368
#define MSR_P4_FLAME_CCCR1 0x00000369
#define MSR_P4_FLAME_CCCR2 0x0000036a
#define MSR_P4_FLAME_CCCR3 0x0000036b
#define MSR_P4_IQ_CCCR0 0x0000036c
#define MSR_P4_IQ_CCCR1 0x0000036d
#define MSR_P4_IQ_CCCR2 0x0000036e
#define MSR_P4_IQ_CCCR3 0x0000036f
#define MSR_P4_IQ_CCCR4 0x00000370
#define MSR_P4_IQ_CCCR5 0x00000371
#define MSR_P4_ALF_ESCR0 0x000003ca
#define MSR_P4_ALF_ESCR1 0x000003cb
#define MSR_P4_BPU_ESCR0 0x000003b2
#define MSR_P4_BPU_ESCR1 0x000003b3
#define MSR_P4_BSU_ESCR0 0x000003a0
#define MSR_P4_BSU_ESCR1 0x000003a1
#define MSR_P4_CRU_ESCR0 0x000003b8
#define MSR_P4_CRU_ESCR1 0x000003b9
#define MSR_P4_CRU_ESCR2 0x000003cc
#define MSR_P4_CRU_ESCR3 0x000003cd
#define MSR_P4_CRU_ESCR4 0x000003e0
#define MSR_P4_CRU_ESCR5 0x000003e1
#define MSR_P4_DAC_ESCR0 0x000003a8
#define MSR_P4_DAC_ESCR1 0x000003a9
#define MSR_P4_FIRM_ESCR0 0x000003a4
#define MSR_P4_FIRM_ESCR1 0x000003a5
#define MSR_P4_FLAME_ESCR0 0x000003a6
#define MSR_P4_FLAME_ESCR1 0x000003a7
#define MSR_P4_FSB_ESCR0 0x000003a2
#define MSR_P4_FSB_ESCR1 0x000003a3
#define MSR_P4_IQ_ESCR0 0x000003ba
#define MSR_P4_IQ_ESCR1 0x000003bb
#define MSR_P4_IS_ESCR0 0x000003b4
#define MSR_P4_IS_ESCR1 0x000003b5
#define MSR_P4_ITLB_ESCR0 0x000003b6
#define MSR_P4_ITLB_ESCR1 0x000003b7
#define MSR_P4_IX_ESCR0 0x000003c8
#define MSR_P4_IX_ESCR1 0x000003c9
#define MSR_P4_MOB_ESCR0 0x000003aa
#define MSR_P4_MOB_ESCR1 0x000003ab
#define MSR_P4_MS_ESCR0 0x000003c0
#define MSR_P4_MS_ESCR1 0x000003c1
#define MSR_P4_PMH_ESCR0 0x000003ac
#define MSR_P4_PMH_ESCR1 0x000003ad
#define MSR_P4_RAT_ESCR0 0x000003bc
#define MSR_P4_RAT_ESCR1 0x000003bd
#define MSR_P4_SAAT_ESCR0 0x000003ae
#define MSR_P4_SAAT_ESCR1 0x000003af
#define MSR_P4_SSU_ESCR0 0x000003be
#define MSR_P4_SSU_ESCR1 0x000003bf /* guess: not in manual */
#define MSR_P4_TBPU_ESCR0 0x000003c2
#define MSR_P4_TBPU_ESCR1 0x000003c3
#define MSR_P4_TC_ESCR0 0x000003c4
#define MSR_P4_TC_ESCR1 0x000003c5
#define MSR_P4_U2L_ESCR0 0x000003b0
#define MSR_P4_U2L_ESCR1 0x000003b1
/* Intel Core-based CPU performance counters */
#define MSR_CORE_PERF_FIXED_CTR0 0x00000309
#define MSR_CORE_PERF_FIXED_CTR1 0x0000030a
#define MSR_CORE_PERF_FIXED_CTR2 0x0000030b
#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x0000038d
#define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e
#define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f
#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390
/* Geode defined MSRs */
#define MSR_GEODE_BUSCONT_CONF0 0x00001900
/* Intel VT MSRs */
#define MSR_IA32_VMX_BASIC 0x00000480
#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481
#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482
#define MSR_IA32_VMX_EXIT_CTLS 0x00000483
#define MSR_IA32_VMX_ENTRY_CTLS 0x00000484
#define MSR_IA32_VMX_MISC 0x00000485
#define MSR_IA32_VMX_CR0_FIXED0 0x00000486
#define MSR_IA32_VMX_CR0_FIXED1 0x00000487
#define MSR_IA32_VMX_CR4_FIXED0 0x00000488
#define MSR_IA32_VMX_CR4_FIXED1 0x00000489
#define MSR_IA32_VMX_VMCS_ENUM 0x0000048a
#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b
#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c
/* AMD-V MSRs */
#define MSR_VM_CR 0xc0010114
#define MSR_VM_IGNNE 0xc0010115
#define MSR_VM_HSAVE_PA 0xc0010117
#endif /* _ASM_X86_MSR_INDEX_H */
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)
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.
merge unrelated git history
This is useful for incorporating third-party code into your project, as an
alternative to git submodule
TL;DR
e.g. you want to incorporate their_project
(master) into
your_project/libs/their_project
(master)
# modify target repo to put all files into a subdirectory,
# i.e. libs/their_project
cd <their project>
git filter-repo --to-subdirectory-filter libs/their_project
# add target project to yoru remote
cd <your_project>
git remote add <rname_theirs> <url-to-their-project>
# do the merging
git merge --allow-unrelated-histories <rname_thries>/master
# remove temporaroy remote
git remote remove <rname_theirs>
Effect
git history of your_project
before the merge
* a0c3793 (HEAD -> master) add makefile
* 8100bab add readme
* 2451af5 add hello world
git history of their_project
* af8683a (HEAD -> master) lib: fix abc
* e232dc4 modify readme
* a0e5690 lib: add xyz
the resulting git hostiry of your_project
* 8b19fed (HEAD -> master) Merge remote-tracking branch 'libxyz/master'
|\
| * af8683a (libxyz/master) lib: fix abc
| * e232dc4 modify readme
| * a0e5690 lib: add xyz
* a0c3793 add makefile
* 8100bab add readme
* 2451af5 add hello world
see @a0e5690
, the two branches have no common ancestor
ref
Merge two Git repositories without breaking file history https://stackoverflow.com/questions/13040958
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.
SPDX Specs and REUSE
source: https://reuse.software/spec-3.3/
license identifier
SPDX-License-Identifier: GPL-3.0-or-later
copyright text (spdx format is recommended)
SPDX-FileCopyrightText: 2021 Jane Doe
SPDX-FileCopyrightText: 2019 Jane Doe <jane@example.com>
SPDX-FileCopyrightText: © 2019 John Doe <john@example.com>
SPDX-FileCopyrightText: Contributors to Example Project <https://project.example.com>
SPDX-FileCopyrightText: 2023 Alice Hack and (other) contributors to Project X <URL>
SPDX-SnippetCopyrightText: (C) Example Cooperative <info@coop.example.com>
compatible copyright text (not recommended)
Copyright 2016, 2018-2019 Joe Anybody
Copyright (c) Alice, some rights reserved
© Example Corporation <https://corp.example.com>
in case not for the whole file (in-line snippet comments)
# SPDX-SnippetBegin
# SPDX-SnippetCopyrightText: 2022 Jane Doe <jane@example.com>
# SPDX-License-Identifier: MIT
print("Hello, world!")
# SPDX-SnippetEnd
Reference
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