]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Source/CV_CoreFunc.c
Run CoreValidation in VHT models
[cmsis] / CMSIS / CoreValidation / Source / CV_CoreFunc.c
1 /*-----------------------------------------------------------------------------
2  *      Name:         CV_CoreFunc.c
3  *      Purpose:      CMSIS CORE validation tests implementation
4  *-----------------------------------------------------------------------------
5  *      Copyright (c) 2017 - 2023 Arm Limited. All rights reserved.
6  *----------------------------------------------------------------------------*/
7
8 #include "CV_Framework.h"
9 #include "cmsis_cv.h"
10
11 /*-----------------------------------------------------------------------------
12  *      Test implementation
13  *----------------------------------------------------------------------------*/
14
15 static volatile uint32_t irqTaken = 0U;
16 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
17 static volatile uint32_t irqActive = 0U;
18 #endif
19
20 static void TC_CoreFunc_EnDisIRQIRQHandler(void) {
21   ++irqTaken;
22 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
23   irqActive = NVIC_GetActive(Interrupt0_IRQn);
24 #endif
25 }
26
27 static volatile uint32_t irqIPSR = 0U;
28 static volatile uint32_t irqXPSR = 0U;
29
30 static void TC_CoreFunc_IPSR_IRQHandler(void) {
31   irqIPSR = __get_IPSR();
32   irqXPSR = __get_xPSR();
33 }
34
35 /*-----------------------------------------------------------------------------
36  *      Test cases
37  *----------------------------------------------------------------------------*/
38
39 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
40 /**
41 \brief Test case: TC_CoreFunc_EnDisIRQ
42 \details
43 Check expected behavior of interrupt related control functions:
44 - __disable_irq() and __enable_irq()
45 - NVIC_EnableIRQ, NVIC_DisableIRQ,  and NVIC_GetEnableIRQ
46 - NVIC_SetPendingIRQ, NVIC_ClearPendingIRQ, and NVIC_GetPendingIRQ
47 - NVIC_GetActive (not on Cortex-M0/M0+)
48 */
49 void TC_CoreFunc_EnDisIRQ (void)
50 {
51   // Globally disable all interrupt servicing
52   __disable_irq();
53
54   // Enable the interrupt
55   NVIC_EnableIRQ(Interrupt0_IRQn);
56   ASSERT_TRUE(NVIC_GetEnableIRQ(Interrupt0_IRQn) != 0U);
57
58   // Clear its pending state
59   NVIC_ClearPendingIRQ(Interrupt0_IRQn);
60   ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) == 0U);
61
62   // Register test interrupt handler.
63   TST_IRQHandler = TC_CoreFunc_EnDisIRQIRQHandler;
64   irqTaken = 0U;
65 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
66   irqActive = UINT32_MAX;
67 #endif
68
69   // Set the interrupt pending state
70   NVIC_SetPendingIRQ(Interrupt0_IRQn);
71   for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
72
73   // Interrupt is not taken
74   ASSERT_TRUE(irqTaken == 0U);
75   ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) != 0U);
76 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
77   ASSERT_TRUE(NVIC_GetActive(Interrupt0_IRQn) == 0U);
78 #endif
79
80   // Globally enable interrupt servicing
81   __enable_irq();
82
83   for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
84
85   // Interrupt was taken
86   ASSERT_TRUE(irqTaken == 1U);
87 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
88   ASSERT_TRUE(irqActive != 0U);
89   ASSERT_TRUE(NVIC_GetActive(Interrupt0_IRQn) == 0U);
90 #endif
91
92   // Interrupt it not pending anymore.
93   ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) == 0U);
94
95   // Disable interrupt
96   NVIC_DisableIRQ(Interrupt0_IRQn);
97   ASSERT_TRUE(NVIC_GetEnableIRQ(Interrupt0_IRQn) == 0U);
98
99   // Set interrupt pending
100   NVIC_SetPendingIRQ(Interrupt0_IRQn);
101   for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
102
103   // Interrupt is not taken again
104   ASSERT_TRUE(irqTaken == 1U);
105   ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) != 0U);
106
107   // Clear interrupt pending
108   NVIC_ClearPendingIRQ(Interrupt0_IRQn);
109   for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
110
111   // Interrupt it not pending anymore.
112   ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) == 0U);
113
114   // Globally disable interrupt servicing
115   __disable_irq();
116 }
117
118 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
119 /**
120 \brief Test case: TC_CoreFunc_IRQPrio
121 \details
122 Check expected behavior of interrupt priority control functions:
123 - NVIC_SetPriority, NVIC_GetPriority
124 */
125 void TC_CoreFunc_IRQPrio (void)
126 {
127   /* Test Exception Priority */
128   uint32_t orig = NVIC_GetPriority(SVCall_IRQn);
129
130   NVIC_SetPriority(SVCall_IRQn, orig+1U);
131   uint32_t prio = NVIC_GetPriority(SVCall_IRQn);
132
133   ASSERT_TRUE(prio == orig+1U);
134
135   NVIC_SetPriority(SVCall_IRQn, orig);
136
137   /* Test Interrupt Priority */
138   orig = NVIC_GetPriority(Interrupt0_IRQn);
139
140   NVIC_SetPriority(Interrupt0_IRQn, orig+1U);
141   prio = NVIC_GetPriority(Interrupt0_IRQn);
142
143   ASSERT_TRUE(prio == orig+1U);
144
145   NVIC_SetPriority(Interrupt0_IRQn, orig);
146 }
147
148 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
149 /** Helper function for TC_CoreFunc_EncDecIRQPrio
150 \details
151 The helper encodes and decodes the given priority configuration.
152 \param[in] prigroup The PRIGROUP setting to be considered for encoding/decoding.
153 \param[in] pre The preempt priority value.
154 \param[in] sub The subpriority value.
155 */
156 static void TC_CoreFunc_EncDecIRQPrio_Step(uint32_t prigroup, uint32_t pre, uint32_t sub) {
157   uint32_t prio = NVIC_EncodePriority(prigroup, pre, sub);
158
159   uint32_t ret_pre = UINT32_MAX;
160   uint32_t ret_sub = UINT32_MAX;
161
162   NVIC_DecodePriority(prio, prigroup, &ret_pre, &ret_sub);
163
164   ASSERT_TRUE(ret_pre == pre);
165   ASSERT_TRUE(ret_sub == sub);
166 }
167
168 /**
169 \brief Test case: TC_CoreFunc_EncDecIRQPrio
170 \details
171 Check expected behavior of interrupt priority encoding/decoding functions:
172 - NVIC_EncodePriority, NVIC_DecodePriority
173 */
174 void TC_CoreFunc_EncDecIRQPrio (void)
175 {
176   /* Check only the valid range of PRIGROUP and preempt-/sub-priority values. */
177   static const uint32_t priobits = (__NVIC_PRIO_BITS > 7U) ? 7U : __NVIC_PRIO_BITS;
178   for(uint32_t prigroup = 7U-priobits; prigroup<7U; prigroup++) {
179     for(uint32_t pre = 0U; pre<(128U>>prigroup); pre++) {
180       for(uint32_t sub = 0U; sub<(256U>>(8U-__NVIC_PRIO_BITS+7U-prigroup)); sub++) {
181         TC_CoreFunc_EncDecIRQPrio_Step(prigroup, pre, sub);
182       }
183     }
184   }
185 }
186
187 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
188 /**
189 \brief Test case: TC_CoreFunc_IRQVect
190 \details
191 Check expected behavior of interrupt vector relocation functions:
192 - NVIC_SetVector, NVIC_GetVector
193 */
194 void TC_CoreFunc_IRQVect(void) {
195 #if defined(__VTOR_PRESENT) && __VTOR_PRESENT
196   /* relocate vector table */
197   extern const VECTOR_TABLE_Type __VECTOR_TABLE[48];
198   static VECTOR_TABLE_Type vectors[sizeof(__VECTOR_TABLE)/sizeof(__VECTOR_TABLE[0])] __ALIGNED(1024) __NO_INIT;
199   memcpy(vectors, __VECTOR_TABLE, sizeof(__VECTOR_TABLE));
200
201   const uint32_t orig_vtor = SCB->VTOR;
202   const uint32_t vtor = ((uint32_t)vectors) & SCB_VTOR_TBLOFF_Msk;
203   SCB->VTOR = vtor;
204
205   ASSERT_TRUE(vtor == SCB->VTOR);
206
207   /* check exception vectors */
208   extern void HardFault_Handler(void);
209   extern void SVC_Handler(void);
210   extern void PendSV_Handler(void);
211   extern void SysTick_Handler(void);
212
213   ASSERT_TRUE(NVIC_GetVector(HardFault_IRQn) == (uint32_t)HardFault_Handler);
214   ASSERT_TRUE(NVIC_GetVector(SVCall_IRQn) == (uint32_t)SVC_Handler);
215   ASSERT_TRUE(NVIC_GetVector(PendSV_IRQn) == (uint32_t)PendSV_Handler);
216   ASSERT_TRUE(NVIC_GetVector(SysTick_IRQn) == (uint32_t)SysTick_Handler);
217
218   /* reconfigure WDT IRQ vector */
219   extern void Interrupt0_Handler(void);
220
221   const uint32_t wdtvec = NVIC_GetVector(Interrupt0_IRQn);
222   ASSERT_TRUE(wdtvec == (uint32_t)Interrupt0_Handler);
223
224   NVIC_SetVector(Interrupt0_IRQn, wdtvec + 32U);
225
226   ASSERT_TRUE(NVIC_GetVector(Interrupt0_IRQn) == (wdtvec + 32U));
227
228   /* restore vector table */
229   SCB->VTOR = orig_vtor;
230 #endif
231 }
232
233 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
234 /**
235 \brief Test case: TC_CoreFunc_GetCtrl
236 \details
237 - Check if __set_CONTROL and __get_CONTROL() sets/gets control register
238 */
239 void TC_CoreFunc_Control (void) {
240   // don't use stack for this variables
241   static uint32_t orig;
242   static uint32_t ctrl;
243   static uint32_t result;
244
245   orig = __get_CONTROL();
246   ctrl = orig;
247   result = UINT32_MAX;
248
249 #ifdef CONTROL_SPSEL_Msk
250   // SPSEL set to 0 (MSP)
251   ASSERT_TRUE((ctrl & CONTROL_SPSEL_Msk) == 0U);
252
253   // SPSEL set to 1 (PSP)
254   ctrl |= CONTROL_SPSEL_Msk;
255
256   // Move MSP to PSP
257   __set_PSP(__get_MSP());
258 #endif
259
260   __set_CONTROL(ctrl);
261   __ISB();
262
263   result = __get_CONTROL();
264
265   __set_CONTROL(orig);
266   __ISB();
267
268   ASSERT_TRUE(result == ctrl);
269   ASSERT_TRUE(__get_CONTROL() == orig);
270 }
271
272 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
273 /**
274 \brief Test case: TC_CoreFunc_IPSR
275 \details
276 - Check if __get_IPSR intrinsic is available
277 - Check if __get_xPSR intrinsic is available
278 - Result differentiates between thread and exception modes
279 */
280 void TC_CoreFunc_IPSR (void) {
281   uint32_t result = __get_IPSR();
282   ASSERT_TRUE(result == 0U); // Thread Mode
283
284   result = __get_xPSR();
285   ASSERT_TRUE((result & xPSR_ISR_Msk) == 0U); // Thread Mode
286
287   TST_IRQHandler = TC_CoreFunc_IPSR_IRQHandler;
288   irqIPSR = 0U;
289   irqXPSR = 0U;
290
291   NVIC_ClearPendingIRQ(Interrupt0_IRQn);
292   NVIC_EnableIRQ(Interrupt0_IRQn);
293   __enable_irq();
294
295   NVIC_SetPendingIRQ(Interrupt0_IRQn);
296   for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
297
298   __disable_irq();
299   NVIC_DisableIRQ(Interrupt0_IRQn);
300
301   ASSERT_TRUE(irqIPSR != 0U); // Exception Mode
302   ASSERT_TRUE((irqXPSR & xPSR_ISR_Msk) != 0U); // Exception Mode
303 }
304
305 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
306
307 #if defined(__CC_ARM)
308 #define SUBS(Rd, Rm, Rn) __ASM volatile("SUBS " # Rd ", " # Rm ", " # Rn)
309 #define ADDS(Rd, Rm, Rn) __ASM volatile("ADDS " # Rd ", " # Rm ", " # Rn)
310 #elif defined(_lint)
311 //lint -save -e(9026) allow function-like macro
312 #define SUBS(Rd, Rm, Rn) ((Rd) = (Rm) - (Rn))
313 #define ADDS(Rd, Rm, Rn) ((Rd) = (Rm) + (Rn))
314 //lint -restore
315 #else
316 #define SUBS(Rd, Rm, Rn) __ASM volatile("SUBS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
317 #define ADDS(Rd, Rm, Rn) __ASM volatile("ADDS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
318 #endif
319
320 /**
321 \brief Test case: TC_CoreFunc_APSR
322 \details
323 - Check if __get_APSR intrinsic is available
324 - Check if __get_xPSR intrinsic is available
325 - Check negative, zero and overflow flags
326 */
327 void TC_CoreFunc_APSR (void) {
328   volatile uint32_t result;
329   //lint -esym(838, Rm) unused values
330   //lint -esym(438, Rm) unused values
331
332   // Check negative flag
333   volatile int32_t Rm = 5;
334   volatile int32_t Rn = 7;
335   SUBS(Rm, Rm, Rn);
336   result  = __get_APSR();
337   ASSERT_TRUE((result & APSR_N_Msk) == APSR_N_Msk);
338
339   Rm = 5;
340   Rn = 7;
341   SUBS(Rm, Rm, Rn);
342   result  = __get_xPSR();
343   ASSERT_TRUE((result & xPSR_N_Msk) == xPSR_N_Msk);
344
345   // Check zero and compare flag
346   Rm = 5;
347   SUBS(Rm, Rm, Rm);
348   result  = __get_APSR();
349   ASSERT_TRUE((result & APSR_Z_Msk) == APSR_Z_Msk);
350   ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
351
352   Rm = 5;
353   SUBS(Rm, Rm, Rm);
354   result  = __get_xPSR();
355   ASSERT_TRUE((result & xPSR_Z_Msk) == xPSR_Z_Msk);
356   ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
357
358   // Check overflow flag
359   Rm = 5;
360   Rn = INT32_MAX;
361   ADDS(Rm, Rm, Rn);
362   result  = __get_APSR();
363   ASSERT_TRUE((result & APSR_V_Msk) == APSR_V_Msk);
364
365   Rm = 5;
366   Rn = INT32_MAX;
367   ADDS(Rm, Rm, Rn);
368   result  = __get_xPSR();
369   ASSERT_TRUE((result & xPSR_V_Msk) == xPSR_V_Msk);
370 }
371
372 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
373 /**
374 \brief Test case: TC_CoreFunc_PSP
375 \details
376 - Check if __get_PSP and __set_PSP intrinsic can be used to manipulate process stack pointer.
377 */
378 void TC_CoreFunc_PSP (void) {
379   // don't use stack for this variables
380   static uint32_t orig;
381   static uint32_t psp;
382   static uint32_t result;
383
384   orig = __get_PSP();
385
386   psp = orig + 0x12345678U;
387   __set_PSP(psp);
388
389   result = __get_PSP();
390
391   __set_PSP(orig);
392
393   ASSERT_TRUE(result == psp);
394 }
395
396 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
397 /**
398 \brief Test case: TC_CoreFunc_MSP
399 \details
400 - Check if __get_MSP and __set_MSP intrinsic can be used to manipulate main stack pointer.
401 */
402 void TC_CoreFunc_MSP (void) {
403   // don't use stack for this variables
404   static uint32_t orig;
405   static uint32_t msp;
406   static uint32_t result;
407   static uint32_t ctrl;
408
409   ctrl = __get_CONTROL();
410   orig = __get_MSP();
411
412   __set_PSP(orig);
413   __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
414
415   msp = orig + 0x12345678U;
416   __set_MSP(msp);
417
418   result = __get_MSP();
419
420   __set_MSP(orig);
421
422   __set_CONTROL(ctrl);
423
424   ASSERT_TRUE(result == msp);
425 }
426
427 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
428 /**
429 \brief Test case: TC_CoreFunc_PSPLIM
430 \details
431 - Check if __get_PSPLIM and __set_PSPLIM intrinsic can be used to manipulate process stack pointer limit.
432 */
433 void TC_CoreFunc_PSPLIM (void) {
434 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
435      (defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1)) || \
436      (defined (__ARM_ARCH_8M_BASE__   ) && (__ARM_ARCH_8M_BASE__   == 1))    )
437   // don't use stack for this variables
438   static uint32_t orig;
439   static uint32_t psplim;
440   static uint32_t result;
441
442   orig = __get_PSPLIM();
443
444   psplim = orig + 0x12345678U;
445   __set_PSPLIM(psplim);
446
447   result = __get_PSPLIM();
448
449   __set_PSPLIM(orig);
450
451 #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
452      !(defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1)) && \
453      (!defined (__ARM_FEATURE_CMSE     ) || (__ARM_FEATURE_CMSE      < 3))    )
454   // without main extensions, the non-secure PSPLIM is RAZ/WI
455   ASSERT_TRUE(result == 0U);
456 #else
457   ASSERT_TRUE(result == psplim);
458 #endif
459
460 #endif
461 }
462
463 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
464 /**
465 \brief Test case: TC_CoreFunc_PSPLIM_NS
466 \details
467 - Check if __TZ_get_PSPLIM_NS and __TZ_set_PSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
468 */
469 void TC_CoreFunc_PSPLIM_NS (void) {
470 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
471      (defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1)) || \
472      (defined (__ARM_ARCH_8M_BASE__   ) && (__ARM_ARCH_8M_BASE__   == 1))    )
473
474 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
475   uint32_t orig;
476   uint32_t psplim;
477   uint32_t result;
478
479   orig = __TZ_get_PSPLIM_NS();
480
481   psplim = orig + 0x12345678U;
482   __TZ_set_PSPLIM_NS(psplim);
483
484   result = __TZ_get_PSPLIM_NS();
485
486   __TZ_set_PSPLIM_NS(orig);
487
488 #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
489      !(defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1))    )
490   // without main extensions, the non-secure PSPLIM is RAZ/WI
491   ASSERT_TRUE(result == 0U);
492 #else
493   ASSERT_TRUE(result == psplim);
494 #endif
495 #endif
496
497 #endif
498 }
499
500 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
501 /**
502 \brief Test case: TC_CoreFunc_MSPLIM
503 \details
504 - Check if __get_MSPLIM and __set_MSPLIM intrinsic can be used to manipulate main stack pointer limit.
505 */
506 void TC_CoreFunc_MSPLIM (void) {
507 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
508      (defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1)) || \
509      (defined (__ARM_ARCH_8M_BASE__   ) && (__ARM_ARCH_8M_BASE__   == 1))    )
510   // don't use stack for this variables
511   static uint32_t orig;
512   static uint32_t msplim;
513   static uint32_t result;
514   static uint32_t ctrl;
515
516   ctrl = __get_CONTROL();
517   __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
518
519   orig = __get_MSPLIM();
520
521   msplim = orig + 0x12345678U;
522   __set_MSPLIM(msplim);
523
524   result = __get_MSPLIM();
525
526   __set_MSPLIM(orig);
527
528   __set_CONTROL(ctrl);
529
530 #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
531      !(defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1)) && \
532      (!defined (__ARM_FEATURE_CMSE     ) || (__ARM_FEATURE_CMSE      < 3))    )
533   // without main extensions, the non-secure MSPLIM is RAZ/WI
534   ASSERT_TRUE(result == 0U);
535 #else
536   ASSERT_TRUE(result == msplim);
537 #endif
538
539 #endif
540 }
541
542 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
543 /**
544 \brief Test case: TC_CoreFunc_MSPLIM_NS
545 \details
546 - Check if __TZ_get_MSPLIM_NS and __TZ_set_MSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
547 */
548 void TC_CoreFunc_MSPLIM_NS (void) {
549 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
550      (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
551      (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    )
552
553 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
554   uint32_t orig;
555   uint32_t msplim;
556   uint32_t result;
557
558   orig = __TZ_get_MSPLIM_NS();
559
560   msplim = orig + 0x12345678U;
561   __TZ_set_MSPLIM_NS(msplim);
562
563   result = __TZ_get_MSPLIM_NS();
564
565   __TZ_set_MSPLIM_NS(orig);
566
567 #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
568      !(defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1))    )
569   // without main extensions, the non-secure MSPLIM is RAZ/WI
570   ASSERT_TRUE(result == 0U);
571 #else
572   ASSERT_TRUE(result == msplim);
573 #endif
574 #endif
575
576 #endif
577 }
578
579 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
580 /**
581 \brief Test case: TC_CoreFunc_PRIMASK
582 \details
583 - Check if __get_PRIMASK and __set_PRIMASK intrinsic can be used to manipulate PRIMASK.
584 - Check if __enable_irq and __disable_irq are reflected in PRIMASK.
585 */
586 void TC_CoreFunc_PRIMASK (void) {
587   uint32_t orig = __get_PRIMASK();
588
589   // toggle primask
590   uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);
591
592   __set_PRIMASK(primask);
593   uint32_t result = __get_PRIMASK();
594   ASSERT_TRUE(result == primask);
595
596   __disable_irq();
597   result = __get_PRIMASK();
598   ASSERT_TRUE((result & 0x01U) == 1U);
599
600   __enable_irq();
601   result = __get_PRIMASK();
602   ASSERT_TRUE((result & 0x01U) == 0U);
603
604   __disable_irq();
605   result = __get_PRIMASK();
606   ASSERT_TRUE((result & 0x01U) == 1U);
607
608   __set_PRIMASK(orig);
609 }
610
611 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
612 /**
613 \brief Test case: TC_CoreFunc_FAULTMASK
614 \details
615 - Check if __get_FAULTMASK and __set_FAULTMASK intrinsic can be used to manipulate FAULTMASK.
616 - Check if __enable_fault_irq and __disable_fault_irq are reflected in FAULTMASK.
617 */
618 void TC_CoreFunc_FAULTMASK (void) {
619 #if ((defined (__ARM_ARCH_7M__        ) && (__ARM_ARCH_7M__        == 1)) || \
620      (defined (__ARM_ARCH_7EM__       ) && (__ARM_ARCH_7EM__       == 1)) || \
621      (defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1)) || \
622      (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1))    )
623
624   uint32_t orig = __get_FAULTMASK();
625
626   // toggle faultmask
627   uint32_t faultmask = (orig & ~0x01U) | (~orig & 0x01U);
628
629   __set_FAULTMASK(faultmask);
630   uint32_t result = __get_FAULTMASK();
631   ASSERT_TRUE(result == faultmask);
632
633   __disable_fault_irq();
634   result = __get_FAULTMASK();
635   ASSERT_TRUE((result & 0x01U) == 1U);
636
637   __enable_fault_irq();
638   result = __get_FAULTMASK();
639   ASSERT_TRUE((result & 0x01U) == 0U);
640
641   __disable_fault_irq();
642   result = __get_FAULTMASK();
643   ASSERT_TRUE((result & 0x01U) == 1U);
644
645   __set_FAULTMASK(orig);
646
647 #endif
648 }
649
650 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
651 /**
652 \brief Test case: TC_CoreFunc_BASEPRI
653 \details
654 - Check if __get_BASEPRI and __set_BASEPRI intrinsic can be used to manipulate BASEPRI.
655 - Check if __set_BASEPRI_MAX intrinsic can be used to manipulate BASEPRI.
656 */
657 void TC_CoreFunc_BASEPRI(void) {
658 #if ((defined (__ARM_ARCH_7M__        ) && (__ARM_ARCH_7M__        == 1)) || \
659      (defined (__ARM_ARCH_7EM__       ) && (__ARM_ARCH_7EM__       == 1)) || \
660      (defined (__ARM_ARCH_8M_MAIN__   ) && (__ARM_ARCH_8M_MAIN__   == 1)) || \
661      (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1))    )
662
663   uint32_t orig = __get_BASEPRI();
664
665   uint32_t basepri = ~orig & 0x80U;
666   __set_BASEPRI(basepri);
667   uint32_t result = __get_BASEPRI();
668
669   ASSERT_TRUE(result == basepri);
670
671   __set_BASEPRI(orig);
672
673   __set_BASEPRI_MAX(basepri);
674   result = __get_BASEPRI();
675
676   ASSERT_TRUE(result == basepri);
677
678 #endif
679 }
680
681 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
682 /**
683 \brief Test case: TC_CoreFunc_FPUType
684 \details
685 Check SCB_GetFPUType returns information.
686 */
687 void TC_CoreFunc_FPUType(void) {
688   uint32_t fpuType = SCB_GetFPUType();
689 #if defined(__FPU_PRESENT) && (__FPU_PRESENT != 0)
690   ASSERT_TRUE(fpuType > 0U);
691 #else
692   ASSERT_TRUE(fpuType  == 0U);
693 #endif
694 }
695
696 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
697 /**
698 \brief Test case: TC_CoreFunc_FPSCR
699 \details
700 - Check if __get_FPSCR and __set_FPSCR intrinsics can be used
701 */
702 void TC_CoreFunc_FPSCR(void) {
703   uint32_t fpscr = __get_FPSCR();
704   __ISB();
705   __DSB();
706
707   __set_FPSCR(~fpscr);
708   __ISB();
709   __DSB();
710
711   uint32_t result = __get_FPSCR();
712
713   __set_FPSCR(fpscr);
714
715 #if (defined (__FPU_USED   ) && (__FPU_USED    == 1U))
716   ASSERT_TRUE(result != fpscr);
717 #else
718   ASSERT_TRUE(result == 0U);
719 #endif
720 }