Skip to content

Initial support for Cortex M-23/M-33 devices. #4875

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 2 commits into from
Sep 11, 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
8 changes: 8 additions & 0 deletions cmsis/TARGET_CORTEX_M/cmsis_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@
#ifndef __ARM_ARCH_7EM__
#define __ARM_ARCH_7EM__ 1
#endif
#elif (__CORE__ == __ARM8M_BASELINE__)
#ifndef __ARM_ARCH_8M_BASE__
#define __ARM_ARCH_8M_BASE__ 1
#endif
#elif (__CORE__ == __ARM8M_MAINLINE__)
#ifndef __ARM_ARCH_8M_MAIN__
#define __ARM_ARCH_8M_MAIN__ 1
#endif
#endif

// IAR version 7.8.1 and earlier do not include __ALIGNED
Expand Down
3 changes: 2 additions & 1 deletion platform/CThunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
#define CTHUNK_ADDRESS 1
#define CTHUNK_VARIABLES volatile uint32_t code[2]

#if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9))
#if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9) \
|| defined(__CORTEX_M23) || defined(__CORTEX_M33))
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this work? I would have guessed that the M23 needed to be aligned with the M0/P version

Copy link
Author

Choose a reason for hiding this comment

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

Armv8-M architecture reference manual has new term now for Thumb instructions. It says v8-M variant supports T32 instruction set and does not distinguish between mainline (M-33) and baseline (M-23) architecture.
All instructions are decoded as T32 (not as 16-bit Thumb has to be aligned to half word).

Also, callbacks in test were successful.

/**
* CTHUNK disassembly for Cortex-M3/M4/M7/A9 (thumb2):
* * adr r0, #4
Expand Down
302 changes: 302 additions & 0 deletions rtos/TARGET_CORTEX/rtx5/TARGET_M23/TOOLCHAIN_GCC/irq_armv8mbl.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
;/*
; * 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
; *
; * -----------------------------------------------------------------------------
; */


.file "irq_armv8mbl.S"
.syntax unified

.equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset
.equ TCB_SM_OFS, 48 // TCB.stack_mem offset
.equ TCB_SP_OFS, 56 // TCB.SP offset
.equ TCB_SF_OFS, 34 // TCB.stack_frame offset
.equ TCB_TZM_OFS, 64 // TCB.tz_memory offset

.section ".rodata"
.global irqRtxLib // Non weak library reference
irqRtxLib:
.byte 0


.thumb
.section ".text"
.align 2


.thumb_func
.type SVC_Handler, %function
.global SVC_Handler
.fnstart
.cantunwind
SVC_Handler:
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

.fnend
.size SVC_Handler, .-SVC_Handler


.thumb_func
.type PendSV_Handler, %function
.global PendSV_Handler
.fnstart
.cantunwind
PendSV_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

.fnend
.size PendSV_Handler, .-PendSV_Handler


.thumb_func
.type SysTick_Handler, %function
.global SysTick_Handler
.fnstart
.cantunwind
SysTick_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

.fnend
.size SysTick_Handler, .-SysTick_Handler


.thumb_func
.type Sys_Context, %function
.global Sys_Context
.fnstart
.cantunwind
Sys_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
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

.fnend
.size Sys_Context, .-Sys_Context


.end
Loading