CP15 —系统控制协处理器 (the system control coprocessor)他通过协处理器指令MCR和MRC提供具体的寄存器来配置和控制caches、MMU、保护系统、配置时钟模式(在bootloader时钟初始化用到)
CP15的寄存器只能被MRC和MCR(Move to Coprocessor from ARM Register )指令访问
MCR{cond} p15,<Opcode_1>,<Rd>,<CRn>,<CRm>,<Opcode_2>
MRC{cond} p15,<Opcode_1>,<Rd>,<CRn>,<CRm>,<Opcode_2>
其中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, <Rd>, c0, c0, {0, 3-7} ;returns ID
以下为ID Code详细描叙(ARM926EJ-S); ARM920T Part Number为0x920,Architecture (ARMv4T) 为0x2具体可参照ARM各型号.
-R0:缓存类型寄存器(CACHE TYPE REGISTER),包含了caches的信息。读这个寄存器的方式是通过设置协处理操作码为1.
MRC p15, 0, <Rd>, c0, c0, 1; returns cache details
以下为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");
}