Line data Source code
1 0 : /*
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 <zephyr/toolchain.h>
17 : #include <zephyr/types.h>
18 : #include <zephyr/sys/sys_io.h>
19 :
20 : #ifdef __cplusplus
21 : extern "C" {
22 : #endif
23 :
24 0 : 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 | (1U << bit);
29 : }
30 :
31 0 : 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 & ~(1U << bit);
36 : }
37 :
38 0 : 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 & (1U << bit);
43 : }
44 :
45 1 : static ALWAYS_INLINE void sys_set_bits(mem_addr_t addr, unsigned int mask)
46 : {
47 : uint32_t temp = *(volatile uint32_t *)addr;
48 :
49 : *(volatile uint32_t *)addr = temp | mask;
50 : }
51 :
52 1 : static ALWAYS_INLINE void sys_clear_bits(mem_addr_t addr, unsigned int mask)
53 : {
54 : uint32_t temp = *(volatile uint32_t *)addr;
55 :
56 : *(volatile uint32_t *)addr = temp & ~mask;
57 : }
58 :
59 : static ALWAYS_INLINE
60 0 : void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit)
61 : {
62 : /* Doing memory offsets in terms of 32-bit values to prevent
63 : * alignment issues
64 : */
65 : sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
66 : }
67 :
68 : static ALWAYS_INLINE
69 0 : void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit)
70 : {
71 : sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
72 : }
73 :
74 : static ALWAYS_INLINE
75 0 : int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit)
76 : {
77 : return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
78 : }
79 :
80 : static ALWAYS_INLINE
81 0 : int sys_test_and_set_bit(mem_addr_t addr, unsigned int bit)
82 : {
83 : int ret;
84 :
85 : ret = sys_test_bit(addr, bit);
86 : sys_set_bit(addr, bit);
87 :
88 : return ret;
89 : }
90 :
91 : static ALWAYS_INLINE
92 0 : int sys_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
93 : {
94 : int ret;
95 :
96 : ret = sys_test_bit(addr, bit);
97 : sys_clear_bit(addr, bit);
98 :
99 : return ret;
100 : }
101 :
102 : static ALWAYS_INLINE
103 0 : int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit)
104 : {
105 : int ret;
106 :
107 : ret = sys_bitfield_test_bit(addr, bit);
108 : sys_bitfield_set_bit(addr, bit);
109 :
110 : return ret;
111 : }
112 :
113 : static ALWAYS_INLINE
114 0 : int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
115 : {
116 : int ret;
117 :
118 : ret = sys_bitfield_test_bit(addr, bit);
119 : sys_bitfield_clear_bit(addr, bit);
120 :
121 : return ret;
122 : }
123 :
124 : #ifdef __cplusplus
125 : }
126 : #endif
127 :
128 : #endif /* _ASMLANGUAGE */
129 :
130 : #endif /* ZEPHYR_INCLUDE_ARCH_COMMON_SYS_BITOPS_H_ */
|