【问题标题】:Cache configuration for DMA device access on ARM Cortex-A72ARM Cortex-A72 上 DMA 设备访问的缓存配置
【发布时间】:2021-03-13 14:53:44
【问题描述】:

我正在为树莓派编写一个操作系统。 我的自定义 sdhost 控制器 (emmc2) 的 sdcard 驱动程序有问题 树莓派 4(Cortex-A72、ARMv8-A、bcm2711 芯片组)。 不使用 sdma 一切正常。用sdma,读可以,但是写扇区后,sdcard上的数据有时会包含无效数据。

对于 sdma 数据传输,我使用具有设备类型内存属性 (nGnRnE) 的传输缓冲区。当我使用新的数据缓冲区进行 dma 写入传输时,sdcard 上的数据是正确的。但是当我在下次写入时重复使用相同的缓冲区时,sdcard 上的扇区会部分包含来自前一个缓冲区内容的数据。

也许这是一个缓存一致性问题。我已启用所有缓存(I 和 D)。 ARM手册里有讲SCU(snoop control unit),不知道有没有对SCU有过困扰。

我的问题是:

  • 是否需要在 Cortex-A72 上启用 SCU?如何做到这一点?
  • 使用 dma 访问设备时还需要注意哪些其他事项?

【问题讨论】:

  • SCU 只是为了保持内核之间的数据一致。它不适用于 DMA。 DMA 设备不访问 L1/L2 缓存,它们总是进行“内存到设备”传输。您必须确保在激活写入 DMA 命令之前刷新缓冲区,或者将驱动程序内存标记为不可缓存。
  • 缓冲区不可缓存。页的内存类型是Device-nGnRnE(Device non-Gathering, non-Reordering, No Early write acknowledgement。相当于早期版本架构中的Strongly-ordered内存类型)。我转储了页面的 L2 转换表条目的值,它是 0x1279033。这个 L2 描述符的元素是: nG,non 全局位(第 11 位)为 0; S,可共享位(bit 10)为0; TEX[2:0](第 8-6 位)为 0; C(第 3 位)为 0; B(第 2 位)为 0。所以 TEX[2:0],C,B 为 000000,这意味着 Device-nGnRnE。 TEX 重映射被禁用(SCTLR.TRE 为 0)。
  • 由于您对这个问题没有其他意见,我建议您尝试冲洗。表可能没有正确设置。很难让所有位都正确。我同意如果表格正确,则不需要冲洗。但是,同花顺会告诉您表格是否正确。
  • 我刷新了缓存。没有成功。然后我用另一个 virt.addr 创建了第二个映射。和phys.addr。在 dma 缓冲区中,我从第二个 virt.addr 读回数据。并且数据是正确的。所以我认为数据到达了内存。结论是sdhci控制器没有从内存中读取所有数据,也许它有自己的缓存?对我来说似乎不太可能。有一点值得注意:一个错误的 512 字节扇区包含 3 个 32 字节的正确数据块(16 字节对齐),所有其他数据都是旧数据。 l2-cache 的 line-size 是 16 字节。也许这表明与 l2-cache 有关系。

标签: raspberry-pi arm osdev bare-metal armv8


【解决方案1】:

我找到了解决问题的方法: 在树莓派 4(bcm2711 芯片)上,写入 dma 引擎寄存器的物理地址必须是旧版主地址。旧版主地址在 0xC0000000-0xFFFFFFFF 范围内。所以我必须将 0xC0000000 添加到写入 sdhci 控制器寄存器的物理地址的值中。

文档可以在这里找到: https://datasheets.raspberrypi.org/bcm2711/bcm2711-peripherals.pdf 1.2.地址地图 1.2.4。旧版主地址

另一个 SCU 问题的答案是:启用缓存时,无需在 Raspberry Pi 4 上启用 SCU。

【讨论】:

    猜你喜欢
    • 2021-09-28
    • 2018-09-06
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    相关资源
    最近更新 更多