2. UHCI 主控制器寄存器模型详解

UHCI(Universal Host Controller Interface)主控制器通过一组 PCI 基地址寄存器(Base Address Register, BAR) 映射到系统内存或 I/O 空间。驱动开发者必须精确理解每个寄存器的位定义、访问时序和复位状态,才能正确初始化控制器、调度传输帧和处理中断。本节将逐一剖析 UHCI 寄存器布局中的关键寄存器。

2.1 寄存器整体布局与基地址

UHCI 主控制器占用 32 字节连续的 I/O 空间(或内存映射空间),起始地址由 PCI 配置空间中的 BAR0 提供。驱动在枚举 PCI 设备时读取 BAR0,获取基地址后即可通过 inl/outl(I/O 空间)或 ioread32/iowrite32(内存映射)访问所有寄存器。

关键点: UHCI 寄存器全部为 32 位宽,但部分寄存器仅低 16 位有效。访问时务必使用 32 位读写指令,避免未定义行为。
UHCI 寄存器偏移地址与功能总览
偏移地址 寄存器名称 缩写 复位值 主要功能
0x00 USB 命令寄存器 USBCMD 0x0000 0020 启动/停止主机控制器、全局复位、帧列表大小配置
0x02 USB 状态寄存器 USBSTS 0x0000 0000 主机控制器当前状态、中断挂起、错误指示
0x04 USB 中断使能寄存器 USBINTR 0x0000 0000 使能/屏蔽各类中断源
0x06 帧号寄存器 FRNUM 0x0000 0000 当前帧号(0~1023),每 1 ms 递增
0x08 帧列表基地址寄存器 FLBASEADD 0x0000 0000 帧列表在系统内存中的 4 KB 对齐基地址
0x0C 起始帧修正寄存器 SOF 0x0000 0040 调整 SOF 包发送时机,微调帧起始位置
0x10–0x1F 端口状态与控制寄存器 PORTSC[0..1] 0x0000 0080 每个端口一个,控制连接检测、复位、使能、挂起
调试提示: 在 Linux 下使用 lspci -vvv -s <bus:dev.func> 查看 UHCI 控制器的 BAR0 地址,然后通过 cat /proc/ioports 确认 I/O 空间是否已被 uhci_hcd 驱动占用。
UHCI 寄存器布局与系统内存映射关系 UHCI 寄存器布局与系统内存映射关系 PCI UHCI 控制器 BAR0 I/O 空间 (32 字节) USBCMD / USBSTS / USBINTR / FRNUM 寄存器偏移 0x00: USBCMD 0x02: USBSTS 0x04: USBINTR 0x06: FRNUM 0x08: FLBASEADD FLBASEADD 系统内存 帧列表 (Frame List) 帧列表项 (1024 项) Frame 0: TDPtr Frame 1: TDPtr ... Frame 1023: TDPtr PORTSC[0..1] 说明:UHCI 通过 FLBASEADD 寄存器指向系统内存中的帧列表,帧列表项指向传输描述符(TD)链表,实现批量/中断/控制传输的调度。

2.2 USBCMD — USB 命令寄存器(偏移 0x00)

USBCMD 是驱动控制主机控制器的核心寄存器。驱动通过写入该寄存器启动/停止控制器、触发全局复位、配置帧列表大小。

USBCMD 寄存器位域定义
位域 名称 描述
Bit 0 RS (Run/Stop) 1 = 运行;0 = 停止。停止后控制器不再处理帧列表。
Bit 1 HCRESET (Host Controller Reset) 写 1 触发软件复位,复位后自动清零。复位所有寄存器(除 FLBASEADD 和 SOF 外)到默认值。
Bit 2 GRESET (Global Reset) 写 1 触发 USB 总线全局复位(至少 10 ms),复位后自动清零。
Bit 3 EGSM (Enter Global Suspend Mode) 1 = 进入全局挂起模式;0 = 正常。用于电源管理。
Bit 4 FGR (Force Global Resume) 写 1 强制全局恢复,用于从挂起中唤醒。
Bit 5 SWDBG (Software Debug) 1 = 使能软件调试模式(保留位,建议写 0)。
Bit 6 CF (Configure Flag) 驱动配置完成后置 1,表示端口路由逻辑已配置。主机控制器据此开始处理端口事件。
Bit 7 MAXP (Max Packet) 0 = 64 字节;1 = 32 字节。控制批量/中断传输的最大包长。
驱动开发陷阱: 在写入 RS=1 启动控制器之前,必须确保 FLBASEADD 已指向有效的帧列表内存,且帧列表项已初始化。否则控制器可能立即访问非法地址,导致 PCI 总线错误(Master Abort)。

2.3 USBSTS — USB 状态寄存器(偏移 0x02)

USBSTS 反映主机控制器的实时状态和中断事件。驱动在中断服务例程(ISR)中读取该寄存器判断中断原因,并在处理完成后写 1 清除对应位。

USBSTS 寄存器位域定义
位域 名称 描述
Bit 0 UI (USB Interrupt) 1 = 有中断挂起。由 USBINTR 使能的中断源触发。
Bit 1 UEI (USB Error Interrupt) 1 = 发生传输错误(如 CRC、超时、Babble)。
Bit 2 PCI (Port Change Interrupt) 1 = 端口状态发生变化(连接/断开/使能/挂起改变)。
Bit 3 RI (Resume Interrupt) 1 = 检测到远程唤醒信号。
Bit 4 HCH (Host Controller Halted) 1 = 控制器已停止(RS=0 且内部状态机空闲)。
Bit 5 HCPE (Host Controller Process Error) 1 = 主机控制器内部处理错误(通常不可恢复)。
Bit 6–15 Reserved 保留位,读返回 0。
调试技巧: 在 ISR 中先读取 USBSTS 保存到局部变量,然后立即写回该值清除中断位。这样可以避免在清除过程中丢失新到达的中断。Linux 内核中的 uhci_irq() 函数正是采用此模式。
USBSTS 中断处理流程 USBSTS 中断处理流程 中断发生 读取 USBSTS 判断中断源 UI: 传输完成 UEI: 传输错误 PCI: 端口变化 写回 USBSTS 清除 注意:写回清除操作必须使用读取到的原值,不能直接写 0xFFFF,否则可能清除未处理的中断。

2.4 USBINTR — 中断使能寄存器(偏移 0x04)

USBINTR 控制哪些 USBSTS 状态位能够产生中断信号。驱动在初始化阶段根据需求使能对应中断源。

USBINTR 位域与对应中断源
位域 名称 对应 USBSTS 位 描述
Bit 0 IUE (Interrupt Enable) UI 使能传输完成中断
Bit 1 IE (Error Interrupt Enable) UEI 使能传输错误中断
Bit 2 IPC (Port Change Interrupt Enable) PCI 使能端口变化中断
Bit 3 IR (Resume Interrupt Enable) RI 使能远程唤醒中断
Bit 4–15 Reserved — 保留位,写 0
推荐配置: 在批量传输与中断处理协同调试场景下,建议使能 IUE(传输完成)和 IPC(端口变化)中断。UEI 可在调试阶段使能,生产环境视情况关闭以减少不必要的 ISR 开销。

2.5 FRNUM — 帧号寄存器(偏移 0x06)

FRNUM 是一个 10 位计数器(Bit 0–9),每 1 ms 递增一次,值范围 0–1023。主机控制器使用帧号索引帧列表,决定当前帧要处理的传输描述符链表。

  • 只读属性: 驱动只能读取 FRNUM,不能写入。写入操作被硬件忽略。
  • 与帧列表的关系: 帧列表包含 1024 个表项,FRNUM 的低 10 位作为索引,选择当前帧对应的帧列表项。
  • 调试用途: 驱动可通过轮询 FRNUM 判断帧是否推进,验证控制器是否正常运行。如果 FRNUM 长时间不变,说明控制器可能挂起或未启动。
性能指标: 帧周期为 1 ms,因此 FRNUM 每 1.024 秒循环一次。驱动可以利用帧号实现简单的定时器,精度为 1 ms。

2.6 FLBASEADD — 帧列表基地址寄存器(偏移 0x08)

FLBASEADD 存储帧列表在系统物理内存中的起始地址。帧列表必须 4 KB 对齐(即地址低 12 位为 0),因为帧列表包含 1024 个 4 字节的表项,正好占用 4 KB。

FLBASEADD 位域定义
位域 描述
Bit 31:12 帧列表基地址(高 20 位),对应物理地址的 [31:12]
Bit 11:0 保留位,必须写 0。硬件忽略低 12 位,强制 4 KB 对齐。
内存分配注意事项: 帧列表内存必须使用 dma_alloc_coherent() 分配,确保物理地址连续且不被 CPU 缓存干扰。在 32 位系统上,地址可能超过 4 GB,需确认 DMA 掩码设置正确。

2.7 SOF — 起始帧修正寄存器(偏移 0x0C)

SOF 寄存器用于微调 SOF(Start of Frame)包的发送时机。UHCI 规范要求每帧开始时发送 SOF 包,但不同 USB 总线拓扑可能导致传播延迟差异。SOF 寄存器允许驱动调整 SOF 包的发送偏移量。

SOF 寄存器位域定义
位域 描述
Bit 7:0 SOF 修正值(SOF Timing Value),单位是位时间(bit time)。默认值 0x40(64 位时间)。
Bit 15:8 保留位,写 0。
  • 默认值: 0x40(64 位时间)对应约 2.67 µs(USB 全速 12 Mbps,每位 83.3 ns)。
  • 调整场景: 当 USB 总线过长或级联集线器过多时,可适当增大 SOF 修正值,确保下游设备有足够时间准备接收数据。
  • 调试建议: 在批量传输出现间歇性超时时,尝试调整 SOF 值(如 0x50 或 0x60)可能改善时序裕量。

2.8 PORTSC — 端口状态与控制寄存器(偏移 0x10–0x1F)

每个 UHCI 控制器最多支持 2 个端口,每个端口对应一个 PORTSC 寄存器,偏移地址分别为 0x10 和 0x12。PORTSC 是驱动与物理 USB 端口交互的主要接口。

PORTSC 寄存器位域定义
位域 名称 描述
Bit 0 CCS (Current Connect Status) 1 = 设备已连接;0 = 未连接。只读。
Bit 1 CSC (Connect Status Change) 1 = 连接状态发生变化。写 1 清除。
Bit 2 PE (Port Enable) 1 = 端口使能;0 = 端口禁用。驱动写 1 使能,写 0 禁用。
Bit 3 PEC (Port Enable Change) 1 = 端口使能状态发生变化。写 1 清除。
Bit 4 OC (Over Current) 1 = 过流事件发生。只读。
Bit 5 OCC (Over Current Change) 1 = 过流状态变化。写 1 清除。
Bit 6 PR (Port Reset) 写 1 触发端口复位,至少保持 10 ms 后写 0 结束复位。
Bit 7 SUSP (Suspend) 1 = 端口挂起;0 = 正常。驱动写 1 进入挂起,写 0 恢复。
Bit 8 RD (Resume Detect) 1 = 检测到远程唤醒信号。写 1 清除。
Bit 9–15 Reserved 保留位,读返回 0。
端口枚举流程:
  1. 检测 CCS 位,确认设备连接。
  2. 写 PR=1 触发端口复位,等待 10 ms 后写 PR=0。
  3. 写 PE=1 使能端口。
  4. 读取 PE 确认使能成功,然后开始地址分配和配置。
PORTSC 端口状态机 未连接 CCS=1 已连接 PR=1 复位中 PR=0 使能 CCS=0 断开 SUSP=1 挂起