| /* |
| * Copyright (c) 2009-2023 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. |
| */ |
| |
| /* |
| * CMSIS-Core(M) Compiler GCC Header File |
| */ |
| |
| #ifndef __CMSIS_GCC_M_H |
| #define __CMSIS_GCC_M_H |
| |
| #ifndef __CMSIS_GCC_H |
| #error "This file must not be included directly" |
| #endif |
| |
| #include <arm_acle.h> |
| |
| /* ######################### Startup and Lowlevel Init ######################## */ |
| #ifndef __PROGRAM_START |
| |
| /** |
| \brief Initializes data and bss sections |
| \details This default implementations initialized all data and additional bss |
| sections relying on .copy.table and .zero.table specified properly |
| in the used linker script. |
| |
| */ |
| __STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) |
| { |
| extern void _start(void) __NO_RETURN; |
| |
| typedef struct __copy_table { |
| uint32_t const* src; |
| uint32_t* dest; |
| uint32_t wlen; |
| } __copy_table_t; |
| |
| typedef struct __zero_table { |
| uint32_t* dest; |
| uint32_t wlen; |
| } __zero_table_t; |
| |
| extern const __copy_table_t __copy_table_start__; |
| extern const __copy_table_t __copy_table_end__; |
| extern const __zero_table_t __zero_table_start__; |
| extern const __zero_table_t __zero_table_end__; |
| |
| for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { |
| for(uint32_t i=0u; i<pTable->wlen; ++i) { |
| pTable->dest[i] = pTable->src[i]; |
| } |
| } |
| |
| for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { |
| for(uint32_t i=0u; i<pTable->wlen; ++i) { |
| pTable->dest[i] = 0u; |
| } |
| } |
| |
| _start(); |
| } |
| |
| #define __PROGRAM_START __cmsis_start |
| #endif |
| |
| #ifndef __INITIAL_SP |
| #define __INITIAL_SP __StackTop |
| #endif |
| |
| #ifndef __STACK_LIMIT |
| #define __STACK_LIMIT __StackLimit |
| #endif |
| |
| #ifndef __VECTOR_TABLE |
| #define __VECTOR_TABLE __Vectors |
| #endif |
| |
| #ifndef __VECTOR_TABLE_ATTRIBUTE |
| #define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) |
| #endif |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| #ifndef __STACK_SEAL |
| #define __STACK_SEAL __StackSeal |
| #endif |
| |
| #ifndef __TZ_STACK_SEAL_SIZE |
| #define __TZ_STACK_SEAL_SIZE 8U |
| #endif |
| |
| #ifndef __TZ_STACK_SEAL_VALUE |
| #define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL |
| #endif |
| |
| |
| __STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { |
| *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; |
| } |
| #endif |
| |
| |
| /* ########################### Core Function Access ########################### */ |
| /** \ingroup CMSIS_Core_FunctionInterface |
| \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions |
| @{ |
| */ |
| |
| /** |
| \brief Get Control Register |
| \details Returns the content of the Control Register. |
| \return Control Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_CONTROL(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, control" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Control Register (non-secure) |
| \details Returns the content of the non-secure Control Register when in secure mode. |
| \return non-secure Control Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); |
| return (result); |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Control Register |
| \details Writes the given value to the Control Register. |
| \param [in] control Control Register value to set |
| */ |
| __STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) |
| { |
| __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); |
| __ISB(); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Control Register (non-secure) |
| \details Writes the given value to the non-secure Control Register when in secure state. |
| \param [in] control Control Register value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) |
| { |
| __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); |
| __ISB(); |
| } |
| #endif |
| |
| |
| /** |
| \brief Get IPSR Register |
| \details Returns the content of the IPSR Register. |
| \return IPSR Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_IPSR(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| /** |
| \brief Get APSR Register |
| \details Returns the content of the APSR Register. |
| \return APSR Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_APSR(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, apsr" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| /** |
| \brief Get xPSR Register |
| \details Returns the content of the xPSR Register. |
| \return xPSR Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_xPSR(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| /** |
| \brief Get Process Stack Pointer |
| \details Returns the current value of the Process Stack Pointer (PSP). |
| \return PSP Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_PSP(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, psp" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Process Stack Pointer (non-secure) |
| \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. |
| \return PSP Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); |
| return (result); |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Process Stack Pointer |
| \details Assigns the given value to the Process Stack Pointer (PSP). |
| \param [in] topOfProcStack Process Stack Pointer value to set |
| */ |
| __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) |
| { |
| __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Process Stack Pointer (non-secure) |
| \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. |
| \param [in] topOfProcStack Process Stack Pointer value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) |
| { |
| __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); |
| } |
| #endif |
| |
| |
| /** |
| \brief Get Main Stack Pointer |
| \details Returns the current value of the Main Stack Pointer (MSP). |
| \return MSP Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_MSP(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, msp" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Main Stack Pointer (non-secure) |
| \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. |
| \return MSP Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); |
| return (result); |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Main Stack Pointer |
| \details Assigns the given value to the Main Stack Pointer (MSP). |
| \param [in] topOfMainStack Main Stack Pointer value to set |
| */ |
| __STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) |
| { |
| __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Main Stack Pointer (non-secure) |
| \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. |
| \param [in] topOfMainStack Main Stack Pointer value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) |
| { |
| __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); |
| } |
| #endif |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Stack Pointer (non-secure) |
| \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. |
| \return SP Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| /** |
| \brief Set Stack Pointer (non-secure) |
| \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. |
| \param [in] topOfStack Stack Pointer value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) |
| { |
| __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); |
| } |
| #endif |
| |
| |
| /** |
| \brief Get Priority Mask |
| \details Returns the current state of the priority mask bit from the Priority Mask Register. |
| \return Priority Mask value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, primask" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Priority Mask (non-secure) |
| \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. |
| \return Priority Mask value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); |
| return (result); |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Priority Mask |
| \details Assigns the given value to the Priority Mask Register. |
| \param [in] priMask Priority Mask |
| */ |
| __STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) |
| { |
| __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Priority Mask (non-secure) |
| \details Assigns the given value to the non-secure Priority Mask Register when in secure state. |
| \param [in] priMask Priority Mask |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) |
| { |
| __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); |
| } |
| #endif |
| |
| |
| #if (__ARM_ARCH_ISA_THUMB >= 2) |
| /** |
| \brief Get Base Priority |
| \details Returns the current value of the Base Priority register. |
| \return Base Priority register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, basepri" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Base Priority (non-secure) |
| \details Returns the current value of the non-secure Base Priority register when in secure state. |
| \return Base Priority register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); |
| return (result); |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Base Priority |
| \details Assigns the given value to the Base Priority register. |
| \param [in] basePri Base Priority value to set |
| */ |
| __STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) |
| { |
| __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Base Priority (non-secure) |
| \details Assigns the given value to the non-secure Base Priority register when in secure state. |
| \param [in] basePri Base Priority value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) |
| { |
| __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Base Priority with condition |
| \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, |
| or the new value increases the BASEPRI priority level. |
| \param [in] basePri Base Priority value to set |
| */ |
| __STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) |
| { |
| __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); |
| } |
| |
| |
| /** |
| \brief Get Fault Mask |
| \details Returns the current value of the Fault Mask register. |
| \return Fault Mask register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); |
| return (result); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Fault Mask (non-secure) |
| \details Returns the current value of the non-secure Fault Mask register when in secure state. |
| \return Fault Mask register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) |
| { |
| uint32_t result; |
| |
| __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); |
| return (result); |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Fault Mask |
| \details Assigns the given value to the Fault Mask register. |
| \param [in] faultMask Fault Mask value to set |
| */ |
| __STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) |
| { |
| __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Fault Mask (non-secure) |
| \details Assigns the given value to the non-secure Fault Mask register when in secure state. |
| \param [in] faultMask Fault Mask value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) |
| { |
| __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); |
| } |
| #endif |
| |
| #endif /* (__ARM_ARCH_ISA_THUMB >= 2) */ |
| |
| |
| #if (__ARM_ARCH >= 8) |
| /** |
| \brief Get Process Stack Pointer Limit |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence zero is returned always in non-secure |
| mode. |
| |
| \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). |
| \return PSPLIM Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \ |
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) |
| /* without main extensions, the non-secure PSPLIM is RAZ/WI */ |
| return (0U); |
| #else |
| uint32_t result; |
| __ASM volatile ("MRS %0, psplim" : "=r" (result) ); |
| return (result); |
| #endif |
| } |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Process Stack Pointer Limit (non-secure) |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence zero is returned always. |
| |
| \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. |
| \return PSPLIM Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1))) |
| /* without main extensions, the non-secure PSPLIM is RAZ/WI */ |
| return (0U); |
| #else |
| uint32_t result; |
| __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); |
| return (result); |
| #endif |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Process Stack Pointer Limit |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence the write is silently ignored in non-secure |
| mode. |
| |
| \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). |
| \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set |
| */ |
| __STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \ |
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) |
| /* without main extensions, the non-secure PSPLIM is RAZ/WI */ |
| (void)ProcStackPtrLimit; |
| #else |
| __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); |
| #endif |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Process Stack Pointer (non-secure) |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence the write is silently ignored. |
| |
| \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. |
| \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1))) |
| /* without main extensions, the non-secure PSPLIM is RAZ/WI */ |
| (void)ProcStackPtrLimit; |
| #else |
| __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); |
| #endif |
| } |
| #endif |
| |
| |
| /** |
| \brief Get Main Stack Pointer Limit |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence zero is returned always. |
| |
| \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). |
| \return MSPLIM Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \ |
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) |
| /* without main extensions, the non-secure MSPLIM is RAZ/WI */ |
| return (0U); |
| #else |
| uint32_t result; |
| __ASM volatile ("MRS %0, msplim" : "=r" (result) ); |
| return (result); |
| #endif |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Get Main Stack Pointer Limit (non-secure) |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence zero is returned always. |
| |
| \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. |
| \return MSPLIM Register value |
| */ |
| __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1))) |
| /* without main extensions, the non-secure MSPLIM is RAZ/WI */ |
| return (0U); |
| #else |
| uint32_t result; |
| __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); |
| return (result); |
| #endif |
| } |
| #endif |
| |
| |
| /** |
| \brief Set Main Stack Pointer Limit |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence the write is silently ignored. |
| |
| \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). |
| \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set |
| */ |
| __STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \ |
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) |
| /* without main extensions, the non-secure MSPLIM is RAZ/WI */ |
| (void)MainStackPtrLimit; |
| #else |
| __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); |
| #endif |
| } |
| |
| |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3) |
| /** |
| \brief Set Main Stack Pointer Limit (non-secure) |
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure |
| Stack Pointer Limit register hence the write is silently ignored. |
| |
| \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. |
| \param [in] MainStackPtrLimit Main Stack Pointer value to set |
| */ |
| __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) |
| { |
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ |
| !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1))) |
| /* without main extensions, the non-secure MSPLIM is RAZ/WI */ |
| (void)MainStackPtrLimit; |
| #else |
| __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); |
| #endif |
| } |
| #endif |
| |
| #endif /* (__ARM_ARCH >= 8) */ |
| |
| /*@} end of CMSIS_Core_RegAccFunctions */ |
| |
| #endif /* __CMSIS_GCC_M_H */ |