ARMv7 CPSR位图
ARMv7架构中的CPSR(Current Program Status Register)是32位的寄存器,用于存储处理器的当前状态信息,包括条件标志、中断禁止位、处理器模式等。

以下是CPSR寄存器中每个bit位的详细说明:
1. 条件标志位(Condition Flags)
这些标志位用于指示算术逻辑单元(ALU)操作的结果状态,支持条件执行指令。
| Bit 位置 | 标志位 | 功能描述 |
|---|---|---|
| 31 | N (Negative) | 负数标志。如果运算结果为负数(补码表示),则N=1;否则N=0。 |
| 30 | Z (Zero) | 零标志。如果运算结果为0,则Z=1;否则Z=0。 |
| 29 | C (Carry) | 进位/借位标志: - 加法操作:如果结果产生进位(无符号溢出),则C=1。 - 减法操作:如果发生借位(无符号下溢),则C=0。 - 移位操作:C保存最后一次移出的位。 |
| 28 | V (Overflow) | 溢出标志。如果带符号运算发生溢出(结果超出补码范围),则V=1。 |
2. 控制位(Control Bits)
这些位控制处理器的运行模式、中断屏蔽、指令集状态等。
| Bit 位置 | 标志位 | 功能描述 |
|---|---|---|
| 27 | Q (Cumulative Saturation) | 饱和标志。仅在ARMv5TE及更高版本中存在,用于指示DSP指令(如饱和加法)是否发生溢出或饱和。 |
| 26:25 | IT[1:0] | Thumb-2指令集的If-Then条件执行状态位的一部分。与IT[7:2](见下文)共同决定条件执行的范围。 |
| 24 | J (Jazelle) | Jazelle模式标志: - J=1:处理器处于Jazelle模式(执行Java字节码)。 - J=0:非Jazelle模式。 |
| 23:20 | 保留位 | 保留未使用,通常忽略。 |
| 19:16 | GE[3:0] | SIMD(单指令多数据)指令的“大于等于”标志。用于控制SIMD指令的并行比较操作。 |
| 15:10 | IT[7:2] | Thumb-2指令集的If-Then条件执行状态位。与IT[1:0](见上文)共同决定条件执行的范围(最多4条指令)。 |
| 9 | E (Endianness) | 大小端模式控制: - E=1:大端模式(Big-Endian)。 - E=0:小端模式(Little-Endian)。 |
| 8 | A (Asynchronous Abort Mask) | 异步终止屏蔽位: - A=1:禁止异步终止(如外部中断)。 - A=0:允许异步终止。 |
| 7 | I (IRQ Mask) | 中断屏蔽位(IRQ): - I=1:禁止普通中断(IRQ)。 - I=0:允许普通中断(IRQ)。 |
| 6 | F (FIQ Mask) | 快速中断屏蔽位(FIQ): - F=1:禁止快速中断(FIQ)。 - F=0:允许快速中断(FIQ)。 |
| 5 | T (Thumb Mode) | 指令集模式标志: - T=1:处理器处于Thumb状态(16位指令集)。 - T=0:处理器处于ARM状态(32位指令集)。 J和T位组合决定具体模式: - J=0, T=0:ARM指令集。 - J=0, T=1:Thumb指令集。 - J=1, T=0:Jazelle指令集。 - J=1, T=1:ThumbEE指令集。 |
3. 处理器模式位(Mode Bits)
M[4:0](Bit 4~0)用于指定处理器当前的工作模式。ARMv7支持7种特权模式和用户模式。
| M[4:0] | 二进制值 | 处理器模式 | 描述 |
|---|---|---|---|
| 0b10000 | 16 | User (usr) | 非特权模式,用户程序运行在此模式。 |
| 0b10001 | 17 | FIQ (fiq) | 快速中断模式,处理高优先级中断。 |
| 0b10010 | 18 | IRQ (irq) | 通用中断模式,处理普通中断。 |
| 0b10011 | 19 | Supervisor (svc) | 管理模式,操作系统内核运行在此模式。 |
| 0b10111 | 23 | Abort (abt) | 数据访问中止模式,处理内存访问异常。 |
| 0b11011 | 27 | Undefined (und) | 未定义指令中止模式,处理未定义指令异常。 |
| 0b11111 | 31 | System (sys) | 特权模式,与User模式共享寄存器,但具有更高权限。 |
| 0b10110 | 22 | Monitor (mon) | ARMv7特有的监控模式,用于安全扩展(TrustZone)。 |
4. 其他功能位
| Bit 位置 | 标志位 | 功能描述 |
|---|---|---|
| 27 | Q (Cumulative Saturation) | 仅在ARMv5TE及更高版本中存在,用于指示DSP指令的溢出或饱和状态。 |
| 26:25 | IT[1:0] | 与IT[7:2](Bit 15:10)共同构成Thumb-2的If-Then条件执行状态。 |
| 19:16 | GE[3:0] | 用于SIMD指令的并行比较操作,控制每组数据是否满足条件。 |
5. CPSR与APSR的区别
- CPSR:所有模式下均可访问,包含完整的状态信息(条件标志、中断禁止位、模式位等)。
- APSR (Application Program Status Register):用户模式下只能访问CPSR的部分位(如N、Z、C、V、Q、GE),用于应用程序编程。
6. 实际应用中的操作
-
修改CPSR:通过MSR(Move to Status Register)和MRS(Move from Status Register)指令读写CPSR的特定字段。
- 示例:
MRS r0, CPSR ; 将CPSR的值读入r0 BIC r0, #0x80 ; 清除I位(允许IRQ中断) MSR CPSR, r0 ; 将修改后的值写回CPSR
- 示例:
-
异常处理:当异常发生时,CPSR会被保存到对应的SPSR(Saved Program Status Register)中,以便异常返回后恢复状态。
总结
CPSR是ARMv7架构中最重要的状态寄存器,其32位字段涵盖了处理器的核心状态信息。理解每个bit的功能对于底层开发(如操作系统、驱动、中断处理)至关重要。开发人员可以通过操作CPSR的特定位来控制处理器行为,例如切换模式、屏蔽中断、执行条件指令等。
#ifndef ARM_H
#define ARM_H
#include <stdbool.h>
#include <stdint.h>
#include <util.h>
/* MIDR definitions */
#define MIDR_PRIMARY_PART_NUM_SHIFT U(4)
#define MIDR_PRIMARY_PART_NUM_WIDTH U(12)
#define MIDR_PRIMARY_PART_NUM_MASK (BIT(MIDR_PRIMARY_PART_NUM_WIDTH) - 1)
#define MIDR_IMPLEMENTER_SHIFT U(24)
#define MIDR_IMPLEMENTER_WIDTH U(8)
#define MIDR_IMPLEMENTER_MASK (BIT(MIDR_IMPLEMENTER_WIDTH) - 1)
#define MIDR_IMPLEMENTER_ARM U(0x41)
#define MIDR_VARIANT_SHIFT U(20)
#define MIDR_VARIANT_WIDTH U(4)
#define MIDR_VARIANT_MASK (BIT(MIDR_VARIANT_WIDTH) - 1)
#define MIDR_REVISION_SHIFT U(0)
#define MIDR_REVISION_WIDTH U(4)
#define MIDR_REVISION_MASK (BIT(MIDR_REVISION_WIDTH) - 1)
#define CORTEX_A5_PART_NUM U(0xC05)
#define CORTEX_A7_PART_NUM U(0xC07)
#define CORTEX_A8_PART_NUM U(0xC08)
#define CORTEX_A9_PART_NUM U(0xC09)
#define CORTEX_A15_PART_NUM U(0xC0F)
#define CORTEX_A17_PART_NUM U(0xC0E)
#define CORTEX_A57_PART_NUM U(0xD07)
#define CORTEX_A72_PART_NUM U(0xD08)
#define CORTEX_A73_PART_NUM U(0xD09)
#define CORTEX_A75_PART_NUM U(0xD0A)
#define CORTEX_A65_PART_NUM U(0xD06)
#define CORTEX_A65AE_PART_NUM U(0xD43)
#define CORTEX_A76_PART_NUM U(0xD0B)
#define CORTEX_A76AE_PART_NUM U(0xD0E)
#define CORTEX_A77_PART_NUM U(0xD0D)
#define CORTEX_A78_PART_NUM U(0xD41)
#define CORTEX_A78AE_PART_NUM U(0xD42)
#define CORTEX_A78C_PART_NUM U(0xD4B)
#define CORTEX_A710_PART_NUM U(0xD47)
#define CORTEX_X1_PART_NUM U(0xD44)
#define CORTEX_X2_PART_NUM U(0xD48)
#define NEOVERSE_E1_PART_NUM U(0xD4A)
#define NEOVERSE_N1_PART_NUM U(0xD0C)
#define NEOVERSE_N2_PART_NUM U(0xD49)
#define NEOVERSE_V1_PART_NUM U(0xD40)
/* MPIDR definitions */
#define MPIDR_AFFINITY_BITS U(8)
#define MPIDR_AFFLVL_MASK U(0xff)
#define MPIDR_AFF0_SHIFT U(0)
#define MPIDR_AFF0_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)
#define MPIDR_AFF1_SHIFT U(8)
#define MPIDR_AFF1_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT)
#define MPIDR_AFF2_SHIFT U(16)
#define MPIDR_AFF2_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)
#define MPIDR_MT_SHIFT U(24)
#define MPIDR_MT_MASK BIT(MPIDR_MT_SHIFT)
#define MPIDR_CPU_MASK MPIDR_AFF0_MASK
#define MPIDR_CLUSTER_SHIFT MPIDR_AFF1_SHIFT
#define MPIDR_CLUSTER_MASK MPIDR_AFF1_MASK
#define MPIDR_AARCH32_AFF_MASK (MPIDR_AFF0_MASK | MPIDR_AFF1_MASK | \
MPIDR_AFF2_MASK)
/* CLIDR definitions */
#define CLIDR_LOUIS_SHIFT U(21)
#define CLIDR_LOC_SHIFT U(24)
#define CLIDR_FIELD_WIDTH U(3)
/* CSSELR definitions */
#define CSSELR_LEVEL_SHIFT U(1)
/* CTR definitions */
#define CTR_CWG_SHIFT U(24)
#define CTR_CWG_MASK U(0xf)
#define CTR_ERG_SHIFT U(20)
#define CTR_ERG_MASK U(0xf)
#define CTR_DMINLINE_SHIFT U(16)
#define CTR_DMINLINE_WIDTH U(4)
#define CTR_DMINLINE_MASK (BIT(4) - 1)
#define CTR_L1IP_SHIFT U(14)
#define CTR_L1IP_MASK U(0x3)
#define CTR_IMINLINE_SHIFT U(0)
#define CTR_IMINLINE_MASK U(0xf)
#define CTR_WORD_SIZE U(4)
#define ARM32_CPSR_MODE_MASK U(0x1f)
#define ARM32_CPSR_MODE_USR U(0x10)
#define ARM32_CPSR_MODE_FIQ U(0x11)
#define ARM32_CPSR_MODE_IRQ U(0x12)
#define ARM32_CPSR_MODE_SVC U(0x13)
#define ARM32_CPSR_MODE_MON U(0x16)
#define ARM32_CPSR_MODE_ABT U(0x17)
#define ARM32_CPSR_MODE_UND U(0x1b)
#define ARM32_CPSR_MODE_SYS U(0x1f)
#define ARM32_CPSR_T BIT(5)
#define ARM32_CPSR_F_SHIFT U(6)
#define ARM32_CPSR_F BIT(6)
#define ARM32_CPSR_I BIT(7)
#define ARM32_CPSR_A BIT(8)
#define ARM32_CPSR_E BIT(9)
#define ARM32_CPSR_FIA (ARM32_CPSR_F | ARM32_CPSR_I | ARM32_CPSR_A)
#define ARM32_CPSR_IT_MASK (ARM32_CPSR_IT_MASK1 | ARM32_CPSR_IT_MASK2)
#define ARM32_CPSR_IT_MASK1 U(0x06000000)
#define ARM32_CPSR_IT_MASK2 U(0x0000fc00)
/* ARM Generic timer definitions */
#define CNTKCTL_PL0PCTEN BIT(0) /* physical counter el0 access enable */
#define CNTKCTL_PL0VCTEN BIT(1) /* virtual counter el0 access enable */
#ifdef ARM32
#include <arm32.h>
#endif
#ifdef ARM64
#include <arm64.h>
#endif
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2015, Linaro Limited
*/
#ifndef ARM64_H
#define ARM64_H
#include <compiler.h>
#include <sys/cdefs.h>
#include <stdint.h>
#include <util.h>
#define SCTLR_M BIT64(0)
#define SCTLR_A BIT64(1)
#define SCTLR_C BIT64(2)
#define SCTLR_SA BIT64(3)
#define SCTLR_I BIT64(12)
#define SCTLR_ENDB BIT64(13)
#define SCTLR_WXN BIT64(19)
#define SCTLR_SPAN BIT64(23)
#define SCTLR_ENDA BIT64(27)
#define SCTLR_ENIB BIT64(30)
#define SCTLR_ENIA BIT64(31)
#define SCTLR_BT0 BIT64(35)
#define SCTLR_BT1 BIT64(36)
#define SCTLR_ITFSB BIT64(37)
#define SCTLR_TCF_MASK SHIFT_U64(0x3, 40)
#define SCTLR_TCF_NONE SHIFT_U64(0x0, 40)
#define SCTLR_TCF_SYNC SHIFT_U64(0x1, 40)
#define SCTLR_TCF_ASYNC SHIFT_U64(0x2, 40)
#define SCTLR_TCF_ASYMM SHIFT_U64(0x3, 40)
#define SCTLR_TCF0_MASK SHIFT_U64(0x3, 38)
#define SCTLR_TCF0_NONE SHIFT_U64(0x0, 38)
#define SCTLR_TCF0_SYNC SHIFT_U64(0x1, 38)
#define SCTLR_TCF0_ASYNC SHIFT_U64(0x2, 38)
#define SCTLR_TCF0_ASYMM SHIFT_U64(0x3, 38)
#define SCTLR_ATA0 BIT64(42)
#define SCTLR_ATA BIT64(43)
#define TTBR_ASID_MASK U(0xff)
#define TTBR_ASID_SHIFT U(48)
#define CLIDR_LOUIS_SHIFT U(21)
#define CLIDR_LOC_SHIFT U(24)
#define CLIDR_FIELD_WIDTH U(3)
#define CSSELR_LEVEL_SHIFT U(1)
#define DAIFBIT_FIQ BIT32(0)
#define DAIFBIT_IRQ BIT32(1)
#define DAIFBIT_ABT BIT32(2)
#define DAIFBIT_DBG BIT32(3)
#define DAIFBIT_ALL (DAIFBIT_FIQ | DAIFBIT_IRQ | \
DAIFBIT_ABT | DAIFBIT_DBG)
#define DAIF_F_SHIFT U(6)
#define DAIF_F BIT32(6)
#define DAIF_I BIT32(7)
#define DAIF_A BIT32(8)
#define DAIF_D BIT32(9)
#define DAIF_AIF (DAIF_A | DAIF_I | DAIF_F)
#define SPSR_MODE_RW_SHIFT U(4)
#define SPSR_MODE_RW_MASK U(0x1)
#define SPSR_MODE_RW_64 U(0x0)
#define SPSR_MODE_RW_32 U(0x1)
#define SPSR_64_MODE_SP_SHIFT U(0)
#define SPSR_64_MODE_SP_MASK U(0x1)
#define SPSR_64_MODE_SP_EL0 U(0x0)
#define SPSR_64_MODE_SP_ELX U(0x1)
#define SPSR_64_MODE_EL_SHIFT U(2)
#define SPSR_64_MODE_EL_MASK U(0x3)
#define SPSR_64_MODE_EL1 U(0x1)
#define SPSR_64_MODE_EL0 U(0x0)
#define SPSR_64_DAIF_SHIFT U(6)
#define SPSR_64_DAIF_MASK U(0xf)
#define SPSR_32_AIF_SHIFT U(6)
#define SPSR_32_AIF_MASK U(0x7)
#define SPSR_32_E_SHIFT U(9)
#define SPSR_32_E_MASK U(0x1)
#define SPSR_32_E_LITTLE U(0x0)
#define SPSR_32_E_BIG U(0x1)
#define SPSR_32_T_SHIFT U(5)
#define SPSR_32_T_MASK U(0x1)
#define SPSR_32_T_ARM U(0x0)
#define SPSR_32_T_THUMB U(0x1)
#define SPSR_32_MODE_SHIFT U(0)
#define SPSR_32_MODE_MASK U(0xf)
#define SPSR_32_MODE_USR U(0x0)
#define SPSR_64(el, sp, daif) \
(SPSR_MODE_RW_64 << SPSR_MODE_RW_SHIFT | \
((el) & SPSR_64_MODE_EL_MASK) << SPSR_64_MODE_EL_SHIFT | \
((sp) & SPSR_64_MODE_SP_MASK) << SPSR_64_MODE_SP_SHIFT | \
((daif) & SPSR_64_DAIF_MASK) << SPSR_64_DAIF_SHIFT)
#define SPSR_32(mode, isa, aif) \
(SPSR_MODE_RW_32 << SPSR_MODE_RW_SHIFT | \
SPSR_32_E_LITTLE << SPSR_32_E_SHIFT | \
((mode) & SPSR_32_MODE_MASK) << SPSR_32_MODE_SHIFT | \
((isa) & SPSR_32_T_MASK) << SPSR_32_T_SHIFT | \
((aif) & SPSR_32_AIF_MASK) << SPSR_32_AIF_SHIFT)
#define TCR_T0SZ_SHIFT U(0)
#define TCR_EPD0 BIT64(7)
#define TCR_IRGN0_SHIFT U(8)
#define TCR_ORGN0_SHIFT U(10)
#define TCR_SH0_SHIFT U(12)
#define TCR_T1SZ_SHIFT U(16)
#define TCR_A1 BIT64(22)
#define TCR_EPD1 BIT64(23)
#define TCR_IRGN1_SHIFT U(24)
#define TCR_ORGN1_SHIFT U(26)
#define TCR_SH1_SHIFT U(28)
#define TCR_EL1_IPS_SHIFT U(32)
#define TCR_EL1_IPS_MASK UINT64_C(0x7)
#define TCR_TG1_4KB SHIFT_U64(2, 30)
#define TCR_RES1 BIT64(31)
#define TCR_TBI0 BIT64(37)
#define TCR_TBI1 BIT64(38)
#define TCR_TCMA0 BIT64(57)
#define TCR_TCMA1 BIT64(58)
/* Normal memory, Inner/Outer Non-cacheable */
#define TCR_XRGNX_NC U(0x0)
/* Normal memory, Inner/Outer Write-Back Write-Allocate Cacheable */
#define TCR_XRGNX_WB U(0x1)
/* Normal memory, Inner/Outer Write-Through Cacheable */
#define TCR_XRGNX_WT U(0x2)
/* Normal memory, Inner/Outer Write-Back no Write-Allocate Cacheable */
#define TCR_XRGNX_WBWA U(0x3)
/* Non-shareable */
#define TCR_SHX_NSH U(0x0)
/* Outer Shareable */
#define TCR_SHX_OSH U(0x2)
/* Inner Shareable */
#define TCR_SHX_ISH U(0x3)
#define ESR_EC_SHIFT U(26)
#define ESR_EC_MASK U(0x3f)
#define ESR_EC_UNKNOWN U(0x00)
#define ESR_EC_WFI U(0x01)
#define ESR_EC_AARCH32_CP15_32 U(0x03)
#define ESR_EC_AARCH32_CP15_64 U(0x04)
#define ESR_EC_AARCH32_CP14_MR U(0x05)
#define ESR_EC_AARCH32_CP14_LS U(0x06)
#define ESR_EC_FP_ASIMD U(0x07)
#define ESR_EC_AARCH32_CP10_ID U(0x08)
#define ESR_EC_PAUTH U(0x09)
#define ESR_EC_AARCH32_CP14_64 U(0x0c)
#define ESR_EC_BTI U(0x0d)
#define ESR_EC_ILLEGAL U(0x0e)
#define ESR_EC_AARCH32_SVC U(0x11)
#define ESR_EC_AARCH64_SVC U(0x15)
#define ESR_EC_AARCH64_SYS U(0x18)
#define ESR_EC_ERET U(0x1a)
#define ESR_EC_FPAC U(0x1c)
#define ESR_EC_IABT_EL0 U(0x20)
#define ESR_EC_IABT_EL1 U(0x21)
#define ESR_EC_PC_ALIGN U(0x22)
#define ESR_EC_DABT_EL0 U(0x24)
#define ESR_EC_DABT_EL1 U(0x25)
#define ESR_EC_SP_ALIGN U(0x26)
#define ESR_EC_AARCH32_FP U(0x28)
#define ESR_EC_AARCH64_FP U(0x2c)
#define ESR_EC_SERROR U(0x2f)
#define ESR_EC_BREAKPT_EL0 U(0x30)
#define ESR_EC_BREAKPT_EL1 U(0x31)
#define ESR_EC_SOFTSTP_EL0 U(0x32)
#define ESR_EC_SOFTSTP_EL1 U(0x33)
#define ESR_EC_WATCHPT_EL0 U(0x34)
#define ESR_EC_WATCHPT_EL1 U(0x35)
#define ESR_EC_AARCH32_BKPT U(0x38)
#define ESR_EC_AARCH64_BRK U(0x3c)
/* Combined defines for DFSC and IFSC */
#define ESR_FSC_MASK U(0x3f)
#define ESR_FSC_SIZE_L0 U(0x00)
#define ESR_FSC_SIZE_L1 U(0x01)
#define ESR_FSC_SIZE_L2 U(0x02)
#define ESR_FSC_SIZE_L3 U(0x03)
#define ESR_FSC_TRANS_L0 U(0x04)
#define ESR_FSC_TRANS_L1 U(0x05)
#define ESR_FSC_TRANS_L2 U(0x06)
#define ESR_FSC_TRANS_L3 U(0x07)
#define ESR_FSC_ACCF_L1 U(0x09)
#define ESR_FSC_ACCF_L2 U(0x0a)
#define ESR_FSC_ACCF_L3 U(0x0b)
#define ESR_FSC_PERMF_L1 U(0x0d)
#define ESR_FSC_PERMF_L2 U(0x0e)
#define ESR_FSC_PERMF_L3 U(0x0f)
#define ESR_FSC_TAG_CHECK U(0x11)
#define ESR_FSC_ALIGN U(0x21)
/* WnR for DABT and RES0 for IABT */
#define ESR_ABT_WNR BIT32(6)
#define CPACR_EL1_FPEN_SHIFT U(20)
#define CPACR_EL1_FPEN_MASK U(0x3)
#define CPACR_EL1_FPEN_NONE U(0x0)
#define CPACR_EL1_FPEN_EL1 U(0x1)
#define CPACR_EL1_FPEN_EL0EL1 U(0x3)
#define CPACR_EL1_FPEN(x) ((x) >> CPACR_EL1_FPEN_SHIFT \
& CPACR_EL1_FPEN_MASK)
#define PAR_F BIT32(0)
#define PAR_PA_SHIFT U(12)
#define PAR_PA_MASK (BIT64(36) - 1)
#define TLBI_MVA_SHIFT U(12)
#define TLBI_ASID_SHIFT U(48)
#define TLBI_ASID_MASK U(0xff)
#define ID_AA64PFR1_EL1_BT_MASK ULL(0xf)
#define FEAT_BTI_IMPLEMENTED ULL(0x1)
#define ID_AA64PFR1_EL1_MTE_MASK UL(0xf)
#define ID_AA64PFR1_EL1_MTE_SHIFT U(8)
#define FEAT_MTE_NOT_IMPLEMENTED U(0x0)
#define FEAT_MTE_IMPLEMENTED U(0x1)
#define FEAT_MTE2_IMPLEMENTED U(0x2)
#define FEAT_MTE3_IMPLEMENTED U(0x3)
#define ID_AA64ISAR1_GPI_SHIFT U(28)
#define ID_AA64ISAR1_GPI_MASK U(0xf)
#define ID_AA64ISAR1_GPI_NI U(0x0)
#define ID_AA64ISAR1_GPI_IMP_DEF U(0x1)
#define ID_AA64ISAR1_GPA_SHIFT U(24)
#define ID_AA64ISAR1_GPA_MASK U(0xf)
#define ID_AA64ISAR1_GPA_NI U(0x0)
#define ID_AA64ISAR1_GPA_ARCHITECTED U(0x1)
#define ID_AA64ISAR1_API_SHIFT U(8)
#define ID_AA64ISAR1_API_MASK U(0xf)
#define ID_AA64ISAR1_API_NI U(0x0)
#define ID_AA64ISAR1_API_IMP_DEF U(0x1)
#define ID_AA64ISAR1_API_IMP_DEF_EPAC U(0x2)
#define ID_AA64ISAR1_API_IMP_DEF_EPAC2 U(0x3)
#define ID_AA64ISAR1_API_IMP_DEF_EPAC2_FPAC U(0x4)
#define ID_AA64ISAR1_API_IMP_DEF_EPAC2_FPAC_CMB U(0x5)
#define ID_AA64ISAR1_APA_SHIFT U(4)
#define ID_AA64ISAR1_APA_MASK U(0xf)
#define ID_AA64ISAR1_APA_NI U(0x0)
#define ID_AA64ISAR1_APA_ARCHITECTED U(0x1)
#define ID_AA64ISAR1_APA_ARCH_EPAC U(0x2)
#define ID_AA64ISAR1_APA_ARCH_EPAC2 U(0x3)
#define ID_AA64ISAR1_APA_ARCH_EPAC2_FPAC U(0x4)
#define ID_AA64ISAR1_APA_ARCH_EPAC2_FPAC_CMB U(0x5)
#define GCR_EL1_RRND BIT64(16)
#ifndef __ASSEMBLER__
static inline __noprof void isb(void)
{
asm volatile ("isb" : : : "memory");
}
static inline __noprof void dsb(void)
{
asm volatile ("dsb sy" : : : "memory");
}
static inline __noprof void dsb_ish(void)
{
asm volatile ("dsb ish" : : : "memory");
}
static inline __noprof void dsb_ishst(void)
{
asm volatile ("dsb ishst" : : : "memory");
}
static inline __noprof void sev(void)
{
asm volatile ("sev" : : : "memory");
}
static inline __noprof void wfe(void)
{
asm volatile ("wfe" : : : "memory");
}
static inline __noprof void wfi(void)
{
asm volatile ("wfi" : : : "memory");
}
static inline __noprof void write_at_s1e1r(uint64_t va)
{
asm volatile ("at S1E1R, %0" : : "r" (va));
}
static __always_inline __noprof uint64_t read_pc(void)
{
uint64_t val;
asm volatile ("adr %0, ." : "=r" (val));
return val;
}
static __always_inline __noprof uint64_t read_fp(void)
{
uint64_t val;
asm volatile ("mov %0, x29" : "=r" (val));
return val;
}
static inline __noprof uint64_t read_pmu_ccnt(void)
{
uint64_t val;
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(val));
return val;
}
static inline __noprof void tlbi_vaae1is(uint64_t mva)
{
asm volatile ("tlbi vaae1is, %0" : : "r" (mva));
}
static inline __noprof void tlbi_vale1is(uint64_t mva)
{
asm volatile ("tlbi vale1is, %0" : : "r" (mva));
}
/*
* Templates for register read/write functions based on mrs/msr
*/
#define DEFINE_REG_READ_FUNC_(reg, type, asmreg) \
static inline __noprof type read_##reg(void) \
{ \
uint64_t val64 = 0; \
\
asm volatile("mrs %0, " #asmreg : "=r" (val64)); \
return val64; \
}
#define DEFINE_REG_WRITE_FUNC_(reg, type, asmreg) \
static inline __noprof void write_##reg(type val) \
{ \
uint64_t val64 = val; \
\
asm volatile("msr " #asmreg ", %0" : : "r" (val64)); \
}
#define DEFINE_U32_REG_READ_FUNC(reg) \
DEFINE_REG_READ_FUNC_(reg, uint32_t, reg)
#define DEFINE_U32_REG_WRITE_FUNC(reg) \
DEFINE_REG_WRITE_FUNC_(reg, uint32_t, reg)
#define DEFINE_U32_REG_READWRITE_FUNCS(reg) \
DEFINE_U32_REG_READ_FUNC(reg) \
DEFINE_U32_REG_WRITE_FUNC(reg)
#define DEFINE_U64_REG_READ_FUNC(reg) \
DEFINE_REG_READ_FUNC_(reg, uint64_t, reg)
#define DEFINE_U64_REG_WRITE_FUNC(reg) \
DEFINE_REG_WRITE_FUNC_(reg, uint64_t, reg)
#define DEFINE_U64_REG_READWRITE_FUNCS(reg) \
DEFINE_U64_REG_READ_FUNC(reg) \
DEFINE_U64_REG_WRITE_FUNC(reg)
/*
* Define register access functions
*/
DEFINE_U32_REG_READWRITE_FUNCS(cpacr_el1)
DEFINE_U32_REG_READWRITE_FUNCS(daif)
DEFINE_U32_REG_READWRITE_FUNCS(fpcr)
DEFINE_U32_REG_READWRITE_FUNCS(fpsr)
DEFINE_U32_REG_READ_FUNC(ctr_el0)
#define read_ctr() read_ctr_el0()
DEFINE_U32_REG_READ_FUNC(contextidr_el1)
DEFINE_U64_REG_READ_FUNC(sctlr_el1)
/* ARM Generic timer functions */
DEFINE_REG_READ_FUNC_(cntfrq, uint32_t, cntfrq_el0)
DEFINE_REG_READ_FUNC_(cntvct, uint64_t, cntvct_el0)
DEFINE_REG_READ_FUNC_(cntpct, uint64_t, cntpct_el0)
DEFINE_REG_READ_FUNC_(cntkctl, uint32_t, cntkctl_el1)
DEFINE_REG_WRITE_FUNC_(cntkctl, uint32_t, cntkctl_el1)
DEFINE_REG_READ_FUNC_(cntps_ctl, uint32_t, cntps_ctl_el1)
DEFINE_REG_WRITE_FUNC_(cntps_ctl, uint32_t, cntps_ctl_el1)
DEFINE_REG_READ_FUNC_(cntps_tval, uint32_t, cntps_tval_el1)
DEFINE_REG_WRITE_FUNC_(cntps_tval, uint32_t, cntps_tval_el1)
DEFINE_REG_READ_FUNC_(pmccntr, uint64_t, pmccntr_el0)
DEFINE_U64_REG_READWRITE_FUNCS(ttbr0_el1)
DEFINE_U64_REG_READWRITE_FUNCS(ttbr1_el1)
DEFINE_U64_REG_READWRITE_FUNCS(tcr_el1)
DEFINE_U64_REG_READ_FUNC(esr_el1)
DEFINE_U64_REG_READ_FUNC(far_el1)
DEFINE_U64_REG_READ_FUNC(mpidr_el1)
/* Alias for reading this register to avoid ifdefs in code */
#define read_mpidr() read_mpidr_el1()
DEFINE_U64_REG_READ_FUNC(midr_el1)
/* Alias for reading this register to avoid ifdefs in code */
#define read_midr() read_midr_el1()
DEFINE_U64_REG_READ_FUNC(par_el1)
DEFINE_U64_REG_WRITE_FUNC(mair_el1)
DEFINE_U64_REG_READ_FUNC(id_aa64pfr1_el1)
DEFINE_U64_REG_READ_FUNC(id_aa64isar1_el1)
DEFINE_REG_READ_FUNC_(apiakeylo, uint64_t, S3_0_c2_c1_0)
DEFINE_REG_READ_FUNC_(apiakeyhi, uint64_t, S3_0_c2_c1_1)
DEFINE_REG_WRITE_FUNC_(apibkeylo, uint64_t, S3_0_c2_c1_2)
DEFINE_REG_WRITE_FUNC_(apibkeyhi, uint64_t, S3_0_c2_c1_3)
DEFINE_REG_READ_FUNC_(apdakeylo, uint64_t, S3_0_c2_c2_0)
DEFINE_REG_READ_FUNC_(apdakeyhi, uint64_t, S3_0_c2_c2_1)
DEFINE_REG_WRITE_FUNC_(apdbkeylo, uint64_t, S3_0_c2_c2_2)
DEFINE_REG_WRITE_FUNC_(apdbkeyhi, uint64_t, S3_0_c2_c2_3)
DEFINE_REG_WRITE_FUNC_(apgakeylo, uint64_t, S3_0_c2_c3_0)
DEFINE_REG_WRITE_FUNC_(apgakeyhi, uint64_t, S3_0_c2_c3_1)
/* Register read/write functions for GICC registers by using system interface */
DEFINE_REG_READ_FUNC_(icc_ctlr, uint32_t, S3_0_C12_C12_4)
DEFINE_REG_WRITE_FUNC_(icc_ctlr, uint32_t, S3_0_C12_C12_4)
DEFINE_REG_WRITE_FUNC_(icc_pmr, uint32_t, S3_0_C4_C6_0)
DEFINE_REG_READ_FUNC_(icc_iar0, uint32_t, S3_0_c12_c8_0)
DEFINE_REG_READ_FUNC_(icc_iar1, uint32_t, S3_0_c12_c12_0)
DEFINE_REG_WRITE_FUNC_(icc_eoir0, uint32_t, S3_0_c12_c8_1)
DEFINE_REG_WRITE_FUNC_(icc_eoir1, uint32_t, S3_0_c12_c12_1)
DEFINE_REG_WRITE_FUNC_(icc_igrpen0, uint32_t, S3_0_C12_C12_6)
DEFINE_REG_WRITE_FUNC_(icc_igrpen1, uint32_t, S3_0_C12_C12_7)
#endif /*__ASSEMBLER__*/
#endif /*ARM64_H*/

浙公网安备 33010602011771号