]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Source/CV_CoreFunc.c
CoreValidation: Fixed TC_CoreFunc_IRQVect missing external declaration to ROM vector...
[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 - 2019 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) {}
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) {}
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) {}
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) {}
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(512);
199
200   memcpy(vectors, __VECTOR_TABLE, sizeof(__VECTOR_TABLE));
201   
202   const uint32_t orig_vtor = SCB->VTOR;
203   const uint32_t vtor = ((uint32_t)vectors) & SCB_VTOR_TBLOFF_Msk;
204   SCB->VTOR = vtor;
205
206   ASSERT_TRUE(vtor == SCB->VTOR);
207
208   /* check exception vectors */
209   extern void HardFault_Handler(void);
210   extern void SVC_Handler(void);
211   extern void PendSV_Handler(void);
212   extern void SysTick_Handler(void);
213
214   ASSERT_TRUE(NVIC_GetVector(HardFault_IRQn) == (uint32_t)HardFault_Handler);
215   ASSERT_TRUE(NVIC_GetVector(SVCall_IRQn) == (uint32_t)SVC_Handler);
216   ASSERT_TRUE(NVIC_GetVector(PendSV_IRQn) == (uint32_t)PendSV_Handler);
217   ASSERT_TRUE(NVIC_GetVector(SysTick_IRQn) == (uint32_t)SysTick_Handler);
218
219   /* reconfigure WDT IRQ vector */
220   extern void Interrupt0_Handler(void);
221
222   const uint32_t wdtvec = NVIC_GetVector(Interrupt0_IRQn);
223   ASSERT_TRUE(wdtvec == (uint32_t)Interrupt0_Handler);
224
225   NVIC_SetVector(Interrupt0_IRQn, wdtvec + 32U);
226
227   ASSERT_TRUE(NVIC_GetVector(Interrupt0_IRQn) == (wdtvec + 32U));
228
229   /* restore vector table */
230   SCB->VTOR = orig_vtor;
231 #endif
232 }
233
234 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
235 /**
236 \brief Test case: TC_CoreFunc_GetCtrl
237 \details
238 - Check if __set_CONTROL and __get_CONTROL() sets/gets control register
239 */
240 void TC_CoreFunc_Control (void) {
241   // don't use stack for this variables
242   static uint32_t orig;
243   static uint32_t ctrl;
244   static uint32_t result;
245
246   orig = __get_CONTROL();
247   ctrl = orig;
248   result = UINT32_MAX;
249
250 #ifdef CONTROL_SPSEL_Msk
251   // SPSEL set to 0 (MSP)
252   ASSERT_TRUE((ctrl & CONTROL_SPSEL_Msk) == 0U);
253
254   // SPSEL set to 1 (PSP)
255   ctrl |= CONTROL_SPSEL_Msk;
256
257   // Move MSP to PSP
258   __set_PSP(__get_MSP());
259 #endif
260
261   __set_CONTROL(ctrl);
262   __ISB();
263
264   result = __get_CONTROL();
265
266   __set_CONTROL(orig);
267   __ISB();
268
269   ASSERT_TRUE(result == ctrl);
270   ASSERT_TRUE(__get_CONTROL() == orig);
271 }
272
273 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
274 /**
275 \brief Test case: TC_CoreFunc_IPSR
276 \details
277 - Check if __get_IPSR intrinsic is available
278 - Check if __get_xPSR intrinsic is available
279 - Result differentiates between thread and exception modes
280 */
281 void TC_CoreFunc_IPSR (void) {
282   uint32_t result = __get_IPSR();
283   ASSERT_TRUE(result == 0U); // Thread Mode
284
285   result = __get_xPSR();
286   ASSERT_TRUE((result & xPSR_ISR_Msk) == 0U); // Thread Mode
287
288   TST_IRQHandler = TC_CoreFunc_IPSR_IRQHandler;
289   irqIPSR = 0U;
290   irqXPSR = 0U;
291
292   NVIC_ClearPendingIRQ(Interrupt0_IRQn);
293   NVIC_EnableIRQ(Interrupt0_IRQn);
294   __enable_irq();
295
296   NVIC_SetPendingIRQ(Interrupt0_IRQn);
297   for(uint32_t i = 10U; i > 0U; --i) {}
298
299   __disable_irq();
300   NVIC_DisableIRQ(Interrupt0_IRQn);
301
302   ASSERT_TRUE(irqIPSR != 0U); // Exception Mode
303   ASSERT_TRUE((irqXPSR & xPSR_ISR_Msk) != 0U); // Exception Mode
304 }
305
306 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
307
308 #if defined(__CC_ARM)
309 #define SUBS(Rd, Rm, Rn) __ASM volatile("SUBS " # Rd ", " # Rm ", " # Rn)
310 #define ADDS(Rd, Rm, Rn) __ASM volatile("ADDS " # Rd ", " # Rm ", " # Rn)
311 #elif defined( __GNUC__ )  && (!defined(__ARMCC_VERSION))  && (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
312 #define SUBS(Rd, Rm, Rn) __ASM volatile("SUB %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
313 #define ADDS(Rd, Rm, Rn) __ASM volatile("ADD %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
314 #elif defined(_lint)
315 //lint -save -e(9026) allow function-like macro
316 #define SUBS(Rd, Rm, Rn) ((Rd) = (Rm) - (Rn))
317 #define ADDS(Rd, Rm, Rn) ((Rd) = (Rm) + (Rn))
318 //lint -restore
319 #else
320 #define SUBS(Rd, Rm, Rn) __ASM volatile("SUBS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
321 #define ADDS(Rd, Rm, Rn) __ASM volatile("ADDS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
322 #endif
323
324 /**
325 \brief Test case: TC_CoreFunc_APSR
326 \details
327 - Check if __get_APSR intrinsic is available
328 - Check if __get_xPSR intrinsic is available
329 - Check negative, zero and overflow flags
330 */
331 void TC_CoreFunc_APSR (void) {
332   volatile uint32_t result;
333   //lint -esym(838, Rm) unused values
334   //lint -esym(438, Rm) unused values
335
336   // Check negative flag
337   volatile int32_t Rm = 5;
338   volatile int32_t Rn = 7;
339   SUBS(Rm, Rm, Rn);
340   result  = __get_APSR();
341   ASSERT_TRUE((result & APSR_N_Msk) == APSR_N_Msk);
342
343   Rm = 5;
344   Rn = 7;
345   SUBS(Rm, Rm, Rn);
346   result  = __get_xPSR();
347   ASSERT_TRUE((result & xPSR_N_Msk) == xPSR_N_Msk);
348
349   // Check zero and compare flag
350   Rm = 5;
351   SUBS(Rm, Rm, Rm);
352   result  = __get_APSR();
353   ASSERT_TRUE((result & APSR_Z_Msk) == APSR_Z_Msk);
354   ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
355
356   Rm = 5;
357   SUBS(Rm, Rm, Rm);
358   result  = __get_xPSR();
359   ASSERT_TRUE((result & xPSR_Z_Msk) == xPSR_Z_Msk);
360   ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
361
362   // Check overflow flag
363   Rm = 5;
364   Rn = INT32_MAX;
365   ADDS(Rm, Rm, Rn);
366   result  = __get_APSR();
367   ASSERT_TRUE((result & APSR_V_Msk) == APSR_V_Msk);
368
369   Rm = 5;
370   Rn = INT32_MAX;
371   ADDS(Rm, Rm, Rn);
372   result  = __get_xPSR();
373   ASSERT_TRUE((result & xPSR_V_Msk) == xPSR_V_Msk);
374 }
375
376 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
377 /**
378 \brief Test case: TC_CoreFunc_PSP
379 \details
380 - Check if __get_PSP and __set_PSP intrinsic can be used to manipulate process stack pointer.
381 */
382 void TC_CoreFunc_PSP (void) {
383   // don't use stack for this variables
384   static uint32_t orig;
385   static uint32_t psp;
386   static uint32_t result;
387
388   orig = __get_PSP();
389
390   psp = orig + 0x12345678U;
391   __set_PSP(psp);
392
393   result = __get_PSP();
394
395   __set_PSP(orig);
396
397   ASSERT_TRUE(result == psp);
398 }
399
400 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
401 /**
402 \brief Test case: TC_CoreFunc_MSP
403 \details
404 - Check if __get_MSP and __set_MSP intrinsic can be used to manipulate main stack pointer.
405 */
406 void TC_CoreFunc_MSP (void) {
407   // don't use stack for this variables
408   static uint32_t orig;
409   static uint32_t msp;
410   static uint32_t result;
411   static uint32_t ctrl;
412
413   ctrl = __get_CONTROL();
414   orig = __get_MSP();
415
416   __set_PSP(orig);
417   __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
418
419   msp = orig + 0x12345678U;
420   __set_MSP(msp);
421
422   result = __get_MSP();
423
424   __set_MSP(orig);
425
426   __set_CONTROL(ctrl);
427
428   ASSERT_TRUE(result == msp);
429 }
430
431 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
432 /**
433 \brief Test case: TC_CoreFunc_PSPLIM
434 \details
435 - Check if __get_PSPLIM and __set_PSPLIM intrinsic can be used to manipulate process stack pointer limit.
436 */
437 void TC_CoreFunc_PSPLIM (void) {
438 #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
439      (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    )
440   // don't use stack for this variables
441   static uint32_t orig;
442   static uint32_t psplim;
443   static uint32_t result;
444
445   orig = __get_PSPLIM();
446
447   psplim = orig + 0x12345678U;
448   __set_PSPLIM(psplim);
449
450   result = __get_PSPLIM();
451
452   __set_PSPLIM(orig);
453
454 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
455      (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
456   // without main extensions, the non-secure PSPLIM is RAZ/WI
457   ASSERT_TRUE(result == 0U);
458 #else
459   ASSERT_TRUE(result == psplim);
460 #endif
461
462 #endif
463 }
464
465 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
466 /**
467 \brief Test case: TC_CoreFunc_PSPLIM_NS
468 \details
469 - Check if __TZ_get_PSPLIM_NS and __TZ_set_PSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
470 */
471 void TC_CoreFunc_PSPLIM_NS (void) {
472 #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
473      (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    )
474
475 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
476   uint32_t orig;
477   uint32_t psplim;
478   uint32_t result;
479
480   orig = __TZ_get_PSPLIM_NS();
481
482   psplim = orig + 0x12345678U;
483   __TZ_set_PSPLIM_NS(psplim);
484
485   result = __TZ_get_PSPLIM_NS();
486
487   __TZ_set_PSPLIM_NS(orig);
488
489 #if (!(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_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
508      (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    )
509   // don't use stack for this variables
510   static uint32_t orig;
511   static uint32_t msplim;
512   static uint32_t result;
513   static uint32_t ctrl;
514
515   ctrl = __get_CONTROL();
516   __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
517
518   orig = __get_MSPLIM();
519
520   msplim = orig + 0x12345678U;
521   __set_MSPLIM(msplim);
522
523   result = __get_MSPLIM();
524
525   __set_MSPLIM(orig);
526
527   __set_CONTROL(ctrl);
528
529 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
530      (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
531   // without main extensions, the non-secure MSPLIM is RAZ/WI
532   ASSERT_TRUE(result == 0U);
533 #else
534   ASSERT_TRUE(result == msplim);
535 #endif
536
537 #endif
538 }
539
540 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
541 /**
542 \brief Test case: TC_CoreFunc_MSPLIM_NS
543 \details
544 - Check if __TZ_get_MSPLIM_NS and __TZ_set_MSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
545 */
546 void TC_CoreFunc_MSPLIM_NS (void) {
547 #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
548      (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    )
549
550 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
551   uint32_t orig;
552   uint32_t msplim;
553   uint32_t result;
554
555   orig = __TZ_get_MSPLIM_NS();
556
557   msplim = orig + 0x12345678U;
558   __TZ_set_MSPLIM_NS(msplim);
559
560   result = __TZ_get_MSPLIM_NS();
561
562   __TZ_set_MSPLIM_NS(orig);
563
564 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
565   // without main extensions, the non-secure MSPLIM is RAZ/WI
566   ASSERT_TRUE(result == 0U);
567 #else
568   ASSERT_TRUE(result == msplim);
569 #endif
570 #endif
571
572 #endif
573 }
574
575 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
576 /**
577 \brief Test case: TC_CoreFunc_PRIMASK
578 \details
579 - Check if __get_PRIMASK and __set_PRIMASK intrinsic can be used to manipulate PRIMASK.
580 - Check if __enable_irq and __disable_irq are reflected in PRIMASK.
581 */
582 void TC_CoreFunc_PRIMASK (void) {
583   uint32_t orig = __get_PRIMASK();
584
585   // toggle primask
586   uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);
587
588   __set_PRIMASK(primask);
589   uint32_t result = __get_PRIMASK();
590
591   ASSERT_TRUE(result == primask);
592
593   __disable_irq();
594   result = __get_PRIMASK();
595   ASSERT_TRUE((result & 0x01U) == 1U);
596
597   __enable_irq();
598   result = __get_PRIMASK();
599   ASSERT_TRUE((result & 0x01U) == 0U);
600
601   __disable_irq();
602   result = __get_PRIMASK();
603   ASSERT_TRUE((result & 0x01U) == 1U);
604
605   __set_PRIMASK(orig);
606 }
607
608 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
609 /**
610 \brief Test case: TC_CoreFunc_FAULTMASK
611 \details
612 - Check if __get_FAULTMASK and __set_FAULTMASK intrinsic can be used to manipulate FAULTMASK.
613 - Check if __enable_fault_irq and __disable_fault_irq are reflected in FAULTMASK.
614 */
615 void TC_CoreFunc_FAULTMASK (void) {
616 #if ((defined (__ARM_ARCH_7M__      ) && (__ARM_ARCH_7M__      == 1)) || \
617      (defined (__ARM_ARCH_7EM__     ) && (__ARM_ARCH_7EM__     == 1)) || \
618      (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))    )
619
620   uint32_t orig = __get_FAULTMASK();
621
622   // toggle faultmask
623   uint32_t faultmask = (orig & ~0x01U) | (~orig & 0x01U);
624
625   __set_FAULTMASK(faultmask);
626   uint32_t result = __get_FAULTMASK();
627
628   ASSERT_TRUE(result == faultmask);
629
630   __disable_fault_irq();
631   result = __get_FAULTMASK();
632   ASSERT_TRUE((result & 0x01U) == 1U);
633
634   __enable_fault_irq();
635   result = __get_FAULTMASK();
636   ASSERT_TRUE((result & 0x01U) == 0U);
637
638   __disable_fault_irq();
639   result = __get_FAULTMASK();
640   ASSERT_TRUE((result & 0x01U) == 1U);
641
642   __set_FAULTMASK(orig);
643
644 #endif
645 }
646
647 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
648 /**
649 \brief Test case: TC_CoreFunc_BASEPRI
650 \details
651 - Check if __get_BASEPRI and __set_BASEPRI intrinsic can be used to manipulate BASEPRI.
652 - Check if __set_BASEPRI_MAX intrinsic can be used to manipulate BASEPRI.
653 */
654 void TC_CoreFunc_BASEPRI(void) {
655 #if ((defined (__ARM_ARCH_7M__      ) && (__ARM_ARCH_7M__      == 1)) || \
656      (defined (__ARM_ARCH_7EM__     ) && (__ARM_ARCH_7EM__     == 1)) || \
657      (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))    )
658
659   uint32_t orig = __get_BASEPRI();
660
661   uint32_t basepri = ~orig & 0x80U;
662   __set_BASEPRI(basepri);
663   uint32_t result = __get_BASEPRI();
664
665   ASSERT_TRUE(result == basepri);
666
667   __set_BASEPRI(orig);
668
669   __set_BASEPRI_MAX(basepri);
670   result = __get_BASEPRI();
671
672   ASSERT_TRUE(result == basepri);
673
674 #endif
675 }
676
677 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
678 /**
679 \brief Test case: TC_CoreFunc_FPUType
680 \details
681 Check SCB_GetFPUType returns information.
682 */
683 void TC_CoreFunc_FPUType(void) {
684   uint32_t fpuType = SCB_GetFPUType();
685 #if defined(__FPU_PRESENT) && (__FPU_PRESENT != 0)
686   ASSERT_TRUE(fpuType > 0U);
687 #else
688   ASSERT_TRUE(fpuType  == 0U);
689 #endif
690 }
691
692 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
693 /**
694 \brief Test case: TC_CoreFunc_FPSCR
695 \details
696 - Check if __get_FPSCR and __set_FPSCR intrinsics can be used
697 */
698 void TC_CoreFunc_FPSCR(void) {
699   uint32_t fpscr = __get_FPSCR();
700   __ISB();
701   __DSB();
702
703   __set_FPSCR(~fpscr);
704   __ISB();
705   __DSB();
706
707   uint32_t result = __get_FPSCR();
708
709   __set_FPSCR(fpscr);
710
711 #if (defined (__FPU_USED   ) && (__FPU_USED    == 1U))
712   ASSERT_TRUE(result != fpscr);
713 #else
714   ASSERT_TRUE(result == 0U);
715 #endif
716 }