add lib/CMSIS_5 v5.7 locally

This commit is contained in:
hathach
2021-03-02 11:02:16 +07:00
parent 7afaae7ffc
commit 42ff88bdaf
103 changed files with 81252 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
NAME irq_armv8mbl.s
#define DOMAIN_NS 0
#include "irq_armv8mbl_common.s"
END

View File

@@ -0,0 +1,301 @@
;/*
; * Copyright (c) 2016-2020 Arm Limited. All rights reserved.
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the License); you may
; * not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; * -----------------------------------------------------------------------------
; *
; * Project: CMSIS-RTOS RTX
; * Title: ARMv8M Baseline Exception handlers
; *
; * -----------------------------------------------------------------------------
; */
#ifndef DOMAIN_NS
#define DOMAIN_NS 0
#endif
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
TCB_SM_OFS EQU 48 ; TCB.stack_mem offset
TCB_SP_OFS EQU 56 ; TCB.SP offset
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset
PRESERVE8
SECTION .rodata:DATA:NOROOT(2)
EXPORT irqRtxLib
irqRtxLib DCB 0 ; Non weak library reference
SECTION .text:CODE:NOROOT(2)
THUMB
SVC_Handler
EXPORT SVC_Handler
IMPORT osRtxUserSVC
IMPORT osRtxInfo
#if (DOMAIN_NS == 1)
IMPORT TZ_LoadContext_S
IMPORT TZ_StoreContext_S
#endif
MOV R0,LR
LSRS R0,R0,#3 ; Determine return stack from EXC_RETURN bit 2
BCC SVC_MSP ; Branch if return stack is MSP
MRS R0,PSP ; Get PSP
SVC_Number
LDR R1,[R0,#24] ; Load saved PC from stack
SUBS R1,R1,#2 ; Point to SVC instruction
LDRB R1,[R1] ; Load SVC number
CMP R1,#0
BNE SVC_User ; Branch if not SVC 0
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDM R0,{R0-R3} ; Load function parameters from stack
BLX R7 ; Call service function
POP {R2,R3} ; Restore SP and EXC_RETURN
STMIA R2!,{R0-R1} ; Store function return values
MOV LR,R3 ; Set EXC_RETURN
SVC_Context
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
CMP R1,R2 ; Check if thread switch is required
BEQ SVC_Exit ; Branch when threads are the same
CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted
SVC_ContextSave
#if (DOMAIN_NS == 1)
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context
PUSH {R1,R2,R3,R7} ; Save registers
MOV R7,LR ; Get EXC_RETURN
BL TZ_StoreContext_S ; Store secure context
MOV LR,R7 ; Set EXC_RETURN
POP {R1,R2,R3,R7} ; Restore registers
#endif
SVC_ContextSave1
MRS R0,PSP ; Get PSP
SUBS R0,R0,#32 ; Calculate SP
STR R0,[R1,#TCB_SP_OFS] ; Store SP
STMIA R0!,{R4-R7} ; Save R4..R7
MOV R4,R8
MOV R5,R9
MOV R6,R10
MOV R7,R11
STMIA R0!,{R4-R7} ; Save R8..R11
SVC_ContextSave2
MOV R0,LR ; Get EXC_RETURN
ADDS R1,R1,#TCB_SF_OFS ; Adjust address
STRB R0,[R1] ; Store stack frame information
SVC_ContextSwitch
SUBS R3,R3,#8 ; Adjust address
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
SVC_ContextRestore
#if (DOMAIN_NS == 1)
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context
PUSH {R2,R3} ; Save registers
BL TZ_LoadContext_S ; Load secure context
POP {R2,R3} ; Restore registers
#endif
SVC_ContextRestore1
MOV R1,R2
ADDS R1,R1,#TCB_SF_OFS ; Adjust address
LDRB R0,[R1] ; Load stack frame information
MOVS R1,#0xFF
MVNS R1,R1 ; R1=0xFFFFFF00
ORRS R0,R1
MOV LR,R0 ; Set EXC_RETURN
#if (DOMAIN_NS == 1)
LSLS R0,R0,#25 ; Check domain of interrupted thread
BPL SVC_ContextRestore2 ; Branch if non-secure
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
MSR PSP,R0 ; Set PSP
BX LR ; Exit from handler
#else
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
MSR PSPLIM,R0 ; Set PSPLIM
#endif
SVC_ContextRestore2
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
ADDS R0,R0,#16 ; Adjust address
LDMIA R0!,{R4-R7} ; Restore R8..R11
MOV R8,R4
MOV R9,R5
MOV R10,R6
MOV R11,R7
MSR PSP,R0 ; Set PSP
SUBS R0,R0,#32 ; Adjust address
LDMIA R0!,{R4-R7} ; Restore R4..R7
SVC_Exit
BX LR ; Exit from handler
SVC_MSP
MRS R0,MSP ; Get MSP
B SVC_Number
SVC_User
LDR R2,=osRtxUserSVC ; Load address of SVC table
LDR R3,[R2] ; Load SVC maximum number
CMP R1,R3 ; Check SVC number range
BHI SVC_Exit ; Branch if out of range
PUSH {R0,LR} ; Save SP and EXC_RETURN
LSLS R1,R1,#2
LDR R3,[R2,R1] ; Load address of SVC function
MOV R12,R3
LDMIA R0,{R0-R3} ; Load function parameters from stack
BLX R12 ; Call service function
POP {R2,R3} ; Restore SP and EXC_RETURN
STR R0,[R2] ; Store function return value
MOV LR,R3 ; Set EXC_RETURN
BX LR ; Return from handler
PendSV_Handler
EXPORT PendSV_Handler
IMPORT osRtxPendSV_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler
POP {R0,R1} ; Restore EXC_RETURN
MOV LR,R1 ; Set EXC_RETURN
B Sys_Context
SysTick_Handler
EXPORT SysTick_Handler
IMPORT osRtxTick_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxTick_Handler ; Call osRtxTick_Handler
POP {R0,R1} ; Restore EXC_RETURN
MOV LR,R1 ; Set EXC_RETURN
B Sys_Context
Sys_Context
EXPORT Sys_Context
IMPORT osRtxInfo
#if (DOMAIN_NS == 1)
IMPORT TZ_LoadContext_S
IMPORT TZ_StoreContext_S
#endif
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
LDM R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
CMP R1,R2 ; Check if thread switch is required
BEQ Sys_ContextExit ; Branch when threads are the same
Sys_ContextSave
#if (DOMAIN_NS == 1)
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context
PUSH {R1,R2,R3,R7} ; Save registers
MOV R7,LR ; Get EXC_RETURN
BL TZ_StoreContext_S ; Store secure context
MOV LR,R7 ; Set EXC_RETURN
POP {R1,R2,R3,R7} ; Restore registers
Sys_ContextSave1
MOV R0,LR ; Get EXC_RETURN
LSLS R0,R0,#25 ; Check domain of interrupted thread
BPL Sys_ContextSave2 ; Branch if non-secure
MRS R0,PSP ; Get PSP
STR R0,[R1,#TCB_SP_OFS] ; Store SP
B Sys_ContextSave3
#endif
Sys_ContextSave2
MRS R0,PSP ; Get PSP
SUBS R0,R0,#32 ; Adjust address
STR R0,[R1,#TCB_SP_OFS] ; Store SP
STMIA R0!,{R4-R7} ; Save R4..R7
MOV R4,R8
MOV R5,R9
MOV R6,R10
MOV R7,R11
STMIA R0!,{R4-R7} ; Save R8..R11
Sys_ContextSave3
MOV R0,LR ; Get EXC_RETURN
ADDS R1,R1,#TCB_SF_OFS ; Adjust address
STRB R0,[R1] ; Store stack frame information
Sys_ContextSwitch
SUBS R3,R3,#8 ; Adjust address
STR R2,[R3] ; osRtxInfo.run: curr = next
Sys_ContextRestore
#if (DOMAIN_NS == 1)
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context
PUSH {R2,R3} ; Save registers
BL TZ_LoadContext_S ; Load secure context
POP {R2,R3} ; Restore registers
#endif
Sys_ContextRestore1
MOV R1,R2
ADDS R1,R1,#TCB_SF_OFS ; Adjust offset
LDRB R0,[R1] ; Load stack frame information
MOVS R1,#0xFF
MVNS R1,R1 ; R1=0xFFFFFF00
ORRS R0,R1
MOV LR,R0 ; Set EXC_RETURN
#if (DOMAIN_NS == 1)
LSLS R0,R0,#25 ; Check domain of interrupted thread
BPL Sys_ContextRestore2 ; Branch if non-secure
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
MSR PSP,R0 ; Set PSP
BX LR ; Exit from handler
#else
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
MSR PSPLIM,R0 ; Set PSPLIM
#endif
Sys_ContextRestore2
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
ADDS R0,R0,#16 ; Adjust address
LDMIA R0!,{R4-R7} ; Restore R8..R11
MOV R8,R4
MOV R9,R5
MOV R10,R6
MOV R11,R7
MSR PSP,R0 ; Set PSP
SUBS R0,R0,#32 ; Adjust address
LDMIA R0!,{R4-R7} ; Restore R4..R7
Sys_ContextExit
BX LR ; Exit from handler

View File

@@ -0,0 +1,4 @@
NAME irq_armv8mbl_ns.s
#define DOMAIN_NS 1
#include "irq_armv8mbl_common.s"
END

View File

@@ -0,0 +1,4 @@
NAME irq_armv8mml.s
#define DOMAIN_NS 0
#include "irq_armv8mml_common.s"
END

View File

@@ -0,0 +1,280 @@
;/*
; * Copyright (c) 2016-2020 Arm Limited. All rights reserved.
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the License); you may
; * not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; * -----------------------------------------------------------------------------
; *
; * Project: CMSIS-RTOS RTX
; * Title: ARMv8M Mainline Exception handlers
; *
; * -----------------------------------------------------------------------------
; */
#ifndef DOMAIN_NS
#define DOMAIN_NS 0
#endif
#ifdef __ARMVFP__
FPU_USED EQU 1
#else
FPU_USED EQU 0
#endif
#if (defined(__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0))
MVE_USED EQU 1
#else
MVE_USED EQU 0
#endif
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
TCB_SM_OFS EQU 48 ; TCB.stack_mem offset
TCB_SP_OFS EQU 56 ; TCB.SP offset
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset
PRESERVE8
SECTION .rodata:DATA:NOROOT(2)
EXPORT irqRtxLib
irqRtxLib DCB 0 ; Non weak library reference
SECTION .text:CODE:NOROOT(2)
THUMB
SVC_Handler
EXPORT SVC_Handler
IMPORT osRtxUserSVC
IMPORT osRtxInfo
#if (DOMAIN_NS == 1)
IMPORT TZ_LoadContext_S
IMPORT TZ_StoreContext_S
#endif
TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2
ITE EQ
MRSEQ R0,MSP ; Get MSP if return stack is MSP
MRSNE R0,PSP ; Get PSP if return stack is PSP
LDR R1,[R0,#24] ; Load saved PC from stack
LDRB R1,[R1,#-2] ; Load SVC number
CMP R1,#0
BNE SVC_User ; Branch if not SVC 0
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDM R0,{R0-R3,R12} ; Load function parameters and address from stack
BLX R12 ; Call service function
POP {R12,LR} ; Restore SP and EXC_RETURN
STM R12,{R0-R1} ; Store function return values
SVC_Context
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
CMP R1,R2 ; Check if thread switch is required
IT EQ
BXEQ LR ; Exit when threads are the same
#if ((FPU_USED == 1) || (MVE_USED == 1))
CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted
TST LR,#0x10 ; Check if extended stack frame
BNE SVC_ContextSwitch
LDR R1,=0xE000EF34 ; FPCCR Address
LDR R0,[R1] ; Load FPCCR
BIC R0,R0,#1 ; Clear LSPACT (Lazy state)
STR R0,[R1] ; Store FPCCR
B SVC_ContextSwitch
#else
CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted
#endif
SVC_ContextSave
#if (DOMAIN_NS == 1)
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context
PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN
BL TZ_StoreContext_S ; Store secure context
POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN
#endif
SVC_ContextSave1
MRS R0,PSP ; Get PSP
STMDB R0!,{R4-R11} ; Save R4..R11
#if ((FPU_USED == 1) || (MVE_USED == 1))
TST LR,#0x10 ; Check if extended stack frame
IT EQ
VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31
#endif
SVC_ContextSave2
STR R0,[R1,#TCB_SP_OFS] ; Store SP
STRB LR,[R1,#TCB_SF_OFS] ; Store stack frame information
SVC_ContextSwitch
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
SVC_ContextRestore
#if (DOMAIN_NS == 1)
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context
PUSH {R2,R3} ; Save registers
BL TZ_LoadContext_S ; Load secure context
POP {R2,R3} ; Restore registers
#endif
SVC_ContextRestore1
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information
MSR PSPLIM,R0 ; Set PSPLIM
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN
#if (DOMAIN_NS == 1)
TST LR,#0x40 ; Check domain of interrupted thread
BNE SVC_ContextRestore2 ; Branch if secure
#endif
#if ((FPU_USED == 1) || (MVE_USED == 1))
TST LR,#0x10 ; Check if extended stack frame
IT EQ
VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31
#endif
LDMIA R0!,{R4-R11} ; Restore R4..R11
SVC_ContextRestore2
MSR PSP,R0 ; Set PSP
SVC_Exit
BX LR ; Exit from handler
SVC_User
LDR R2,=osRtxUserSVC ; Load address of SVC table
LDR R3,[R2] ; Load SVC maximum number
CMP R1,R3 ; Check SVC number range
BHI SVC_Exit ; Branch if out of range
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDR R12,[R2,R1,LSL #2] ; Load address of SVC function
LDM R0,{R0-R3} ; Load function parameters from stack
BLX R12 ; Call service function
POP {R12,LR} ; Restore SP and EXC_RETURN
STR R0,[R12] ; Store function return value
BX LR ; Return from handler
PendSV_Handler
EXPORT PendSV_Handler
IMPORT osRtxPendSV_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler
POP {R0,LR} ; Restore EXC_RETURN
B Sys_Context
SysTick_Handler
EXPORT SysTick_Handler
IMPORT osRtxTick_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxTick_Handler ; Call osRtxTick_Handler
POP {R0,LR} ; Restore EXC_RETURN
B Sys_Context
Sys_Context
EXPORT Sys_Context
IMPORT osRtxInfo
#if (DOMAIN_NS == 1)
IMPORT TZ_LoadContext_S
IMPORT TZ_StoreContext_S
#endif
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
CMP R1,R2 ; Check if thread switch is required
IT EQ
BXEQ LR ; Exit when threads are the same
Sys_ContextSave
#if (DOMAIN_NS == 1)
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context
PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN
BL TZ_StoreContext_S ; Store secure context
POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN
Sys_ContextSave1
TST LR,#0x40 ; Check domain of interrupted thread
IT NE
MRSNE R0,PSP ; Get PSP
BNE Sys_ContextSave3 ; Branch if secure
#endif
Sys_ContextSave2
MRS R0,PSP ; Get PSP
STMDB R0!,{R4-R11} ; Save R4..R11
#if ((FPU_USED == 1) || (MVE_USED == 1))
TST LR,#0x10 ; Check if extended stack frame
IT EQ
VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31
#endif
Sys_ContextSave3
STR R0,[R1,#TCB_SP_OFS] ; Store SP
STRB LR,[R1,#TCB_SF_OFS] ; Store stack frame information
Sys_ContextSwitch
STR R2,[R3] ; osRtxInfo.run: curr = next
Sys_ContextRestore
#if (DOMAIN_NS == 1)
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context
PUSH {R2,R3} ; Save registers
BL TZ_LoadContext_S ; Load secure context
POP {R2,R3} ; Restore registers
#endif
Sys_ContextRestore1
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information
MSR PSPLIM,R0 ; Set PSPLIM
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN
#if (DOMAIN_NS == 1)
TST LR,#0x40 ; Check domain of interrupted thread
BNE Sys_ContextRestore2 ; Branch if secure
#endif
#if ((FPU_USED == 1) || (MVE_USED == 1))
TST LR,#0x10 ; Check if extended stack frame
IT EQ
VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31
#endif
LDMIA R0!,{R4-R11} ; Restore R4..R11
Sys_ContextRestore2
MSR PSP,R0 ; Set PSP
Sys_ContextExit
BX LR ; Exit from handler

View File

@@ -0,0 +1,4 @@
NAME irq_armv8mml_ns.s
#define DOMAIN_NS 1
#include "irq_armv8mml_common.s"
END

View File

@@ -0,0 +1,441 @@
;/*
; * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the License); you may
; * not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; * -----------------------------------------------------------------------------
; *
; * Project: CMSIS-RTOS RTX
; * Title: Cortex-A Exception handlers
; *
; * -----------------------------------------------------------------------------
; */
NAME irq_ca.s
MODE_FIQ EQU 0x11
MODE_IRQ EQU 0x12
MODE_SVC EQU 0x13
MODE_ABT EQU 0x17
MODE_UND EQU 0x1B
CPSR_BIT_T EQU 0x20
K_STATE_RUNNING EQU 2 ; osKernelState_t::osKernelRunning
I_K_STATE_OFS EQU 8 ; osRtxInfo.kernel.state offset
I_TICK_IRQN_OFS EQU 16 ; osRtxInfo.tick_irqn offset
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
TCB_SP_FRAME EQU 34 ; osRtxThread_t.stack_frame offset
TCB_SP_OFS EQU 56 ; osRtxThread_t.sp offset
PRESERVE8
SECTION .rodata:DATA:NOROOT(2)
EXPORT irqRtxLib
irqRtxLib DCB 0 ; Non weak library reference
SECTION .data:DATA:NOROOT(2)
EXPORT IRQ_PendSV
IRQ_NestLevel DCD 0 ; IRQ nesting level counter
IRQ_PendSV DCB 0 ; Pending SVC flag
SECTION .text:CODE:NOROOT(2)
Undef_Handler
EXPORT Undef_Handler
IMPORT CUndefHandler
SRSFD SP!, #MODE_UND
PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack
MRS R0, SPSR
TST R0, #CPSR_BIT_T ; Check mode
MOVEQ R1, #4 ; R1 = 4 ARM mode
MOVNE R1, #2 ; R1 = 2 Thumb mode
SUB R0, LR, R1
LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction
BEQ Undef_Cont
; Thumb instruction
; Determine if it is a 32-bit Thumb instruction
LDRH R0, [R0]
MOV R2, #0x1C
CMP R2, R0, LSR #11
BHS Undef_Cont ; 16-bit Thumb instruction
; 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction
LDRH R2, [LR]
ORR R0, R2, R0, LSL #16
Undef_Cont
MOV R2, LR ; Set LR to third argument
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
SUB SP, SP, R12 ; Adjust stack
PUSH {R12, LR} ; Store stack adjustment and dummy LR
; R0 =Offending instruction, R1 =2(Thumb) or =4(ARM)
BL CUndefHandler
POP {R12, LR} ; Get stack adjustment & discard dummy LR
ADD SP, SP, R12 ; Unadjust stack
LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry
SUB LR, LR, R0
LDR R0, [SP, #28] ; Restore stacked SPSR
MSR SPSR_CXSF, R0
CLREX ; Clear exclusive monitor
POP {R0-R4, R12} ; Restore stacked APCS registers
ADD SP, SP, #8 ; Adjust SP for already-restored banked registers
MOVS PC, LR
PAbt_Handler
EXPORT PAbt_Handler
IMPORT CPAbtHandler
SUB LR, LR, #4 ; Pre-adjust LR
SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack
PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
MRC p15, 0, R0, c5, c0, 1 ; IFSR
MRC p15, 0, R1, c6, c0, 2 ; IFAR
MOV R2, LR ; Set LR to third argument
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
SUB SP, SP, R12 ; Adjust stack
PUSH {R12, LR} ; Store stack adjustment and dummy LR
BL CPAbtHandler
POP {R12, LR} ; Get stack adjustment & discard dummy LR
ADD SP, SP, R12 ; Unadjust stack
CLREX ; Clear exclusive monitor
POP {R0-R4, R12} ; Restore stack APCS registers
RFEFD SP! ; Return from exception
DAbt_Handler
EXPORT DAbt_Handler
IMPORT CDAbtHandler
SUB LR, LR, #8 ; Pre-adjust LR
SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack
PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
MRC p15, 0, R0, c5, c0, 0 ; DFSR
MRC p15, 0, R1, c6, c0, 0 ; DFAR
MOV R2, LR ; Set LR to third argument
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
SUB SP, SP, R12 ; Adjust stack
PUSH {R12, LR} ; Store stack adjustment and dummy LR
BL CDAbtHandler
POP {R12, LR} ; Get stack adjustment & discard dummy LR
ADD SP, SP, R12 ; Unadjust stack
CLREX ; Clear exclusive monitor
POP {R0-R4, R12} ; Restore stacked APCS registers
RFEFD SP! ; Return from exception
IRQ_Handler
EXPORT IRQ_Handler
IMPORT IRQ_GetActiveIRQ
IMPORT IRQ_GetHandler
IMPORT IRQ_EndOfInterrupt
SUB LR, LR, #4 ; Pre-adjust LR
SRSFD SP!, #MODE_SVC ; Save LR_irq and SPSR_irq on to the SVC stack
CPS #MODE_SVC ; Change to SVC mode
PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers
LDR R0, =IRQ_NestLevel
LDR R1, [R0]
ADD R1, R1, #1 ; Increment IRQ nesting level
STR R1, [R0]
MOV R3, SP ; Move SP into R3
AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment
SUB SP, SP, R3 ; Adjust stack
PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4)
BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0
MOV R4, R0 ; Move interrupt ID to R4
BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID
CMP R0, #0 ; Check if handler address is 0
BEQ IRQ_End ; If 0, end interrupt and return
CPSIE i ; Re-enable interrupts
BLX R0 ; Call IRQ handler
CPSID i ; Disable interrupts
IRQ_End
MOV R0, R4 ; Move interrupt ID to R0
BLX IRQ_EndOfInterrupt ; Signal end of interrupt
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
ADD SP, SP, R3 ; Unadjust stack
BL osRtxContextSwitch ; Continue in context switcher
LDR R0, =IRQ_NestLevel
LDR R1, [R0]
SUBS R1, R1, #1 ; Decrement IRQ nesting level
STR R1, [R0]
CLREX ; Clear exclusive monitor for interrupted code
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
RFEFD SP! ; Return from IRQ handler
SVC_Handler
EXPORT SVC_Handler
IMPORT IRQ_Disable
IMPORT IRQ_Enable
IMPORT osRtxUserSVC
IMPORT osRtxInfo
SRSFD SP!, #MODE_SVC ; Store SPSR_svc and LR_svc onto SVC stack
PUSH {R12, LR}
MRS R12, SPSR ; Load SPSR
TST R12, #CPSR_BIT_T ; Thumb bit set?
LDRHNE R12, [LR,#-2] ; Thumb: load halfword
BICNE R12, R12, #0xFF00 ; extract SVC number
LDREQ R12, [LR,#-4] ; ARM: load word
BICEQ R12, R12, #0xFF000000 ; extract SVC number
CMP R12, #0 ; Compare SVC number
BNE SVC_User ; Branch if User SVC
PUSH {R0-R3}
LDR R0, =IRQ_NestLevel
LDR R1, [R0]
ADD R1, R1, #1 ; Increment IRQ nesting level
STR R1, [R0]
LDR R0, =osRtxInfo
LDR R1, [R0, #I_K_STATE_OFS] ; Load RTX5 kernel state
CMP R1, #K_STATE_RUNNING ; Check osKernelRunning
BLT SVC_FuncCall ; Continue if kernel is not running
LDR R0, [R0, #I_TICK_IRQN_OFS] ; Load OS Tick irqn
BLX IRQ_Disable ; Disable OS Tick interrupt
SVC_FuncCall
POP {R0-R3}
LDR R12, [SP] ; Reload R12 from stack
CPSIE i ; Re-enable interrupts
BLX R12 ; Branch to SVC function
CPSID i ; Disable interrupts
SUB SP, SP, #4
STM SP, {SP}^ ; Store SP_usr onto stack
POP {R12} ; Pop SP_usr into R12
SUB R12, R12, #16 ; Adjust pointer to SP_usr
LDMDB R12, {R2,R3} ; Load return values from SVC function
PUSH {R0-R3} ; Push return values to stack
LDR R0, =osRtxInfo
LDR R1, [R0, #I_K_STATE_OFS] ; Load RTX5 kernel state
CMP R1, #K_STATE_RUNNING ; Check osKernelRunning
BLT SVC_ContextCheck ; Continue if kernel is not running
LDR R0, [R0, #I_TICK_IRQN_OFS] ; Load OS Tick irqn
BLX IRQ_Enable ; Enable OS Tick interrupt
SVC_ContextCheck
BL osRtxContextSwitch ; Continue in context switcher
LDR R0, =IRQ_NestLevel
LDR R1, [R0]
SUB R1, R1, #1 ; Decrement IRQ nesting level
STR R1, [R0]
CLREX ; Clear exclusive monitor
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
RFEFD SP! ; Return from exception
SVC_User
PUSH {R4, R5}
LDR R5,=osRtxUserSVC ; Load address of SVC table
LDR R4,[R5] ; Load SVC maximum number
CMP R12,R4 ; Check SVC number range
BHI SVC_Done ; Branch if out of range
LDR R12,[R5,R12,LSL #2] ; Load SVC Function Address
BLX R12 ; Call SVC Function
SVC_Done
CLREX ; Clear exclusive monitor
POP {R4, R5, R12, LR}
RFEFD SP! ; Return from exception
osRtxContextSwitch
EXPORT osRtxContextSwitch
IMPORT osRtxPendSV_Handler
IMPORT osRtxInfo
IMPORT IRQ_Disable
IMPORT IRQ_Enable
PUSH {LR}
; Check interrupt nesting level
LDR R0, =IRQ_NestLevel
LDR R1, [R0] ; Load IRQ nest level
CMP R1, #1
BNE osRtxContextExit ; Nesting interrupts, exit context switcher
LDR R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next
LDR R2, =IRQ_PendSV ; Load address of IRQ_PendSV flag
LDRB R3, [R2] ; Load PendSV flag
CMP R0, R1 ; Check if context switch is required
BNE osRtxContextCheck ; Not equal, check if context save required
CMP R3, #1 ; Compare IRQ_PendSV value
BNE osRtxContextExit ; No post processing (and no context switch requested)
osRtxContextCheck
STR R1, [R12] ; Store run.next as run.curr
; R0 = curr, R1 = next, R2 = &IRQ_PendSV, R3 = IRQ_PendSV, R12 = &osRtxInfo.thread.run
PUSH {R1-R3, R12}
CMP R0, #0 ; Is osRtxInfo.thread.run.curr == 0
BEQ osRtxPostProcess ; Current deleted, skip context save
osRtxContextSave
MOV LR, R0 ; Move &osRtxInfo.thread.run.curr to LR
MOV R0, SP ; Move SP_svc into R0
ADD R0, R0, #20 ; Adjust SP_svc to R0 of the basic frame
SUB SP, SP, #4
STM SP, {SP}^ ; Save SP_usr to current stack
POP {R1} ; Pop SP_usr into R1
SUB R1, R1, #64 ; Adjust SP_usr to R4 of the basic frame
STMIA R1!, {R4-R11} ; Save R4-R11 to user stack
LDMIA R0!, {R4-R8} ; Load stacked R0-R3,R12 into R4-R8
STMIA R1!, {R4-R8} ; Store them to user stack
STM R1, {LR}^ ; Store LR_usr directly
ADD R1, R1, #4 ; Adjust user sp to PC
LDMIB R0!, {R5-R6} ; Load current PC, CPSR
STMIA R1!, {R5-R6} ; Restore user PC and CPSR
SUB R1, R1, #64 ; Adjust SP_usr to stacked R4
; Check if VFP state need to be saved
MRC p15, 0, R2, c1, c0, 2 ; VFP/NEON access enabled? (CPACR)
AND R2, R2, #0x00F00000
CMP R2, #0x00F00000
BNE osRtxContextSave1 ; Continue, no VFP
VMRS R2, FPSCR
STMDB R1!, {R2,R12} ; Push FPSCR, maintain 8-byte alignment
VSTMDB R1!, {D0-D15} ; Save D0-D15
#ifdef __ARM_ADVANCED_SIMD__
VSTMDB R1!, {D16-D31} ; Save D16-D31
#endif
LDRB R2, [LR, #TCB_SP_FRAME] ; Load osRtxInfo.thread.run.curr frame info
#ifdef __ARM_ADVANCED_SIMD__
ORR R2, R2, #4 ; NEON state
#else
ORR R2, R2, #2 ; VFP state
#endif
STRB R2, [LR, #TCB_SP_FRAME] ; Store VFP/NEON state
osRtxContextSave1
STR R1, [LR, #TCB_SP_OFS] ; Store user sp to osRtxInfo.thread.run.curr
osRtxPostProcess
; RTX IRQ post processing check
POP {R8-R11} ; Pop R8 = run.next, R9 = &IRQ_PendSV, R10 = IRQ_PendSV, R11 = &osRtxInfo.thread.run
CMP R10, #1 ; Compare PendSV value
BNE osRtxContextRestore ; Skip post processing if not pending
MOV R4, SP ; Move SP_svc into R4
AND R4, R4, #4 ; Get stack adjustment to ensure 8-byte alignment
SUB SP, SP, R4 ; Adjust stack
; Disable OS Tick
LDR R5, =osRtxInfo ; Load address of osRtxInfo
LDR R5, [R5, #I_TICK_IRQN_OFS] ; Load OS Tick irqn
MOV R0, R5 ; Set it as function parameter
BLX IRQ_Disable ; Disable OS Tick interrupt
MOV R6, #0 ; Set PendSV clear value
B osRtxPendCheck
osRtxPendExec
STRB R6, [R9] ; Clear PendSV flag
CPSIE i ; Re-enable interrupts
BLX osRtxPendSV_Handler ; Post process pending objects
CPSID i ; Disable interrupts
osRtxPendCheck
LDR R8, [R11, #4] ; Load osRtxInfo.thread.run.next
STR R8, [R11] ; Store run.next as run.curr
LDRB R0, [R9] ; Load PendSV flag
CMP R0, #1 ; Compare PendSV value
BEQ osRtxPendExec ; Branch to PendExec if PendSV is set
; Re-enable OS Tick
MOV R0, R5 ; Restore irqn as function parameter
BLX IRQ_Enable ; Enable OS Tick interrupt
ADD SP, SP, R4 ; Restore stack adjustment
osRtxContextRestore
LDR LR, [R8, #TCB_SP_OFS] ; Load next osRtxThread_t.sp
LDRB R2, [R8, #TCB_SP_FRAME] ; Load next osRtxThread_t.stack_frame
ANDS R2, R2, #0x6 ; Check stack frame for VFP context
MRC p15, 0, R2, c1, c0, 2 ; Read CPACR
ANDEQ R2, R2, #0xFF0FFFFF ; VFP/NEON state not stacked, disable VFP/NEON
ORRNE R2, R2, #0x00F00000 ; VFP/NEON state is stacked, enable VFP/NEON
MCR p15, 0, R2, c1, c0, 2 ; Write CPACR
BEQ osRtxContextRestore1 ; No VFP
ISB ; Sync if VFP was enabled
#ifdef __ARM_ADVANCED_SIMD__
VLDMIA LR!, {D16-D31} ; Restore D16-D31
#endif
VLDMIA LR!, {D0-D15} ; Restore D0-D15
LDR R2, [LR]
VMSR FPSCR, R2 ; Restore FPSCR
ADD LR, LR, #8 ; Adjust sp pointer to R4
osRtxContextRestore1
LDMIA LR!, {R4-R11} ; Restore R4-R11
ADD R12, LR, #32 ; Adjust sp and save it into R12
PUSH {R12} ; Push sp onto stack
LDM SP, {SP}^ ; Restore SP_usr directly
ADD SP, SP, #4 ; Adjust SP_svc
LDMIA LR!, {R0-R3, R12} ; Load user registers R0-R3,R12
STMIB SP!, {R0-R3, R12} ; Store them to SP_svc
LDM LR, {LR}^ ; Restore LR_usr directly
LDMIB LR!, {R0-R1} ; Load user registers PC,CPSR
ADD SP, SP, #4
STMIB SP!, {R0-R1} ; Store them to SP_svc
SUB SP, SP, #32 ; Adjust SP_svc to stacked LR
osRtxContextExit
POP {PC} ; Return
END

View File

@@ -0,0 +1,158 @@
;/*
; * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the License); you may
; * not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; * -----------------------------------------------------------------------------
; *
; * Project: CMSIS-RTOS RTX
; * Title: Cortex-M0 Exception handlers
; *
; * -----------------------------------------------------------------------------
; */
NAME irq_cm0.s
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
TCB_SP_OFS EQU 56 ; TCB.SP offset
PRESERVE8
SECTION .rodata:DATA:NOROOT(2)
EXPORT irqRtxLib
irqRtxLib DCB 0 ; Non weak library reference
THUMB
SECTION .text:CODE:NOROOT(2)
SVC_Handler
EXPORT SVC_Handler
IMPORT osRtxUserSVC
IMPORT osRtxInfo
MOV R0,LR
LSRS R0,R0,#3 ; Determine return stack from EXC_RETURN bit 2
BCC SVC_MSP ; Branch if return stack is MSP
MRS R0,PSP ; Get PSP
SVC_Number
LDR R1,[R0,#24] ; Load saved PC from stack
SUBS R1,R1,#2 ; Point to SVC instruction
LDRB R1,[R1] ; Load SVC number
CMP R1,#0
BNE SVC_User ; Branch if not SVC 0
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDMIA R0,{R0-R3} ; Load function parameters from stack
BLX R7 ; Call service function
POP {R2,R3} ; Restore SP and EXC_RETURN
STMIA R2!,{R0-R1} ; Store function return values
MOV LR,R3 ; Set EXC_RETURN
SVC_Context
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
CMP R1,R2 ; Check if thread switch is required
BEQ SVC_Exit ; Branch when threads are the same
CMP R1,#0
BEQ SVC_ContextSwitch ; Branch if running thread is deleted
SVC_ContextSave
MRS R0,PSP ; Get PSP
SUBS R0,R0,#32 ; Calculate SP
STR R0,[R1,#TCB_SP_OFS] ; Store SP
STMIA R0!,{R4-R7} ; Save R4..R7
MOV R4,R8
MOV R5,R9
MOV R6,R10
MOV R7,R11
STMIA R0!,{R4-R7} ; Save R8..R11
SVC_ContextSwitch
SUBS R3,R3,#8 ; Adjust address
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
SVC_ContextRestore
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
ADDS R0,R0,#16 ; Adjust address
LDMIA R0!,{R4-R7} ; Restore R8..R11
MOV R8,R4
MOV R9,R5
MOV R10,R6
MOV R11,R7
MSR PSP,R0 ; Set PSP
SUBS R0,R0,#32 ; Adjust address
LDMIA R0!,{R4-R7} ; Restore R4..R7
MOVS R0,#~0xFFFFFFFD
MVNS R0,R0 ; Set EXC_RETURN value
BX R0 ; Exit from handler
SVC_MSP
MRS R0,MSP ; Get MSP
B SVC_Number
SVC_Exit
BX LR ; Exit from handler
SVC_User
LDR R2,=osRtxUserSVC ; Load address of SVC table
LDR R3,[R2] ; Load SVC maximum number
CMP R1,R3 ; Check SVC number range
BHI SVC_Exit ; Branch if out of range
PUSH {R0,LR} ; Save SP and EXC_RETURN
LSLS R1,R1,#2
LDR R3,[R2,R1] ; Load address of SVC function
MOV R12,R3
LDMIA R0,{R0-R3} ; Load function parameters from stack
BLX R12 ; Call service function
POP {R2,R3} ; Restore SP and EXC_RETURN
STR R0,[R2] ; Store function return value
MOV LR,R3 ; Set EXC_RETURN
BX LR ; Return from handler
PendSV_Handler
EXPORT PendSV_Handler
IMPORT osRtxPendSV_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler
POP {R0,R1} ; Restore EXC_RETURN
MOV LR,R1 ; Set EXC_RETURN
B SVC_Context
SysTick_Handler
EXPORT SysTick_Handler
IMPORT osRtxTick_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxTick_Handler ; Call osRtxTick_Handler
POP {R0,R1} ; Restore EXC_RETURN
MOV LR,R1 ; Set EXC_RETURN
B SVC_Context
END

View File

@@ -0,0 +1,130 @@
;/*
; * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the License); you may
; * not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; * -----------------------------------------------------------------------------
; *
; * Project: CMSIS-RTOS RTX
; * Title: Cortex-M3 Exception handlers
; *
; * -----------------------------------------------------------------------------
; */
NAME irq_cm3.s
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
TCB_SP_OFS EQU 56 ; TCB.SP offset
PRESERVE8
SECTION .rodata:DATA:NOROOT(2)
EXPORT irqRtxLib
irqRtxLib DCB 0 ; Non weak library reference
THUMB
SECTION .text:CODE:NOROOT(2)
SVC_Handler
EXPORT SVC_Handler
IMPORT osRtxUserSVC
IMPORT osRtxInfo
TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2
ITE EQ
MRSEQ R0,MSP ; Get MSP if return stack is MSP
MRSNE R0,PSP ; Get PSP if return stack is PSP
LDR R1,[R0,#24] ; Load saved PC from stack
LDRB R1,[R1,#-2] ; Load SVC number
CBNZ R1,SVC_User ; Branch if not SVC 0
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDM R0,{R0-R3,R12} ; Load function parameters and address from stack
BLX R12 ; Call service function
POP {R12,LR} ; Restore SP and EXC_RETURN
STM R12,{R0-R1} ; Store function return values
SVC_Context
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
CMP R1,R2 ; Check if thread switch is required
IT EQ
BXEQ LR ; Exit when threads are the same
CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted
SVC_ContextSave
STMDB R12!,{R4-R11} ; Save R4..R11
STR R12,[R1,#TCB_SP_OFS] ; Store SP
SVC_ContextSwitch
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
SVC_ContextRestore
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
LDMIA R0!,{R4-R11} ; Restore R4..R11
MSR PSP,R0 ; Set PSP
MVN LR,#~0xFFFFFFFD ; Set EXC_RETURN value
SVC_Exit
BX LR ; Exit from handler
SVC_User
LDR R2,=osRtxUserSVC ; Load address of SVC table
LDR R3,[R2] ; Load SVC maximum number
CMP R1,R3 ; Check SVC number range
BHI SVC_Exit ; Branch if out of range
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDR R12,[R2,R1,LSL #2] ; Load address of SVC function
LDM R0,{R0-R3} ; Load function parameters from stack
BLX R12 ; Call service function
POP {R12,LR} ; Restore SP and EXC_RETURN
STR R0,[R12] ; Store function return value
BX LR ; Return from handler
PendSV_Handler
EXPORT PendSV_Handler
IMPORT osRtxPendSV_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler
POP {R0,LR} ; Restore EXC_RETURN
MRS R12,PSP
B SVC_Context
SysTick_Handler
EXPORT SysTick_Handler
IMPORT osRtxTick_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxTick_Handler ; Call osRtxTick_Handler
POP {R0,LR} ; Restore EXC_RETURN
MRS R12,PSP
B SVC_Context
END

View File

@@ -0,0 +1,146 @@
;/*
; * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the License); you may
; * not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; * -----------------------------------------------------------------------------
; *
; * Project: CMSIS-RTOS RTX
; * Title: Cortex-M4F Exception handlers
; *
; * -----------------------------------------------------------------------------
; */
NAME irq_cm4f.s
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
TCB_SP_OFS EQU 56 ; TCB.SP offset
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
PRESERVE8
SECTION .rodata:DATA:NOROOT(2)
EXPORT irqRtxLib
irqRtxLib DCB 0 ; Non weak library reference
THUMB
SECTION .text:CODE:NOROOT(2)
SVC_Handler
EXPORT SVC_Handler
IMPORT osRtxUserSVC
IMPORT osRtxInfo
TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2
ITE EQ
MRSEQ R0,MSP ; Get MSP if return stack is MSP
MRSNE R0,PSP ; Get PSP if return stack is PSP
LDR R1,[R0,#24] ; Load saved PC from stack
LDRB R1,[R1,#-2] ; Load SVC number
CBNZ R1,SVC_User ; Branch if not SVC 0
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDM R0,{R0-R3,R12} ; Load function parameters and address from stack
BLX R12 ; Call service function
POP {R12,LR} ; Restore SP and EXC_RETURN
STM R12,{R0-R1} ; Store function return values
SVC_Context
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
CMP R1,R2 ; Check if thread switch is required
IT EQ
BXEQ LR ; Exit when threads are the same
CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted
TST LR,#0x10 ; Check if extended stack frame
BNE SVC_ContextSwitch
LDR R1,=0xE000EF34 ; FPCCR Address
LDR R0,[R1] ; Load FPCCR
BIC R0,R0,#1 ; Clear LSPACT (Lazy state)
STR R0,[R1] ; Store FPCCR
B SVC_ContextSwitch
SVC_ContextSave
STMDB R12!,{R4-R11} ; Save R4..R11
TST LR,#0x10 ; Check if extended stack frame
IT EQ
VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31
STR R12,[R1,#TCB_SP_OFS] ; Store SP
STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information
SVC_ContextSwitch
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
SVC_ContextRestore
LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN
TST LR,#0x10 ; Check if extended stack frame
IT EQ
VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31
LDMIA R0!,{R4-R11} ; Restore R4..R11
MSR PSP,R0 ; Set PSP
SVC_Exit
BX LR ; Exit from handler
SVC_User
LDR R2,=osRtxUserSVC ; Load address of SVC table
LDR R3,[R2] ; Load SVC maximum number
CMP R1,R3 ; Check SVC number range
BHI SVC_Exit ; Branch if out of range
PUSH {R0,LR} ; Save SP and EXC_RETURN
LDR R12,[R2,R1,LSL #2] ; Load address of SVC function
LDM R0,{R0-R3} ; Load function parameters from stack
BLX R12 ; Call service function
POP {R12,LR} ; Restore SP and EXC_RETURN
STR R0,[R12] ; Store function return value
BX LR ; Return from handler
PendSV_Handler
EXPORT PendSV_Handler
IMPORT osRtxPendSV_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler
POP {R0,LR} ; Restore EXC_RETURN
MRS R12,PSP
B SVC_Context
SysTick_Handler
EXPORT SysTick_Handler
IMPORT osRtxTick_Handler
PUSH {R0,LR} ; Save EXC_RETURN
BL osRtxTick_Handler ; Call osRtxTick_Handler
POP {R0,LR} ; Restore EXC_RETURN
MRS R12,PSP
B SVC_Context
END