1 /*-----------------------------------------------------------------------------
3 * Purpose: CMSIS CORE validation tests implementation
4 *-----------------------------------------------------------------------------
5 * Copyright (c) 2017 ARM Limited. All rights reserved.
6 *----------------------------------------------------------------------------*/
8 #include "CV_Framework.h"
11 /*-----------------------------------------------------------------------------
13 *----------------------------------------------------------------------------*/
15 static volatile uint32_t irqTaken = 0U;
16 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
17 static volatile uint32_t irqActive = 0U;
20 static void TC_CoreFunc_EnDisIRQIRQHandler(void) {
22 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
23 irqActive = NVIC_GetActive(WDT_IRQn);
27 static volatile uint32_t irqIPSR = 0U;
28 static volatile uint32_t irqXPSR = 0U;
30 static void TC_CoreFunc_IPSR_IRQHandler(void) {
31 irqIPSR = __get_IPSR();
32 irqXPSR = __get_xPSR();
35 /*-----------------------------------------------------------------------------
37 *----------------------------------------------------------------------------*/
39 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
41 \brief Test case: TC_CoreFunc_EnDisIRQ
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+)
49 void TC_CoreFunc_EnDisIRQ (void)
51 // Globally disable all interrupt servicing
54 // Enable the interrupt
55 NVIC_EnableIRQ(WDT_IRQn);
56 ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) != 0U);
58 // Clear its pending state
59 NVIC_ClearPendingIRQ(WDT_IRQn);
60 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
62 // Register test interrupt handler.
63 TST_IRQHandler = TC_CoreFunc_EnDisIRQIRQHandler;
65 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
66 irqActive = UINT32_MAX;
69 // Set the interrupt pending state
70 NVIC_SetPendingIRQ(WDT_IRQn);
71 for(uint32_t i = 10U; i > 0U; --i) {}
73 // Interrupt is not taken
74 ASSERT_TRUE(irqTaken == 0U);
75 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U);
76 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
77 ASSERT_TRUE(NVIC_GetActive(WDT_IRQn) == 0U);
80 // Globally enable interrupt servicing
83 for(uint32_t i = 10U; i > 0U; --i) {}
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(WDT_IRQn) == 0U);
92 // Interrupt it not pending anymore.
93 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
96 NVIC_DisableIRQ(WDT_IRQn);
97 ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) == 0U);
99 // Set interrupt pending
100 NVIC_SetPendingIRQ(WDT_IRQn);
101 for(uint32_t i = 10U; i > 0U; --i) {}
103 // Interrupt is not taken again
104 ASSERT_TRUE(irqTaken == 1U);
105 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U);
107 // Clear interrupt pending
108 NVIC_ClearPendingIRQ(WDT_IRQn);
109 for(uint32_t i = 10U; i > 0U; --i) {}
111 // Interrupt it not pending anymore.
112 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
114 // Globally disable interrupt servicing
118 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
120 \brief Test case: TC_CoreFunc_GetCtrl
122 - Check if __set_CONTROL and __get_CONTROL() sets/gets control register
124 void TC_CoreFunc_Control (void) {
125 // don't use stack for this variables
126 static uint32_t orig;
127 static uint32_t ctrl;
128 static uint32_t result;
130 orig = __get_CONTROL();
134 #ifdef CONTROL_SPSEL_Msk
136 ctrl = (ctrl & ~CONTROL_SPSEL_Msk) | (~ctrl & CONTROL_SPSEL_Msk);
142 result = __get_CONTROL();
147 ASSERT_TRUE(result == ctrl);
148 ASSERT_TRUE(__get_CONTROL() == orig);
151 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
153 \brief Test case: TC_CoreFunc_IPSR
155 - Check if __get_IPSR intrinsic is available
156 - Check if __get_xPSR intrinsic is available
157 - Result differentiates between thread and exception modes
159 void TC_CoreFunc_IPSR (void) {
160 uint32_t result = __get_IPSR();
161 ASSERT_TRUE(result == 0U); // Thread Mode
163 result = __get_xPSR();
164 ASSERT_TRUE((result & xPSR_ISR_Msk) == 0U); // Thread Mode
166 TST_IRQHandler = TC_CoreFunc_IPSR_IRQHandler;
170 NVIC_ClearPendingIRQ(WDT_IRQn);
171 NVIC_EnableIRQ(WDT_IRQn);
174 NVIC_SetPendingIRQ(WDT_IRQn);
175 for(uint32_t i = 10U; i > 0U; --i) {}
178 NVIC_DisableIRQ(WDT_IRQn);
180 ASSERT_TRUE(irqIPSR != 0U); // Exception Mode
181 ASSERT_TRUE((irqXPSR & xPSR_ISR_Msk) != 0U); // Exception Mode
184 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
186 #if defined(__CC_ARM)
187 #define SUBS(Rd, Rm, Rn) __ASM("SUBS " # Rd ", " # Rm ", " # Rn)
188 #define ADDS(Rd, Rm, Rn) __ASM("ADDS " # Rd ", " # Rm ", " # Rn)
189 #elif defined( __GNUC__ ) && (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
190 #define SUBS(Rd, Rm, Rn) __ASM("SUB %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
191 #define ADDS(Rd, Rm, Rn) __ASM("ADD %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
193 //lint -save -e(9026) allow function-like macro
194 #define SUBS(Rd, Rm, Rn) ((Rd) = (Rm) - (Rn))
195 #define ADDS(Rd, Rm, Rn) ((Rd) = (Rm) + (Rn))
198 #define SUBS(Rd, Rm, Rn) __ASM("SUBS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
199 #define ADDS(Rd, Rm, Rn) __ASM("ADDS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
203 \brief Test case: TC_CoreFunc_APSR
205 - Check if __get_APSR intrinsic is available
206 - Check if __get_xPSR intrinsic is available
207 - Check negative, zero and overflow flags
209 void TC_CoreFunc_APSR (void) {
211 //lint -esym(838, Rm) unused values
212 //lint -esym(438, Rm) unused values
214 // Check negative flag
218 result = __get_APSR();
219 ASSERT_TRUE((result & APSR_N_Msk) == APSR_N_Msk);
224 result = __get_xPSR();
225 ASSERT_TRUE((result & xPSR_N_Msk) == xPSR_N_Msk);
227 // Check zero and compare flag
230 result = __get_APSR();
231 ASSERT_TRUE((result & APSR_Z_Msk) == APSR_Z_Msk);
232 ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
236 result = __get_xPSR();
237 ASSERT_TRUE((result & xPSR_Z_Msk) == xPSR_Z_Msk);
238 ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
240 // Check overflow flag
244 result = __get_APSR();
245 ASSERT_TRUE((result & APSR_V_Msk) == APSR_V_Msk);
250 result = __get_xPSR();
251 ASSERT_TRUE((result & xPSR_V_Msk) == xPSR_V_Msk);
254 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
256 \brief Test case: TC_CoreFunc_PSP
258 - Check if __get_PSP and __set_PSP intrinsic can be used to manipulate process stack pointer.
260 void TC_CoreFunc_PSP (void) {
261 // don't use stack for this variables
262 static uint32_t orig;
264 static uint32_t result;
268 psp = orig + 0x12345678U;
271 result = __get_PSP();
275 ASSERT_TRUE(result == psp);
278 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
280 \brief Test case: TC_CoreFunc_MSP
282 - Check if __get_MSP and __set_MSP intrinsic can be used to manipulate main stack pointer.
284 void TC_CoreFunc_MSP (void) {
285 // don't use stack for this variables
286 static uint32_t orig;
288 static uint32_t result;
289 static uint32_t ctrl;
291 ctrl = __get_CONTROL();
292 __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
296 msp = orig + 0x12345678U;
299 result = __get_MSP();
305 ASSERT_TRUE(result == msp);
308 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
309 #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
310 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
313 \brief Test case: TC_CoreFunc_PSPLIM
315 - Check if __get_PSPLIM and __set_PSPLIM intrinsic can be used to manipulate process stack pointer limit.
317 void TC_CoreFunc_PSPLIM (void) {
318 // don't use stack for this variables
319 static uint32_t orig;
320 static uint32_t psplim;
321 static uint32_t result;
323 orig = __get_PSPLIM();
325 psplim = orig + 0x12345678U;
326 __set_PSPLIM(psplim);
328 result = __get_PSPLIM();
332 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
333 (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
334 // without main extensions, the non-secure PSPLIM is RAZ/WI
335 ASSERT_TRUE(result == 0U);
337 ASSERT_TRUE(result == psplim);
341 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
343 \brief Test case: TC_CoreFunc_PSPLIM_NS
345 - Check if __TZ_get_PSPLIM_NS and __TZ_set_PSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
347 void TC_CoreFunc_PSPLIM_NS (void) {
348 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
353 orig = __TZ_get_PSPLIM_NS();
355 psplim = orig + 0x12345678U;
356 __TZ_set_PSPLIM_NS(psplim);
358 result = __TZ_get_PSPLIM_NS();
360 __TZ_set_PSPLIM_NS(orig);
362 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
363 // without main extensions, the non-secure PSPLIM is RAZ/WI
364 ASSERT_TRUE(result == 0U);
366 ASSERT_TRUE(result == psplim);
371 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
373 \brief Test case: TC_CoreFunc_MSPLIM
375 - Check if __get_MSPLIM and __set_MSPLIM intrinsic can be used to manipulate main stack pointer limit.
377 void TC_CoreFunc_MSPLIM (void) {
378 // don't use stack for this variables
379 static uint32_t orig;
380 static uint32_t msplim;
381 static uint32_t result;
382 static uint32_t ctrl;
384 ctrl = __get_CONTROL();
385 __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
387 orig = __get_MSPLIM();
389 msplim = orig + 0x12345678U;
390 __set_MSPLIM(msplim);
392 result = __get_MSPLIM();
398 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
399 (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
400 // without main extensions, the non-secure MSPLIM is RAZ/WI
401 ASSERT_TRUE(result == 0U);
403 ASSERT_TRUE(result == msplim);
407 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
409 \brief Test case: TC_CoreFunc_MSPLIM_NS
411 - Check if __TZ_get_MSPLIM_NS and __TZ_set_MSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
413 void TC_CoreFunc_MSPLIM_NS (void) {
414 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
419 orig = __TZ_get_MSPLIM_NS();
421 msplim = orig + 0x12345678U;
422 __TZ_set_MSPLIM_NS(msplim);
424 result = __TZ_get_MSPLIM_NS();
426 __TZ_set_MSPLIM_NS(orig);
428 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
429 // without main extensions, the non-secure MSPLIM is RAZ/WI
430 ASSERT_TRUE(result == 0U);
432 ASSERT_TRUE(result == msplim);
439 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
441 \brief Test case: TC_CoreFunc_PRIMASK
443 - Check if __get_PRIMASK and __set_PRIMASK intrinsic can be used to manipulate PRIMASK.
444 - Check if __enable_irq and __disable_irq are reflected in PRIMASK.
446 void TC_CoreFunc_PRIMASK (void) {
447 uint32_t orig = __get_PRIMASK();
450 uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);
452 __set_PRIMASK(primask);
453 uint32_t result = __get_PRIMASK();
455 ASSERT_TRUE(result == primask);
458 result = __get_PRIMASK();
459 ASSERT_TRUE((result & 0x01U) == 1U);
462 result = __get_PRIMASK();
463 ASSERT_TRUE((result & 0x01U) == 0U);
466 result = __get_PRIMASK();
467 ASSERT_TRUE((result & 0x01U) == 1U);
472 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
473 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
474 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
475 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
478 \brief Test case: TC_CoreFunc_FAULTMASK
480 - Check if __get_FAULTMASK and __set_FAULTMASK intrinsic can be used to manipulate FAULTMASK.
481 - Check if __enable_fault_irq and __disable_fault_irq are reflected in FAULTMASK.
483 void TC_CoreFunc_FAULTMASK (void) {
484 uint32_t orig = __get_FAULTMASK();
487 uint32_t faultmask = (orig & ~0x01U) | (~orig & 0x01U);
489 __set_FAULTMASK(faultmask);
490 uint32_t result = __get_FAULTMASK();
492 ASSERT_TRUE(result == faultmask);
494 __disable_fault_irq();
495 result = __get_FAULTMASK();
496 ASSERT_TRUE((result & 0x01U) == 1U);
498 __enable_fault_irq();
499 result = __get_FAULTMASK();
500 ASSERT_TRUE((result & 0x01U) == 0U);
502 __disable_fault_irq();
503 result = __get_FAULTMASK();
504 ASSERT_TRUE((result & 0x01U) == 1U);
506 __set_FAULTMASK(orig);
509 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
511 \brief Test case: TC_CoreFunc_BASEPRI
513 - Check if __get_BASEPRI and __set_BASEPRI intrinsic can be used to manipulate BASEPRI.
514 - Check if __set_BASEPRI_MAX intrinsic can be used to manipulate BASEPRI.
516 void TC_CoreFunc_BASEPRI(void) {
517 uint32_t orig = __get_BASEPRI();
519 uint32_t basepri = ~orig & 0x80U;
520 __set_BASEPRI(basepri);
521 uint32_t result = __get_BASEPRI();
523 ASSERT_TRUE(result == basepri);
527 __set_BASEPRI_MAX(basepri);
528 result = __get_BASEPRI();
530 ASSERT_TRUE(result == basepri);
534 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
535 #if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
536 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
539 \brief Test case: TC_CoreFunc_BASEPRI
541 - Check if __get_FPSCR and __set_FPSCR intrinsics can be used
543 void TC_CoreFunc_FPSCR(void) {
544 uint32_t fpscr = __get_FPSCR();
552 uint32_t result = __get_FPSCR();
556 #if (defined (__FPU_USED ) && (__FPU_USED == 1U))
557 ASSERT_TRUE(result != fpscr);