CMDQ 是 eMMC 5.1 引入的最重要的性能增强特性它允许主机将多个数据传输任务排队到设备内部队列中设备自主调度执行从而大幅提升随机 I/O 性能。一、CMDQ 核心概念1.1 为什么需要 CMDQ传统 eMMC 的问题传统模式无CMDQ 主机发CMD17 → 等待数据传完 → 主机发CMD17 → 等待... └─ 每次只能处理一个请求命令和数据串行执行 └─ 设备内部Flash的并行能力无法利用 └─ 随机I/O性能极差CMDQ 模式CMDQ模式 主机排队Task0(CMD44CMD45) ─┐ 主机排队Task1(CMD44CMD45) ─┤ 队列中 主机排队Task2(CMD44CMD45) ─┘ └─ 设备内部并行准备多个任务 └─ 主机选择就绪的任务执行(CMD46/CMD47) └─ 排队和执行可重叠DAT线传输数据时CMD线可继续排队新任务1.2 架构概览┌─────────────────────────────────────────────────────┐ │ Host Software │ │ ┌──────────────────────────────────────────────┐ │ │ │ Task Descriptor List (内存) │ │ │ │ Task0, Task1, Task2, ... TaskN │ │ │ └──────────────────┬───────────────────────────┘ │ │ │ │ │ ┌──────────────────▼───────────────────────────┐ │ │ │ CQE (Command Queue Engine) — 主机硬件 │ │ │ │ ┌────────┐ ┌────────┐ ┌───────────────┐ │ │ │ │ │Doorbell│ │ICoal │ │Halt/Clear │ │ │ │ │ └────────┘ └────────┘ └───────────────┘ │ │ │ └──────────────────┬───────────────────────────┘ │ └─────────────────────┼─────────────────────────────────┘ │ eMMC总线 ┌─────────────────────▼─────────────────────────────────┐ │ Device (eMMC) │ │ ┌──────────────────────────────────────────────┐ │ │ │ Internal Task Queue (设备内部队列) │ │ │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │TID0│ │TID1│ │TID2│ │ ...│ │TIDN│ │ │ │ │ └────┘ └────┘ └────┘ └────┘ └────┘ │ │ │ │ 状态: Pending → Ready for Execution → Done │ │ │ └──────────────────────────────────────────────┘ │ │ ┌──────────────────────────────────────────────┐ │ │ │ QSR (Queue Status Register) — 32位 │ │ │ │ 每位对应一个Task ID的就绪状态 │ │ │ └──────────────────────────────────────────────┘ │ │ ┌──────────────────────────────────────────────┐ │ │ │ Flash Controller (并行调度) │ │ │ └──────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘二、CMDQ 命令集CMDQ 引入了5条新命令属于Class 11命令名称功能响应CMD44QUEUED_TASK_PARAMS设置任务参数第1步R1CMD45QUEUED_TASK_ADDRESS设置任务地址第2步R1CMD46EXECUTE_READ_TASK执行已排队的读任务R1 数据CMD47EXECUTE_WRITE_TASK执行已排队的写任务R1 数据CMD48CMDQ_TASK_MGMT任务管理丢弃队列/任务R1b2.1 CMD44QUEUED_TASK_PARAMS排队参数功能设置任务的参数是排队的第一步。参数格式32位 ArgumentBit 31: Reserved Bit 30: Force Programming (Forced_Prog) Bit 29: Reliable Write Bit 28: Data Direction (0Write, 1Read) Bit 27: Tag Request Bit [26:24]: Context ID (3位, 0-7) Bit 23: Priority (0Simple, 1High) Bit [22:21]: Reserved Bit [20:16]: Task ID (5位, 0-31) Bit [15:0]: Block Count (16位)字段详解字段位说明Block Count[15:0]传输的块数0为错误Task ID[20:16]任务标识符0到CMDQ_DEPTH不可重复使用已在队列中的IDPriority[23]0普通优先级, 1高优先级。设备优先准备高优先级任务Context ID[26:24]上下文ID用于上下文管理特性Tag Request[27]数据标签请求Data Direction[28]0写, 1读Reliable Write[29]可靠写标志Force Programming[30]强制编程标志2.2 CMD45QUEUED_TASK_ADDRESS排队地址功能紧接CMD44之后设置任务的起始块地址。参数格式Bit [31:0]: Start Block Address起始块地址关键规则必须紧跟CMD44之后发送否则设备报Illegal CommandCMD44 CMD45 共同构成一个完整的排队操作可以在DAT线数据传输或Busy期间发送这是CMDQ的核心优势2.3 CMD46EXECUTE_READ_TASK执行读任务功能从队列中执行一个已就绪的读任务。参数格式Bit [31:5]: Reserved Bit [4:0]: Task ID (要执行的任务ID)执行条件指定Task ID必须是读任务Data Direction1该任务必须在QSR中标记为ready for execution设备返回R1响应后立即开始数据传输2.4 CMD47EXECUTE_WRITE_TASK执行写任务功能从队列中执行一个已就绪的写任务。参数格式与CMD46相同执行条件指定Task ID必须是写任务Data Direction0该任务必须在QSR中标记为ready for execution主机发送数据设备在最后一个数据块后拉低DAT0Busy2.5 CMD48CMDQ_TASK_MGMT任务管理功能管理队列中的任务丢弃全部或单个。参数格式Bit [31:24]: Reserved Bit [23:16]: Task ID (Discard Task时需要) Bit [15:8]: Reserved Bit [7:4]: Reserved Bit [3:0]: TM op-codeTM op-code值操作需要Task ID?0x0Reserved-0x1Discard entire queue— 丢弃整个队列QSR清零否0x2Discard Task— 丢弃指定任务QSR对应位清零是0x3-0xFReserved-三、任务周期CMD44(参数) CMD45(地址) Host ──────────────────────────────────────► Device │ ▼ ┌─────────────────────┐ │ Queue: Pending │ 设备内部准备中 │ (QSR bit 0) │ (Flash读取/地址映射等) └──────────┬──────────┘ │ 设备准备完成 ▼ ┌─────────────────────┐ │ Ready for Execution│ QSR对应bit 1 │ (QSR bit 1) │ └──────────┬──────────┘ │ Host发CMD46/CMD47(Task ID) │ ▼ ┌─────────────────────┐ │ Executing │ DAT线数据传输 │ (Data Transfer) │ └──────────┬──────────┘ │ ┌──────────▼──────────┐ │ Completed │ │ QSR bit cleared │ Task ID可复用 └─────────────────────┘任务完成定义读任务最后一个数据块完全通过eMMC总线传输完毕写任务最后一个数据块后的Busy信号释放Flash编程完成四、QSR — Queue Status Register队列状态寄存器QSR 是一个32位寄存器每一位对应一个 Task IDQSR [31:0]: bit[i] 0 → Task i 不在队列中 / 尚未就绪 bit[i] 1 → Task i 已就绪可执行读取方式通过CMD13的特殊模式读取CMD13 Argument: Bit [15] 1 → 返回QSR而非Device Status Bit [15] 0 → 返回Device Status传统行为 CMD13 Response (R1): 当Bit[15]1时32位响应 QSR内容CMDQ 相关 EXT_CSD 字段偏移字段说明[308]CMDQ_SUPPORTbit01 表示支持CMDQ[307]CMDQ_DEPTH队列深度 N1最大32[15]CMDQ_MODE_ENbit01 启用CMDQ模式五、完整操作流程5.1 初始化流程1. 检查设备是否支持CMDQ: CMD8 → 读EXT_CSD → 检查CMDQ_SUPPORT[308] bit0 2. 设置块大小为512BCMDQ强制要求: CMD16 → Block Length 512 3. 启用CMDQ模式: CMD6 → Index15(CMDQ_MODE_EN), Value0x01 4. 确认队列深度: EXT_CSD[307] CMDQ_DEPTH → Queue Depth N15.2 排队任务Queuing┌─ 排队 Task 0 (读操作) ───────────────────────────┐ │ CMD44: Arg {TaskID0, Dir1(Read), Count8, │ │ Priority1(High)} │ │ → Device返回R1 │ │ CMD45: Arg 0x00001000 (Start Address) │ │ → Device返回R1, Task0进入Pending状态 │ └───────────────────────────────────────────────────┘ ┌─ 排队 Task 1 (写操作) ───────────────────────────┐ │ CMD44: Arg {TaskID1, Dir0(Write), Count4, │ │ Priority0(Simple)} │ │ → Device返回R1 │ │ CMD45: Arg 0x00002000 (Start Address) │ │ → Device返回R1, Task1进入Pending状态 │ └───────────────────────────────────────────────────┘ ┌─ 排队 Task 2 (读操作) ───────────────────────────┐ │ CMD44: Arg {TaskID2, Dir1(Read), Count16, │ │ Priority0(Simple)} │ │ → Device返回R1 │ │ CMD45: Arg 0x00003000 (Start Address) │ │ → Device返回R1, Task2进入Pending状态 │ └───────────────────────────────────────────────────┘5.3 查询状态并执行┌─ 查询队列状态 ───────────────────────────────────┐ │ CMD13: Arg 0x00008000 (bit[15]1, 读QSR) │ │ → R1 Response 0x00000005 │ │ bit01 → Task0 Ready │ │ bit21 → Task2 Ready │ │ bit10 → Task1 尚未就绪(仍在Pending) │ └───────────────────────────────────────────────────┘ ┌─ 执行 Task 0 (读) ───────────────────────────────┐ │ CMD46: Arg 0x00000000 (TaskID0) │ │ → R1 Response │ │ → 设备发送8个数据块 │ │ → 传输完成后QSR[0]清零 │ └───────────────────────────────────────────────────┘ ┌─ 执行 Task 2 (读) ───────────────────────────────┐ │ CMD46: Arg 0x00000002 (TaskID2) │ │ → R1 Response │ │ → 设备发送16个数据块 │ │ → 传输完成后QSR[2]清零 │ └───────────────────────────────────────────────────┘ ┌─ 再次查询 ───────────────────────────────────────┐ │ CMD13: Arg 0x00008000 │ │ → R1 Response 0x00000002 │ │ bit11 → Task1 现在也Ready了 │ └───────────────────────────────────────────────────┘ ┌─ 执行 Task 1 (写) ───────────────────────────────┐ │ CMD47: Arg 0x00000001 (TaskID1) │ │ → R1 Response │ │ → 主机发送4个数据块 │ │ → 设备Busy(DAT0Low) → Flash编程 │ │ → Busy释放后QSR[1]清零 │ └───────────────────────────────────────────────────┘5.4 丢弃任务/队列┌─ 丢弃单个任务 ───────────────────────────────────┐ │ CMD48: Arg {TM_op0x2, TaskID3} │ │ → R1b Response │ │ → Task3从队列移除, QSR[3]清零 │ └───────────────────────────────────────────────────┘ ┌─ 丢弃整个队列 ───────────────────────────────────┐ │ CMD48: Arg {TM_op0x1} │ │ → R1b Response │ │ → 所有任务清除, QSR全部清零 │ └───────────────────────────────────────────────────┘六、CMDQ 关键特性6.1 优先级机制2级优先级High Priority (bit231) 和 Simple Priority (bit231)设备优先准备高优先级任务高优先级任务通常比先入队的普通任务更早变为Ready但如果设备已经开始准备普通任务可能仍会先标记为Ready6.2 乱序执行排队顺序: Task0 → Task1 → Task2 → Task3 执行顺序: Task2 → Task0 → Task3 → Task1 (完全由主机决定)设备不保证任务准备顺序主机可以按任意顺序执行已Ready的任务如果任务间有LBA重叠主机负责保证顺序6.3 排队与执行的重叠核心优势时间线: ──────────────────────────────────────────────────────► CMD线: [CMD44][CMD45] [CMD44][CMD45] [CMD46] └─ 排队Task0 └─ 排队Task1 └─ 执行Task0 DAT线: [ Task0 Data ] └─ 空闲 └─ Task0数据传输期间CMD线可继续排队新任务这是CMDQ最大的性能优势DAT线传输数据时CMD线可以继续排队新任务实现命令与数据的并行。6.4 CMD12 在 CMDQ 中的行为场景行为CMD12 在 CMD46(读) 传输期间回到Transfer状态任务视为完成(QSR[i]清零)CMD12 在 CMD47(写) 传输期间进入Programming状态数据全部编程完成后任务才算完成七、错误处理#命令错误场景响应处理方式1CMD44-48CMDQ未启用时收到Class 11命令无响应Illegal Command2CMD44Task ID已在使用 / 超出CMDQ_DEPTH / Block Count0无响应Illegal Command3CMD44其他参数错误(如ContextID)OKType X错误4CMD45未紧跟CMD44之后无响应Illegal Command5CMD45Type R错误(如地址越界)响应中带错误错误在响应中返回6CMD45Type X错误(如写保护违例)OKType X错误7CMD46/47Task ID不存在 / 未Ready / 方向错误无响应Illegal Command8CMD48无效TM op-codeOKType X错误(ERROR位)八、CMDQ 启用/禁用时的命令合法性模式队列状态命令状态CMDQ_MODE_EN0N/AClass 11 (CMD44-48)IllegalCMDQ_MODE_EN0N/A其他所有命令Legal (同eMMC 5.0)CMDQ_MODE_EN1空CMD17/18/24/25IllegalCMDQ_MODE_EN1空Class 11命令LegalCMDQ_MODE_EN1空其他命令LegalCMDQ_MODE_EN1非空Class 11命令LegalCMDQ_MODE_EN1非空CMD0Legal (队列和QSR全部复位)CMDQ_MODE_EN1非空CMD12LegalCMDQ_MODE_EN1非空CMD13LegalCMDQ_MODE_EN1非空其他所有命令Illegal关键约束启用CMDQ后CMD17/18/24/25 变为Illegal必须用CMD46/CMD47替代队列非空时只能发Class 11命令 CMD0/CMD12/CMD13禁用CMDQ前队列必须为空否则视为Illegal Command块大小必须设为512B九、Annex B — 主机控制器接口 (CQE)规范还定义了主机侧的Command Queue Engine (CQE)硬件接口Annex B规范性附录9.1 CQE 架构┌─────────────────────────────────────────────────────┐ │ Host System │ │ ┌─────────────────────────────────────────────┐ │ │ │ Driver Software │ │ │ │ ┌──────────────────────────────────────┐ │ │ │ │ │ Task Descriptor List (系统内存) │ │ │ │ │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │TD0 │ │TD1 │ │TD2 │ │TDN │ │ │ │ │ │ │ └────┘ └────┘ └────┘ └────┘ │ │ │ │ │ └──────────────────┬───────────────────┘ │ │ │ │ │ Doorbell │ │ │ │ ┌──────────────────▼───────────────────┐ │ │ │ │ │ CQE Registers (MMIO) │ │ │ │ │ │ CQTDBR (Doorbell) — 通知硬件有新任务 │ │ │ │ │ │ CQIS (Interrupt Status) │ │ │ │ │ │ CQIC (Interrupt Coalescing) │ │ │ │ │ │ CQDQS (Device Queue Status) │ │ │ │ │ │ CQTCLR (Task Clear) │ │ │ │ │ └──────────────────┬───────────────────┘ │ │ │ └─────────────────────┼────────────────────────┘ │ └────────────────────────┼──────────────────────────────┘ │ eMMC总线9.2 CQE 寄存器映射偏移寄存器功能00hCQVERCQE版本号04hCQCAP能力寄存器最大队列深度等08hCQCFG配置寄存器0ChCQCTL控制寄存器Enable/Halt10hCQIS中断状态14hCQISTE中断状态使能18hCQISGE中断信号使能1ChCQIC中断合并配置20hCQTDLBA任务描述符列表基地址(低32位)24hCQTDLBAU任务描述符列表基地址(高32位)28hCQTDBRDoorbell寄存器— 写入通知硬件有新任务2ChCQTCN任务完成通知30hCQDQS设备队列状态(QSR镜像)34hCQDPT设备待处理任务38hCQTCLR任务清除40hCQSSC1Send Status配置144hCQSSC2Send Status配置248hCQCRDCTDirect-Command响应50hCQRMEM响应模式错误掩码54hCQTERRI任务错误信息58hCQCRI命令响应索引5ChCQCRA命令响应参数9.3 任务描述符 (Task Descriptor)每个任务在主机内存中有一个Task Descriptor┌──────────────────────────────────────┐ │ Task Descriptor (数据传输任务) │ │ ┌────────────────────────────────┐ │ │ │ Attribute: │ │ │ │ - Task ID │ │ │ │ - Data Direction (R/W) │ │ │ │ - Priority │ │ │ │ - Block Count │ │ │ │ - Context ID / Tag Request │ │ │ │ - Reliable Write / Force Prog │ │ │ ├────────────────────────────────┤ │ │ │ Block Address │ │ │ ├────────────────────────────────┤ │ │ │ Transfer Descriptor Pointer │ │ │ │ (指向DMA描述符链) │ │ │ └────────────────────────────────┘ │ └──────────────────────────────────────┘9.4 CQE 工作流程1. 驱动准备Task Descriptor (系统内存) 2. 写Doorbell寄存器 (CQTDBR) → 通知CQE有新任务 3. CQE硬件自动: a. 读取Task Descriptor b. 发送CMD44 CMD45到设备 c. 通过CMD13轮询QSR 4. 当任务Ready时CQE自动: a. 发送CMD46/CMD47执行 b. 管理DMA数据传输 5. 传输完成后CQE产生中断通知驱动 6. 驱动处理完成通知释放资源9.5 中断合并 (Interrupt Coalescing)CQE支持中断合并减少中断开销CQIC寄存器配置: - 合并计数阈值: N个任务完成后才产生中断 - 合并超时: 超过T时间即使不足N个也产生中断9.6 Halt 特性CQCTL.Halt 1: → CQE停止发送新命令 → 等待当前传输完成 → 允许软件安全地修改队列或恢复错误 CQCTL.Halt 0: → CQE恢复正常运行9.7 Direct Command (DCMD)CQE支持通过队列发送非数据传输命令如CMD6/CMD13等DCMD Task Descriptor: → 编码一个直接命令 → CQE通过总线发送该命令 → 响应存储在CQCRDCT/CQCRI/CQCRA寄存器中9.8 Queue Barrier (QBR)QBR任务: → 确保QBR之前的所有任务完成后才开始执行QBR之后的任务 → 用于需要严格顺序的场景十、CMDQ 性能优势总结对比项传统模式CMDQ模式命令与数据串行并行排队与传输重叠设备调度无设备内部优化调度随机读极差逐个寻址优秀并行准备中断开销每个操作一次可合并CPU负载高频繁发命令低CQE硬件自动管理队列深度1最多32