在内联汇编中启用 ARM 勘误表

Enable ARM errata in inline assembly

我正在尝试通过在驱动程序中启用勘误表来学习 asm。这应该是可能的,因为内核代码是在特权世界中执行的。 (简约的)代码如下所示。

unsigned int cp15c15 = 0, result = 0;
__asm__ volatile("mrc p15, 0, %0, c15, c0, 1" : "=r" (cp15c15));
cp15c15 |= (1<<22); /* Errata 845369 */
__asm__ volatile("mcr p15, 0, %0, c15, c0, 1" : "+r" (cp15c15));

这似乎可行,但是当我多次读取寄存器时,有时我会得到一个没有启用第 22 位的值。 (例如 0x000001 而不是 0x400001)。

char buf[10];
__asm__ volatile("mrc p15, 0, %0, c15, c0, 1" : "=r" (cp15c15));
sprintf(buf, "0x%.8x", cp15c15);
copy_to_user(buffer, buf, 10);

我认为我在 asm 调用中做错了什么。如果有人能告诉我为什么这只在 10% 的时间内有效,我真的很感激。 (Asm 有点酷)。

编辑:
原始 NXP 勘误表描述中的汇编代码:

MRC p15,0,rt,c15,c0,1
ORR rt,rt,#0x00400000
MCR p15,0,rt,c15,c0,1

编辑 2:
如果我在 ./linux/arch/arm/mm/proc-v7.S 中启用它,当我从我的驱动程序读取它时,该位保持设置。但是,如果我禁用它,似乎该位会不规则地关闭和打开。这似乎证实了该位何时设置。

如果计算机有多个处理器内核(比如某些 i.MX 6 个芯片),那么除非您安排 运行 这所有处理器内核,否则 运行 上的处理器将随 Linux 调度程序的心血来潮。

因此可以将寄存器设置在一个 CPU 上,然后如果检查是 运行 在那个 CPU 上修改将显示,但如果检查是 运行 在不同的 CPU 上将读取原始值。