【乾貨】從CPU角度理解PCIe續集

2021-02-07 SSDFans


上篇文章剩下兩個問題,上電掃描PCIe樹和存儲地址到PCIe地址的映射,本篇文章將對這兩個問題做出解答。本文可能會針對某一款晶片做出詳細流程解答,讀者可以只關注整個流程,具體映射機制和寄存器參考晶片datasheet。上篇文章已經了解到如何訪問配置空間,前256Bytes可以通過寄存器方式訪問,後面的256B~4k必須通過映射才能訪問,映射無非就是把配置空間映射到存儲地址空間,或者把PCIe設備空間映射到存儲地址空間。下面開始討論映射關係。



PCIe在存儲域地址空間分為三部分,PCIe控制器本身的寄存器、PCIe設備的配置空間、PCIe設備空間。寄存器和配置空間由處理器本身決定存儲地址範圍,本款處理器地址範圍如圖 1所示,配置空間地址、寄存器地址、內存地址都已經確定。PCIe設備空間需要編程人員去配置Outbound和Inbound寄存器組,確定映射關係。

圖1


Outbound在PCIe控制器中扮演的角色是將存儲地址翻譯到PCIe域的PCIe地址,Inbound是將PCIe地址翻譯成存儲地址,圖 2是一個完整的RC和EP模型地址翻譯模型,圖中的地址數字僅僅代表一種形態,具體地址應該是什麼在後文中講解。當cpu需要訪問EP的內存空間時,首先應該將存儲地址轉換成PCIe地址,在根據TLP到達指定的EP,進而將PCIe地址轉換成EP端的存儲地址。


圖2


PCIe地址到存儲地址之間的映射關係由三個寄存器決定(有兩個寄存器組應該是32個寄存器)OB_SIZE、OB_OFFSET_INDEXn、OB_OFFSETn_HI,n的範圍是0~31。在PCIe控制器中是把PCIe地址等分成32塊regions (Regions 0 to 31),每個regions的大小是可以通過編程設置OB_SIZE寄存器確定大小,大小有1, 2, 4, or 8 MB,那麼通過Outbound能夠翻譯的地址最大為8M*32=256M。存儲域地址中有5位作為識別32個regions的index,OB_SIZE的大小決定這5位在32位地址上的位置。當OB_SIZE等於0,1,2,3時,index在存儲地址中對應的位置是Bits[24:20], bits[25:21], bits[26:22], and bits[27:23],每個regions翻倍,是不是對應的地址應該按翻倍對齊呢,翻倍就是左移一位數據。OB_SIZE寄存器如圖 3所示。


圖3


OB_OFFSET_INDEXn寄存器結構如圖 4所示,n是上一段落提到的index的值。該寄存器第0位是地址翻譯使能位,第31~20位是第n個regions的基地址的31~20位,這裡的取值取決regions的大小,當OB_SIZE 等於0,1,2,3時,bits[31:20], bits[31:21], bits[31:22], and bits[31:23]位相應被使用。


OB_OFFSETn_HI寄存器的值是64位PCIe地址中第n個regions的基地址的63~32位,在32位PCIe地址中,該寄存器的值等於0。


圖4


配置OutBound翻譯的幾個寄存器也做了詳解,下面根據舉例說明。圖 5中配置空間存儲地址由CPU本身架構所決定,這部分的地址映射才晶片內部完成,不需要由編程人員配置。PCIe設備空間被分成了32等分。假設region大小是2M,PCIe地址是64位,程序中需要對0x9D3A_1234存儲地址做映射, 64位PCIe地址被使用在region 9上,初始化OBOFFSET9_HI值為0x3344 5566, OB_OFFSET9值56Ex xxxx(x的值這裡不關心,看該寄存器結構就很清楚,第0位在地址翻譯時候應該使能位1,這裡僅僅用來講解怎麼做映射,不需要關心後面的Bits) ,下面分析怎麼翻譯到PCIe地址:


由於是regions大小2M,那麼index應該取地址的bits [25:21],提取0x9D3A_1234存儲地址的bits [25:21得到01001b,該值等於9,那麼該地址應該啟用regions 9 翻譯。存儲地址的bits[20:00]是用做翻譯到PCIe地址的bits[20:00]位,該值也可以理解成reginos 9內的偏移值,值是0x001A 1234。


生成regions 塊PCIe的基地址,該地址應pcie_base=OBOFFSET9_HI <<32 + OB_OFFSET9的bits[31:21] = 0x 3344 5566 56E0 0000。


計算PCIe地址,pcie_addr = pcie_base + 存儲地址bits[20:0] =0x3344 5566 56FA 1234。


圖5


從上面存儲地址到PCIe地址映射可以看到,通過cpu尋址可以直接訪問到PCIe設備空間,最多可以訪問PCIe設備空間大小為256M,具體Outbound能夠訪問的大小根據晶片而定,當CPU與FPGA之間有大量數據交互時候也可以採用Inbound方式(Inbound地址翻譯流程如圖 6所示,這裡就不在翻譯),將CPU的內存映射到FPGA的尋址空間(這裡是站在CPU角度看的,從圖2可以理解具體映射大小還由EP決定),FPGA可以採用DMA方式訪問cpu的內存,並且速度很快。有些晶片廠商乾脆採用同核異構方式將CPU於FPGA集成在一起(有的將cpu與dsp集成在一起),兩者之間採用AXI高速總線通訊。


圖6



掃描樹的流程如下:


掃描PCIe總線樹時,需要對這些PCIe總線進行編號,即初始化PCIe橋(在本文一律指透明橋)的Primary、Secondary和Subordinate Bus寄存器。在Linux內核中採用DFS算法對PCIe總線樹進行遍歷,DFS算法是按照深度優先的原則遍歷PCIe樹,局部代碼如圖 7所示,這裡可以跟蹤pci_scan_bridge函數,函數採用DFS算法對總線進行編號(後期會講解搜索樹,比較常見hash表、紅黑樹)。


圖7



PCIe設備的IDSEL信號與PCIe總線的AD[31:0]信號的連接關係決定了該設備在這條總線上的設備號。在配置讀寫總線事務的地址周期中,AD[10:0]已經被信號已經被功能號和寄存器號使用,因此PCIe設備的IDSEL只能與AD[31:11]信號連接。上一篇文章中談到CONFIG_ADDR寄存器中的Device Number欄位一共有5位,最大能夠表示32個設備,這裡只有21位,顯然在兩者之間不能建立一一映射關係。一個PCIe總線號下最多可以掛在21個PCIe設備,那麼多個PCIe總線不就可以掛載32個設備了麼。



在32位PCIe地址空間中,PCIe設備通常將PCIe配置存放在E2PROM中,PCIe設備進行上電初始化時,將E2PROM中的信息讀到PCIe設備的配置空間作為初始值,由硬體自動完成。BAR0空間存儲了PCIe設備空間的大小,某些位被設置成不可預讀,當BAR0全部寫入1時,然後在讀取BAR0值,從數據低位看有多少連續位沒有改變。沒有改變的數據位數記錄的該PCIe設備空間的大小,假如有n位沒有改變,那麼設備空間大小應該是2的n次方。第0位代表IO/Memory、第2,3位代表32/64位地址、第4位代表是否可預取,具體位定義格式可以直接參考內核PCIe總線代碼,解析BAR函數如圖 8所示。


圖8


系統軟體根據根據設備空間大小建立存儲地址PCIe設備地址空間的映射,給PCIe設備分配的PCIe基地址寫入到BAR0,如果是64位PCIe地址,那麼BAR1是高32位地址。



寫《從cpu角度理解PCIe》文章我參考了部分晶片的datasheet,並結合linux代碼分析,本文僅僅起到分析流程的作用,具體映射機制和寄存器晶片參考相應晶片datasheet。如有錯誤,還望指正。


相關焦點

  • 深入理解Kubernetes資源限制:CPU
    想要理解這篇文章所說的內容,不一定要先閱讀上一篇文章,但我建議那些工程師和集群管理員最好還是先閱讀完第一篇,以便全面掌控你的集群。1. CPU 限制正如我在上一篇文章中提到的,CPU 資源限制比內存資源限制更複雜,原因將在下文詳述。幸運的是 CPU 資源限制和內存資源限制一樣都是由 cgroup 控制的,上文中提到的思路和工具在這裡同樣適用,我們只需要關注他們的不同點就行了。
  • 投資加密貨幣的乾貨,從市值的角度去理解投資就會豁然開朗
    01你應該擁有的投資基礎概念今天來說點乾貨。我覺得作為一個新人,很好的理解市值是太有必要的投資技能,而不是從大家很喜歡去分析的價格、幣的總量或者流通量去投資。這個其實和賺錢是一個道理,很多人投資賺錢特別在意收益率,其實收益率的天花板特別明顯。
  • CPU配置|cpuinfo參數
    如果想了解系統中CPU的提供商和相關配置信息,則可以通過/proc/cpuinfo文件得到。是否在內核態支持對用戶空間的防寫;flags : 當前cpu支持的功能;bogomips : 粗略測算的cpu速度;clflush size :每次刷新緩存的大小單位;
  • Linux - cpupower調整CPU主頻
    ondemand:按需快速動態調整 CPU 頻率, 一有 cpu 計算量的任務,就會立即達到最大頻率運行,等執行完畢就立即回到最低頻率;ondemand:userspace 是內核態的檢測,用戶態調整,效率低。
  • 手機CPU天梯圖2020 最新手機cpu性能排行榜
    首頁 > 問答 > 關鍵詞 > cpu最新資訊 > 正文 手機CPU天梯圖2020 最新手機cpu性能排行榜
  • cpu-z怎麼用,cpu-z使用教程
    很多人知道cpu-z,可能更多的是通過它來了解電腦的顯存大小,不過除了查看顯存這樣的功能,對了解我們電腦配置情況也是有著極大的參考作用的,下面我來說下cpu-z怎麼用,cpu-z使用教程。安裝好cpu-z後,在我們桌面雙擊打開cpu-z的運行圖標。
  • CPU頻率和核心
    設置CPU的核心數在/sys/devices/system/cpu目錄下可以看到你的CPU有幾個核心,如果是四核,就是cpu0,cpu1,cpu2,cpu3 4個文件夾。cpu0 常開。echo "0" > /sys/devices/system/cpu/cpu0/online # 關閉該CPU核心echo "1" > /sys/devices/system/cpu/cpu0/online # 打開該CPU核心設置CPU的頻率查看CPU
  • 性能測試之用例得分評價和 CPU 內存數據監控——談談個人看法和實踐總結
    小編導讀:性能測試不少人應該都做過,但你知道性能測試的數據最後能拿來做什麼嗎
  • 2018筆記本cpu性能天梯圖 筆記本cpu性能排行2018
    2018筆記本cpu性能天梯圖 筆記本cpu性能排行2018 2018年11月18日 HuangJiang來源:IT之家
  • 性能基礎之CPU、物理核、邏輯核概念與關係
    作業系統被欺騙了,因為它被提供了兩個虛擬或邏輯cpu (LCPU),而不是單個cpu,因為它被允許「同時」執行兩個進程。但是值得注意的是,不可能產生傳統處理器兩倍的處理能力,也不可能提供完全的並行處理能力。 因此,從Linux或其他作業系統的角度來看,一個只有一個核心處理器但HT的機器就像有兩個cpu一樣出現在我們眼前。但是這是在同一個物理cpu中運行的兩個邏輯cpu。
  • Linux CPU負載與利用率
    如果是多核多cpu,比如現在是2個cpu,每個cpu是1個核,那麼理論上總負載不能超過2。2、如何查看CPU信息?(1)查看單個cpu核數:cat /proc/cpuinfo | grep "cpu cores"|uniq(2)查看物理CPU個數:cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l(3)查看邏輯CPU的個數:cat
  • 中科大劉淇:從自適應學習的角度理解AI+教育
    不到現場,照樣看最乾貨的學術報告!嗨,大家好。這裡是學術報告專欄,讀芯術小編不定期挑選並親自跑會,為大家奉獻科技領域最優秀的學術報告,為同學們記錄報告乾貨,並想方設法搞到一手的PPT和現場視頻——足夠乾貨,足夠新鮮!話不多說,快快看過來,希望這些優秀的青年學者、專家傑青的學術報告 ,能讓您在業餘時間的知識閱讀更有價值。
  • e1500cpu多少錢 e1500cpu報價及評測【詳解】
    e1500cpu是因特爾旗下的一款經典暢銷產品,它定價不高。但是性能參數以及與機子的適配方面的表現十分出色,這也使得e1500cpu成為高性價比高口碑的卓越代表。那麼接下來不妨就隨小編一起來了解幾個關於e1500cpu的相關方面的信息吧。我們將為大家詳細介紹e1500cpu的報價、評測以及支持主板舉例這三個板塊的文字圖片內容。
  • Android Systrace 基礎知識(12) - Kernel_CPU Info 解讀
    本文是 Systrace 系列文章的第十二篇,主要是對 Systrace 中的 CPU 信息區域(Kernel)進行簡單介紹,簡單介紹了如何在 Systrace 中查看 Kernel 模塊輸出的 CPU 相關的信息,了解 CPU 頻率、調度、鎖頻、鎖核相關的信息本系列的目的是通過 Systrace 這個工具,從另外一個角度來看待
  • 老奶奶都能看懂的CPU技術科普
    因為作業系統根本不需要知道你cpu是怎麼設計的,作業系統只要知道,我需要運行這些指令,你知道怎麼運行就行了,每個不同牌子的cpu,只要你運行出來結果都一樣,就行了。如果isa定義1+1=9,那麼這個是定義下來的,所有人都這樣錯,就沒錯。如果isa定義了1+1=9,你要糾正他,我的cpu是1+1=2,那麼你做出來的cpu雖然數學上正確,但是所有軟體,系統,就突然不知道怎麼辦了。
  • 使用 nice、cpulimit 和 cgroups 限制 cpu 佔用率
    如果想讓一個CPU密集型的進程運行在較低優先級,那麼你就得事先配置好調度器。下面介紹3種控制進程運行時間的方法:我們來看一下這3個工具的工作原理和各自的優缺點。模擬高cpu佔用率在分析這3種技術前,我們要先安裝一個工具來模擬高CPU佔用率的場景。我們會用到CentOS作為測試系統,並使用Mathomatic toolkit中的質數生成器來模擬CPU負載。
  • 透過Tracepoint理解內核 - 調度器框架和性能
    相比於直接鑽到scheduler的實現細節中去, 我們先通過tracepoint及其相關工具去理解實現背後的邏輯, 細節總是不停變化, 而分析方法往往相對固定, 也更容易沉澱下來.NUMA相關, 從性能分析角度上看, 它們必須在我們的checklist中, 一定程度可以把它們當作是異常(USE)sched_pi_setprio. 用於實現rt_mutex的優先級繼承, 比如用在futex上.
  • CPU 利用率背後的真相,只有 1% 人知道
    通過進一步分析 CPU 停頓的原因,可以指導代碼優化,提高執行效率,這是我們深入理解CPU微架構的動力之一。2. CPU 利用率的真實含義是什麼?我們通常所說的CPU利用率是指 「non-idle time」:即CPU不執行 idle thread 的時間。作業系統內核會在上下文切換時記錄CPU的運行時間。
  • cpu高不是問題?如果不是,那什麼才是問題?
    cpu如何計算當我們執行top命令的時候,看到裡面的值(主要是cpu和load)值是一直在變的,因此有必要簡單了解一下Linux系統中cpu的計算方式。cpu分為系統cpu和進程、線程cpu,系統cpu的統計值位於/proc/stat下(以下的截圖未截全):