欢迎光临
我们一直在努力

BAR空间要给哪些功能使用

BAR 空间主要给 Host/Linux 驱动控制 FPGA 用户逻辑 使用。
一句话:

BAR 空间 = Host 访问 FPGA 的控制面 / 状态面 / 调试面

对你的 PCIe Block DMA 来说,BAR 空间最应该给这些功能使用:DMA 控制、中断控制、状态查询、错误诊断、版本能力识别、调试统计。你前面流程里 probe() 映射 BAR、ioctl() 写 DMA 参数、irq_handler() 读 IRQ/DMA 状态,都是围绕 BAR 空间完成的。


1. 必须放 BAR 空间的功能

1.1 版本 / 能力识别寄存器

这类寄存器用于驱动确认 FPGA bitstream 是否正确。

推荐放:

VERSION
CAPABILITY
BUILD_TIME
IP_ID
REGISTER_MAP_VERSION

作用:

驱动 probe() 时先读 VERSION
→ 判断是不是正确 FPGA 版本
→ 判断寄存器布局是否匹配
→ 判断支持几通道 DMA、是否支持 64-bit 地址、是否支持 MSI-X

例如:

BAR0 + 0x0000 VERSION
BAR0 + 0x0004 CAPABILITY

这类寄存器非常适合放 BAR。


1.2 全局控制寄存器

用于控制整个 FPGA DMA IP。

推荐放:

GLOBAL_CTRL
GLOBAL_STATUS
SOFT_RESET
GLOBAL_ENABLE
IP_READY

作用:

驱动可以复位 DMA IP
驱动可以判断 FPGA 逻辑是否 ready
驱动可以关闭整个 DMA 模块

例如:

BAR0 + 0x0008 GLOBAL_CTRL
BAR0 + 0x000C GLOBAL_STATUS


1.3 DMA 控制寄存器

这是 BAR 空间最核心的用途。

推荐放:

DMA_CTRL
DMA_STATUS
DMA_DIR
DMA_CHANNEL
DMA_ADDR_LOW
DMA_ADDR_HIGH
DMA_LEN
DMA_START
DMA_STOP
DMA_RESET

作用:

驱动把 Host DMA buffer 地址写给 FPGA
驱动把 DMA 长度写给 FPGA
驱动告诉 FPGA 是 H2C 还是 C2H
驱动写 START 启动 DMA
驱动读 STATUS 判断 DMA 状态

例如:

BAR0 + 0x0010 DMA_CTRL
BAR0 + 0x0014 DMA_STATUS
BAR0 + 0x0018 DMA_DIR
BAR0 + 0x0020 DMA_ADDR_LOW
BAR0 + 0x0024 DMA_ADDR_HIGH
BAR0 + 0x0028 DMA_LEN

对于 Block DMA,这部分基本必须有。


1.4 中断控制寄存器

MSI/MSI-X 是 FPGA 通知 Host 的机制,但驱动仍然需要通过 BAR 管理中断状态。

推荐放:

IRQ_ENABLE
IRQ_STATUS
IRQ_CLEAR
IRQ_MASK
IRQ_VECTOR_MAP

作用:

驱动使能 DMA_DONE / DMA_ERROR 中断
FPGA 完成 DMA 后置 IRQ_STATUS
驱动中断处理中读取 IRQ_STATUS
驱动写 IRQ_CLEAR 清中断

例如:

BAR0 + 0x0030 IRQ_ENABLE
BAR0 + 0x0034 IRQ_STATUS
BAR0 + 0x0038 IRQ_CLEAR

没有这些寄存器,中断会很难管理:驱动不知道为什么中断,也不知道如何清中断。


1.5 错误状态寄存器

用于 DMA 或 PCIe 出错后的诊断。

推荐放:

ERROR_CODE
PCIE_ERR_STATUS
FIFO_STATUS
LAST_ERROR_ADDR_LOW
LAST_ERROR_ADDR_HIGH
TIMEOUT_STATUS

作用:

DMA 出错后,驱动可以读错误码
用户态可以通过 ioctl(GET_STATUS) 获取错误原因
调试 FPGA 时能判断是 PCIe 错、FIFO 错、地址错还是长度错

例如:

BAR0 + 0x0044 ERROR_CODE
BAR0 + 0x0050 PCIE_ERR_STATUS
BAR0 + 0x0054 FIFO_STATUS


2. 建议放 BAR 空间的功能

2.1 调试寄存器

这类不是必须,但非常有用。

推荐放:

DEBUG_STATE
FSM_STATE
LAST_DMA_ADDR
LAST_DMA_LEN
LAST_TLP_INFO
READ_REQ_COUNT
WRITE_REQ_COUNT
COMPLETION_COUNT

作用:

上板调试 DMA 卡死
查看状态机停在哪里
查看 PCIe 请求是否发出
查看 Completion 是否回来
查看 FIFO 是否堵住

例如:

BAR0 + 0x2000 DEBUG_STATE
BAR0 + 0x2004 FSM_STATE
BAR0 + 0x2008 READ_REQ_COUNT
BAR0 + 0x200C WRITE_REQ_COUNT

调试寄存器建议单独放一段,不要和正式控制寄存器混在一起。


2.2 性能统计寄存器

如果你要分析 DMA 带宽,可以放:

BYTES_DONE
TRANSFER_COUNT
DMA_CYCLE_COUNT
MAX_LATENCY
MIN_LATENCY
PCIE_READ_REQ_CNT
PCIE_WRITE_REQ_CNT

作用:

统计 DMA 传输量
估算 DMA 带宽
分析 PCIe 性能瓶颈
定位 FPGA 侧还是 Host 侧慢

例如:

BAR0 + 0x0040 BYTES_DONE
BAR0 + 0x3000 PERF_CYCLE_COUNT
BAR0 + 0x3004 PERF_BYTES_COUNT


2.3 多通道 DMA 管理

如果你以后支持多个 DMA channel,可以每个 channel 一块寄存器区域。

例如:

0x0100 ~ 0x01FF DMA channel 0
0x0200 ~ 0x02FF DMA channel 1
0x0300 ~ 0x03FF DMA channel 2
0x0400 ~ 0x04FF DMA channel 3

每个通道都有:

CH_DMA_CTRL
CH_DMA_STATUS
CH_DMA_ADDR_LOW
CH_DMA_ADDR_HIGH
CH_DMA_LEN
CH_DMA_DIR
CH_IRQ_STATUS
CH_ERROR_CODE

好处是驱动容易写:

#define CH_BASE(ch) (0x0100 + (ch) * 0x100)
#define CH_DMA_CTRL(ch) (CH_BASE(ch) + 0x00)
#define CH_DMA_STATUS(ch) (CH_BASE(ch) + 0x04)
#define CH_DMA_LEN(ch) (CH_BASE(ch) + 0x10)


2.4 Scatter-Gather DMA / Descriptor Ring 控制

如果以后从 Block DMA 升级到 SGDMA,BAR 也要放这些控制寄存器:

DESC_BASE_LOW
DESC_BASE_HIGH
DESC_RING_SIZE
DESC_HEAD
DESC_TAIL
DOORBELL
SGDMA_CTRL
SGDMA_STATUS

作用:

驱动把 descriptor ring 地址告诉 FPGA
驱动更新 tail
驱动敲 doorbell
FPGA 从 Host 内存读取 descriptor

即使 descriptor 本身放在 Host 内存里,descriptor base address / doorbell 仍然通常通过 BAR 寄存器下发。


3. 不适合放 BAR 空间的功能

3.1 大块数据 buffer 不建议放 BAR

不要把大规模业务数据放 BAR 里。

比如这些不适合放 BAR:

图像大帧数据
ADC 连续采样数据
网络包大流量数据
几 MB / 几百 MB 的数据缓存

原因:

BAR 适合控制寄存器,不适合高吞吐数据面
大数据应该走 DMA buffer

正确方式:

BAR:写 DMA 地址、长度、方向、START
DMA buffer:真正放大块数据


3.2 高频数据流不建议通过 BAR 读写

比如你让 CPU 不断:

readl(bar0 + DATA_REG);

去读 ADC 数据,这种效率很低。

问题:

每次 readl 都是 MMIO/PCIe 访问
吞吐低
CPU 占用高
延迟不可控
不适合连续数据流

高频数据应该走:

FPGA DMA → Host DMA buffer


3.3 PCIe 标准配置项不放 BAR

这些不应该由你自己放 BAR:

Vendor ID
Device ID
BAR Register
MSI Capability
MSI-X Capability
PCIe Capability
Link Status
Command Register

这些属于 PCIe 配置空间,由 PCIe IP / PCIe Core 管理,不是 BAR 用户寄存器。


4. 推荐 BAR0 功能分区

如果你做单通道 Block DMA,可以这样:

BAR0 64KB

0x0000 ~ 0x00FF 全局控制 / 版本 / 能力
0x0100 ~ 0x01FF DMA channel 0 控制寄存器
0x0200 ~ 0x02FF 预留 DMA channel 1
0x0300 ~ 0x03FF 预留 DMA channel 2
0x1000 ~ 0x1FFF IRQ / event 管理
0x2000 ~ 0x2FFF debug 调试寄存器
0x3000 ~ 0x3FFF performance 统计寄存器
0x4000 ~ 0xFFFF 保留扩展


5. 单通道 Block DMA 推荐寄存器

0x0000 VERSION
0x0004 CAPABILITY
0x0008 GLOBAL_CTRL
0x000C GLOBAL_STATUS

0x0100 CH0_DMA_CTRL
0x0104 CH0_DMA_STATUS
0x0108 CH0_DMA_ADDR_LOW
0x010C CH0_DMA_ADDR_HIGH
0x0110 CH0_DMA_LEN
0x0114 CH0_DMA_DIR
0x0118 CH0_DMA_CONFIG
0x011C CH0_BYTES_DONE
0x0120 CH0_ERROR_CODE
0x0124 CH0_TIMEOUT_CFG

0x1000 IRQ_ENABLE
0x1004 IRQ_STATUS
0x1008 IRQ_CLEAR
0x100C IRQ_MASK

0x2000 DEBUG_STATE
0x2004 DEBUG_FSM
0x2008 DEBUG_FIFO_LEVEL
0x200C DEBUG_PCIE_TAG_CNT

0x3000 PERF_DMA_CYCLES
0x3004 PERF_BYTES_TOTAL
0x3008 PERF_READ_REQ_CNT
0x300C PERF_WRITE_REQ_CNT

这个比全部塞到 0x0000 ~ 0x0050 更适合后续扩展。


6. 最小可用版本

如果你只想先跑通,最少需要这些:

VERSION
DMA_CTRL
DMA_STATUS
DMA_ADDR_LOW
DMA_ADDR_HIGH
DMA_LEN
DMA_DIR
IRQ_ENABLE
IRQ_STATUS
IRQ_CLEAR
ERROR_CODE

也就是:

BAR0 + 0x0000 VERSION
BAR0 + 0x0010 DMA_CTRL
BAR0 + 0x0014 DMA_STATUS
BAR0 + 0x0020 DMA_ADDR_LOW
BAR0 + 0x0024 DMA_ADDR_HIGH
BAR0 + 0x0028 DMA_LEN
BAR0 + 0x002C DMA_DIR
BAR0 + 0x0030 IRQ_ENABLE
BAR0 + 0x0034 IRQ_STATUS
BAR0 + 0x0038 IRQ_CLEAR
BAR0 + 0x0044 ERROR_CODE

这个版本能完成:

驱动识别 FPGA
驱动配置 DMA 地址
驱动配置 DMA 长度
驱动配置方向
驱动启动 DMA
FPGA 上报完成
驱动清中断
驱动查询错误


7. BAR 空间功能分配原则

原则说明
控制类放 BAR START、STOP、RESET、ENABLE
状态类放 BAR BUSY、DONE、ERROR、IDLE
参数类放 BAR DMA 地址、长度、方向、通道
中断类放 BAR IRQ_ENABLE、IRQ_STATUS、IRQ_CLEAR
错误类放 BAR ERROR_CODE、PCIE_ERR_STATUS
调试类可放 BAR FSM_STATE、FIFO_LEVEL、计数器
大数据不要放 BAR 大数据走 DMA buffer
PCIe 标准能力不放 BAR Vendor ID、MSI Capability 属于配置空间

8. 最终结论

BAR 空间最应该给这些功能使用:

1. FPGA 版本 / 能力识别
2. 全局复位 / 使能 / 状态
3. DMA 地址 / 长度 / 方向 / 通道配置
4. DMA START / STOP / RESET 控制
5. DMA DONE / BUSY / ERROR 状态
6. IRQ_ENABLE / IRQ_STATUS / IRQ_CLEAR
7. ERROR_CODE / PCIE_ERR_STATUS / FIFO_STATUS
8. DEBUG_STATE / 统计计数器 / 性能计数器
9. SGDMA descriptor ring base / doorbell,若以后扩展 SGDMA

不应该给这些功能使用:

1. 大块数据缓存
2. 高频连续数据流
3. Host DMA buffer 本身
4. PCIe 标准配置空间内容

一句话:

BAR 空间用来做“控制和状态”;
DMA buffer 用来做“数据搬运”。

赞(0)
未经允许不得转载:171主机测评 » BAR空间要给哪些功能使用
分享到: 更多 (0)

评论 抢沙发

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