文章目录
- 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