SVC handlers in C and assembly language

Although the top-level handler must always be written in ARM assembly language, the routines that handle each SVC can be written in either assembly language or in C.

The top-level handler uses a BL instruction to jump to the appropriate C function. Because the SVC number is loaded into R0 by the assembly routine, this is passed to the C function as the first parameter. The function can use this value in, for example, a switch() statement, see the following example.

To call this C function you can add the following line to the SVC_Handler routine in the Example 44 example:

    BL    C_SVC_Handler     ; Call C routine to handle the SVC

Example 46. SVC handler in C function

void C_SVC_handler (unsigned number)
{
    switch (number)
    {
        case 0 :                 /* SVC number 0 code */
            ...
            break;
        case 1 :                 /* SVC number 1 code */
            ...
            break;
        ...
        default :                /* Unknown SVC - report error */
    }
}

The Supervisor mode stack space might be limited, so avoid using functions that require a large amount of stack space.

    MOV     R1, sp        ; Second parameter to C routine...
                          ; ...is pointer to register values.
    BL    C_SVC_Handler   ; Call C routine to handle the SVC.

You can pass values in and out of an SVC handler written in C, provided that the top-level handler passes the stack pointer value into the C function as the second parameter, in R1, and the C function is updated to access it:

void C_SVC_handler(unsigned number, unsigned *reg)

The C function can now access the values contained in the registers at the time the SVC instruction was encountered in the main application code, see the following example. It can read from them:

    value_in_reg_0 = reg [0];
    value_in_reg_1 = reg [1];
    value_in_reg_2 = reg [2];
    value_in_reg_3 = reg [3];

and also write back to them:

    reg [0] = updated_value_0;
    reg [1] = updated_value_1;
    reg [2] = updated_value_2;
    reg [3] = updated_value_3;

This causes the updated value to be written into the appropriate stack position, and then restored into the register by the top-level handler.

Figure 14. Accessing the Supervisor mode stack

To view this graphic, your browser must support the SVG format. Either install a browser with native support, or install an appropriate plugin such as Adobe SVG Viewer.


Show/hideSee also

Copyright © 2010-2012 ARM. All rights reserved.ARM DUI 0471G
Non-ConfidentialID021412