寄存器编程优化UHCI控制器初始化阶段的DMA描述符管理 - 第1节
1.1 UHCI 在 USB 系统中的位置
通用主机控制器接口(UHCI, Universal Host Controller Interface)是 Intel 制定的 USB 1.1 全速/低速主机控制器标准。在 x86 平台 USB 子系统中,UHCI 控制器位于软件栈与硬件传输层之间,承担着将操作系统 USB 请求块(URB)转换为帧级事务处理的核心职责。
关键定位: UHCI 是 PCI 多功能设备,通常与 EHCI(USB 2.0)控制器配对,形成“companion controller”架构。UHCI 负责全速(12 Mbps)和低速(1.5 Mbps)传输,EHCI 负责高速(480 Mbps)传输。
1.2 UHCI 寄存器空间布局
UHCI 控制器通过 PCI 配置空间暴露一组 I/O 映射的寄存器。基地址由 PCI 配置空间的 BAR0(偏移 0x20)提供,寄存器空间总长度为 32 字节。所有寄存器均为 8/16/32 位宽,必须使用 I/O 指令(in/out)访问。
| 偏移地址 | 寄存器名称 | 位宽 | 描述 |
|---|---|---|---|
| 0x00 | USBCMD | 16-bit | 主机控制器命令寄存器(运行/停止/全局复位/帧列表长度) |
| 0x02 | USBSTS | 16-bit | 主机控制器状态寄存器(HCHalted、PCI Interrupt、Error 等) |
| 0x04 | USBINTR | 16-bit | 中断使能寄存器 |
| 0x06 | FRNUM | 16-bit | 帧号寄存器(当前帧计数器,每 1 ms 递增) |
| 0x08 | FLBASEADD | 32-bit | 帧列表基地址寄存器(4 KB 对齐的物理地址) |
| 0x0C | SOF | 8-bit | 帧起始调节寄存器(SOF 时序微调) |
| 0x10 | PORTSC1 | 16-bit | 端口状态/控制寄存器(端口 1) |
| 0x12 | PORTSC2 | 16-bit | 端口状态/控制寄存器(端口 2) |
初始化关键寄存器: USBCMD(0x00)的 Bit 2 控制帧列表长度(1024 或 256 项);FLBASEADD(0x08)必须指向 4 KB 对齐的物理内存区域,该区域存储帧列表指针数组。
1.3 DMA 描述符的作用
UHCI 使用两种类型的 DMA 描述符来实现 USB 事务调度:传输描述符(TD, Transfer Descriptor) 和 队列头(QH, Queue Head)。描述符位于系统主存中,控制器通过 PCI 总线直接读取,无需 CPU 逐字节搬运数据。
1.3.1 传输描述符(TD)结构
每个 TD 长度为 32 字节(4 个 64-bit 双字),包含以下关键字段:
| 双字偏移 | 位域 | 描述 |
|---|---|---|
| DW0 (0x00) | Link Pointer (32-bit) + 控制位 | 指向下一个 TD 或 QH 的物理地址;Vf=1 表示有效,Qf=1 表示指向 QH |
| DW1 (0x04) | 控制/状态 (32-bit) | 包含 PID(IN/OUT/SETUP)、数据切换(Data Toggle)、错误计数、SPD、IOC 等 |
| DW2 (0x08) | Buffer Pointer (32-bit) | 数据缓冲区物理地址(必须 4 字节对齐) |
| DW3 (0x0C) | 保留 / 扩展 | UHCI 规范保留,驱动可自定义使用 |
对齐要求: TD 必须 16 字节对齐(物理地址低 4 位为 0);数据缓冲区必须 4 字节对齐。违反对齐会导致控制器 DMA 错误(USBSTS 寄存器中的 HCHalted 位置位)。
1.3.2 队列头(QH)结构
QH 长度为 16 字节(2 个 64-bit 双字),作为 TD 链表的入口点:
- DW0: 水平链接指针(Horizontal Link Pointer),指向下一个 QH 或 TD,形成帧级调度环。
- DW1: 垂直链接指针(Vertical Link Pointer),指向该端点对应的第一个 TD,形成事务队列。
1.3.3 描述符管理的关键寄存器编程
初始化阶段,驱动必须完成以下寄存器编程步骤:
- 分配帧列表内存: 4 KB 物理连续内存,地址 4 KB 对齐。
- 写入 FLBASEADD: 将帧列表物理地址写入 0x08 寄存器。
- 设置帧列表长度: 在 USBCMD 寄存器 Bit 2 写入 0(1024 项)或 1(256 项)。
- 初始化帧列表项: 每个帧列表项写入指向第一个 QH 的物理地址(Vf=1, Qf=1)。
- 创建 QH 和 TD: 在系统内存中分配并初始化描述符,设置链接指针。
- 设置 USBCMD 的 Run/Stop 位: Bit 0 写 1 启动控制器。
优化切入点: 描述符的分配、对齐、链接指针写入和缓存一致性维护是初始化阶段的主要开销。后续章节将深入分析如何通过寄存器批量编程、预分配描述符池和写合并(Write-Combining)技术减少初始化延迟。