Home | History | Annotate | Download | only in Arm
      1 #========================================================================================
      2 #  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
      3 #
      4 #  This program and the accompanying materials
      5 #  are licensed and made available under the terms and conditions of the BSD License
      6 #  which accompanies this distribution.  The full text of the license may be found at
      7 #  http://opensource.org/licenses/bsd-license.php
      8 #
      9 #  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 #  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 #
     12 #=======================================================================================
     13 
     14 #start of the code section
     15 .text
     16 .align 3
     17 
     18 GCC_ASM_EXPORT(return_from_exception)
     19 GCC_ASM_EXPORT(enter_monitor_mode)
     20 GCC_ASM_EXPORT(copy_cpsr_into_spsr)
     21 GCC_ASM_EXPORT(set_non_secure_mode)
     22 
     23 # r0: Monitor World EntryPoint
     24 # r1: MpId
     25 # r2: SecBootMode
     26 # r3: Secure Monitor mode stack
     27 ASM_PFX(enter_monitor_mode):
     28     cmp     r3, #0                      @ If a Secure Monitor stack base has not been defined then use the Secure stack
     29     moveq   r3, sp
     30 
     31     mrs     r4, cpsr                    @ Save current mode (SVC) in r4
     32     bic     r5, r4, #0x1f               @ Clear all mode bits
     33     orr     r5, r5, #0x16               @ Set bits for Monitor mode
     34     msr     cpsr_cxsf, r5               @ We are now in Monitor Mode
     35 
     36     mov     sp, r3                      @ Set the stack of the Monitor Mode
     37 
     38     mov     lr, r0                      @ Use the pass entrypoint as lr
     39 
     40     msr     spsr_cxsf, r4               @ Use saved mode for the MOVS jump to the kernel
     41 
     42     mov     r4, r0                      @ Swap EntryPoint and MpId registers
     43     mov     r0, r1
     44     mov     r1, r2
     45     mov     r2, r3
     46 
     47     bx      r4
     48 
     49 # Return-from-exception is not an interworking return, so we must do it
     50 # in two steps, in case r0 has the Thumb bit set.
     51 ASM_PFX(return_from_exception):
     52     adr     lr, returned_exception
     53     movs    pc, lr
     54 returned_exception:                           @ We are now in non-secure state
     55     bx      r0
     56 
     57 # Save the current Program Status Register (PSR) into the Saved PSR
     58 ASM_PFX(copy_cpsr_into_spsr):
     59     mrs     r0, cpsr
     60     msr     spsr_cxsf, r0
     61     bx      lr
     62 
     63 # Set the Non Secure Mode
     64 ASM_PFX(set_non_secure_mode):
     65     push    { r1 }
     66     and     r0, r0, #0x1f     @ Keep only the mode bits
     67     mrs     r1, spsr          @ Read the spsr
     68     bic     r1, r1, #0x1f     @ Clear all mode bits
     69     orr     r1, r1, r0
     70     msr     spsr_cxsf, r1     @ write back spsr (may have caused a mode switch)
     71     isb
     72     pop     { r1 }
     73     bx      lr                @ return (hopefully thumb-safe!)
     74 
     75 ASM_FUNCTION_REMOVE_IF_UNREFERENCED
     76