很快,我们将讨论具有两级缓存(L1,L2(的SoC。我需要将缓存中的所有数据刷新到主DDR内存中。问题是应该按照什么顺序进行
- 冲洗L1,冲洗L2
- 或者冲洗L2、冲洗L1
详细信息:
有问题的SoC是带有4个CPU的AArch64芯片。每个CPU都有单独的一级缓存和共享的二级缓存,主DDR内存在二级缓存之后
系统上CPU0启动并
- 初始化本身
- 初始化操作系统
- init环境(实际上是一堆全局变量(
- 为其他CPU做准备
- 其他CPU的发布重置,这样它们就可以启动、初始化自己并开始执行作业
现在CPU0,在允许其他人启动之前,先刷新整个缓存(L1和L2(,以便使全局环境变量可供其他人正确初始化。主初始化是由其他CPU在缓存关闭的情况下完成的,因此将数据存储在主存储器中而不仅仅是共享L2中是很重要的。通过使用dc csw ...
指令在所有集合/路径上迭代来刷新缓存。
问题是,一些全局变量并没有完全进入主内存。我可以看到CPU(而不是CPU0(用默认值读取这些变量(就像它们从未被CPU0分配过一样(。
重要信息:按"整个L1"-"整个L2"的顺序刷新缓存时会发生这种情况。当我将刷新顺序更改为L2-L1时,一切都很好,CPU从内存中读取正确的值。
但这可能只是一个"运气",所有必要的环境变量都被缓存控制器而不是我的缓存刷新例程从缓存中逐出。
那么,闪存的正确顺序是什么呢?谢谢
PS:
- 我很确定每个缓存的闪烁例程是好的,这只是在集合上的2个
for
循环&方式。第一次刷新一个缓存,然后刷新另一个缓存 - 缓存没有什么是确定的,L1-L2顺序通常有效。但我经常遇到问题。因此,在这种情况下"工作"只是运气数据驱逐
- 我们不是在谈论任何特定的操作系统
ARMv8参考手册在D4.4.7:
缓存维护指令的定义点不同,这取决于指令是通过VA操作还是通过set/way操作。
- 对于通过set/way操作的指令,该点被定义为下一级缓存。[…]
所以正确的顺序应该是L1,然后是L2。