1 /*
2  * Copyright (c) 2009-2023 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 /*
20  * CMSIS-Core(M) Compiler GCC Header File
21  */
22 
23 #ifndef __CMSIS_GCC_M_H
24 #define __CMSIS_GCC_M_H
25 
26 #ifndef __CMSIS_GCC_H
27   #error "This file must not be included directly"
28 #endif
29 
30 #include <arm_acle.h>
31 
32 /* #########################  Startup and Lowlevel Init  ######################## */
33 #ifndef __PROGRAM_START
34 
35 /**
36   \brief   Initializes data and bss sections
37   \details This default implementations initialized all data and additional bss
38            sections relying on .copy.table and .zero.table specified properly
39            in the used linker script.
40 
41  */
__cmsis_start(void)42 __STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void)
43 {
44   extern void _start(void) __NO_RETURN;
45 
46   typedef struct __copy_table {
47     uint32_t const* src;
48     uint32_t* dest;
49     uint32_t  wlen;
50   } __copy_table_t;
51 
52   typedef struct __zero_table {
53     uint32_t* dest;
54     uint32_t  wlen;
55   } __zero_table_t;
56 
57   extern const __copy_table_t __copy_table_start__;
58   extern const __copy_table_t __copy_table_end__;
59   extern const __zero_table_t __zero_table_start__;
60   extern const __zero_table_t __zero_table_end__;
61 
62   for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) {
63     for(uint32_t i=0u; i<pTable->wlen; ++i) {
64       pTable->dest[i] = pTable->src[i];
65     }
66   }
67 
68   for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) {
69     for(uint32_t i=0u; i<pTable->wlen; ++i) {
70       pTable->dest[i] = 0u;
71     }
72   }
73 
74   _start();
75 }
76 
77 #define __PROGRAM_START           __cmsis_start
78 #endif
79 
80 #ifndef __INITIAL_SP
81 #define __INITIAL_SP              __StackTop
82 #endif
83 
84 #ifndef __STACK_LIMIT
85 #define __STACK_LIMIT             __StackLimit
86 #endif
87 
88 #ifndef __VECTOR_TABLE
89 #define __VECTOR_TABLE            __Vectors
90 #endif
91 
92 #ifndef __VECTOR_TABLE_ATTRIBUTE
93 #define __VECTOR_TABLE_ATTRIBUTE  __attribute__((used, section(".vectors")))
94 #endif
95 
96 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
97 #ifndef __STACK_SEAL
98 #define __STACK_SEAL              __StackSeal
99 #endif
100 
101 #ifndef __TZ_STACK_SEAL_SIZE
102 #define __TZ_STACK_SEAL_SIZE      8U
103 #endif
104 
105 #ifndef __TZ_STACK_SEAL_VALUE
106 #define __TZ_STACK_SEAL_VALUE     0xFEF5EDA5FEF5EDA5ULL
107 #endif
108 
109 
__TZ_set_STACKSEAL_S(uint32_t * stackTop)110 __STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) {
111   *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE;
112 }
113 #endif
114 
115 
116 /* ###########################  Core Function Access  ########################### */
117 /** \ingroup  CMSIS_Core_FunctionInterface
118     \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
119   @{
120  */
121 
122 /**
123   \brief   Get Control Register
124   \details Returns the content of the Control Register.
125   \return               Control Register value
126  */
__get_CONTROL(void)127 __STATIC_FORCEINLINE uint32_t __get_CONTROL(void)
128 {
129   uint32_t result;
130 
131   __ASM volatile ("MRS %0, control" : "=r" (result) );
132   return (result);
133 }
134 
135 
136 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
137 /**
138   \brief   Get Control Register (non-secure)
139   \details Returns the content of the non-secure Control Register when in secure mode.
140   \return               non-secure Control Register value
141  */
__TZ_get_CONTROL_NS(void)142 __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void)
143 {
144   uint32_t result;
145 
146   __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
147   return (result);
148 }
149 #endif
150 
151 
152 /**
153   \brief   Set Control Register
154   \details Writes the given value to the Control Register.
155   \param [in]    control  Control Register value to set
156  */
__set_CONTROL(uint32_t control)157 __STATIC_FORCEINLINE void __set_CONTROL(uint32_t control)
158 {
159   __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
160   __ISB();
161 }
162 
163 
164 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
165 /**
166   \brief   Set Control Register (non-secure)
167   \details Writes the given value to the non-secure Control Register when in secure state.
168   \param [in]    control  Control Register value to set
169  */
__TZ_set_CONTROL_NS(uint32_t control)170 __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control)
171 {
172   __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
173   __ISB();
174 }
175 #endif
176 
177 
178 /**
179   \brief   Get IPSR Register
180   \details Returns the content of the IPSR Register.
181   \return               IPSR Register value
182  */
__get_IPSR(void)183 __STATIC_FORCEINLINE uint32_t __get_IPSR(void)
184 {
185   uint32_t result;
186 
187   __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
188   return (result);
189 }
190 
191 
192 /**
193   \brief   Get APSR Register
194   \details Returns the content of the APSR Register.
195   \return               APSR Register value
196  */
__get_APSR(void)197 __STATIC_FORCEINLINE uint32_t __get_APSR(void)
198 {
199   uint32_t result;
200 
201   __ASM volatile ("MRS %0, apsr" : "=r" (result) );
202   return (result);
203 }
204 
205 
206 /**
207   \brief   Get xPSR Register
208   \details Returns the content of the xPSR Register.
209   \return               xPSR Register value
210  */
__get_xPSR(void)211 __STATIC_FORCEINLINE uint32_t __get_xPSR(void)
212 {
213   uint32_t result;
214 
215   __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
216   return (result);
217 }
218 
219 
220 /**
221   \brief   Get Process Stack Pointer
222   \details Returns the current value of the Process Stack Pointer (PSP).
223   \return               PSP Register value
224  */
__get_PSP(void)225 __STATIC_FORCEINLINE uint32_t __get_PSP(void)
226 {
227   uint32_t result;
228 
229   __ASM volatile ("MRS %0, psp"  : "=r" (result) );
230   return (result);
231 }
232 
233 
234 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
235 /**
236   \brief   Get Process Stack Pointer (non-secure)
237   \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
238   \return               PSP Register value
239  */
__TZ_get_PSP_NS(void)240 __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void)
241 {
242   uint32_t result;
243 
244   __ASM volatile ("MRS %0, psp_ns"  : "=r" (result) );
245   return (result);
246 }
247 #endif
248 
249 
250 /**
251   \brief   Set Process Stack Pointer
252   \details Assigns the given value to the Process Stack Pointer (PSP).
253   \param [in]    topOfProcStack  Process Stack Pointer value to set
254  */
__set_PSP(uint32_t topOfProcStack)255 __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
256 {
257   __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
258 }
259 
260 
261 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
262 /**
263   \brief   Set Process Stack Pointer (non-secure)
264   \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
265   \param [in]    topOfProcStack  Process Stack Pointer value to set
266  */
__TZ_set_PSP_NS(uint32_t topOfProcStack)267 __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
268 {
269   __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : );
270 }
271 #endif
272 
273 
274 /**
275   \brief   Get Main Stack Pointer
276   \details Returns the current value of the Main Stack Pointer (MSP).
277   \return               MSP Register value
278  */
__get_MSP(void)279 __STATIC_FORCEINLINE uint32_t __get_MSP(void)
280 {
281   uint32_t result;
282 
283   __ASM volatile ("MRS %0, msp" : "=r" (result) );
284   return (result);
285 }
286 
287 
288 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
289 /**
290   \brief   Get Main Stack Pointer (non-secure)
291   \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
292   \return               MSP Register value
293  */
__TZ_get_MSP_NS(void)294 __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void)
295 {
296   uint32_t result;
297 
298   __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
299   return (result);
300 }
301 #endif
302 
303 
304 /**
305   \brief   Set Main Stack Pointer
306   \details Assigns the given value to the Main Stack Pointer (MSP).
307   \param [in]    topOfMainStack  Main Stack Pointer value to set
308  */
__set_MSP(uint32_t topOfMainStack)309 __STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
310 {
311   __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
312 }
313 
314 
315 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
316 /**
317   \brief   Set Main Stack Pointer (non-secure)
318   \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
319   \param [in]    topOfMainStack  Main Stack Pointer value to set
320  */
__TZ_set_MSP_NS(uint32_t topOfMainStack)321 __STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
322 {
323   __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : );
324 }
325 #endif
326 
327 
328 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
329 /**
330   \brief   Get Stack Pointer (non-secure)
331   \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state.
332   \return               SP Register value
333  */
__TZ_get_SP_NS(void)334 __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void)
335 {
336   uint32_t result;
337 
338   __ASM volatile ("MRS %0, sp_ns" : "=r" (result) );
339   return (result);
340 }
341 
342 
343 /**
344   \brief   Set Stack Pointer (non-secure)
345   \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state.
346   \param [in]    topOfStack  Stack Pointer value to set
347  */
__TZ_set_SP_NS(uint32_t topOfStack)348 __STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack)
349 {
350   __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : );
351 }
352 #endif
353 
354 
355 /**
356   \brief   Get Priority Mask
357   \details Returns the current state of the priority mask bit from the Priority Mask Register.
358   \return               Priority Mask value
359  */
__get_PRIMASK(void)360 __STATIC_FORCEINLINE uint32_t __get_PRIMASK(void)
361 {
362   uint32_t result;
363 
364   __ASM volatile ("MRS %0, primask" : "=r" (result) );
365   return (result);
366 }
367 
368 
369 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
370 /**
371   \brief   Get Priority Mask (non-secure)
372   \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
373   \return               Priority Mask value
374  */
__TZ_get_PRIMASK_NS(void)375 __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void)
376 {
377   uint32_t result;
378 
379   __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
380   return (result);
381 }
382 #endif
383 
384 
385 /**
386   \brief   Set Priority Mask
387   \details Assigns the given value to the Priority Mask Register.
388   \param [in]    priMask  Priority Mask
389  */
__set_PRIMASK(uint32_t priMask)390 __STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask)
391 {
392   __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
393 }
394 
395 
396 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
397 /**
398   \brief   Set Priority Mask (non-secure)
399   \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
400   \param [in]    priMask  Priority Mask
401  */
__TZ_set_PRIMASK_NS(uint32_t priMask)402 __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
403 {
404   __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
405 }
406 #endif
407 
408 
409 #if (__ARM_ARCH_ISA_THUMB >= 2)
410 /**
411   \brief   Get Base Priority
412   \details Returns the current value of the Base Priority register.
413   \return               Base Priority register value
414  */
__get_BASEPRI(void)415 __STATIC_FORCEINLINE uint32_t __get_BASEPRI(void)
416 {
417   uint32_t result;
418 
419   __ASM volatile ("MRS %0, basepri" : "=r" (result) );
420   return (result);
421 }
422 
423 
424 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
425 /**
426   \brief   Get Base Priority (non-secure)
427   \details Returns the current value of the non-secure Base Priority register when in secure state.
428   \return               Base Priority register value
429  */
__TZ_get_BASEPRI_NS(void)430 __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void)
431 {
432   uint32_t result;
433 
434   __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
435   return (result);
436 }
437 #endif
438 
439 
440 /**
441   \brief   Set Base Priority
442   \details Assigns the given value to the Base Priority register.
443   \param [in]    basePri  Base Priority value to set
444  */
__set_BASEPRI(uint32_t basePri)445 __STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri)
446 {
447   __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory");
448 }
449 
450 
451 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
452 /**
453   \brief   Set Base Priority (non-secure)
454   \details Assigns the given value to the non-secure Base Priority register when in secure state.
455   \param [in]    basePri  Base Priority value to set
456  */
__TZ_set_BASEPRI_NS(uint32_t basePri)457 __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri)
458 {
459   __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory");
460 }
461 #endif
462 
463 
464 /**
465   \brief   Set Base Priority with condition
466   \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
467            or the new value increases the BASEPRI priority level.
468   \param [in]    basePri  Base Priority value to set
469  */
__set_BASEPRI_MAX(uint32_t basePri)470 __STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri)
471 {
472   __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory");
473 }
474 
475 
476 /**
477   \brief   Get Fault Mask
478   \details Returns the current value of the Fault Mask register.
479   \return               Fault Mask register value
480  */
__get_FAULTMASK(void)481 __STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void)
482 {
483   uint32_t result;
484 
485   __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
486   return (result);
487 }
488 
489 
490 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
491 /**
492   \brief   Get Fault Mask (non-secure)
493   \details Returns the current value of the non-secure Fault Mask register when in secure state.
494   \return               Fault Mask register value
495  */
__TZ_get_FAULTMASK_NS(void)496 __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void)
497 {
498   uint32_t result;
499 
500   __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
501   return (result);
502 }
503 #endif
504 
505 
506 /**
507   \brief   Set Fault Mask
508   \details Assigns the given value to the Fault Mask register.
509   \param [in]    faultMask  Fault Mask value to set
510  */
__set_FAULTMASK(uint32_t faultMask)511 __STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask)
512 {
513   __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
514 }
515 
516 
517 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
518 /**
519   \brief   Set Fault Mask (non-secure)
520   \details Assigns the given value to the non-secure Fault Mask register when in secure state.
521   \param [in]    faultMask  Fault Mask value to set
522  */
__TZ_set_FAULTMASK_NS(uint32_t faultMask)523 __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
524 {
525   __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
526 }
527 #endif
528 
529 #endif /* (__ARM_ARCH_ISA_THUMB >= 2) */
530 
531 
532 #if (__ARM_ARCH >= 8)
533 /**
534   \brief   Get Process Stack Pointer Limit
535   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
536   Stack Pointer Limit register hence zero is returned always in non-secure
537   mode.
538 
539   \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
540   \return               PSPLIM Register value
541  */
__get_PSPLIM(void)542 __STATIC_FORCEINLINE uint32_t __get_PSPLIM(void)
543 {
544 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
545       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
546        (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
547   /* without main extensions, the non-secure PSPLIM is RAZ/WI */
548   return (0U);
549 #else
550   uint32_t result;
551   __ASM volatile ("MRS %0, psplim"  : "=r" (result) );
552   return (result);
553 #endif
554 }
555 
556 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
557 /**
558   \brief   Get Process Stack Pointer Limit (non-secure)
559   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
560   Stack Pointer Limit register hence zero is returned always.
561 
562   \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
563   \return               PSPLIM Register value
564  */
__TZ_get_PSPLIM_NS(void)565 __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void)
566 {
567 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
568       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)))
569   /* without main extensions, the non-secure PSPLIM is RAZ/WI */
570   return (0U);
571 #else
572   uint32_t result;
573   __ASM volatile ("MRS %0, psplim_ns"  : "=r" (result) );
574   return (result);
575 #endif
576 }
577 #endif
578 
579 
580 /**
581   \brief   Set Process Stack Pointer Limit
582   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
583   Stack Pointer Limit register hence the write is silently ignored in non-secure
584   mode.
585 
586   \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
587   \param [in]    ProcStackPtrLimit  Process Stack Pointer Limit value to set
588  */
__set_PSPLIM(uint32_t ProcStackPtrLimit)589 __STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
590 {
591 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
592       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
593        (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
594   /* without main extensions, the non-secure PSPLIM is RAZ/WI */
595   (void)ProcStackPtrLimit;
596 #else
597   __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
598 #endif
599 }
600 
601 
602 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
603 /**
604   \brief   Set Process Stack Pointer (non-secure)
605   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
606   Stack Pointer Limit register hence the write is silently ignored.
607 
608   \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
609   \param [in]    ProcStackPtrLimit  Process Stack Pointer Limit value to set
610  */
__TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)611 __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
612 {
613 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
614       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)))
615   /* without main extensions, the non-secure PSPLIM is RAZ/WI */
616   (void)ProcStackPtrLimit;
617 #else
618   __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
619 #endif
620 }
621 #endif
622 
623 
624 /**
625   \brief   Get Main Stack Pointer Limit
626   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
627   Stack Pointer Limit register hence zero is returned always.
628 
629   \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
630   \return               MSPLIM Register value
631  */
__get_MSPLIM(void)632 __STATIC_FORCEINLINE uint32_t __get_MSPLIM(void)
633 {
634 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
635       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
636        (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
637   /* without main extensions, the non-secure MSPLIM is RAZ/WI */
638   return (0U);
639 #else
640   uint32_t result;
641   __ASM volatile ("MRS %0, msplim" : "=r" (result) );
642   return (result);
643 #endif
644 }
645 
646 
647 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
648 /**
649   \brief   Get Main Stack Pointer Limit (non-secure)
650   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
651   Stack Pointer Limit register hence zero is returned always.
652 
653   \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
654   \return               MSPLIM Register value
655  */
__TZ_get_MSPLIM_NS(void)656 __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void)
657 {
658 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
659       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)))
660   /* without main extensions, the non-secure MSPLIM is RAZ/WI */
661   return (0U);
662 #else
663   uint32_t result;
664   __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
665   return (result);
666 #endif
667 }
668 #endif
669 
670 
671 /**
672   \brief   Set Main Stack Pointer Limit
673   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
674   Stack Pointer Limit register hence the write is silently ignored.
675 
676   \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
677   \param [in]    MainStackPtrLimit  Main Stack Pointer Limit value to set
678  */
__set_MSPLIM(uint32_t MainStackPtrLimit)679 __STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
680 {
681 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
682       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
683        (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
684   /* without main extensions, the non-secure MSPLIM is RAZ/WI */
685   (void)MainStackPtrLimit;
686 #else
687   __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
688 #endif
689 }
690 
691 
692 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
693 /**
694   \brief   Set Main Stack Pointer Limit (non-secure)
695   Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
696   Stack Pointer Limit register hence the write is silently ignored.
697 
698   \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
699   \param [in]    MainStackPtrLimit  Main Stack Pointer value to set
700  */
__TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)701 __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
702 {
703 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
704       !(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)))
705   /* without main extensions, the non-secure MSPLIM is RAZ/WI */
706   (void)MainStackPtrLimit;
707 #else
708   __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
709 #endif
710 }
711 #endif
712 
713 #endif /* (__ARM_ARCH >= 8) */
714 
715 /*@} end of CMSIS_Core_RegAccFunctions */
716 
717 #endif /* __CMSIS_GCC_M_H */
718