> 文章列表 > 【ARMv8 异常模型入门及渐进2 - 系统寄存器访问方法:op1,CRn,CRm,op2】

【ARMv8 异常模型入门及渐进2 - 系统寄存器访问方法:op1,CRn,CRm,op2】

【ARMv8 异常模型入门及渐进2 - 系统寄存器访问方法:op1,CRn,CRm,op2】

文章目录

    • 1.1 ARMv8 系统寄存器访问概要
      • 1.1.1 系统寄存器访问级别
      • 1.1.2 ARMv8 系统寄存器编码

1.1 ARMv8 系统寄存器访问概要

ARMv8中,取消了协处理器,之前协处理器实现的功能,全部由系统寄存器来是实现。对于系统寄存器的访问,使用 mrsmsr 指令来访问。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>_<CRn>_<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)

其在手册中的编码如下:
【ARMv8 异常模型入门及渐进2 - 系统寄存器访问方法:op1,CRn,CRm,op2】

图 1-2

sys_reg 中的参数分别对应 op0, op1, CRn, CRm, op2, 对于它的访问可以使用下面两个函数:

read_sysreg_s(r)
write_sysreg_s(v, r)

或者使用:

mrs x0, S3_0_9_11_6
msr S3_0_9_11_6, x0