Skip to content

ARMC6 support for Cortex-M23 #5094

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
298 changes: 298 additions & 0 deletions rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_ARM/irq_armv8mbl.S
Original file line number Diff line number Diff line change
@@ -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
13 changes: 7 additions & 6 deletions tools/test/build_api/build_api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
from mock import patch, MagicMock
from tools.build_api import prepare_toolchain, build_project, build_library,\
scan_resources
from tools.toolchains import TOOLCHAINS

"""
Tests for build_api.py
"""
make_mock_target = namedtuple(
"Target", "init_hooks name features core supported_toolchains")

class BuildApiTests(unittest.TestCase):
"""
Expand Down Expand Up @@ -82,9 +85,8 @@ def test_prepare_toolchain_app_config(self, mock_config_init):
:return:
"""
app_config = "app_config"
mock_target = namedtuple("Target",
"init_hooks name features core")(lambda _, __ : None,
"Junk", [], "Cortex-M3")
mock_target = make_mock_target(lambda _, __ : None,
"Junk", [], "Cortex-M3", TOOLCHAINS)
mock_config_init.return_value = namedtuple(
"Config", "target has_regions name")(mock_target, False, None)

Expand All @@ -102,9 +104,8 @@ def test_prepare_toolchain_no_app_config(self, mock_config_init):
:param mock_config_init: mock of Config __init__
:return:
"""
mock_target = namedtuple("Target",
"init_hooks name features core")(lambda _, __ : None,
"Junk", [], "Cortex-M3")
mock_target = make_mock_target(lambda _, __ : None,
"Junk", [], "Cortex-M3", TOOLCHAINS)
mock_config_init.return_value = namedtuple(
"Config", "target has_regions name")(mock_target, False, None)

Expand Down
21 changes: 18 additions & 3 deletions tools/toolchains/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def __init__(self, target, notify=None, macros=None,
extra_verbose=extra_verbose,
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+":
cpu = "Cortex-M0"
elif target.core == "Cortex-M4F":
Expand Down Expand Up @@ -276,15 +279,18 @@ def check_executable():
def __init__(self, target, *args, **kwargs):
mbedToolchain.__init__(self, target, *args, **kwargs)

if "ARM" not in target.supported_toolchains:
raise NotSupportedException("ARM compiler support is required for ARMC6 support")
if not set(("ARM", "ARMC6")).intersection(set(target.supported_toolchains)):
raise NotSupportedException("ARM/ARMC6 compiler support is required for ARMC6 build")

if target.core.lower().endswith("fd"):
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-2])
self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-2])
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"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does ns at the end of the core signify? NEON?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NS - Non Secure

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

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())
Expand All @@ -298,12 +304,21 @@ def __init__(self, target, *args, **kwargs):
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")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this flag do?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cortex-M23-NS : Non-secure build
Cortex-M23: Secure build (-mcmse flag is required to build a secure image).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super helpful.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super helpful.

It might be better if this type of flags are part of the commit message what they do or in the code as comment if they have special meaning (why are we enabling a secure image).


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)

Expand Down