【我所認知的BIOS】—>SPD

2019-04-14 16:14发布

【我所認知的BIOS—>SPD

By LightSeed 2009-7-22 

1、什麼是 SPD

存在SPDSerial Presence Detect的縮寫,中文意思是模組存在的串列檢測。也即是通過上面講的I2C串列介面的EEPROM堆記憶體插槽中的模組存在的資訊檢查。這樣的話,模組有關的資訊都必須紀錄在EEPROM中。習慣的,我們把這顆EEPROM IC就稱為SPD了。以往開機時BIOS必須偵測memory,但有了SPD就不必再去作偵測的動作,而由BIOS直接讀取 SPD取得記憶體的相關資料。那我們來看看事物的SPD吧,先看我們的SPD位於記憶體的哪個部位,比如說圖1中紅線框住的地方就是SPD。然後我們再放大來看看我們的SPD,比如說其他記憶體上的SPD放大圖見圖2.     1 記憶體的實物圖     2 SPD放大圖

2SPD內容

SPD是一組關於記憶體模組的配置資訊,如P-Bank數量、電壓、行位址/列地址數量、位寬、各種主要操作時序(如CLtRCDtRPtRAS等)……它們存放在一個容量為256位元組的EEPROMElectrically Erasable Programmable Read Only Memory,電擦除可編程唯讀記憶體)中。讓我們來看看SPDspec的一個截圖,見圖3   3 SPD的內容截圖 實際上在SPD中,JEDEC規定的標準資訊只用了128個位元組(還有128位元組,屬於廠商自己的專用區)。一般的,一個位元組至少對應一種參數,有的參數需要多個位元組來表述(如產品續列號,生產商在JEDEC組織中的代碼)。 其中,一個位元組中的每個bit都可能用來表示這一參數的具體數值。由於SPD的資訊很多,在此就不一一列出了,有興趣的讀者可以參閱相關文檔。

3SPD的作用

SPD內的時序資訊由模組生產商根據所使用的記憶體晶片的特點編寫並寫入至EEPROM,主要用途就是協助北橋晶片精確調整記憶體的物理/時序參數,以達到最佳的使用效果。如果在BIOS中將記憶體設置選項定為“By SPD”。那麼在開機時,北橋會根據SPD中的參數資訊來自動配置相應的記憶體時序與控制寄存器,避免人為出現調校錯誤而引起故障。當然,對於DIYer來說,也可以自由調整時序與控制參數(物理參數仍要借助SPD或北橋自己檢測來確定)。前面所說的 by SPD”在AWXXXsetup介面就會出現了。 上面這三部分,主要是參考百度里的資訊,另外加了自己的截圖等等。  

4、讀取SPDread by byte的實戰)

既然SPD裏面存儲有這麼重要的資訊,而且又和整個系統有這麼密切關係,那麼我們應該怎麼讀取出來呢? 關於SPD裏的資訊,要讀取它的話就要說到上一章講的SMBUS的操作了。因為SPD是通過SMBUS來讀取的。在這裏我把主要的讀取演算法寫出來,然後加注我想就可以了。因為如果能夠有心情看這篇文章的人,我想也應該對BIOS有一定興趣的,那麼自己再加點週邊的code肯定是不成問題的啦。 通過SMBUS來讀取SPD大約要有這麼幾個重要的步驟要去做。但是我們要首先明確是以什麼的方式去讀取呢?因為SMBUS的讀取可以分read by byteread by wordread by block。不過現在我們從read by byte開始說起。 通過遍曆PCI設備,比較class code來找到SMbus controllerbase address。這個base address我們可以參考ICH6datasheet的相關說明。(當然只要是ICH系列的datasheet都是可以查閱的。)它代表了SMBUSsystem I/O base address。也就是前面我們提到的SMBUSIO埠。(因為我們都要通過這些IO來實現我們動作比如說readwrite等等。關於怎麼在我們的板子上獲取這個base address,如果您有興趣可以參考我的好友peterhublog“戲說BIOSclock generator”裏有相應的程式操作。) 根據SMBUS的協定,我們要先向controlleroffset 04h也就是(Transmit Slave Address)發送slave address。然後等帶這個SMBUS準備ok 以上兩步ok了以後,我們就可以讀取相應的寄存器了。這是向controllerHost Command0ffset 03h)發的命令。內容就是對應的寄存器indexok了。 有了上面的準備,那麼我們就準備給controller說開始讀取資料吧,這個動作是通過向Host Controloffset 02h)發送讀取的命令48h。(如果不太清楚就自己對應到ICHdatasheet詳細看看是什麼意思。) 經過SMbus準備好了以後,我們就可以從data0這個埠取得我們需要的資料了(offset 05h)。 如果想要把SPD的內容(128bytes)一下子全部讀出來,那麼就直接用加了迴圈就ok了,迴圈~   溫馨提示,在通過SMBUS controller來讀取SPD的內容的時候,一定要去等待SMBUS準備ok才能去讀或者其他操作哦。只需要一直去判斷狀態位元就好了。 下面我提供一段核心代碼,希望以此抛磚引玉的效果,當然我也是參考了別人的代碼: ;[]============================[] ;Input     : CL - register index ;        CH - device ID ;Output : AL - Value read ;[]============================[] Smbus_ReadByte    Proc    Near           Push          cx       ;保存cx           mov      dx,05000h     ;SMBus Base address,在我的機器上的      mov      dl,04h          ;選擇Transmit Slave Address      or         ch01h      ;read      mov      al,ch            ;ID cmd(read)      out       dx,al      IODELAY      call       Chk_SMBus_Ready   ;如SMbusok就一直停在這裏,直到超過規定的時間,如果SMbus還不ok那麼就報錯。           pop      ax                ;恢復cxax      mov      dl,03h          ;選擇Host Command Register      out       dx,al            ;把要讀取的寄存器index送出去      IODELAY      mov      dl,02h          ;選擇Host Control Register      mov      al,48h          ;下命令開始讀取by Byte Data:      out       dx,al            Read data      IODELAY       mov      cx, 100h @@:                     IODELAY                  loop      short @B      ;這裏這個迴圈是為了讓smbus準備好而加的延時      call       Chk_SMBus_Ready      mov      dl,05            ;選擇Host Data 0 Register      in         al,dx            Data0      IODELAY            ret Smbus_ReadByte   Endp 讀取的顯示效果如圖4   4 byte形式讀取的SPD顯示截圖