文章目录
- 1.1 ARMv8 系统寄存器访问概要
- 1.1.1 系统寄存器访问级别
- 1.1.2 ARMv8 系统寄存器编码
 
 
1.1 ARMv8 系统寄存器访问概要
ARMv8中,取消了协处理器,之前协处理器实现的功能,全部由系统寄存器来是实现。对于系统寄存器的访问,使用 mrs,msr 指令来访问。ARM架构的之前版本 (如ARMv7) 使用协处理器来进行系统配置。 但是,AArch64 不支持协处理器。
1.1.1 系统寄存器访问级别
AArch64 中系统寄存器会以 ”_ELn“ 的方式名命,寄存器的名称会告诉你可以访问它的最低异常级别。
 <Reg>_EL1:处理器处于 EL1、EL2、EL3时可以访问。
 <Reg>_EL2:处理器处于 EL2、EL3 时可以访问。
 大部分寄存器不支持处于 EL0 时访问,但也有一些例外,如 CTR_EL0。
例如:
 TTBR0_EL1 可以从 EL1、EL2 和 EL3 访问。
 TTBR0_EL2 可以从 EL2 和 EL3 访问。
可以采用以下形式来访问系统寄存器:
MRS x0, TTBR0_EL1 // 把 TTBR0_EL1 的值保存到x0
MSR TTBR0_EL1, x0 // 把x0 的值写入TTBR0_EL1寄存器
1.1.2 ARMv8 系统寄存器编码
指令编码如下:
 
图 1-1
L: 1, mrs,读取系统寄存器值到通用寄存器中;
 L: 0, msr,将通用寄存器值写入到系统寄存器中;
 而系统寄存器的编码,由 op1,CRn,CRm,op2 位域来决定,op1,CRn,CRm,op2 的编码组合有很多,arm 并没有将所有的组合都定义系统寄存器。
对于未使用的编码组合,arm 允许实现自定义这些系统寄存器的功能,对于自定义的系统寄存器,在写汇编程序的时候,是不能通过系统寄存器的名字去访问的,否则编译会报错。为了解决访问自定义系统寄存器,arm 定义了以下格式,来表示系统寄存器
S<op0>_<op1>_c<CRn>_c<CRm0>_<op2>

图 1-2
从上图 1-2 的内容可以在 arch/arm64/include/asm/sysreg.h 中找打对应:
/*
 * ARMv8 ARM reserves the following encoding for system registers:
 * (Ref: ARMv8 ARM, Section: "System instruction class encoding overview",
 *  C5.2, version:ARM DDI 0487A.f)
 *      [20-19] : Op0
 *      [18-16] : Op1
 *      [15-12] : CRn
 *      [11-8]  : CRm
 *      [7-5]   : Op2
 */
比如:Trace 的寄存器 TRBTRG_EL1 的定义如下:
#define SYS_TRBTRG_EL1                  sys_reg(3, 0, 9, 11, 6)
其在手册中的编码如下:
 
图 1-2
sys_reg 中的参数分别对应 op0, op1, CRn, CRm, op2, 对于它的访问可以使用下面两个函数:
read_sysreg_s(r)
write_sysreg_s(v, r)
或者使用:
mrs x0, S3_0_c9_c11_6
msr S3_0_c9_c11_6, x0
推荐阅读:
 https://community.arm.com/support-forums/f/compilers-and-libraries-forum/46782/gnu-toolchain—unknown-or-missing-system-register-gic-register—cortex-a53



















