mirror of https://github.com/ARMmbed/mbed-os.git
commit
02a10e5974
|
@ -0,0 +1,298 @@
|
||||||
|
;/*
|
||||||
|
; * Copyright (c) 2016-2017 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 64 ; TCB.tz_memory offset
|
||||||
|
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
THUMB
|
||||||
|
|
||||||
|
|
||||||
|
AREA |.constdata|, DATA, READONLY
|
||||||
|
EXPORT irqRtxLib
|
||||||
|
irqRtxLib DCB 0 ; Non weak library reference
|
||||||
|
|
||||||
|
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
|
||||||
|
SVC_Handler PROC
|
||||||
|
EXPORT SVC_Handler
|
||||||
|
IMPORT osRtxUserSVC
|
||||||
|
IMPORT osRtxInfo
|
||||||
|
#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,=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
|
||||||
|
#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] ; osRtxInfo.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,=osRtxUserSVC ; 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 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
|
||||||
|
|
||||||
|
ALIGN
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
|
||||||
|
SysTick_Handler PROC
|
||||||
|
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
|
||||||
|
|
||||||
|
ALIGN
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
|
||||||
|
Sys_Context PROC
|
||||||
|
EXPORT Sys_Context
|
||||||
|
IMPORT osRtxInfo
|
||||||
|
#ifdef __DOMAIN_NS
|
||||||
|
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
|
||||||
|
#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] ; osRtxInfo.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
|
|
@ -20,10 +20,13 @@ from collections import namedtuple
|
||||||
from mock import patch, MagicMock
|
from mock import patch, MagicMock
|
||||||
from tools.build_api import prepare_toolchain, build_project, build_library,\
|
from tools.build_api import prepare_toolchain, build_project, build_library,\
|
||||||
scan_resources
|
scan_resources
|
||||||
|
from tools.toolchains import TOOLCHAINS
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Tests for build_api.py
|
Tests for build_api.py
|
||||||
"""
|
"""
|
||||||
|
make_mock_target = namedtuple(
|
||||||
|
"Target", "init_hooks name features core supported_toolchains")
|
||||||
|
|
||||||
class BuildApiTests(unittest.TestCase):
|
class BuildApiTests(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
|
@ -82,9 +85,8 @@ class BuildApiTests(unittest.TestCase):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
app_config = "app_config"
|
app_config = "app_config"
|
||||||
mock_target = namedtuple("Target",
|
mock_target = make_mock_target(lambda _, __ : None,
|
||||||
"init_hooks name features core")(lambda _, __ : None,
|
"Junk", [], "Cortex-M3", TOOLCHAINS)
|
||||||
"Junk", [], "Cortex-M3")
|
|
||||||
mock_config_init.return_value = namedtuple(
|
mock_config_init.return_value = namedtuple(
|
||||||
"Config", "target has_regions name")(mock_target, False, None)
|
"Config", "target has_regions name")(mock_target, False, None)
|
||||||
|
|
||||||
|
@ -102,9 +104,8 @@ class BuildApiTests(unittest.TestCase):
|
||||||
:param mock_config_init: mock of Config __init__
|
:param mock_config_init: mock of Config __init__
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
mock_target = namedtuple("Target",
|
mock_target = make_mock_target(lambda _, __ : None,
|
||||||
"init_hooks name features core")(lambda _, __ : None,
|
"Junk", [], "Cortex-M3", TOOLCHAINS)
|
||||||
"Junk", [], "Cortex-M3")
|
|
||||||
mock_config_init.return_value = namedtuple(
|
mock_config_init.return_value = namedtuple(
|
||||||
"Config", "target has_regions name")(mock_target, False, None)
|
"Config", "target has_regions name")(mock_target, False, None)
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,9 @@ class ARM(mbedToolchain):
|
||||||
extra_verbose=extra_verbose,
|
extra_verbose=extra_verbose,
|
||||||
build_profile=build_profile)
|
build_profile=build_profile)
|
||||||
|
|
||||||
|
if "ARM" not in target.supported_toolchains:
|
||||||
|
raise NotSupportedException("ARM compiler support is required for ARM build")
|
||||||
|
|
||||||
if target.core == "Cortex-M0+":
|
if target.core == "Cortex-M0+":
|
||||||
cpu = "Cortex-M0"
|
cpu = "Cortex-M0"
|
||||||
elif target.core == "Cortex-M4F":
|
elif target.core == "Cortex-M4F":
|
||||||
|
@ -276,8 +279,8 @@ class ARMC6(ARM_STD):
|
||||||
def __init__(self, target, *args, **kwargs):
|
def __init__(self, target, *args, **kwargs):
|
||||||
mbedToolchain.__init__(self, target, *args, **kwargs)
|
mbedToolchain.__init__(self, target, *args, **kwargs)
|
||||||
|
|
||||||
if "ARM" not in target.supported_toolchains:
|
if not set(("ARM", "ARMC6")).intersection(set(target.supported_toolchains)):
|
||||||
raise NotSupportedException("ARM compiler support is required for ARMC6 support")
|
raise NotSupportedException("ARM/ARMC6 compiler support is required for ARMC6 build")
|
||||||
|
|
||||||
if target.core.lower().endswith("fd"):
|
if target.core.lower().endswith("fd"):
|
||||||
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-2])
|
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-2])
|
||||||
|
@ -285,6 +288,9 @@ class ARMC6(ARM_STD):
|
||||||
elif target.core.lower().endswith("f"):
|
elif target.core.lower().endswith("f"):
|
||||||
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-1])
|
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-1])
|
||||||
self.flags['ld'].append("--cpu=%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:
|
else:
|
||||||
self.flags['common'].append("-mcpu=%s" % target.core.lower())
|
self.flags['common'].append("-mcpu=%s" % target.core.lower())
|
||||||
self.flags['ld'].append("--cpu=%s" % target.core.lower())
|
self.flags['ld'].append("--cpu=%s" % target.core.lower())
|
||||||
|
@ -298,12 +304,21 @@ class ARMC6(ARM_STD):
|
||||||
elif target.core == "Cortex-M7FD":
|
elif target.core == "Cortex-M7FD":
|
||||||
self.flags['common'].append("-mfpu=fpv5-d16")
|
self.flags['common'].append("-mfpu=fpv5-d16")
|
||||||
self.flags['common'].append("-mfloat-abi=softfp")
|
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 = {
|
asm_cpu = {
|
||||||
"Cortex-M0+": "Cortex-M0",
|
"Cortex-M0+": "Cortex-M0",
|
||||||
"Cortex-M4F": "Cortex-M4.fp",
|
"Cortex-M4F": "Cortex-M4.fp",
|
||||||
"Cortex-M7F": "Cortex-M7.fp.sp",
|
"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)
|
self.flags['asm'].append("--cpu=%s" % asm_cpu)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue