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