This is an assembly function which is called the first time the secure world switches to the normal world and is responsible for preparing the monitor for future SMC calls.
.global init_secure_monitor init_secure_monitor: @ Install Secure Monitor @ ----------------------- ldr r1, =ns_image @ R1 is used str r0, [r1] ldr r0, =monitor @ Get address of Monitors vector table mcr p15, 0, r0, c12, c0, 1 @ Write Monitor Vector Base Address Register @ Save Secure state @ ------------------ ldr r0, =S_STACK_LIMIT @ Get address of Secure state stack stmfd r0!, {r4-r12} @ Save general purpose registers @ ADD support for SPs mrs r1, cpsr @ Also get a copy of the CPSR stmfd r0!, {r1, lr} @ Save CPSR and LR @ Switch to Monitor mode @ ----------------------- cps #Mode_MON @ Move to Monitor mode after saving Secure state @ Save Secure state stack pointer @ -------------------------------- ldr r1, =S_STACK_SP @ Get address of global str r0, [r1] @ Save pointer @ Set up initial NS state stack pointer @ -------------------------------------- ldr r0, =NS_STACK_SP @ Get address of global ldr r1, =NS_STACK_LIMIT @ Get top of Normal state stack (assuming FD model) str r1, [r0] @ Save pointer @ Set up exception return information @ ------------------------------------ @IMPORT ns_image ldr lr, ns_image @ ns_image msr spsr_cxsf, #Mode_SVC @ Set SPSR to be SVC mode @ Switch to Normal world @ ----------------------- mrc p15, 0, r4, c1, c1, 0 @ Read Secure Configuration Register data orr r4, #NS_BIT @ Set NS bit mcr p15, 0, r4, c1, c1, 0 @ Write Secure Configuration Register data @ Clear general purpose registers @ -------------------------------- mov r0, #0 mov r1, #0 mov r2, #0 mov r3, #0 mov r4, #0 mov r5, #0 mov r6, #0 mov r7, #0 mov r8, #0 mov r9, #0 mov r10, #0 mov r11, #0 mov r12, #0 movs pc, lr