0

我正在尝试将 PCIe 驱动程序写入从主机内存到 FPGA 的 DMA 页面。我的主机设置是 Cavium ThunderX2,我的 FPGA 是 Xilinx Alveo U50。

来自/到主机的 DMA 会导致 ARM SMMU v3.4 引发事件 0x10 Translation fault。我正在使用 dma_map_single(..) 和 dma_alloc_coherent(..) Linux API 将页面的虚拟地址映射到支持 DMA 的地址。

进一步检查事件记录、上下文描述符和流表条目,我有以下信息。

Type of Fault - F_TRANSLATION (Translation Fault)

S2 == 0 (Stage 1 Fault - Virtual Address -> Intermediate Physical Address stage)
Class of Fault = TT/TTD (Translation Table Descriptor Fetch)
PnU == Underprivileged Access
T0SZ == 5'b01000 (16); T1SZ == 5'b00000 (IGNORED because EPD1 == 1)
VAS == 49 bits (Virtual Address Size)
TG0 == 00 (4 kB page granule size)
EPD0 == 0 (Stage 1 page table walk enabled)
EPD1 == 1 (Stage 2 is bypassed)
TB0/1 == 0 (Top byte ignore disabled)
IPS == 44 bits (Input Address size)
SMMU Config = 3'b101 (Stage 1 translation enabled, Stage 2 bypassed)

获得的页面的示例虚拟和 DMA 地址 -

Virtual Address - 0xFFFF--- (64-bit value)
DMA Address - 0x9F733CA000 (looks within the range defined by T0SZ and compliant with the IPS)

当一切看起来都很好时,我无法弄清楚为什么我会遇到第 1 阶段的翻译错误。从技术上讲,我应该遇到第 2 阶段故障,因为它被绕过并且输入地址应该通过 TTB0 进行转换。

PS我是ARM v8的新手。如果您需要评论中的其他信息,请告诉我。

附件是故障F_TRANSLATION的图片。

4

1 回答 1

0

我能够解决这个问题。IOMMU 和 DMA 映射之间存在同步失效。在 SMMU 中没有为映射的 DMA 地址找到有效的描述符。

我使用 dma_alloc_coherent(SZ_2M) 获取缓冲区并使用 IOMMU 域操作将 IOVA 映射到 SMMU。

int ret = iommu_domain->ops->map(domain, IOVA, size, phys_addr, PROT)

现在 SMMU 能够获取和翻译 IOVA。

出于某种原因, dma_map_single(..) 不适用于我当前的实现。我必须调查为什么流式 DMA API 不起作用。

于 2022-01-12T02:58:26.153 回答