MAIR_EL1 简介

MAIR_EL1 是 ARMv8 架构内存管理的核心,它通过一个索引机制来定义内存的"性格"。简单来说,页表项通过一个3位索引(AttrIndx)来引用 MAIR_EL1 中预先定义好的8种内存属性之一,从而避免了在每个页表项中都重复描述这些复杂的属性。

寄存器结构

MAIR_EL1 是一个 64位 寄存器,它被均匀地划分为 8个字段 ,每个字段宽度为 8位,用于定义一种内存属性。

assembly

复制代码
MAIR_EL1 的位域分布如下(63-0 位):

+---------------+---------------+-----+---------------+
| Attr7 (63-56) | Attr6 (55-48) | ... | Attr0 (7-0)   |
+---------------+---------------+-----+---------------+
  • 字段索引 (n): 8个字段的索引从0到7。

  • 选择机制 : 页表描述符的 bit[4:2] (即 AttrIndx 字段) 用于选择 Attr<n>。例如,若页表项的 AttrIndx0b001,则 CPU 会使用 MAIR_EL1Attr1 字段的值。

支持的属性值

ARMv8 架构将内存主要分为两大类:设备内存 (Device Memory)普通内存 (Normal Memory)MAIR_EL1 的每个8位字段必须填入符合特定编码规则的值。

1. 设备内存 (Device Memory)
  • 编码格式 : 0b0000dd00 (8位)

  • 属性说明: 用于映射外设地址空间(如UART、GPIO),其访问行为是严格受控的,通常不可缓存。

  • dd 编码详解:

二进制 类型 行为说明
0b00 Device-nGnRnE 最强限制:不允许聚合(Gathering)、不允许重排序(Re-ordering)、不提前写应答(Early Write Acknowledge)。这是最安全的设备内存配置,适用于UART等敏感外设。
0b01 Device-nGnRE 允许提前写应答,但不允许聚合和重排序。
0b10 Device-GRE 允许聚合、重排序和提前写应答,性能更高,但需设备支持。
2. 普通内存 (Normal Memory)
  • 编码格式 : 0booooiiii (8位)

  • 属性说明: 用于映射RAM等常规内存。CPU可对其进行缓存、预取和乱序执行以提升性能。

  • 编码详解:

    • oooo (Outer)iiii (Inner): 分别控制外部和内部共享域(如多核集群内/间)的缓存策略。

    • RW 编码 : 表内 RW 字段共同决定策略:

二进制 (ooooiiii) 策略
0b0000 Non-cacheable (不可缓存)
0b0001 Write-Through (写透)
0b0010 Write-Back, Write-Allocate (回写,写分配)
0b0011 Write-Back, no Write-Allocate (回写,非写分配)

Linux 内核的配置参考

Linux 内核中预定义了几种常用的内存类型和对应的 MAIR_EL1 编码,可以直接参考使用。

属性名 描述 MAIR_EL1 编码值 (8位)
MT_DEVICE_nGnRnE 强限制设备内存,用于 UART 等 0b00000000 (0x00)
MT_DEVICE_nGnRE 允许提前应答的设备内存 0b00000100 (0x04)
MT_DEVICE_GRE 允许聚合和重排序的设备内存 0b00001000 (0x08)
MT_NORMAL_NC 普通内存,不可缓存 0b01000100 (0x44)
MT_NORMAL 普通内存,回写、写分配 0b11111111 (0xFF)
MT_NORMAL_WT 普通内存,写透 0b10101010 (0xAA)

使用示例

假设需要配置一个支持回写的普通内存(索引0)和一个严格的设备内存(索引1),代码片段如下:

复制代码
// 定义宏
#define NORMAL_MEM_ATTR  0xFF  // 用于索引 0
#define DEVICE_MEM_ATTR  0x00  // 用于索引 1

// 组装 MAIR_EL1 的值
unsigned long mair_val = (unsigned long)DEVICE_MEM_ATTR << 8 | NORMAL_MEM_ATTR;

// 写入寄存器
__asm__ volatile("msr mair_el1, %0" : : "r" (mair_val));
__asm__ volatile("isb"); // 确保配置生效

在页表项中,设置 AttrIndx 字段(bit[4:2])为 0b000 即选择普通内存,为 0b001 则选择设备内存。

配置的关键步骤

  1. 计算并写入 : 根据需求计算出64位值,通过 MSR MAIR_EL1, Xn 写入。

  2. 刷新 TLB : 修改后必须刷新TLB,确保旧属性被清除,使新配置生效。使用 TLBI *DSB/ISB 指令。

  3. 使能 MMU : 确保 MMU 已使能 (SCTLR_EL1.M = 1)。

  4. 与页表协同 : 页表项中的 AttrIndx 必须与 MAIR_EL1 中的索引配置相匹配

相关推荐
liuluyang5302 天前
Arm DynamIQ --- DSU (DynamIQ Shared Unit)
armv8
liuluyang5302 天前
SCR_EL3,安全配置寄存器
安全·armv8·scr_el3
liuluyang5303 天前
HCR_EL2,Hypervisor 配置寄存器
armv8
liuluyang5303 天前
VMPIDR_EL2,虚拟化多处理器 ID 寄存器
armv8
tianrun12343 天前
ARMv8 两级页表内存属性合并原理
虚拟化·mmu·armv8
Jia ming2 个月前
ARMv8内存模型与屏障指令详解
armv8·内存模型·内存屏障
openHiTLS密码开源社区5 个月前
ARM架构深度解析:ARMv7、ARMv8、ARMv9的技术演进、芯片实现与未来展望
armv8·armv9·armv7·cortex-m·sve2·cca架构
全栈工程师修炼日记6 个月前
ARMv8系统的安全性(一):安全目标是什么?
安全·trustzone·armv8
liuluyang5309 个月前
ARMv8 创建3级页表示例
mmu·armv8·页表