我正在调整 u-boot 以支持 Cyclone V SX PCIe + NVMe。我通过对版本 2020.10 socfpga fork 的一系列黑客攻击使其工作。
我有两个问题需要解决:
u-boot 似乎并不理解 PCI 地址空间和主机地址空间不一定相同,当 nvme 获取分配给 PCIe 端口的地址时,PCI 驱动程序假定读取的地址直接映射到主存储器。它没有。它完全映射到另一个地址。我有一个黑客来处理这个问题。我将尝试向 u-boot 中的设备树实用程序添加一项功能,以在不破坏现有功能的情况下进行地址转换。
在 NVMe 执行命令后,nvme 驱动程序处理清除和无效缓存以获取对内存的更改的方式存在重大问题。门铃寄存器需要在轮询期间在传出时清除并在传入时无效,也就是说,在各种方面几乎完全错误。
这是我需要指导的地方。
u-boot 中有两位代码用于处理缓存清除/失效。一个是arm v7核心代码的一部分,另一个是pl310控制器代码。arm v7 代码认为缓存行是 64 字节,pl310 代码认为缓存行是 32 字节。什么?
nvme 代码正在使用这两个代码。我认为清除通过 pl310 和无效通过 arm v7,但我可能在这一点上倒退了,我还在学习,很容易把它们混在一起。
nvme 驱动程序的问题很简单:它要求清除未缓存对齐的地址范围,并且两个代码都阻塞并做错了事情,最终不会清除或使需要清除和无效的缓存无效。在 pl310 的情况下,它对起始地址进行四舍五入并且不做任何事情,在 arm v7 代码的情况下,如果开始和停止,在将它们对齐到 64 字节边界后,是相同的,代码确实没有什么。
我通过在 nvme 代码中强制对齐到 64 个字节来解决这个问题,并确保它通过在 stop 上添加一个来清除缓存,如果它与 arm v7 调用的情况下的 start 相同。
如果你还在关注我。谢谢,我真的很感激。
解决此问题的正确方法是什么。这些代码都不是我的。在我看来,缓存代码中存在错误。pl310 不应该在起始地址上加一,也许它应该在停止地址上加一,这取决于 for 循环的编写方式。用于在 arm v7 代码中失效的 for 循环应至少运行一次,以确保它清除起始位置。所以无效循环应该是<=,而不是<。
如果有人感兴趣,我可以发布此代码,请告诉我。
但最大的问题是:为什么有两种方法可以清除/使缓存无效,为什么两者都被使用?在我看来,由于 Cyclone V 使用 pl310 缓存控制器,它的代码应该用于清除和无效。这是通过#define 配置的,用于确定调用了哪些代码,并且告诉我这也应该修复。
意见?选项?想法?
我是开放的,请让我知道你的想法。