1.协处理器和协处理器指令详解算法
mcr & mrc缓存
mrc用于读取CP15中的寄存器学习
mcr用于写入CP15中的寄存器编码
1.2什么是协处理器?操作系统
1.SoC内部另外一处理核心,协助主CPU实现某些功能,被主CPU调用执行必定任务。.net
2.ARM设计上支持多达16个协处理器,可是通常SoC只实现其中的CP15.(cp:coprocessor)设计
3.协处理器和MMU、cache、TLB等处理有关,功能上和操做系统的虚拟地址映射、cache 管理等有关。code
1.3MRC & MCR的使用方法进程
(1)mcr{<cond>} p15, <opcode_1>, <Rd>, <Crn>, <Crm>, {<opcode_2>}内存
(2)opcode_1:对于cp15永远为0
(3)Rd:ARM的普通寄存器
(4)Crn:cp15的寄存器,合法值是c0~c15
(5)Crm:cp15的寄存器,通常均设为c0
(6)opcode_2:通常省略或为0
1.3.1 CP15寄存器指令的编码格式及语法说明以下:
31 28 |
27 24 |
23 21 |
20 |
19 16 |
15 12 |
11 8 |
7 5 |
4 |
3 0 |
cond |
1 1 1 0 |
opcode_1 |
L |
cr n |
rd |
1 1 1 1 |
opcode_2 |
1 |
crm |
注意:
(1)<opcode_1>:协处理器行为操做码,对于CP15来讲,<opcode_1>永远为0b000, 不然结果未知。
(2)<rd>:不能是r15/pc,不然,结果未知。
(3)<crn>:做为目标寄存器的协处理器寄存器,编号为C0~C15。
(4)<crm>:附加的目标寄存器或源操做数寄存器,若是不须要设置附加信息,将crm设置为c0, 不然结果未知。
(5)<opcode_2>:提供附加信息好比寄存器的版本号或者访问类型,用于区分同一个编号的不 同物理寄存器,能够省略<opcode_2>或者将其设置为0,不然结果未知。
1.3.2ARM处理器中CP15协处理器的寄存器
寄存器编号 |
基本做用 |
在MMU中的做用 |
在PU中的做用 |
0 |
ID编码(只读) |
ID编码和cache类型 |
|
1 |
控制位(可读写) |
各类控制位 |
|
2 |
存储保护和控制 |
地址转换表基地址 |
Cachability的控制位 |
3 |
存储保护和控制 |
域访问控制位 |
Bufferablity控制位 |
4 |
存储保护和控制 |
保留 |
保留 |
5 |
存储保护和控制 |
内存失效状态 |
访问权限控制位 |
6 |
存储保护和控制 |
内存失效地址 |
保护区域控制 |
7 |
高速缓存和写缓存 |
高速缓存和写缓存控制 |
|
8 |
存储保护和控制 |
TLB控制 |
保留 |
9 |
高速缓存和写缓存 |
高速缓存锁定 |
|
10 |
存储保护和控制 |
TLB锁定 |
保留 |
11 |
保留 |
|
|
12 |
保留 |
|
|
13 |
进程标识符 |
进程标识符 |
|
14 |
保留 |
|
|
15 |
因不一样设计而异 |
因不一样设计而异 |
因不一样设计而异 |
(1)CP15的寄存器C0
CP15中寄存器C0对应两个标识符寄存器,由访问CP15中的寄存器指令中的<opcode_2>指定要访问哪一个具体物理寄存器,<opcode_2>与两个标识符寄存器的对应关系以下所示:
opcode_2编码 |
对应的标识符号寄存器 |
0b000 |
主标识符寄存器 |
0b001 |
cache类型标识符寄存器 |
其余 |
保留 |
(2)CP15的寄存器C1
访问主标识符寄存器的指令格式以下所示:
mrc p15, 0, r0, c1, c0{, 0} ;将CP15的寄存器C1的值读到r0中
mcr p15, 0, r0, c1, c0{, 0} ;将r0的值写到CP15的寄存器C1中
CP15中的寄存器C1的编码格式及含义说明以下:
31 16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
附加 |
L4 |
RR |
V |
I |
Z |
F |
R |
S |
B |
L |
D |
P |
W |
C |
A |
M |
位 |
说 明 |
M |
0:禁止MMU或者PU;1:使能MMU或者PU |
A |
0:禁止地址对齐检查;1:使能地址对齐检查 |
C |
0:禁止数据/整个cache;1:使能数据/整个cache |
W |
0:禁止写缓冲;1:使能写缓冲 |
P |
0:异常中断处理程序进入32位地址模式;1:异常中断处理程序进入26位地址模式 |
D |
0:禁止26位地址异常检查;1:使能26位地址异常检查 |
L |
0:选择早期停止模型;1:选择后期停止模型 |
B |
0:little endian;1:big endian |
S |
在基于MMU的存储系统中,本位用做系统保护 |
R |
在基于MMU的存储系统中,本位用做ROM保护 |
F |
0:由生产商定义 |
Z |
0:禁止跳转预测功能;1:使能跳转预测指令 |
I |
0:禁止指令cache;1:使能指令cache |
V |
0:选择低端异常中断向量0x0~0x1c;1:选择高端异常中断向量0xffff0000~ 0xffff001c |
RR |
0:常规的cache淘汰算法,如随机淘汰;1:预测性淘汰算法,如round-robin淘汰算法 |
L4 |
0:保持ARMv5以上版本的正常功能;1:将ARMv5以上版本与之前版本处理器兼容,不根据跳转地址的bit[0]进行ARM指令和Thumb状态切换:bit[0]等于0表示ARM指令,等于1表示Thumb指令 |
附加: |
|
(3)CP15的寄存器C2
CP15中的寄存器C2保存的是页表的基地址,即一级映射描述符表的基地址。其编码格以下所示:
31 0 |
一级映射描述符表的基地址(物理地址) |
(4)CP15的寄存器C3
CP15中的寄存器C3定义了ARM处理器的16个域的访问权限。
31 0 |
|||||||||||||||
D15 |
D14 |
D13 |
D12 |
D11 |
D10 |
D9 |
D8 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
(5)CP15的寄存器C5
CP15中的寄存器C5是失效状态寄存器,编码格式以下所示:
31 9 8 7 4 3 0 |
|||
UNP/SBZP |
0 |
域标识 |
状态标识 |
其中,域标识bit[7:4]表示存放引发存储访问失效的存储访问所属的域。
状态标识bit[3:0]表示放引发存储访问失效的存储访问类型,该字段含义如表4-3所示(优先级由上到下递减)。
表4-3 状态标识字段含义
引发访问失效的缘由 |
状态标识 |
域标识 |
C6 |
终端异常(Terminal Exception) |
0b0010 |
无效 |
生产商定义 |
中断向量访问异常(Vector Exception) |
0b0000 |
无效 |
有效 |
地址对齐 |
0b00x1 |
无效 |
有效 |
一级页表访问失效 |
0b1100 |
无效 |
有效 |
二级页表访问失效 |
0b1110 |
有效 |
有效 |
基于段的地址变换失效 |
0b0101 |
无效 |
有效 |
基于页的地址变换失效 |
0b0111 |
有效 |
有效 |
基于段的存储访问中域控制失效 |
0b1001 |
有效 |
有效 |
基于页的存储访问中域控制失效 |
0b1101 |
有效 |
有效 |
基于段的存储访问中访问权限控制失效 |
0b1111 |
有效 |
有效 |
基于页的存储访问中访问权限控制失效 |
0b0100 |
有效 |
有效 |
基于段的cache预取时外部存储系统失效 |
0b0110 |
有效 |
有效 |
基于页的cache预取时外部存储系统失效 |
0b1000 |
有效 |
有效 |
基于段的非cache预取时外部存储系统失效 |
0b1010 |
有效 |
有效 |
(6)CP15中的寄存器C6
CP15中的寄存器C5是失效地址寄存器,编码格式以下所示:
31 0 |
失效地址(虚拟地址) |
(7)CP15中的寄存器C7
CP15的C7寄存器用来控制cache和写缓存,它是一个只写寄存器,读操做将产生不可预知的后果。
访问CP15的C7寄存器的指令格式以下所示:
mcr p15, 0, <rd>, <c7>, crm, <opcode_2> ;<rd>、<crm>和<opcode_2>的不一样取值组合 实现不一样功能
(8)CP15中的寄存器C8
CP15的C8寄存器用来控制清除TLB的内容,是只写寄存器,读操做将产生不可预知的后果。
访问CP15的C8寄存器的指令格式以下所示:
mcr p15, 0, <rd>, <c8>, crm, <opcode_2> ;<rd>、<crm>和<opcode_2>的不一样取值组合实现不一样功能,见第4.2节
(9)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以下所示:
31 32-W 31-W 0 |
|
cache组内块序号index |
0 |
其中index表示当下一次发生cache未命中时,将预取的存储块存入cache中该块对应的组中序号为index的cache块中。此时序号为0~index-1的cache块被锁定,当发生cache替换时,从序号为index到ASSOCIATIVITY的块中选择被替换的块。
编码格式B以下所示:
31 30 W W-1 0 |
||
L |
0 |
cache组内块序号index |
位 |
说 明 |
L=0 |
当发生cache未命中时,将预取的存储块存入cache中该块对应的组中序号为index的cache块中 |
续表
位 |
说 明 |
L=1 |
若是本次写操做以前L=0,而且index值小于本次写入的index,本次写操做执行的结果不可预知;不然,这时被锁定的cache块包括序号为0~index-1的块,当发生cache替换时,从序号为index到ASSOCIATIVITY的块中选择被替换的块 |
(10)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寄存器的编码格式以下:
31 30 32-W 31-W 32-2W 31-2W 1 0 |
|||
可被替换的条目起始地址的base |
下一个将被替换的条目地址victim |
0 |
P |
位 |
说 明 |
victim |
指定下一次TLB没有命中(所需的地址变换条目没有包含在TLB中)时,从内存页表中读取所需的地址变换条目,并把该地址变换条目保存在TLB中地址victim处 |
base |
指定TLB替换时,所使用的地址范围,从(base)到(TLB中条目数-1);字段victim的值应该包含在该范围内 |
P |
1:写入TLB的地址变换条目不会受使整个TLB无效操做的影响,一直保持有效;0:写入TLB的地址变换条目将会受到使整个TLB无效操做的影响 |
(11)CP15的寄存器C13
C13寄存器用于快速上下文切换FCSE。
访问CP15的C13寄存器的指令格式以下所示:
mcr p15, 0, <rd>, <c13>, c0, 0
mrc p15, 0, <rd>, <c13>, c0, 0
C13寄存器的编码格式以下所示:
31 25 24 0 |
|
PID |
0 |
其中,PID表示当前进程的所在的进程空间块的编号,即当前进程的进程标识符,取值为0~127。
0:MVA(变换后的虚拟地址)= VA(虚拟地址),禁止FCSE(快速上下文切换技术),系统复位后PID=0;
非0:使能FCSE。
举例:
来自于uboot
---------------------------------------------
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #1
mcr p15, 0, r0, c1, c0, 0
学习要点
了解代码目的。
没必要深究,将uboot中和kernel中起始代码中的通常操做搞明白便可。
只看通常用法,不详细区分参数细节,不然会陷入不少复杂未知中。
关键在于理解,而不在于记住。