ARM v8 secondary CPU bootup

Hi experts,

     i am trying wakeup the secondary CPU core in bootloader, i am able to do this through a trusted firmware. The problem comes after wakeup!

Once the cpu is up it will be in EL-2 mode and it executes a predefined function, in which i will load the stack pointer(SP) with a valid address and transfer the control to a function written in c-code. once the controls  is transferred it is not executing the any of further functions. Are there any additional settings which need to be done before we pass the control to actual function?

below is the code which is executed by the secondary cpu.

.global reset_handler_smp
reset_handler_smp:
        ldr     x3, =( svc_secondary_stack )    /* stack base ptr */
        mrs     x1, mpidr_el1                   /* read mpidr reg */
        and     x0, x1, #0xf                    /* cpuid =mpidr[3:0] */
        mov     x2, #STACK_SIZE                 /* stack size */
        mul     x0, x0, x2
        add     x3, x3, x0                      /* x3 - per cpu stack */
        bic     sp, x3, #7                      /* 8bit aligned stack */
        bl       _secondary_cpu_entry
looop: b looop

can some one please help me

Parents
  • Hello,

    A few things to note:

    • AArch64 uses a "Full Descending" stack
      The "full" means that the SP points to the most-recently-pushed item (unlike an "empty" stack, where SP points to the next empty slot for an item to be pushed to). The "descending" means that the SP is decremented when pushing items, and incremented when popping (unlike an "ascending" stack, which is the reverse)

      So, your code for initialising the SP is wrong, because CPU #0's SP will point to the base of your stack, and then pushing anything to the stack will take you outside of your stack region. To fix this, you should be loading the limit of the stack into X3, and then subtracting the multiple of (CPUID * STACK_SIZE) from this limit.
    • You are aligning your stack to 8-bytes, but the AAPCS (ARM AArch64 Procedure Call Standard) mandates that the SP be 16-byte aligned
      You should simply guarantee that the STACK_SIZE constant is a multiple of 16, and remove the BIC that is trying to force alignment, as your current implementation could actually end up with two different CPUs sharing a location on the stack, which is obviously a programming error
    • When you say "it is not executing any further functions", what do you mean? Has the core taken an exception? What is the value of ESR_ELx when the exception is taken?
    • Has the C library been initialised?
      You need to branch to __main on the primary CPU in order to initialise the C library, and you must do this before the secondary CPUs attempt to call any C functiosn
    • Did you mean to put a BL to _secondary_cpu_entry, rather than just a B?
      I wouldn't expect the secondary CPUs to ever return to this reset handler code, so a BL is probably wrong? And you actually just want a B

    In terms of helping you narrow down the exact issue, the most important information to provide will be the value of the ESR_ELx register (probably ESR_EL2 from what you've said) when you take the exception.

    Ash.

Reply
  • Hello,

    A few things to note:

    • AArch64 uses a "Full Descending" stack
      The "full" means that the SP points to the most-recently-pushed item (unlike an "empty" stack, where SP points to the next empty slot for an item to be pushed to). The "descending" means that the SP is decremented when pushing items, and incremented when popping (unlike an "ascending" stack, which is the reverse)

      So, your code for initialising the SP is wrong, because CPU #0's SP will point to the base of your stack, and then pushing anything to the stack will take you outside of your stack region. To fix this, you should be loading the limit of the stack into X3, and then subtracting the multiple of (CPUID * STACK_SIZE) from this limit.
    • You are aligning your stack to 8-bytes, but the AAPCS (ARM AArch64 Procedure Call Standard) mandates that the SP be 16-byte aligned
      You should simply guarantee that the STACK_SIZE constant is a multiple of 16, and remove the BIC that is trying to force alignment, as your current implementation could actually end up with two different CPUs sharing a location on the stack, which is obviously a programming error
    • When you say "it is not executing any further functions", what do you mean? Has the core taken an exception? What is the value of ESR_ELx when the exception is taken?
    • Has the C library been initialised?
      You need to branch to __main on the primary CPU in order to initialise the C library, and you must do this before the secondary CPUs attempt to call any C functiosn
    • Did you mean to put a BL to _secondary_cpu_entry, rather than just a B?
      I wouldn't expect the secondary CPUs to ever return to this reset handler code, so a BL is probably wrong? And you actually just want a B

    In terms of helping you narrow down the exact issue, the most important information to provide will be the value of the ESR_ELx register (probably ESR_EL2 from what you've said) when you take the exception.

    Ash.

Children
More questions in this forum