欢迎光临
我们一直在努力

如果不使用BAR空间,会有什么影响吗

可以不使用 BAR 空间,但影响很大。
简单说:

没有 BAR 空间,Linux 仍然可能枚举到 PCIe 设备;
但是 Linux 驱动很难控制 FPGA 里的 DMA、寄存器、中断状态和业务逻辑。

也就是说:

配置空间:设备还能被发现
BAR 空间:驱动能不能真正控制设备


1. 不使用 BAR 空间,设备还能被 Linux 识别吗?

可以。

即使没有 BAR,PCIe Endpoint 仍然有 配置空间,Linux 仍然可以读取:

Vendor ID
Device ID
Class Code
Command / Status
PCIe Capability
MSI Capability

所以 Linux 可能仍然能看到设备:

lspci

也可能还能根据:

Vendor ID / Device ID

匹配驱动。

但是问题在于:

能识别设备 ≠ 能控制设备

没有 BAR 后,驱动缺少访问 FPGA 自定义寄存器的入口。


2. 没有 BAR,最大影响是什么?

最大影响是:

Linux 驱动不能通过 readl()/writel() 访问 FPGA 自定义寄存器

也就是说,下面这些都没有地方写:

DMA_ADDR_LOW
DMA_ADDR_HIGH
DMA_LEN
DMA_DIR
DMA_CTRL.START
IRQ_ENABLE
IRQ_CLEAR
RESET

原来有 BAR 时:

writel(dma_addr_low, bar0 + REG_DMA_ADDR_LOW);
writel(dma_addr_high, bar0 + REG_DMA_ADDR_HIGH);
writel(len, bar0 + REG_DMA_LEN);
writel(DMA_DIR_C2H, bar0 + REG_DMA_DIR);
writel(DMA_CTRL_START, bar0 + REG_DMA_CTRL);

没有 BAR 后:

bar0 不存在
pci_iomap() 没有可映射对象
驱动没有地方写这些寄存器


3. 对 DMA 的影响最大

对于你现在讨论的 Block DMA,BAR 几乎是必需的。

因为 Block DMA 启动前,驱动必须告诉 FPGA:

Host DMA buffer 地址是多少?
传输长度是多少?
方向是 H2C 还是 C2H?
使用哪个通道?
什么时候开始?
是否使能中断?

正常流程是:

驱动写 BAR 寄存器
→ FPGA 读取 DMA 参数
→ FPGA 发 PCIe Memory Read / Memory Write
→ DMA 完成后 FPGA 中断通知 Host

如果没有 BAR,驱动没法告诉 FPGA 这些参数。

结果就是:

DMA 地址无法下发
DMA 长度无法下发
DMA 方向无法配置
DMA 无法 START
DMA 状态无法读取
DMA 错误无法查询

所以对 Block DMA 来说:

没有 BAR,基本无法正常做软件可控 DMA。


4. 对中断的影响

MSI/MSI-X 是 FPGA 向 Host 发中断。

但是驱动通常需要通过 BAR 控制:

IRQ_ENABLE
IRQ_STATUS
IRQ_CLEAR

没有 BAR 会导致:

4.1 不能灵活使能/关闭中断

正常有 BAR:

writel(IRQ_EN_DMA_DONE | IRQ_EN_DMA_ERROR, bar0 + REG_IRQ_ENABLE);

没有 BAR:

驱动无法控制 FPGA 哪些事件可以触发中断

4.2 不能清中断

正常中断处理:

irq_status = readl(bar0 + REG_IRQ_STATUS);
writel(irq_status, bar0 + REG_IRQ_CLEAR);
readl(bar0 + REG_IRQ_STATUS);

没有 BAR:

驱动不知道 FPGA 为何中断
驱动也无法清 FPGA 的 pending IRQ

这很危险,可能导致:

中断一直重复触发
驱动无法判断 DONE / ERROR
无法恢复 DMA 状态


5. 对 probe() 的影响

有 BAR 时,probe() 一般做:

pci_enable_device()
pci_request_regions()
pci_iomap()
readl(VERSION)
关闭 IRQ
清 IRQ
复位 DMA
分配 DMA buffer
申请中断
创建设备节点

没有 BAR 后,这几步会受影响:

probe 动作没有 BAR 的影响
pci_request_regions() 没有 BAR region 可申请,或者只申请不到 MMIO
pci_iomap() 没有 BAR 可映射
读取 VERSION 无法读取 FPGA 版本
关闭 IRQ_ENABLE 无法关闭 FPGA 中断
清 IRQ_STATUS 无法清旧中断
复位 DMA Engine 无法通过寄存器复位
初始化 DMA Engine 无法配置控制寄存器

结果是:

probe 只能识别设备,但无法真正初始化 FPGA 用户逻辑。


6. 对用户态接口的影响

如果没有 BAR,你的用户态流程会断掉。

原流程:

open()
mmap DMA buffer
ioctl START_DMA
poll 等待完成
读取 mmap buffer

其中 ioctl START_DMA 依赖驱动写 FPGA 寄存器。

没有 BAR 后:

open 可能还能成功
mmap Host DMA buffer 也可能还能做
但是 ioctl START_DMA 没法真正启动 FPGA DMA
poll 也等不到可靠完成事件

所以字符设备会变成:

有 /dev/my_pcie0
但是功能不可控


7. 没有 BAR,还有什么替代办法?

理论上有,但都不推荐作为常规 PCIe DMA 设备方案。


方案一:用配置空间 Vendor Specific Capability

可以在 PCIe 配置空间里放一些 Vendor Specific Capability,然后驱动通过:

pci_read_config_dword()
pci_write_config_dword()

读写少量控制信息。

但是缺点很大:

1. 配置空间很小
2. 访问慢
3. 不适合频繁控制
4. 不适合大量寄存器
5. 不适合 DMA doorbell
6. 不适合复杂状态机

配置空间主要用于枚举和能力声明,不适合当正常控制寄存器空间用。


方案二:FPGA 固定 DMA 地址,自主 DMA

比如 FPGA 上电后就往某个固定 Host 地址 DMA。

这个基本不现实,因为:

1. Host 物理地址不是固定的
2. Linux 内存分配是动态的
3. IOMMU 可能会转换 DMA 地址
4. FPGA 不知道 Host buffer 在哪里
5. 安全性很差

驱动必须通过某种方式把 dma_handle 告诉 FPGA。最常见方式就是 BAR 寄存器。


方案三:Host 内存里放 Descriptor,FPGA 自己取

这是 Scatter-Gather DMA 的思路。

但是问题是:

FPGA 第一次怎么知道 Descriptor Ring 的地址?

仍然需要一个启动/配置通道告诉 FPGA:

descriptor base address
ring size
doorbell
start

这些通常还是通过 BAR 寄存器下发。

所以即使用 SGDMA,BAR 仍然很常见。


方案四:FPGA 只作为纯数据采集设备,固定逻辑自动运行

比如 FPGA 上电后自动采集,自动 DMA,Host 只接收中断。

但仍然有几个问题:

1. Host buffer 地址如何告诉 FPGA?
2. 数据长度如何配置?
3. 出错如何复位?
4. 中断如何清除?
5. 状态如何读取?

最终通常还是需要 BAR。


8. 不使用 BAR,会不会影响 PCIe Memory Read / Write?

不会直接影响 FPGA 发 DMA TLP 的能力。

也就是说:

FPGA 理论上仍然可以发 PCIe Memory Read / Memory Write

但问题是:

它不知道应该读写哪个 Host 地址
它不知道传输长度
它不知道什么时候开始
它不知道 Host 当前分配的 DMA buffer 在哪里

所以不是硬件能力完全消失,而是:

缺少软件控制通道


9. 不使用 BAR,对 MSI/MSI-X 有什么影响?

MSI

MSI 不一定强制依赖 BAR。
MSI Capability 在配置空间中,PCI Core 可以配置 MSI Message Address / Data。

但是你的 FPGA 用户逻辑仍然需要知道:

什么时候发 MSI?
发完后 Host 如何清状态?
中断状态在哪里?

如果没有 BAR,驱动很难读写:

IRQ_STATUS
IRQ_ENABLE
IRQ_CLEAR

所以 MSI 本身可能可用,但系统不完整。


MSI-X

MSI-X 更麻烦。

MSI-X Table 和 PBA 通常位于某个 BAR 空间中,MSI-X Capability 里会描述:

Table BIR
Table Offset
PBA BIR
PBA Offset

如果完全没有 BAR,MSI-X 通常不好实现,甚至无法放置 MSI-X Table / PBA。

所以:

不用 BAR,MSI 还有可能;
不用 BAR,MSI-X 基本不适合。


10. 哪些设备可以没有 BAR?

有些非常简单的 PCIe 设备理论上可以没有 BAR,比如:

1. 只需要被枚举,不需要 Host 控制
2. 只用配置空间完成极少量控制
3. 固定功能设备
4. 测试用 Endpoint
5. 非常特殊的协议设备

但是对 FPGA PCIe DMA 设备来说,通常不建议。


11. 对你的 FPGA PCIe DMA 项目来说

如果你的目标是:

Linux 驱动控制 FPGA DMA
用户态 ioctl 启动 DMA
mmap buffer 收发数据
MSI/MSI-X 通知完成
poll 等待结果

那么建议:

必须使用 BAR0 作为控制寄存器空间

推荐结构仍然是:

配置空间:设备身份、BAR 描述、MSI/MSI-X Capability
BAR0:DMA 控制寄存器、状态寄存器、中断寄存器
Host DMA buffer:真正搬运的数据

关系是:

驱动通过 BAR0 控制 FPGA
FPGA 通过 DMA 访问 Host buffer
FPGA 通过 MSI/MSI-X 通知驱动


12. 最终结论

如果不使用 BAR 空间:

1. Linux 仍然可能枚举到 PCIe 设备
2. 驱动仍然可能根据 Vendor ID / Device ID 绑定设备
3. 但驱动无法方便访问 FPGA 自定义寄存器
4. DMA 地址、长度、方向、START 很难下发
5. DMA 状态、错误、中断状态很难读取
6. FPGA 中断很难清除
7. remove 时也很难可靠停止 DMA
8. 对 Block DMA 来说基本不可行

一句话:

没有 BAR,PCIe 设备还能“被看见”;
但 FPGA DMA 设备基本无法“被控制”。

所以对你这个 FPGA PCIe Block DMA 驱动 来说,BAR0 控制寄存器空间几乎是必须的。

赞(0)
未经允许不得转载:171主机测评 » 如果不使用BAR空间,会有什么影响吗
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址