ARM 锁定寄存器写操作导致设备崩溃
我正在使用运行 Linux 内核的 ARM Cortex A-8 设备进行一些实验。
我可以毫无问题地访问和读取 L2 缓存锁定寄存器的值:
asm volatile ("mrc p15, 1, %0, c9, c0, 0" : "=r" (i));
当我尝试写回该值时,设备立即崩溃:
asm volatile ("mcr p15, 1, %0, c9, c0, 0" : : "r" (i));
该代码作为内核模块运行,因此不存在权限问题。
我想知道在写入该寄存器值之前我是否遗漏了任何特殊的东西?
I'm doing some experiments with a ARM Cortex A-8 device running Linux kernel.
I can access and read the value of the L2 cache lockdown register without any problems:
asm volatile ("mrc p15, 1, %0, c9, c0, 0" : "=r" (i));
When I try to write the value back, the device immediately crashes:
asm volatile ("mcr p15, 1, %0, c9, c0, 0" : : "r" (i));
The code is running as a kernel module so there are no permission issues.
I wonder if I'm missing anything special before writing that register value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您要使用缓存锁定,则需要注意一个很长的清单。 ARM 的信息中心有一些提示: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344i/Chdeghcb.html
特别是,请确保已禁用中断,并使相应的指令/数据无效。还要检查读/写访问是否已启用 - 即使您处于内核模式,也可能不会启用。您需要确保代码在关键点不会跨页或跨缓存行。 要做到正确确实很困难。你不能只设置一个缓存路锁定并期望一切都能正常工作,你也不能只用 C 语言的内联 ASM 来完成它。
最坏的情况是你最终会堵塞 L2 缓存控制器的内部状态机,锁定错误的数据,阻止数据完全缓存并导致一切中止,或者使标签不同步。这就能解释这次车祸了。
另外,这只是实验还是你想提高性能?它对于避免接触精心设计的代码序列的 DRAM/总线很有用,例如,如果您想将其关闭(深度睡眠),但这通常不会带来性能优势。
There's a long checklist you need to be careful about if you're going to play with cache lockdown. ARM's information center has a few tips: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344i/Chdeghcb.html
In particular, ensure you have interrupts disabled, and appropriate instructions/data invalidated. Also check that read/write access is enabled - which it might not be even if you're in kernel mode. You need to ensure your code isn't crossing pages or cache lines at critical points. It's really tricky to get right. You can't just set a cache-way locked and expect everything to be work, and you can't just do it with inline ASM in C.
Worst case you'll end up jamming the internal state machine of the L2 cache controller, locking the wrong data down, preventing data from caching altogether and causing everything to abort, or getting the tags out of sync. That'll explain the crash.
Also, is this just experimentation or are you trying to boost performance? It's useful for avoiding touching DRAM/bus for well crafted code sequences, for example if you want to turn it off (deep sleep), but it's not usually a performance win.