Explicación detallada de la pila de protocolos SATA: desde la señal serial hasta la lectura y escritura del disco duro

Tabla de contenido

1. Interfaz y cable SATA

2. Descripción general de la pila de protocolos SATA

2.1 Descripción general de la capa física

2.2 Descripción general de la capa de enlace y la capa de transporte

2.3 Descripción general de la capa de comando

3. Explicación detallada de la capa de enlace y la capa de transporte

3.1 Inicialización del enlace

3.2 Lista de primitivas SATA

3.3 Mecanismo de alineación de bytes: primitiva ALIGN

3.4 codificación 8b10b

3.5 Estructura del paquete FIS

3.6 Cálculo de la CRC

3.7 Proceso de envío de FIS

3.8 Codificación/Descodificación FIS

3.9 Mezcla repetida de primitivas

3.10 Control de flujo

3.11 Resumen de la capa de enlace y la capa de transporte

4. Capa de comando: lectura y escritura DMA

Referencias


SATA es el protocolo de interfaz más utilizado para discos duros. Este artículo presenta brevemente la pila de protocolos SATA, con la esperanza de permitir a los lectores comprender el propósito de varios mecanismos y comprender algunos detalles. Antes de leer los cientos de páginas de la extensa Especificación SATA, puede leer este artículo primero para tener una idea general

Abro un núcleo de host SATA Gen2 (HBA), que puede ejecutarse en Xilinx FPGA con GTH. Proporcione un ejemplo basado en la placa de desarrollo oficial de netfpga-sume  , que puede realizar la lectura y escritura del disco duro:

github: SATA HBA de código abierto que puede ejecutarse en Xilinx FPGA con GTH​github.com/WangXuan95/FPGA-SATA-HBA

1. Interfaz y cable SATA

La interfaz SATA se muestra en la Figura 1, en la que el adaptador de bus de host SATA (HBA) es el controlador de lectura y escritura del disco duro, que a menudo se implementa mediante el conjunto de chips de la placa base en la computadora (en mi proyecto de código abierto, el HBA se implementa por la FPGA). El dispositivo SATA es un disco duro (disco duro mecánico o disco duro de estado sólido). Están conectados por dos pares de pares diferenciales, entre los cuales (SATA_A+, SATA_A-) el par diferencial es HBA emisor y dispositivo receptor (es decir, canal TX para HBA y canal RX para dispositivo); (SATA_B+, SATA_B- ) El par diferencial es transmisión de dispositivo, recepción HBA (para HBA, es canal RX, para dispositivo, es canal TX). Los relojes de velocidad de los dos canales son los mismos, respectivamente:

  • SATA Gen1: 1,5 Gbps
  • SATA Gen2: 3 Gbps
  • SATA Gen3: 6 Gbps

Figura 1: interfaz SATA (dos pares de pares diferenciales)

La Figura 2 (arriba)  es una foto de la interfaz SATA de una unidad de estado sólido, en la que el puerto de 7 pines más estrecho de la izquierda es una interfaz de señal y se incluyen dos pares diferenciales (SATA_A, SATA_B). El puerto más ancho de 15 pines a la derecha se usa para suministrar energía al disco duro. Las definiciones de pin de estos PIN se muestran en la Figura 2 (abajo) .

Figura 2: Mapa físico de interfaz de disco duro SATA (arriba); definición de pin de interfaz (abajo)

La Figura 3 es el cable SATA, la izquierda es el cable de alimentación, que puede convertir el puerto de alimentación de 4 pines proporcionado por la fuente de alimentación del escritorio en el puerto de alimentación SATA de 15 pines. El lado derecho es el cable de señal, un extremo está conectado al puerto 7PIN del disco duro y el otro extremo está conectado al HBA.

Figura 3: cable de alimentación SATA (izquierda); cable de señal SATA (derecha)

2. Descripción general de la pila de protocolos SATA

Como se muestra en la Figura , la estructura de la pila de protocolos SATA incluye desde aguas abajo hasta aguas arriba: capa física (PHY), capa de enlace (capa de enlace), capa de transporte (capa de transporte) y capa de comando (capa de comando).

Figura 4: Pila de protocolos SATA

2.1 Descripción general de la capa física

El flujo descendente de la capa física está conectado al dispositivo SATA con dos pares de pares de señales diferenciales en serie, y las señales paralelas se transmiten entre el flujo ascendente y la capa de enlace. El trabajo principal realizado por la capa física incluye:

  • Recuperación del reloj : diferente de la comunicación común de baja velocidad (como el puerto paralelo ATA del disco duro antiguo con decenas de MHz) y la comunicación de velocidad media (como DDR3 y MIPI LVDS con cientos de MHz), en la alta velocidad de varios Gbps como SATA, cada señal es difícil de alinear entre ellas, por lo que SATA no usa diferentes líneas de señal para transmitir relojes, sino que modula el reloj y los datos al mismo par de pares diferenciales a través de la codificación 8b10b, por lo que el canal RX de la capa física necesita usar un bucle de bloqueo de fase (PLL, un circuito analógico) para recuperar el reloj de la señal en serie, los datos RX se pueden muestrear correctamente solo con el reloj recuperado.
  • Conversión de serie a paralelo : el canal RX de la capa física necesita usar el reloj recuperado para convertir los datos RX en señales paralelas en unidades de 10 bits; el canal TX necesita convertir las señales paralelas en unidades de 10 bits proporcionadas por la capa de enlace en señales seriales y enviarlas. Por ejemplo, para SATA Gen2 de 3 Gbps, la señal paralela convertida puede tener un ancho de 150 MHz y 20 bits o un ancho de 75 MHz y 40 bits.
  • Alineación de bytes : la conversión de serie a paralelo implica cómo definir el límite de unidades paralelas de 10 bits en el flujo de bits en serie. SATA utiliza un primitivo ALIGN especial para definir el límite de byte. Bajo la codificación 8b10b, el primitivo ALIGN generará un único 10- modo de combinación de bits, la capa física es responsable de identificar este modo, cada vez que se encuentra este modo, el receptor sabe que actualmente se encuentra en un límite de 10 bits.

2.2 Descripción general de la capa de enlace y la capa de transporte

Este artículo combina la capa de enlace y la capa de transporte , porque el acoplamiento entre los dos es relativamente grande, y personalmente creo que es mejor entenderlo juntos. La capa de enlace y la capa de transporte deben implementar: códec 8b10b, generación y detección primitivas (incluido el reconocimiento de límites de paquetes FIS), codificación/descodificación, generación y verificación de CRC, control de flujo. Finalmente, la capa de transporte interactúa con la capa de comando ascendente utilizando una  estructura de paquetes denominada Estructuras de información de tramas  ( FIS ). Las funciones de la capa de enlace y transporte se describen a continuación:

  • Codificación y decodificación 8b10b : los datos paralelos del canal RX de la capa física son datos codificados 8b10b en unidades de 10 bits, y la capa de enlace necesita decodificarlos en datos de 8 bits (1 byte); mientras que el canal TX necesita codificar datos de 8 bits en 10bit Obviamente, la codificación 8b10b conducirá a una pérdida de una quinta parte del ancho de banda.La razón por la que se diseña esta redundancia es para distribuir el 0 y el 1 de la manera más uniforme posible, para que el receptor pueda recuperar el reloj de la señal.
  • Inserción y detección de primitivas : SATA especifica varias primitivas (Primitive), y la longitud de cada primitiva es de 4 bytes. Las primitivas no transportan datos, pero se utilizan para el control de la comunicación. Las primitivas cubiertas en este artículo incluyen ALIGN, CONT, SYNC, R_RDY, R_IP, R_OK, R_ERR, X_RDY, SOF, EOF, WTRM, HOLD, HOLDA. Las primitivas tienen sus propias funciones, por ejemplo, la primitiva ALIGN se usa para la alineación de bytes, la primitiva X_RDY se usa para decirle a la otra parte que desea enviar un FIS a la otra parte, la primitiva SOF se usa para indicar el comienzo de el FIS, y la primitiva EOF se usa para indicar el FIS (a través de las primitivas SOF y EOF, el canal RX puede analizar correctamente el límite del paquete FIS). Para el canal TX, las primitivas deben insertarse correctamente. Para el canal RX, las primitivas deben detectarse y la transición de estado de la máquina de estado debe llevarse a cabo de acuerdo con las funciones especificadas por las primitivas.
  • Codificación/descodificación FIS : El codificador (Scrambler) y el decodificador pueden generar una secuencia de números pseudoaleatorios.Después de cada reinicio, la secuencia de números pseudoaleatorios generada es fija. En el canal TX, los datos FIS que se van a enviar deben someterse a XOR con la secuencia de números pseudoaleatorios generada por el codificador, lo que se denomina codificación; en el canal RX, los datos FIS recibidos deben combinarse con los números pseudoaleatorios secuencia de números generada por el descifrador Las secuencias también se someten a XOR bit a bit , lo que se conoce como descifrado. Debido a que los datos permanecen sin cambios después de los dos XOR, se garantiza que los datos se puedan restaurar correctamente después de codificar primero y luego decodificar. El propósito de la codificación es hacer que los datos transmitidos en el cable SATA estén más codificados, de modo que la radiación electromagnética esté más cerca del ruido blanco (en lugar de concentrarse en una determinada frecuencia), reduciendo así la interferencia electromagnética (EMI).
  • Codificación repetida de primitivas : la codificación FIS solo puede reducir la EMI durante la transmisión FIS. Cuando SATA está transmitiendo una gran cantidad de primitivas repetidas, para reducir la EMI, se debe usar otro mecanismo similar: la codificación repetida de primitivas. Este proceso usa la primitiva CONT.
  • Generación y verificación de CRC : el canal TX debe calcular el CRC en función de los datos FIS y adjuntarlo al final del FIS; el canal RX debe generar un CRC en función de los datos FIS recibidos y compararlo con el CRC recibido ( es decir, verificación CRC). Si no coincide, significa que hay un error de bit en la transmisión FIS, y el FIS debe descartarse y el error debe informarse al flujo ascendente.
  • Control de flujo : la velocidad de lectura/escritura del medio del disco duro a menudo no coincide con la velocidad de la interfaz SATA, por lo que la capa de transporte estipula un mecanismo de control de flujo (Flow Control), que depende de las primitivas HOLD y HOLDA, incluidos dos tipos de control de flujo:
    • Control de flujo del remitente : cuando el remitente aún no está listo para enviar datos FIS (por ejemplo, la velocidad de lectura del disco duro es más lenta que la velocidad de la interfaz SATA), el remitente puede insertar la primitiva HOLD para completar el espacio en blanco, para que pueda admitir el envío de datos "intermitentes".
    • Control de flujo del receptor : cuando el receptor no puede recibir datos FIS temporalmente (por ejemplo, la tasa de escritura en el disco duro es más lenta que la tasa de la interfaz SATA), el receptor puede enviar la primitiva HOLD al remitente, diciéndole al remitente " no envíe tan rápido, acepto "No más", el remitente suspenderá el envío de datos y enviará la primitiva HOLDA al receptor para completar el espacio en blanco.

Tantas funciones mencionadas anteriormente pueden hacer que los lectores confundan su relación lógica, por ejemplo, una estructura de capa de enlace y capa de transporte Figura 5 .

Figura 5: Ejemplo de implementación de capa de enlace y capa de transporte

2.3 Descripción general de la capa de comando

Capa de comando : acepte comandos de lectura y escritura ascendentes, genere y analice el comando FIS y realice operaciones de lectura y escritura en el disco duro. SATA admite conjuntos de comandos ATA y ATAPI, y cada conjunto de comandos incluye una variedad de métodos de lectura y escritura del disco duro, como el modo PIO, el modo DMA, etc., por lo que una capa de comando completa debe implementar una máquina de estado con muchos comandos complicados. pero su propósito no es complicado, son utilizar varios métodos para lograr la lectura y escritura del disco duro. Este artículo solo presentará brevemente el método DMA: incluido cómo usar el método DMA para enviar y recibir FIS, para leer y escribir en el disco duro.

Hasta ahora, los lectores han tenido un conocimiento aproximado de la pila de protocolos SATA. A continuación se explicarán algunos detalles uno por uno desde la capa de enlace hacia arriba. No entiendo los detalles de la capa física, por lo que este artículo no habla de la capa física.

3. Explicación detallada de la capa de enlace y la capa de transporte

3.1 Inicialización del enlace

Después de encender el sistema, se debe realizar la inicialización del enlace (inicialización del enlace) entre el HBA y el dispositivo. Antes de la inicialización, los datos FIS no se pueden transmitir normalmente entre el HBA y el dispositivo, por lo que SATA usa una señal fuera de banda (señal OOB) para detectar la existencia de la otra parte, realizando así la inicialización del enlace. Se denomina señal "fuera de banda" porque conduce el par diferencial al mismo voltaje común, que no corresponde ni a un 0 lógico ni a un 1 lógico.

Se estipula que el nivel de línea diferencial es diferente (0 lógico o 1 lógico) es SEÑAL, y el nivel de línea diferencial es el mismo que NO SEÑAL. SATA especifica dos señales OOB:

  • COMINIT  : se refiere al envío continuo de 6 SEÑALES, cada SEÑAL dura 106ns, y NOSIGNAL dura 320ns entre dos SEÑALES adyacentes.
  • COMWAKE  : envía continuamente 6 SEÑALES, cada SEÑAL dura 106ns, y NOSIGNAL dura 106ns entre dos SEÑALES adyacentes.

La Figura 6 es un diagrama de secuencia de la inicialización del enlace. Primero, el HBA envía un COMINIT y espera que el dispositivo responda al COMINIT. Si no se reciben COMINIT, el host puede enviar más COMINIT hasta que se reciba uno. Luego, el host envía COMWAKE al dispositivo y espera a que el dispositivo responda COMWAKE. Después de eso, el HBA envía continuamente un TONO DE MARCACIÓN de datos especiales (traducido como tono de marcación, que es un patrón alternado de 1 y 0) al dispositivo, y espera a que el dispositivo envíe la primitiva ALINEACIÓN. primitivo, el HBA también envía el lenguaje primitivo ALIGN al dispositivo, la inicialización del enlace se puede completar. Después de la inicialización, tanto el HBA como el dispositivo se envían primitivos SYNC continuos entre sí, lo que indica que están inactivos y listos para enviar y recibir FIS.

Figura 6: Diagrama de tiempo para la inicialización del enlace. Extraído de la referencia [3]

3.2 Lista de primitivas SATA

Después de que se inicializa el enlace, SATA siempre transmite primitivas y datos (lo que se puede llamar señalización en banda). La longitud de todas las primitivas en SATA (antes de la codificación 8b10b) es de 4 bytes (1 dword), y los datos se transmiten en otros momentos excepto las primitivas (aunque no son necesariamente datos FIS, también pueden ser basura fuera de los datos FIS), y el los datos también están en la unidad de 1 dword.

Dword se traduce como "doble palabra", lo que significa 4 bytes.

Las primitivas y los datos involucrados en este artículo se muestran en la Tabla 1 (no se enumeran varias primitivas poco comunes), y la forma de byte y la forma dword están antes de la codificación 8b10b.

Tenga en cuenta que todos los DWORD en SATA son little-endian. Después de expresarse en forma de byte, el byte bajo viene primero y luego el byte alto. Cuando se transmite en la capa física, el byte bajo de DWORD se transmite primero y luego el byte alto. del DWORD se transmite. byte. Por ejemplo, para la primitiva ALIGN, el byte BC se transmite primero y el byte 7B se transmite en último lugar.

Tabla 1 : definición primitiva de SATA

nombre formato de bytes (hexadecimal) Formato Dword (hexadecimal) Si el primer byte es K función/significado
ALINEAR BC 4A 4A 7B 7B4A4ABC Sí (K28.5) alineación de bytes
CONT 7C AA 99 99 9999AA7C Sí (K28.3) Codificación/Descodificación Primitiva Repetida
SINCRONIZAR 7C95 B5 B5 B5B5957C Sí (K28.3) Inactivo (sin transmitir FIS)
R_RDY 7C 95 4A 4A 4A4A957C Sí (K28.3) Listo para Recibir FIS
ROTURA 7C B5 55 55 5555B57C Sí (K28.3) recibiendo FIS
R_OK 7C B5 35 35 3535B57C Sí (K28.3) Recibir FIS con éxito
R_ERR 7C B5 56 56 5656B57C Sí (K28.3) Error al recibir FIS
X_RDY 7C B5 57 57 5757B57C Sí (K28.3) listo para enviar fis
SOF 7C B5 37 37 3737B57C Sí (K28.3) enviar FIS comenzando con
fin de semana 7C B5 D5 D5 D5D5B57C Sí (K28.3) enviar fis fin
wtrm 7C B5 58 58 5858B57C Sí (K28.3) Enviar fin FIS
SOSTENER 7C AA D5 D5 D5D5AA7C Sí (K28.3) Control de flujo
EN CASO 7C AA 95 95 9595AA7C Sí (K28.3) Control de flujo
TONO DE MARCACIÓN 4A 4A 4A 4A 4A4A4A4A No Usado durante la inicialización del enlace
DATOS (datos ordinarios) XX XX XX XX XXXXXXXX No Datos FIS o datos basura

Tenga en cuenta que el significado de XXXXXXXX en DATA (datos ordinarios) en la Tabla 1 es que los datos ordinarios son una palabra clave que puede tomar cualquier valor.

Después de leer la Tabla 1 , es posible que tenga preguntas sobre la distinción entre primitivas y datos: por ejemplo, si un dato común resulta ser 0xB5B5957C, que es lo mismo que la primitiva SYNC, entonces cómo distinguirlo como datos en lugar de la primitiva SYNC ? De hecho, se basa en información adicional: depende de si el primer byte (el byte más bajo) de dword está codificado como K. Si es K, es primitivo; de lo contrario, es un dato común. Si es K, en realidad es información adicional de 1 bit, que se realiza mediante la codificación 8b10b (consulte a continuación para obtener más detalles: codificación 8b10b).

Tenga en cuenta que el primer byte de DIAL-TONE utilizado para la inicialización del enlace no es K, lo que significa que DIAL-TONE no es una primitiva, ni se puede distinguir de los datos ordinarios 0x4A4A4A4A. De hecho, debido a que DIAL-TONE es solo un concepto antes de la inicialización del enlace, todos los 0x4A4A4A4A encontrados antes de la inicialización del enlace se consideran como DIAL-TONE, y DIAL-TONE después de la inicialización del enlace se consideran datos ordinarios.

3.3 Mecanismo de alineación de bytes: primitiva ALIGN

La capa inferior de SATA es la señal en serie, que implica cómo definir el límite de bytes en el flujo de bits en serie. Por esta razón, SATA utiliza una primitiva de ALINEACIÓN especial para definir el límite de bytes. La primitiva ALIGN es la única de las primitivas más especiales, su primer byte es K28.5, mientras que el primer byte de otras primitivas es K28.3 (para los conceptos de K28.3 y K28.5, ver más abajo: codificación 8b10b ), bajo la codificación 8b10b, la primitiva K28.5 generará un modo de combinación único de 10 bits, y la capa física es responsable de identificar este modo. Siempre que se encuentra este modo, el receptor sabe que actualmente se encuentra en un modo de combinación de 10 bits. .

Teniendo en cuenta que la frecuencia del reloj tiene cierta precisión, el receptor aún puede definir correctamente el límite de 10 bits durante un período de tiempo después de encontrar ALIGN, pero después de un tiempo lo suficientemente largo, el límite aún se perderá, por lo que SATA requiere que ambas partes envíen periódicamente La primitiva ALIGN, conocida como el mecanismo de inserción ALIGN:

  • La especificación SATA estipula que se deben insertar al menos 2 primitivas ALIGN consecutivas por cada 256 dwords enviados . Y se permite que sea más frecuente, por ejemplo, se pueden insertar 2 primitivas ALIGN consecutivas cada 128 dwords.
  • Siempre que se inicialice el enlace, el mecanismo de inserción de ALIGN funciona en cualquier momento, independientemente de si se están enviando primitivas o datos en ese momento.
  • En el lado del remitente, el trabajo de insertar ALIGN lo realiza la capa de enlace
  • En el lado receptor, el trabajo de usar ALIGN para definir el límite de 10 bits lo realiza la capa física. La capa de enlace también recibirá la primitiva ALIGN, simplemente ignórela.

Nota: Los datos FIS, la primitiva SOF y la primitiva EOF que se van a enviar no se pueden reemplazar solo porque se va a insertar la primitiva ALIGN. Un ejemplo es el siguiente (donde "DATA" es el dword de datos FIS)

// 插入ALIGN举例
插入ALIGN前 : X_RDY X_RDY SOF DATA DATA DATA DATA DATA EOF WTRM WTRM WTRM ...
插入ALIGN后 : X_RDY X_RDY SOF DATA DATA DATA DATA DATA ALIGN ALIGN EOF WTRM WTRM WTRM, ...

Cuando queremos enviar EOF, solo necesitamos insertar 2 primitivas ALIGN consecutivas, no podemos reemplazar EOF, solo podemos retrasar el envío de EOF, de lo contrario, el receptor no podrá definir el final de FIS.

3.4 codificación 8b10b

La codificación 8b10b significa que el extremo emisor codifica datos de 1 byte (8 bits) en una codificación de 10 bits (llamado código de balance de CC ) para enviar; la decodificación 8b10b significa que el extremo receptor decodifica los 10 bits recibidos en el 1 byte original. El número de 0 lógico y 1 lógico del código de equilibrio de 10 bits está más o menos equilibrado, y solo hay 3 situaciones:

  • 5 1s lógicos, 5 0s lógicos
  • 4 1s lógicos, 6 0s lógicos
  • 6 1s lógicos, 4 1s lógicos

La razón por la que se transmite el código de equilibrio de CC es permitir que el bucle de enganche de fase (PLL) de la capa física en el extremo receptor recupere el reloj de los datos sin perder el enganche.

De hecho, además de transportar 1 byte, la codificación 8b10b también puede transportar 1 bit de control adicional, que indica si el byte es K o D. SATA usa si es K para distinguir si es un primitivo: es decir, el primer byte del primitivo es el byte K y los bytes restantes son el byte D. Todos los bytes de datos (no primitivos) son bytes D.

En el contexto de la codificación 8b10b, se acostumbra escribir datos sin procesar de 1 byte (8 bits) en forma de Kxx.y o Dxx.y, donde xx es la forma decimal de los 5 bits inferiores del byte e y son los 3 bits superiores. del byte Representación decimal. La razón por la que se separan los 5 bits inferiores y los 3 bits superiores es porque se codifican por separado más adelante. En la Figura 7 se muestra un ejemplo .

Figura 7: Representación habitual de datos sin procesar de 1 byte con codificación 8b10b

El byte D utilizado por SATA puede ser arbitrario, pero solo se utilizan dos bytes K, a saber, K28.5 y K28.3. Entre ellos, K28.5 es el primer byte de la primitiva ALIGN y K28.3 es el primer byte de otras primitivas.

Este artículo solo proporciona una descripción general de la codificación 8b10b y no explica los detalles posteriores del algoritmo de codificación. Si está interesado, consulte el Apéndice A: Tutorial de codificación 8b/10b en la referencia [1].

3.5 Estructura del paquete FIS

A excepción de las primitivas ALIGN y CONT, se utilizan otras primitivas para controlar el proceso de envío y recepción de FIS, por lo que primero debemos comprender la estructura del paquete de datos FIS.

La Tabla 2 es la estructura del paquete de datos FIS, en la que el campo de tipo FIS y el campo CRC se fijan en 1 dword. El campo Payload es un campo de datos con una longitud indeterminada, que puede ser de 0~2048 dword. No es necesario que la capa de comando envíe o procese el CRC, porque la capa de transporte insertará automáticamente el CRC en el TX FIS; verifique y elimine el CRC del RX FIS, y la capa de comando informará si el CRC es incorrecto .

Tabla 2 : Estructura del paquete FIS

campo tipo FIS Carga útil CDN
longitud (byte) 4 0~8192 4
longitud (dword) 1 0~2048 1
comportamiento de envío Necesita capa de comando para enviar Necesita capa de comando para enviar No se requiere envío de nivel de comando. inserción de la capa de transporte
comportamiento de recepción La capa de comando es visible La capa de comando es visible La capa de comando no es visible. La capa de transporte comprueba, elimina y notifica errores de CRC

En el siguiente contexto, usamos el sustantivo  FIS length  para referirnos a la longitud total del campo FIS-type + Payload (mínimo 1 dword, máximo 2049 dword), excluyendo CRC.

FIS toma dword como unidad (la longitud puede ser divisible por 4 bytes) Es costumbre usar dword para representar FIS. Por ejemplo, un FIS con longitud FIS=5 es el siguiente:

// FIS 举例,十六进制形式,第一个 dword 是 FIS-type ,后面是 Payload ,不包含 CRC 
00258027 E0023456 00000012 00000004 00000000

El primer dword 00258027 es de tipo FIS y los siguientes 4 dwords son de carga útil.

注意 FIS 数据的也是小端序,例如对于第一个 dword E0023456 ,在底层最先传输的byte是 56 ,最后传输的byte 是 E0 。

3.6 CRC 的计算

FIS-type 字段和 Payload 字段的所有 dword 会依次参与 CRC 的计算。计算方法用 Verilog 语言风格的伪代码表示如下:

// Verilog 风格的伪代码
wire [31:0] fis_data;     // 一个 FIS数据 dword (包括FIS_type和Payload)
reg  [31:0] crc;          // 当前 CRC 寄存器
reg  [31:0] crc_next;     // 下一个 CRC 。并不是真正的寄存器,只是 always 块内的临时变量
reg         x32;          // 并不是真正的寄存器,只是 always 块内的临时变量
integer     i;            // 并不是真正的寄存器,只是 always 块内的临时变量
always @(posedge clk)
    if( FIS传输还没有开始 ) begin
        crc <= 32'h52325032;       // 把 CRC 复位为初始值!
    end else if( 正在传输FIS,遇到一个dword的fis_data (包括FIS_type和Payload) ) begin
        crc_next = crc;
        for(i=31; i>=0; i=i-1) begin
            x32 = crc_next[31] ^ fis_data[i];
            crc_next = (crc_next<<1) ^ {5'h0, x32, 2'h0, x32, x32, 5'h0, x32, 3'h0, x32, x32, x32, 1'b0, x32, x32, 1'b0, x32, x32, 1'b0, x32, x32, x32};
        end
        crc <= crc_next;         // 算出来的 crc_next 更新 crc 寄存器
    end else if( 当前FIS传输结束 ) begin
        // 把 crc 插入FIS的末尾
    end

在接收方,用同样的算法算出 CRC ,并与发送方发送的 CRC 进行对比,匹配则无错误,不匹配则有错误,该错误需要报告给命令层。

3.7 FIS 发送过程

除了 ALIGN 和 CONT 原语外,表1中的其它原语几乎都用来控制 FIS 收发过程。这里举一个例子如下(注意这里省略了周期性插入 ALIGN 原语,也省略了下文要讲的重复原语加扰机制),其中 "DATA" 代表一个 FIS 数据 dword 。

// FIS 发送进程举例 (忽略 ALIGN 的插入和 原语的重复加扰)
发送方发送 : SYNC SYNC X_RDY X_RDY X_RDY X_RDY X_RDY  SOF  DATA  DATA  DATA DATA EOF  WTRM WTRM WTRM WTRM SYNC SYNC SYNC SYNC SYNC
接收方发送 : SYNC SYNC SYNC  SYNC  SYNC  R_RDY R_RDY R_RDY R_RDY R_RDY R_IP R_IP R_IP R_IP R_IP R_OK R_OK R_OK R_OK R_OK SYNC SYNC

对以上过程解读如下:

  • 当双方都空闲时,都在持续发送 SYNC 原语,这种状态称为空闲状态(IDLE)。
  • 发送方想要发起 FIS 发送,它开始持续发送 X_RDY 原语。
  • 经过一段延迟后,接收方收到了 X_RDY (该延迟来自链路层、物理层的信号处理延迟),此时如果接收方准备好接收 FIS 了,就持续发送 R_RDY 原语。
  • 发送方收到了 R_RDY 原语,就发送一个 SOF 原语,随后紧跟着逐个发送 FIS 数据包的 dword (包括 FIS-type,Payload,CRC),最后一个 dword (CRC) 发送完后要紧跟一个 EOF 原语,然后持续发送 WTRM 原语。
  • 接收方收到 SOF 后,开始持续发送 R_IP 原语,指示接受正在进行 (receiving in progress) 。完整地收完 FIS 后进行 CRC 检查。在收到 WTRM 原语后,如果 CRC 检查正确,就持续发送 R_OK 原语,否则持续发送 R_ERR 原语。
  • Después de que el remitente recibe R_OK o R_ERR, comienza a enviar SYNC continuamente.
  • Después de que el receptor recibe el SYNC, también comienza a enviar el SYNC continuamente, y luego vuelve al estado inactivo, y finaliza la transmisión FIS.
  • Si el remitente recibe R_ERR, informará el error a la capa superior, y la capa superior decidirá si retransmitir el FIS.

A partir de este proceso, podemos ver que cuando un canal envía FIS, el otro canal envía las cuatro primitivas R_RDY, R_IP, R_OK, R_ERR para controlar el proceso de envío de FIS por la otra parte, por lo que es imposible que FIS sea bidireccional en enviar un punto en el tiempo. En otras palabras, SATA es físicamente dúplex completo y lógicamente semidúplex.

Además, dado que tanto el HBA como el dispositivo tienen autoridad para iniciar el proceso de envío de FIS, es posible que tanto el HBA como el dispositivo envíen X_RDY mientras intentan iniciar el envío de FIS. SATA estipula que, en este caso, el HBA siempre cede ante el dispositivo: siempre que el HBA detecte el X_RDY enviado por el dispositivo, debe abandonar el proceso de envío actual y enviar R_RDY en su lugar, listo para recibir el FIS enviado por el dispositivo. .

3.8 Codificación/Descodificación FIS

El propósito de la codificación es hacer que la secuencia 0-1 transmitida por el cable SATA sea más caótica, de modo que la radiación electromagnética esté más cerca del ruido blanco (en lugar de concentrarse en una determinada frecuencia), reduciendo así la interferencia electromagnética (EMI).

El codificador FIS generará una secuencia de números pseudoaleatorios, cada vez que se genera una dword, y se realiza un XOR bit a bit con la dword de los datos FIS para obtener el FIS codificado. El campo de tipo FIS, el campo de carga útil y el campo CRC del FIS deben codificarse. Ninguna de las primitivas está cifrada en FIS.

El proceso de codificación FIS se expresa en el pseudocódigo del estilo de lenguaje Verilog de la siguiente manera:

// Verilog 风格的伪代码
wire [31:0] fis_data;        // 加扰前的一个 FIS 数据 dword 输入 (包括FIS_type、Payload、CRC)
reg  [31:0] fis_data_scram;  // 加扰后的一个 FIS 数据 dword 输出
reg  [15:0] scram;           // 当前的加扰值寄存器
reg  [15:0] scram_next;      // 下一个加扰值。并不是真正的寄存器,只是 always 块内的临时变量
reg  [31:0] scram_rand;      // 加扰器生成的伪随机数。并不是真正的寄存器,只是 always 块内的临时变量
reg         x16;             // 并不是真正的寄存器,只是 always 块内的临时变量
integer     i;               // 并不是真正的寄存器,只是 always 块内的临时变量
always @(posedge clk)
    if( FIS传输还没有开始 ) begin
        scram <= 16'hFFFF;       // 把加扰值复位为初始值!
    end else if( 正在传输FIS,遇到一个dword的fis_data (包括FIS_type、Payload、CRC) ) begin
        scram_next = scram;
        for(int i=0; i<32; i++) begin
            x16 = scram_next[0];
            scram_next = (scram_next>>1) ^ {x16, 3'h0, x16, 8'h0, x16, 1'b0, x16};
            scram_rand[i] = x16;
        end
        scram <= scram_next;         // 算出来的 scram_next 更新 scram 寄存器
        fis_data_scram <= fis_data ^ scram_rand;   // 按位异或,对 FIS 数据的 dword 加扰
    end

FIS necesita ser descifrado en el extremo receptor. El descifrado es una operación simétrica de codificación. Solo necesita usar el mismo algoritmo para generar una secuencia dword pseudoaleatoria y realizar una operación XOR bit a bit en el FIS recibido. Debido a que los datos permanecen sin cambios después de dos XOR, los datos antes de la codificación se pueden recuperar después de la descodificación.

Tenga en cuenta que tanto el remitente como el receptor deben restablecer el codificador/descodificador cuando FIS no está transmitiendo, es decir, restablecer el registro de scram en el pseudocódigo anterior a 0xFFFF. Después del reinicio, la secuencia de dwords pseudoaleatoria generada se corrige, y las primeras 6 dwords se enumeran aquí de la siguiente manera:

// 加扰器/解扰器复位后生成的伪随机 dword 序列,只展示前 6 个
0xC2D2768D , 0x1F26B368 , 0xA508436C , 0x3452D354 , 0x8A559502 , 0xBB1ABE1B , ......

3.9 Mezcla repetida de primitivas

Esta sección hablará sobre el rol de la primitiva CONT.

El mecanismo de codificación FIS de la sección anterior solo resuelve el problema de EMI durante la transmisión FIS, pero SATA no envía FIS en muchos casos, sino que envía primitivas repetidas (como enviar repetidamente primitivas SYNC cuando está inactivo). la radiación se concentre en una cierta banda de frecuencia, causando problemas de EMI. Por lo tanto, SATA introduce la primitiva CONT y el mecanismo de codificación en la primitiva de repetición.

En el mecanismo de codificación repetido, SATA divide las primitivas en 4 categorías:

  • Primitivas no repetibles : SOF, EOF, CONT
  • Primitivos repetibles (no es necesario conservar la última repetición) : SYNC, R_RDY, R_IP, R_OK, R_ERR, X_RDY, WTRM
  • Primitivas repetibles (se debe mantener la última repetición) : HOLD, HOLDA
  • Primitivas que no afectan en absoluto a la codificación repetida : ALIGN

Para primitivos repetibles , si se repiten más de tres veces seguidas, SATA requiere que el tercer primitivo repetido se reemplace con CONT, y luego lo reemplace con datos basura a partir del cuarto primitivo repetido, que es una secuencia dword pseudoaleatoria, su algoritmo de generación es el mismo que el algoritmo de generación de números pseudoaleatorios utilizado para la codificación FIS en la sección anterior. Sin embargo, los dos generadores de números pseudoaleatorios no pueden afectarse entre sí y deberían funcionar de forma independiente. Además, el extremo receptor distinguirá y descartará directamente los datos basura, por lo que el extremo receptor no se preocupa por el valor de los datos basura, y SATA no requiere que el extremo emisor reinicie el generador de números pseudoaleatorios del datos basura, que nunca se pueden restablecer.

Un ejemplo es el siguiente (donde "DATA" representa una palabra clave de datos FIS y "GARB" representa una palabra clave de datos basura):

// 重复加扰举例 (忽略 ALIGN 的插入)
重复加扰前 : SYNC SYNC SYNC SYNC X_RDY X_RDY X_RDY SOF DATA  DATA  DATA DATA EOF WTRM WTRM WTRM WTRM WTRM SYNC SYNC SYNC SYNC SYNC
重复加扰后 : SYNC SYNC CONT GRAB X_RDY X_RDY CONT  SOF DATA  DATA  DATA DATA EOF WTRM WTRM CONT GARB GARB SYNC SYNC CONT GARB GARB
Ahora podemos entender: después de la inicialización del enlace, cada dword realmente transmitido en SATA solo se puede dividir en tres tipos: primitivo, datos FIS o datos basura después de la primitiva CONT.

Hay dos primitivos repetibles especiales : HOLD y HOLDA, que deben conservarse cuando se repite la última vez y no se pueden reemplazar con CONT o datos basura. Esto se debe a que HOLD y HOLDA se insertarán en los datos FIS (discutido en la sección de control de flujo a continuación). Durante la codificación repetida, para permitir que el receptor distinga los datos basura de los datos FIS, se requiere que esté en HOLD y HOLD La última vez que se repite HOLDA, en lugar de reemplazarlo con CONT o datos basura, se pasan HOLD y HOLDA.

Ejemplos de codificación repetida de HOLD y HOLDA son los siguientes. Entre ellos, la codificación repetida errónea tiene la situación continua de "GRAB" y "DATA", porque el receptor no puede distinguir si un dato es FIS o basura de los propios datos, por lo que esto provocará errores de confusión. Sin embargo, la codificación correcta usa las primitivas HOLD y HOLDA para separar los datos FIS de los datos basura, y no hay problema de confusión.

// HOLD 和 HOLDA 在重复加扰时的特殊处理举例 (忽略 ALIGN 的插入)
重复加扰前         : SOF DATA DATA HOLD HOLD HOLD HOLD HOLD HOLD DATA DATA DATA HOLDA HOLDA HOLDA HOLDA DATA EOF WTRM WTRM WTRM WTRM SYNC
重复加扰后(错误!!) : SOF DATA DATA HOLD HOLD CONT GRAB GARB GRAB DATA DATA DATA HOLDA HOLDA CONT  GRAB  DATA EOF WTRM WTRM CONT GARB SYNC
重复加扰后(正确  ) : SOF DATA DATA HOLD HOLD CONT GRAB GARB HOLD DATA DATA DATA HOLDA HOLDA CONT  HOLDA DATA EOF WTRM WTRM CONT GARB SYNC

Además, ALIGN es una primitiva especial para el mecanismo de codificación de repetición, y el mecanismo de inserción de ALIGN no interrumpirá el mecanismo de codificación de repetición. Por ejemplo, la secuencia anterior a la codificación repetida se inserta periódicamente en ALIGN. Puede verse que el mecanismo de codificación repetida ignora directamente la primitiva ALIGN, y las primitivas repetidas que aparecen antes y después de ALIGN todavía se consideran repetidas.

// ALIGN 不会打断重复加扰的进程举例
重复加扰前 : EOF WTRM WTRM WTRM ALIGN ALIGN WTRM WTRM WTRM WTRM SYNC SYNC SYNC SYNC SYNC ALIGN ALIGN SYNC
重复加扰后 : EOF WTRM WTRM CONT ALIGN ALIGN GRAB GRAB GARB GRAB SYNC SYNC CONT GRAB GRAB ALIGN ALIGN GRAB

Finalmente, debe mencionarse que el mecanismo de codificación repetida de las primitivas en realidad es relativamente flexible, y el remitente puede realizar una codificación repetida de manera flexible, lo que simplifica un poco la lógica:

  • No es necesario insertar CONT cuando se repite la 3ª vez, puede insertar CONT cuando es 4ª, 5ª..., seguido de datos basura (pero al menos la 3ª vez).
  • El ALIGN insertado puede interrumpir el proceso de codificación de repetición actual.
  • Es posible hacer que la codificación de repetición de todas las demás primitivas repetibles sea igual que HOLD y HOLDA: al repetir la última vez, no la reemplace. De esta manera no necesitamos distinguir entre los dos casos.
  • Incluso es posible no realizar ninguna codificación repetida y todas las primitivas se envían sin cambios. Esto no afectará ninguna funcionalidad en el extremo receptor, siempre que no se preocupe por EMI.

Sin embargo, el receptor debe ser capaz de manejar correctamente todos los casos que cumplan con la especificación.

El mecanismo de codificación repetida se resume en los siguientes principios:

  • Solo las primitivas repetibles  (SYNC, R_RDY, R_IP, R_OK, R_ERR, X_RDY, WTRM, HOLD, HOLDA) participarán en el mecanismo de aleatorización de repetición.
  • Al menos la tercera (o más) repetición debe reemplazarse con CONT.
  • Los datos basura deben seguir continuamente a CONT. Los datos basura solo pueden ser interrumpidos por la primitiva ALINEAR, y deben permanecer continuos en otros casos.
  • La última vez que se repiten HOLD y HOLDA, DEBE enviarse sin cambios y no puede reemplazarse por CONT o datos basura.
  • La codificación repetida de primitivas no afecta la codificación de datos FIS, y los dos funcionan de forma independiente.

3.10 Control de flujo

Esta sección describe el papel de las primitivas HOLD y HOLDA.

Debido a que la velocidad de lectura/escritura del medio del disco duro no coincide con la velocidad de la interfaz SATA, la capa de transporte especifica un mecanismo de control de flujo, que depende de las primitivas HOLD y HOLDA, incluidos dos tipos de control de flujo: control de flujo del remitente y control de flujo del receptor .

Control de flujo del remitente : cuando el remitente aún no está listo para enviar datos FIS (por ejemplo, la velocidad de lectura del disco duro es más lenta que la velocidad de la interfaz SATA), el remitente puede insertar la primitiva HOLD para completar el espacio en blanco, para que pueda admitir el envío de datos "intermitentes". La lógica de control de flujo del emisor es la siguiente:

  • Cuando el remitente envía datos FIS, si los siguientes datos de dword aún no están listos, enviará HOLD hasta que los datos estén listos.
  • Si la parte receptora detecta HOLD, enviará HOLDA para decirle a la otra parte "Sé que no estás listo". Por el contrario, si detecta datos FIS, enviará R_IP con normalidad.

Los ejemplos son los siguientes:

// 发送方流控举例 (忽略 ALIGN 的插入和 原语的重复加扰)
发送方发送 : X_RDY  SOF  DATA  DATA DATA HOLD DATA DATA  DATA HOLD HOLD HOLD  HOLD  DATA  EOF   WTRM WTRM
接收方发送 : R_RDY R_RDY R_RDY R_IP R_IP R_IP R_IP HOLDA R_IP R_IP R_IP HOLDA HOLDA HOLDA HOLDA R_IP R_OK

Control de flujo del receptor : cuando el receptor no puede recibir datos FIS temporalmente (por ejemplo, la tasa de escritura en el disco duro es más lenta que la tasa de la interfaz SATA), el receptor puede enviar la primitiva HOLD al remitente, diciéndole al remitente " no envíe tan rápido, acepto "No más", el remitente suspenderá el envío de datos y enviará la primitiva HOLDA al receptor para completar el espacio en blanco.

Nota: Debido a que existe una diferencia de tiempo de ida y vuelta entre el momento en que el receptor envía HOLD y el remitente inserta HOLDA, el receptor necesita un búfer de recepción y envía HOLD cuando el búfer está casi lleno (no completamente lleno ), hasta que el remitente envía Cuando llega HOLDA, la memoria caché aún puede almacenar los datos transmitidos dentro de esta diferencia de tiempo sin causar un desbordamiento. La especificación SATA estipula que el caché está casi lleno, lo que significa que solo quedan 20 dwords (80 bytes) de espacio en el caché, por lo que también se estipula que esta diferencia de tiempo no puede ser mayor que el tiempo de transmisión de 20 dwords.

La lógica del control de flujo del receptor es la siguiente:

  • Al recibir datos FIS, si el receptor descubre que solo quedan 20 dwords en el búfer de recepción, dejará de enviar R_IP y comenzará a enviar HOLD continuamente hasta que se eliminen algunos datos en el búfer de recepción y el espacio restante sea suficiente, luego continúe. enviando R_IP.
  • Cuando el remitente envía datos FIS, si recibe HOLD, suspenderá el envío de datos, pero enviará HOLDA para completar el espacio en blanco y continuará enviando datos hasta que reciba R_IP.

Los ejemplos son los siguientes:

// 接收方流控举例 (忽略 ALIGN 的插入和 原语的重复加扰)
发送方发送 :  SOF  DATA  DATA  DATA DATA DATA DATA DATA HOLDA HOLDA HOLDA HOLDA HOLDA DATA DATA EOF  WTRM WTRM WTRM
接收方发送 : R_RDY R_RDY R_RDY R_IP R_IP HOLD HOLD HOLD HOLD  HOLD  HOLD  R_IP  R_IP  R_IP R_IP R_IP R_IP R_IP R_OK

3.11 Resumen de la capa de enlace y la capa de transporte

Hemos visto que existen muchos y complejos mecanismos en la capa de enlace y la capa de transporte, pero su propósito no es complicado, es considerar cómo usar dos pares de líneas diferenciales seriales de alta velocidad para lograr una transmisión confiable de paquetes FIS. recuperación, alineación de bytes, reducción de EMI, verificación de errores de bit y mecanismo de control de flujo cuando la tasa no coincide. Se recomienda al lector que revise la Figura 5 para comprender la relación entre los diversos mecanismos.

4. Capa de comando: lectura y escritura DMA

Todo el contenido explicado anteriormente está en la capa de enlace y la capa de transporte. Esta sección explica brevemente los comandos de lectura y escritura de DMA en la capa de comandos y muestra cómo usar el paquete FIS para implementar la lectura y escritura del disco duro.

Como se mencionó anteriormente, la primera palabra clave de FIS es el campo de tipo de FIS, que determina el tipo de FIS, como se muestra en la Tabla 3 .

Tabla 3 : Tipos de FIS

Campo de tipo FIS
(hexadecimal, X significa no importa)
Tipo FIS Longitud FIS (tipo FIS+carga útil)
(dword)
XXXXXX27 HBA al registro del dispositivo 5
XXXXXX34 dispositivo al registro HBA 5
XXXXXXA1 establecer bits de dispositivo 2
XXXXXX5F configuración de PIO 5
XXXXXX39 DMA activar 2
XXXXXX41 Configuración de DMA propia 7
XXXXXX46 datos 1~2049
XXXXXX58 BIST activar 3

De hecho, para realizar una lectura y escritura DMA simple, solo se necesitan cuatro tipos de FIS: XXXXXX27, XXXXXX34, XXXXXX39 y XXXXXX46.

Después de inicializar el enlace y antes de leer y escribir, el HBA debe iniciar una solicitud de identificación al dispositivo para FIS, que es del tipo Registro HBA a dispositivo y contiene 5 dwords:

// 用于发起 identify 请求的 FIS ,HBA->device ,第一个 dword 是 FIS-type ,后面是 Payload ,这里不包含 CRC
00EC8027 00000000 00000000 00000000 00000000

El dispositivo responde con dos FIS:

  • El primero es FIS de tipo PIO setup.
  • El segundo es FIS de tipo de datos, y su carga útil se fija en 128 dword, que contiene información diversa del disco duro (ver [1] para más detalles, y no se explicará en detalle aquí).

Luego puede iniciar solicitudes de lectura y escritura. DMA lee y escribe en unidades de sectores, cada sector tiene 512 bytes (128 dword), y puede especificar el número de sectores consecutivos para leer y escribir a la vez. Utilice LBA de 48 bits (dirección de bloque lógico, dirección de bloque lógico) para direccionar el sector, por ejemplo, LBA=0x000001234567 representa el sector 0x1234567 .

Figura 8: Diagrama de tiempo de lectura de DMA

En la figura 8 se muestra el diagrama de tiempo del sector de lectura de DMA . En primer lugar, el HBA envía una solicitud de lectura de tipo de registro de HBA al dispositivo de 5 dword FIS, el formato es el siguiente. Donde XXXXXX es LBA[23:0] y YYYYYY es LBA[47:24]. ZZ es el número de sectores de lectura y escritura, se pueden leer uno o más sectores a la vez.

// 用于发起DMA读请求的 FIS ,HBA->device ,第一个 dword 是 FIS-type ,后面是 Payload ,这里不包含 CRC
00258027 E0XXXXXX 00YYYYYY 000000ZZ 00000000

Por ejemplo, si queremos leer LBA=0x0000A1234567 (es decir, el sector 0xA1234567), y leer 4 sectores continuamente, entonces el HBA debería enviar el comando FIS:

// 用于发起DMA读请求的 FIS 举例,HBA->device ,第一个 dword 是 FIS-type ,后面是 Payload ,这里不包含 CRC
00258027 E0234567 000000A1 00000004 00000000

Luego, el disco duro enviará los datos leídos (FIS de tipo de datos). Considerando que el valor máximo del campo Payload de FIS es 2048 dword, si el número de sectores a escribir por HBA es ≤16 (≤2048 dword), el disco duro solo responderá a 1 FIS. De lo contrario, se responderán múltiples FIS. El formato es:

// 硬盘发送DMA读数据,device->HBA ,第一个 dword 是 FIS-type ,后面是 Payload (也即读出的数据),这里不包含 CRC
00000046 XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX ...

Después de que se envíen todos los datos, el dispositivo también enviará un FIS de tipo de registro de dispositivo a HBA con una longitud de 5 dwords al HBA para mostrar su propio estado.

Figura 9: Diagrama de tiempo de escritura de DMA

El diagrama de tiempo del sector de escritura DMA se muestra en la Figura 9. En primer lugar, el HBA envía una solicitud de lectura de tipo de registro de HBA al dispositivo de 5 dword FIS, el formato es el siguiente. Donde XXXXXX es LBA[23:0] y YYYYYY es LBA[47:24]. ZZ es el número de sectores de lectura y escritura, se pueden escribir uno o más sectores a la vez.

// 用于发起DMA写请求的 FIS ,HBA->device ,第一个 dword 是 FIS-type ,后面是 Payload ,这里不包含 CRC
00358027 E0XXXXXX 00YYYYYY 000000ZZ 00000000

Por ejemplo, si queremos escribir en LBA=0x000000000001 y solo escribir 1 sector, entonces HBA debería enviar el comando FIS:

// 用于发起DMA写请求的 FIS ,HBA->device ,第一个 dword 是 FIS-type ,后面是 Payload ,这里不包含 CRC
00358027 E0000001 00000000 00000001 00000000

Luego, el disco duro responderá con un tipo de activación DMA FIS, el FIS es solo 1 dword (longitud de la carga útil = 0), el formato es el siguiente, diciéndole al HBA que envíe datos de escritura ahora.

// 用于通知HBA可以发送数据的FIS ,device->HBA ,第一个 dword 是 FIS-type ,没有 Payload ,这里不包含 CRC
00000039

A continuación, el HBA envía los datos de lectura (FIS de tipo datos). Considerando que el valor máximo del campo Payload de FIS es 2048 dword, si el número de sectores a escribir por HBA es ≤16 (≤2048 dword), HBA enviará 1 FIS. De lo contrario, se envían múltiples FIS. El formato es:

// HBA发送DMA写数据,HBA->device ,第一个 dword 是 FIS-type ,后面是 Payload (也即要写的数据),这里不包含 CRC
00000046 XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX ...

Después de que se envíen todos los datos, el dispositivo también enviará un FIS de tipo de registro de dispositivo a HBA con una longitud de 5 dwords al HBA para mostrar su propio estado.

Hasta ahora tenemos una breve comprensión de los métodos de lectura y escritura de discos duros. Para obtener más información sobre los protocolos de capa de comando, lea las referencias [1].

Referencias

[1] Tecnología de almacenamiento SATA:  https://www.mindshare.com/Books/Titles/SATA_Storage_Technology

[2] Serial ATA: accesorio AT serializado de alta velocidad:  https://www.seagate.com/support/disc/manuals/sata/sata_im.pdf

[3] Nikola Zlatanov: diseño de un núcleo sata de código abierto:  https://www.researchgate.net/publication/295010956_Design_of_an_Open-Source_SATA_Core

[4] Louis Woods et al. : Groundhog: un adaptador de bus de host (HBA) Serial ATA para FPGA:  https://ieeexplore.ieee.org/abstract/document/6239818/

[5] Host SATA Gen2 de código abierto (HBA):  https://github.com/WangXuan95/FPGA-SATA-HBA

Supongo que te gusta

Origin blog.csdn.net/cy413026/article/details/131904690
Recomendado
Clasificación