This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

CPUIdle Marvell SoC

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 ?