CV_CoreInstr.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. /*-----------------------------------------------------------------------------
  2. * Name: CV_CoreInstr.c
  3. * Purpose: CMSIS CORE validation tests implementation
  4. *-----------------------------------------------------------------------------
  5. * Copyright (c) 2017 - 2018 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. volatile uint32_t value = 0U;
  323. volatile uint32_t result = 0U;
  324. volatile xPSR_Type xPSR;
  325. value = 0x80000002;
  326. xPSR.w = __get_xPSR();
  327. result = __RRX(value);
  328. ASSERT_TRUE(result == (0x40000001 | (uint32_t)(xPSR.b.C << 31)));
  329. #endif
  330. }
  331. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  332. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  333. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  334. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  335. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
  336. (defined(__CORTEX_A) ) )
  337. /// Exclusive byte value
  338. static volatile uint8_t TC_CoreInstr_LoadStoreExclusive_byte = 0x47U;
  339. /// Exclusive halfword value
  340. static volatile uint16_t TC_CoreInstr_LoadStoreExclusive_hword = 0x0815U;
  341. /// Exclusive word value
  342. static volatile uint32_t TC_CoreInstr_LoadStoreExclusive_word = 0x08154711U;
  343. /**
  344. \brief Interrupt function for TC_CoreInstr_LoadStoreExclusive
  345. \details
  346. The interrupt manipulates all the global data
  347. which disrupts the exclusive sequences in the test
  348. */
  349. static void TC_CoreInstr_LoadStoreExclusive_IRQHandler(void) {
  350. const uint8_t b = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  351. __STREXB((uint8_t)~b, &TC_CoreInstr_LoadStoreExclusive_byte);
  352. const uint16_t hw = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  353. __STREXH((uint16_t)~hw, &TC_CoreInstr_LoadStoreExclusive_hword);
  354. const uint32_t w = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  355. __STREXW((uint32_t)~w, &TC_CoreInstr_LoadStoreExclusive_word);
  356. }
  357. /**
  358. \brief Helper function for TC_CoreInstr_LoadStoreExclusive to enable test interrupt.
  359. \details
  360. This helper function implements interrupt enabling according to target
  361. architecture, i.e. Cortex-A or Cortex-M.
  362. */
  363. static void TC_CoreInstr_LoadStoreExclusive_IRQEnable(void) {
  364. #if defined(__CORTEX_M)
  365. TST_IRQHandler = TC_CoreInstr_LoadStoreExclusive_IRQHandler;
  366. NVIC_EnableIRQ(Interrupt0_IRQn);
  367. #elif defined(__CORTEX_A)
  368. IRQ_SetHandler(SGI0_IRQn, TC_CoreInstr_LoadStoreExclusive_IRQHandler);
  369. IRQ_Enable(SGI0_IRQn);
  370. #else
  371. #error __CORTEX_M or __CORTEX_A must be defined!
  372. #endif
  373. __enable_irq();
  374. }
  375. /**
  376. \brief Helper function for TC_CoreInstr_LoadStoreExclusive to set test interrupt pending.
  377. \details
  378. This helper function implements set pending the test interrupt according to target
  379. architecture, i.e. Cortex-A or Cortex-M.
  380. */
  381. static void TC_CoreInstr_LoadStoreExclusive_IRQPend(void) {
  382. #if defined(__CORTEX_M)
  383. NVIC_SetPendingIRQ(Interrupt0_IRQn);
  384. #elif defined(__CORTEX_A)
  385. IRQ_SetPending(SGI0_IRQn);
  386. #else
  387. #error __CORTEX_M or __CORTEX_A must be defined!
  388. #endif
  389. for(uint32_t i = 10U; i > 0U; --i) {}
  390. }
  391. /**
  392. \brief Helper function for TC_CoreInstr_LoadStoreExclusive to disable test interrupt.
  393. \details
  394. This helper function implements interrupt disabling according to target
  395. architecture, i.e. Cortex-A or Cortex-M.
  396. */
  397. static void TC_CoreInstr_LoadStoreExclusive_IRQDisable(void) {
  398. __disable_irq();
  399. #if defined(__CORTEX_M)
  400. NVIC_DisableIRQ(Interrupt0_IRQn);
  401. TST_IRQHandler = NULL;
  402. #elif defined(__CORTEX_A)
  403. IRQ_Disable(SGI0_IRQn);
  404. IRQ_SetHandler(SGI0_IRQn, NULL);
  405. #else
  406. #error __CORTEX_M or __CORTEX_A must be defined!
  407. #endif
  408. }
  409. #endif
  410. /**
  411. \brief Test case: TC_CoreInstr_LoadStoreExclusive
  412. \details
  413. Checks exclusive load and store instructions:
  414. - LDREXB, LDREXH, LDREXW
  415. - STREXB, STREXH, STREXW
  416. - CLREX
  417. */
  418. void TC_CoreInstr_LoadStoreExclusive (void) {
  419. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  420. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  421. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  422. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
  423. (defined(__CORTEX_A)) )
  424. uint8_t u8, u8Inv;
  425. uint16_t u16, u16Inv;
  426. uint32_t u32, u32Inv;
  427. uint32_t result;
  428. /* 1. Test exclusives without interruption */
  429. u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  430. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
  431. result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
  432. ASSERT_TRUE(result == 0U);
  433. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_byte == u8+1U);
  434. u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  435. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
  436. result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
  437. ASSERT_TRUE(result == 0U);
  438. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_hword == u16+1U);
  439. u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  440. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
  441. result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
  442. ASSERT_TRUE(result == 0U);
  443. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_word == u32+1U);
  444. /* 2. Test exclusives with clear */
  445. u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  446. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
  447. __CLREX();
  448. result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
  449. ASSERT_TRUE(result == 1U);
  450. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_byte == u8);
  451. u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  452. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
  453. __CLREX();
  454. result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
  455. ASSERT_TRUE(result == 1U);
  456. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_hword == u16);
  457. u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  458. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
  459. __CLREX();
  460. result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
  461. ASSERT_TRUE(result == 1U);
  462. ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_word == u32);
  463. /* 3. Test exclusives with interruption */
  464. TC_CoreInstr_LoadStoreExclusive_IRQEnable();
  465. u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
  466. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
  467. TC_CoreInstr_LoadStoreExclusive_IRQPend();
  468. result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
  469. ASSERT_TRUE(result == 1U);
  470. u8Inv = (uint8_t)~u8;
  471. ASSERT_TRUE(u8Inv == TC_CoreInstr_LoadStoreExclusive_byte);
  472. u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
  473. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
  474. TC_CoreInstr_LoadStoreExclusive_IRQPend();
  475. result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
  476. ASSERT_TRUE(result == 1U);
  477. u16Inv = (uint16_t)~u16;
  478. ASSERT_TRUE(u16Inv == TC_CoreInstr_LoadStoreExclusive_hword);
  479. u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
  480. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
  481. TC_CoreInstr_LoadStoreExclusive_IRQPend();
  482. result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
  483. ASSERT_TRUE(result == 1U);
  484. u32Inv = (uint32_t)~u32;
  485. ASSERT_TRUE(u32Inv == TC_CoreInstr_LoadStoreExclusive_word);
  486. TC_CoreInstr_LoadStoreExclusive_IRQDisable();
  487. #endif
  488. }
  489. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  490. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  491. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  492. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
  493. /// byte value unprivileged access
  494. static volatile uint8_t TC_CoreInstr_LoadStoreUnpriv_byte = 0x47U;
  495. /// halfword value unprivileged access
  496. static volatile uint16_t TC_CoreInstr_LoadStoreUnpriv_hword = 0x0815U;
  497. /// word value unprivileged access
  498. static volatile uint32_t TC_CoreInstr_LoadStoreUnpriv_word = 0x08154711U;
  499. #endif
  500. /**
  501. \brief Test case: TC_CoreInstr_LoadStoreUnpriv
  502. \details
  503. Checks load/store unprivileged instructions:
  504. - LDRBT, LDRHT, LDRT
  505. - STRBT, STRHT, STRT
  506. */
  507. void TC_CoreInstr_LoadStoreUnpriv (void) {
  508. #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
  509. (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
  510. (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
  511. uint8_t u8 = 0U;
  512. uint16_t u16 = 0U;
  513. uint32_t u32 = 0U;
  514. /* 1. Test without interruption */
  515. u8 = __LDRBT(&TC_CoreInstr_LoadStoreUnpriv_byte);
  516. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreUnpriv_byte);
  517. __STRBT(u8+1U, &TC_CoreInstr_LoadStoreUnpriv_byte);
  518. ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_byte == u8+1U);
  519. u16 = __LDRHT(&TC_CoreInstr_LoadStoreUnpriv_hword);
  520. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreUnpriv_hword);
  521. __STRHT(u16+1U, &TC_CoreInstr_LoadStoreUnpriv_hword);
  522. ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_hword == u16+1U);
  523. u32 = __LDRT(&TC_CoreInstr_LoadStoreUnpriv_word);
  524. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreUnpriv_word);
  525. __STRT(u32+1U, &TC_CoreInstr_LoadStoreUnpriv_word);
  526. ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_word == u32+1U);
  527. #endif
  528. }
  529. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  530. #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  531. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  532. /// byte value unprivileged access
  533. static volatile uint8_t TC_CoreInstr_LoadStoreAcquire_byte = 0x47U;
  534. /// halfword value unprivileged access
  535. static volatile uint16_t TC_CoreInstr_LoadStoreAcquire_hword = 0x0815U;
  536. /// word value unprivileged access
  537. static volatile uint32_t TC_CoreInstr_LoadStoreAcquire_word = 0x08154711U;
  538. #endif
  539. /**
  540. \brief Test case: TC_CoreInstr_LoadStoreAquire
  541. \details
  542. Checks Load-Acquire and Store-Release instructions:
  543. - LDAB, LDAH, LDA
  544. - STLB, STLH, STL
  545. */
  546. void TC_CoreInstr_LoadStoreAcquire (void) {
  547. #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  548. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  549. uint8_t u8 = 0U;
  550. uint16_t u16 = 0U;
  551. uint32_t u32 = 0U;
  552. /* 1. Test without interruption */
  553. u8 = __LDAB(&TC_CoreInstr_LoadStoreAcquire_byte);
  554. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreAcquire_byte);
  555. __STLB(u8+1U, &TC_CoreInstr_LoadStoreAcquire_byte);
  556. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_byte == u8+1U);
  557. u16 = __LDAH(&TC_CoreInstr_LoadStoreAcquire_hword);
  558. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreAcquire_hword);
  559. __STLH(u16+1U, &TC_CoreInstr_LoadStoreAcquire_hword);
  560. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_hword == u16+1U);
  561. u32 = __LDA(&TC_CoreInstr_LoadStoreAcquire_word);
  562. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreAcquire_word);
  563. __STL(u32+1U, &TC_CoreInstr_LoadStoreAcquire_word);
  564. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_word == u32+1U);
  565. #endif
  566. }
  567. /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
  568. #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  569. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  570. /// byte value unprivileged access
  571. static volatile uint8_t TC_CoreInstr_LoadStoreAcquireExclusive_byte = 0x47U;
  572. /// halfword value unprivileged access
  573. static volatile uint16_t TC_CoreInstr_LoadStoreAcquireExclusive_hword = 0x0815U;
  574. /// word value unprivileged access
  575. static volatile uint32_t TC_CoreInstr_LoadStoreAcquireExclusive_word = 0x08154711U;
  576. #endif
  577. /**
  578. \brief Test case: TC_CoreInstr_LoadStoreAquire
  579. \details
  580. Checks Load-Acquire and Store-Release exclusive instructions:
  581. - LDAEXB, LDAEXH, LDAEX
  582. - STLEXB, STLEXH, STLEX
  583. */
  584. void TC_CoreInstr_LoadStoreAcquireExclusive (void) {
  585. #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
  586. (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
  587. uint8_t u8 = 0U;
  588. uint16_t u16 = 0U;
  589. uint32_t u32 = 0U;
  590. uint32_t result = 0U;
  591. /* 1. Test without interruption */
  592. u8 = __LDAEXB(&TC_CoreInstr_LoadStoreAcquireExclusive_byte);
  593. ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreAcquireExclusive_byte);
  594. result = __STLEXB(u8+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_byte);
  595. ASSERT_TRUE(result == 0U);
  596. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_byte == u8+1U);
  597. u16 = __LDAEXH(&TC_CoreInstr_LoadStoreAcquireExclusive_hword);
  598. ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreAcquireExclusive_hword);
  599. result = __STLEXH(u16+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_hword);
  600. ASSERT_TRUE(result == 0U);
  601. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_hword == u16+1U);
  602. u32 = __LDAEX(&TC_CoreInstr_LoadStoreAcquireExclusive_word);
  603. ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreAcquireExclusive_word);
  604. result = __STLEX(u32+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_word);
  605. ASSERT_TRUE(result == 0U);
  606. ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_word == u32+1U);
  607. #endif
  608. }
  609. /**
  610. \brief Test case: TC_CoreInstr_UnalignedUint16
  611. \details
  612. Checks macro functions to access unaligned uint16_t values:
  613. - __UNALIGNED_UINT16_READ
  614. - __UNALIGNED_UINT16_WRITE
  615. */
  616. void TC_CoreInstr_UnalignedUint16(void) {
  617. uint8_t buffer[3] = { 0U, 0U, 0U };
  618. uint16_t val;
  619. for(int i=0; i<2; i++) {
  620. __UNALIGNED_UINT16_WRITE(&(buffer[i]), 0x4711U);
  621. ASSERT_TRUE(buffer[i] == 0x11U);
  622. ASSERT_TRUE(buffer[i+1] == 0x47U);
  623. ASSERT_TRUE(buffer[(i+2)%3] == 0x00U);
  624. buffer[i] = 0x12U;
  625. buffer[i+1] = 0x46U;
  626. val = __UNALIGNED_UINT16_READ(&(buffer[i]));
  627. ASSERT_TRUE(val == 0x4612U);
  628. buffer[i] = 0x00U;
  629. buffer[i+1] = 0x00U;
  630. }
  631. }
  632. /**
  633. \brief Test case: TC_CoreInstr_UnalignedUint32
  634. \details
  635. Checks macro functions to access unaligned uint32_t values:
  636. - __UNALIGNED_UINT32_READ
  637. - __UNALIGNED_UINT32_WRITE
  638. */
  639. void TC_CoreInstr_UnalignedUint32(void) {
  640. uint8_t buffer[7] = { 0U, 0U, 0U, 0U, 0U, 0U, 0U };
  641. uint32_t val;
  642. for(int i=0; i<4; i++) {
  643. __UNALIGNED_UINT32_WRITE(&(buffer[i]), 0x08154711UL);
  644. ASSERT_TRUE(buffer[i+0] == 0x11U);
  645. ASSERT_TRUE(buffer[i+1] == 0x47U);
  646. ASSERT_TRUE(buffer[i+2] == 0x15U);
  647. ASSERT_TRUE(buffer[i+3] == 0x08U);
  648. ASSERT_TRUE(buffer[(i+4)%7] == 0x00U);
  649. ASSERT_TRUE(buffer[(i+5)%7] == 0x00U);
  650. ASSERT_TRUE(buffer[(i+6)%7] == 0x00U);
  651. buffer[i+0] = 0x12U;
  652. buffer[i+1] = 0x46U;
  653. buffer[i+2] = 0x14U;
  654. buffer[i+3] = 0x09U;
  655. val = __UNALIGNED_UINT32_READ(&(buffer[i]));
  656. ASSERT_TRUE(val == 0x09144612UL);
  657. buffer[i+0] = 0x00U;
  658. buffer[i+1] = 0x00U;
  659. buffer[i+2] = 0x00U;
  660. buffer[i+3] = 0x00U;
  661. }
  662. }