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 static volatile uint32_t irqActive = 0U;
18 static void TC_CoreFunc_EnDisIRQIRQHandler(void) {
20 irqActive = NVIC_GetActive(WDT_IRQn);
23 static volatile uint32_t irqIPSR = 0U;
24 static volatile uint32_t irqXPSR = 0U;
26 static void TC_CoreFunc_IPSR_IRQHandler(void) {
27 irqIPSR = __get_IPSR();
28 irqXPSR = __get_xPSR();
31 /*-----------------------------------------------------------------------------
33 *----------------------------------------------------------------------------*/
35 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
37 \brief Test case: TC_CoreFunc_EnDisIRQ
39 Check expected behavior of interrupt related control functions:
40 - __disable_irq() and __enable_irq()
41 - NVIC_EnableIRQ, NVIC_DisableIRQ, and NVIC_GetEnableIRQ
42 - NVIC_SetPendingIRQ, NVIC_ClearPendingIRQ, and NVIC_GetPendingIRQ
45 void TC_CoreFunc_EnDisIRQ (void)
47 // Globally disable all interrupt servicing
50 // Enable the interrupt
51 NVIC_EnableIRQ(WDT_IRQn);
52 ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) != 0U);
54 // Clear its pending state
55 NVIC_ClearPendingIRQ(WDT_IRQn);
56 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
58 // Register test interrupt handler.
59 TST_IRQHandler = TC_CoreFunc_EnDisIRQIRQHandler;
61 irqActive = UINT32_MAX;
63 // Set the interrupt pending state
64 NVIC_SetPendingIRQ(WDT_IRQn);
65 for(uint32_t i = 10U; i > 0U; --i) {}
67 // Interrupt is not taken
68 ASSERT_TRUE(irqTaken == 0U);
69 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U);
70 ASSERT_TRUE(NVIC_GetActive(WDT_IRQn) == 0U);
72 // Globally enable interrupt servicing
75 for(uint32_t i = 10U; i > 0U; --i) {}
77 // Interrupt was taken
78 ASSERT_TRUE(irqTaken == 1U);
79 ASSERT_TRUE(irqActive != 0U);
80 ASSERT_TRUE(NVIC_GetActive(WDT_IRQn) == 0U);
82 // Interrupt it not pending anymore.
83 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
86 NVIC_DisableIRQ(WDT_IRQn);
87 ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) == 0U);
89 // Set interrupt pending
90 NVIC_SetPendingIRQ(WDT_IRQn);
91 for(uint32_t i = 10U; i > 0U; --i) {}
93 // Interrupt is not taken again
94 ASSERT_TRUE(irqTaken == 1U);
95 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U);
97 // Clear interrupt pending
98 NVIC_ClearPendingIRQ(WDT_IRQn);
99 for(uint32_t i = 10U; i > 0U; --i) {}
101 // Interrupt it not pending anymore.
102 ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
104 // Globally disable interrupt servicing
108 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
110 \brief Test case: TC_CoreFunc_GetCtrl
112 - Check if __set_CONTROL and __get_CONTROL() sets/gets control register
114 void TC_CoreFunc_Control (void) {
115 // don't use stack for this variables
116 static uint32_t orig;
117 static uint32_t ctrl;
118 static uint32_t result;
120 orig = __get_CONTROL();
124 #ifdef CONTROL_SPSEL_Msk
126 ctrl = (ctrl & ~CONTROL_SPSEL_Msk) | (~ctrl & CONTROL_SPSEL_Msk);
132 result = __get_CONTROL();
137 ASSERT_TRUE(result == ctrl);
138 ASSERT_TRUE(__get_CONTROL() == orig);
141 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
143 \brief Test case: TC_CoreFunc_IPSR
145 - Check if __get_IPSR intrinsic is available
146 - Check if __get_xPSR intrinsic is available
147 - Result differentiates between thread and exception modes
149 void TC_CoreFunc_IPSR (void) {
150 uint32_t result = __get_IPSR();
151 ASSERT_TRUE(result == 0U); // Thread Mode
153 result = __get_xPSR();
154 ASSERT_TRUE((result & xPSR_ISR_Msk) == 0U); // Thread Mode
156 TST_IRQHandler = TC_CoreFunc_IPSR_IRQHandler;
160 NVIC_ClearPendingIRQ(WDT_IRQn);
161 NVIC_EnableIRQ(WDT_IRQn);
164 NVIC_SetPendingIRQ(WDT_IRQn);
165 for(uint32_t i = 10U; i > 0U; --i) {}
168 NVIC_DisableIRQ(WDT_IRQn);
170 ASSERT_TRUE(irqIPSR != 0U); // Exception Mode
171 ASSERT_TRUE((irqXPSR & xPSR_ISR_Msk) != 0U); // Exception Mode
174 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
176 #if defined(__CC_ARM)
177 #define SUBS(Rd, Rm, Rn) __ASM("SUBS " # Rd ", " # Rm ", " # Rn)
178 #define ADDS(Rd, Rm, Rn) __ASM("ADDS " # Rd ", " # Rm ", " # Rn)
179 #elif defined( __GNUC__ ) && (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
180 #define SUBS(Rd, Rm, Rn) __ASM("SUB %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
181 #define ADDS(Rd, Rm, Rn) __ASM("ADD %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
183 //lint -save -e(9026) allow function-like macro
184 #define SUBS(Rd, Rm, Rn) ((Rd) = (Rm) - (Rn))
185 #define ADDS(Rd, Rm, Rn) ((Rd) = (Rm) + (Rn))
188 #define SUBS(Rd, Rm, Rn) __ASM("SUBS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
189 #define ADDS(Rd, Rm, Rn) __ASM("ADDS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
193 \brief Test case: TC_CoreFunc_APSR
195 - Check if __get_APSR intrinsic is available
196 - Check if __get_xPSR intrinsic is available
197 - Check negative, zero and overflow flags
199 void TC_CoreFunc_APSR (void) {
201 //lint -esym(838, Rm) unused values
202 //lint -esym(438, Rm) unused values
204 // Check negative flag
208 result = __get_APSR();
209 ASSERT_TRUE((result & APSR_N_Msk) == APSR_N_Msk);
214 result = __get_xPSR();
215 ASSERT_TRUE((result & xPSR_N_Msk) == xPSR_N_Msk);
217 // Check zero and compare flag
220 result = __get_APSR();
221 ASSERT_TRUE((result & APSR_Z_Msk) == APSR_Z_Msk);
222 ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
226 result = __get_xPSR();
227 ASSERT_TRUE((result & xPSR_Z_Msk) == xPSR_Z_Msk);
228 ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
230 // Check overflow flag
234 result = __get_APSR();
235 ASSERT_TRUE((result & APSR_V_Msk) == APSR_V_Msk);
240 result = __get_xPSR();
241 ASSERT_TRUE((result & xPSR_V_Msk) == xPSR_V_Msk);
244 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
246 \brief Test case: TC_CoreFunc_PSP
248 - Check if __get_PSP and __set_PSP intrinsic can be used to manipulate process stack pointer.
250 void TC_CoreFunc_PSP (void) {
251 // don't use stack for this variables
252 static uint32_t orig;
254 static uint32_t result;
258 psp = orig + 0x12345678U;
261 result = __get_PSP();
265 ASSERT_TRUE(result == psp);
268 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
270 \brief Test case: TC_CoreFunc_MSP
272 - Check if __get_MSP and __set_MSP intrinsic can be used to manipulate main stack pointer.
274 void TC_CoreFunc_MSP (void) {
275 // don't use stack for this variables
276 static uint32_t orig;
278 static uint32_t result;
279 static uint32_t ctrl;
281 ctrl = __get_CONTROL();
282 __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
286 msp = orig + 0x12345678U;
289 result = __get_MSP();
295 ASSERT_TRUE(result == msp);
298 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
299 #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
300 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
303 \brief Test case: TC_CoreFunc_PSPLIM
305 - Check if __get_PSPLIM and __set_PSPLIM intrinsic can be used to manipulate process stack pointer limit.
307 void TC_CoreFunc_PSPLIM (void) {
308 // don't use stack for this variables
309 static uint32_t orig;
310 static uint32_t psplim;
311 static uint32_t result;
313 orig = __get_PSPLIM();
315 psplim = orig + 0x12345678U;
316 __set_PSPLIM(psplim);
318 result = __get_PSPLIM();
322 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
323 (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
324 // without main extensions, the non-secure PSPLIM is RAZ/WI
325 ASSERT_TRUE(result == 0U);
327 ASSERT_TRUE(result == psplim);
331 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
333 \brief Test case: TC_CoreFunc_PSPLIM_NS
335 - Check if __TZ_get_PSPLIM_NS and __TZ_set_PSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
337 void TC_CoreFunc_PSPLIM_NS (void) {
338 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
343 orig = __TZ_get_PSPLIM_NS();
345 psplim = orig + 0x12345678U;
346 __TZ_set_PSPLIM_NS(psplim);
348 result = __TZ_get_PSPLIM_NS();
350 __TZ_set_PSPLIM_NS(orig);
352 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
353 // without main extensions, the non-secure PSPLIM is RAZ/WI
354 ASSERT_TRUE(result == 0U);
356 ASSERT_TRUE(result == psplim);
361 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
363 \brief Test case: TC_CoreFunc_MSPLIM
365 - Check if __get_MSPLIM and __set_MSPLIM intrinsic can be used to manipulate main stack pointer limit.
367 void TC_CoreFunc_MSPLIM (void) {
368 // don't use stack for this variables
369 static uint32_t orig;
370 static uint32_t msplim;
371 static uint32_t result;
372 static uint32_t ctrl;
374 ctrl = __get_CONTROL();
375 __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
377 orig = __get_MSPLIM();
379 msplim = orig + 0x12345678U;
380 __set_MSPLIM(msplim);
382 result = __get_MSPLIM();
388 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
389 (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
390 // without main extensions, the non-secure MSPLIM is RAZ/WI
391 ASSERT_TRUE(result == 0U);
393 ASSERT_TRUE(result == msplim);
397 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
399 \brief Test case: TC_CoreFunc_MSPLIM_NS
401 - Check if __TZ_get_MSPLIM_NS and __TZ_set_MSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
403 void TC_CoreFunc_MSPLIM_NS (void) {
404 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
409 orig = __TZ_get_MSPLIM_NS();
411 msplim = orig + 0x12345678U;
412 __TZ_set_MSPLIM_NS(msplim);
414 result = __TZ_get_MSPLIM_NS();
416 __TZ_set_MSPLIM_NS(orig);
418 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
419 // without main extensions, the non-secure MSPLIM is RAZ/WI
420 ASSERT_TRUE(result == 0U);
422 ASSERT_TRUE(result == msplim);
429 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
431 \brief Test case: TC_CoreFunc_PRIMASK
433 - Check if __get_PRIMASK and __set_PRIMASK intrinsic can be used to manipulate PRIMASK.
434 - Check if __enable_irq and __disable_irq are reflected in PRIMASK.
436 void TC_CoreFunc_PRIMASK (void) {
437 uint32_t orig = __get_PRIMASK();
440 uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);
442 __set_PRIMASK(primask);
443 uint32_t result = __get_PRIMASK();
445 ASSERT_TRUE(result == primask);
448 result = __get_PRIMASK();
449 ASSERT_TRUE((result & 0x01U) == 1U);
452 result = __get_PRIMASK();
453 ASSERT_TRUE((result & 0x01U) == 0U);
456 result = __get_PRIMASK();
457 ASSERT_TRUE((result & 0x01U) == 1U);
462 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
463 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
464 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
465 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
468 \brief Test case: TC_CoreFunc_FAULTMASK
470 - Check if __get_FAULTMASK and __set_FAULTMASK intrinsic can be used to manipulate FAULTMASK.
471 - Check if __enable_fault_irq and __disable_fault_irq are reflected in FAULTMASK.
473 void TC_CoreFunc_FAULTMASK (void) {
474 uint32_t orig = __get_FAULTMASK();
477 uint32_t faultmask = (orig & ~0x01U) | (~orig & 0x01U);
479 __set_FAULTMASK(faultmask);
480 uint32_t result = __get_FAULTMASK();
482 ASSERT_TRUE(result == faultmask);
484 __disable_fault_irq();
485 result = __get_FAULTMASK();
486 ASSERT_TRUE((result & 0x01U) == 1U);
488 __enable_fault_irq();
489 result = __get_FAULTMASK();
490 ASSERT_TRUE((result & 0x01U) == 0U);
492 __disable_fault_irq();
493 result = __get_FAULTMASK();
494 ASSERT_TRUE((result & 0x01U) == 1U);
496 __set_FAULTMASK(orig);
499 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
501 \brief Test case: TC_CoreFunc_BASEPRI
503 - Check if __get_BASEPRI and __set_BASEPRI intrinsic can be used to manipulate BASEPRI.
504 - Check if __set_BASEPRI_MAX intrinsic can be used to manipulate BASEPRI.
506 void TC_CoreFunc_BASEPRI(void) {
507 uint32_t orig = __get_BASEPRI();
509 uint32_t basepri = ~orig & 0x80U;
510 __set_BASEPRI(basepri);
511 uint32_t result = __get_BASEPRI();
513 ASSERT_TRUE(result == basepri);
517 __set_BASEPRI_MAX(basepri);
518 result = __get_BASEPRI();
520 ASSERT_TRUE(result == basepri);
524 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
525 #if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
526 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
529 \brief Test case: TC_CoreFunc_BASEPRI
531 - Check if __get_FPSCR and __set_FPSCR intrinsics can be used
533 void TC_CoreFunc_FPSCR(void) {
534 uint32_t fpscr = __get_FPSCR();
542 uint32_t result = __get_FPSCR();
546 #if (defined (__FPU_USED ) && (__FPU_USED == 1U))
547 ASSERT_TRUE(result != fpscr);