assembly 在内嵌组件中启用ARM勘误表

7ivaypg9  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(132)

我试图通过在驱动程序中启用勘误表的变通方法来学习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有点酷)。
编辑:
原始恩智浦勘误表说明中的汇编代码:

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中启用这个功能,当我从驱动程序中读取时,这个位会保持设置状态。但是如果我禁用它,这个位似乎会不规则地开关。它似乎可以证实这个位是什么时候设置的。

7kjnsjlb

7kjnsjlb1#

如果计算机有多个处理器核心(如一些i.MX6芯片),那么除非您安排运行所有处理器核心,否则它运行的处理器将由Linux调度程序决定。
因此,可以在一个CPU上设置寄存器,然后如果在该CPU上运行检查,则会显示修改,但如果在不同的CPU上运行检查,则会读取原始值。

相关问题