| #ifndef __STATIC_INLINE | #ifndef __STATIC_INLINE | ||||
| #define __STATIC_INLINE static inline | #define __STATIC_INLINE static inline | ||||
| #endif | #endif | ||||
| #ifndef __STATIC_FORCEINLINE | |||||
| #ifndef __STATIC_FORCEINLINE | |||||
| #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline | #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline | ||||
| #endif | |||||
| #endif | |||||
| #ifndef __NO_RETURN | #ifndef __NO_RETURN | ||||
| #define __NO_RETURN __attribute__((__noreturn__)) | #define __NO_RETURN __attribute__((__noreturn__)) | ||||
| #endif | #endif | ||||
| \details This default implementations initialized all data and additional bss | \details This default implementations initialized all data and additional bss | ||||
| sections relying on .copy.table and .zero.table specified properly | sections relying on .copy.table and .zero.table specified properly | ||||
| in the used linker script. | in the used linker script. | ||||
| */ | */ | ||||
| __STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) | __STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) | ||||
| { | { | ||||
| extern void _start(void) __NO_RETURN; | extern void _start(void) __NO_RETURN; | ||||
| typedef struct { | typedef struct { | ||||
| uint32_t const* src; | uint32_t const* src; | ||||
| uint32_t* dest; | uint32_t* dest; | ||||
| uint32_t wlen; | uint32_t wlen; | ||||
| } __copy_table_t; | } __copy_table_t; | ||||
| typedef struct { | typedef struct { | ||||
| uint32_t* dest; | uint32_t* dest; | ||||
| uint32_t wlen; | uint32_t wlen; | ||||
| } __zero_table_t; | } __zero_table_t; | ||||
| extern const __copy_table_t __copy_table_start__; | extern const __copy_table_t __copy_table_start__; | ||||
| extern const __copy_table_t __copy_table_end__; | extern const __copy_table_t __copy_table_end__; | ||||
| extern const __zero_table_t __zero_table_start__; | extern const __zero_table_t __zero_table_start__; | ||||
| pTable->dest[i] = pTable->src[i]; | pTable->dest[i] = pTable->src[i]; | ||||
| } | } | ||||
| } | } | ||||
| for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { | for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { | ||||
| for(uint32_t i=0u; i<pTable->wlen; ++i) { | for(uint32_t i=0u; i<pTable->wlen; ++i) { | ||||
| pTable->dest[i] = 0u; | pTable->dest[i] = 0u; | ||||
| } | } | ||||
| } | } | ||||
| _start(); | _start(); | ||||
| } | } | ||||
| #define __PROGRAM_START __cmsis_start | #define __PROGRAM_START __cmsis_start | ||||
| #endif | #endif | ||||
| @{ | @{ | ||||
| */ | */ | ||||
| #ifndef TEENSYDUINO | |||||
| /** | /** | ||||
| \brief Enable IRQ Interrupts | \brief Enable IRQ Interrupts | ||||
| \details Enables IRQ interrupts by clearing the I-bit in the CPSR. | \details Enables IRQ interrupts by clearing the I-bit in the CPSR. | ||||
| __ASM volatile ("cpsid i" : : : "memory"); | __ASM volatile ("cpsid i" : : : "memory"); | ||||
| } | } | ||||
| #endif /* TEENSYDUINO */ | |||||
| /** | /** | ||||
| \brief Get Control Register | \brief Get Control Register | ||||
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the 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 in non-secure | Stack Pointer Limit register hence zero is returned always in non-secure | ||||
| mode. | mode. | ||||
| \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). | \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). | ||||
| \return PSPLIM Register value | \return PSPLIM Register value | ||||
| */ | */ | ||||
| Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the 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 in non-secure | Stack Pointer Limit register hence the write is silently ignored in non-secure | ||||
| mode. | mode. | ||||
| \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). | \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). | ||||
| \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set | \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set | ||||
| */ | */ | ||||
| { | { | ||||
| #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | ||||
| (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) | (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) | ||||
| #if __has_builtin(__builtin_arm_get_fpscr) | |||||
| #if __has_builtin(__builtin_arm_get_fpscr) | |||||
| // Re-enable using built-in when GCC has been fixed | // Re-enable using built-in when GCC has been fixed | ||||
| // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) | // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) | ||||
| /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ | /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ |