3

我已经编写了一个小 AHCI 驱动程序两个星期了。我已经阅读了这篇文章英特尔的串行 ATA 高级主机控制器接口 (AHCI) 1.3。有一个例子,它显示了如何通过 DMA 模式(osdev.org)读取扇区。我已成功完成此操作(ATA_CMD_READ_DMA 0xC8),但是当我尝试将扇区(ATA_CMD_WRITE_DMA 0xCA)写入设备时,HBA 设置了错误

Offset 30h: PxSERR – Port x Serial ATA Error - Handshake Error

(这是从英特尔 AHCI 规范解码)。我不明白为什么会这样。请帮我。

另外,我尝试发出命令IDENTIFY 0xEC,但没有成功...

4

1 回答 1

9

你差不多两个月前问过这个问题,所以我不确定你是否已经弄清楚了。请注意,我是从记忆中写出必须首先做的事情等。我可能没有记住全部或准确地记住必须做的事情。您应该为所有内容参考 AHCI 规范。这样做的方法是多种多样的,因为有这样做的程序员。出于这个原因,我不包括代码示例。

对于初学者,请确保您已相应地设置了 HBA 状态机。您将能够在同一 SATA 规范 1.3 中找到 HBA 支持的状态机的参考。取而代之的是,您应该检查一些寄存器。

请注意,所有页码都是针对在 Adob​​e Acrobat 中查看而给出的,比实际文档中的页码多 8 页

从规范的第 24 页和第 25 页,检查 GHC.IE 和 GHC.AE。这两个将打开中断并确保 HBA 工作在 AHCI 模式下。另一个需要检查的非常重要的寄存器是 CAP.SSS(第 23 页)。如果该位为高,则 HBA 支持交错启动。这意味着 HBA 不会对任何端口执行任何协议协商。在执行以下操作之前,请存储 PxSIG 的值(第 35 和 36 页)。

要真正启动端口,您需要访问规范的第 33、34 和 35 页。这些页面涵盖了 PxCMD 寄存器。对于 HBA 支持的每个端口(检查 CAP.NP 以了解有多少),您必须切换高位 PxCMD.SUD。将该位切换为高电平后,您需要轮询 PxSSTS(第 36 页)以检查 PHY 的状态。您可以检查 CAP.ISS 以了解您可以期望在 PxSSTS 上看到“活跃”的速度。

启动端口后,检查 PxSIG(第 35 和 36 页)。该值应该与您开始时不同。我现在不记得你可以期望他们变成什么,但他们会有所不同。当实际建立通信时,设备向主机发送初始 FIS。如果没有第一个 FIS,HBA 将无法与设备通信。(正是在第一个 FIS 中,HBA 在 PxSIG 中设置了正确的位。)

最后,在所有这些之后,您需要设置 PxCMD.FRE(第 34 页)。端口命令寄存器中的该位使 FIS 能够传送到设备。如果该位为低,HBA 将忽略您发送给它的任何内容。

正如我在开始时所说,我不确定这是否会回答您的所有问题,但我希望它确实能让您走上正轨。为了有效地与 SATA 设备通信,我将从记忆中了解必须完成的事件。我可能没有完全记得。

我希望这可以帮助你。

于 2012-09-12T03:33:42.047 回答