AXI-5.3.2~5.3.5
5.3.2 不匹配的内存属性
在一个典型的 SoC 中,多个主设备(如 CPU、GPU、DMA 控制器)可能需要访问同一块物理内存。由于这些主设备由不同的驱动或程序控制,它们可能会为同一内存区域设置不同的 AxCACHE 属性。协议允许这种不匹配,但为确保功能正确,设定了明确的边界。
让我们通过具体场景来理解这些规则:
规则一:缓存性必须一致
-
规则:所有访问同一内存区域的主设备必须在该区域是 可缓存 还是 不可缓存 上达成一致。
-
非缓存区域:所有主设备必须使用
AxCACHE[3:2] = 0b00的事务。 -
可缓存区域:所有主设备必须使用
AxCACHE[3:2]至少有一位被置起的事务。
-
-
举例:一片内存被配置为 DMA 缓冲区,在 CPU 和网络控制器之间共享。
-
正确做法:CPU 和 DMA 控制器都应将该区域标记为
Normal Non-cacheable(AxCACHE[3:2]=0b00)。这样,CPU 的写入会直接进入主内存,DMA 控制器总能读到最新数据;DMA 的写入也能被 CPU 直接看到。 -
错误做法及后果:如果 CPU 错误地将其标记为
Write-Back(AxCACHE[3:2]=0b11),那么它写入的数据可能会长时间停留在自己的缓存中。当 DMA 控制器从主内存读取数据时,得到的是旧值,导致数据不一致和功能错误。
-
规则二:分配提示可以不同
-
规则:不同的主设备可以使用不同的分配建议(
Allocate和Other Allocate位)。 -
举例:一片可缓存的内存区域,存储着游戏引擎的纹理数据。
-
GPU 的核心工作是渲染,它会频繁读写纹理。因此,GPU 可能使用
Write-Back Read and Write-Allocate,积极地将纹理保留在缓存中以获得最高性能。 -
CPU 可能偶尔需要读取纹理数据进行物理计算或网络同步,但不会频繁修改。因此,CPU 可能使用
Write-Back Read-Allocate,建议只在读取时分配缓存行,避免不必要的缓存占用。 -
结果:系统仍能正常工作,因为缓存性基础一致。每个主设备根据自身的最佳策略来使用缓存,提升了整体效率。
-
规则三:可用更严格的设备事务访问普通非缓存内存
-
规则:如果一个地址区域是
Normal Non-cacheable,任何主设备都可以使用Device内存事务来访问它。 -
举例:一段普通的
Normal Non-cacheable Bufferable内存,用于通用数据共享。-
行为:一个特别谨慎或需要强保证的驱动,可以临时使用
Device Non-bufferable属性来执行一次写入。 -
效果:这次写入将遵循最严格的规则——不可缓冲、不可修改、响应来自最终目的地。这相当于在普通操作中插入了一个内存屏障,确保了此次写入在它返回时已对全局可见。虽然性能较低,但用于同步点或关键标志的更新时,能保证正确性。
-
规则四:可用非缓冲事务访问可缓冲区域
-
规则:如果一个地址区域具有
Bufferable属性,任何主设备都可以使用不允许缓冲行为的事务(即Non-bufferable)来访问它。 -
举例:一片内存被主要标记为
Normal Non-cacheable Bufferable,以提升普通写入性能。-
行为:当 DMA 控制器需要启动一次传输,并必须确保之前所有CPU的写入都已到位时,它可以在启动命令前,使用一个
Normal Non-cacheable Non-bufferable的事务来写入DMA的控制寄存器(或一个标志位)。 -
效果:这个
Non-bufferable的写入会强制穿透所有写缓冲区,确保在其完成时,之前所有Bufferable写入的数据都已到达内存。之后,DMA 控制器可以安全地开始传输,因为它知道所有数据都已就绪。
-
这些规则的核心目的是在 灵活性 和 正确性 之间建立一道坚固的防线。
-
保证数据一致性的基石
-
规则一 是绝对底线。缓存性与否决定了数据在系统中的存在形式(是单一副本还是有多个副本)。在这个根本问题上不允许分歧,否则整个内存一致性模型都会崩溃。
-
-
允许性能优化的灵活性
-
规则二 承认了不同主设备有不同的工作负载和优化目标。允许分配提示不同,使得每个组件都能在不破坏一致性的前提下,根据自身情况微调性能。
-
-
提供安全强化的后门
-
规则三和规则四 是重要的安全网。它们允许软件在需要的时候,通过使用更严格、更保守的属性来“收紧缰绳”,强制实现强内存序和即时可见性。这对于实现同步原语、驱动中的关键操作以及调试都至关重要。
-
这些规则的诞生,是复杂 SoC 设计实践中经验和教训的总结。
-
异构计算的现实
-
现代 SoC 是真正的异构系统,包含不同架构的 CPU、GPU、DSP 和各类加速器。
-
背景:这些组件可能运行不同的操作系统、驱动,甚至有自己对内存属性的默认配置。无法强求所有组件对每一块内存的属性配置完全一致。
-
解决方案:协议必须定义一个最低限度的、必须遵守的规则集(如缓存性必须一致),同时允许在其他方面存在差异。这使得集成不同来源的 IP 核成为可能。
-
-
对“内存属性不匹配”错误的反思
-
在早期设计中,由于内存属性不匹配导致的间歇性数据错误非常难以调试。
<
-
