目录
参考文献
基本概念
HBA
AHCI HBA
OOB(Out of Band)信号解析
PIO
FPDMA
TAG
FIS(Frame Information Structure)
PRD
PIO
Port Multiplier
NCQ
sht
SATA
Shadow Register
SATA Registers
SStatus register (SCR0)
SError register (SCR1)
SControl register (SCR2)
SActive register (SCR3)
SNotification register (可选) (SCR4)
NCQ
SATA FIS
Register Host to Device FIS 0x27,主机 -> 设备
Register Device to Host FIS 0x34,设备 -> 主机
Set Device Bits FIS 0xA1,设备 -> 主机
DMA Activate FIS 0x39,设备 -> 主机
DMA Setup FIS 0x41,设备 <-> 主
BIST FIS 0x58,设备 <-> 主机
PIO Setup FIS 0x5F,设备 -> 主机
编辑
Data FIS 0x46,设备 <-> 主机
ATA Comannd
CFA ERASE SECTORS - C0h, Non-Data
IDENTIFY DEVICE - ECh, PIO Data-In编辑
PACKET - A0h, Packet编辑
READ DMA - C8h, DMA编辑
WRITE DMA - CAh, DMA
编辑
SATA DMA Read 流程
SATA DMA Write 流程
AHCI
HBA Configuration Registers
HBA Memory Registers - HBA通用寄存器(Generic Host Control)
Offset 00h: CAP – HBA Capabilities --HBA能力寄存器
Offset 04h: GHC – Global HBA Control --全局HBA控制寄存器
Offset 08h: IS – Interrupt Status Register --中断状态寄存器
Offset 0Ch: PI – Ports Implemented --端口实现寄存器
Offset 10h: VS – AHCI Version --AHCI版本
HBA Memory Registers - HBA端口寄存器(Port)
System Memory Structures
Data Transfer Operation
PRD中DBC字段更新规则
PRD中断规则
系统软件规则
参考文献
《SerialATA_Revision_3_1_Gold.pdf》SerialATA_Revision_3_1_Gold (kdocs.cn)
《serial-ata-ahci-spec-rev1-3-1.pdf》serial-ata-ahci-spec-rev1-3-1 (kdocs.cn)
《ATA8-ACS Draft Rev.6a__T13.pdf》ATA8-ACS Draft Rev.6a__T13 (kdocs.cn)
《pcie_3.0_总线规范.pdf》pcie_3.0_总线规范 (kdocs.cn)
文章:【转载】SATA专题文章 - 知乎 (zhihu.com)
规范文件放在WPS的在线文档中,可申请访问权限,若长时间未同意,可评论区提醒
百度网盘:百度网盘 请输入提取码
提取码:iunf
基本概念
HBA
Host Bus Adapter,即AHCI HBA(AHCI的主机控制器),可以集成在SOC芯片中,也可以是单独的AHCI主机控制器芯片。
AHCI HBA
独立于SOC芯片以外的AHCI HBA是一个PCI类设备。集成在SOC芯片中的AHCI HBA则使用内部总线访问,只是AHCI寄存器偏移量和功能复合AHCI规范标准。
OOB(Out of Band)信号解析
SATA信号链结的建立主要是靠OOB(Out Of Band)的检测实现的,并且向上层Link Layer提供了物理层的链结情况。
OOB主要的作用包括以下几点:
- 初始化(initialization),
- 传输速率的协商与对接(Speed negotiation),
---透过OOB handshake,host与device可以决定要在Gen1,Gen2或Gen3做data传输。 - 重置(Reset),
- 从省电状态(Slumer/Partial)的唤醒。
PIO
Programmed Input/Output,SATA的一种传输模式。
FPDMA
First Party DMA引擎
TAG
NCQ中最多32个命令的标签,用于指示使用哪个命令队列或命令队列状态。
FIS(Frame Information Structure)
FIS是SATA规范中的概念,SATA规范的传输层使用FIS进行通信。传输层不必关心需要传输或接收资讯的多少,只需把要传输的资料封装成FIS 格式,发送到Link Layer,或者把收到的FIS去除封装,提交给Application Layer。
参考《SerialATA_Revision_3_1_Gold.pdf》10 Transport Layer章节。每个FIS的格式都是固定的,并且对应唯一的ID,SATA Spec定义了14类FIS ID,真正被使用到的只有前面8类。
PRD
Physical Region Descriptor 物理区域描述符,PRD表是DMA引擎使用的数据结构,符合ATA/ATAPI主机适配器标准。PRD描述了在DMA传输期间用作数据来源或目标的内存区域。PRD表通常称为散/聚集列表(scatter/gather list)。
PIO
PIO模式是一种通过CPU执行I/O端口指令来进行数据的读写的数据交换模式。是最早先的硬盘数据传输模式,数据传输速率低下。分PIO mode0-6,速率从3.3MB/s到16.6MB/s不等。
Port Multiplier
端口倍增器。SATA 1.0的一个缺点就是可连接性不好,即连接多个硬盘的扩展性不好。因为在SATA 1.0规范中,一个SATA接口只能连接一个设备。SATA的制定者们显然也意识到了这个问题,于是他们在SATA2.0中引入了Port Multiplier的概念。Port Multiplier是一种可以在一个控制器上扩展多个SATA设备的技术,它采用4位(bit)宽度的Port Multiplier端口字段,其中控制端口占用一个地址,因此最多能输出15个设备连接----与并行SCSI相当。
NCQ
Native Command Queuing 原生指令序列,对多个命令进行重新排序,减少机械硬盘磁头切换耗时。
sht
scsi_host_template
SATA
Shadow Register
SATA Host 和Device之间有一组相同的寄存器,在Host端叫Shadow Registers,在Device端叫Task File。Host的Shadow Registers与Device的Task File通过Register FIS来进行同步。
Shadow Registers包括如下内容。
Command filed
要执行的command的编码,当被写入后,Device开始解析,并执行相应的Command的操作
Status"#"号代表和command耦和,不同的command,该filed代表的含义不同
如果bit0为1,则代表有Error,才需要去看Error field中8个bit 的情况
Features
和command field耦合,不同的command,feature指代的含义也不同
Error与具体命令有关
Alternate Status
和Status field中的内容完全相同
Device Control允许Host去软复位Device
下图更加详细的描述了Shadow Regs和Sata Regs。
SATA Registers
又称为Status and Control Registers,即SCRs,小端字节序。《SerialATA_Revision_3_1_Gold.pdf》14.1章节。
Sata Registers为SATA专属寄存器(相对于PATA),称为SCR(Status and Control register),包括SCR[0 ~ 15],但只用了SCR0~4。基地址SATA规范不做规定,但在AHCI规范中,该基地址在AHCI的端口寄存器表中是确定的,如果不支持AHCI,芯片厂商自由发挥。
AHCI中规定了SCR寄存器地址,如下。
SStatus register (SCR0)
32bit只读寄存器,指示接口和HOST的状态。
DET Detection,表示接口设备检测和Phy状态。
0000b 未检测到设备且未建立Phy通信
0001b 检测到设备存在,但Phy通信未建立
0011b 检测到设备存在并建立Phy通信
0100b 由于接口被禁用或运行在BIST环回模式下,导致Phy处于离线模式
SPD Speed,表示协商建立的接口通信速率0000b 未协商速度(设备不存在或通信未建立)
0001b 协商为Gen1通信速率(1.5 Gbps)
0010b 协商为Gen2通信速率(3 Gbps)
0011b 协商为Gen3通信速率 (6 Gbps)
IPM interface power management,显示当前接口电源管理状态
0000b 设备不存在或通信未建立
0001b 接口处于Active状态
0010b 接口处于Partial状态
0110b 接口处于Slumber状态
SError register (SCR1)
32bit只读写寄存器,用于补充Shadow Registers中的错误及诊断信息。对应位写1清0。
R 保留位
DIAG 诊断
A 检测到端口选择器存在
X 设备的存在发生改变
F 无法识别的FIS类型
T 传输状态转换错误
S 链路序列错误
H 握手错误
C CRC错误
D Disparity错误
B 10b到8b解码错误
W 检测到COMWAKE信号
I Phy内部错误
N PHYRDY信号变化
ERR 错误
E 内部错误
P 协议错误
C 不可恢复的通信或数据完整性错误
T 不可恢复的瞬态数据完整性错误
M 可恢复的通信错误
I 可恢复的数据完整性错误
SControl register (SCR2)
32bit读写寄存器,软件通过此寄存器控制HBA
DET 控制HOST适配器设备检测和接口初始化。
0000b 不检测设备和初始化接口
0001b 执行接口通信初始化顺序来建立通信
0100b 关闭Serial ATA接口,将Phy置于离线模式
SPD 配置速率协商时支持的最高速率
0000b 无速率限制
0001b 限制最大协商为Gen1通信速率(1.5 Gbps)
0010b 限制最大协商为Gen2通信速率(3 Gbps)
0011b 限制最大协商为Gen3通信速率 (6 Gbps)IPM IPM字段表示可以通过串行ATA接口电源管理功能调用的已启用的接口电源管理状态
0000b 无接口电源管理状态限制
0001b 不允许转换到 Partial(部分睡眠) 电源管理状态
0010b 不允许转换到 Slumber(完全睡眠) 电源管理状态
0011b 不允许转换到 Partial和Slumber 电源管理状态SPM 用于选择电源管理状态
0000b 没有请求电源管理状态转换
0001b 进入Partial电源管理状态
0010b 进入Slumber电源管理状态
0100b 进入活跃电源管理状态PMP Port Multiplier Port 端口扩展端口,所有传输FISes的PM Port字段中的4位将用该字段替代。如果不支持PMP,HBA可忽略该字段。
SActive register (SCR3)
32bit读写寄存器,用于传达收到的Set Device Bits FIS中的SActive字段(即Protocol Specific字段)。如果不支持NCQ,该寄存器可不实现。
主机可以通过对SActive寄存器的写操作来设置SActive寄存器中的位,但不能清零,只能通过Set Device Bits FIS的SActive字段来清零
SActive 对于NCQ协议,SActive值表示尚未成功完成的未完成命令队列集合。
Set Device Bits FIS如下:
SNotification register (可选) (SCR4)
32bit读写寄存器,当Host收到了设置Notification位的Set Device Bits FIS时,需要将该FIS中的PM Port字段值反映到本寄存器的Notify字段中,如FIS中PM Port字段为7,则本寄存器的Notify字段的bit7为1,且如果该FIS中的‘I’为置位了,还应该产生一个中断
NCQ
Native Command Queuing 命令队列,使得设备支持最大32个命令队列的同时处理,设备可根据情况自己决定先执行命令队列中的哪个命令,以此提高执行效率。HHD的磁头运动、SSD的擦除动作都会影响执行时间,有效的重新命令排序能提高命令执行效率。
《SerialATA_Revision_3_1_Gold.pdf》13.6.8章节介绍了NCQ使用的PFDMA引擎(First-party DMA),并定义了如何组织DMA集散列表,使用PRD表,但没具体介绍细节。
SATA FIS
8个FIS的结构都不相同,每个FIS都有几个bit控制位。如:
I :Interrupt 是否让Host产生中断,只会出现在设备 -> 主机的FIS中;
D:Direction 方向。
N:Notification 位
Register Host to Device FIS 0x27,主机 -> 设备
用来传输主机的Shadow Register(可以理解为CPU的传达室)的内容到设备,与ATA/ATAPI指令字和寄存器相容。
当Device接收到一个有效的Register FIS - H2D,检查C bit的内容,然后更新命令寄存器 / 控制寄存器中的内容中,
C bit为‘1’,Device按照Command Register中的命令执行命令,
C bit为‘0’,Device按照Control Register中的内容执行控制请求。
Register Device to Host FIS 0x34,设备 -> 主机
Device使用该FIS来修改host中shadow block里对应寄存器。
如在出现错误时,设备发送Register Device to Host FIS给Host,并置位Shadow Regs 的Status中相应bit。设备也可主动往HOST发送SDB FIS并置位Shadow Regs 的Status中相应bit,从而。ERROR放置错误码,有些地方ERROR中包含其它错误信息,Status放置状态位。
Status共包含BSY/DRDY/DF/DRQ/ERR五个bit
Set Device Bits FIS 0xA1,设备 -> 主机
SDB FIS的作用是Device用来改写host 的shadow register中的error或status的某些bits;
NCQ使用保留字段Protocol Specific来标记最多32个未完成命令中的待处理状态,每个bit称为一个tag,该字段也称为SActive。在NCQ命令中会有一个5bit的TAG字段(1<<5=32),TAG的值与此处的tag bit对应。
SDB FIS不改变状态寄存器中的bit7 BSY(Busy)、bit3 DRQ(Data Request)。即该FIS中Status该两个bit为Reserved。
主要用于NCQ command,每一个NCQ结束,设备都要回复一个SDB FIS告诉主机完成状态。
DMA Activate FIS 0x39,设备 -> 主机
主要用于NCQ write、DMA write,告诉主机是否准备好接收数据。
- Device发送该FIS同意主机以DMA方式向设备发送资料,
- 是Device对主机DMA写命令的一个回应,
- 当发送完FIS后,Device必须进入接收DMA资料接收状态,
- 每发送一个DATA FIS后,要再次收到DMA Activate FIS才能发送下一个DMA DATA FIS;
DMA Setup FIS 0x41,设备 <-> 主
发送方通过发送此FIS,让对方配置好DMA控制器,同时存储空间必须按要求处于准备状态。D位是Direction方向标志,1表示接下来的数据是发送给此FIS的接收方,0表示此FIS的接收方发送数据。简言之对发送此FIS的设备而言,D=1表示写数据,D=0表示读数据
BIST FIS 0x58,设备 <-> 主机
内建自测试(Build-in Self-test)用于厂商对芯片进行自测,排查问题或芯片设计非常重要。
PIO Setup FIS 0x5F,设备 -> 主机
由设备发送给主机,告诉主机相关PIO操作参数,包括了在PIO传输前和传输后shadow register的内容。
- 在PIO传输数据的过程中,Device必须先发送这个FIS给主机,表示Device准备好发送或接受数据。
- 与DMA传输一样,每传一个DATA FIS就要一个PIO SETUP FIS传输下一个DATA FIS;
Data FIS 0x46,设备 <-> 主机
唯一承载数据的FIS,数据量最大8KB
ATA Comannd
ATA Comannd 通过 Register Write FIS来完成,通过command字段来区分命令类型,不同命令类型需填充的FIS字段不相同,并非所有字段都需要填充。
ATA通过以下字段下发命令:Feature、Count、LBA、Device和Command,
命令类型非常多,参考《ATA8-ACS Draft Rev.6a__T13.pdf》7章节及Table B.1 ~ B.4。
PACKET命令用于传输SCSI的CDB命令(Command Descriptor Block)。
如下列举几个Command。
CFA ERASE SECTORS - C0h, Non-Data
IDENTIFY DEVICE - ECh, PIO Data-In
PACKET - A0h, Packet
READ DMA - C8h, DMA
WRITE DMA - CAh, DMA
SATA DMA Read 流程
Host发起DMA读类命令,Device收到这些DMA读类命令后准备数据,Device准备好数据后通过DMA发送Data FIS给Host,Host收到数据后,如果已无数据待发送或出错则通过Register Device to Host FIS告诉Host数据已发送完,否则继续准备数据并发送Data FIS给Host,直到数据发送完或发送错。流程图待补充。
SATA DMA Write 流程
Host准备待发送的数据后发送DMA写类命令给Device,Device准备好接收数据后发送 DMA Activate FIS给Host,Host收到 DMA Activate FIS后通过DMA发送Data FIS给Device,Device收到数据后,如果已无数据待接收或出错则通过Register Device to Host FIS告诉Host数据已接收完,否则继续发送准备接收数据后发送 DMA Activate FIS给Host,让Host继续发送数据,直到Host将所有数据发送完成或发送错误。流程图待补充。
AHCI
AHCI为SATA的上层协议规范,SATA规范只规定了FIS结构、Shadow Regs(Command/Control)、SATA Regs(SCR0~15)、命令流程,并未规定SATA控制器如何给软件提供访问接口,如软件如何组装FIS、在哪个地址读取SCR0~4,使得不同芯片的sata驱动不同。为解决此问题Interl推出了一个AHCI规范,用于规范SATA对上层应用的接口。
HBA Configuration Registers
HBA Configuration Registers通过PCI配置空间来定义,包括PCI Header及3个Capability (PMCAP、MSICAP、SATACAP)。
PCI Header
Start (hex) | End (hex) | Symbol | Name |
00 | 03 | ID | Identifiers |
04 | 05 | CMD | Command Register |
06 | 07 | STS | Device Status |
08 | 08 | RID | Revision ID |
09 | 0B | CC | Class Codes |
0C | 0C | CLS | Cache Line Size |
0D | 0D | MLT | Master Latency Timer |
0E | 0E | HTYPE | Header Type |
0F | 0F | BIST | Built In Self Test (Optional) |
10 | 23 | BARS | Other Base Address Registres (Optional) <BAR0-4> |
24 | 27 | ABAR | AHCI Base Address <BAR5> |
2C | 2F | SS | Subsystem Identifiers |
30 | 33 | EROM | Expansion ROM Base Address (Optional) |
34 | 34 | CAP | Capabilities Pointer |
3C | 3D | INTR | Interrupt Information |
3E | 3E | MGNT | Min Grant (Optional) |
3F | 3F | MLAT | Max Latency (Optional) |
0x09 (Class Code)
设备类型,Base Class Code =1,表示是一个大容量存储设备;Sub Class Code=6,表示是一个串行ATA设备;PI=1且Sub Class Code=6时,表示这是一个主要版本为1的AHCI HBA。88se9230芯片此寄存器值为0x010601。
0x34(CAP)
能力寄存器字段的值指向了PMCAP,用于描述电源管理能力
0x3C(INTR)
中断信息,如果HBA是单功能PCI设备,则应将INTR.IPIN设置为01h以指示INTA#引脚
0x10-0x20(BAR0-BAR4)
字段描述其余BAR,可用于支持遗留软件的HBA实现本机IDE和总线主IDE。
0x24(BAR5)字段为AHCI Base Address,简称ABAR。用于容纳AHCI寄存器以及厂商特定的寄存器,即AHCI的寄存器是基于BAR5来偏移的。(不一定所有芯片都遵循此规范,从linux的ahci驱动来看,有使用BAR0/2/4的芯片,如ST ConneXt使用BAR0)
规定了3个功能寄存器,PMCAP(CID=0x1)、MSICAP(CID=0x5)、SATACAP(CID=0x12),功能寄存器PCIECAP(0x10)未做单独规定
PCI 的Capabilities组成:8 bit Cap ID (CID) + 8 bit Next Capability + 剩余内容(视CID而定,查规范或芯片手册)
查看88SE9230配置空间,如下:
offset0x34: 0x40为第一个功能寄存器地址(此处为PMCAP偏移地址),即0x40偏移处存放下了一个功能描述。
offset0x40: Byte1=0x01为PMCAP-ID,Byte2=0x50为下一个功能偏移(此处为MSICAP偏移地址);
offset0x50: Byte1=0x05为MSICAP-ID,Byte2=0x70为下一个功能偏移(此处为PCIECAP偏移地址);
offset0x70: Byte1=0x10为PCIECAP-ID,Byte2=0xe0为下一个功能偏移(此处为SATACAP偏移地址);
offset0xe0: Byte1=0x12为SATACAP-ID,Byte2=0x00表示无下一个功能;
PMCAP
描述了电源管理功能;
MSICAP
描述了MSI消息中断功能,如地址,数据等等;
PCIECAP
描述了pcie规范定义的功能;
SATACAP
描述了SATA版本、BAR Offset 和BAR Location。如88SE9230的SATACAP+4 = 0x48,则BAR Offset=0x4(0x10 offset), BAR Location=0x8(BAR4)。
AHCI驱动并没看到使用此功能的描述:
enum {AHCI_PCI_BAR_STA2X11 = 0,AHCI_PCI_BAR_CAVIUM = 0,AHCI_PCI_BAR_ENMOTUS = 2,AHCI_PCI_BAR_CAVIUM_GEN5 = 4,AHCI_PCI_BAR_STANDARD = 5, }; int ahci_pci_bar = AHCI_PCI_BAR_STANDARD;/* Some devices use non-standard BARs */if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06)ahci_pci_bar = AHCI_PCI_BAR_STA2X11;else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000)ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS;else if (pdev->vendor == PCI_VENDOR_ID_CAVIUM) {if (pdev->device == 0xa01c)ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;if (pdev->device == 0xa084)ahci_pci_bar = AHCI_PCI_BAR_CAVIUM_GEN5;}
HBA Memory Registers - HBA通用寄存器(Generic Host Control)
基地址计算公式:Base = BAR5(从Linux源码得知,并非所有芯片都使用BAR5)
Offset 00h: CAP – HBA Capabilities --HBA能力寄存器
AHCI_ONLY[8]:用于指示此HBA是否只支持AHCI,如果为1:只支持AHCI,0:除了支持AHCI外还支持传统SATA接口。
PORTS[4:0]:指示端口个数Offset 04h: GHC – Global HBA Control --全局HBA控制寄存器
AHCI_EN[31]:AHCI使能,1:使能AHCI。0:关闭AHCI,关闭AHCI后软件只能使用传统机制与HBA通信。
MSI_RSM[2]:MSI是否恢复到单一模式(未能理解单一MSI的用法)。此位由硬件置位或清除。1:正在使用单一MSI模式。0:HBA未恢复到单一MSI模式。
INT_EN[1]:HBA全局中断使能位。1:使能中断,0所有端口中断被关闭。
HBA_RST[0]:软件通过此为对HBA进行复位。HBA完成复位后由硬件置0。Offset 08h: IS – Interrupt Status Register --中断状态寄存器
IPS[31:0]:指示控制器中哪些端口有挂起的中断并且需要服务。
Offset 0Ch: PI – Ports Implemented --端口实现寄存器
此寄存器指示哪些端口被暴露出来,比如CAP.PORTS=6,但只有端口0和端口6可被用户使用,其余端口无法使用。此寄存器的目的是为了让系统厂商构建低于HBA芯片全端口数量的平台。此寄存器是按bit位表示,为1表示可被软件使用,0表示不能被软件使用。
Offset 10h: VS – AHCI Version --AHCI版本
HBA支持的AHCI版本号,高2字节为主版本号,低2字节为次版本号。
......
HBA Memory Registers - HBA端口寄存器(Port)
HBA每个端口寄存器定义相同
基地址计算公式:Port Base = BAR5 + 0x100 + (0x80 * Port number)
System Memory Structures
大部分软件与SATA设备之间的交流都是通过系统内存来完成的,存放于这些内存中的数据结构指示了所有接收和发送的FIS状态,以及数据传输的指针;
有些附加交流是通过HBA寄存器完成的。
Command Header的CTBA指向了一个命令表:
Command Header字段解析
Physical Region Descriptor Table Length (PRDTL):PRD表的条目个数,每个条目16字节(4个DW),条目数范围[0, 65535],用来告诉HBA何时停止获取PRD。此值可以为0.
Port Multiplier Port (PMP): 指示在传输时构造Data FIS时应使用的端口号,如果使用直连端口,该值配置为0.
Clear Busy upon R_OK (C): PxTFD.STS.BSY和PxCI.CI位在传输完成并收到R_OK后自动清除。
BIST (B): 内建自测Built-in Self Test,1 指示软件构建的是一个BIST FIS,HBA将发送此FIS并进入测试模式,测试内容不在规范范围之内。
Reset (R):
Prefetchable (P): 预加载,只有当PRDTL不为0或ATAPI为1时才能配置为1。如果为1且PRDTL不为0,在预期执行数据传输时,HBA可以预取PRD或ATAPI命令。当系统软件使用NCQ或FIS-base交换时不会置位该位。
Write (W): 1 写操作,0 读操作。
ATAPI (A):1 设备将发送PIO Setup FIS
Command FIS Length (CFL):FIS长度DWord个数,HBA通过该字段知道发送多长的FIS数据。
Physical Region Descriptor Byte Count (PRDBC): 状态字段,用于指示当前已经完成的读写字节数。
CTBA:命令表所在的内存物理地址(32bit或64bit),必须128字节对齐,即bit[6:0]保留
Command Table字段解析
Command FIS
这是一个软件构建的FIS命令结构,规范描述的是HBA设置PxTFD.STS.BSY后发送该FIS到连接端口。个人理解:HBA直接根据来组装传输层的FIS并发送到连接端口 或 HBA根据CFIS更新HOST端的Shadow Regs对应字段(SATA规范),传输层再根据Shadow Regs组装FIS并发送到连接端口
ATAPI Command (ACMD)
如果Command Table中的’A’为1,则此字段包含12或16字节的ATAPI命令,长度取决于CFIS字段中的PIO Setup FIS命令。通过寄存器写CFIS写入PACKET命令
ATAPI命令即为SCSI的CDB(命令描述块)命令。
驱动使用SCSI接口来控制ATA设备时需要使用SCSI的CDB命令,而ATA本身不支持该命令,后来ATA规范加入了ATAPI命令,用于支持SCSI的CDB命令。
Physical Region Descriptor Table (PRDT)
PRD表用于存放聚散链表,条目个数为0~65535个,每个条目4个DW
Data Base Address (DBA)
数据块的内存物理地址,地址为Word对齐,所以bit0始终为0
Interrupt on Completion (I)
中断使能,此条目的数据块传输完成后发出中断,PxIS.DPS=1
DBC
数据块的字节数,字节数量为DBC+1,由于数据量为Word对齐,所以DBC的bit0始终为1。
Data Transfer Operation
数据传输操作
PRD中DBC字段更新规则
传输开始之前由软件填0。仅反映了收到了R_OK且CRC有效的数据。如果需要,硬件可以在每个数据FIS传输后更新字节计数(每个FIS包含了由多个PRD组成的PRD表)。
PRD中断规则
当PRD表中所有PRD指向的数据都传输完成且FIS中包含了‘I’位,则HBA产生中断。
系统软件规则
创建命令的基本步骤:
通过PxCI(=0) 和 PxSACT(=0)查找空闲命令槽,找到空闲命令槽后
- 在系统内存中组装命令FIS,并将地址写入PxCLB;
- 如果为ATAPI命令,ACMD字段处填充ATAPI命令;
- 系统软件在PxCLB处填充如下内容:
PRDTL(PRD个数) + CFL(FIS DWord数) + A(ATAPI) + W(读/写) + P(预取) + (PMP)
- 如果为命令队列,软件需要先置位PxSACT对应的位。
- 置位PxCI.CI对应位,告诉HBA此命令是活动的。
配置Command Head P位(预取位):
为了避免HBA卡预取不能使用的项,软件必须遵循以下规则:
- 当构建排队的ATA命令时,软件不应该设置CH(pFreeSlot).P。串行ATA设备可能以与发送命令不同的顺序运行命令。
- 当构建命令到几个设备后面的端口倍增器且启用基于FIS的交换时,软件不应该设置CH(pFreeSlot) .P。FISes可能是从不同设备的端口倍增器接收到的,而不是刚刚由HBA发送的。
处理已完成命令:
中断处理函数处理命令完成中断。中断服务函数通过IS.IPS识别是哪些端口有中断挂起。
对有中断挂起的端口做如下处理:
- 软件通过读取PxIS来确定产生中断的原因;
- 软件清除PxIS对应位;
- 软件清除IS.IPS对应位;
- 如果执行非NCQ命令,软件将读取PxCI寄存器,并将当前值与软件之前发出的尚未执行的命令列表进行比较。如果执行NCQ命令,软件将读取PxSACT寄存器,并将当前值与软件先前发出的命令列表进行比较。软件成功地完成所有未执行的命令,其相应的位已在相应的寄存器中被清除。PxCI和PxSACT是volatile寄存器;软件应该只使用它们的值来确定已经完成的命令,而不是确定以前发出过哪些命令;
- 如果有错误(记录在PxIS寄存器中),软件将执行错误恢复操作。