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