CV_CoreFunc.c 21 KB

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