3. UHCI 命令寄存器(USBCMD)详解
UHCI 命令寄存器(USBCMD)是主机控制器初始化与运行控制的核心寄存器,位于 I/O 空间偏移地址 0x00,宽度为 16 位。该寄存器中的每一位都直接控制着控制器的运行状态、复位行为、电源管理以及调试模式。本章将逐一解析 USBCMD 的各个字段,并结合实战场景说明其编程要点与性能调优策略。
3.1 USBCMD 寄存器位域总览
下表列出了 USBCMD 寄存器中所有有效位的名称、位号、访问属性及功能简述。理解这些位域是进行 UHCI 初始化的第一步。
| 位号 | 名称 | 访问 | 功能描述 |
|---|---|---|---|
| 15:7 | Reserved | R | 保留位,必须写 0 |
| 6 | CF | R/W | Configure Flag(配置标志) |
| 5 | SWDBG | R/W | SW Debug(软件调试模式) |
| 4 | FGR | R/W | Force Global Resume(强制全局唤醒) |
| 3 | EGSM | R/W | Enter Global Suspend Mode(进入全局挂起) |
| 2 | GRESET | R/W | Global Reset(全局复位) |
| 1 | HCRESET | R/W | Host Controller Reset(主机控制器复位) |
| 0 | RS | R/W | Run/Stop(运行/停止) |
3.2 Run/Stop(RS)位 —— 控制器的启停开关
位号:0
访问:R/W
默认值:0(停止状态)
RS 位是 UHCI 控制器运行状态的总开关。当该位被置为 1 时,控制器开始按照帧列表(Frame List)的调度执行 USB 事务处理;当该位被清 0 时,控制器在完成当前帧的所有事务后停止运行,进入空闲状态。
编程要点
- 启动控制器: 在完成所有初始化配置(如设置帧列表基地址、配置端口、设置中断使能等)后,最后一步将 RS 位置 1。
- 停止控制器: 在系统休眠、挂起或卸载驱动前,先将 RS 位清 0,并轮询等待控制器状态寄存器(USBSTS)中的 HCHalted 位变为 1,确认控制器已安全停止。
- 性能调优: 频繁启停 RS 位会增加调度延迟。在批量传输场景中,建议保持 RS 位为 1,仅在电源管理或错误恢复时操作该位。
// 假设 USBCMD 寄存器 I/O 地址为 0xC000
// 1. 设置帧列表基地址(略)
// 2. 设置端口配置(略)
// 3. 启动控制器
outw(inw(0xC000) | 0x0001, 0xC000); // 将 RS 位置 1
// 4. 等待控制器进入运行状态
while (!(inw(0xC004) & 0x0001)); // 轮询 USBSTS 的 HCHalted 位为 0
3.3 Host Controller Reset(HCRESET)位 —— 软件复位
位号:1
访问:R/W
默认值:0
HCRESET 位用于对 UHCI 主机控制器执行软件复位。当该位被置 1 时,控制器内部状态机、寄存器(除 USBCMD 本身和 USBSTS 的某些位外)以及所有端口逻辑都会被复位到默认状态。该位由硬件在复位完成后自动清 0。
使用场景
- 驱动加载初始化: 在 BIOS 或系统引导后,驱动应首先通过 HCRESET 确保控制器处于已知的初始状态。
- 错误恢复: 当检测到控制器挂起或传输超时等不可恢复错误时,使用 HCRESET 复位控制器,然后重新初始化。
- 热插拔处理: 在设备拔出后,可选择性复位控制器以清理残留状态。
编程流程
- 将 USBCMD 的 HCRESET 位置 1。
- 轮询等待 HCRESET 位被硬件自动清 0(通常需要 10~50 微秒)。
- 确认 USBSTS 中的 HCHalted 位为 1,表示控制器已进入停止状态。
- 重新进行完整的初始化配置。
3.4 Global Reset(GRESET)位 —— 全局复位
位号:2
访问:R/W
默认值:0
GRESET 位用于对 USB 总线上的所有下游设备执行全局复位。当该位被置 1 时,UHCI 控制器会驱动 D+ 和 D- 信号线进入复位状态(SE0 状态),持续时间由硬件控制(通常为 10~50 毫秒)。该位由硬件在复位完成后自动清 0。
与 HCRESET 的区别
| 特性 | HCRESET | GRESET |
|---|---|---|
| 复位目标 | 主机控制器内部逻辑 | USB 总线上的所有设备 |
| 持续时间 | 微秒级(10~50 µs) | 毫秒级(10~50 ms) |
| 对端口影响 | 端口寄存器复位 | 端口状态机复位,设备断开重连 |
| 使用场景 | 驱动初始化、错误恢复 | 系统级复位、电源管理 |
3.5 Enter Global Suspend Mode(EGSM)与 Force Global Resume(FGR)
EGSM 位号:3
FGR 位号:4
访问:R/W
默认值:0
EGSM 和 FGR 位用于控制 UHCI 控制器的全局电源管理。EGSM 位使控制器进入全局挂起模式,此时控制器停止帧启动(SOF)包的发送,所有端口进入挂起状态。FGR 位用于强制唤醒,使控制器恢复 SOF 发送并唤醒所有挂起的设备。
电源管理状态转换
下图展示了 UHCI 控制器在正常运行、全局挂起和全局唤醒之间的状态转换关系。
编程注意事项
- 进入挂起: 先确保所有 USB 设备已进入挂起状态(通过端口控制寄存器),再将 EGSM 位置 1。控制器将在当前帧结束后停止 SOF 发送。
- 唤醒: 将 FGR 位置 1,控制器会立即恢复 SOF 发送并持续 20 毫秒,然后自动清 0 FGR 位。驱动应轮询等待 FGR 位清 0 后,再恢复正常操作。
- 性能影响: 全局挂起/唤醒操作会引入 20~50 毫秒的延迟,不适合频繁使用。建议仅在系统进入 S3(挂起到内存)或 S4(休眠)状态时使用。
3.6 SW Debug(SWDBG)位 —— 软件调试模式
位号:5
访问:R/W
默认值:0
SWDBG 位用于启用 UHCI 控制器的软件调试模式。当该位被置 1 时,控制器会在每个帧结束后暂停,等待软件干预。调试模式允许驱动开发者单步执行帧调度,检查传输描述符(TD)和队列头(QH)的状态。
调试模式工作流程
- 将 SWDBG 位置 1,同时确保 RS 位为 1。
- 控制器执行完当前帧的所有事务后,暂停并设置 USBSTS 中的 Debug 状态位。
- 驱动读取帧列表、TD 和 QH 的状态,分析传输结果。
- 驱动清除 Debug 状态位,控制器继续执行下一帧。
3.7 Configure Flag(CF)位 —— 配置标志
位号:6
访问:R/W
默认值:0
CF 位是 UHCI 控制器的配置标志位。该位用于指示主机控制器驱动(HCD)已完成对控制器的配置。在 CF 位被置 1 之前,控制器不会开始处理任何 USB 传输请求。CF 位通常作为初始化完成的最后一步。
CF 位的使用规则
- 置位时机: 在所有初始化步骤(包括 HCRESET、帧列表设置、端口配置、中断使能)完成后,最后将 CF 位置 1。
- 清 0 时机: 在驱动卸载或系统进入休眠前,先将 CF 位清 0,再停止控制器(RS 位清 0)。
- 多控制器协调: 在具有多个 UHCI 控制器的系统中,每个控制器的 CF 位独立管理,互不影响。
3.8 初始化流程整合:USBCMD 寄存器编程实战
以下是一个完整的 UHCI 控制器初始化流程,展示了 USBCMD 各字段的正确编程顺序。
// 步骤 1: 复位主机控制器
outw(inw(0xC000) | 0x0002, 0xC000); // 置位 HCRESET
// 步骤 2: 等待复位完成
while (inw(0xC000) & 0x0002);
// 步骤 3: 设置帧列表基地址(假设基地址为 0x100000)
outl(0x100000, 0xC008);
// 步骤 4: 配置端口 1(启用端口)
outw(inw(0xC010) | 0x0001, 0xC010);
// 步骤 5: 设置中断使能(启用完成中断)
outw(0x0001, 0xC006);
// 步骤 6: 置位 CF
outw(inw(0xC000) | 0x0040, 0xC000);
// 步骤 7: 启动控制器
outw(inw(0xC000) | 0x0001, 0xC000);
// 等待控制器运行
while (inw(0xC004) & 0x0001);
3.9 性能调优建议
| 场景 | USBCMD 配置建议 | 性能影响 |
|---|---|---|
| 高吞吐量传输 | RS=1, SWDBG=0, CF=1 | 最大化帧调度效率 |
| 低功耗待机 | RS=1, EGSM=1, CF=1 | 减少功耗,唤醒延迟约 20ms |
| 调试阶段 | RS=1, SWDBG=1, CF=1 | 单帧执行,吞吐量下降 90% 以上 |
| 错误恢复 | 先 HCRESET=1,再重新初始化 | 完全重置,恢复时间约 50µs |