CV_CoreInstr.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. /*-----------------------------------------------------------------------------
  2. * Name: CV_CoreInstr.c
  3. * Purpose: CMSIS CORE validation tests implementation
  4. *-----------------------------------------------------------------------------
  5. * Copyright (c) 2017 - 2021 Arm Limited. All rights reserved.
  6. *----------------------------------------------------------------------------*/
  7. #include "CV_Framework.h"
  8. #include "cmsis_cv.h"
  9. #if defined(__CORTEX_M)
  10. #elif defined(__CORTEX_A)
  11. #include "irq_ctrl.h"
  12. #else
  13. #error __CORTEX_M or __CORTEX_A must be defined!
  14. #endif
  15. /*-----------------------------------------------------------------------------
  16. * Test implementation
  17. *----------------------------------------------------------------------------*/
  18. /*-----------------------------------------------------------------------------
  19. * Test cases
  20. *----------------------------------------------------------------------------*/
  21. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  22. /**
  23. \brief Test case: TC_CoreInstr_NOP
  24. \details
  25. - Check if __NOP instrinsic is available
  26. - No real assertion is deployed, just a compile time check.
  27. */
  28. void TC_CoreInstr_NOP (void) {
  29. __NOP();
  30. ASSERT_TRUE(1U == 1U);
  31. }
  32. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  33. /**
  34. \brief Test case: TC_CoreInstr_SEV
  35. \details
  36. - Check if __SEV instrinsic is available
  37. - No real assertion is deployed, just a compile time check.
  38. */
  39. void TC_CoreInstr_SEV (void) {
  40. __SEV();
  41. ASSERT_TRUE(1U == 1U);
  42. }
  43. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  44. /**
  45. \brief Test case: TC_CoreInstr_BKPT
  46. \details
  47. - Check if __BKPT instrinsic is available
  48. - No real assertion is deployed, just a compile time check.
  49. */
  50. void TC_CoreInstr_BKPT (void) {
  51. __BKPT(0xABU);
  52. ASSERT_TRUE(1U == 1U);
  53. }
  54. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  55. /**
  56. \brief Test case: TC_CoreInstr_ISB
  57. \details
  58. - Check if __ISB instrinsic is available
  59. - No real assertion is deployed, just a compile time check.
  60. */
  61. void TC_CoreInstr_ISB (void) {
  62. __ISB();
  63. ASSERT_TRUE(1U == 1U);
  64. }
  65. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  66. /**
  67. \brief Test case: TC_CoreInstr_DSB
  68. \details
  69. - Check if __DSB instrinsic is available
  70. - No real assertion is deployed, just a compile time check.
  71. */
  72. void TC_CoreInstr_DSB (void) {
  73. __DSB();
  74. ASSERT_TRUE(1U == 1U);
  75. }
  76. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  77. /**
  78. \brief Test case: TC_CoreInstr_DMB
  79. \details
  80. - Check if __DNB instrinsic is available
  81. - No real assertion is deployed, just a compile time check.
  82. */
  83. void TC_CoreInstr_DMB (void) {
  84. __DMB();
  85. ASSERT_TRUE(1U == 1U);
  86. }
  87. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  88. /**
  89. \brief Test case: TC_CoreInstr_WFI
  90. \details
  91. - Check if __WFI instrinsic is available
  92. - No real assertion is deployed, just a compile time check.
  93. */
  94. void TC_CoreInstr_WFI (void) {
  95. __WFI();
  96. ASSERT_TRUE(1U == 1U);
  97. }
  98. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  99. /**
  100. \brief Test case: TC_CoreInstr_WFE
  101. \details
  102. - Check if __WFE instrinsic is available
  103. - No real assertion is deployed, just a compile time check.
  104. */
  105. void TC_CoreInstr_WFE (void) {
  106. __WFE();
  107. ASSERT_TRUE(1U == 1U);
  108. }
  109. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  110. /**
  111. \brief Test case: TC_CoreInstr_REV
  112. \details
  113. - Check if __REV instrinsic swaps all bytes in a word.
  114. */
  115. void TC_CoreInstr_REV (void) {
  116. volatile uint32_t op1_u32;
  117. volatile uint32_t res_u32;
  118. op1_u32 = 0x47110815U;
  119. res_u32 = __REV(op1_u32);
  120. ASSERT_TRUE(res_u32 == 0x15081147U);
  121. op1_u32 = 0x80000000U;
  122. res_u32 = __REV(op1_u32);
  123. ASSERT_TRUE(res_u32 == 0x00000080U);
  124. op1_u32 = 0x00000080U;
  125. res_u32 = __REV(op1_u32);
  126. ASSERT_TRUE(res_u32 == 0x80000000U);
  127. }
  128. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  129. /**
  130. \brief Test case: TC_CoreInstr_REV16
  131. \details
  132. - Check if __REV16 instrinsic swaps the bytes in both halfwords independendly.
  133. */
  134. void TC_CoreInstr_REV16(void) {
  135. volatile uint32_t op1_u32;
  136. volatile uint32_t res_u32;
  137. op1_u32 = 0x47110815U;
  138. res_u32 = __REV16(op1_u32);
  139. ASSERT_TRUE(res_u32 == 0x11471508U);
  140. op1_u32 = 0x00001234U;
  141. res_u32 = __REV16(op1_u32);
  142. ASSERT_TRUE(res_u32 == 0x00003412U);
  143. }
  144. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  145. /**
  146. \brief Test case: TC_CoreInstr_REVSH
  147. \details
  148. - Check if __REVSH instrinsic swaps bytes in a signed halfword keeping the sign.
  149. */
  150. void TC_CoreInstr_REVSH(void) {
  151. volatile int16_t value = 0U;
  152. int16_t result = 0U;
  153. value = 0x4711;
  154. result = __REVSH(value);
  155. ASSERT_TRUE(result == 0x1147);
  156. value = (int16_t)0x8000;
  157. result = __REVSH(value);
  158. ASSERT_TRUE(result == 0x0080);
  159. value = 0x0080;
  160. result = __REVSH(value);
  161. ASSERT_TRUE(result == (int16_t)0x8000);
  162. value = -0x1234;
  163. result = __REVSH(value);
  164. ASSERT_TRUE(result == (int16_t)0xcced);
  165. }
  166. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  167. /**
  168. \brief Test case: TC_CoreInstr_RBIT
  169. \details
  170. - Check if __RBIT instrinsic revserses the bit order of arbitrary words.
  171. */
  172. void TC_CoreInstr_RBIT (void) {
  173. volatile uint32_t value = 0U;
  174. uint32_t result = 0U;
  175. value = 0xAAAAAAAAU;
  176. result = __RBIT(value);
  177. ASSERT_TRUE(result == 0x55555555U);
  178. value = 0x55555555U;
  179. result = __RBIT(value);
  180. ASSERT_TRUE(result == 0xAAAAAAAAU);
  181. value = 0x00000001U;
  182. result = __RBIT(value);
  183. ASSERT_TRUE(result == 0x80000000U);
  184. value = 0x80000000U;
  185. result = __RBIT(value);
  186. ASSERT_TRUE(result == 0x00000001U);
  187. value = 0xDEADBEEFU;
  188. result = __RBIT(value);
  189. ASSERT_TRUE(result == 0xF77DB57BU);
  190. }
  191. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  192. /**
  193. \brief Test case: TC_CoreInstr_ROR
  194. \details
  195. - Check if __ROR instrinsic moves all bits as expected.
  196. */
  197. void TC_CoreInstr_ROR(void) {
  198. volatile uint32_t value = 0U;
  199. uint32_t result = 0U;
  200. value = 0x00000001U;
  201. result = __ROR(value, 1U);
  202. ASSERT_TRUE(result == 0x80000000U);
  203. value = 0x80000000U;
  204. result = __ROR(value, 1U);
  205. ASSERT_TRUE(result == 0x40000000U);
  206. value = 0x40000000U;
  207. result = __ROR(value, 30U);
  208. ASSERT_TRUE(result == 0x00000001U);
  209. value = 0x00000001U;
  210. result = __ROR(value, 32U);
  211. ASSERT_TRUE(result == 0x00000001U);
  212. value = 0x08154711U;
  213. result = __ROR(value, 8U);
  214. ASSERT_TRUE(result == 0x11081547U);
  215. }
  216. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  217. /**
  218. \brief Test case: TC_CoreInstr_CLZ
  219. \details
  220. - Check if __CLZ instrinsic counts leading zeros.
  221. */
  222. void TC_CoreInstr_CLZ (void) {
  223. volatile uint32_t value = 0U;
  224. uint32_t result = 0U;
  225. value = 0x00000000U;
  226. result = __CLZ(value);
  227. ASSERT_TRUE(result == 32);
  228. value = 0x00000001U;
  229. result = __CLZ(value);
  230. ASSERT_TRUE(result == 31);
  231. value = 0x40000000U;
  232. result = __CLZ(value);
  233. ASSERT_TRUE(result == 1);
  234. value = 0x80000000U;
  235. result = __CLZ(value);
  236. ASSERT_TRUE(result == 0);
  237. value = 0xFFFFFFFFU;
  238. result = __CLZ(value);
  239. ASSERT_TRUE(result == 0);
  240. value = 0x80000001U;
  241. result = __CLZ(value);
  242. ASSERT_TRUE(result == 0);
  243. }
  244. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  245. /**
  246. \brief Test case: TC_CoreInstr_SSAT
  247. \details
  248. - Check if __SSAT instrinsic saturates signed integer values.
  249. */
  250. void TC_CoreInstr_SSAT (void) {
  251. volatile int32_t value = 0;
  252. int32_t result = 0;
  253. value = INT32_MAX;
  254. result = __SSAT(value, 32U);
  255. ASSERT_TRUE(result == INT32_MAX);
  256. value = INT32_MAX;
  257. result = __SSAT(value, 16U);
  258. ASSERT_TRUE(result == INT16_MAX);
  259. value = INT32_MAX;
  260. result = __SSAT(value, 8U);
  261. ASSERT_TRUE(result == INT8_MAX);
  262. value = INT32_MAX;
  263. result = __SSAT(value, 1U);
  264. ASSERT_TRUE(result == 0);
  265. value = INT32_MIN;
  266. result = __SSAT(value, 32U);
  267. ASSERT_TRUE(result == INT32_MIN);
  268. value = INT32_MIN;
  269. result = __SSAT(value, 16U);
  270. ASSERT_TRUE(result == INT16_MIN);
  271. value = INT32_MIN;
  272. result = __SSAT(value, 8U);
  273. ASSERT_TRUE(result == INT8_MIN);
  274. value = INT32_MIN;
  275. result = __SSAT(value, 1U);
  276. ASSERT_TRUE(result == -1);
  277. }
  278. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  279. /**
  280. \brief Test case: TC_CoreInstr_USAT
  281. \details
  282. - Check if __USAT instrinsic saturates unsigned integer values.
  283. */
  284. void TC_CoreInstr_USAT (void) {
  285. volatile int32_t value = 0U;
  286. uint32_t result = 0U;
  287. value = INT32_MAX;
  288. result = __USAT(value, 31U);
  289. ASSERT_TRUE(result == (UINT32_MAX >> 1U));
  290. value = INT32_MAX;
  291. result = __USAT(value, 16U);
  292. ASSERT_TRUE(result == UINT16_MAX);
  293. value = INT32_MAX;
  294. result = __USAT(value, 8U);
  295. ASSERT_TRUE(result == UINT8_MAX);
  296. value = INT32_MAX;
  297. result = __USAT(value, 0U);
  298. ASSERT_TRUE(result == 0U);
  299. value = INT32_MIN;
  300. result = __USAT(value, 31U);
  301. ASSERT_TRUE(result == 0U);
  302. value = INT32_MIN;
  303. result = __USAT(value, 16U);
  304. ASSERT_TRUE(result == 0U);
  305. value = INT32_MIN;
  306. result = __USAT(value, 8U);
  307. ASSERT_TRUE(result == 0U);
  308. value = INT32_MIN;
  309. result = __USAT(value, 0U);
  310. ASSERT_TRUE(result == 0U);
  311. }
  312. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  313. /**
  314. \brief Test case: TC_CoreInstr_RRX
  315. \details
  316. - Check if __USAT instrinsic saturates unsigned integer values.
  317. */
  318. void TC_CoreInstr_RRX (void) {
  319. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  320. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  321. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  322. (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
  323. volatile uint32_t value = 0U;
  324. volatile uint32_t result = 0U;
  325. volatile xPSR_Type xPSR;
  326. value = 0x80000002;
  327. xPSR.w = __get_xPSR();
  328. result = __RRX(value);
  329. ASSERT_TRUE(result == (0x40000001 | (uint32_t)(xPSR.b.C << 31)));
  330. #endif
  331. }
  332. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  333. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  334. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  335. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  336. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
  337. (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
  338. (defined(__CORTEX_A) ) )
  339. /// Exclusive byte value
  340. static volatile uint8_t TC_CoreInstr_LoadStoreExclusive_byte = 0x47U;
  341. /// Exclusive halfword value
  342. static volatile uint16_t TC_CoreInstr_LoadStoreExclusive_hword = 0x0815U;
  343. /// Exclusive word value
  344. static volatile uint32_t TC_CoreInstr_LoadStoreExclusive_word = 0x08154711U;
  345. /**
  346. \brief Interrupt function for TC_CoreInstr_LoadStoreExclusive
  347. \details
  348. The interrupt manipulates all the global data
  349. which disrupts the exclusive sequences in the test
  350. */
  351. static void TC_CoreInstr_LoadStoreExclusive_IRQHandler(void) {
  352. const uint8_t b = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  353. __STREXB((uint8_t)~b, &TC_CoreInstr_LoadStoreExclusive_byte);
  354. const uint16_t hw = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  355. __STREXH((uint16_t)~hw, &TC_CoreInstr_LoadStoreExclusive_hword);
  356. const uint32_t w = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  357. __STREXW((uint32_t)~w, &TC_CoreInstr_LoadStoreExclusive_word);
  358. }
  359. /**
  360. \brief Helper function for TC_CoreInstr_LoadStoreExclusive to enable test interrupt.
  361. \details
  362. This helper function implements interrupt enabling according to target
  363. architecture, i.e. Cortex-A or Cortex-M.
  364. */
  365. static void TC_CoreInstr_LoadStoreExclusive_IRQEnable(void) {
  366. #if defined(__CORTEX_M)
  367. TST_IRQHandler = TC_CoreInstr_LoadStoreExclusive_IRQHandler;
  368. NVIC_EnableIRQ(Interrupt0_IRQn);
  369. #elif defined(__CORTEX_A)
  370. IRQ_SetHandler(SGI0_IRQn, TC_CoreInstr_LoadStoreExclusive_IRQHandler);
  371. IRQ_Enable(SGI0_IRQn);
  372. #else
  373. #error __CORTEX_M or __CORTEX_A must be defined!
  374. #endif
  375. __enable_irq();
  376. }
  377. /**
  378. \brief Helper function for TC_CoreInstr_LoadStoreExclusive to set test interrupt pending.
  379. \details
  380. This helper function implements set pending the test interrupt according to target
  381. architecture, i.e. Cortex-A or Cortex-M.
  382. */
  383. static void TC_CoreInstr_LoadStoreExclusive_IRQPend(void) {
  384. #if defined(__CORTEX_M)
  385. NVIC_SetPendingIRQ(Interrupt0_IRQn);
  386. #elif defined(__CORTEX_A)
  387. IRQ_SetPending(SGI0_IRQn);
  388. #else
  389. #error __CORTEX_M or __CORTEX_A must be defined!
  390. #endif
  391. for(uint32_t i = 10U; i > 0U; --i) {}
  392. }
  393. /**
  394. \brief Helper function for TC_CoreInstr_LoadStoreExclusive to disable test interrupt.
  395. \details
  396. This helper function implements interrupt disabling according to target
  397. architecture, i.e. Cortex-A or Cortex-M.
  398. */
  399. static void TC_CoreInstr_LoadStoreExclusive_IRQDisable(void) {
  400. __disable_irq();
  401. #if defined(__CORTEX_M)
  402. NVIC_DisableIRQ(Interrupt0_IRQn);
  403. TST_IRQHandler = NULL;
  404. #elif defined(__CORTEX_A)
  405. IRQ_Disable(SGI0_IRQn);
  406. IRQ_SetHandler(SGI0_IRQn, NULL);
  407. #else
  408. #error __CORTEX_M or __CORTEX_A must be defined!
  409. #endif
  410. }
  411. #endif
  412. /**
  413. \brief Test case: TC_CoreInstr_LoadStoreExclusive
  414. \details
  415. Checks exclusive load and store instructions:
  416. - LDREXB, LDREXH, LDREXW
  417. - STREXB, STREXH, STREXW
  418. - CLREX
  419. */
  420. void TC_CoreInstr_LoadStoreExclusive (void) {
  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)) || \
  424. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
  425. (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
  426. (defined(__CORTEX_A) ) )
  427. uint8_t u8, u8Inv;
  428. uint16_t u16, u16Inv;
  429. uint32_t u32, u32Inv;
  430. uint32_t result;
  431. /* 1. Test exclusives without interruption */
  432. u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  433. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
  434. result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
  435. ASSERT_TRUE(result == 0U);
  436. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_byte == u8+1U);
  437. u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  438. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
  439. result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
  440. ASSERT_TRUE(result == 0U);
  441. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_hword == u16+1U);
  442. u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  443. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
  444. result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
  445. ASSERT_TRUE(result == 0U);
  446. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_word == u32+1U);
  447. /* 2. Test exclusives with clear */
  448. u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  449. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
  450. __CLREX();
  451. result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
  452. ASSERT_TRUE(result == 1U);
  453. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_byte == u8);
  454. u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  455. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
  456. __CLREX();
  457. result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
  458. ASSERT_TRUE(result == 1U);
  459. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_hword == u16);
  460. u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  461. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
  462. __CLREX();
  463. result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
  464. ASSERT_TRUE(result == 1U);
  465. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_word == u32);
  466. /* 3. Test exclusives with interruption */
  467. TC_CoreInstr_LoadStoreExclusive_IRQEnable();
  468. u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  469. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
  470. TC_CoreInstr_LoadStoreExclusive_IRQPend();
  471. result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
  472. ASSERT_TRUE(result == 1U);
  473. u8Inv = (uint8_t)~u8;
  474. ASSERT_TRUE(u8Inv == TC_CoreInstr_LoadStoreExclusive_byte);
  475. u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  476. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
  477. TC_CoreInstr_LoadStoreExclusive_IRQPend();
  478. result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
  479. ASSERT_TRUE(result == 1U);
  480. u16Inv = (uint16_t)~u16;
  481. ASSERT_TRUE(u16Inv == TC_CoreInstr_LoadStoreExclusive_hword);
  482. u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  483. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
  484. TC_CoreInstr_LoadStoreExclusive_IRQPend();
  485. result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
  486. ASSERT_TRUE(result == 1U);
  487. u32Inv = (uint32_t)~u32;
  488. ASSERT_TRUE(u32Inv == TC_CoreInstr_LoadStoreExclusive_word);
  489. TC_CoreInstr_LoadStoreExclusive_IRQDisable();
  490. #endif
  491. }
  492. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  493. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  494. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  495. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  496. (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
  497. /// byte value unprivileged access
  498. static volatile uint8_t TC_CoreInstr_LoadStoreUnpriv_byte = 0x47U;
  499. /// halfword value unprivileged access
  500. static volatile uint16_t TC_CoreInstr_LoadStoreUnpriv_hword = 0x0815U;
  501. /// word value unprivileged access
  502. static volatile uint32_t TC_CoreInstr_LoadStoreUnpriv_word = 0x08154711U;
  503. #endif
  504. /**
  505. \brief Test case: TC_CoreInstr_LoadStoreUnpriv
  506. \details
  507. Checks load/store unprivileged instructions:
  508. - LDRBT, LDRHT, LDRT
  509. - STRBT, STRHT, STRT
  510. */
  511. void TC_CoreInstr_LoadStoreUnpriv (void) {
  512. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  513. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  514. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  515. (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
  516. uint8_t u8 = 0U;
  517. uint16_t u16 = 0U;
  518. uint32_t u32 = 0U;
  519. /* 1. Test without interruption */
  520. u8 = __LDRBT(&TC_CoreInstr_LoadStoreUnpriv_byte);
  521. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreUnpriv_byte);
  522. __STRBT(u8+1U, &TC_CoreInstr_LoadStoreUnpriv_byte);
  523. ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_byte == u8+1U);
  524. u16 = __LDRHT(&TC_CoreInstr_LoadStoreUnpriv_hword);
  525. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreUnpriv_hword);
  526. __STRHT(u16+1U, &TC_CoreInstr_LoadStoreUnpriv_hword);
  527. ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_hword == u16+1U);
  528. u32 = __LDRT(&TC_CoreInstr_LoadStoreUnpriv_word);
  529. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreUnpriv_word);
  530. __STRT(u32+1U, &TC_CoreInstr_LoadStoreUnpriv_word);
  531. ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_word == u32+1U);
  532. #endif
  533. }
  534. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  535. #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
  536. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  537. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  538. /// byte value unprivileged access
  539. static volatile uint8_t TC_CoreInstr_LoadStoreAcquire_byte = 0x47U;
  540. /// halfword value unprivileged access
  541. static volatile uint16_t TC_CoreInstr_LoadStoreAcquire_hword = 0x0815U;
  542. /// word value unprivileged access
  543. static volatile uint32_t TC_CoreInstr_LoadStoreAcquire_word = 0x08154711U;
  544. #endif
  545. /**
  546. \brief Test case: TC_CoreInstr_LoadStoreAquire
  547. \details
  548. Checks Load-Acquire and Store-Release instructions:
  549. - LDAB, LDAH, LDA
  550. - STLB, STLH, STL
  551. */
  552. void TC_CoreInstr_LoadStoreAcquire (void) {
  553. #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
  554. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  555. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  556. uint8_t u8 = 0U;
  557. uint16_t u16 = 0U;
  558. uint32_t u32 = 0U;
  559. /* 1. Test without interruption */
  560. u8 = __LDAB(&TC_CoreInstr_LoadStoreAcquire_byte);
  561. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreAcquire_byte);
  562. __STLB(u8+1U, &TC_CoreInstr_LoadStoreAcquire_byte);
  563. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_byte == u8+1U);
  564. u16 = __LDAH(&TC_CoreInstr_LoadStoreAcquire_hword);
  565. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreAcquire_hword);
  566. __STLH(u16+1U, &TC_CoreInstr_LoadStoreAcquire_hword);
  567. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_hword == u16+1U);
  568. u32 = __LDA(&TC_CoreInstr_LoadStoreAcquire_word);
  569. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreAcquire_word);
  570. __STL(u32+1U, &TC_CoreInstr_LoadStoreAcquire_word);
  571. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_word == u32+1U);
  572. #endif
  573. }
  574. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  575. #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
  576. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  577. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  578. /// byte value unprivileged access
  579. static volatile uint8_t TC_CoreInstr_LoadStoreAcquireExclusive_byte = 0x47U;
  580. /// halfword value unprivileged access
  581. static volatile uint16_t TC_CoreInstr_LoadStoreAcquireExclusive_hword = 0x0815U;
  582. /// word value unprivileged access
  583. static volatile uint32_t TC_CoreInstr_LoadStoreAcquireExclusive_word = 0x08154711U;
  584. #endif
  585. /**
  586. \brief Test case: TC_CoreInstr_LoadStoreAquire
  587. \details
  588. Checks Load-Acquire and Store-Release exclusive instructions:
  589. - LDAEXB, LDAEXH, LDAEX
  590. - STLEXB, STLEXH, STLEX
  591. */
  592. void TC_CoreInstr_LoadStoreAcquireExclusive (void) {
  593. #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
  594. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  595. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  596. uint8_t u8 = 0U;
  597. uint16_t u16 = 0U;
  598. uint32_t u32 = 0U;
  599. uint32_t result = 0U;
  600. /* 1. Test without interruption */
  601. u8 = __LDAEXB(&TC_CoreInstr_LoadStoreAcquireExclusive_byte);
  602. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreAcquireExclusive_byte);
  603. result = __STLEXB(u8+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_byte);
  604. ASSERT_TRUE(result == 0U);
  605. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_byte == u8+1U);
  606. u16 = __LDAEXH(&TC_CoreInstr_LoadStoreAcquireExclusive_hword);
  607. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreAcquireExclusive_hword);
  608. result = __STLEXH(u16+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_hword);
  609. ASSERT_TRUE(result == 0U);
  610. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_hword == u16+1U);
  611. u32 = __LDAEX(&TC_CoreInstr_LoadStoreAcquireExclusive_word);
  612. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreAcquireExclusive_word);
  613. result = __STLEX(u32+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_word);
  614. ASSERT_TRUE(result == 0U);
  615. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_word == u32+1U);
  616. #endif
  617. }
  618. /**
  619. \brief Test case: TC_CoreInstr_UnalignedUint16
  620. \details
  621. Checks macro functions to access unaligned uint16_t values:
  622. - __UNALIGNED_UINT16_READ
  623. - __UNALIGNED_UINT16_WRITE
  624. */
  625. void TC_CoreInstr_UnalignedUint16(void) {
  626. uint8_t buffer[3] = { 0U, 0U, 0U };
  627. uint16_t val;
  628. for(int i=0; i<2; i++) {
  629. __UNALIGNED_UINT16_WRITE(&(buffer[i]), 0x4711U);
  630. ASSERT_TRUE(buffer[i] == 0x11U);
  631. ASSERT_TRUE(buffer[i+1] == 0x47U);
  632. ASSERT_TRUE(buffer[(i+2)%3] == 0x00U);
  633. buffer[i] = 0x12U;
  634. buffer[i+1] = 0x46U;
  635. val = __UNALIGNED_UINT16_READ(&(buffer[i]));
  636. ASSERT_TRUE(val == 0x4612U);
  637. buffer[i] = 0x00U;
  638. buffer[i+1] = 0x00U;
  639. }
  640. }
  641. /**
  642. \brief Test case: TC_CoreInstr_UnalignedUint32
  643. \details
  644. Checks macro functions to access unaligned uint32_t values:
  645. - __UNALIGNED_UINT32_READ
  646. - __UNALIGNED_UINT32_WRITE
  647. */
  648. void TC_CoreInstr_UnalignedUint32(void) {
  649. uint8_t buffer[7] = { 0U, 0U, 0U, 0U, 0U, 0U, 0U };
  650. uint32_t val;
  651. for(int i=0; i<4; i++) {
  652. __UNALIGNED_UINT32_WRITE(&(buffer[i]), 0x08154711UL);
  653. ASSERT_TRUE(buffer[i+0] == 0x11U);
  654. ASSERT_TRUE(buffer[i+1] == 0x47U);
  655. ASSERT_TRUE(buffer[i+2] == 0x15U);
  656. ASSERT_TRUE(buffer[i+3] == 0x08U);
  657. ASSERT_TRUE(buffer[(i+4)%7] == 0x00U);
  658. ASSERT_TRUE(buffer[(i+5)%7] == 0x00U);
  659. ASSERT_TRUE(buffer[(i+6)%7] == 0x00U);
  660. buffer[i+0] = 0x12U;
  661. buffer[i+1] = 0x46U;
  662. buffer[i+2] = 0x14U;
  663. buffer[i+3] = 0x09U;
  664. val = __UNALIGNED_UINT32_READ(&(buffer[i]));
  665. ASSERT_TRUE(val == 0x09144612UL);
  666. buffer[i+0] = 0x00U;
  667. buffer[i+1] = 0x00U;
  668. buffer[i+2] = 0x00U;
  669. buffer[i+3] = 0x00U;
  670. }
  671. }