ARM指令集-协处理器指令详解
ARM可支撑多达16个协处理器,首要的效果:ARM处理器初始化,ARM与协处理器的数据处理操作,ARM的寄存器与协处理器的寄存器之间传送数据,以及ARM协处理器的寄存器和存储器之间传送数据。共有5条: -CDP 协处理器数据操作指令 -LDC 协处理器数据加载指令 -STC 协处理器数据存储指令 -MCR ARM的寄存器到协处理器的寄存器的数据传送 -MRC 协处理器的寄存器到ARM的寄存器的数据传送 1、CDP 指令 CDP 指令的格局为: CDP{条件} 协处理器编码,协处理器操作码1,意图寄存器,源寄存器1,源寄存器2,协处理器操作码2。 CDP 指令用于ARM 处理器告诉ARM 协处理器履行特定的操作,若协处理器不能成功完结特定的操作,则发生未定义指令反常。其间协处理器操作码1 和协处理器操作码2 为协处理器即将履行的操作,意图寄存器和源寄存器均为协处理器的寄存器,指令不触及ARM 处理器的寄存器和存储器。 指令示例: CDP P3 , 2 , C12 , C10 , C3 , 4 ;该指令完结协处理器 P3 的初始化 2、LDC 指令 LDC 指令的格局为: LDC{条件}{L} 协处理器编码,意图寄存器,[源寄存器] LDC 指令用于将源寄存器所指向的存储器中的字数据传送到意图寄存器中,若协处理器不能成功完结传送操作,则发生未定义指令反常。其间,{L}选项标明指令为长读取操作,如用于双精度数据的传输。 指令示例: LDC P3 , C4 , [R0] ;将 ARM 处理器的寄存器 R0 所指向的存储器中的字数据传送到协处理器 P3 的寄存器 C4 中。 3、STC 指令 STC 指令的格局为: STC{条件}{L} 协处理器编码,源寄存器,[意图寄存器] STC 指令用于将源寄存器中的字数据传送到意图寄存器所指向的存储器中,若协处理器不能成功完结传送操作,则发生未定义指令反常。其间,{L}选项标明指令为长读取操作,如用于双精度数据的传输。 指令示例: STC P3 , C4 , [R0] ;将协处理器 P3 的寄存器 C4 中的字数据传送到 ARM 处理器的寄存器R0 所指向的存储器中。 4、MCR 指令 MCR 指令的格局为: MCR{条件} 协处理器编码,协处理器操作码1,源寄存器,意图寄存器1,意图寄存器2,协处理器操作码2。 MCR 指令用于将ARM 处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完结操作,则发生未定义指令反常。其间协处理器操作码1 和协处理器操作码2 为协处理器即将履行的操作,源寄存器为ARM 处理器的寄存器,意图寄存器1 和意图寄存器2 均为协处理器的寄存器。 指令示例: MCR P3 , 3 , R0 , C4 , C5 , 6 ;该指令将 ARM 处理器寄存器 R0 中的数据传送到协处理器 P3 的寄存器 C4 和 C5 中。 5、MRC 指令 MRC 指令的格局为: MRC{条件} 协处理器编码,协处理器操作码1,意图寄存器,源寄存器1,源寄存器2,协处理器操作码2。 MRC 指令用于将协处理器寄存器中的数据传送到ARM 处理器寄存器中,若协处理器不能成功完结操作,则发生未定义指令反常。其间协处理器操作码1 和协处理器操作码2 为协处理器即将履行的操作,意图寄存器为ARM 处理器的寄存器,源寄存器1 和源寄存器2 均为协处理器的寄存器。 指令示例: MRC P3 , 3 , R0 , C4 , C5 , 6 ;该指令将协处理器 P3 的寄存器中的数据传送到 ARM 处理器寄存器中. ARM920T 有两个详细协处理器 1.CP14调试通讯通道协处理器 调试通讯通道协处理器DCC(the Debug Communications Channel)供给了两个32bits寄存器用于传送数据,还供给了6bits通讯数据操控寄存器操控寄存器中的两个位供给方针和主机调试器之间的同步握手。 |
此操控寄存器中的两个位供给方针和主机调试器之间的同步握手:
位 1(W 位) 从方针的视点标明通讯数据写入寄存器是否闲暇:
W = 0 方针使用程序能够写入新数据。
W = 1 主机调试器能够从写入寄存器中扫描出新数据。
位 0(R 位) 从方针的视点标明通讯数据读取寄存器中是否有新数据:
R = 1 有新数据,方针使用程序能够读取。
R = 0 主机调试器能够将新数据扫描到读取寄存器中。
留意
调试器不能运用协处理器 14 直接拜访调试通讯通道,由于这对调试器无意义。但调试器可运用扫描链读写 DCC 寄存器。 DCC 数据和操控寄存器可映射到 EmbeddedICE 逻辑单元中的地址。 若要查看 EmbeddedICE 逻辑寄存器,请参阅您的调试器和调试方针的相关文档。
通讯数据读取寄存器
用于接纳来自调试器的数据的 32 位宽寄存器。 以下指令在 Rd 中返
回读取寄存器的值:
MRC p14, 0, Rd, c1, c0
通讯数据写入寄存器
用于向调试器发送数据的 32 位宽寄存器。 以下指令将 Rn 中的值写
到写入寄存器中:
MCR p14, 0, Rn, c1, c0
留意
有关拜访 ARM10 和 ARM11 内核 DCC 寄存器的信息,请参阅相应的技能参阅手册。 ARM9 之后的各处理器中,所用指令、状况位方位以及对状况位的解说都有所不同。
方针到调试器的通讯
这是运转于 ARM 内核上的使用程序与运转于主机上的调试器之间的通讯事情次序:
1. 方针使用程序查看 DCC 写入寄存器是否闲暇可用。为此,方针使用程序运用 MRC 指令读取调试通讯通道操控寄存器,以查看 W 位是否已铲除。
2. 假如 W 位已铲除,则通讯数据写入寄存器已清空,使用程序对协处理器14 ,运用 MCR 指令将字写入通讯数据写入寄存器。 写入寄存器操作会主动设置W 位。假如 W 位已设置,则标明调试器没有清空通讯数据写入寄存器。此刻,假如使用程序需求发送另一个字,它有必要轮询 W 位,直到它已铲除。
3. 调试器经过扫描链 2 轮询通讯数据操控寄存器。 假如调试器发现 W 位已设置,则它能够读 DCC 数据寄存器,以读取使用程序发送的信息。 读取数据的进程会主动铲除通讯数据操控寄存器中的 W 位。
以下代码显现了这一进程
AREA OutChannel, CO
ENTRY
MOV r1,#3 ; Number of words to send
ADR r2, outdata ; Address of da
pollout
MRC p14,0,r0,c0,c0 ; Read control register
TST r0, #2
BNE pollout ; if W set, register still full
write
LDR r3,[r2],#4 ; Read word from outdata
; into r3 and update the pointer
MCR p14,0,r3,c1,c0 ; Write word from r3
SUBS r1,r1,#1 ; Update counter
BNE pollout ; Loop if more words to be written
MOV r0, #0x18 ; Angel_SWIreason_ReportException
LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit
SVC 0x123456 ; ARM semihosting (formerly SWI)
outdata
DCB “Hello there!”
END
调试器到方针的通讯
这是运转于主机上的调试器向运转于内核上的使用程序传输音讯的事情次序:
1. 调试器轮询通讯数据操控寄存器的 R 位。 假如 R 位已铲除,则通讯数据读取寄存器已清空,可将数据写入此寄存器,以供方针使用程序读取。
2. 调试器经过扫描链 2 将数据扫描到通讯数据读取寄存器中。此操作会主动设置通讯数据操控寄存器中的 R 位。
3. 方针使用程序轮询通讯数据操控寄存器中的 R 位。假如该位现已设置,则通讯数据读取寄存器中现已有数据,使用程序可运用 MRC 指令从协处理器14 读取该数据。 一起,读取指令还会铲除 R 位。
以下显现的方针使用程序代码演示了这一进程
AREA InChannel, CO
ENTRY
MOV r1,#3 ; Number of words to read
LDR r2, =indata ; Address to store da
pollin
MRC p14,0,r0,c0,c0 ; Read control register
TST r0, #1
BEQ pollin ; If R bit clear then loop
read
MRC p14,0,r3,c1,c0 ; read word into r3
STR r3,[r2],#4 ; Store to memory and
; update pointer
SUBS r1,r1,#1 ; Update counter
BNE pollin ; Loop if more words to read
MOV r0, #0x18 ; Angel_SWIreason_ReportException
LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit
SVC 0x123456 ; ARM semihosting (formerly SWI)
AREA Storage, DA
indata
DCB “Duffmessage#”
END
CP15体系操控协处理器
CP15 —体系操控协处理器 (the system control coprocessor)他经过协处理器指令MCR和MRC供给详细的寄存器来装备和操控caches、MMU、维护体系、装备时钟形式(在bootloader时钟初始化用到)
CP15的寄存器只能被MRC和MCR(Move to Coprocessor from ARM Register )指令拜访
MCR{cond} p15,,,,,
MRC{cond} p15,,,,,
其间L位用来区别MCR(L=1)和MRC(L=0)操作. CP15包含15个详细的寄存器如下
-R0:ID号寄存器
-R0:缓存类型寄存器
-R1:操控寄存器
-R2:转化表基址寄存器(Translation Table Base –TTB)
-R3:域拜访操控寄存器(Domain access control )
-R4:保存
-R5:反常状况寄存器(fault status -FSR)
-R6:反常地址寄存器(fault address -FAR)
-R7:缓存操作寄存器
-R8:TLB操作寄存器
-R9:缓存确定寄存器
-R10:TLB 确定寄存器
-R11-12&14:保存
-R13:处理器ID
-R15:测验装备寄存器 2-24
要留意有2个R0,依据MCR操作数的不同传送不同的值,这也一个只读寄存器
-R0:ID号寄存器这是一个只读寄存器,回来一个32位的设备ID号,详细功用参阅ARM各个系列类型的的CP15 Register 0阐明.
MRC p15, 0, , c0, c0, {0, 3-7} ;returns ID
以下为CP15的一些使用示例
U32 ARM_CP15_DeviceIDRead(void)
{
U32 id;
__asm { MRC P15, 0, id, c0, c0; }
return id;
}
void ARM_CP15_SetPageTableBase(P_U32 TableAddress)
{
__asm { MCR P15, 0, TableAddress, c2, c0, 0; }
}
void ARM_CP15_SetDomainAccessControl(U32 flags)
{
__asm { MCR P15, 0, flags, c3, c0, 0; }
}
void ARM_CP15_ICacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c5, 0; }
}
void ARM_CP15_DCacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c6, 0; }
}
void ARM_CP15_CacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c7, 0; }
}
void ARM_CP15_TLBFlush(void)
{
unsigned long dummy;
__asm { MCR P15, 0, dummy, c8, c7, 0; }
}
void ARM_CP15_ControlRegisterWrite(U32 flags)
{
__asm { MCR P15, 0, flags, c1, c0; }
}
void ARM_CP15_ControlRegisterOR(U32 flag)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2,flag
orr r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
void ARM_CP15_ControlRegisterAND(U32 flag)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2,flag
and r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
void ARM_MMU_Init(P_U32 TableAddress)
{
ARM_CP15_TLBFlush();
ARM_CP15_CacheFlush();
ARM_CP15_SetDomainAccessControl(0xFFFFFFFF);
ARM_CP15_SetPageTableBase(TableAddress);
}
void Enable_MMU (void)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2, #0x00000001
orr r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
printf(“MMU enabled\n”);
}
void Disable_MMU (void)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2, #0xFFFFFFFE
and r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
printf(“MMU disabled\n”);
}