2. DMA基础回顾:DMA工作原理、总线主控模式、UHCI中的DMA角色

在深入UHCI控制器初始化阶段的DMA传输优化之前,必须重新夯实DMA(Direct Memory Access,直接存储器访问)的核心原理。UHCI作为PCI总线上的主控设备,其DMA操作并非传统的“外设→内存”搬运,而是总线主控模式(Bus Mastering)下的自主传输。本节将拆解DMA的底层机制,并明确UHCI在USB传输中的DMA角色定位。

2.1 DMA工作原理:从CPU搬运到总线主控

传统I/O操作中,CPU必须逐字节或逐字地从外设读取数据并写入内存(PIO模式),这会严重占用CPU时间。DMA控制器(DMAC)或具备DMA能力的设备接管了数据总线的控制权,实现内存与外设之间的直接数据传输。

核心要点: DMA传输的本质是总线仲裁——DMA设备向CPU请求总线控制权,CPU在总线周期内释放总线,DMA设备成为总线主控,完成数据传输后释放总线。

下图展示了标准DMA传输的典型流程,包含请求、仲裁、传输和结束四个阶段:

DMA传输典型流程(非UHCI通用模型) CPU 总线仲裁器 DMA控制器 (DMAC) 系统内存 数据缓冲区 I/O外设 (磁盘/网卡) ① 总线请求 (HOLD) ② 总线授权 (HLDA) ③ 内存读 (源地址) ④ 外设写 (目标地址) 说明:传统DMA由专用DMAC控制,UHCI则直接作为PCI总线主控,无需独立DMAC,由UHCI内部的状态机直接驱动总线周期。
关键区别: 传统DMA需要独立的DMA控制器芯片(如Intel 8237),而UHCI将DMA引擎集成在控制器内部。UHCI通过PCI总线接口直接发起内存读写,不需要CPU或外部DMAC介入地址生成。

2.2 总线主控模式:UHCI的DMA实现基础

UHCI控制器工作在PCI总线主控(Bus Master)模式下。这意味着UHCI可以主动发起PCI总线周期,直接读写系统内存,而无需依赖CPU或南桥中的DMA控制器。这是UHCI实现高效USB传输的基石。

下表对比了三种常见的I/O数据传输模式:

特性 PIO (Programmed I/O) 传统DMA (Third-party DMA) 总线主控DMA (Bus Mastering)
控制方 CPU 专用DMAC 外设/控制器自身
总线仲裁 CPU独占 CPU→DMAC CPU→外设
数据传输路径 外设→CPU→内存 外设↔内存 (DMAC控制) 外设↔内存 (外设控制)
CPU负载 高(逐字节搬运) 低(仅初始化) 极低(仅提交描述符)
UHCI使用情况 不使用 不使用 标准模式

UHCI作为总线主控设备,其DMA操作的核心是描述符链表(Descriptor List)。UHCI通过读取内存中的帧列表(Frame List)和传输描述符(TD, Transfer Descriptor),自主决定何时发起DMA传输、传输多少数据、数据去向何处。

常见误解: 很多人认为UHCI的DMA是“USB数据直接进入内存”。实际上,UHCI的DMA传输的是描述符和缓冲区指针,而非USB数据本身。真正的USB数据包(SOF、令牌、数据、握手)由UHCI内部的SIE(串行接口引擎)通过UTMI总线收发,UHCI再通过DMA将数据从FIFO搬运到系统内存。

2.3 UHCI中的DMA角色:从帧列表到传输描述符

在UHCI架构中,DMA承担了三个关键角色:

  1. 帧列表读取器: 每1ms(1帧),UHCI通过DMA从内存中的帧列表(Frame List)读取当前帧的起始指针,指向一个传输描述符链表。
  2. 描述符遍历器: UHCI通过DMA依次读取链表中的TD,解析出传输方向(IN/OUT)、数据缓冲区地址、数据长度、PID类型等关键信息。
  3. 数据搬运工: 对于OUT传输,UHCI通过DMA从系统内存读取数据到内部FIFO;对于IN传输,UHCI通过DMA将FIFO中的数据写入系统内存。

下图展示了UHCI内部DMA引擎与系统内存、USB总线之间的数据流关系:

UHCI控制器DMA角色与数据流架构 系统内存 (System Memory) 帧列表 Frame List (1024项) 每项4字节,指向TD链表 传输描述符链表 TD (Transfer Descriptor) 水平/垂直链接 数据缓冲区 Data Buffer (最大1024字节) 由TD中的Buffer Pointer指向 UHCI控制器 (内部) DMA引擎 总线主控状态机 帧列表基址寄存器 (FLBASEADD) SIE 串行接口引擎 内部FIFO (64字节) USB总线 USB设备 (端点0~15) ① DMA读帧列表 ② DMA读TD ③ DMA读写数据 ④ USB包传输 说明:UHCI的DMA引擎负责①②③,SIE负责④。DMA不直接操作USB总线,而是为SIE准备数据。

2.4 UHCI DMA的关键特性与优化切入点

理解UHCI的DMA角色后,可以提炼出以下关键特性,这些特性直接决定了初始化阶段的优化策略:

  • 描述符驱动: UHCI不直接执行程序,而是通过遍历内存中的TD链表来驱动传输。链表的组织方式(水平链接 vs 垂直链接)直接影响DMA效率。
  • 非连续DMA: UHCI的DMA传输是非连续的——每传输一个TD,UHCI需要重新读取下一个TD的指针,这导致总线利用率不如块设备DMA。
  • 帧同步: UHCI的DMA操作以帧(1ms)为周期同步。帧列表的读取发生在每帧开始时的SOF(Start of Frame)时刻。
  • 小数据量传输: USB全速(12Mbps)下,每个TD最大传输1024字节。对于控制传输(Setup阶段),数据量通常只有8字节。频繁的小DMA传输是性能瓶颈。
优化启示: 在初始化阶段,我们需要关注:
• 帧列表的对齐与缓存行填充(避免DMA读取跨越缓存行)
• TD链表的预构建与缓存一致性维护(避免DMA读到脏数据)
• 描述符的内存布局(减少DMA读取次数)
• 中断与DMA完成信号的同步(避免忙等)

2.5 小结:UHCI DMA的“三权分立”

UHCI的DMA体系可以概括为“三权分立”的协作模型:

角色 负责内容 DMA操作 优化关注点
帧列表管理器 维护1024项的帧列表,每项指向TD链表头 每帧开始DMA读取帧列表项 帧列表对齐、预取
TD解析器 遍历TD链表,解析传输参数 顺序DMA读取TD TD内存布局、链表深度
数据搬运器 在FIFO与系统内存之间搬运USB数据 DMA读写数据缓冲区 缓冲区对齐、Cache策略