ARM处理器中CP15协处理器的寄存器
0 前言
之前我们在学习MMU的时候,知道这个内存的分配和CP15协处理器。这里先介绍一下CP15寄存器以及访问CP15寄存器的汇编指令。
1 访问CP15寄存器的指令
访问CP15寄存器指令的编码格式及语法说明如下:
说明:
- <opcode_1>:协处理器行为操作码,对于CP15来说,<opcode_1>永远为0b000,否则结果未知。
- :不能是r15/pc,否则,结果未知。
- :作为目标寄存器的协处理器寄存器,编号为C0~C15。
- :附加的目标寄存器或源操作数寄存器,如果不需要设置附加信息,将crm设置为c0,否则结果未知。
- <opcode_2>:提供附加信息比如寄存器的版本号或者访问类型,用于区分同一个编号的不同物理寄存器,可以省略<opcode_2>或者将其设置为0,否则结果未知。
2 CP15寄存器介绍
CP15的寄存器列表:
CP15中寄存器C0对应两个标识符寄存器,由访问CP15中的寄存器指令中的<opcode_2>指定要访问哪个具体物理寄存器,<opcode_2>与两个标识符寄存器的对应关系如下所示:
● CP15的寄存器C0
1)主标识符寄存器
访问主标识符寄存器的指令格式如下所示:
mrc p15, 0, r0, c0, c0, 0 ;将主标识符寄存器C0,0的值读到r0中
为了防止大家不理解:
MRC:协处理器寄存器到ARM寄存器的数据传送指令 p15:ARM中用于存储管理的系统控制协处理器CP15 第一个0:操作码1 R0:ARM寄存器 c0:协处理器寄存器; 基本作用:ID编码(只读); 在MMU中的作用:ID编码和cache类型 最后一个0:操作码2 整句作用:读取CP15的主标识寄存器的指令,该指令将主标识符寄存器的内容读取到ARM寄存器R0中。
ARM不同版本体系处理器中主标识符寄存器的编码格式说明如下。
ARM7之后处理器的主标识符寄存器编码格式如下所示:
ARM7处理器的主标识符寄存器编码格式如下所示:
ARM7之前处理器的主标识符寄存器编码格式如下所示:
2)cache类型标识符寄存器
访问cache类型标识符寄存器的指令格式如下所示:
mrc p15, 0, r0, c0, c0, 1 ;将cache类型标识符寄存器C0,1的值读到r0中
ARM处理器中cache类型标识符寄存器的编码格式如下所示:
其中控制字段位[28:25]的含义说明如下:
控制字段位[23:12]和控制字段位[11:0]的编码格式相同,含义如下所示:
cache容量字段bits[8: 6]的含义如下所示:
cache相联特性字段bits[5: 3]的含义如下所示:
cache块大小字段bits[1: 0]的含义如下所示:
● CP15的寄存器C1
访问主标识符寄存器的指令格式如下所示:
mrc p15, 0, r0, c1, c0{, 0} ;将CP15的寄存器C1的值读到r0中 mcr p15, 0, r0, c1, c0{, 0} ;将r0的值写到CP15的寄存器C1中
CP15中的寄存器C1的编码格式及含义说明如下:
● CP15的寄存器C2
CP15中的寄存器C2保存的是页表的基地址,即一级映射描述符表的基地址。其编码格如下所示:
● CP15的寄存器C3
CP15中的寄存器C3定义了ARM处理器的16个域的访问权限。
在ARM处理器中,MMU将整个存储空间分成最多16个域,记作D0~D15,每个域对应一定的存储区域,该区域具有相同的访问控制属性。每个域的访问权限分别由CP15的C3寄存器中的两位来设定,c3寄存器的大小为32bits,刚好可以设置16个域的访问权限。
● CP15的寄存器C5
CP15中的寄存器C5是失效状态寄存器,编码格式如下所示:
其中,域标识bit[7:4]表示存放引起存储访问失效的存储访问所属的域。
状态标识bit[3:0]表示放引起存储访问失效的存储访问类型,该字段含义如表4-3所示(优先级由上到下递减)。
● CP15中的寄存器C6
CP15中的寄存器C5是失效地址寄存器,编码格式如下所示:
● CP15中的寄存器C7
CP15的C7寄存器用来控制cache和写缓存,它是一个只写寄存器,读操作将产生不可预知的后果。
访问CP15的C7寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c7>, crm, <opcode_2>; <rd>、<crm>和<opcode_2>的不同取值 组合 实现不同功能
● CP15中的寄存器C8
CP15的C8寄存器用来控制清除TLB的内容,是只写寄存器,读操作将产生不可预知的后果。
访问CP15的C8寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c8>, crm, <opcode_2>; <rd>、<crm>和<opcode_2>的不同取值 组合实现不同功能
● CP15中的寄存器C9
CP15的C9寄存器用于控制cache内容锁定。
访问CP15的C9寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c9>, c0, <opcode_2> mrc p15, 0, <rd>, <c9>, c0, <opcode_2>
如果系统中包含独立的指令cache和数据cache,那么对应于数据cache和指令cache分别有一个独立的cache内容锁定寄存器,<opcode_2>用来选择其中的某个寄存器:
- <opcode_2>=1选择指令cache的内容锁定寄存器;
- <opcode_2>=0选择数据cache的内容锁定寄存器。
CP15的C9寄存器有A、B两种编码格式。编码格式A如下所示:
其中index表示当下一次发生cache未命中时,将预取的存储块存入cache中该块对应的组中序号为index的cache块中。
此时序号为0~index-1的cache块被锁定,当发生cache替换时,从序号为index到ASSOCIATIVITY的块中选择被替换的块。
编码格式B如下所示:
● CP15的寄存器C10
CP15的C10寄存器用于控制TLB内容锁定。
访问CP15的C10寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c10>, c0, <opcode_2> mrc p15, 0, <rd>, <c10>, c0, <opcode_2>
如果系统中包含独立的指令TLB和数据TLB,那么对应于数据TLB和指令TLB分别有一个独立的TLB内容锁定寄存器,
- <opcode_2>用来选择其中的某个寄存器:
- <opcode_2>=1选择指令TLB的内容锁定寄存器;
- <opcode_2>=0选择数据TLB的内容锁定寄存器。
C10寄存器的编码格式如下:
● CP15的寄存器C13
C13寄存器用于快速上下文切换FCSE。
FCSE(Fast Context Switch Extension,快速上下文切换)位于 CPU 和 MMU 之间,如果两个进程使用了同样的虚拟地址空间,则对 CPU而言,两个进程使用了同样的虚拟地址空间。
访问CP15的C13寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c13>, c0, 0 mrc p15, 0, <rd>, <c13>, c0, 0
C13寄存器的编码格式如下所示:
其中,PID表示当前进程的所在的进程空间块的编号,即当前进程的进程标识符,取值为0~127。
- 0:MVA(变换后的虚拟地址)= VA(虚拟地址),禁止FCSE(快速上下文切换技术),系统复位后PID=0;
- 非0:使能FCSE。
3 FCSE
● FCSE 概述
FCSE(Fast Context Switch Extension,快速上下文切换)位于 CPU 和 MMU 之间,如果两个进程使用了同样的虚拟地址空间,则对 CPU而言,两个进程使用了同样的虚拟地址空间。
快速上下文切换机构对各进程的虚拟地址进行变换,这样系统中除了 CPU 之外的部分看到的是经过快速上下文切换机构变换的虚拟地址。
快速上下文切换机构将各进程的虚拟空间变换成不同的虚拟空间,这样在进行进程间切换时就不需要进行虚拟地址到物理地址的重映射。
通常情况下,如果两个进程占用的虚拟地址空间由重叠,系统在这两个进程之间进行切换时,必须进行虚拟地址到物理地址的重映射。
而虚拟地址到物理地址的重映射涉及到重建MMU中的页表,而且cache 及TLB中的内容都必须使无效(通过设置协处理器寄存器的相关位)。
这些操作将带类巨大的系统开销,一方面重建MMU和使无效cache及TLB的内容需要很大的开销,另一方面重建cache和TLB内容也需要很大的开销。
快速上下文切换(FCSE)通过修改系统中不同进程的虚拟地址,避免在进行进程间切换时造成的虚拟地址到物理地址的重映射,这样就减少了重建 MMU,使 Cache 和 TLB无效,重建 Cache和 TLB内容等操作的巨大开销,从而提高了系统的性能。
● FCSE 原理
ARM系统中,4GB的虚拟空间被分成了128个进程空间块,每一个进程空间块大小为32MB。
每个进程空间块中可以包含一个进程,该进程可以使用虚拟地址空间0x0~0x01FFFFFF,这个地址范围也就是CPU看到的进程的虚拟空间。
系统128个进程空间块的编号0~127,
标号为X 的进程空间块中的进程实际使用的虚拟地址空间为(X0x02000000)到(X0x02000000+0x01FFFFFF),这个地址空间是系统中除了CPU 之外的其他部分看到的该进程所占用的虚拟地址空间。
快速上下文切换机构将CPU发出的每个虚拟地址按照上述的规则进行变换,然后发送到系统的其他部分。变换过程如下图:
由地址VA到MVA的变换算法如下所示;
if (VA[31:25]==0b0000000)then MVA=VA|(PID<<25) else MVA=VA
其中。PID为当前进程的所在进程空间的编号,即当前进程的进程标识符。其取值为0~127。
- a.系统中,每个进程都使用虚拟地址空间0x0~0x01FFFFFF,当进程访问本进程的指令和数据时,它产生的为虚拟地址VA的高7位为0;快速上下文切换机构用该进程的进程标示符代替VA的高7位,从而得到变换后的虚拟地址MVA,这个MVA在该进程对应的进程空间块内。
PID | PID | 0.....0 | VA |0000000| VA | 置1运算 MVA | PID | VA |
- b.当VA的高7位不全是0时,MVA=VA。这种VA是本进程用于访问别的进程中的数据和指令的虚拟地址,注意这时被访问的进程标识符不能为0.
CP15中的寄存器C13用于快速上下文切换。其编码格式如下所示。
其中,PID 表示当前进程所在的进程空间块的编号,即当前进程的进程标识符,取值为 0~127.
访问寄存器C13的指令格式如下所示。
MCR p15, 0,,,c0,0 MRC P15,0,,,c0,0
其中, 在读操作时,结果中位[31::25]返回PID,其他位的数值是不可以预知的。写操作将设置PID的值。
- 当PID的值为0时,MVA=VA,相当于禁止了FCSE。系统复位后PID即为0.
- 当PID的值不为0时,相当于使能了FCSE。
参考资料
- 《嵌入式系统Linux内核开发实战指南》
- https://blog.csdn.net/yinsexingkong/article/details/51291683