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