极术小姐姐 · 2019年12月19日

CPUIdle Marvell SoC

我面临一些Linux内核代码的问题。我正在尝试使用linux下一个内核的CPU挂起功能(位于arch / arm / kernel / sleep.s中)

代码如下:

/ *

 *保存CPU状态以挂起。这节省了CPU通用

 *注册并在内核堆栈上分配空间以节省CPU

 *特定的寄存器和一些其他数据以供恢复。

 * r0 =暂停功能arg0

 * r1 =暂停功能

 * r2 =恢复CPU将使用的MPIDR值

 * /

ENTRY(__ cpu_suspend)

    stmfd sp !, {r4-r11,lr}

#ifdef MULTI_CPU

    ldr r10,=处理器

    ldr r4,[r10,#CPU_SLEEP_SIZE] @ CPU睡眠状态的大小

#其他

    ldr r4,= cpu_suspend_size

#万一

    mov r5,sp @当前虚拟SP

    添加r4,r4,#12 @ pgd,virt sp,phys简历的空间fn

    sub sp,sp,r4 @在堆栈上分配CPU状态

    ldr r3,= sleep_save_sp

    stmfd sp !, {r0,r1} @保存暂停函数arg和指针

    ldr r3,[r3,#SLEEP_SAVE_SP_VIRT]

    ALT_SMP(ldr r0,= mpidr_hash)

    ALT_UP_B(1f)

    / *此ldmia依赖于mpidr_hash结构的内存布局* /

    ldmia r0,{r1,r6-r8} @ r1 = Mpidr掩码(r6,r7,r8)= l [0,1,2]个移位

    compute_mpidr_hash r0,r6,r7,r8,r2,r1

    加r3,r3,r0,lsl#2

1:mov r2,r5 @虚拟SP

    mov r1,r4 @保存块的大小

    添加r0,sp,#8 @指针以保存块

    bl __cpu_suspend_save

    adr lr,BSYM(cpu_suspend_abort)

    ldmfd sp !, {r0,pc} @调用暂停fn

ENDPROC(__ cpu_suspend)

    .ltorg

cpu_suspend_abort:

    ldmia sp !, {r1-r3} @ pop phys pgd,virt SP,phys resume fn

    teq r0,#0

    moveq r0,#1 @强制非零值

    mov sp,r2

    ldmfd sp !, {r4-r11,pc}

ENDPROC(cpu_suspend_abort)

该代码似乎遵循以下ARM文档中描述的标准过程:

http://www.google.fr/url?sa=t... AFQjCNEVnPO_e_2aYi2Q_4BMthr1Bp-AtA&sig2 = NGAYgxTY_MIB1qA3_zeBcA&bvm = bv.72185853,d.d2k

我对ARM汇编不是很熟悉,但是我知道代码将寄存器状态保存在堆栈中,然后进入子例程cpu_suspend_save刷新L1和L2高速缓存。

当程序进入__cpu_suspend保存函数时,CPU迷失在其中,这会导致内核崩溃。您看到这种事情的原因了吗?刷新L1和L2缓存可能是原因?

1 个回答 得票排序 · 时间排序
棋子 · 2019年12月19日

我发现您已经与Marvel SoC的作者/维护者进行了有关ALKML的讨论。

他们是回答Marvel SoC特定问题的最佳人选。

补丁已由ARM工程师进行了审查。

你的回答