PCIE列舉失敗問題及分析

2021-10-05 22:27:07 字數 3870 閱讀 6754

在接觸pcie介面的這兩年當中,遇到了很多關於pcie啟動的問題,做了乙個彙總,以加固自己的認識和了解,也希望可以幫助其他新入門的同學,少走彎路。

在系統上電或者reset之後,裝置會有乙個初始化的過程,這個過程中裝置的暫存器都是無意義的,當初始化之後,所有暫存器資料穩定並且有意義。這是才可以進行configuration和裝置的列舉。

如圖,在系統初始化時,只有rc被硬編碼為bus0,列舉過程將從bus0 開始。

再次還要介紹兩個概念,pcie裝置中有device id和vendor id,它們都是硬編碼在晶元當中,不同的裝置有著不同的id,其中值ffffh保留 ,任何裝置不能使用。當rc發出乙個configuration讀請求時,如果返回的不是ffffh,那麼系統就認為存在這樣的裝置,如果返回的為ffffh那麼系統就認為不存在這個裝置。

列舉程式將要探測bus 0下面有幾個裝置,pcie允許每個匯流排上最多存在32個device。上面我們已經介紹了怎麼探測乙個裝置是否存在,這時rc將要產生乙個configuration read tlp,目的id為bus 0,device 0,function 0,讀取vendor id,如果返回的不是ffffh,那表明存在device 0,function 0。跳到下一步。如果返回為ffffh,那就表明一定不存在device 0。那麼程式就開始探測是否存在bus 0,device 1,function 0。

如果探測到裝置存在。在裝置的header type field中存在header type register,capability register。這兩個register表明device的一些特性。header type register的bit 7表明他是否是乙個多功能裝置(multi-function device)。capability register的bit4-7表明這個裝置的型別。假設現在列舉程式開始讀取bus 0,device 0,function 0的這兩個暫存器,返回header type資料為00000001b,表明這是乙個單function,橋裝置說明它還有下游裝置即存在bus 1。

現在程式進行一系列configuration write操作,將a裝置(fig.2)的primary bus number register=0,secondary bus number register=1,subordinate bus number register=1.現在橋a就可以感知他的下游匯流排為bus 1,下游最遠的匯流排為bus 1.

程式更新rc的相關暫存器。

程式讀取a的capability register,得到device/port type field=0100b,表明這是rc的乙個root port。

程式必須執行depth-first search。也就是說在探測bus 0上的其他裝置,程式應該首先探測device a下面的所有裝置。

程式讀取bus 1,device 0,function 0的vendor id,乙個有效的值返回,表示存在這個裝置c。

讀取header type field,返回00000001,表明c是乙個橋,且c是乙個單功能裝置。

c的capability register device/port type field=0101b,表明這是乙個switch的上行埠。

程式對c重複像步驟3一樣的操作。

同時更新host/bridge和橋a的subordinate bus number=2。

繼續depth-first search,發現裝置d。讀取相關暫存器,得知d為switch的下游介面橋裝置。得知bus 3的存在。對d的暫存器修改,更新上游裝置。

對bus 3 上的裝置進行探測,發現bus 3,device 0。讀暫存器,發現為endpoint多功能裝置。

結束depth-first search,回滾到bus 2,繼續探測裝置,然後執行depth-first search。

重複上述過程完成所有裝置遍歷。

以下將對幾個常見的pcie列舉失敗問題做個彙總,由於設計專案都是關於fpga的,問題大多以fpga為例。

硬體問題:上電時序問題,如果fpga上電時序未按要求進行設計,則可能發生fpga啟動不了。

解決方案:測試fpga各個電源的上電時序,調整電源上電時序,來滿足時序要求。

以xilinx fpga為例為例,上電時序為vccint≤vccbram≤vccaux≤vcco。如下:

以上這個時序問題嗎,基本上大家設計時都會注意到,但是還有個時序約束條件常常被忽略。

手冊中是這樣描述的:

指的的上公升時間必須在0.2ms到50ms之間,否則會發生fpga啟動異常。

之前就有專案,將vcco的上電時間大於50ms,出過fpga載入失敗問題。

操作問題:啟動時連線了jtag,並且開啟了hardware,

解決方案:將軟體關掉,最有效的是將jtag線纜拔掉。具體我就不做過多介紹了。詳細見(ug908),我的理解是jtag具有較高的優先順序,會影響到fpga的正常配置。

約束問題:設計時並未嚴格按規範要求設計,導致識別不了,這裡面要檢查兩個方面,乙個是tx和rx,這個接反了就得重新頭版了,另乙個就是針對x1以上的pcie時序,pcie是硬核,需與硬體設計一致

解決方案:核對pcie的時序資訊,對錯誤的時序進行調整,注意到pcie是硬核,在約束時需考慮進行調整。由於pcie是硬核,ip核例化生成的檔案中包含了xdc以固定引腳分配,該xdc是read only的,以下方法經常實際專案實踐,是可以解決問題的。以下是更改pcie硬核約束檔案的一種方式。

set_property package_pin {} [get_ports rx0_p]

set_property package_pin {} [get_ports rx1_p]

set_property package_pin {} [get_ports rx2_p]

set_property package_pin {} [get_ports rx3_p]

set_property package_pin y2 [get_ports rx0_p]

set_property package_pin w4 [get_ports rx1_p]

set_property package_pin v2 [get_ports rx2_p]

set_property package_pin u4 [get_ports rx3_p]

啟動時序問題:fpga啟動時間在協議上有特定要求,協議要求pcie需要120ms內載入完成,以保證可以正常被列舉到。如果邏輯檔案較大,配置時間大於協議要求,則會導致rc裝置發現不了板卡。

解決方案:縮短pcie載入時間,兩個方便去提公升,乙個是壓縮檔案,乙個是提高載入速度。

提高載入速度,可以提高cclk的時鐘頻率,從手冊中了解到最高可設定為66mhz,如果需要選擇66到100mhz,需要外接晶振,

結論就是外接晶振範圍為大於66m小於100m。(因為66m以下,fpga可以自己產生,100m是最大頻率限制)

壓縮配置檔案。

新增壓縮**:set-property bitstream.general.compress ture[current-design]00

更改配置方式,採用xilinx tandem pcie方式對fpga進行配置,這種配置過程極大的節省的配置時間,優先將pcie部分進行載入,以便pcie裝置列舉成功。此方法優於上面兩個方法。

以上針對pcie列舉失敗常見的問題進行了小結合分析,並提出的各個問題的原因和解決方案,以便各位更好的理解,關於各個解決方案的具體操作,可根據方案的描述,在網上進行查詢。

第二層皮

2020.5.10 合肥

列舉注意的問題及應用

在學校學c語言的時候,很多人都沒有經常用,以至於對enum不是很了解,後來工作的時候,我發現這個經常用到,於是就上網查了下詳解。1.enum的用法 列舉型別定義用關鍵字enum標識,形式為 enum 識別符號 列舉型別status僅有兩個資料,乙個是copy,乙個是delete,序號為0 1,代表複...

Tomcat 啟動失敗原因分析 埠問題

問題描述 今天啟動tomcat時遇到乙個狀況,開啟bin目錄下的startup.bat批處理檔案,出現載入頁面,但是中途會報出錯誤,並迅速閃退,tomcat啟動失敗,但奇怪的是localhost 8080依舊可以正常訪問,其間原因暫時沒能理解。更換多個版本tomcat未能解決,後來朋友提醒會不會是埠...

expect自動互動指令碼執行失敗問題分析

前言 寫了乙個自動互動指令碼中用到了expect自動互動工具。目的是自動登陸到伺服器,並執行預先寫好的shell指令碼。如下 usr bin expect settimeout 1 set script weblogic sj viewusage.sh set host 100.12.128.1 s...