CP15协处理器

 

关于 CP15 协处理器和其相关寄存器的详细内容请参考下面两份文档:《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf》第 1469 页“B3.17 Oranization of the CP15 registers in a VMSA implementation”。《Cortex-A7 Technical ReferenceManua.pdf》第55 页“Capter 4 System Control”。CP15 协处理器一般用于存储系统管理,但是在中断中也会使用到,CP15 协处理器一共有16 32 位寄存器。CP15 协处理器的访问通过如下指令完成:

MRC: CP15 协处理器中的寄存器数据读到 ARM 寄存器中。

MCR: ARM 寄存器的数据写入到 CP15 协处理器寄存器中。

MRC 就是读 CP15 寄存器,MCR 就是写 CP15 寄存器,MCR 指令格式如下:

MCR{cond} p15, <opc1>, <Rt>, <CRn>, <CRm>, <opc2>

cond:指令执行的条件码,如果忽略的话就表示无条件执行。

opc1:协处理器要执行的操作码。

RtARM 源寄存器,要写入到 CP15 寄存器的数据就保存在此寄存器中。

CRn CP15 协处理器的目标寄存器。

CRm: :协处理器中附加的目标寄存器或者源操作数寄存器,如果不需要附加信息就将

CRm 设置为 C0,否则结果不可预测。

opc2 :可选的协处理器特定操作码,当不需要的时候要设置为 0

MRC 的指令格式和 MCR 一样,只不过在 MRC 指令中 Rt 就是目标寄存器,也就是从

CP15 指定寄存器读出来的数据会保存在 Rt 中。而 CRn 就是源寄存器,也就是要读取的写处理器寄存器。假如我们要将 CP15 C0 寄存器的值读取到 R0 寄存器中,那么就可以使用如下命令:

MRC p15, 0, r0, c0, c0, 0

CP15 协处理器有 16 32 位寄存器,c0~c15,只介绍c0c1c12 c15 这四个寄存器,其他的寄存器大家参考上面的两个文档即可。

1 c0  寄存器

CP15 协处理器有 16 32 位寄存器,c0~c15,在使用 MRC 或者 MCR 指令访问这 16

寄存器的时候,指令中的 CRnopc1CRm opc2 通过不同的搭配,其得到的寄存器含义是不同的。比如 c0 在不同的搭配情况下含义如图所示:

在上图中当 MRC/MCR 指令中的 CRn=c0opc1=0CRm=c0opc2=0 的时候就表示此时的 c0 就是 MIDR 寄存器,也就是主 ID 寄存器,这个也是 c0 的基本作用。对于 Cortex-A7内核来说,c0 作为 MDIR 寄存器的时候其含义如图所示:

在上图中各位所代表的含义如下:

bit31:24:厂商编号,0X41ARM

bit23:20:内核架构的主版本号,ARM 内核版本一般使用 rnpn 来表示,比如 r0p1,其中 r0 后面的 0 就是内核架构主版本号。

bit19:16:架构代码,0XFARMv7 架构。

bit15:4:内核版本号,0XC07Cortex-A7 MPCore 内核。

bit3:0:内核架构的次版本号,rnpn 中的 pn,比如 r0p1 p1 后面的 1 就是次版本号。

2 c1  寄存器

c1 寄存器同样通过不同的配置,其代表的含义也不同,如图所示:

 

在上图中当 MRC/MCR 指令中的 CRn=c1opc1=0CRm=c0opc2=0 的时候就表示此时的 c1 就是 SCTLR 寄存器,也就是系统控制寄存器,这个是 c1 的基本作用。SCTLR 寄存器主要是完成控制功能的,比如使能或者禁止 MMUI/D Cache 等,c1 作为 SCTLR 寄存器的时候其含义如图所示:

bit13V , 中断向量表基地址选择位,为 0 的话中断向量表基地址为 0X00000000,软件可以使用 VBAR 来重映射此基地址,也就是中断向量表重定位。为 1 的话中断向量表基地址为0XFFFF0000,此基地址不能被重映射。

bit12II Cache 使能位,为 0 的话关闭 I Cache,为 1 的话使能 I Cache

bit11Z,分支预测使能位,如果开启 MMU 的话,此位也会使能。

bit10SWSWP SWPB 使能位,当为 0 的话关闭 SWP SWPB 指令,当为 1 的时候就使能 SWP SWPB 指令。

bit9:3:未使用,保留。

bit2CD Cache 和缓存一致性使能位,为 0 的时候禁止 D Cache 和缓存一致性,为 1

使能。

bit1A,内存对齐检查使能位,为 0 的时候关闭内存对齐检查,为 1 的时候使能内存对齐检查。

bit0MMMU 使能位,为 0 的时候禁止 MMU,为 1 的时候使能 MMU

如果要读写 SCTLR 的话,就可以使用如下命令:

MRC p15, 0, <Rt>, c1, c0, 0 ;读取 SCTLR 寄存器,数据保存到 Rt 中。

MCR p15, 0, <Rt>, c1, c0, 0 ;Rt 中的数据写到 SCTLR(c1)寄存器中。

3 c12  寄存器

c12 寄存器通过不同的配置,其代表的含义也不同,如图所示:

在上图中当 MRC/MCR 指令中的 CRn=c12opc1=0CRm=c0opc2=0 的时候就表示此时 c12 VBAR 寄存器,也就是向量表基地址寄存器。设置中断向量表偏移的时候就需要将新的中断向量表基地址写入 VBAR 中,假如代码链接的起始地址为0X87800000,而中断向量表肯定要放到最前面,也就是 0X87800000 这个地址处。所以需要设置 VBAR 0X87800000,设置命令如下:

ldr r0, =0X87800000  ; r0=0X87800000

MCR p15, 0, r0, c12, c0, 0  ;r0 里面的数据写入到 c12 中,即 c12=0X87800000

c15  寄存器

c15 寄存器也可以通过不同的配置得到不同的含义,参考文档《Cortex-A7 Technical ReferenceManua.pdf》第 68 页“4.2.16 c15 registers”,其配置如图 17.1.4.5 所示:

 

在图 17.1.4.5 中,我们需要 c15 作为 CBAR 寄存器,因为 GIC 的基地址就保存在 CBAR中,我们可以通过如下命令获取到 GIC 基地址:

MRC p15, 4, r1, c15, c0, 0 ; 获取 GIC 基础地址,基地址保存在 r1 中。

获取到 GIC 基地址以后就可以设置 GIC 相关寄存器了,比如我们可以读取当前中断 ID,当前中断 ID 保存在 GICC_IAR 中,寄存器 GICC_IAR 属于 CPU 接口端寄存器,寄存器地址相对于 CPU 接口端起始地址的偏移为 0XC,因此获取当前中断 ID 的代码如下:

MRC p15, 4, r1, c15, c0, 0 ;获取 GIC 基地址

ADD r1, r1, #0X2000  ;GIC 基地址加 0X2000 得到 CPU 接口端寄存器起始地址

LDR r0, [r1, #0XC] ;读取 CPU 接口端起始地址+0XC 处的寄存器值,也就是寄存器;GIC_IAR 的值

关于 CP15 协处理器就讲解到这里,简单总结一下,通过 c0 寄存器可以获取到处理器内核信息;通过 c1 寄存器可以使能或禁止 MMUI/D Cache 等;通过 c12 寄存器可以设置中断向量偏移;通过 c15 寄存器可以获取 GIC 基地址。关于 CP15 的其他寄存器,查阅本文前面列举的 2 ARM 官方资料。

 

 注:原文出自 【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.3

 

posted @ 2020-04-04 21:06  on_the_go  阅读(1233)  评论(0编辑  收藏  举报