ARMv8 内存属性

普通内存 (normal memory)

弱一致性(weakly ordered)。
存在分支预测,数据预取,高速缓存行预取,乱序加载等优化。

设备内存(device memory)

访问时有特定的时序限制。访问性能比普通内存差。

arm64 mair_el1 系统寄存器及linux 对其配置

linux中的几种memory 属性定义如下:

/*
 * Memory types available.
 */
#define MT_DEVICE_nGnRnE	0
#define MT_DEVICE_nGnRE		1
#define MT_DEVICE_GRE		2
#define MT_NORMAL_NC		3
#define MT_NORMAL			4
#define MT_NORMAL_WT		5

其中 G/nG/R/nR/E/nE 的含义如下:
G:Gathering,内存聚合
R:Re-ordering,指令重排
E:Early Write Ackowledgement,提前写应答
_NC: Non-Cacheable,关闭高速缓存
_WT: write through 直写策略

在内核启动时,会对mair_el1 进行配置
在这里插入图片描述
从arm官网可以看到MAIR 这一列数值的含义
在这里插入图片描述
其中,开头的0b 是二进制的含义,后边dd, x, iiii这些具体是0还是1 及对应的含义要看如下几个表格
在这里插入图片描述
在这里插入图片描述

页表中的内存属性

ioremap 是将设备地址映射成虚拟地址的接口,从如下定义可以看到其使用了上述提到的内存属性 PROT_DEVICE_nGnRE 等

#define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
#define ioremap_wt(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))

// 其中
typedef u64 pteval_t;

typedef struct { pteval_t pgprot; } pgprot_t;
#define pgprot_val(x)	((x).pgprot)
#define __pgprot(x)	((pgprot_t) { (x) } )

如下属性会直接或到64位pte 中。

/*arch/arm64/include/asm/pgtable-prot.h*/
#define PROT_DEVICE_nGnRnE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
#define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
#define PROT_NORMAL_NC		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
#define PROT_NORMAL_WT		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
#define PROT_NORMAL		(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))

/*arch/arm64/include/asm/pgtable-hwdef.h*/
#define PTE_ATTRINDX(t)		(_AT(pteval_t, (t)) << 2)

页表属性占了pte 中的bit[4:2]。因此mmu 在查询当前页表的内存属性时,会使用pte 的bit[4:2] 拿到AttrIndex,然后找到系统寄存器 MAIR 中下标为AttrIndex 的内存属性。

在这里插入图片描述

总结

1、在linux arm64 中,共有MT_DEVICE_nGnRnE 等共6种内存属性
2、arm64 系统寄存器MAIR 可以配置共8种内存属性,每个内存属性占用8bit。linux 仅配置了6种。
3、页表描述符中,bit[4:2] 为AttrIndx。当前页的内存属性,就是MAIR 寄存器中下标为AttrIndx 的属性。

参考
《Arm® Architecture Reference Manual for A-profile architecture》(DDI0487K_a_a-profile_architecture_reference_manual.pdf)

<think>好的,用户想了解ARMv8架构中的可共享内存。我需要先回忆一下ARMv8内存属性相关知识。ARMv8内存类型和属性对于缓存和共享机制很重要,特别是可共享内存的作用。 首先,内存属性分为普通内存和设备内存。普通内存又分为Non-cacheable和Cacheable。在Cacheable中,缓存策略包括Write-Back和Write-Through等。但用户关注的是可共享性,这涉及到内存区域是否被多个处理器或设备共享。 接下来,可共享内存属性ARMv8中的可共享属性有几种情况:Non-shareable、Inner Shareable、Outer Shareable和Full System Shareable。这些属性决定了内存区域在不同层次的共享范围。例如,Inner Shareable可能在处理器集群内部共享,而Outer可能包括外部组件。 需要解释可共享内存的应用场景,比如多核间的数据共享,DMA设备访问等。同时,要注意内存屏障的使用,确保数据一致性。还有,与缓存一致性的关系,比如Inner Shareable区域在集群内维护缓存一致性,但跨集群可能需要软件管理。 另外,页表配置部分,ARMv8通过MAIR_ELx寄存器定义内存属性,页表项中的字段设置可共享属性。这部分需要简要说明,但用户可能不需要太底层的细节,重点在概念和应用。 还要检查是否有常见的误解,比如可共享内存是否自动保证原子性,可能需要指出需要同步机制。同时,对比其他架构如x86的缓存一致性,强调ARMv8需要显式配置共享属性。 最后,整理结构,先介绍基本概念,再讲属性和类型,接着应用场景,注意事项,以及配置方法。确保语言通俗,避免过多术语,但保持准确性。</think>在ARMv8架构中,内存的共享属性内存管理的重要部分,尤其涉及多核处理器、DMA设备访问和缓存一致性时。以下是关于ARMv8可共享内存的逐步解析: --- ### 一、ARMv8内存属性基础 ARMv8定义了内存区域的**访问属性**,主要包括: 1. **普通内存 (Normal Memory)** - 可缓存(Cacheable)或不可缓存(Non-cacheable) - 可共享(Shareable)或非共享(Non-shareable) 2. **设备内存 (Device Memory)** - 用于外设寄存器访问,强制不可缓存且具有严格访问顺序 --- ### 二、可共享内存 (Shareable Memory) #### 1. 定义与作用 - **可共享内存**指该内存区域可能被多个处理器核(或设备)同时访问。 - **核心目的**:确保不同核或设备看到一致的内存视图,通过缓存一致性协议或软件管理实现。 #### 2. 共享类型 ARMv8定义了两种共享粒度: - **Inner Shareable** 在处理器集群(Cluster)内部共享,例如同一物理芯片上的多个CPU核。 - **Outer Shareable** 扩展到集群外部的组件(如GPU、DMA控制器等)。 --- ### 三、可共享内存的应用场景 1. **多核数据共享** 多核间共享数据时需标记为可共享,例如全局变量或通信缓冲区。 ```c // 示例:多核共享的计数器 volatile uint32_t __attribute__((aligned(64))) shared_counter; ``` 2. **设备与CPU交互** DMA设备访问的内存区域需标记为可共享,确保CPU和设备看到一致数据。 3. **缓存一致性维护** - Inner Shareable区域由硬件维护缓存一致性。 - Outer Shareable区域可能需要软件干预(如手动刷新缓存)。 --- ### 四、配置可共享内存 #### 1. 页表属性设置 通过ARMv8页表项中的**内存属性字段(MAIR)**定义: - **MAIR_ELx寄存器**:配置内存类型(如Normal/Device)和属性。 - **页表项中的AttrIndx**:选择MAIR中预定义的内存属性模板。 #### 2. 示例配置 配置一个可共享的普通内存区域(Write-Back缓存策略): ```assembly // MAIR_EL1配置:索引0对应Normal内存属性 MAIR_EL1 = 0xFF << 0 // Inner/Outer Write-Back, Shareable // 页表项设置 页表项.AttrIndx = 0 // 使用MAIR索引0 页表项.SH = 0b11 // Inner Shareable ``` --- ### 五、关键注意事项 1. **内存屏障指令** 在访问可共享内存前后,需使用屏障指令(如`DMB`, `DSB`)保证访问顺序。 ```c // 示例:写操作后插入屏障 *shared_ptr = value; asm volatile("dmb ish" ::: "memory"); ``` 2. **原子操作支持** ARMv8提供`LDXR/STXR`指令实现原子访问,适用于共享内存的同步。 3. **非一致性共享** Outer Shareable区域可能不保证硬件缓存一致性,需结合`cache维护操作`(如`DC CIVAC`)。 --- ### 六、与x86架构的对比 | 特性 | ARMv8 | x86 | |---------------------|--------------------------------|-----------------| | 缓存一致性范围 | 需显式配置Shareable属性 | 默认全局一致 | | 共享内存管理 | 更依赖软件屏障 | 硬件自动管理更多 | | DMA访问 | 通常需标记为Shareable+Non-cacheable | 通过Uncachable属性 | --- ### 七、总结 ARMv8的可共享内存机制通过灵活的内存属性配置,平衡了性能与一致性需求。开发中需根据场景选择: - 多核紧耦合通信 → Inner Shareable + Write-Back - 跨设备数据传输 → Outer Shareable + Non-cacheable - 关键共享数据 → 结合原子操作与内存屏障
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值