Yiwei Lin
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    15
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- tags: I/O, System Software --- # PCI/PCIe(1): 基礎篇 ## Introduction ### PCI [Peripheral Component Interconnect(PCI)](https://en.wikipedia.org/wiki/Peripheral_Component_Interconnect) 是一種連接電腦主機板和外部裝置的匯流排標準。其取代了 [ISA](https://en.wikipedia.org/wiki/Industry_Standard_Architecture) 和 [VESA](https://en.wikipedia.org/wiki/Video_Electronics_Standards_Association),成為現代電腦中常見的標準。 特性上,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")](https://en.wikipedia.org/wiki/Plug_and_play)。Host 有能力確定 PCI bus 中每個 PCI 裝置的身份,例如製造商、功能等。也可以判斷每個 PCI 裝置需要多少記憶體空間、多少中斷等資訊。除此之外,可以重新分配/映射每個裝置的記憶體空間。 ### PCIe [Peripheral Component Interconnect Express(PCIe)](https://zh.wikipedia.org/zh-tw/PCI_Express),是電腦匯流排(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](https://hackmd.io/_uploads/SyGNkAmFC.png) > [PCIe_vs_PCI](https://commons.wikimedia.org/wiki/File:PCIe_vs_PCI.gif) 截至撰文為止,各代的速度如下表所顯示: ![image](https://hackmd.io/_uploads/Bykt3IAjp.png) > [PCI_Express](https://zh.wikipedia.org/zh-tw/PCI_Express) ## PCIe Connector 下圖展示了一個 1 lane 的 PCIe 的連結器(connector)。可以看到共有 36 個 Pin 腳,又分成上下個 18 個成為兩列。其中只有 6 個 pin 與傳輸資料有關(其他是電源或輔助信號)。分別是: * 一對 REFCLK * 一對 PER,與資料接收有關(receive) * 一對 PET,與資料發送有關(transmit) ![image](https://hackmd.io/_uploads/BJP4_TQF0.png) ![image](https://hackmd.io/_uploads/HyJSupmtA.png) > [fpga4fun: PCI Express - Connector](https://www.fpga4fun.com/PCI-Express1.html) 這些成對的訊號通稱為「[差分訊號(differential signal)](https://en.wikipedia.org/wiki/Differential_signalling)」。因為對中的兩個信號攜帶實際上攜帶相同的資料,但相位相反。其目的主要是為了傳輸的可靠性。 PCIe 可以通過使用多個 lane 來提升速度。由於 REFCLK pair 不需要重複,因此以具有 2 個 lane 的 PCIe 為例,需要使用 1 對 REFCLK + 2 對 PET + 2 對 PER。 ## PCIe Topology 如下圖是一個 [PCI Express(PCIe)](https://en.wikipedia.org/wiki/PCI_Express) topology: ![image](https://hackmd.io/_uploads/B16DewesT.png) > [PCI-SIG specifications](https://pcisig.com/specifications) 在 PCIe 系統中,有幾個關鍵名詞/角色: * Hierarchy 是含 Root Complex 的 port 上,以及通過 Switch、Bridge 關聯至 RC 上的所有裝置形成的網路,如上圖所呈現即是一個 Hierachy * [Root Complex(RC)](https://en.wikipedia.org/wiki/Root_complex) 是整個 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**。 ![](https://i.imgur.com/h240Shj.png =600x) 從 bus -> device -> function 的 **BDF** 結構構成了每個 PCIe 設備節點的 identifier。 :::info 關於硬體相關基礎知識,由於非專案因此不多深入。更多詳細知識推薦閱讀以下文章: > [深入PCI与PCIe之一:硬件篇](https://zhuanlan.zhihu.com/p/26172972) ::: ## 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](https://hackmd.io/_uploads/r14b--Aqp.png) > [[BIOS]PCI Read/Write](https://medium.com/@jacksonchen_43335/bios-pci-read-write-14356b013c43) 傳統的 PCI 裝置的 Configuration Space 包含了 64 bytes 的 header space 和 192 bytes 的 capability space,加起來是 256 bytes。CPU 可以透過 BDF 加上 register offset 的方式來存取 I/O address space 讀取 PCI header。 ![](https://i.imgur.com/jTexQz3.png) 而對 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 的方式進行操作。總結來說,即下圖所示: ![](https://i.imgur.com/CP5PSCc.png) ![](https://i.imgur.com/y6XDvyc.png) 下面我們特別說明幾個重要的 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 的映射位址該如何得知呢? ![](https://i.imgur.com/ujl2phH.png) 該 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:訊號的穩定高速之旅](https://phisonblog.com/zh-tw/the-automotive-pcie-repeater-a-high-speed-journey-of-stable-signals/) ### Signal 在 PCIe 的傳輸上,訊號協議如下圖所呈現。 ![image](https://hackmd.io/_uploads/ByYx7XWgyg.png) > [從硬體的角度,解析 PCIe 介面初始化](https://www.eagletek.com.tw/post/analyzes-pcie-interface-initialization-from-a-hardware-perspective) 除了傳輸資料(DATA Rx/Tx)的訊號以外,REFCLK 即參考時脈(reference clock),是 PCIe 可以傳輸資料的前提。PCIe 採用 100MHz 的 reference clock 以使在鏈結上的 PCIe 裝置可以高速的交換資料。 此外,有三個重要的控制訊號: * PERST#: PERST# 被稱基礎復位(fundamental reset),該訊號要一直被拉低直到 power rail 和 reference clock 穩定,當鏈路初始化的開始,便由低電位轉為高電位,通常這也就意外著鏈路的初始化(Link Initialization)完成 * CLKREQ#: 與低功耗狀態的轉換有關。這是一個 active-low 並用來請求 reference clock 的訊號 * WAKE#: 與低功耗狀態的轉換有關。同樣是一個 active-low 訊號,用於將 PCIe 裝置從低功耗模式重置到運作(active)模式 ### Link Training 當鏈路上的所有裝置獲得電源與參考時脈後,PCIe 中的實體層會進行鏈路初始化(Link Initialization & Training)。 細節可參考 [PCIe Link Training Overview](https://www.ti.com/lit/an/snla415/snla415.pdf) 一文即影片。 ## 驅動程式介面 有關描述 PCI driver 的結構,以及如何註冊 PCI driver 的詳細說明,可參考以下資料: * [How To Write Linux PCI Drivers: pci_register_driver() call](https://docs.kernel.org/PCI/pci.html#pci-register-driver-call) ## Reference * [深入PCI与PCIe之一:硬件篇](https://zhuanlan.zhihu.com/p/26172972) * [深入PCI与PCIe之二:软件篇](https://zhuanlan.zhihu.com/p/26244141) * [原來 PCIe 技術原理這麼簡單!](https://www.gushiciku.cn/dc_tw/110022319) * [老男孩读PCIe之六:配置和地址空间](http://www.ssdfans.com/?p=8210) * [PCIe(一) —— 基础概念与设备树](https://r12f.com/posts/pcie-1-basics/) * [PCI Bus Subsystem](https://docs.kernel.org/PCI/index.html) * [Linux makes your PCIe topology visible in sysfs (/sys)](https://utcc.utoronto.ca/~cks/space/blog/linux/PCIeTopologyInSysfs) * [Fun and Easy PCIE - How the PCI Express Protocol works](https://www.youtube.com/watch?v=sRx2YLzBIqk) * [fpga4fun - PCI](https://www.fpga4fun.com/PCI.html) * [fpga4fun - PCIe](https://www.fpga4fun.com/PCI-Express.html)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully