sdf
Fork of mbed-rtos by
Diff: rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.s
- Revision:
- 80:2dab120a94c2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.s Mon Jun 01 11:00:36 2015 +0100
@@ -0,0 +1,329 @@
+/*----------------------------------------------------------------------------
+ * RL-ARM - RTX
+ *----------------------------------------------------------------------------
+ * Name: HAL_CM0.S
+ * Purpose: Hardware Abstraction Layer for ARM7TDMI
+ * Rev.: V1.0
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
+ * All rights reserved.
+ * 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 ARM 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 COPYRIGHT HOLDERS AND 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.
+ *---------------------------------------------------------------------------*/
+
+ .file "HAL_CM0.S"
+ .syntax unified
+
+ .equ TCB_TSTACK, 40
+
+
+/*----------------------------------------------------------------------------
+ * Functions
+ *---------------------------------------------------------------------------*/
+
+ .arm
+
+ .section ".text"
+ .align 2
+
+/*-------------------------- Save Context --------------------------------*/
+/* MUST be called the first */
+.macro SaveContext
+
+ /* Push R0 as we are going to use the register. */ \
+ STMDB SP!, {R0}
+
+ /* Set R0 to SP(user) */
+ STMDB SP,{SP}^
+ NOP
+ SUB SP, SP, #4
+ LDMIA SP!,{R0}
+
+ /* Push the LR return address onto the user stack. */
+ STMDB R0!, {LR}
+
+ /* Now we have saved LR we can use it instead of R0. */
+ MOV LR, R0
+
+ /* Pop R0 so we can save it onto the system mode stack. */
+ LDMIA SP!, {R0}
+
+ /* Push all the system mode registers onto the task stack. */
+ STMDB LR,{R0-R12,LR}^ /* LR can not be changed because user's LR is used*/
+ NOP /* pass 1 cycle before changing LR */
+ SUB LR, LR, #14*4 /* change LR now -15 dwords (R0-R14)*/
+
+ /* Push the SPSR onto the task stack. */
+ MRS R0, SPSR
+ STMDB LR!, {R0}
+
+ /* Store the new top of stack for the task. */
+ LDR R0,=os_tsk
+ LDR R0, [R0] /* R0 = (tcb) os_tsk.run */
+ STR LR, [R0, TCB_TSTACK] /* tcb.tsk_stack = SP(user) */
+.endm
+
+/*-------------------------- Restore Context --------------------------------*/
+ .type RestoreContext, %function
+ .global RestoreContext
+RestoreContext:
+ .fnstart
+ .cantunwind
+ /* Set the LR to the task stack. */
+ LDR R0,=os_tsk
+ LDR R1, [R0, 4] /* R1 = (tcb) os_tsk.new */
+ STR R1, [R0] /* os_tsk.run = os_tsk_newk */
+ LDR LR, [R1, TCB_TSTACK] /* LR = tcb.tsk_stack */
+
+ /* Get the SPSR from the stack. */
+ LDMFD LR!, {R0} /* SPSR */
+ MSR SPSR, R0
+
+ /* Restore all system mode registers for the task. */
+ LDMFD LR, {R0-R12,LR}^
+ NOP
+
+ ADD LR, LR, 15*4 /* increase starck pointer */
+ /* Set SP(user) to LR */
+ STMDB SP!,{LR}
+ LDMIA SP,{SP}^
+ NOP
+ ADD SP, SP, #4
+
+ /* Restore the return address. */
+ LDR LR, [LR,#-4] /* last dword is task's PC register */
+
+ /* And return - correcting the offset in the LR to obtain the */
+ /* correct address. */
+ SUBS PC, LR, #4
+
+/*-------------------------- End --------------------------------*/
+ .fnend
+ .size RestoreContext, .-RestoreContext
+
+
+
+/*--------------------------- rt_set_PSP ------------------------------------*/
+
+# void rt_set_PSP (U32 stack);
+
+ .type rt_set_PSP, %function
+ .global rt_set_PSP
+rt_set_PSP:
+ .fnstart
+ .cantunwind
+
+ MOV SP,R0
+ BX LR
+
+ .fnend
+ .size rt_set_PSP, .-rt_set_PSP
+
+
+/*--------------------------- rt_get_PSP ------------------------------------*/
+
+# U32 rt_get_PSP (void);
+
+ .type rt_get_PSP, %function
+ .global rt_get_PSP
+rt_get_PSP:
+ .fnstart
+ .cantunwind
+
+ MOV R0,SP
+ BX LR
+
+ .fnend
+ .size rt_get_PSP, .-rt_get_PSP
+
+
+
+/*--------------------------- _alloc_box ------------------------------------*/
+
+# void *_alloc_box (void *box_mem);
+ /* Function wrapper for Unprivileged/Privileged mode. */
+
+ .type _alloc_box, %function
+ .global _alloc_box
+_alloc_box:
+ .fnstart
+ .cantunwind
+
+ LDR R3,=rt_alloc_box
+ MOV R12, R3
+ MRS R3, CPSR
+ AND R3, 0x1F
+ CMP R3, 0x12 /* IRQ mode*/
+ BNE PrivilegedA
+ CMP R3, 0x1F /* System mode*/
+ BNE PrivilegedA
+ SVC 0
+ BX LR
+PrivilegedA:
+ BX R12
+
+ .fnend
+ .size _alloc_box, .-_alloc_box
+
+
+/*--------------------------- _free_box -------------------------------------*/
+
+# int _free_box (void *box_mem, void *box);
+ /* Function wrapper for Unprivileged/Privileged mode. */
+
+ .type _free_box, %function
+ .global _free_box
+_free_box:
+ .fnstart
+ .cantunwind
+
+ LDR R3,=rt_free_box
+ MOV R12, R3
+ MRS R3, CPSR
+ AND R3, 0x1F
+ CMP R3, 0x12 /* IRQ mode*/
+ BNE PrivilegedA
+ CMP R3, 0x1F /* System mode*/
+ BNE PrivilegedA
+ SVC 0
+ BX LR
+PrivilegedF:
+ BX R12
+
+ .fnend
+ .size _free_box, .-_free_box
+
+
+/*-------------------------- SVC_Handler ------------------------------------*/
+
+# void SVC_Handler (void);
+
+ .type SVC_Handler, %function
+ .global SVC_Handler
+SVC_Handler:
+ .fnstart
+ .cantunwind
+ /* Within an IRQ ISR the link register has an offset from the true return
+ address, but an SWI ISR does not. Add the offset manually so the same
+ ISR return code can be used in both cases. */
+
+ STMFD SP!, {R0,LR} /* Store registers. */
+ ADD LR, LR, #4 /* Align LR with IRQ handler */
+ SaveContext
+ MOV R11, LR /* Save Task Stack Pointer */
+ LDMFD SP!, {R0,LR} /* Restore registers and return. */
+ STMFD SP!, {R11} /* Save Task Stack Pointer */
+
+ LDR R5, [LR,#-4] /* Calculate address of SWI instruction and load it into r5. */
+ BIC R5, R5,#0xff000000 /* Mask off top 8 bits of instruction to give SWI number. */
+
+ CMP R5, #0
+ BNE SVC_User /* User SVC Number > 0 */
+ MOV LR, PC /* set LR to return address */
+ BX R12 /* Call SVC Function */
+
+ LDMFD SP!, {R11} /* Load Task Stack Pointer */
+ STMIB R11!, {R0-R3} /* Store return values to Task stack */
+
+SVC_Exit:
+ B RestoreContext /* return to the task */
+
+ /*------------------- User SVC ------------------------------*/
+
+SVC_User:
+ LDR R6,=SVC_Count
+ LDR R6,[R6]
+ CMP R5,R6
+ LDMFDHI SP!, {R11}
+ BHI SVC_Done /* Overflow */
+
+ LDR R4,=SVC_Table - 4
+ LSLS R5,R5,#2
+ LDR R4,[R4,R5] /* Load SVC Function Address */
+ /* R0-R3,R12 are unchanged */
+ MOV LR, PC /* set LR to return address */
+ BX R4 /* Call SVC Function */
+
+ LDMFD SP!, {R11} /* Load Task Stack Pointer */
+ BEQ SVC_Exit /* no need in return values */
+
+ STMIB R11!, {R0-R3} /* Store return values to Task stack */
+SVC_Done:
+ B RestoreContext /* return to the task */
+
+ .fnend
+ .size SVC_Handler, .-SVC_Handler
+
+
+/*-------------------------- IRQ_Handler ---------------------------------*/
+
+# void IRQ_Handler (void);
+
+ .type IRQ_Handler, %function
+ .global IRQ_Handler
+IRQ_Handler:
+ .fnstart
+ .cantunwind
+
+ SaveContext
+
+ MOV R0, #0xFFFFFF00
+ LDR R0, [R0] /* Load address of raised IRQ handler*/
+
+ MOV LR, PC
+ BX R0
+
+ MOV R0, #0xFFFFFF00
+ STR R0, [R0] /* Clear interrupt */
+
+ B RestoreContext
+
+ .fnend
+ .size IRQ_Handler, .-IRQ_Handler
+
+/*-------------------------- SysTick_Handler --------------------------------*/
+
+# void SysTick_Handler (void);
+
+ .type SysTick_Handler, %function
+ .global SysTick_Handler
+SysTick_Handler:
+ .fnstart
+ .cantunwind
+
+ PUSH {LR}
+ BL rt_systick
+ POP {LR}
+ BX LR /* return to IRQ handler */
+
+/*-------------------------- End --------------------------------*/
+ .fnend
+ .size SysTick_Handler, .-SysTick_Handler
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
+.end
\ No newline at end of file
