From 60c600ac113d12a85f1695b384daadce050df581 Mon Sep 17 00:00:00 2001 From: Deepika Date: Wed, 13 Sep 2017 17:07:05 -0500 Subject: [PATCH] ARMC6 support for Cortex-M23 --- .../TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S | 298 ++++++++++++++++++ tools/toolchains/arm.py | 14 +- 2 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S diff --git a/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S b/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S new file mode 100644 index 0000000000..325f6cc1dc --- /dev/null +++ b/rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S @@ -0,0 +1,298 @@ +;/* +; * Copyright (c) 2016 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 +; * +; * ----------------------------------------------------------------------------- +; */ + +I_T_RUN_OFS EQU 28 ; osInfo.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 60 ; TCB.tz_memory offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT os_irq_cm +os_irq_cm DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT os_UserSVC_Table + IMPORT os_Info +#ifdef __DOMAIN_NS + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S +#endif + + MRS R0,PSP ; Get PSP + 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 PSP and EXC_RETURN + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore PSP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=os_Info+I_T_RUN_OFS; Load address of os_Info.run + LDMIA R3!,{R1,R2} ; Load os_Info.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 +#ifdef __DOMAIN_NS + 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 ; Adjust PSP + 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] ; os_Info.thread.run: curr = next + +SVC_ContextRestore +#ifdef __DOMAIN_NS + 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 + +#ifdef __DOMAIN_NS + 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_User + PUSH {R4,LR} ; Save registers + LDR R2,=os_UserSVC_Table ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LSLS R1,R1,#2 + LDR R4,[R2,R1] ; Load address of SVC function + + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STR R0,[R4] ; Store function return value + +SVC_Done + POP {R4,PC} ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT os_PendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL os_PendSV_Handler ; Call os_PendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B Sys_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT os_Tick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL os_Tick_Handler ; Call os_Tick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B Sys_Context + + ALIGN + ENDP + + +Sys_Context PROC + EXPORT Sys_Context + IMPORT os_Info +#ifdef __DOMAIN_NS + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S +#endif + + LDR R3,=os_Info+I_T_RUN_OFS; Load address of os_Info.run + LDM R3!,{R1,R2} ; Load os_Info.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ Sys_ContextExit ; Branch when threads are the same + +Sys_ContextSave +#ifdef __DOMAIN_NS + 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 + LSLS R7,R7,#25 ; Check domain of interrupted thread + BMI Sys_ContextSave1 ; Branch if secure + MRS R0,PSP ; Get PSP + STR R0,[R1,#TCB_SP_OFS] ; Store SP + B Sys_ContextSave2 +#endif + +Sys_ContextSave1 + 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_ContextSave2 + 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] ; os_Info.run: curr = next + +Sys_ContextRestore +#ifdef __DOMAIN_NS + 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 + +#ifdef __DOMAIN_NS + 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 + + ALIGN + ENDP + + + END \ No newline at end of file diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index f1d954a8b2..8225fe9c7c 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -285,6 +285,9 @@ class ARMC6(ARM_STD): elif target.core.lower().endswith("f"): self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-1]) self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-1]) + elif target.core.lower().endswith("ns"): + self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-3]) + self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-3]) else: self.flags['common'].append("-mcpu=%s" % target.core.lower()) self.flags['ld'].append("--cpu=%s" % target.core.lower()) @@ -298,12 +301,21 @@ class ARMC6(ARM_STD): elif target.core == "Cortex-M7FD": self.flags['common'].append("-mfpu=fpv5-d16") self.flags['common'].append("-mfloat-abi=softfp") + elif target.core.startswith("Cortex-M23"): + self.flags['common'].append("-march=armv8-m.base") + elif target.core.startswith("Cortex-M33"): + self.flags['common'].append("-march=armv8-m.main") + + if target.core == "Cortex-M23" or target.core == "Cortex-M33": + self.flags['common'].append("-mcmse") asm_cpu = { "Cortex-M0+": "Cortex-M0", "Cortex-M4F": "Cortex-M4.fp", "Cortex-M7F": "Cortex-M7.fp.sp", - "Cortex-M7FD": "Cortex-M7.fp.dp"}.get(target.core, target.core) + "Cortex-M7FD": "Cortex-M7.fp.dp", + "Cortex-M23-NS": "Cortex-M23", + "Cortex-M33-NS": "Cortex-M33" }.get(target.core, target.core) self.flags['asm'].append("--cpu=%s" % asm_cpu)