linux内存管理 (二) 3.1 硬件 CP15系统控制协处理器

引言

为什么linux会发展成这个样子,这当然是程序员对程序的要求决定的,
为了满足这些要求,提出了 进程地址空间抽象(1) , 其中 硬件上增加了新的模块MMU(2), 软件上根据MMU的使用手册(3)更新了系统
另外在 进程地址空间抽象 的基础上, 软件上更新了很多新的内存特性(4).


这当中并没有提到硬件做的其他工作.例如为了管理MMU,ARM核心上还增加了CP15
我们可以通到代码来通过控制 CP15,从而来控制 MMU

1.协处理器

  • 协处理器按功能分类
CP0-CP7     ARM留给各生产商使用
CP8-CP9     保留
CP10        一般用于单精度浮点数计算
CP11        一般用于双精度浮点数计算
CP12-CP13   保留ARM公司以后使用
CP14        一般用于Debug调试
CP15        cache 缓存(包括write buffer TLB)的管理、mmu内存的管理、中断向量的管理 时钟模式的管理等

2. 协处理器预留了哪些编程接口

协处理器的操作指令以及协处理器的寄存器 
协处理器操作指令属于ARM指令集的一部分
协处理器寄存器和ARM标准寄存器(r0-r15,cpsr spsr) 不是同一组寄存器
  • 协处理器的操作指令
访问CP15协处理器不能使用常规指令,ARM提供了一组专门操作协处理器的指令,这些指令与ARM自身的指令格式有很大的不同。

对CP15协处理器的操作使用mcr和mrc两条协处理器指令,
这两条指令的记法是从后往前看:
	mcr 是把r(cpu核寄存器)中的数据传送到c(协处理器寄存器)中
	mrc则是把c(协处理器)中的数据传送到r(cpu核寄存器)中。

对cp15协处理器的所有操作都是通过cpu核寄存器和cp15寄存器之间交换数据来完成的。

amrv4v5v6 P212 MCR
	MCR Move to Coprocessor from ARM Register
	MRC Move to ARM Register from Coprocessor

MCR{<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}

Cond是条件码 // {可选}
coproc 是协处理器编号,CP15的编号是15,因此是41// <必选>
CRn是CP15寄存器编号,4个位,也就是说协处理器的主寄存器(还有辅助寄存器)不会超过16个
Rd是CPU核寄存器编号,4个位

// 指令二进制码是32位
bit 20是L位,表示该指令是读还是写
	如果L=1就表示Load,从外面读到CPU核中,也就是mrc指令
	如果L=0就表示Store,也就是mcr指令

// 例子
MRC p15, 5, R4, c0, c2, 3 ; Coproc 15 transfer to ARM register
; opcode 1 = 5, opcode 2 = 3
; ARM destination register = R4
; coproc source registers are 0 and 2
MCR p14, 1, R7, c7, c12, 6 ; ARM register transfer to Coproc 14
; opcode 1 = 1, opcode 2 = 6
; ARM source register = R7
; coproc dest registers are 7 and 12

  • 协处理器的寄存器
协处理器也有属于它自己的寄存器

CP15协处理器内部就有16个寄存器,通常使用Cn来表示,这里的n代表协处理器寄存器的序号。
想使能cache只需要设置CP15相关的寄存器就可以了。

  • 协处理器读写及其内存顺序模型
	B2.7.6对CP15寄存器的更改和内存顺序模型
	===============================================
		保证在任何显式内存操作之后以程序顺序出现的对CP14和CP15寄存器的所有更改不会影响之前的内存操作。

		对CP14和CP15寄存器的所有更改只保证在执行预取刷新操作、获取异常或从异常返回后对后续指令可见。
		
		但是,以下内容适用于协处理器寄存器访问:
			•当MRC操作直接使用前一个MCR操作用来写入寄存器的相同寄存器号直接读取寄存器时,可以保证观察写入的值,而不需要MCR和MRC之间的上下文同步。
			•当MCR操作直接使用前一个MCR操作所用的寄存器号写入寄存器时,最终结果将是第二个MCR的值,而不需要在两个MCR指令之间进行上下文同步。
		
		一些CP15寄存器可能需要在预取刷新、异常或从异常返回之前执行额外的操作,以确保其可见性。这些案件是根据这些登记册的定义具体确定的。
		如果对尚未保证可见的CP15寄存器的更改对异常处理有影响,则适用以下规则:
			•在涉及异常触发的CP15寄存器中保存的任何状态更改尚未保证可见,而涉及异常本身处理的任何更改(一旦确定异常正在发生)则保证生效。
		
		因此,在以下示例中(其中A=1,V=0最初),LDR可能会或可能不会由于未对齐的事务而执行数据中止,但如果发生异常,则使用的向量将受到V位的影响:
			MCR p15, r0, c1, c0, 0 ; clears the A bit and sets the V bit
			LDR r2, [R3] ; unaligned load.

		同步ASID和TTBR的更改
			TLB管理的一种常见使用模型要求同时更改ContextID和转换表基址寄存器,以允许ContextID与不同的页表相关联。
			但是,实现定义的预取深度和分支预测的使用在确保ContextID和翻译表寄存器的更改同步方面产生了问题(例如,tlb、分支目标缓存和/或ASID和翻译信息的其他缓存可能会因无效翻译而损坏)。
			此同步是必要的,以避免:
				•旧ASID与新页表的页表行走关联
				•新ASID与旧页表的页表行走关联。

			这个问题有很多可能的解决方案,如下例所示。
				示例解决方案
					在这种方法中,ASID值0由操作系统保留,除了ASID和转换表基址寄存器的同步之外,不使用。然后遵循以下顺序(从标记为全局的内存执行):
					将ASID更改为0 PrefetchFlush更改转换表基址寄存器PrefetchFlush将ASID更改为新值此方法确保在不确定是否正在访问旧页表或新页表时访问的任何非全局页(通过预取)将与未使用的ASID值0相关联,因此不能导致执行腐败。这个问题的另一个表现是,如果在ASID的改变与其同步之间遇到分支,那么分支预测器中的值可能与不正确的ASID相关联。这种表现通过ASID 0方法解决,但也可以通过避免此类分支来解决。

3. CP15处理器 系统控制协处理器及其接口

  • 功能
1.支持对缓存、TCM 和协处理器的自动查询。
2.它还提供了内存管理的控制机制(如适用,支持MMU和MPU)。
  • 寄存器
寄存器:
	种类及如何索引
		系统控制协处理器最多可包含16个主寄存器,每个主寄存器的长度为32位。
		在系统控制协处理器的描述中,4位主寄存器编号用于标识寄存器,因为它是决定寄存器功能的主要因素。
		寄存器访问指令中的附加字段用于进一步优化访问,从而增加CP15中物理32位寄存器的数量。

	属性
		CP15寄存器可以是只读的、只读的或读/写的。
		寄存器的详细说明规定:
			•允许的访问类型
			•每种访问类型调用的功能
			•主寄存器是否标识多个物理寄存器,如果标识多个物理寄存器,如何区分它们
			•与登记册使用有关的任何其他细节
  • 指令
MCR{<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
// cp15 的 mcr 和 mrc
MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{, <opcode2>} (L = 0)
MRC{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{, <opcode2>} (L = 1)

一般情况下,对于cp15 
// Rd是cpu寄存器,目标寄存器 ,Cn是cp15寄存器,是源寄存器
// 意思是将cp15 的 Cn寄存器读到 cpu的 Rd寄存器里面来
mrc p15 ,0 ,Rd ,Cn ,C0 ,0
或
mrc p15 ,0 ,Rd ,Cn ,C0

对于CP15协处理器,规定opcode1应该为0,opcode2和CRm是指令的选项,具体含义取决于不同的寄存器。
寄存器访问指令 // 唯一定义的系统控制协处理器指令是:
	1. 种类
		•将ARM®寄存器写入CP15寄存器的MCR指令
		•将CP15寄存器的值读入ARM寄存器的MRC指令
		•ARMv6中引入的范围操作MCRR说明,在早期版本的体系结构中是可选的。
		•MRRC对于实现定义的特性是可选的。 // MCRR格式(见第A4-64页的MCRR)的解码范围较小。主寄存器是隐含的(没有CRn字段),CRm和opcode字段用于解码正确的函数。
		所有CP15 CDP、CDP2、LDC、LDC2、MCR2、MCRR2、MRC2、MRRC2、STC和STC2指令都未定义。
	2. 格式
		MCR/MRC指令的格式如下所示,

		MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{, <opcode2>} (L = 0)
		MRC{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{, <opcode2>} (L = 1)[11:8](cp_num)表示CP15
		CRn字段表示主寄存器号

		CRm和opcode2提供额外的寄存器解码。

		<cond> 这是执行指令的条件。条件在第A3-3页的条件字段中定义。如果省略<cond>,则使用AL(always)条件。


		位[23:21]
			这些指令位是通用MRC和MCR指令中的<opcode1>字段,在有效的CP15指令中通常是0b000。
			但是,<opcode1>==1正用于2级缓存支持,并考虑用于其他一些专业任务。未分配的值是不可预测的。
		<Rd>
			这是传输中涉及的ARM寄存器(MCR的源寄存器和MRC的目标寄存器)。
			这个寄存器不能是R15,即使MRC指令通常允许它是R15。如果在CP15 MRC或MCR指令中为<Rd>指定了R15,则该指令是不可预测的。

		<CRn>
			这是参与传输的主CP15寄存器(MCR的目标寄存器和MRC的源寄存器)。标准通用协处理器寄存器名为c0、c1、…、c15。
		
		<CRm>
			这是一个附加协处理器寄存器名,用于访问某些主寄存器,以指定有关寄存器版本和/或访问类型的附加信息。
			当主寄存器的描述没有指定<CRm>时,必须指定c0。如果指定了另一个寄存器,则指令是不可预测的。
		<opcode2>
			这是一个可选的3位数字,用于访问一些主寄存器,以指定有关寄存器版本和/或访问类型的附加信息。如果省略,则使用0。
			当主寄存器的描述没有指定<opcode2>时,必须省略它或指定0。如果指定了另一个值,则指令是不可预测的。
	3.指令使用时间
		
		在ARMv6之前,MCR和MRC指令只能在处理器处于特权模式时使用。如果它们在处理器处于用户模式时执行,则会发生未定义的指令异常。
		
		如果需要通过用户模式程序访问特权系统控制协处理器功能,通常的解决方案是操作系统定义一个或多个swi来提供它。
		由于不同处理器上可用的内存和系统设施的精确设置可能有很大的差异,因此建议所有此类SWI均在易于更换的模块中实现,并且该模块的SWI接口被定义为尽可能独立于处理器细节。
		
		ARMv6引入了以下命令的用户访问:
			•预取刷新
			•数据同步屏障
			•数据存储屏障
			•清除和预取范围操作。
L2 L3 cache 的访问
	所有系统控制协处理器操作(使用MCRR格式的范围操作除外)均使用以下指令访问:
	MCR p15、<opcode1><Rd><CRn><CRm><opcode2>
	MRC p15、<opcode1><Rd><CRn><CRm><opcode2>
	所有常规操作和级别1操作均定义为使用值<opcode1>==0。
	对于与寄存器7相关联的一般高速缓存操作,<CRn>==7,
	以及与寄存器9相关联的锁定操作,<CRn>==9<opcode1>==1被保留以提供2级缓存操作。

	一般来说, 类似操作中 , 级别1与级别2中的 <CRm><opcode2> 的值 类似.
	
	因此,2级一般缓存操作由以下形式的指令访问:
	MCR p15,1<Rd>,c7,<CRm><opcode2>
	MRC p15,1<Rd>,c7,<CRm><opcode2>2级缓存锁定操作由以下形式的指令访问:
	MCR p15,1<Rd>,c9,<CRm><opcode2>
	MRC p15,1<Rd>,c9,<CRm><opcode2>如果需要VA=>PA转换支持,则在寄存器7中定义与级别1缓存操作一起的相关操作:
	MCR p15,0<Rd>,c7,<CRm><opcode2>
	MRC p15,0<Rd>,c7,<CRm><opcode2>为了将来的兼容性,ARM建议实现者在多级缓存设计上与ARM密切合作。
	第B6-30页的表B6-12显示了当前保留的定义。
	建议的最小二级缓存操作集为:
		•按地址使缓存线失效
		•按地址清除缓存线
		•按设置/方式清除缓存线
		•通过set/way清除缓存线并使其失效。

4.CP15 控制哪些硬件及寄存器分类

  • 怎么设置
关联硬件 
	cpu mmu mmu中的TLBs mmu中的TableWalkUnit cache 主存中的转换表(页表) 主存中其他部分
需要设置的硬件
	mmu mmu中的TLBs mmu中的TableWalkUnit cache 主存中的转换表(页表)
设置相关的指令及流程
	MRC(读CP15寄存器到CPU寄存器) CHANGE(改变CPU寄存器的值)  MCR(读CPU寄存器的值并写值CP15寄存器)
设置相关的寄存器
	MMU/CACHE总控制
		Register 1: Control register //enable/disable
		Register 13: Process ID
	TLB
		Register 0: TLB type register (VMSAv6)
		Register 8: TLB functions
		Register 10: TLB lockdown
	TableWalkUnit
		Register 3: Domain access control
		Register 2: Translation table base
		Register 5: Fault status
		Register 6: Fault Address register
	CACHE:
		Register 0: cache type
		Register 1: cache and write buffer control bits
		Register 7: cache management functions
	
	主存中的转换表(页表):
		跟CP15寄存器无关,只需要在 Register 2: Translation table base 所在的主存地址建立 页表即可		

你可能感兴趣的:(Linux内存管理)