Hello,
I'm facing an issue with some of the linux kernel code. I'm trying to use the CPU suspend fonction (located in arch/arm/kernel/sleep.s) of the linux next kernel
The code is the following:
/*
* Save CPU state for a suspend. This saves the CPU general purpose
* registers, and allocates space on the kernel stack to save the CPU
* specific registers and some other data for resume.
* r0 = suspend function arg0
* r1 = suspend function
* r2 = MPIDR value the resuming CPU will use
*/
ENTRY(__cpu_suspend)
stmfd sp!, {r4 - r11, lr}
#ifdef MULTI_CPU
ldr r10, =processor
ldr r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
#else
ldr r4, =cpu_suspend_size
#endif
mov r5, sp @ current virtual SP
add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
sub sp, sp, r4 @ allocate CPU state on stack
ldr r3, =sleep_save_sp
stmfd sp!, {r0, r1} @ save suspend func arg and pointer
ldr r3, [r3, #SLEEP_SAVE_SP_VIRT]
ALT_SMP(ldr r0, =mpidr_hash)
ALT_UP_B(1f)
/* This ldmia relies on the memory layout of the mpidr_hash struct */
ldmia r0, {r1, r6-r8} @ r1 = mpidr mask (r6,r7,r8) = l[0,1,2] shifts
compute_mpidr_hash r0, r6, r7, r8, r2, r1
add r3, r3, r0, lsl #2
1: mov r2, r5 @ virtual SP
mov r1, r4 @ size of save block
add r0, sp, #8 @ pointer to save block
bl __cpu_suspend_save
adr lr, BSYM(cpu_suspend_abort)
ldmfd sp!, {r0, pc} @ call suspend 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 @ force non-zero value
mov sp, r2
ldmfd sp!, {r4 - r11, pc}
ENDPROC(cpu_suspend_abort)
This code appears to follow the standard procedure described in the following ARM document:
http://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCAQFjAA&url=http%3A%2F%2Ffr.slideshare.net%2Flinaroorg%2Fidling-ar-msinabusyworld&ei=7f_ZU_TnIeuV0QXW74DoDg&usg=AFQjCNEVnPO_e_2aYi2Q_4BMthr1Bp-AtA&sig2=NGAYgxTY_MIB1qA3_zeBcA&bvm=bv.72185853,d.d2k
I'm not so familiar with ARM assembly, but I understand that the code is saving the register states on the stack, and then enter the subroutine cpu_suspend_save to flush L1 and L2 cache memory.
When the programm is entering the __cpu_suspend save function, the CPU get lost in it and that turns into a kernel panic. Do you see a reason for such a thing ? Flushing the L1 and L2 cache could be the reason ?
Hi,
Sorry more questions back to you as it's not complete:
Regards,
Sudeep
[1] [PATCHv2 00/17] cpuidle for Marvell Armada 370 and 38x
Hello Sudeep and thank your for your answer,
Regards,Nicolas DEROUINEAU
Hi Nicolas,
Sorry for the delay, I see that you have already engaged with this discussion on the ALKML with authors/maintainers of the Marvel SoC.
They are the best people to answer any Marvel SoC specific questions.
The patches were reviewed by ARM engineer already.