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;
17 static void TC_CoreFunc_EnDisIRQIRQHandler(void) {
21 static volatile uint32_t irqIPSR = 0U;
22 static volatile uint32_t irqXPSR = 0U;
24 static void TC_CoreFunc_IPSR_IRQHandler(void) {
25 irqIPSR = __get_IPSR();
26 irqXPSR = __get_xPSR();
29 /*-----------------------------------------------------------------------------
31 *----------------------------------------------------------------------------*/
33 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
35 \brief Test case: TC_CoreFunc_EnDisIRQ
37 - Check if __disable_irq() and __enable_irq() have expected behaviour.
39 void TC_CoreFunc_EnDisIRQ (void)
43 NVIC_EnableIRQ(WDT_IRQn);
44 NVIC_ClearPendingIRQ(WDT_IRQn);
46 TST_IRQHandler = TC_CoreFunc_EnDisIRQIRQHandler;
49 NVIC_SetPendingIRQ(WDT_IRQn);
50 for(uint32_t i = 10U; i > 0U; --i) {}
52 // Interrupt is not taken
53 ASSERT_TRUE(irqTaken == 0U);
57 for(uint32_t i = 10U; i > 0U; --i) {}
59 // Interrupt was taken
60 ASSERT_TRUE(irqTaken == 1U);
63 NVIC_DisableIRQ(WDT_IRQn);
66 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
68 \brief Test case: TC_CoreFunc_GetCtrl
70 - Check if __set_CONTROL and __get_CONTROL() sets/gets control register
72 void TC_CoreFunc_Control (void) {
73 // don't use stack for this variables
76 static uint32_t result;
78 orig = __get_CONTROL();
82 #ifdef CONTROL_SPSEL_Msk
84 ctrl = (ctrl & ~CONTROL_SPSEL_Msk) | (~ctrl & CONTROL_SPSEL_Msk);
90 result = __get_CONTROL();
95 ASSERT_TRUE(result == ctrl);
96 ASSERT_TRUE(__get_CONTROL() == orig);
99 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
101 \brief Test case: TC_CoreFunc_IPSR
103 - Check if __get_IPSR instrinsic is available
104 - Check if __get_xPSR instrinsic is available
105 - Result differentiates between thread and exception modes
107 void TC_CoreFunc_IPSR (void) {
108 uint32_t result = __get_IPSR();
109 ASSERT_TRUE(result == 0U); // Thread Mode
111 result = __get_xPSR();
112 ASSERT_TRUE((result & xPSR_ISR_Msk) == 0U); // Thread Mode
114 TST_IRQHandler = TC_CoreFunc_IPSR_IRQHandler;
118 NVIC_ClearPendingIRQ(WDT_IRQn);
119 NVIC_EnableIRQ(WDT_IRQn);
122 NVIC_SetPendingIRQ(WDT_IRQn);
123 for(uint32_t i = 10U; i > 0U; --i) {}
126 NVIC_DisableIRQ(WDT_IRQn);
128 ASSERT_TRUE(irqIPSR != 0U); // Exception Mode
129 ASSERT_TRUE((irqXPSR & xPSR_ISR_Msk) != 0U); // Exception Mode
132 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
134 #if defined(__CC_ARM)
135 #define SUBS(Rd, Rm, Rn) __ASM("SUBS " # Rd ", " # Rm ", " # Rn)
136 #define ADDS(Rd, Rm, Rn) __ASM("ADDS " # Rd ", " # Rm ", " # Rn)
137 #elif defined( __GNUC__ ) && (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
138 #define SUBS(Rd, Rm, Rn) __ASM("SUB %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
139 #define ADDS(Rd, Rm, Rn) __ASM("ADD %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
141 //lint -save -e(9026) allow function-like macro
142 #define SUBS(Rd, Rm, Rn) ((Rd) = (Rm) - (Rn))
143 #define ADDS(Rd, Rm, Rn) ((Rd) = (Rm) + (Rn))
146 #define SUBS(Rd, Rm, Rn) __ASM("SUBS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
147 #define ADDS(Rd, Rm, Rn) __ASM("ADDS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
151 \brief Test case: TC_CoreFunc_APSR
153 - Check if __get_APSR instrinsic is available
154 - Check if __get_xPSR instrinsic is available
155 - Check negative, zero and overflow flags
157 void TC_CoreFunc_APSR (void) {
159 //lint -esym(838, Rm) unused values
160 //lint -esym(438, Rm) unused values
162 // Check negative flag
166 result = __get_APSR();
167 ASSERT_TRUE((result & APSR_N_Msk) == APSR_N_Msk);
172 result = __get_xPSR();
173 ASSERT_TRUE((result & xPSR_N_Msk) == xPSR_N_Msk);
175 // Check zero and compare flag
178 result = __get_APSR();
179 ASSERT_TRUE((result & APSR_Z_Msk) == APSR_Z_Msk);
180 ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
184 result = __get_xPSR();
185 ASSERT_TRUE((result & xPSR_Z_Msk) == xPSR_Z_Msk);
186 ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
188 // Check overflow flag
192 result = __get_APSR();
193 ASSERT_TRUE((result & APSR_V_Msk) == APSR_V_Msk);
198 result = __get_xPSR();
199 ASSERT_TRUE((result & xPSR_V_Msk) == xPSR_V_Msk);
202 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
204 \brief Test case: TC_CoreFunc_PSP
206 - Check if __get_PSP and __set_PSP instrinsic can be used to manipulate process stack pointer.
208 void TC_CoreFunc_PSP (void) {
209 // don't use stack for this variables
210 static uint32_t orig;
212 static uint32_t result;
216 psp = orig + 0x12345678U;
219 result = __get_PSP();
223 ASSERT_TRUE(result == psp);
226 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
228 \brief Test case: TC_CoreFunc_MSP
230 - Check if __get_MSP and __set_MSP instrinsic can be used to manipulate main stack pointer.
232 void TC_CoreFunc_MSP (void) {
233 // don't use stack for this variables
234 static uint32_t orig;
236 static uint32_t result;
237 static uint32_t ctrl;
239 ctrl = __get_CONTROL();
240 __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
244 msp = orig + 0x12345678U;
247 result = __get_MSP();
253 ASSERT_TRUE(result == msp);
256 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
257 #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
258 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
261 \brief Test case: TC_CoreFunc_PSPLIM
263 - Check if __get_PSPLIM and __set_PSPLIM instrinsic can be used to manipulate process stack pointer limit.
265 void TC_CoreFunc_PSPLIM (void) {
266 // don't use stack for this variables
267 static uint32_t orig;
268 static uint32_t psplim;
269 static uint32_t result;
271 orig = __get_PSPLIM();
273 psplim = orig + 0x12345678U;
274 __set_PSPLIM(psplim);
276 result = __get_PSPLIM();
280 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
281 (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
282 // without main extensions, the non-secure PSPLIM is RAZ/WI
283 ASSERT_TRUE(result == 0U);
285 ASSERT_TRUE(result == psplim);
289 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
291 \brief Test case: TC_CoreFunc_PSPLIM_NS
293 - Check if __TZ_get_PSPLIM_NS and __TZ_set_PSPLIM_NS instrinsic can be used to manipulate process stack pointer limit.
295 void TC_CoreFunc_PSPLIM_NS (void) {
296 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
301 orig = __TZ_get_PSPLIM_NS();
303 psplim = orig + 0x12345678U;
304 __TZ_set_PSPLIM_NS(psplim);
306 result = __TZ_get_PSPLIM_NS();
308 __TZ_set_PSPLIM_NS(orig);
310 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
311 // without main extensions, the non-secure PSPLIM is RAZ/WI
312 ASSERT_TRUE(result == 0U);
314 ASSERT_TRUE(result == psplim);
319 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
321 \brief Test case: TC_CoreFunc_MSPLIM
323 - Check if __get_MSPLIM and __set_MSPLIM instrinsic can be used to manipulate main stack pointer limit.
325 void TC_CoreFunc_MSPLIM (void) {
326 // don't use stack for this variables
327 static uint32_t orig;
328 static uint32_t msplim;
329 static uint32_t result;
330 static uint32_t ctrl;
332 ctrl = __get_CONTROL();
333 __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
335 orig = __get_MSPLIM();
337 msplim = orig + 0x12345678U;
338 __set_MSPLIM(msplim);
340 result = __get_MSPLIM();
346 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
347 (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
348 // without main extensions, the non-secure MSPLIM is RAZ/WI
349 ASSERT_TRUE(result == 0U);
351 ASSERT_TRUE(result == msplim);
357 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
359 \brief Test case: TC_CoreFunc_MSPLIM_NS
361 - Check if __TZ_get_MSPLIM_NS and __TZ_set_MSPLIM_NS instrinsic can be used to manipulate process stack pointer limit.
363 void TC_CoreFunc_MSPLIM_NS (void) {
364 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
369 orig = __TZ_get_MSPLIM_NS();
371 msplim = orig + 0x12345678U;
372 __TZ_set_MSPLIM_NS(msplim);
374 result = __TZ_get_MSPLIM_NS();
376 __TZ_set_MSPLIM_NS(orig);
378 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
379 // without main extensions, the non-secure PSPLIM is RAZ/WI
380 ASSERT_TRUE(result == 0U);
382 ASSERT_TRUE(result == msplim);
387 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
389 \brief Test case: TC_CoreFunc_PRIMASK
391 - Check if __get_PRIMASK and __set_PRIMASK instrinsic can be used to manipulate PRIMASK.
392 - Check if __enable_irq and __disable_irq are reflected in PRIMASK.
394 void TC_CoreFunc_PRIMASK (void) {
395 uint32_t orig = __get_PRIMASK();
398 uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);
400 __set_PRIMASK(primask);
401 uint32_t result = __get_PRIMASK();
403 ASSERT_TRUE(result == primask);
406 result = __get_PRIMASK();
407 ASSERT_TRUE((result & 0x01U) == 1U);
410 result = __get_PRIMASK();
411 ASSERT_TRUE((result & 0x01U) == 0U);
414 result = __get_PRIMASK();
415 ASSERT_TRUE((result & 0x01U) == 1U);
420 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
421 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
422 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
423 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
426 \brief Test case: TC_CoreFunc_FAULTMASK
428 - Check if __get_FAULTMASK and __set_FAULTMASK instrinsic can be used to manipulate FAULTMASK.
429 - Check if __enable_fault_irq and __disable_fault_irq are reflected in FAULTMASK.
431 void TC_CoreFunc_FAULTMASK (void) {
432 uint32_t orig = __get_FAULTMASK();
435 uint32_t faultmask = (orig & ~0x01U) | (~orig & 0x01U);
437 __set_FAULTMASK(faultmask);
438 uint32_t result = __get_FAULTMASK();
440 ASSERT_TRUE(result == faultmask);
442 __disable_fault_irq();
443 result = __get_FAULTMASK();
444 ASSERT_TRUE((result & 0x01U) == 1U);
446 __enable_fault_irq();
447 result = __get_FAULTMASK();
448 ASSERT_TRUE((result & 0x01U) == 0U);
450 __disable_fault_irq();
451 result = __get_FAULTMASK();
452 ASSERT_TRUE((result & 0x01U) == 1U);
454 __set_FAULTMASK(orig);
457 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
459 \brief Test case: TC_CoreFunc_BASEPRI
461 - Check if __get_BASEPRI and __set_BASEPRI instrinsic can be used to manipulate BASEPRI.
462 - Check if __set_BASEPRI_MAX instrinsic can be used to manipulate BASEPRI.
464 void TC_CoreFunc_BASEPRI(void) {
465 uint32_t orig = __get_BASEPRI();
467 uint32_t basepri = ~orig & 0x80U;
468 __set_BASEPRI(basepri);
469 uint32_t result = __get_BASEPRI();
471 ASSERT_TRUE(result == basepri);
475 __set_BASEPRI_MAX(basepri);
476 result = __get_BASEPRI();
478 ASSERT_TRUE(result == basepri);
482 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
483 #if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
484 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
487 \brief Test case: TC_CoreFunc_BASEPRI
489 - Check if __get_FPSCR and __set_FPSCR intrinsics can be used
491 void TC_CoreFunc_FPSCR(void) {
492 uint32_t fpscr = __get_FPSCR();
500 uint32_t result = __get_FPSCR();
504 #if (defined (__FPU_USED ) && (__FPU_USED == 1U))
505 ASSERT_TRUE(result != fpscr);