当前位置: 首页 > backend >正文

飞腾2000+/64核 PCIE扫描异常问题排查

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上把日志信息贴出后,建议解决思路如下:

结合情况分析

  1. 硬件侧 (FPGA/bitstream)

    • 这个设备是 Xilinx XDMA IP 导出的 PCIe Endpoint。

    • 如果 bitstream 没有正确启用 BAR0(或者 BAR 大小配置和驱动不一致),内核扫描 PCIe 配置空间时不会分配内存资源。

    • 你可以用 setpci -s 11:00.0 BASE_ADDRESS_0 查看 BAR0 的原始值,确认是不是 0x00000000

  2. BIOS/UEFI 设置

    • 如果 BAR 是 64-bit,需要 BIOS 支持并开启 Above 4G Decoding / Large BAR support,否则 BIOS 不会给它分配地址。

    • 典型症状就是 lspci 里显示 <unassigned>

  3. 内核资源分配

    • 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. 从硬件/时序上根治

  1. 保证“配置先于枚举”

    • 把 bitstream 存在板载 SPI-Flash,随上电完成 FPGA 配置;

    • 或者用 CPLD/MCU 延迟释放 PERST#,直到 DONE=1MMCM/PLL lockeduser_lnk_up=1(或 LTSSM=L0)再放开。

  2. 检查 XDMA 配置

    • PF0 BAR0 启用且大小与驱动期望一致(常见 64 KB AXI-Lite 控制空间)。

    • 不要改动到导致 BAR 为 0 的设置。

  3. 主板 BIOS 设置

    • 打开 Above 4G Decoding / Large BAR,避免 64-bit BAR 分配失败。

    • 若插槽支持热插拔/下行端口复位,确保启用。

B. 运行时的补救(设备已“错过”枚举)

成功与否取决于上游 Root Port/桥是否支持热插拔/热复位以及系统是否允许 OS 侧重新分配资源。

  1. 尝试 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 
  2. 对上游端口做热复位(可选、谨慎)

    • 如果内核导出了 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)

http://www.xdnf.cn/news/19529.html

相关文章:

  • COM组件——ServicedComponent 类
  • 【架构师干货】系统架构设计
  • Vue3 + MQTT + 高德地图 实现车辆在线状态与实时位置更新
  • 云手机和云游戏之间有着哪些区别?
  • qData 数据中台【开源版】发布 1.0.4 版本,全面升级数据清洗与资产管理能力
  • 使用LoadBalancer替换Ribbon(五)
  • 使用C#语言 基于FTP协议进行文件夹上传下载
  • ansible知识点总结1
  • C/C++ Linux系统编程:进程通讯完全指南,管道通讯、共享内存以及消息队列
  • Linux之Docker虚拟化技术(三)
  • nacos微服务介绍及环境搭建
  • Oracle 查询有哪些用户 提示用户名密码无效
  • AI 入门指南:从 “听不懂人话” 到 “比你懂你”,人工智能到底是个啥?
  • shell编程 函数、数组与正则表达式
  • 网络与信息安全有哪些岗位:(13)安全服务工程师 / 顾问
  • pip不是内部或外部命令的问题怎么解决?
  • 基于.NET Framework 4.0的FTP文件传输类
  • 【云存储桶安全】怎么满足业务需求,又最大程度上满足信息安全要求呢?
  • 构建深度学习音频识别模型:从数据预处理到性能评估
  • 【K8s】整体认识K8s之监控与升级/ETCD的备份和恢复/kustomization/CRD
  • wpf之样式
  • PAT 1089 Insert or Merge
  • UBUNTU之Onvif开源服务器onvif_srvd:1、编译
  • 如何使用VMware创建一台Ubuntu机器
  • Shell脚本实用技巧集锦:从时间判断到系统监控
  • 【数据可视化-104】安徽省2025年上半年GDP数据可视化分析:用Python和Pyecharts打造炫酷大屏
  • HTTP/2 多路复用
  • 网络流量分析——熟悉Wireshark
  • 时序数据库国产的有哪些?
  • ​​--flush-logs 的作用:刷新 MySQL 的日志文件(主要是二进制日志 binlog)​