文章目录
- MMU 转换控制寄存器 TCR_ELx
- TCR_ELx 概览
- TCR_ELx 寄存器字段详解
- TCR 使用示例
- Normal Memory
- Cacheable
- Shareability
- MMU 内存属性寄存器 MAIR_ELx
- 寄存器结构
- 内存属性字段
- 使用实例
- MMU 地址翻译表基址寄存器 TTBR0/1_ELx
- TTBR0_ELx 寄存器概述
- 寄存器结构
- 功能和用途
- 编程示例
- 注意事项
- MMU 使能寄存 SCTLR_EL3
ARM MUU 的配置主要用到了下面4个寄存器
MMU 转换控制寄存器 TCR_ELx
在ARMv8/v架构中,TCR_ELx
(Translation Control Register at Exception Level x)寄存器用于控制地址转换的操作。这些控制包括页表的大小、地址空间的大小、以及内存区域的可缓存性和共享性等方面。TCR_ELx
寄存器对于配置和优化系统的内存管理至关重要。
bit[5:0]
: 用于配置使用多少位地址宽度,比如,要使用40位的地址宽度,那么T0SZ=64-40=24
.bits [9:8]
Inner cacheability attribute for memory associated with translation table walks0b00
Normal memory, Inner Non-cacheable.0b01
Normal memory, Inner Write-Back Read-Allocate Write-Allocate Cacheable.0b10
Normal memory, Inner Write-Through Read-Allocate No Write-Allocate Cacheable.0b11
Normal memory, Inner Write-Back Read-Allocate No Write-Allocate Cacheable.
bits [11:10]
:Outer cacheability attribute for memory associated with translation table walks:0b00
Normal memory, Outer Non-cacheable.0b01
Normal memory, Outer Write-Back Read-Allocate Write-Allocate Cacheable.0b10
Normal memory, Outer Write-Through Read-Allocate No Write-Allocate Cacheable.0b11
Normal memory, Outer Write-Back Read-Allocate No Write-Allocate Cacheable.
bits [13:12]
:由于 translation table 经常被访问且只需要在cluster内部使用所以可以将其配置为 Inner Shareable,cache coherent 可以避免掉对cache的操作。0b00
Non-shareable.0b10
Outer Shareable.0b11
Inner Shareable.
bit[15:14]
: 用于配置物理页颗粒(Granule size )的大小,比如要使用4K的页面,就需要将这两位配置为0即可;0b00
4KB.0b01
64KB.0b10
16KB.
bit[18:16]
: 用于配置物理空间地址大小:0b000
32 bits, 4GB.0b001
36 bits, 64GB.0b010
40 bits, 1TB.0b011
42 bits, 4TB.0b100
44 bits, 16TB.0b101
48 bits, 256TB.0b110
52 bits, 4PB.
TCR_ELx 概览
TCR_ELx
寄存器中包含多个字段,这些字段影响地址转换和内存访问的不同方面。以下是一些主要字段的简介:
- T0SZ 和 T1SZ: 分别控制第0级和第1级的输入地址空间的大小。它们指定的是地址空间顶部未使用的位数,从而间接地定义了地址空间的大小。
- TG0 和 TG1: 分别设置第0级和第1级页表的粒度(页大小),比如4KB、16KB或64KB。
- IPS: 设置物理地址位宽,例如32位、36位、40位等,影响可访问的物理内存范围。
- SH0 和 SH1: 定义第0级和第1级页表条目的Shareability属性,指示内存区域是否可以在多个处理器核心间共享。
- ORGN0, ORGN1, IRGN0, IRGN1: 分别设置第0级和第1级页表的Outer和Inner缓存策略,包括Non-cacheable、Write-Back、Write-Through等。
TCR_ELx 寄存器字段详解
以下是TCR_ELx
中一些关键字段的更详细说明:
- T0SZ 和 T1SZ(Translation Size): 它们确定了两个不同的转换表(页表)覆盖的虚拟地址空间的大小。例如,如果
T0SZ
为25,则第0级的地址空间大小是[2^(64-25)]字节。 - TG0 和 TG1(Translation Granule): 这些值确定页表项所描述的页的大小。常见的页大小有4KB、16KB和64KB。页的大小影响页表的总体层级和每个页表项所能覆盖的内存大小。
- IPS(Intermediate Physical Address Size): 这个字段指定系统使用的最大物理地址位数。较大的物理地址允许系统访问更多的物理内存。
- SH0 和 SH1(Shareability): 这些字段决定内存访问是否可以在多个处理器之间共享。共享性设置有助于在多核处理器系统中维护内存的一致性。
- ORGN0, ORGN1, IRGN0, IRGN1(Outer and Inner Cacheability): 这些字段控制缓存策略,包括是否缓存以及使用何种缓存模式(如Write-Back或Write-Through)。
TCR 使用示例
假设需要为一个具有64KB页大小、使用48位虚拟地址和40位物理地址的系统配置TCR_EL1
:
TCR_EL1.T0SZ = 16 // 设置虚拟地址空间为48位(64 - 16)
TCR_EL1.TG0 = 2 // 设置第0级页表粒度为64KB
TCR_EL1.IPS = 2 // 设置物理地址大小为40位
TCR_EL1.SH0 = 3 // 设置第0级页表条目为内部共享
TCR_EL1.ORGN0 = 1 // 设置第0级页表条目的外部缓存策略为Write-Back
TCR_EL1.IRGN0 = 1 // 设置第0级页表条目的内部缓存策略为Write-Back
此配置示例中,我们配置了一套页表来覆盖48位的虚拟地址空间,使用64KB的页大小,并且页表条目使用内部共享和Write-Back缓存策略。
Normal Memory
"Normal Memory"是对比于"Device Memory"的一种内存类型。Normal Memory通常用于存储应用数据和代码,而Device Memory则用于映射到设备寄存器。Normal Memory允许缓存和重新排序访问,从而提高效率。
Cacheable
Cacheable属性指示内存访问可以被缓存。这种属性可以进一步细分为以下类型:
- Write-Back (WB) Read-Allocate Write-Allocate Cacheable: 这是最常见的缓存类型,它在读操作时分配缓存行,在写操作时也分配缓存行。在写操作时,数据首先被写入到缓存中,然后在某个时刻异步地被写回到主存储器。这种方式可以减少访问主存储器的次数,提高性能。
- Write-Through (WT) Cacheable: 在这种模式下,数据在写操作时同时写入缓存和主存储器。这确保了主存储器中的数据总是最新的,但可能会牺牲一些写操作的性能。
Shareability
Shareability属性定义了内存区域的共享级别。ARMv8定义了三种共享级别:
- Non-Shareable: 这表示内存区域不被多个处理器核心共享。在单核心系统中,或者在不需要在核心之间共享该内存区域的情况下,可以使用此属性。
- Outer Shareable: 这表示内存区域可以在一组处理器核心之间共享,这组核心共享同一个外部(Level 2 或更高级别)缓存。
- Inner Shareable: 这表示内存区域可以在一组处理器核心之间共享,这组核心共享同一个内部(Level 1)缓存。这对于确保内部缓存中的数据一致性非常重要,特别是在多核处理器系统中。
MMU 内存属性寄存器 MAIR_ELx
在ARMv8架构中,MAIR_ELx
寄存器(Memory Attribute Indirection Registers at Exception Level x)用于定义和配置内存属性表。这些寄存器允许软件定义多种内存属性类型,例如缓存策略和访问权限,这对于物理地址的属性定义至关重要。
MAIR_ELx
寄存器支持多个异常级别,如MAIR_EL1
、MAIR_EL2
和MAIR_EL3
,分别对应不同的异常级别使用。寄存器中的每个字段与转换表(Translation Table)中的属性字段相关联,这些属性字段用于描述如何访问对应的物理内存。
寄存器结构
MAIR_ELx
寄存器包含多个字段,每个字段8位,总共可以配置8种不同的内存属性。这意味着在转换表项(Translation Table Entry, TTE)中可以引用这8种配置中的任意一种来指定对应内存区域的访问特性。
字段格式如下:
- Attr0[7:0]
- Attr1[15:8]
- Attr2[23:16]
- Attr3[31:24]
- Attr4[39:32]
- Attr5[47:40]
- Attr6[55:48]
- Attr7[63:56]
每一对Attrn
字段定义了一种内存类型,包括其缓存策略和访问权限。每个Attrn
字段内部分为两个子字段,高四位和低四位,分别代表不同的属性。
内存属性字段
每个Attrn
字段按以下方式定义:
- 低四位定义了内存区域的正常内存类型的属性(如缓存行为)。
0b0000
:设备内存(Device memory),非缓存。0b0100
:正常内存(Normal memory),非缓存。- 其他值定义了正常内存的缓存类型,如Write-Through (WT), Write-Back (WB), Read-Allocate, Write-Allocate等。
- 高四位定义了内存区域的外部内存类型的属性(如对于SoC外部的内存,或是多核处理器间的共享内存的缓存行为)。
- 这些位通常定义了与低四位相类似的属性,但适用于处理器外部的内存。
使用实例
配置MAIR_EL1
为最常见的例子,下面是一个典型的配置过程:
- 配置非缓存访问(设备内存):
// Attr0设为0x00:设备内存,非缓存,非缓冲
- 配置写回缓存(正常内存):
// Attr1设为0xFF:正常内存,Write-Back, Read & Write Allocate
配置完成后,转换表项可以通过指定的属性索引(Attrn
)来使用这些定义。
MMU 地址翻译表基址寄存器 TTBR0/1_ELx
在ARMv8架构中,TTBR0_ELx
和TTBR1_ELx
寄存器是用来存放转换表基址(Translation Table Base Register)的。这些寄存器分别定义了在不同范围内虚拟地址映射到物理地址的页表的基址。这里我们特别关注TTBR0_ELx
。
TTBR0_ELx 寄存器概述
TTBR0_ELx
(Translation Table Base Register 0 at Exception Level x)用于存储页表的物理基址,其中x
可以是1、2或3,表示不同的异常级别。在多级页表结构中,这个寄存器指向页表的第一级。
寄存器结构
在ARMv8架构中,TTBR0_ELx
拥有以下关键组成部分:
- BADDR: 基址字段。它包含页表的物理基址。页表的物理基址的对齐要求取决于内存的页面大小和表的总大小。
- ASID: 地址空间标识符。它用于支持地址空间的上下文切换,确保TLB(Translation Lookaside Buffer)条目与特定的地址空间关联。
- CNP: 常用非安全页表标志(Common not Private)。指示页表是否为非私有,这与虚拟化和安全扩展有关。
功能和用途
TTBR0_ELx
主要用途是定义基本的虚拟内存到物理内存的映射。这是通过页表机制来实现的,其中TTBR0_ELx
指向页表的根。ARMv8支持使用两个TTBR寄存器(TTBR0_ELx
和TTBR1_ELx
)来支持不同范围的地址空间,通常:
TTBR0_ELx
用于较低范围的虚拟地址。TTBR1_ELx
用于较高范围的虚拟地址。
这种分割允许操作系统将用户空间和内核空间的映射分开管理,提高了安全性和效率。
编程示例
配置TTBR0_EL1
通常涉及到计算页表基址,然后将其加载到寄存器中。以下是设置TTBR0_EL1
的一个示例代码片段:
// 假设x0寄存器包含页表的物理基址
msr TTBR0_EL1, x0 // 将x0寄存器的值写入TTBR0_EL1
// 其中,必须确保基址符合对齐要求
注意事项
- 对齐要求:
TTBR0_ELx
的BADDR字段必须正确对齐。对齐要求取决于页表的大小和页面大小。 - ASID管理:在进行上下文切换时,ASID的管理是关键。它确保了TLB条目的有效性只在特定上下文中被保持。
- 内存属性:与
TTBR0_ELx
配合使用的MAIR_ELx
寄存器定义了页表及其映射的内存的属性,确保了正确的缓存策略被应用。
通过正确配置TTBR0_ELx
(以及可能的TTBR1_ELx
),系统可以有效地管理不同类型的内存访问,包括用户空间和内核空间的隔离,提高系统的安全性和效率。
MMU 使能寄存 SCTLR_EL3
对于MMU 的使能是通过 系统控制寄存器 SCTLR 来控制的,包括SCTLR_EL1、SCTLR_EL2和SCTLR_EL3,但并不是所有bit在EL1都可用。
详细内容见:【ARMv8 异常模型入门及渐进 2 – ARMv8/v9 寄存器 (SCR_ELn | ELR_ELn | ESR_ELn | CTR | HCR_ELn … 详细介绍】
判断当前 MMU是否打开:
func Arm_MmuEnabled
EL1_OR_EL2_OR_EL3 x1
1: mrs x0, sctlr_el1 // Get control register EL1
b 4f
2: mrs x0, sctlr_el2 // Get control register EL2
b 4f
3: mrs x0, sctlr_el3 // Get control register EL3
4: and x0, x0, #CTRL_M_BIT
ret
endfunc Arm_MmuEnabled
打开MMU 函数:
func Arm_EnableMmu
EL1_OR_EL2_OR_EL3 x1
1: mrs x0, sctlr_el1 // Read System control register EL1
b 4f
2: mrs x0, sctlr_el2 // Read System control register EL2
b 4f
3: mrs x0, sctlr_el3 // Read System control register EL3
4: orr x0, x0, #CTRL_M_BIT // Set MMU enable bit
bic x0, x0, #(0x1 << 19) // WXN bit (writeable execute never)
EL1_OR_EL2_OR_EL3 x1
1: tlbi vmalle1
dsb nsh
isb
msr sctlr_el1, x0 // Write back
b 4f
2: tlbi alle2
dsb nsh
isb
msr sctlr_el2, x0 // Write back
b 4f
3: tlbi alle3
dsb nsh
isb
msr sctlr_el3, x0 // Write back
4: isb
ret
endfunc Arm_EnableMmu