1. UHCI 控制器概述
1.1 UHCI 在 USB 体系中的位置
通用主机控制器接口(UHCI,Universal Host Controller Interface)是 Intel 公司为 USB 1.0/1.1 全速(12 Mbps)和低速(1.5 Mbps)传输定义的主机控制器硬件/软件接口规范。在 USB 主机端软件栈中,UHCI 控制器位于最底层,直接与 USB 总线交互,向上为操作系统提供统一的寄存器编程接口。
关键定位: UHCI 是 USB 主机控制器中唯一将大部分协议处理(如帧生成、SOF 令牌、位填充)交由软件(驱动程序)完成的规范,硬件仅负责最底层的串行引擎和 DMA 传输。
USB 主机端软件栈层次关系如下表所示:
| 层次 | 组件 | 职责 |
|---|---|---|
| 应用层 | USB 设备驱动 | 与具体 USB 设备功能交互(如 HID、大容量存储) |
| 总线层 | USB 核心(USB Core) | 设备枚举、地址分配、管道管理、标准请求处理 |
| 主机控制器层 | UHCI 驱动(uhci-hcd) | 帧列表管理、TD/QH 调度、寄存器编程、中断处理 |
| 硬件层 | UHCI 控制器(PCI 设备) | USB 总线信号、串行接口引擎(SIE)、DMA 传输 |
实战要点: UHCI 驱动需要直接操作 I/O 寄存器(而非 MMIO),且必须维护软件帧列表(Frame List)和队列头(QH)链表。这是 UHCI 性能调优的核心战场。
1.2 UHCI 与 OHCI / EHCI / xHCI 的区别
USB 主机控制器规范经历了四代演进,每一代在硬件/软件分工、传输速率、调度模型上都有本质差异。UHCI 是唯一采用“软件主导”调度模型的主流规范。
| 特性 | UHCI | OHCI | EHCI | xHCI |
|---|---|---|---|---|
| USB 版本 | USB 1.0/1.1 | USB 1.0/1.1 | USB 2.0 | USB 3.x / 4 |
| 速率 | 全速 12 Mbps 低速 1.5 Mbps |
全速 12 Mbps 低速 1.5 Mbps |
高速 480 Mbps | 超高速 5/10/20 Gbps |
| 协议处理 | 软件主导(驱动负责帧生成、SOF、位填充) | 硬件主导(硬件自动处理协议) | 硬件主导 | 硬件主导(事件环) |
| 调度模型 | 帧列表 + 队列头(QH)链表 | 中断端点列表 + 周期性列表 | 异步列表 + 周期性列表(微帧) | 环(Ring)结构 + 事件环 |
| 寄存器接口 | I/O 端口(0x60-0x6F 等) | MMIO | MMIO + 能力寄存器 | MMIO + 扩展能力 |
| DMA 传输 | 软件管理传输描述符(TD) | 硬件管理端点描述符(ED) | 硬件管理 iTD/siTD | TRB 环 |
| 主要厂商 | Intel | Compaq / Microsoft / National | Intel / 多家 | Intel / 多家 |
开发避坑: UHCI 的帧周期固定为 1 ms(1000 帧/秒),而 EHCI 引入微帧(125 µs)。在 UHCI 上做等时传输调度时,必须考虑软件帧列表的更新延迟,否则容易导致帧溢出或带宽浪费。
1.3 UHCI 的硬件架构框图
UHCI 控制器内部由以下核心模块构成,理解这些模块的协作关系是进行寄存器编程和性能调优的前提。
- PCI 配置空间: 标准 PCI 设备配置空间(Vendor ID、Device ID、Class Code、BAR 等),用于系统枚举和资源分配。
- I/O 寄存器组: 包括命令寄存器(USBCMD)、状态寄存器(USBSTS)、帧号寄存器(FRNUM)、帧基地址寄存器(FLBASEADD)、端口状态/控制寄存器(PORTSC)等。
- 帧列表(Frame List): 位于系统内存中的 1024 个 32 位指针数组,每个指针指向一个队列头(QH)或传输描述符(TD)链表。
- 串行接口引擎(SIE): 负责 USB 总线上的串行/并行转换、位填充/解填充、CRC 生成/校验、包检测等物理层处理。
- DMA 引擎: 通过 PCI 总线主控(Bus Master)从系统内存读取帧列表、QH、TD,并将数据写入内存。
- 根集线器(Root Hub): 集成在控制器内部,提供 2 个 USB 端口(通常),负责端口状态检测、复位、使能等。
性能调优关键: 帧列表的物理地址对齐(必须 4KB 对齐)、TD 链表的深度、中断延迟的优化,都直接影响 UHCI 的吞吐量。后续章节将逐一深入。
1.4 UHCI 核心寄存器一览
UHCI 控制器通过一组 I/O 寄存器暴露控制接口。以下是初始化阶段必须操作的寄存器:
| 偏移 | 寄存器名称 | 缩写 | 初始化关键位 |
|---|---|---|---|
| 0x00 | 命令寄存器 | USBCMD | RS(Run/Stop)、HCRESET(Host Controller Reset)、GRESET(Global Reset)、EG(Enable Global) |
| 0x02 | 状态寄存器 | USBSTS | HCHalted(主机控制器暂停)、HCPE(主机控制器错误)、RD(Resume Detect) |
| 0x04 | 中断使能寄存器 | USBINTR | OCIE(过流中断使能)、TOCRC(超时/CRC 使能)、IOC(完成中断使能) |
| 0x06 | 帧号寄存器 | FRNUM | 帧号(10 位),每帧硬件自动递增 |
| 0x08 | 帧基地址寄存器 | FLBASEADD | 帧列表物理基地址(4KB 对齐) |
| 0x0A | 帧修正寄存器 | FRMOD | 帧长度修正(默认 11936 位时钟) |
| 0x10-0x12 | 端口状态/控制寄存器 | PORTSC | PE(端口使能)、PED(端口使能改变)、LS(低速设备)、PR(端口复位) |
初始化顺序建议: 先 HCRESET 复位控制器 → 设置 FLBASEADD(帧列表基址)→ 配置 FRMOD(帧长度)→ 设置 USBINTR(中断使能)→ 最后置位 USBCMD.RS 启动运行。端口初始化在控制器启动后进行。