大家好,欢迎来到IT知识分享网。
系统控制协处理器CP15的作用是提供对内核部分功能的控制。主要功能包括:
- 整个系统控制和配置
- 缓存配置和管理
- 内存管理单元(
MMU)的配置和管理 - 用于L2缓存的预加载引擎
- 系统性能监控
文章目录
1 读写CP15寄存器
读CP15寄存器
MRC(Move to Register from Coprocessor)指令用于将CP15中的寄存器读到通用寄存器中:
MRC{cond} p15, <opcode_1>, <rd>, <CRn>, <CRm>, <opcode_2>
写CP15寄存器
MCR(Move to Coprocessor from Register)指令用于将通用寄存器的值写入CP15中的寄存器中:
MCR{cond} p15, <opcode_1>, <rd>, <CRn>, <CRm>, <opcode_2>
p15为协处理器cp15的编号- 这两条指令必须在特权模式下才能访问
参数
执行MRC和MCR指令实际上就是组成这样一个32位的ARM指令集:
cond:条件字段,表示指令执行的条件。例如,EQ表示等于。如果省略,则该指令总是执行。opcode_1:操作码1,用于指定要执行的协处理器操作的具体类型。L:1为MRC、0为MCRCRn和CRm: 控制寄存器编号,用于选择在协处理器中的控制寄存器Rd: 目标寄存器,用于存储从协处理器读取的数据opcode_2: 操作码2,与CRm一起用于指定在控制寄存器中执行的特定操作。
2 CP15的寄存器
2.1 简介
CP15共16组寄存器:C0-C15,每组寄存器都包含多个寄存器。前面看到读写CP15寄存器有很多的参数,我们就可以通过提供不同的控制寄存器编号和操作码,来读取不同寄存器组下的不同寄存器。这16个寄存器的大致功能如下:
| Function | CP15 Registers |
|---|---|
| System Configuration | c0 |
| System Control | c1 |
| Translation Base Control | c2 |
| Domain Access Control | c3 |
| Faults | c5/c6 |
| Cache Operations | c7 |
| TLB Operations | c8/c10 |
| Performance Monitor | c9 |
| L2 Control | c9 |
| Pre-load Engine | c11 |
| Interrupts | c12 |
| Process ID | c13 |
| Memory Arrays | c15 |
对于不同的Cortex-A核的不同ARM架构,CP15所包括的寄存器都会有一些区别,所以具体请查阅相关的ARM版本参考手册。
- 这里我整理了ARM11、ARMv7和最新的ARMv8/v9的架构参考手册:下载地址
比如对于最老的ARM11架构来说,在3.3小节有CP15不同参数访问的寄存器表格:
2.2 ARMv7实例
我手上有一块I.MX6ULL的板子,它所用的架构为ARMv7,这里就以ARMv7为例举几个读写CP15寄存器的例子。
在ARMv7中,有两种内存系统架构:VMSA(Virtual Memory System Architecture)和PMSA(Physical Memory System Architecture),分别用于处理虚拟内存和物理内存的映射和管理。比如跑Linux的时候要用MMU,用的就是VMSA,如果跑裸机的话,用的就是PMSA。
那不同的架构,对应的CP15协处理器访问的参数都不同,分别对应手册中的B3.12 CP15 registers for a VMSA implementation和B4.6 CP15 registers for a PMSA implementation。VMSA架构下,详细地配置如下:
下面就以VMSA为例,介绍一些常用的配置寄存器。
2.2.1 读取C0的MDIR寄存器
MDIR寄存器的字段实际上就是系统架构的一些信息,它的组成如下:
- 具体字段含义参考
B3.12.7 c0, Main ID Register (MIDR)
下面的汇编指令将MDIR寄存器的值读到r0寄存器中:
MRC p15, 0, r0, c0, c0, 0
MDIR寄存器为只读的,不可调用MCR写
2.2.2 读/写c1的SCTLR寄存器
SCTLR就是上面的System Control Registers(系统控制寄存器),它与使能MMU、I-Cache和D-Cache等功能有关,所以很重要。组成如下:
比如bit0就是打开/禁用MMU的位,如果使用了Linux,一般是需要打开的。
- 其它字段含义参考:
B3.12.17 c1, System Control Register (SCTLR)
在前面那张总图中没有明确操作码2的值,我们可以参考B3.12.16 CP15 c1, System control registers章节:
所以SCTLR寄存器的操作码2为0。
读SCTLR寄存器的值到r0:
MRC p15,0,r0,c1,c0,0
写r0的值到SCTLR寄存器
MCR p15,0,r0,c1,c0,0
2.2.3 读/写c12的VBAR寄存器
c12寄存器集的寄存器如下:
这里我们学习一下VBAR寄存器:
VBAR[31:5]表示程序的向量表地址,比如芯片自带的BootROM中,如果需要使用U-Boot来引导启动Linux,就需要设置向量表地址为U-Boot程序的向量表地址。
- 低5位表示异常的偏移,默认0为
Reset异常,通过设置这个字段,就可以在上电时进入别的异常- 这也暗示着程序向量表的基地址需要32位对齐
读VBAR寄存器的值到r0
MRC p15,0,r0,c12,c0,0
写r0的值到VBAR寄存器:
ldr r0, =0X MCR p15,0,r0,c12,c0,0
2.2.4 读c15的CBAR寄存器(Cortex-A7)
从最上面的表格我们可以看到c15为IMPLEMENTATION DEFINED registers,也就是不同的芯片厂商可以自己定义这个寄存器的位。这里就以Cortex-A7内核为例,它的架构就是ARMv7,我们来看看Cortex-A7手册中对于CP15的定义:
- Cortex-A7 Technical Reference Manual
我们这里就了解一下CBAR寄存器,它的值为GIC(通用中断控制器)的基地址:
它的字段组成如下:
- 这些字段我们不必深究,这个是用来配置上电后的初始值的,我们只要知道这个寄存器的值会被Cortex-A7核赋值为
GIC的基地址就行了
读GIC基地址到r0:
MRC p15,4,r0,c15,c3,0;
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/115288.html











