ARMv7-A Coprocessor概要以及读写
关键词:MRC/MCR/MRRC/MCRR、CP14、CP15等等。
1. ARMv7-A Coprocessor介绍
ARMv7-A支持16个Coprocessor,分别是:(A2.9 Coprocessor support)
- CP15-System Control。
- CP14-Debug、The Thumb Execution Environment、Direct Java bytecode execution。
- CP10和CP11-Floating-point和Advanced SIMD。
- CP8/9/12/13-ARM保留。
- CP0-7-预留厂商自定义。
Coprocessor相关指令有:(A4.10 Coprocessor instructions)
- 发起Coprocessor数据处理操作:CDP/CDP2。
- Core寄存器和Coprocessor寄存器之间传输:MCR/MCR2/MCRR/MCRR2/MRC/MRC2/MRRC/MRRC2。
- 存取Coprocessor寄存器:LDC/LDC2/STC/STC2。
ARM NEON测试代码:《GitHub - christophe-lyon/arm-neon-tests: Tests for ARM/Neon instructions, useful for compilers and simulators.》。
NEON优化库:《GitHub - projectNe10/Ne10: An open optimized software library project for the ARM® Architecture》。
ARM官方NEON编程指导:《Learn the architecture - Neon programmers' guide (arm.com)》。
ARM A7 FPU技术参考手册:《Cortex-A7 Floating-Point Unit Technical Reference Manual r0p5 (arm.com)》。
1.1 CP14
CP14提供Debug/Trace/Execution environment相关控制功能。
32位指令组成形式为{CRn, opc1, CRm, opc2},其中:
- opc1==0 Debug registers.
- opc1==1 Trace registers.
- opc1==6 ThumbEE registers.
- opc1==7 Jazelle registers.
1.2 CP15
CP15是System Control寄存器集合,其组成形势根据32位或64位不同。
32位组成形式为{CRn, opc1, CRm, opc2};64位组成形式为{CRm, opc1}。
下图为mcr/mrc指令和CP15指令对应关系:
CP15从c0~c15详细如下:
更详细参考:《B3.17 Organization of the CP15 registers in a VMSA implementation》。
1.3 CP10和CP11
使能CP10和CP11,需要将CPACR.{cp10, cp11}设置为0b01或者0b11。0b00-不可访问;0b01-仅PL1可访问;0b11-PL0/PL1都可访问。
在使能Security情况下,可以配置NSACR.{cp10, cp11}来控制不同安全个状态的是否可用。0-仅安全状态可访问;1-安全和非安全都可访问。
相关寄存器列表如下:
2. ARMv7-A Coprocessor相关指令寄存器
2.1 MCR/MRC/MCRR/MRRC
MRC: Move to general-purpose register from Coprocessor.
MCR: Move to Coprocessor from general-purpose register.
MRRC: Move to two general-purpose registers from Coprocessor.
MCRR: Move to Coprocessor from two general-purpose registers.
MCR/MCR2将ARM Core寄存器值传递到Coprocessor,指令格式为:
MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
coproc-协处理器名称;opc1-Coprocessor的opcode;Rt-传递数据给Coprocessor的ARM Core寄存器;CRn-Coprocessor目的寄存器;CRm-Coprocessor的补充寄存器;opc2-Coprocessor的opcode。
MRC/MRC2将Coprocessor内容传递给ARM Core寄存器,指令格式为:
MRC<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
相对于MCR,Rt变成目的寄存器,CRn/CRm变成源寄存器。
MCRR/MRRC功能类似于MRC/MCR,但是ARM Core寄存器变成了两个。MCRR/MRRC访问的是64位协处理器寄存器,CRn为空,仅靠CRm找到对应寄存器。
指令格式如下:
MCRR<c> <coproc>, <opc1>, <Rt>, <Rt2>, <CRm>
MRRC<c> <coproc>, <opc1>, <Rt>, <Rt2>, <CRm>
参考:《A8.8.99 MCR, MCR2》《A8.8.100 MCRR, MCRR2》《A8.8.108 MRC, MRC2》《A8.8.109 MRRC, MRRC2》
2.2 CPACR
CPACR寄存器如下:
ASEDIS:1关闭Advanced SIMD功能。
D32DIS:1关闭对D16-D31寄存器访问。
TRCDIS:1关闭对CP14 Trace寄存器访问。
2.3 VMRS/VMSR
VMRS将Advanced SIMD和FP寄存器内容搬移到ARM Core寄存器;VMSR将ARM Core寄存器搬移到Advanced SIMD和FP寄存器。
3. GCC下Coprocessor读写
CMSIS中定义了对Coprocessor的操作接口:
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) #define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) #define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) #define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
__get_CP/__set_CP分别读取和设置32位寄存器;__get_CP64/__set_CP64分别读取和设置64位寄存器。
使用CMSIS提供的API进行Coprocessor操作:
unsigned int cntp_ctl = __get_CNTP_CTL(); __set_CNTP_CTL(cntp_ctl); unsigned long long cntp_cval = __get_CNTP_CVAL(); __set_CNTP_CVAL(cntp_cval); __STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value) { __set_CP(15, 0, value, 14, 2, 1); } __STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void) { uint32_t result; __get_CP(15, 0, result, 14, 2, 1); return result; } __STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value) { __set_CP64(15, 2, value, 14); } __STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void) { uint64_t result; __get_CP64(15, 2, result, 14); return result; }
得到的汇编结果如下:
从如下图中可知,当CRn=c14, op1=0, CRm=2, op2=1时,操作的寄存器为CNTP_CTL。
从如下图中可知,当CRn=c14, opc1=2时,操作的寄存器为CNTP_CVAL。
参考文档:《ARM® Architecture Reference Manual ARMv7-A and ARMv7-R edition》、《Cortex™-A7 MPCore™ Revision: r0p5 Technical Reference Manual》。