• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

内存类型device Non-bufferablex详解

好的,我们来详细解释 AXI 协议中的 Device Non-cacheable 属性。这是一个非常关键的概念,尤其在与硬件外设(如寄存器、DMA 缓冲区)打交道时至关重要。

核心思想

Device Non-cacheable 是一种内存类型属性,它告诉系统互联结构和处理器:“这次访问的目标是内存映射的设备(如硬件寄存器),而不是普通的内存。因此,你必须严格按照我的指令来访问,不能做任何可能改变访问行为或顺序的优化。”

为了理解它,我们首先要看 AXI 协议如何定义内存属性。


AXI 协议中的内存属性:AxCACHE 信号

在 AXI 协议中,每次读或写事务都会有一组信号来定义其内存属性。最关键的是 AxCACHE[3:0] 信号(ARACHE 用于读,AWCACHE 用于写)。这 4 个比特位定义了事务的缓存和缓冲特性。

AxCACHE 信号的四个位分别是:

  1. [0] - Bufferable (B)
  2. [1] - Cacheable (C)
  3. [2] - Read-Allocate (RA)
  4. [3] - Write-Allocate (WA)

不同的位组合定义了不同的内存类型。Device Non-cacheable 是其中的一种特定组合。


Device Non-cacheable 的具体含义

通常,Device Non-cacheable 对应于 AxCACHE = 4'b0000(即 Bufferable=0, Cacheable=0, Read-Allocate=0, Write-Allocate=0)。

让我们分解这个配置的含义:

  1. Non-cacheable (C=0)

    • 最重要的一点:该事务不能通过缓存(Cache)来完成。
    • 处理器核心必须直接向最终的目标地址发起访问,绝对不能从缓存中读取数据,也绝对不能将数据只写入缓存就结束。
    • 对于读操作,必须从设备/内存中读取最新值。
    • 对于写操作,必须将数据最终写入设备/内存。
  2. Non-bufferable (B=0)

    • 强调写入的完成确认:一个写事务只有在它真正到达最终的外设设备并被其接受后,才能返回“完成”信号(BRESP/RRESP)给发起者(如 CPU)。
    • 中间不能有写缓冲区(Write Buffer)暂存数据并提前返回完成信号。发起者需要确切地知道写操作是否被设备成功执行。
  3. Non-allocate (RA=0, WA=0)

    • 这次访问绝不会导致缓存行分配(Cache Line Allocation)。因为本身就不是 Cacheable 的,所以自然不会分配。

为什么需要这种属性?(关键特性)

当你访问一个内存映射的设备(例如 UART 的数据寄存器、GPIO 的控制寄存器、中断控制器等)时,你必须遵守两条铁律:

  1. 副作用(Side Effects):

    • 对设备的每一次读写都可能具有不可重复的副作用。
    • 读操作:读取一个 UART 的接收数据寄存器,每读一次,硬件可能就会将“数据已就绪”的标志位清零。如果你第一次读操作被缓存了,后续的读操作直接从缓存返回旧数据,你就永远无法读到新的数据,并且硬件状态也会错乱。
    • 写操作:向一个设备控制寄存器写入“启动”和“停止”命令。如果这两个写操作被缓冲或重排序,可能会导致“停止”先于“启动”到达设备,使得设备无法正常工作。
  2. 严格有序(Strict Ordering):

    • 对设备的访问顺序必须与程序发出的顺序严格一致。编译器或处理器的重排序优化会彻底破坏设备驱动程序的控制流。
    • 例如,必须先配置设备寄存器 A,再配置寄存器 B。如果写操作 B 先于 A 到达设备,设备可能无法初始化。

Device Non-cacheable (AxCACHE=0000) 的设置正是为了满足这些苛刻要求:

  • 禁止缓存:确保每次访问都直接“戳到”硬件设备,避免副作用的重复或丢失。
  • 禁止缓冲:确保写操作完成的确认信号意味着数据已被设备真正接收,驱动程序可以可靠地检查设备状态或发起下一次操作。
  • 隐含的强序:虽然 AXI 协议本身允许事务乱序完成,但对于 Non-bufferable 的访问,系统互联通常会将它们视为强有序的,或者会确保对同一设备的访问保持程序顺序,以满足设备驱动的期望。

与其他内存类型的对比

内存类型 典型 AxCACHE 值 用途 缓存 缓冲 分配
Device Non-cacheable 4‘b0000 设备寄存器 否 否 否
Normal Non-cacheable 4‘b0001 不需要缓存但可缓冲的内存区域(如 DMA 缓冲区) 否 是 否
Write-Back Cacheable 4‘b1111 普通系统内存(如程序堆栈) 是 是 是
Write-Through Cacheable 4‘b1011 需要缓存且写操作需同时更新内存的区域 是 是 是

重要区别:Device vs Normal Non-cacheable

  • 两者都是 Non-cacheable。
  • 关键区别在于 Bufferable 位。
    • Device (B=0): 用于有副作用、对顺序敏感的设备访问。必须等待最终完成。
    • Normal Non-cacheable (B=1): 用于无副作用的内存访问(例如,一块标记为 non-cacheable 的 DMA 缓冲区)。写入可以先进写缓冲区,处理器可以继续执行,无需等待写入最终完成,提高了效率。

软件视角:如何设置?

在软件中,特别是在编写驱动程序或设置 MMU(内存管理单元)时,程序员需要为设备寄存器的内存映射区域配置正确的页表属性。

在 ARM 架构中,这通常意味着在页表描述符中设置:

  • Memory Type:
    • Device 或 Strongly-ordered(这两种类型对应到 AXI 上基本都是 Device Non-cacheable 行为,Strongly-ordered 的要求甚至更严格)。
  • Shareability:
    • 通常设置为 Outer Shareable 或 Global,以确保不同核心(或其它主机,如 DMA)对设备的访问是相互可见和有序的。

例如,在 Linux 内核中,用 ioremap() 函数来映射设备寄存器时,内核会自动将其映射为 Device Non-cacheable 类型。而你用 dma_alloc_coherent() 分配 DMA 缓冲区时,它可能会被映射为 Normal Non-cacheable。

总结

  • 是什么: Device Non-cacheable 是 AXI 协议中一种关键的内存事务属性,配置为 AxCACHE = 0b0000(Non-bufferable, Non-cacheable)。
  • 为什么: 它是为访问内存映射的设备寄存器而设计的,这些访问具有副作用和严格的顺序要求。
  • 做什么: 它强制每次访问都直达设备,并且写操作必须等待设备的最终确认,从而确保软件可以精确地控制硬件状态。
  • 在哪用: 所有设备驱动程序的开发都依赖于正确设置此属性,通常由操作系统内核在映射设备地址空间时自动完成。

简单来说,Device Non-cacheable 是处理器与硬件设备之间一种“简单、直接、可靠”的通信方式,避免了任何可能引起歧义的优化手段。

posted on 2025-09-15 21:51  SOC验证工程师  阅读(12)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3