Try   HackMD

PCI/PCIe(1): 基礎篇

Introduction

PCI

Peripheral Component Interconnect(PCI) 是一種連接電腦主機板和外部裝置的匯流排標準。其取代了 ISAVESA,成為現代電腦中常見的標準。

特性上,PCI 是採同步傳輸(Synchronous transaction)。這意味著 PCI bus 只使用一個 clock。預設情況下,時脈運行在 33MHz,但允許更低到甚至 0MHz 以省電。如果硬體支援,則可以運行較高的 66MHz。

PCI 是 32 位元匯流排,採用 BURST 傳輸。所謂 BURST,意指傳輸的方式為:

  • 開始傳輸
  • 第一個 clock cycle 用於指定 32 位元位址
  • 之後的許多 clock cycles 用來傳遞資料
  • 結束傳輸

在 BURST 傳輸下,每次傳遞資料時不重新指定位址,位址會在每個資料的 clock cycle 自動遞增。如果要改變位址,需停止目前的傳輸並重啟另一個新的。

PCI 的另一關鍵特性是隨插即用("plug-and-play")。Host 有能力確定 PCI bus 中每個 PCI 裝置的身份,例如製造商、功能等。也可以判斷每個 PCI 裝置需要多少記憶體空間、多少中斷等資訊。除此之外,可以重新分配/映射每個裝置的記憶體空間。

PCIe

Peripheral Component Interconnect Express(PCIe),是電腦匯流排(bus)的一個重要分支。沿用既有的 PCI 概念及訊號標準,並且構建了更加高速的序列通訊(Serial communication)系統標準。目前這一標準由 PCI-SIG 組織制定和維護。PCIe 僅應用於內部互連。由於 PCIe 是基於既有的 PCI 系統,所以只需修改實體層而無須修改軟體就可將現有 PCI 系統轉換為 PCIe。

PCIe 標準的演進相當快速,也反映了該規格在計算機中重要的地位。與 PCI 是 shared bus 不同,PCIe 是點對點(point-to-point)的匯流排。這意味著每個裝置都有其專屬的連接,不像PCI 那樣共享 bandwidth。也因此與 33MHz 的 PCI 相比,GEN 1 的 PCIe 就可達 2.5GHz 的速度。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

PCIe_vs_PCI

截至撰文為止,各代的速度如下表所顯示:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

PCI_Express

PCIe Connector

下圖展示了一個 1 lane 的 PCIe 的連結器(connector)。可以看到共有 36 個 Pin 腳,又分成上下個 18 個成為兩列。其中只有 6 個 pin 與傳輸資料有關(其他是電源或輔助信號)。分別是:

  • 一對 REFCLK
  • 一對 PER,與資料接收有關(receive)
  • 一對 PET,與資料發送有關(transmit)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

fpga4fun: PCI Express - Connector

這些成對的訊號通稱為「差分訊號(differential signal)」。因為對中的兩個信號攜帶實際上攜帶相同的資料,但相位相反。其目的主要是為了傳輸的可靠性。

PCIe 可以通過使用多個 lane 來提升速度。由於 REFCLK pair 不需要重複,因此以具有 2 個 lane 的 PCIe 為例,需要使用 1 對 REFCLK + 2 對 PET + 2 對 PER。

PCIe Topology

如下圖是一個 PCI Express(PCIe) topology:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

PCI-SIG specifications

在 PCIe 系統中,有幾個關鍵名詞/角色:

  • Hierarchy 是含 Root Complex 的 port 上,以及通過 Switch、Bridge 關聯至 RC 上的所有裝置形成的網路,如上圖所呈現即是一個 Hierachy
  • Root Complex(RC) 是整個 I/O 架構的根節點,其將 CPU 和 memory subsystem 連接到 Switch 或 Endpoint,以構成 PCIe 的 Hierarchy
  • PCIe to PCI/PCI-X Bridge 提供 PCIe Hierarchy 和 PCI/PCI-X Hierarchy 之間的連結
  • Switch 是多個虛擬 PCI-PCI bridge 的邏輯組合
  • Endpoint 在 topology 中是指一種 function,可以是 PCIe 任務的 requester 或 completer,又可分三種
    • Legacy
    • PCIe
    • RCiEP

有了連接的機制,CPU 啟動後,Host 會試著去讀不同的 bus 和 device numbers 之組合下的 function 0 之 VID/DID(DFS),若成功讀取就代表這個 BDF 下具有 device,這個流程被稱作 Bus Enumeration/PCI Enumeration

從 bus -> device -> function 的 BDF 結構構成了每個 PCIe 設備節點的 identifier。

關於硬體相關基礎知識,由於非專案因此不多深入。更多詳細知識推薦閱讀以下文章:

深入PCI与PCIe之一:硬件篇

PCI Configuration Space

PCI Configuration Space 和一般記憶體空間是分離的,通常我們會以 BDF 做為 PCI 裝置的唯一位址,並以此透過晶片廠商提供的方式存取 PCI Configuration Space。以 Intel 的晶片組為例,其使用 I/O 空間的 0xCF8 來設定 Configuration Address Register 來決定要存取的 BDF(參照下圖),然後再以 0xCFC 位址來讀取或寫入 Configuration Data Register 以得到想存取的 Configuration Space 內容。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

[BIOS]PCI Read/Write

傳統的 PCI 裝置的 Configuration Space 包含了 64 bytes 的 header space 和 192 bytes 的 capability space,加起來是 256 bytes。CPU 可以透過 BDF 加上 register offset 的方式來存取 I/O address space 讀取 PCI header。

而對 PCIe 而言,Configuration Space 擴展至 4096 bytes。剩餘的 (4096 - 256) bytes 必須以 Memory map I/O 進行存取。硬體上,因為有 root complex,如果 CPU 想讀 PCIe device 的數據,可以先讓 root complex 把數據從 PCIe device 讀到 CPU memory,然後 CPU 再從 memory 讀取數據即可;反之,如果 CPU 要往 device 寫數據,先把數據在 memory 中寫入,然後再通過 root complex 寫入 PCIe 即可。

包含裝置上的 RAM 和 ROM 也可能可以透過 MMIO 的方式進行操作。總結來說,即下圖所示:

下面我們特別說明幾個重要的 configuration 欄位:

  • CMD (0x4): 一般情形下,Host會在 init controller 時將 BME 跟 MSE bit 設為 1
    • BME : 允許 controller 能夠向 Host 發送 DMA Read/Write Memory request
    • MSE : 控制能不能存取 controller register
  • CC(class code, 0x9): 可用來判別 controller 類型為 NVMe
  • BAR: 透過讀寫 BARs 可以得知目標 function 需要的記憶體空間大小,並可藉其提供配置空間位址的資訊
    • BAR0: – Memory Register Base Address, lower 32-bits
    • BAR1: – Memory Register Base Address, upper 32-bits
  • capability pointer(0x34): linked capability

那麼 MMIO 的映射位址該如何得知呢?

該 mapping 的位置需透過過 PCI header 的 BAR0 和 BAR1 取得。當 Host 準備配置空間時,對 BAR register 發送 write request,嘗試將所有 bit 寫為 1,PCIe 收到 request 後,因為 BAR 有些 bit 是 read only 的,我們可以從保持不變的值取得所需空間的信息。以上圖為例,寫完後
低 12 bits 沒改變,表示需要 mapping 的空間大小是 4KB,此外注意到低 4 bits 表示了該存儲空間的一些屬性。

PCIe Signaling

Reapter

隨著 PCIe 的演進,傳輸速度也不斷提升,加上現代硬體設計更加複雜。在實際的硬體應用上,訊號的完整性問題成為一大問題。

為克服上述的訊號問題,可以在 CPU 和 Endpoint 之間加上 Repeater 以解決。Reapter 能做為一種訊號調節的裝置,以確保 Root complex 和 endpoint 之間的溝通品質。Repeater 又可以分為兩大類: Redriver 和 Retimer:

  • Redriver: 主要用於訊號增強,能夠增強 PCIe 訊號的強度和穩定性,補償訊號衰減,常用於較短距離的連接,如主機板內部
  • Retimer: 不僅可以增強訊號,還能重整訊號、提供時脈並復原數據等功能。可以在長距離連接中恢復和補償傳輸時的時序失真,確保高資料率傳輸的品質

詳細可閱讀:

車用PCIe中繼IC:訊號的穩定高速之旅

Signal

在 PCIe 的傳輸上,訊號協議如下圖所呈現。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

從硬體的角度,解析 PCIe 介面初始化

除了傳輸資料(DATA Rx/Tx)的訊號以外,REFCLK 即參考時脈(reference clock),是 PCIe 可以傳輸資料的前提。PCIe 採用 100MHz 的 reference block 以使在鏈結上的 PCIe 裝置可以高速的交換資料。

此外,有三個重要的控制訊號:

  • PERST#: PERST# 被稱基礎復位(fundamental reset),該訊號要一直被拉低直到 power rail 和 reference clock 穩定,當鏈路初始化的開始,便由低電位轉為高電位,通常這也就意外著鏈路的初始化(Link Initialization)完成
  • CLKREQ#: 與低功耗狀態的轉換有關。這是一個 active-low 並用來請求 reference clock 的訊號
  • WAKE#: 與低功耗狀態的轉換有關。同樣是一個 active-low 訊號,用於將 PCIe 裝置從低功耗模式重置到運作(active)模式

當鏈路上的所有裝置獲得電源與參考時脈後,PCIe 中的實體層會進行鏈路初始化(Link Initialization & Training)。

細節可參考 PCIe Link Training Overview 一文即影片。

驅動程式介面

有關描述 PCI driver 的結構,以及如何註冊 PCI driver 的詳細說明,可參考以下資料:

Reference