@******************************************************************************
@
@ ARMv7_CPU.S - CPU related APIs
@
@******************************************************************************
@
@ Copyright (C) 2014 Texas InSTRuments Incorporated - http://www.ti.com/
@
@
@  RediSTRibution and use in source and binary forms, with or without
@  modification, are permitted provided that the following conditions
@  are met:
@
@    RediSTRibutions of source code must retain the above copyright
@    notice, this list of conditions and the following disclaimer.
@
@    RediSTRibutions in binary form must reproduce the above copyright
@    notice, this list of conditions and the following disclaimer in the
@    documentation and/or other materials provided with the
@    diSTRibution.
@
@    Neither the name of Texas InSTRuments Incorporated nor the names of
@    its contributors may be used to endorse or promote products derived
@    from this software without specific prior written permission.
@
@  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
@  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
@  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
@  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
@  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
@  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
@  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
@  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@
@******************************************************************************
@ Created by Brighton Feng for Cortex A15 on July 10, 2014
@****************************** Global Symbols*********************************
        .global CPU_IRQ_enable
        .global CPU_IRQ_disable
        .global CPU_FIQ_enable
        .global CPU_FIQ_disable
        .global CPU_goto_user_mode
        .global CPU_goto_supervisor_mode
        .global CPU_securely_execute

@************************ Internal Definitions ******************************
 @ to set the mode bits in CPSR for different modes
        .set  MODE_USR, 0x10            
        .set  MODE_FIQ, 0x11
        .set  MODE_IRQ, 0x12
        .set  MODE_SVC, 0x13
        .set  MODE_MON, 0x16
        .set  MODE_ABT, 0x17
        .set  MODE_HYP, 0x1A
        .set  MODE_UND, 0x1B
        .set  MODE_SYS, 0x1F            

        .equ  I_BIT_MASK, 0x80               
        .equ  F_BIT_MASK, 0x40               

@**************************** Code section ************************************
        .text

        @ This code is assembled for ARM instructions
        .code 32

@-----------------------------------------------------------------------------
@ IRQ/FIQ operations
@-----------------------------------------------------------------------------

@*****************************************************************************
@ This API enable the IRQ
@*****************************************************************************
CPU_IRQ_enable:
	DSB
	MRS 	r0, CPSR        	@read CPSR
	BIC 	r0, #I_BIT_MASK 	@clear I bit
	MSR 	CPSR, r0 			@write back CPSR

    BX      lr

@*****************************************************************************
@ This API disable the IRQ
@*****************************************************************************
CPU_IRQ_disable:
	DSB
	MRS 	r0, CPSR        	@read CPSR
	ORR 	r0, #I_BIT_MASK 	@set I bit
	MSR 	CPSR, r0 			@write back CPSR

    BX      lr

@*****************************************************************************
@ This API enable the FIQ
@*****************************************************************************
CPU_FIQ_enable:
	DSB
	MRS 	r0, CPSR        	@read CPSR
	BIC 	r0, #F_BIT_MASK 	@clear F bit
	MSR 	CPSR, r0 			@write back CPSR

    BX      lr

@*****************************************************************************
@ This API enable the FIQ
@*****************************************************************************
CPU_FIQ_disable:
	DSB
	MRS 	r0, CPSR        	@read CPSR
	ORR 	r0, #I_BIT_MASK 	@set F bit
	MSR 	CPSR, r0 			@write back CPSR

    BX      lr

@*****************************************************************************
@ This API enable switch the CPU mode to user mode
@*****************************************************************************
CPU_goto_user_mode:
	MOV r1, lr                  @save LR
	MRS r0, CPSR 				@Take a copy of Program Status Register
	BIC r0, r0, #0x1f   		@Clear the mode bits
	ORR r0, r0, #MODE_USR 		@Set User mode
	MSR CPSR, r0				@Write back the modified value
	DSB
	MOV lr, r1                  @restore LR

    BX      lr

@*****************************************************************************
@ This API enable switch the CPU mode to user mode
@*****************************************************************************
CPU_goto_supervisor_mode:
	MOV r1, lr                  @save LR
	MRS r0, CPSR 				@Take a copy of Program Status Register
	BIC r0, r0, #0x1f   		@Clear the mode bits
	ORR r0, r0, #MODE_SVC 		@Set User mode
	MSR CPSR, r0				@Write back the modified value
	DSB
	MOV lr, r1                  @restore LR

    BX      lr

@*****************************************************************************
@execute the function can only be executed in secure mode (monitor mode).
@used only when RBL monitor vector and svc vectors are in place
@ In K2 ARM Boot ROM, ISR of SMC will execute the function 
@ pointer stored in R0. User can store functional pointer in R0 and call the 
@ SMC (or SMI) to switch to the Monitor mode and execution the function
@*****************************************************************************
CPU_securely_execute:
	PUSH  {r1-r3, lr}
	SMC   #0
	POP   {r1-r3, lr}
	BX    lr

@
@ End of the file
@
    .end

