1 /*
2  * Copyright (c) 2024 NextSilicon LTD
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <zephyr/ztest.h>
7 #include <zephyr/sys/atomic.h>
8 #include <zephyr/arch/riscv/atomic.h>
9 
10 /**
11  * @brief Verify RISC-V specific atomic functionalities
12  * @details
13  * Test Objective:
14  * - Test if the RISC-V atomic instructions API is correct.
15  *
16  * Test Procedure:
17  * - Call the API interface of the following atomic operations in turn,
18  * decision is based on function return value and target operands.
19  * - atomic_swap()
20  * - atomic_max()
21  * - atomic_min()
22  *
23  * Expected Test Result:
24  * - The function return value and target operands are correct.
25  *
26  * Pass/Fail Criteria:
27  * - Successful if all check points in the test procedure have passed, failure otherwise.
28  */
29 
30 #define ATOMIC_WORD(val_if_64, val_if_32)                                                          \
31 	((atomic_t)((sizeof(void *) == sizeof(uint64_t)) ? (val_if_64) : (val_if_32)))
32 
ZTEST_USER(riscv_atomic,test_atomic)33 ZTEST_USER(riscv_atomic, test_atomic)
34 {
35 	atomic_t target;
36 	atomic_val_t value;
37 	unsigned long utarget, uvalue;
38 
39 	zassert_equal(sizeof(atomic_t), ATOMIC_WORD(sizeof(uint64_t), sizeof(uint32_t)),
40 		      "sizeof(atomic_t)");
41 
42 	/* atomic_swap */
43 	target = 21;
44 	value = 7;
45 	zassert_true((atomic_swap(&target, value) == 21), "atomic_swap");
46 	zassert_true((target == 7), "atomic_swap");
47 
48 	/* atomic_max */
49 	target = 5;
50 	value = -8;
51 	zassert_true((atomic_max(&target, value) == 5), "atomic_max");
52 	zassert_true((target == 5), "atomic_max");
53 
54 	/* atomic_min */
55 	target = 5;
56 	value = -8;
57 	zassert_true((atomic_min(&target, value) == 5), "atomic_min");
58 	zassert_true((target == -8), "atomic_min");
59 
60 	/* atomic_max unsigned */
61 	utarget = 5;
62 	uvalue = ATOMIC_WORD(0xffffffff00000000, 0xffff0000);
63 	zassert_true((atomic_maxu(&utarget, uvalue) == 5), "atomic_maxu");
64 	zassert_true((utarget == ATOMIC_WORD(0xffffffff00000000, 0xffff0000)), "atomic_maxu");
65 
66 	/* atomic_min unsigned */
67 	utarget = 5;
68 	uvalue = ATOMIC_WORD(0xffffffff00000000, 0xffff0000);
69 	zassert_true((atomic_minu(&utarget, uvalue) == 5), "atomic_minu");
70 	zassert_true((utarget == 5), "atomic_minu");
71 }
72 
73 ZTEST_SUITE(riscv_atomic, NULL, NULL, NULL, NULL, NULL);
74