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

SVCall returning to 0xdeadbeee

Hi,

I am developing for an ARM Cortex-M7 core (NXP iMIMXRT1062 chip), which is a Thumb only processor. I am using MCUXpressoIDE 11.1 which is based on Eclipse.

I have a problem returning from SVCall. When free running, it usually ends up at address 0xdeadbeee (0xdeadbeef with last bit removed), or can be caught in the HardFault_Handler. When I step through using a debugger (GDB) it appears to work correctly.

in excep.S

SVC_Handler:
    // This call follows the  ARM Architecture Procedure Calling Standard (AAPCS)
    // which pushes the following onto the stack from the calling function.
    // {r0-r3}, r12, LR, PC, xPSR
    // The LR currently set is the EXC_RETURN value which will cause the stack to
    // be unwound and the registers set to the initial values.
    .syntax unified

    // stack contains r0, r1, r2, r3 which are used as function arguments

    // Check whether we are using PSP or MSP (Handler mode always uses MSP)
    TST LR, #4                     // Test EXC_RETURN to see which stack is expected.

    ITE EQ
    MOVEQ    r1,  sp                // MSP in use
    MRSNE    r1, psp                // PSP in use

    LDR     r3, [r1, #0x18]        // excavate pc from stack

    // No need to check Thumb state
    LDRH  r0, [r3,#-2]           // Yes: Load halfword and...
    BIC   r0, r0, #0xFF00        // ...extract comment field

    STMFD    sp!, {LR}               // push LR onto stack before call

    BL      SVC_Handler_C          // Call main part of handler

    LDMIA    sp!, {LR}               // retrieve LR from stack

    // Put r0 (return value) into stack as return value from this function.
    stm sp, {r0}

    // Set PC to LR (which contains EXC_RETURN value), which will unwind the
    // stack and restore the registers
    BX LR
    .syntax divided
.endfunc

in excep_handlers.h

/** @brief Enumeration of operations performed by SVC.
 * The operation IDs need to fit into a uint8_t.
 */
typedef enum
{
    C4_SVC_Reserved,
    C4_SVC_PRINT,
    C4_SVC_ADD,
    C4_SVC_USER,
}C4_SVC_Op_t;


in excep_handlers.c


void *SVC_Handler_C(uint8_t SVC_type, void **args)
{
    switch (SVC_type)
    {
    case C4_SVC_PRINT:
        printf((char *)*args, (int) *(args+1));
        break;

    case C4_SVC_ADD:
        return (void *)((int)*args + (int)*(args+1));
        break;

    case C4_SVC_USER:
        break;
    default:
    {
        pointer expt_frm_ptr = 0;
        // Get PSP - should this test whether to get PSP or MSP
        asm volatile ("MRS %0, psp"  : "=r" (expt_frm_ptr) );
        expt_frm_dump(expt_frm_ptr);

        // C4_PRINT_ERR_STRING is safe here as the exception handler is already executing in privileged
        // state so does not need to use the exception call mechanism.
        C4_PRINT_ERR_STRING("Unhandled option in %s(%d)\n", __PRETTY_FUNCTION__, SVC_type);
        while(1) {}
    }
    }
    return NULL;
}

It is called like this:

int a1 = 3;
int a2 = 5;
int res = 0;
asm("MOV r0, %1\n\tMOV r1, %2\n\tSVC %3\n\tMOV %0, r0\n\t":"=r"(res): \
    "r"(a1), "r"(a2), "I" (C4_SVC_ADD));




The value of LR is 0xFFFF_FFF1 which is the expectd value of EXC_RETURN

What am I doing wrong in the return?

thanks

Dan

Parents
  • I am not following all of your logic, but one thing jumped out at me was that you expected, and got, an LR of 0xfffffff1. That would suggest you were in handler mode at time of the SVC call. I have always seen SVC as the way an RTOS implements the thread mode (aka user space) to handler mode (aka kernel space) trap. If you were truly in handler mode at time of SVC call, you were either in an ISR or in a system exception.  I think both are not good places to call SVC from.

Reply
  • I am not following all of your logic, but one thing jumped out at me was that you expected, and got, an LR of 0xfffffff1. That would suggest you were in handler mode at time of the SVC call. I have always seen SVC as the way an RTOS implements the thread mode (aka user space) to handler mode (aka kernel space) trap. If you were truly in handler mode at time of SVC call, you were either in an ISR or in a system exception.  I think both are not good places to call SVC from.

Children