关键词: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。
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}。
更详细参考:《B3.17 Organization of the CP15 registers in a VMSA implementation》。
1.3 CP10
1.4 CP11
2. ARMv7-A MCR/MRC/MCRR/MRRC
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<c> <coproc>, <opc1>, <Rt>, <Rt2>, <CRm> MRRC<c> <coproc>, <opc>, <Rt>, <Rt2>, <CRm>
参考:《A8.8.99 MCR, MCR2》《A8.8.100 MCRR, MCRR2》《A8.8.108 MRC, MRC2》《A8.8.109 MRRC, MRRC2》
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》。
标签:__,Rt,get,读写,ARMv7,寄存器,Coprocessor,CRm From: https://www.cnblogs.com/arnoldlu/p/16974157.html