1、背景介紹
近期項目中采用全國產飛騰計算模塊搭配一塊FPGA模塊(FPGA為復旦微的VU9P),實現業務數據的收發。FPGA中采用了Xilinx的XDMA IP核,飛騰計算模塊中的FT2000+/64核處理器通過PEU1的一路 PCIE3.0x8與VU9P相連接,發現在飛騰上加載xilinx的xdma驅動時提示xdma驅動正常加載,但no device found。等于沒有找到設備。
2、問題排查
首先確認硬件設備能否找到,輸入lspci能看到設備
輸入lspci -s 12:00.0 -vvv查看詳細設備信息時輸出如下:
[系統未激活][root@node12-0 tests]# lspci -s 11:00.0 -vvv
11:00.0 Serial controller: Xilinx Corporation Device 9018 (prog-if 01 [16450])Subsystem: Xilinx Corporation Device 0007Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-Interrupt: pin A routed to IRQ 14Region 0: Memory at <unassigned> (64-bit, non-prefetchable) [virtual] [size=64K]Capabilities: [40] Power Management version 3Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+Address: 0000000000000000 Data: 0000Capabilities: [70] Express (v2) Endpoint, MSI 00DevCap: MaxPayload 1024 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1usExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0.000WDevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+MaxPayload 512 bytes, MaxReadReq 1024 bytesDevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM not supportedClockPM- Surprise- LLActRep- BwNot- ASPMOptComp+LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-LnkSta: Speed 8GT/s (ok), Width x8 (ok)TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-DevCap2: Completion Timeout: Range BC, TimeoutDis+, NROPrPrP-, LTR-10BitTagComp-, 10BitTagReq-, OBFF Not Supported, ExtFmt-, EETLPPrefix-EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-FRS-, TPHComp-, ExtTPHComp-AtomicOpsCap: 32bit- 64bit- 128bitCAS-DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis+, LTR-, OBFF DisabledAtomicOpsCtl: ReqEn-LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-Compliance De-emphasis: -6dBLnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-Capabilities: [100 v1] Advanced Error ReportingUESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+AERCap: First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-HeaderLog: 00000000 00000000 00000000 00000000
上面顯示
Region 0: Memory at <unassigned> (64-bit, non-prefetchable) [virtual] [size=64K]
也就是bar空間無法分配,此時輸入dmesg 查看驅動加載異常日志,顯示
[ 1203.426451] xdma v2017.0.45
[ 1203.426560] xdma 0000:11:00.0: can't enable device: BAR 0 [mem size 0x00010000 64bit] not assigned
[ 1203.426572] xdma: probe of 0000:11:00.0 failed with error -1
[ 1203.426597] xdma 0000:12:00.0: can't enable device: BAR 0 [mem size 0x00010000 64bit] not assigned
[ 1203.426603] xdma: probe of 0000:12:00.0 failed with error -1
[ 1255.253522] xdma v2017.0.45
[ 1255.253629] xdma 0000:11:00.0: can't enable device: BAR 0 [mem size 0x00010000 64bit] not assigned
[ 1255.253640] xdma: probe of 0000:11:00.0 failed with error -1
[ 1255.253665] xdma 0000:12:00.0: can't enable device: BAR 0 [mem size 0x00010000 64bit] not assigned
[ 1255.253671] xdma: probe of 0000:12:00.0 failed with error -1
也提示找不到設備的原因為bar空間probe失敗了。
可以判斷直接原因是?BAR0 根本沒有被分配物理地址。
在chatgpt上把日志信息貼出后,建議解決思路如下:
結合情況分析
硬件側 (FPGA/bitstream)
這個設備是
Xilinx XDMA
IP 導出的 PCIe Endpoint。如果 bitstream 沒有正確啟用 BAR0(或者 BAR 大小配置和驅動不一致),內核掃描 PCIe 配置空間時不會分配內存資源。
你可以用
setpci -s 11:00.0 BASE_ADDRESS_0
查看 BAR0 的原始值,確認是不是0x00000000
。BIOS/UEFI 設置
如果 BAR 是 64-bit,需要 BIOS 支持并開啟 Above 4G Decoding / Large BAR support,否則 BIOS 不會給它分配地址。
典型癥狀就是
lspci
里顯示<unassigned>
。內核資源分配
Linux 看到 BAR0 需要內存,但 BIOS 沒分配,就不會啟用設備。
內核有時候能“重新分配”資源,可以嘗試在 grub 加參數:
pci=realloc
pci=assign-busses
然后
update-grub && reboot
。
其實針對2和3點,因為使用同一個模塊與另一個FPGA模塊(復旦微的V7)測試xdma沒有問題,可以排除。第1點在FPGA工程師檢查和確認下也進行了排除。
最后排查發現,當FPGA 的XDMA IP核啟動慢時,將導致BAR0空間無法分配,chatgpt也給出了解釋:
短答:會的。
如果 FPGA(含 XDMA IP)在主機進行 PCIe 枚舉/資源分配時還沒就緒,BIOS/固件無法讀取有效的 BAR 配置,就不會給 BAR 分配 MMIO 地址;等你后面 bitstream 才起來時,設備已經“錯過了”最初的分配時機,于是出現你看到的BAR 0 ... not assigned
,驅動 probe 失敗。為什么會這樣
PCIe 上電后主機流程是:
釋放 PERST# → 鏈路訓練到 L0 → 讀配置空間(BAR size) → 分配 MMIO
。
若 XDMA 在這些步驟發生時還沒配置好(如 bitstream 還沒完成、user_lnk_up 還沒到 L0、BAR 寄存器還未有效),主機會認為“沒有/不需要內存資源”,于是不會給 BAR 地址。后面即使鏈路正常了,除非固件/OS重新分配,否則lspci
里就會一直是<unassigned>
,驅動就啟用不了設備。你可以怎么解決(兩條路線)
A. 從硬件/時序上根治
保證“配置先于枚舉”
把 bitstream 存在板載 SPI-Flash,隨上電先完成 FPGA 配置;
或者用 CPLD/MCU 延遲釋放 PERST#,直到
DONE=1
、MMCM/PLL locked
、user_lnk_up=1
(或 LTSSM=L0)再放開。檢查 XDMA 配置
PF0 BAR0 啟用且大小與驅動期望一致(常見 64 KB AXI-Lite 控制空間)。
不要改動到導致 BAR 為 0 的設置。
主板 BIOS 設置
打開 Above 4G Decoding / Large BAR,避免 64-bit BAR 分配失敗。
若插槽支持熱插拔/下行端口復位,確保啟用。
B. 運行時的補救(設備已“錯過”枚舉)
成功與否取決于上游 Root Port/橋是否支持熱插拔/熱復位以及系統是否允許 OS 側重新分配資源。
嘗試 OS 側重新分配資源
臨時一次性:
echo 1 | sudo tee /sys/bus/pci/rescan
若仍不分配,先“移除再掃描”:
echo 1 | sudo tee /sys/bus/pci/devices/0000:11:00.0/remove echo 1 | sudo tee /sys/bus/pci/rescan
仍失敗,給內核加參數讓其強制重新分配(下次重啟生效):
pci=realloc
對上游端口做熱復位(可選、謹慎)
如果內核導出了 reset 接口:
echo 1 | sudo tee /sys/bus/pci/devices/0000:<UPSTREAM_PORT>/reset
或通過 Secondary Bus Reset(依平臺而定,可能影響同總線其他設備)。
如果這些補救都不行,基本就只能回到 A 路線:保證 FPGA 在 BIOS/OS 枚舉時已經就緒。
不過由于飛騰2000+ 64核不支持PCIE熱插拔,于是重新reset或先移除再掃描無法解決該問題
在 飛騰 2000+ 這種處理器平臺上,PCIe 確實沒有熱插拔(Hot-Plug)能力,所以不能像服務器那樣靠 Root Port 做 Slot Reset,讓設備重新枚舉。但 remove/rescan 這類軟件操作,本質上只是讓內核釋放并重新探測配置空間,并不是真的“熱插拔”,因此是否可行要看 設備枚舉時 BAR 是否已經有效。
最終解決辦法是讓FPGA 邏輯在飛騰計算模塊枚舉前加載完畢,否則只能讓飛騰計算模塊上電后執行reboot了。
chatgpt也產生了一個自動檢測PCIE設備的腳本,供參考
#!/bin/bash
# quick_pcie_rescan_auto.sh
# 自動檢測并測試 Xilinx XDMA (10ee:9018) 設備是否能在 bitstream 加載后重新分配 BAR
# 打印 BAR0 地址和大小,并檢查是否有效VENDOR="10ee"
DEVICE="9018"echo ">>> 掃描 PCIe 總線,查找 Xilinx XDMA 設備 ($VENDOR:$DEVICE) ..."
DEVICES=$(lspci -Dnnd ${VENDOR}:${DEVICE} | awk '{print $1}')if [ -z "$DEVICES" ]; thenecho "未發現 Xilinx XDMA 設備 ($VENDOR:$DEVICE)。"exit 1
fifor DEV in $DEVICES; doecho "------------------------------------------"echo ">>> 處理設備: $DEV"SYSFS_DEV="/sys/bus/pci/devices/0000:$DEV"if [ ! -d "$SYSFS_DEV" ]; thenecho "設備 $DEV 的 sysfs 路徑不存在,跳過。"continuefiecho ">>> 移除設備 $DEV ..."echo 1 > "$SYSFS_DEV/remove"echo ">>> 重新掃描 PCIe 總線 ..."echo 1 > /sys/bus/pci/rescanecho ">>> 查看 BAR0 分配情況:"REGION_INFO=$(lspci -s $DEV -vvv | grep -A5 "Region 0")echo "$REGION_INFO"# 解析 BAR0 大小 (size=字段)BAR0_SIZE=$(echo "$REGION_INFO" | grep -oP "size=\K\S+")if [ -n "$BAR0_SIZE" ]; thenecho "BAR0 大小: $BAR0_SIZE"elseecho "BAR0 大小: 未檢測到"fiecho ">>> 讀取 BAR0 原始寄存器值:"BAR0_HEX=$(setpci -s $DEV BASE_ADDRESS_0)echo "BAR0 raw value = 0x$BAR0_HEX"# 檢查 BAR0 是否有效if [[ "$BAR0_HEX" == "00000000" || "$BAR0_HEX" == "ffffffff" ]]; thenecho "!!! 警告: FPGA BAR0 未導出 (值=$BAR0_HEX)"echo ">>> 可能原因: FPGA bitstream 未配置 BAR0 或啟動時序太慢,需檢查硬件側。"elseecho ">>> FPGA BAR0 看起來有效 (值=$BAR0_HEX)"fi
done
輸出示例如下:
>>> 查看 BAR0 分配情況:
Region 0: Memory at 91c00000 (64-bit, non-prefetchable) [size=64K]
BAR0 大小: 64K
>>> 讀取 BAR0 原始寄存器值:
BAR0 raw value = 0x91c00004
>>> FPGA BAR0 看起來有效 (值=0x91c00004)