最近因為工作原因開始學(xué)習(xí)SATA屡江,因為這個不涉及公司機(jī)密惹苗,我就把我學(xué)習(xí)的內(nèi)容搬到網(wǎng)上來劳闹,這樣也方便自己日后查看样漆。這個系列文章是按照我學(xué)習(xí)的進(jìn)度而不是按照SATA Specification或者參考書籍的順序來寫的京景,如果有機(jī)會,我會在之后重新調(diào)整文章順序仰挣。
Link Layer主要負(fù)責(zé)FIS的傳輸和接收顷锰,F(xiàn)IS是什么呢州藕?FIS就是Frame Information Structure的簡寫,SATA的Host和Device間都是通過FIS進(jìn)行通信的严嗜,我會在之后的文章中單獨介紹FIS。它通過一系列的辦法(比如添加CRC,進(jìn)行8bit/10bit編碼解碼踢俄,對數(shù)據(jù)和primitive進(jìn)行scramble)保證FIS能順利地在Host和Device間進(jìn)行傳輸,下面是Linker Layer的示意圖:
這一層要做的事情還挺多,比如進(jìn)行CRC的生成和檢測查剖,將數(shù)據(jù)進(jìn)行8b-10b的編碼和解碼菌仁,對數(shù)據(jù)和primitive進(jìn)行scramble等疟赊。下面是一個更詳細(xì)的示意圖:
從上圖我們可以看出椅挣,當(dāng)Link Layer接收到來自于Transport Layer的FIS后,Link Layer需要添加CRC到FIS中。同時诉瓦,所有的FIS會被加上SOF和EOF這兩個primitive,因此昔脯,在這層傳輸?shù)腇IS長這樣:
協(xié)議規(guī)定payload(FIS + CRC)最多能有2049DW(DW = 32bit)云稚,也就是8196Bytes桑李。一般的非數(shù)據(jù)類型的FIS都遠(yuǎn)遠(yuǎn)小于8196Bytes禁荒,最大的除數(shù)據(jù)類型的FIS占7DW也就是28Bytes。FIS payload的大小會影響data flow,關(guān)于data flow我也會在之后的文章中講解惊暴。下面我們就來看看這一層的一些細(xì)節(jié)罕模,首先我們來看看FIS Scrambling。
FIS Scrambling
在信號的傳輸過程中媒殉,如果信號具有一定的重復(fù)性(pattern repetition)摔敛,那么在這種情況下,EMI(Electromagnetic interference電磁干擾)會比較高桃犬。為了減少EMI行楞,我們需要將信號的周期性打亂子房,讓信號更像是隨機(jī)的。為了實現(xiàn)這一目的尾序,在Link Layer中躯砰,我們會用scrambler來對信號進(jìn)行scramble。
在這層中兰怠,一共有兩種scrambling機(jī)制李茫,第一種是只scramble FIS+CRC魄宏,不scramble任何primitive;第二種是用于scramble重復(fù)的primitives宠互,這被稱為primitive suppression予跌。 對于第一種scrambling,之所以不對primitive進(jìn)行擾亂频轿,是因為在physical layer,我們需要知道primitive到底是什么集币。如果對primitive進(jìn)行scramble的話翠忠,在這里,physical layer根本就不知道接收的primitive到底是什么(這是在unscramble前)当娱,因此考榨,我們不對primitive進(jìn)行擾亂河质。而對于第二種scrambling,因為有其它機(jī)制的存在散休,即使一些primitives被scramble了乐尊,Device端也是知道這些primitives是什么的,因此我們可以將重復(fù)的primitives進(jìn)行scramble限府。
我們下面通過一個例子來看第二種scrambling是如何實現(xiàn)的:
要實現(xiàn)這種scrambling胁勺,我們需要使用特殊的primitive - CONT独旷。比如在這個例子中,為了減少X_RDY傳輸?shù)臄?shù)量蛇捌,我們需要先發(fā)送2個X_RDY咱台,之后再發(fā)送一個CONT回溺,當(dāng)CONT發(fā)送完后,我們就可以將剩下的X_RDY進(jìn)行scramble萍恕。當(dāng)遇到第一個不是X_RDY并且沒有被scramble的primitive時车要,說明所有的X_RDY都已經(jīng)傳輸完成翼岁,那我們就不要對之后的primitive進(jìn)行擾亂了。 注意琅坡,并不是所有的primitive都能這樣操作榆俺,比如SOF,EOF陪捷,CONT等就不能進(jìn)行primitive suppression诺擅,下面這些primitives是可以進(jìn)行primitive suppression的:
8b/10b編碼譯碼
我對這部分不是很了解掀虎,只知道這么做是為了將clock信號嵌入在傳輸?shù)男盘栔校瑥亩鴾p少單獨傳輸clock信號時產(chǎn)生的EMI驰怎。
FIS Arbitration
Link Layer接收到來自Transport Layer的發(fā)送FIS通知后县忌,它會發(fā)出X_RDY的primitive給接收端继效。有一種情況就是當(dāng)Host和Device同時發(fā)出X_RDY后,如果不采取任何措施的話厉颤,兩端都會等對方發(fā)出R_RDY凡简。但此時BUS是被X_RDY占據(jù)了,兩端都不能發(fā)出R_RDY帜乞,這就形成了一種死鎖黎烈。為了解決這種問題,SATA協(xié)議要求Device端具有更高的優(yōu)先級津畸,也就是出現(xiàn)這種情況時必怜,Host端會放棄發(fā)送X_RDY梳庆,轉(zhuǎn)而發(fā)送R_RDY來回應(yīng)Device端的請求。
FIS傳輸與接收流程
下面我們來看看FIS到底是如何在Host和Device間進(jìn)行傳輸?shù)模?/p>
- 首先膏执,發(fā)送端的Link Layer接收到Transport Layer的發(fā)送FIS的通知后更米,會持續(xù)發(fā)出X_RDY。
- 當(dāng)接收端收到X_RDY后迟几,它的Link Layer持續(xù)發(fā)送R_RDY栏笆。
- 當(dāng)發(fā)送端接收到R_RDY后蛉加,它開始發(fā)送FIS(SOF+FIS+CRC)。
- 接收端收到SOF后就會持續(xù)發(fā)出R_IP厂抽。
- 當(dāng)發(fā)送端送出EOF后丁眼,它會持續(xù)發(fā)出WTRM并等待傳輸?shù)慕K止户盯。
- 接收端在收到并驗證了FIS嵌施,CRC等信息后饲化,發(fā)出R_OK莽鸭,表示接收端完成了接收工作吗伤。
- 之后,發(fā)送端會持續(xù)送出SYNC來讓接收端的BUS進(jìn)入idle狀態(tài)硫眨。
- 接收端收到SYNC后也會持續(xù)發(fā)出SYNC來使發(fā)送端的BUS進(jìn)入idle狀態(tài)足淆。
下面我們來看看示意圖:
步驟1 - 2:
步驟3 - 4:
步驟5 - 6:
下面這是一個實際測試中的FIS傳輸trace,結(jié)合這個trace能更好的理解FIS的傳輸和接收: