地址流、数据流、控制流与中断流¶
1. 为什么要按“流”分析¶
只看静态模块列表无法解释系统行为。同一个外设通常有独立的配置路径、数据路径和中断路径,并共享 Clock/Reset/Power 依赖。故障定位的核心是判断哪一条流断了。
本章用六种流描述系统:
- 指令流。
- 地址/事务流。
- 数据流。
- 控制流。
- 中断流。
- 时钟、复位和电源依赖流。
2. CPU 读取 DDR 变量¶
假设程序执行 value = *ptr,且 ptr 指向普通可缓存内存。
2.1 指令流¶
CPU 首先要取得执行这条 Load 指令本身:
2.2 数据地址流¶
Load 指令计算出 VA,MMU/TLB 将其转换为 PA,并检查权限和内存属性。TLB Miss 时还会由硬件或软件执行 Page Table Walk,而页表项本身也保存在内存层次中。
2.3 数据流¶
数据若命中 L1 D-Cache,访问很快结束;若 Miss,则请求向 L2、System Cache、NoC 和 DDR 传播,返回的 Cache Line 被填充后,CPU 取出所需字节。
2.4 可能的停顿点¶
- TLB Miss 或 Page Fault。
- Cache Miss、MSHR/Fill Buffer 已满。
- NoC 仲裁或 Backpressure。
- DDR Bank 冲突、Refresh 或低功耗退出。
- ECC 错误。
“Load 很慢”不等同于“DDR 很慢”,必须沿全路径测量。
3. CPU 写 MMIO 寄存器¶
假设 CPU 启动 DMA:
CPU Store 指令
→ MMU 将 VA 转为设备寄存器 PA
→ Store Buffer/内存顺序约束
→ AXI/NoC
→ Peripheral Bridge
→ DMA Register Bank
→ 写入 Doorbell/Start 位
→ DMA 状态机启动
关键差异:
- MMIO 必须使用适合设备的内存属性。
- 写入可能在 CPU 指令退休后才真正到达设备。
- Start/Doorbell 之前写入内存中的 Descriptor 必须先对设备可见。
- 某些寄存器写入后需读回或轮询状态,确保跨 Bridge 生效。
4. DMA 从外设接收数据¶
以 Ethernet RX 为例:
4.1 配置流¶
CPU
→ 配置 Clock/Reset/Pinmux/PHY
→ 分配 RX Buffer 和 Descriptor Ring
→ 将 Buffer 的 DMA 地址写入 Descriptor
→ 同步 Descriptor/Buffer 所有权
→ 配置 DMA Ring Base
→ 使能 MAC、DMA 和中断
4.2 数据流¶
4.3 完成与中断流¶
DMA 更新 Descriptor 状态
→ 设备置 Interrupt Status
→ 中断控制器记录 Pending
→ 路由到某 CPU
→ CPU 进入异常向量
→ 驱动读取状态并处理完成项
→ 同步 Buffer 所有权
→ 协议栈消费数据
→ 驱动补充 Buffer
4.4 三种常见“半通”状态¶
- 寄存器可配置但没有数据:配置流通,PHY/数据/DMA 流可能断。
- DDR 中有数据但没有 ISR:数据流通,中断状态、Mask、路由或 CPU 侧可能断。
- ISR 到达但 CPU 看见旧数据:中断流通,Cache 一致性或内存顺序可能错误。
5. UART 接收字符¶
UART 不使用 DMA 时:
Pad → Pinmux → UART RX Sampler → RX FIFO
→ IRQ Line → Interrupt Controller → CPU
→ ISR 读取 UART_DATA → 软件 Ring Buffer
依赖流:
如果 RX 状态位变化但 CPU 无中断,应优先检查 UART Interrupt Mask、原始/屏蔽状态、中断触发类型、控制器路由及 CPU 屏蔽位;如果 RX 状态完全不变,则优先检查 Pinmux、输入 Pad、Clock 和波特率。
6. CPU 异常流¶
CPU 访问非法地址时可能发生:
Load/Store
→ MMU 权限或翻译检查
→ 若通过则发往 NoC
→ NoC/Target 返回错误
→ CPU 将错误转换为同步异常
→ 保存异常返回地址和状态
→ 跳转异常向量
→ OS 记录 Fault Address/Status
→ 修复、终止进程或 Panic
要区分异常发生在 MMU 翻译阶段还是外部总线阶段。前者多检查页表,后者多检查 Address Map、Clock/Reset/Power 和 Firewall。
7. Boot 控制流¶
一个简化启动链:
POR/Reset
→ CPU 从规定地址取指
→ BootROM 读取 Strap/Fuse
→ 选择启动介质并验证第一阶段镜像
→ SPL 在片上 SRAM 运行
→ 配置 Clock/Pinmux/DDR
→ 将下一阶段加载到 DDR
→ 安全固件配置异常级和安全边界
→ Bootloader 加载 Kernel/DTB
→ Kernel 建立 MMU、内存和驱动模型
→ 启动用户空间
启动早期 DDR 尚不可用,代码、栈和数据必须位于 BootROM、SRAM 或处理器特殊存储中。DDR 初始化成功是系统从“芯片”走向“复杂软件平台”的关键边界。
8. 怎样把“设备不工作”缩小到一段路径¶
有效的故障树从最靠近 CPU 的已知点向外推进。每一步都要找一个能把路径分成前后两半的观察点,而不是一次读取几十个寄存器。
8.1 先证明配置通路可达¶
从模块的只读 ID、Version 或具有稳定复位值的寄存器开始。若访问直接触发 CPU Abort,应读取 Fault Address 和 Fault Status:翻译或权限 Fault 发生在 MMU 一侧,External Abort 则说明请求已经越过 MMU,问题更接近互联或 Target。若访问不异常却超时,按顺序检查 Address Map、Firewall、Power Good、Bus Clock 和 Reset。
只读回零并不能证明可达。默认错误 Target、掉电域的隔离钳位和真正的复位值都可能是零。更可靠的方法是读取两个具有不同固定值的寄存器,或对一个无副作用的 RW 字段写入特征值并读回。
8.2 再证明模块具备运行条件¶
MMIO 可达之后,核对 Power、功能 Clock、Reset、Pinmux 和 PHY。这里要利用现象区分层次:核心 Clock 未开时,Enable 位可能可以写入,但 Busy/FIFO 指针永远不动;Pinmux 错误时,内部 FIFO 和状态机会工作,封装引脚却没有波形;PHY 未锁定时,Controller 往往会给出独立的 Link/PLL 错误。
8.3 找到数据停止移动的位置¶
数据路径上的 FIFO Level、Descriptor Consumer Index、DMA Active、NoC Transaction Counter 和 DDR Write Counter 是一系列观察点。以接收路径为例:外设 RX Counter 增长而 FIFO 不变,问题在协议接收或过滤;FIFO 增长而 DMA Index 不动,问题在 DMA 配置;DMA Index 前进而 DDR Counter 不变,检查 SMMU、Firewall 和 NoC;DDR 已被写入而上层没有数据,则转向一致性、Descriptor 和软件队列。
这种定位方法的价值在于,每个计数器都给出一个边界。计数器本身不能说明根因,但能排除边界之前已经正常的环节。
8.4 把中断路径单独验证¶
先读设备 Raw Interrupt Status。Raw 位未置位,说明设备尚未满足中断条件;Raw 已置位而 Masked Status 未置位,说明设备内部 Mask 或 Enable 配错;设备 Masked Status 有效而 GIC/PLIC 不 Pending,问题位于中断连线、触发类型或控制器配置;控制器已 Pending 而目标 CPU 不进 ISR,则检查路由、优先级、CPU 屏蔽位和当前异常级。
对于电平中断,设备状态在服务完成前通常必须保持有效。ISR 若只在控制器执行 EOI,却没有清除设备源,中断会立刻重新触发,形成中断风暴。边沿中断的风险相反:在控制器尚未启用时出现的短脉冲,若中间没有锁存,可能永久丢失。
8.5 最后检查软件是否正确消费结果¶
ISR 到达只证明通知路径工作。驱动还要按协议读取完成状态、转换 Descriptor 所有权、执行 DMA 同步,并将数据交给上层。若硬件 Producer Index 增长而软件 Consumer Index 不动,查看驱动循环退出条件;若两者都增长而业务仍无数据,检查上层队列和过滤逻辑。对于共享内存,再验证 Barrier 是否把“先写数据、后发布状态”的顺序传递到了观察者。
最终的故障记录应写成结论,例如“DMA 已消费 Descriptor,但 SMMU 在 IOVA 0x... 报 Translation Fault”,而不是“检查过 DMA、SMMU 和内存”。前一种记录给出了故障边界,后一种没有。
9. 一张实用的系统路径记录表¶
| 维度 | 内容示例 |
|---|---|
| Initiator | Ethernet DMA,Stream ID 0x21 |
| 地址 | IOVA 0x8200_0000,转换至 PA 0x4A00_0000 |
| 路径 | MAC → SMMU → NoC → DDRC0 |
| 属性 | Non-secure、Write、Outer Shareable |
| 一致性 | 非一致,需要 DMA API 同步 |
| Clock | MAC 250 MHz、AXI 400 MHz、PHY Ref 125 MHz |
| Reset | MAC、DMA、PHY 三路 Reset |
| Power | PD_NET,可独立关断 |
| 中断 | SPI 96,Level-high,Affinity CPU2 |
| 观察点 | DMA Status、SMMU Fault、NoC Counter、IRQ Pending |
对复杂问题填完这张表,往往就能暴露缺失的配置或错误假设。