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 "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 */
TC_CoreInstr_NOP(void)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 */
TC_CoreInstr_SEV(void)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 */
TC_CoreInstr_BKPT(void)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 */
TC_CoreInstr_ISB(void)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 */
TC_CoreInstr_DSB(void)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 */
TC_CoreInstr_DMB(void)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 */
TC_CoreInstr_WFI(void)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 */
TC_CoreInstr_WFE(void)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 */
TC_CoreInstr_REV(void)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 */
TC_CoreInstr_REV16(void)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 */
TC_CoreInstr_REVSH(void)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 */
TC_CoreInstr_RBIT(void)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 */
TC_CoreInstr_ROR(void)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 */
TC_CoreInstr_CLZ(void)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 */
TC_CoreInstr_SSAT(void)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 */
TC_CoreInstr_USAT(void)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 */
TC_CoreInstr_RRX(void)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 (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
385
386 volatile uint32_t value = 0U;
387 volatile uint32_t result = 0U;
388 volatile xPSR_Type xPSR;
389
390 value = 0x80000002;
391 xPSR.w = __get_xPSR();
392 result = __RRX(value);
393 ASSERT_TRUE(result == (0x40000001 | (uint32_t)(xPSR.b.C << 31)));
394 #endif
395 }
396
397 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
398 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
399 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
400 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
401 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
402 (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
403 (defined(__CORTEX_A) ) )
404
405 /// Exclusive byte value
406 static volatile uint8_t TC_CoreInstr_LoadStoreExclusive_byte = 0x47U;
407
408 /// Exclusive halfword value
409 static volatile uint16_t TC_CoreInstr_LoadStoreExclusive_hword = 0x0815U;
410
411 /// Exclusive word value
412 static volatile uint32_t TC_CoreInstr_LoadStoreExclusive_word = 0x08154711U;
413
414 /**
415 \brief Interrupt function for TC_CoreInstr_LoadStoreExclusive
416 \details
417 The interrupt manipulates all the global data
418 which disrupts the exclusive sequences in the test
419 */
TC_CoreInstr_LoadStoreExclusive_IRQHandler(void)420 static void TC_CoreInstr_LoadStoreExclusive_IRQHandler(void) {
421
422 const uint8_t b = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
423 __STREXB((uint8_t)~b, &TC_CoreInstr_LoadStoreExclusive_byte);
424
425 const uint16_t hw = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
426 __STREXH((uint16_t)~hw, &TC_CoreInstr_LoadStoreExclusive_hword);
427
428 const uint32_t w = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
429 __STREXW((uint32_t)~w, &TC_CoreInstr_LoadStoreExclusive_word);
430 }
431
432 /**
433 \brief Helper function for TC_CoreInstr_LoadStoreExclusive to enable test interrupt.
434 \details
435 This helper function implements interrupt enabling according to target
436 architecture, i.e. Cortex-A or Cortex-M.
437 */
TC_CoreInstr_LoadStoreExclusive_IRQEnable(void)438 static void TC_CoreInstr_LoadStoreExclusive_IRQEnable(void) {
439 #if defined(__CORTEX_M)
440 TST_IRQHandler = TC_CoreInstr_LoadStoreExclusive_IRQHandler;
441 NVIC_EnableIRQ(Interrupt0_IRQn);
442 #elif defined(__CORTEX_A)
443 IRQ_SetHandler(SGI0_IRQn, TC_CoreInstr_LoadStoreExclusive_IRQHandler);
444 IRQ_Enable(SGI0_IRQn);
445 #else
446 #error __CORTEX_M or __CORTEX_A must be defined!
447 #endif
448 __enable_irq();
449 }
450
451 /**
452 \brief Helper function for TC_CoreInstr_LoadStoreExclusive to set test interrupt pending.
453 \details
454 This helper function implements set pending the test interrupt according to target
455 architecture, i.e. Cortex-A or Cortex-M.
456 */
TC_CoreInstr_LoadStoreExclusive_IRQPend(void)457 static void TC_CoreInstr_LoadStoreExclusive_IRQPend(void) {
458 #if defined(__CORTEX_M)
459 NVIC_SetPendingIRQ(Interrupt0_IRQn);
460 #elif defined(__CORTEX_A)
461 IRQ_SetPending(SGI0_IRQn);
462 #else
463 #error __CORTEX_M or __CORTEX_A must be defined!
464 #endif
465 __ISB();
466 for(uint32_t i = 10U; i > 0U; --i) {}
467 }
468
469 /**
470 \brief Helper function for TC_CoreInstr_LoadStoreExclusive to disable test interrupt.
471 \details
472 This helper function implements interrupt disabling according to target
473 architecture, i.e. Cortex-A or Cortex-M.
474 */
TC_CoreInstr_LoadStoreExclusive_IRQDisable(void)475 static void TC_CoreInstr_LoadStoreExclusive_IRQDisable(void) {
476 __disable_irq();
477 #if defined(__CORTEX_M)
478 NVIC_DisableIRQ(Interrupt0_IRQn);
479 TST_IRQHandler = NULL;
480 #elif defined(__CORTEX_A)
481 IRQ_Disable(SGI0_IRQn);
482 IRQ_SetHandler(SGI0_IRQn, NULL);
483 #else
484 #error __CORTEX_M or __CORTEX_A must be defined!
485 #endif
486 }
487 #endif
488
489 /**
490 \brief Test case: TC_CoreInstr_LoadStoreExclusive
491 \details
492 Checks exclusive load and store instructions:
493 - LDREXB, LDREXH, LDREXW
494 - STREXB, STREXH, STREXW
495 - CLREX
496 */
TC_CoreInstr_LoadStoreExclusive(void)497 void TC_CoreInstr_LoadStoreExclusive (void) {
498 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
499 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
500 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
501 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
502 (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
503 (defined(__CORTEX_A) ) )
504 uint8_t u8, u8Inv;
505 uint16_t u16, u16Inv;
506 uint32_t u32, u32Inv;
507 uint32_t result;
508
509 /* 1. Test exclusives without interruption */
510 u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
511 ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
512
513 result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
514 ASSERT_TRUE(result == 0U);
515 ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_byte == u8+1U);
516
517 u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
518 ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
519
520 result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
521 ASSERT_TRUE(result == 0U);
522 ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_hword == u16+1U);
523
524 u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
525 ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
526
527 result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
528 ASSERT_TRUE(result == 0U);
529 ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_word == u32+1U);
530
531 /* 2. Test exclusives with clear */
532 u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
533 ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
534
535 __CLREX();
536
537 result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
538 ASSERT_TRUE(result == 1U);
539 ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_byte == u8);
540
541 u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
542 ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
543
544 __CLREX();
545
546 result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
547 ASSERT_TRUE(result == 1U);
548 ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_hword == u16);
549
550 u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
551 ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
552
553 __CLREX();
554
555 result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
556 ASSERT_TRUE(result == 1U);
557 ASSERT_TRUE(TC_CoreInstr_LoadStoreExclusive_word == u32);
558
559 /* 3. Test exclusives with interruption */
560 TC_CoreInstr_LoadStoreExclusive_IRQEnable();
561
562 u8 = __LDREXB(&TC_CoreInstr_LoadStoreExclusive_byte);
563 ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreExclusive_byte);
564
565 TC_CoreInstr_LoadStoreExclusive_IRQPend();
566
567 result = __STREXB(u8+1U, &TC_CoreInstr_LoadStoreExclusive_byte);
568 ASSERT_TRUE(result == 1U);
569 u8Inv = (uint8_t)~u8;
570 ASSERT_TRUE(u8Inv == TC_CoreInstr_LoadStoreExclusive_byte);
571
572 u16 = __LDREXH(&TC_CoreInstr_LoadStoreExclusive_hword);
573 ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreExclusive_hword);
574
575 TC_CoreInstr_LoadStoreExclusive_IRQPend();
576
577 result = __STREXH(u16+1U, &TC_CoreInstr_LoadStoreExclusive_hword);
578 ASSERT_TRUE(result == 1U);
579 u16Inv = (uint16_t)~u16;
580 ASSERT_TRUE(u16Inv == TC_CoreInstr_LoadStoreExclusive_hword);
581
582 u32 = __LDREXW(&TC_CoreInstr_LoadStoreExclusive_word);
583 ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreExclusive_word);
584
585 TC_CoreInstr_LoadStoreExclusive_IRQPend();
586
587 result = __STREXW(u32+1U, &TC_CoreInstr_LoadStoreExclusive_word);
588 ASSERT_TRUE(result == 1U);
589 u32Inv = (uint32_t)~u32;
590 ASSERT_TRUE(u32Inv == TC_CoreInstr_LoadStoreExclusive_word);
591
592 TC_CoreInstr_LoadStoreExclusive_IRQDisable();
593 #endif
594 }
595
596 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
597 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
598 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
599 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
600 (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
601
602 /// byte value unprivileged access
603 static volatile uint8_t TC_CoreInstr_LoadStoreUnpriv_byte = 0x47U;
604
605 /// halfword value unprivileged access
606 static volatile uint16_t TC_CoreInstr_LoadStoreUnpriv_hword = 0x0815U;
607
608 /// word value unprivileged access
609 static volatile uint32_t TC_CoreInstr_LoadStoreUnpriv_word = 0x08154711U;
610 #endif
611
612
613 /**
614 \brief Test case: TC_CoreInstr_LoadStoreUnpriv
615 \details
616 Checks load/store unprivileged instructions:
617 - LDRBT, LDRHT, LDRT
618 - STRBT, STRHT, STRT
619 */
TC_CoreInstr_LoadStoreUnpriv(void)620 void TC_CoreInstr_LoadStoreUnpriv (void) {
621 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
622 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
623 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
624 (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
625 uint8_t u8 = 0U;
626 uint16_t u16 = 0U;
627 uint32_t u32 = 0U;
628
629 /* 1. Test without interruption */
630 u8 = __LDRBT(&TC_CoreInstr_LoadStoreUnpriv_byte);
631 ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreUnpriv_byte);
632
633 __STRBT(u8+1U, &TC_CoreInstr_LoadStoreUnpriv_byte);
634 ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_byte == u8+1U);
635
636 u16 = __LDRHT(&TC_CoreInstr_LoadStoreUnpriv_hword);
637 ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreUnpriv_hword);
638
639 __STRHT(u16+1U, &TC_CoreInstr_LoadStoreUnpriv_hword);
640 ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_hword == u16+1U);
641
642 u32 = __LDRT(&TC_CoreInstr_LoadStoreUnpriv_word);
643 ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreUnpriv_word);
644
645 __STRT(u32+1U, &TC_CoreInstr_LoadStoreUnpriv_word);
646 ASSERT_TRUE(TC_CoreInstr_LoadStoreUnpriv_word == u32+1U);
647 #endif
648 }
649
650 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
651 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
652 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
653 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
654
655 /// byte value unprivileged access
656 static volatile uint8_t TC_CoreInstr_LoadStoreAcquire_byte = 0x47U;
657
658 /// halfword value unprivileged access
659 static volatile uint16_t TC_CoreInstr_LoadStoreAcquire_hword = 0x0815U;
660
661 /// word value unprivileged access
662 static volatile uint32_t TC_CoreInstr_LoadStoreAcquire_word = 0x08154711U;
663 #endif
664
665
666 /**
667 \brief Test case: TC_CoreInstr_LoadStoreAquire
668 \details
669 Checks Load-Acquire and Store-Release instructions:
670 - LDAB, LDAH, LDA
671 - STLB, STLH, STL
672 */
TC_CoreInstr_LoadStoreAcquire(void)673 void TC_CoreInstr_LoadStoreAcquire (void) {
674 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
675 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
676 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
677 uint8_t u8 = 0U;
678 uint16_t u16 = 0U;
679 uint32_t u32 = 0U;
680
681 /* 1. Test without interruption */
682 u8 = __LDAB(&TC_CoreInstr_LoadStoreAcquire_byte);
683 ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreAcquire_byte);
684
685 __STLB(u8+1U, &TC_CoreInstr_LoadStoreAcquire_byte);
686 ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_byte == u8+1U);
687
688 u16 = __LDAH(&TC_CoreInstr_LoadStoreAcquire_hword);
689 ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreAcquire_hword);
690
691 __STLH(u16+1U, &TC_CoreInstr_LoadStoreAcquire_hword);
692 ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_hword == u16+1U);
693
694 u32 = __LDA(&TC_CoreInstr_LoadStoreAcquire_word);
695 ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreAcquire_word);
696
697 __STL(u32+1U, &TC_CoreInstr_LoadStoreAcquire_word);
698 ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquire_word == u32+1U);
699 #endif
700 }
701
702 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
703 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
704 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
705 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
706
707 /// byte value unprivileged access
708 static volatile uint8_t TC_CoreInstr_LoadStoreAcquireExclusive_byte = 0x47U;
709
710 /// halfword value unprivileged access
711 static volatile uint16_t TC_CoreInstr_LoadStoreAcquireExclusive_hword = 0x0815U;
712
713 /// word value unprivileged access
714 static volatile uint32_t TC_CoreInstr_LoadStoreAcquireExclusive_word = 0x08154711U;
715 #endif
716
717
718 /**
719 \brief Test case: TC_CoreInstr_LoadStoreAquire
720 \details
721 Checks Load-Acquire and Store-Release exclusive instructions:
722 - LDAEXB, LDAEXH, LDAEX
723 - STLEXB, STLEXH, STLEX
724 */
TC_CoreInstr_LoadStoreAcquireExclusive(void)725 void TC_CoreInstr_LoadStoreAcquireExclusive (void) {
726 #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
727 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
728 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
729 uint8_t u8 = 0U;
730 uint16_t u16 = 0U;
731 uint32_t u32 = 0U;
732 uint32_t result = 0U;
733
734 /* 1. Test without interruption */
735 u8 = __LDAEXB(&TC_CoreInstr_LoadStoreAcquireExclusive_byte);
736 ASSERT_TRUE(u8 == TC_CoreInstr_LoadStoreAcquireExclusive_byte);
737
738 result = __STLEXB(u8+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_byte);
739 ASSERT_TRUE(result == 0U);
740 ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_byte == u8+1U);
741
742 u16 = __LDAEXH(&TC_CoreInstr_LoadStoreAcquireExclusive_hword);
743 ASSERT_TRUE(u16 == TC_CoreInstr_LoadStoreAcquireExclusive_hword);
744
745 result = __STLEXH(u16+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_hword);
746 ASSERT_TRUE(result == 0U);
747 ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_hword == u16+1U);
748
749 u32 = __LDAEX(&TC_CoreInstr_LoadStoreAcquireExclusive_word);
750 ASSERT_TRUE(u32 == TC_CoreInstr_LoadStoreAcquireExclusive_word);
751
752 result = __STLEX(u32+1U, &TC_CoreInstr_LoadStoreAcquireExclusive_word);
753 ASSERT_TRUE(result == 0U);
754 ASSERT_TRUE(TC_CoreInstr_LoadStoreAcquireExclusive_word == u32+1U);
755 #endif
756 }
757
758
759 /**
760 \brief Test case: TC_CoreInstr_UnalignedUint16
761 \details
762 Checks macro functions to access unaligned uint16_t values:
763 - __UNALIGNED_UINT16_READ
764 - __UNALIGNED_UINT16_WRITE
765 */
TC_CoreInstr_UnalignedUint16(void)766 void TC_CoreInstr_UnalignedUint16(void) {
767 uint8_t buffer[3] = { 0U, 0U, 0U };
768 uint16_t val;
769
770 for(int i=0; i<2; i++) {
771 __UNALIGNED_UINT16_WRITE(&(buffer[i]), 0x4711U);
772 ASSERT_TRUE(buffer[i] == 0x11U);
773 ASSERT_TRUE(buffer[i+1] == 0x47U);
774 ASSERT_TRUE(buffer[(i+2)%3] == 0x00U);
775
776 buffer[i] = 0x12U;
777 buffer[i+1] = 0x46U;
778
779 val = __UNALIGNED_UINT16_READ(&(buffer[i]));
780 ASSERT_TRUE(val == 0x4612U);
781
782 buffer[i] = 0x00U;
783 buffer[i+1] = 0x00U;
784 }
785 }
786
787
788 /**
789 \brief Test case: TC_CoreInstr_UnalignedUint32
790 \details
791 Checks macro functions to access unaligned uint32_t values:
792 - __UNALIGNED_UINT32_READ
793 - __UNALIGNED_UINT32_WRITE
794 */
TC_CoreInstr_UnalignedUint32(void)795 void TC_CoreInstr_UnalignedUint32(void) {
796 uint8_t buffer[7] = { 0U, 0U, 0U, 0U, 0U, 0U, 0U };
797 uint32_t val;
798
799 for(int i=0; i<4; i++) {
800 __UNALIGNED_UINT32_WRITE(&(buffer[i]), 0x08154711UL);
801 ASSERT_TRUE(buffer[i+0] == 0x11U);
802 ASSERT_TRUE(buffer[i+1] == 0x47U);
803 ASSERT_TRUE(buffer[i+2] == 0x15U);
804 ASSERT_TRUE(buffer[i+3] == 0x08U);
805 ASSERT_TRUE(buffer[(i+4)%7] == 0x00U);
806 ASSERT_TRUE(buffer[(i+5)%7] == 0x00U);
807 ASSERT_TRUE(buffer[(i+6)%7] == 0x00U);
808
809 buffer[i+0] = 0x12U;
810 buffer[i+1] = 0x46U;
811 buffer[i+2] = 0x14U;
812 buffer[i+3] = 0x09U;
813
814 val = __UNALIGNED_UINT32_READ(&(buffer[i]));
815 ASSERT_TRUE(val == 0x09144612UL);
816
817 buffer[i+0] = 0x00U;
818 buffer[i+1] = 0x00U;
819 buffer[i+2] = 0x00U;
820 buffer[i+3] = 0x00U;
821 }
822 }
823