1 /*
2 * Copyright (c) 2020, Wind River Systems, Inc.
3 * Copyright (c) 2017, Oticon A/S
4 * Copyright (c) 2020, Synopsys
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 /* Memory bits manipulation functions in non-arch-specific C code */
10
11 #ifndef ZEPHYR_INCLUDE_ARCH_COMMON_SYS_BITOPS_H_
12 #define ZEPHYR_INCLUDE_ARCH_COMMON_SYS_BITOPS_H_
13
14 #ifndef _ASMLANGUAGE
15
16 #include <toolchain.h>
17 #include <zephyr/types.h>
18 #include <sys/sys_io.h>
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
sys_set_bit(mem_addr_t addr,unsigned int bit)24 static ALWAYS_INLINE void sys_set_bit(mem_addr_t addr, unsigned int bit)
25 {
26 uint32_t temp = *(volatile uint32_t *)addr;
27
28 *(volatile uint32_t *)addr = temp | (1 << bit);
29 }
30
sys_clear_bit(mem_addr_t addr,unsigned int bit)31 static ALWAYS_INLINE void sys_clear_bit(mem_addr_t addr, unsigned int bit)
32 {
33 uint32_t temp = *(volatile uint32_t *)addr;
34
35 *(volatile uint32_t *)addr = temp & ~(1 << bit);
36 }
37
sys_test_bit(mem_addr_t addr,unsigned int bit)38 static ALWAYS_INLINE int sys_test_bit(mem_addr_t addr, unsigned int bit)
39 {
40 uint32_t temp = *(volatile uint32_t *)addr;
41
42 return temp & (1 << bit);
43 }
44
45 static ALWAYS_INLINE
sys_bitfield_set_bit(mem_addr_t addr,unsigned int bit)46 void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit)
47 {
48 /* Doing memory offsets in terms of 32-bit values to prevent
49 * alignment issues
50 */
51 sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
52 }
53
54 static ALWAYS_INLINE
sys_bitfield_clear_bit(mem_addr_t addr,unsigned int bit)55 void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit)
56 {
57 sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
58 }
59
60 static ALWAYS_INLINE
sys_bitfield_test_bit(mem_addr_t addr,unsigned int bit)61 int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit)
62 {
63 return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
64 }
65
66 static ALWAYS_INLINE
sys_test_and_set_bit(mem_addr_t addr,unsigned int bit)67 int sys_test_and_set_bit(mem_addr_t addr, unsigned int bit)
68 {
69 int ret;
70
71 ret = sys_test_bit(addr, bit);
72 sys_set_bit(addr, bit);
73
74 return ret;
75 }
76
77 static ALWAYS_INLINE
sys_test_and_clear_bit(mem_addr_t addr,unsigned int bit)78 int sys_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
79 {
80 int ret;
81
82 ret = sys_test_bit(addr, bit);
83 sys_clear_bit(addr, bit);
84
85 return ret;
86 }
87
88 static ALWAYS_INLINE
sys_bitfield_test_and_set_bit(mem_addr_t addr,unsigned int bit)89 int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit)
90 {
91 int ret;
92
93 ret = sys_bitfield_test_bit(addr, bit);
94 sys_bitfield_set_bit(addr, bit);
95
96 return ret;
97 }
98
99 static ALWAYS_INLINE
sys_bitfield_test_and_clear_bit(mem_addr_t addr,unsigned int bit)100 int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
101 {
102 int ret;
103
104 ret = sys_bitfield_test_bit(addr, bit);
105 sys_bitfield_clear_bit(addr, bit);
106
107 return ret;
108 }
109
110 #ifdef __cplusplus
111 }
112 #endif
113
114 #endif /* _ASMLANGUAGE */
115
116 #endif /* ZEPHYR_INCLUDE_ARCH_COMMON_SYS_BITOPS_H_ */
117