eMMC Command Queuing简介-Command和 Register
原本是想着一次性把 Command Queuing(CMDQ)介绍完的,后面翻译 register发现不对头,这 register又长又臭,于是就拆分出来了。下面一开始是惯例的超简单介绍:
Command Queuing(CQ)的介绍主要来自 JESD84-B51的 6.6.39 Command Queuing和 Annex B (Normative) Host Controller Interface for Command Queuing,想了解一手资料还是要看协议。Command Queuing是在 5.1规范引入的,host 软件通过任务队列形式,提前准备数据,在逻辑侧完成对任务的命令级交互,降低对CPU调度的依赖,从而实现提高性能和降低损耗的目的。
Command
CMD index | type | argument | resp | abbr. | description |
---|---|---|---|---|---|
CMD13 | ac | [31:16] RCA [15] SQS [14:1] stuff bits [0] HPI | R1 | SEND_QUEUE_STATUS(SQS) | SQS bit=1:表示这是一个 QSR查询。device应发送 QSR寄存器给 host。这种情况下,HPI必须为 0 |
CMD44 | ac | [31] Reliable Write Request [30] DD: “1” read / “0” write [29] Tag request [28:25] Context ID [24]: Forced Programming [23] Priority: “0” simple / “1” high [22:21] reserved [20:16] Task ID [15:0] Number of Blocks | R1 | QUEUED_TASK_PARAMS | bit [31] 可靠写请求,bit [30] 定义操作的方向,’1’ 读取 / ‘0’ 写入,bit [23] 优先级,bit [20:16] 任务 ID,bit [15:0] 任务队列的块计数 |
CMD45 | ac | [31:0] Start block address | R1 | QUEUED_TASK_ADDRESS | 定义任务队列的起始块地址 |
CMD46 | adtc | [31:21] reserved [20:16] Task ID [15:0] reserved | EXECUTE_READ_TASK | device执行对应任务 ID的读操作 | |
CMD47 | adtc | [31:21] reserved [20:16] Task ID [15:0] reserved | R1 | EXECUTE_WRITE_TASK | device执行对应任务 ID的写操作 |
CMD48 | ac | [31:21] reserved [20:16]: TaskID [15:4]: reserved [3:0] TM op-code (Table 5) | R1b | CMDQ_TASK_MGMT | device 丢弃特定任务或者整个队列 当 bit [3:0] TM op-code = 0x2时,bit [20:16]表示 task id,当 TM op-code = 0x1时,bit [20:16]为保留,无意义。 |
当 CQ使能时,数据传输仅支持 class 11命令集,CQ关闭时,数据传输不可用 class 11命令集,但可以使用 CMD18/CMD17和 CMD24/CMD25。不过 CQ使能时,还可以通过 Direct Command (DCMD)发送非数据传输命令,如:CMD0、CMD12、CMD13。
详细介绍可以看 6.6.39.2到 6.6.39.7和 6.6.39.9 Supported Commands或者参考 eMMC命令简介。
Register
详见 B.4. CQE Registers
Symbol | Offset | descriptor | |
---|---|---|---|
CFG and CAP | CQVER | 0x00 | Command Queuing Version,RO,CQ版本寄存器,提供了eMMC CQ的版本信息,当前版本为 5.1,bit [11:8]=0x5,bit [7:4]=0x1,即 0x0510。 |
CQCAP | 0x04 | Command Queuing Capabilities,RO,CQ能力寄存器,描述 eMMC CQ的能力。 Internal Timer Clock Frequency Multiplier(ITCFMUL) bit [15:12],ITCFMUL与 ITCFVAL一起用于中断聚合的定时器和确定 SQS(CMD13)轮询周期的时钟频率。0x0 = 0.001 MHz、0x1 = 0.01 MHz、0x2 = 0.1 MHz、0x3 = 1 MHz、0x4 = 10 MHz。 Internal Timer Clock Frequency Value(ITCFVAL) bit [9:0],ITCFMUL与 ITCFVAL一起用于中断聚合的定时器和确定 SQS(CMD13)轮询周期的时钟频率。时钟频率计算方式为 ITCFMUL * ITCFVAL,例如 ITCFVAL = 0xc0(192 dec.),ITCFMUL = 0x2(0.1MHz),则时钟频率 f = 192 * 0.1 = 192.MHz。 | |
CQCFG | 0x08 | Command Queuing Configuration,RW,CQ配置寄存器,用于使能 CQ、DCMD和配置任务描述符长度 64bits或是 128bits。 Direct Command (DCMD) Enable bit [12],用于告知 CQE,TDL的 slot 31的任务描述符是数据传输任务描述符(0x0)还是 Direct CMD任务描述符(0x1); Task Descriptor Size bit [8],描述任务描述符长度是 128bits(0x1)还是 64bits(0x0); Command Queuing Enable bit [0],软件将该 bit写 1则使能 CQE,软件写 1前应该确保 host控制器处于空闲状态,软件要退出 CQ,将 bit清零前也要确保清除所有任务。 | |
CQCTL | 0x0c | Command Queuing Control,CQ控制寄存器,软件用于 halt CQE取得总线控制权,或是在 recovery流程中清除所有 task。 Clear All Tasks bit [8],RWAC,当软件要清除发送到 device上的所有任务时,应将该 bit置位,且只有 CQE处于 halt状态(CQCTL.bit [0] = 1)时,才能写入该 bit。软件置位后,CQE会重置所有未完成任务的 CQTDBR和其他上下文信息,然后 CQE会清零该 bit。同时软件负责发送 CMDQ_TASK_MGMT(CMD48)命令 device丢弃队列中的任务,软件应该同时通知 device和 CQE但没有明确的顺序关系,只要 CQE处于 halt状态。如果软件需要恢复 CQE,只有该 bit为 0时,才可以清零 CQCTL.bit [0],让 CQE恢复正常操作。 Halt bit [0],R/W,软件想获取总线控制权并禁止 CQE在总线上发出命令时,应将该 bit写 1。例如,当软件写 1 halt CQE后发出 CMDQ_TASK_MGMT(CMD48)命令,如果任务正在进行,CQE应该完成正在进行的任务。一旦任务完成且 CQE处于空闲状态,CQE不得发出新的命令,且 CQE应设置该 bit为 1。软件可以轮询该 bit,等待 CQE将该 bit置位,表明 CQE释放了总线。软件将该 bit写 0则 CQE退出 halt状态,bit已为 0时,写 0无效。 | |
Interrupt Control | CQIS | 0x10 | Command Queuing Interrupt Status,RW1C,CQ中断状态寄存器,描述触发中断的事件,当前只有bit [3:0],且需要 CQISTE也配置对应的 bit才有效。 Task Cleared(TCL) bit [3],当清除单个或全部任务完成时置位; Response Error Detected Interrupt(RED) bit [2],当 response中 device status设置了错误位时置位,软件可以配置 CQRMEM来使能哪些 device status bit可以触发中断; Task Complete Interrupt(TCC) bit [1],当一个任务完成或是聚合中断触发时置位; Halt Complete Interrupt(HAC) bit [0],当 CQ进入 halt状态时置位。 |
CQISTE | 0x14 | Command Queuing Interrupt Status Enable,RW,CQ中断状态使能寄存器,该寄存器用于使能或者禁用向软件上报 CQIS的中断事件,每个 bit都与 CQIS的 bits匹配。 | |
CQISGE | 0x18 | Command Queuing Interrupt Signal Enable,RW,CQ中断信号使能寄存器,该寄存器用于使能或者禁用 CQIS的中断事件产生,每个 bit都与 CQIS的 bits匹配。 | |
CQIC | 0x1c | Command Queuing Interrupt Coalescing,CQ中断聚合寄存器,该寄存器用于控制中断聚合。 Interrupt Coalescing Enable/Disable bit [31],RW,软件设置该 bit为 0时,命令响应不计数与不定时,中断继续由任务描述符中 INT=1的任务完成后触发,设置为 1时,使能中断聚合,并生成聚合中断; Interrupt Coalescing Status Bit(ICSB) bit [20],RO,当 INT=0的任务完成并计数到中断聚合,即 IC count > 0时置位; Counter and Timer Reset(ICCTR) bit [16],WO,软件把该 bit写 1时,中断聚合定时器和计数器复位; Interrupt Coalescing Counter Threshold Write Enable(ICCTHWEN) bit [15],WO,该 bit软件写 1时,可以更新 ICCTH的值,只有任务队列为空时才可写 1; Interrupt Coalescing Counter Threshold(ICCTH) bit [12:8],RW,软件配置该字段用于设置产生中断所需的任务(INT=0)完成数,最大为 31,CQE负责计数,到达配置值后停止计数,软件负责计数器(ICCTR)复位,该字段为 0时,CQE不计数; Interrupt Coalescing Timeout Value Write Enable (ICTOVALWEN) bit [7],WO,该 bit软件写 1时,才可以更新 ICTOVAL的值,只有任务队列为空时才可写 1; Interrupt Coalescing Timeout Value(ICTOVAL) bit [6:0],软件设置此字段来配置完成总线上的任务到生成中断允许的最长时间,软件负责定时器的(ICCTR)复位,复位定时器后,当数据传输任务(INT=0)完成时开始定时,到达配置值后停止定时并生成中断,定时器单位是 CQCAP描述的频率的时钟的 1024个时钟周期,最小值 0x01(1*1024时钟周期),最大值 0x7f(127*1024时钟周期),具体计算方法见协议,该字段为 0时,定时器不运行。 | |
Task Submission | CQTDLBA | 0x20 | Command Queuing Task Descriptor List Base Address,RW,CQ任务描述符列表(TDL)基址寄存器,该寄存器储存任务描述符列表头(TDL)的低 32位地址,且分配的内存地址应该 1k对齐,即低 10 bits软件应该设置为 0,且 CQE应该忽略低 10bits数值,而TDL的大小为 32 *(任务描述符大小 + 传输描述符大小)。 |
CQTDLBAU | 0x24 | Command Queuing Task Descriptor List Base Address Upper 32 bits,RW,CQ任务描述符列表(TDL)基址寄存器,该寄存器储存任务描述符列表头(TDL)的高 32位地址,使用 32位寻址模式时,该寄存器为保留不用。 | |
CQTDBR | 0x28 | Command Queuing Task Doorbell,RW1S,CQ任务门铃寄存器,该寄存器用于软件触发 CQE处理对应的任务,这个动作一般叫敲门铃,当然软件应该先配置 TDLBA和 TDLBAU并在 CQCFG中使能 CQE。 软件将 1写入该寄存器 bit n会触发 CQE处理 TDL中对应的 slot n任务,软件可以同时对多个 bit写 1,实现批量提交,CQE处理批量提交时,会从最小的 task id(slot n)开始。如果有一个或多个任务 QBR置位,则处理顺序应该按照 QBR流程,详见 B.2.6. Queue-Barrier (QBR) Tasks。 软件写 0对 CQE不会有任何影响,也不会改变寄存器的值。 CQE被触发后会读取任务描述符,并向 device发送 QUEUED_TASK_PARAMS(CMD44)和QUEUED_TASK_ADDRESS(CMD45) 如果是 DCMD任务( slot 31使能),CQE会根据任务描述符中的 CMD index和参数生成命令并在 CMD line发出。 以下事件中,CQE会将相应 bit清 0:1、任务完成,不管成功或错误;2、使用 CQTCLR清除任务;3、使用 CQCTL清除所有任务;4、CQCFG中禁用了 CQE。 | |
CQTCN | 0x2c | Command Queuing Task Completion Notification,RW1C,CQ任务完成通知寄存器,当任务(task id=n)完成(成功或错误),CQE会置位该寄存器 bit n并清零 CQTDBR bit n。软件收到任务完成中断后,读取该寄存器以确定哪些任务已经完成,软件负责将已经完成的任务对应的 bit写 1清零。 | |
Task Management | CQDQS | 0x30 | Command Queuing Device Queue Status,RO,device队列状态寄存器,该寄存器储存着 device队列状态最新值,host通过 CMD13获取 device的 QSR后,都会用 QSR的值更新到本寄存器,如果 DCMD使能,则由 CQE负责更新本寄存器。 |
CQDPT | 0x34 | Command Queuing Device Pending Tasks,RO,CQ任务挂起寄存器,该寄存器表示哪些任务在 device中排队等待执行。当 CQE为任务(task id=n)发送了QUEUED_TASK_PARAMS(CMD44)和QUEUED_TASK_ADDRESS(CMD45)且收到了 CMD45的成功响应但未发送 EXECUTE_WRITE_TASK(CMD47)或 CMDQ_TASK_MGMT(CMD48)执行任务时,CQE会置位该寄存器的 bit n,CQE在任务(task id=n)执行完成后会清除对应的 bit n。 当 CQE halt住时,软件需要在任务丢弃过程中读取该寄存器,以确定是否有任务在 device中排队,如果有则软件应该发送 CMDQ_TASK_MGMT(CMD48)让 device放弃任务,同时软件会清除 CQE中的任务。只有这样才能在软件恢复 CQE的时候,将CQCTL.halt(bit [0])写 0。 | |
CQTCLR | 0x38 | Command Queuing Task Clear,RW,CQ单任务清除寄存器,该寄存器用于清除 CQE中单个未完成的任务。只有 CQE处于 halt状态才可使用。当软件置位该寄存器的 bit n时,CQE会将该 bit n置为 1(CQE才有权限实际更新该寄存器值),并开始清除对应任务的相关数据结构,清除完成后,CQE会清零 CQTCLR和 CQTDBR中对应的 bit n。软件应该轮询 CQTCLR,直到 CQE完成清除操作。软件将 0写入该寄存器不会有影响。 同样软件操作该寄存器只影响 CQE,device中的任务还需要软件按照流程发送 CMDQ_TASK_MGMT(CMD48)。 软件不应该使用该寄存器清除多个任务,应该使用 CQCTL寄存器来清除多个任务。 | |
SQS and DCMD | CQSSC1 | 0x40 | Command Queuing Send Status Configuration 1,RW,CQSQS配置寄存器1,该寄存器控制何时发送 SEND_QUEUE_STATUS(CMD13)查询 device 任务队列的状态。 Send Status Command Block Counter(CBC) bit [19:16],该字段配置 CQE何时发送 SEND_QUEUE_STATUS(CMD13)查询 device 任务队列的状态,CQE应该在 CMD线上发送 SQS。该字段值为 n,表示 CQE应该在块数量为 BLOCK_CNT - n期间发送 SQS,BLOCK_CNT是指当前这笔传输的块数量;该字段值为 0,表示在数据传输期间,不应该发送 SEND_QUEUE_STATUS(CMD13),只在 DATA线空闲时发送;该字段值为 1,表示 SQS将在这笔传输的最后一个块期间发送。 Send Status Command Idle Timer(CIT) bit [15:0],该字段配置 CQE周期性发送 SEND_QUEUE_STATUS(CMD13)所使用的轮询周期。Periodic polling is used when tasks are pending in the device, but no data transfer is in progress. When a SEND_QUEUE_STATUS response indicating that no task is ready for execution, CQE counts the configured time until it issues the next SEND_QUEUE_STATUS. 注1 定时器的时钟周期,其频率已经在 CQCAP(ITCFMUL * ITCFVAL)中确定,最小值是 0x1(1个时钟周期),最大值是 0xffff(65535个时钟周期),默认值是 4096个时钟周期。例如,ITCFMUL * ITCFVAL = 19.2MHz,即周期为 52.08ns,如果 CQSSC1.CIT = 0x1000(4960 dec.),则 SQS的轮询周期为 4096 * 52.08ns = 213.33us。 注1:在 CIT的介绍中,协议原文比较晦涩难懂,原本是翻译如下,当 SQS的 response表示 device中有任务等待执行,但没有进行数据传输时,CQE定时轮询发送 SQS。device没有任务可供执行时,CQE开始定时,直到它发出下一个 SQS。但还是觉得不妥。翻阅协议,在 B.2.3. Task Selection and Execution - Reading the QSR,获得了清晰明了的说明。当有任务在 device中排队时(等待执行),CQE发送 SEND_QUEUE_STATUS(CMD13)获取 QSR以确定哪些任务准备好执行。如果此时正在进行数据传输,则 CQE根据 CQSSC1.CBC的配置,在数据传输的末尾发送 SQS。如果此时总线空闲,则 CQE根据 CQSSC1.CIT的配置周期性的发送 SQS。 |
CQSSC2 | 0x44 | Command Queuing Send Status Configuration 2,RW,CQSQS配置寄存器2,该寄存器用于配置 SQS argument中的 RCA。 Send Queue Status RCA bit [15:0],配置 CQE发送 SEND_QUEUE_STATUS(CMD13)argument中 16位的 RCA,即 argument bit [31:16]。 | |
CQRDCT | 0x48 | Command Queuing Command Response for Direct-Command Task,RO,CQ直接命令响应寄存器,该寄存器储存着 CQE最后接收到 direct-command(DCMD)任务的 response,CQE应该在每次收到命令的响应后更新该寄存器,且只有在 CQE清零 CQTDBR的 bit31,该寄存器才被认为有效。 | |
Error handing | CQRMEM | 0x50 | Command Queuing Response Mode Error Mask,RW,CQ命令响应错误掩码寄存器,该寄存器控制 Response Error Detection(RED)中断的生成,即作为 R1/R1b响应中接收的 device状态的中断掩码。 bit n = 1对应 device状态中对应的 bit n为 1时能触发 RED中断,为 bit n = 0时则被忽略。该寄存器的默认值为 0xFDF9A080,即能触发 device状态中所有错误类型的 RED中断,具体错误类型可以查看 Table 68 — Device status。 对于 CMD13(SQS)的响应 QSR,逻辑(CQE)应该忽略。 |
CQTERRI | 0x54 | Command Queuing Task Error Information,RO,CQ任务错误信息寄存器,该寄存器会在任务相关数据或者命令出现错误的时候由 CQE进行更新。不管是 CQE还是 device上报的,CQE会将错误发生时在 CMD线和 DATA线上执行的 CMD index和 task id储存在 CQTERRI中,并在错误恢复流程中使用,具体见 B.2.8. Error Detection and Recovery。 Data Transfer Error Fields Valid bit [31],当 CQE检测到错误或者 device上报错误,该 bit将会更新。如果正在进行数据传输出问题则 bit [31] = 1,如果出问题时是无数据传输则 bit [31] = 0。注1 Data Transfer Error Task ID bit [28:24],如果出现错误且正在进行数据传输(CQTERRI.bit [31] = 1),CQE应更新该字段,将 DATA线上执行的 task id存储于此。 Data Transfer Error Command Index bit [21:16],如果出现错误且正在进行数据传输(CQTERRI.bit [31] = 1),CQE应更新该字段,将发生错误时在 DATA线执行的 CMD index存储于此。根据数据方向,CMD index不是 EXECUTE_READ_TASK(CMD46)就是 EXECUTE_WRITE_TASK(CMD47)。 Response Mode Error Fields Valid bit [15],当 CQE检测到错误或者 device上报错误,该 bit将会更新。如果正在进行命令传输出问题则 bit [15] = 1,如果出问题时是无命令传输则 bit [15] = 0。注2 Response Mode Error Task ID bit [12:8],如果出现错误且正在进行命令传输(CQTERRI.bit [15] = 1),CQE应更新该字段,将 CMD线上执行的 task id存储于此。 Response Mode Error Command Index bit [5:0],如果出现错误且正在进行命令传输(CQTERRI.bit [15] = 1),CQE应更新该字段,将 CMD线上执行的 CMD index存储于此。 注1、注2:协议此处说得比较模糊,结合 Data Transfer Error Task ID、Data Transfer Error Command Index和 Response Mode Error Task ID、Response Mode Error Command Index,可以理解为只有 bit [31] = 1时,Data Transfer Error Task ID、Data Transfer Error Command Index有效或 bit [15] = 1时,Response Mode Error Task ID、Response Mode Error Command Index有效,bit [31]或 bit [15]为 0时,上述字段是无效的。 | |
CQCRI | 0x58 | Command Queuing Command Response Index,RO,CQ命令索引寄存器,该寄存器储存着 CQE最后接收到的是哪个命令(CMD index),CQE应该在每次收到命令的响应后更新该寄存器。 | |
CQCRA | 0x5c | Command Queuing Command Response Argument,RO,CQ命令响应寄存器,该寄存器储存着 CQE最后接收到的 response,CQE应该在每次收到命令的响应后更新该寄存器。 |
eMMC Command Queuing简介-Command和 Register
http://xxxdk.xyz/xxx/2021/05/eMMC-Command-Queuing简介-Command和-Register/