/*************************************************************************
*
*             Copyright Mentor Graphics Corporation 2013
*                         All Rights Reserved.
*
* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS
* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS
* SUBJECT TO LICENSE TERMS.
*
*************************************************************************

*************************************************************************
*
* FILE NAME                                      
*
*      arch_proc_mode.h                      
*
* DESCRIPTION
*
*      This file contains MMU constants and macros for Supervisor-User 
*      Mode Switching.
*
* DATA STRUCTURES
*
*      None
*
* DEPENDENCIES
*
*      None
*
*************************************************************************/
#ifndef _ARCH_PROC_MODE_H
#define _ARCH_PROC_MODE_H

#define PROC_AR_MODE_MASK       0x0000001FUL    /* Processor Mode Mask */
#define PROC_AR_SYS_MODE        0x0000001FUL    /* System Mode (SYS) */
#define PROC_AR_USER_MODE       0x00000010UL    /* CPSR User Mode (USR) */

/* Function prototypes */
VOID PROC_AR_User_Mode(VOID);
VOID PROC_AR_Software_Interrupt(INT exception_num, VOID *stack_frame);
VOID PROC_AR_Trampoline_Return(VOID) __attribute__((section("nutramp"),naked));

/* Macro to switch to supervisor mode without trampoline */
#define PROC_SUPERVISOR_MODE()  __asm volatile ("swi 0\n\t")

/* Architecture specific trampoline code */
#define PROC_AR_TRAMPOLINE(symbol_name)                                                         \
        asm volatile(/* Save return address in r12 so that it can be saved in SWI handler */    \
                     " MOV  r12,lr\n"                                                           \
                                                                                                \
                     /* Perform service call to switch to supervisor mode */                    \
                     " SWI  0\n"                                                                \
                                                                                                \
                     /* Get address to return to after service call */                          \
                     " LDR  lr,=PROC_AR_Trampoline_Return\n"                                    \
                                                                                                \
                     /* Get address of actual kernel service and call service */                \
                     " LDR  r12,=" #symbol_name "\n"                                            \
                     " BX   r12\n")

#endif /* _ARCH_PROC_MODE_H */
