Rtos code cntains bug possible incompatability with I2C
Fork of mbed-rtos by
rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.S
- Committer:
- mbed_official
- Date:
- 2016-05-23
- Revision:
- 118:4c105b8d7cae
- Parent:
- 110:7a567bf048bf
File content as of revision 118:4c105b8d7cae:
/*---------------------------------------------------------------------------- * 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 stack 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