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.
View all questions in SoC Design forum