bloggerads

2014年4月26日 星期六

IDE (Integrated Drive Electronics) controller

IDE是早期用來控制碟機的spec, 目前已完全被AHCI所取代。

Q: 為什麼還是要學IDE protocol呢?
A: 因為Intel目前為止的設計,還是保留著支援IDE的彈性,在一些老系統(如xp)也只有IDE driver。通常都會讓使用者自行透過Bios選項將AHCI controller切換成IDE controller,這時Driver/Bios的控制硬碟方式就要改成IDE,所以還是有學習的價值。

Q: Why not default use IDE in modern PC?
A: IDE原理是控制IO register去下ATA command,除了速度慢以外。最大問題是他的設計是古老的思維而限制住他未來擴充的彈性,因此在2003年Intel release AHCI 用以取代IDE。

+ 本文開始 +

spec請參考以下這三分。古老的spec設計通常都比較簡單易懂
  1. PCI IDE Controller Specification Revision  1.0    3/4/94
  2. Programming Interface for Bus Master IDE Controller Revision  1.0     5/16/94
  3. Information Technology - AT Attachment - 8 ATA/ATAPI Command Set 
一個IDE controller規定了四個channel, 基本上有兩種mode, Compatibility and Native。

Compatibility mode:
  • 固定的IO register(Primary cmd/ctrl = 0x1f0~0x1f7/0x3f6, Secondary cmd/ctrl = 0x170~0x177/0x376)位址和固定的IRQ(14, 15)。
Native mode:
  • 由系統來assign: Primary cmd/ctrl = bar#0/bar#1, Secondary cmd/ctrl = bar#2/bar#3, 
需要注意的是control register 的位址是 ctrl port + 2

Q: 如何知道現在這個IDE是Compatibility or Native?
A: 在PCI header, Base-Class(09h), Sub-Class(0Ah), Interface:(0Bh) 定義了class code, 如果programmable indicator 不是fixed,operating mode可由程式來填入改變

Programmable Indicator: Indicate if controller support both mode (1), or fixed mode(0)
Operating Mode: Determine mode (0: compatibility, 1: native) 
Q: 如何找到硬碟插在哪個channel上並且發送ATA command?
A: 可以透過設定device register的bit 4, 然後看status是否回0x50來判斷channel上是否有device, 


接著請參考ATA spec定義的欄位,填寫要發的 command


Q: Bus Master code怎麼寫?
A: Bar#4 給定了Bus Master IO base address, 剩下的部分請參考圖,和原文spec step by step, 照做就可以把code寫出來了。


注意Command Register的Bit 3(read/write control), 下read command 時 bit3要設為 1, write command 時 bit3設為 0
programming bus master IDE, 請參考以下原文
3.1. Standard Programming Sequence
To initiate a bus master transfer between memory and an IDE DMA slave device, the following steps are required:

1) Software prepares a PRD Table in system memory. Each PRD is 8 bytes long and consists of an address pointer to the starting address and the transfer count of the memory buffer to be transferred. In any given PRD Table, two consecutive PRDs are offset by 8-bytes and are aligned on a 4-byte boundary.


2) Software provides the starting address of the PRD Table by loading the PRD Table Pointer Register . The direction of the data transfer is specified by setting the Read/Write Control bit. Clear the Interrupt bit and Error bit in the Status register.


3) Software issues the appropriate DMA transfer command to the disk device.


4) Engage the bus master function by writing a '1' to the Start bit in the Bus Master IDE Command Register for the appropriate channel.


5) The controller transfers data to/from memory responding to DMA requests from the IDE device.


6) At the end of the transfer the IDE device signals an interrupt.


7) In response to the interrupt, software resets the Start/Stop bit in the command register. It then reads the controller status and then the drive status to determine if the transfer completed


successfully.




2014年4月14日 星期一

PCIe Capability (0x10)



列出常參考的部分:


# Offset 0x0C (Link Capabilities)
=> Link能力
# Offset 0x10 (Link Control)
=> 電源控制 bit[1:0]: ASPM, 00b(Disabled) / 01b(L0s) / 10b(L1) /11b(L0s+L1)

# Offset 0x12 (Link Status)

=> 速度 bit[3:0]: 1=>Gen1(2.5GT), 2=>Gen2(5GT), 3=>Gen3(8GT), Gen1/Gen2採8b/10b編碼,實際速度約打8折
=> 寬度 bit[9:4]: 1/2/4/8/16=>x1/x2/x4/x8/x16 lane



2014年4月5日 星期六

AHCI (Advanced Host Controller Interface)

AHCI是PC架構下常見的儲存裝置控制器,透過AHCI我們可以將ATA command以SATA的形式發送給device。

一個AHCI controller最多可以implement 32個port,AHCI spec厲害的地方是定義了NCQ command。也就是host可以先發送最多32個command給device, 由device來決定要先做哪個command。近年來拜NAND flash快速發展所賜, 配上NCQ command,硬碟終於可以跑到接近SATA 3所定義的物理極速600MB/s。請參考下面這張TOSHIBA 120G的SSD跑分


焦點拉回spec,AHCI在PC架構上是一個PCI 或PCIe controller, 他的class code是Rx[B:9]=0x010601。

MMIO base address定義在PCI CFG header就Bar#4,在開機時,Bios會依照AHCI spec要求assign 一個align to 8KB的MMIO的base address。access MMIO address 可以看到General Host Control Registers(0~0xFF) + port0~31 (每個port range為0x80)這兩大部分


從GHC registers我們可以知道這個controller的能力如這個AHCI controller implement哪些port可以讓software使用,發生中斷的原因以及透過這些register做Global host reset。

至於對某個port上的硬碟發command最主要是透過port control registers來辦到。透過port的register我們也可以發port reset這種局部reset來命令此port的SATA phy重新link。

Q: 如何對port發command?
A: 首先先把記憶體宣告好,把要發的command以 command FIS型態填在宣告的記憶體上,如果是帶資料的command則還需要把PRD Table描述好,並將其指到一個準備傳送或接收資料的記憶體位址(注意必須是Word aligned)。最後去set PxCI,command就可以發到碟機了。

最後附上精心製作的AHCI register表,祝大家都可以寫出屬於自己的AHCI driver


Overall Registers layout

PRDT layout



2014年4月1日 星期二

EBDA (Extended BIOS Data Area)

這篇是說明在Legacy Bios中,如何動態申請memory的規範。

第一次碰到Option Rom,我對使用記憶體第一個想法就是, 難道不能用Malloc這類的函式嗎? 答案是不行,因為在boot的階段是沒有C函式庫可以用的。因此要使用memory存放資料就必須透過EBDA所定義的規範從640KB內抓一快記憶體來用。

定義幾個欄位:
[40:13]: EBDA的起始位址, 單位是KB, 欄位是一個Word
[40:13] ] = EBDA的長度, 單位是KB, 欄位是一個Byte
[40:0E] = EBDA的起始segment, 欄位是一個Word

<範例> 申請 2KB的記憶體位址

step 1. 程式先去讀出以上這三個欄位的位址
  • [40:13] = 27Ch (KB) = 9F000h
  • [9F00:0] = 4
  • [40:0E] = 9F00h
step 2. 將EBDA起始位址下移2KB, 並在EBDA起始的第一個Byte加上2
  • [40:13] = 27Ch (KB) -2 = 27Ah (KB) = 9E800h
  • [9E80:0] = 4+2= 6
  • [40:0E] = 9E80h