648db22b |
1 | /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ |
2 | /* |
3 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
4 | * All rights reserved. |
5 | * |
6 | * This source code is licensed under both the BSD-style license (found in the |
7 | * LICENSE file in the root directory of this source tree) and the GPLv2 (found |
8 | * in the COPYING file in the root directory of this source tree). |
9 | * You may select, at your option, one of the above-listed licenses. |
10 | */ |
11 | |
12 | #ifndef MEM_H_MODULE |
13 | #define MEM_H_MODULE |
14 | |
15 | /*-**************************************** |
16 | * Dependencies |
17 | ******************************************/ |
18 | #include <asm/unaligned.h> /* get_unaligned, put_unaligned* */ |
19 | #include <linux/compiler.h> /* inline */ |
20 | #include <linux/swab.h> /* swab32, swab64 */ |
21 | #include <linux/types.h> /* size_t, ptrdiff_t */ |
22 | #include "debug.h" /* DEBUG_STATIC_ASSERT */ |
23 | |
24 | /*-**************************************** |
25 | * Compiler specifics |
26 | ******************************************/ |
f535537f |
27 | #undef MEM_STATIC /* may be already defined from common/compiler.h */ |
648db22b |
28 | #define MEM_STATIC static inline |
29 | |
30 | /*-************************************************************** |
31 | * Basic Types |
32 | *****************************************************************/ |
33 | typedef uint8_t BYTE; |
34 | typedef uint8_t U8; |
35 | typedef int8_t S8; |
36 | typedef uint16_t U16; |
37 | typedef int16_t S16; |
38 | typedef uint32_t U32; |
39 | typedef int32_t S32; |
40 | typedef uint64_t U64; |
41 | typedef int64_t S64; |
42 | |
43 | /*-************************************************************** |
44 | * Memory I/O API |
45 | *****************************************************************/ |
46 | /*=== Static platform detection ===*/ |
47 | MEM_STATIC unsigned MEM_32bits(void); |
48 | MEM_STATIC unsigned MEM_64bits(void); |
49 | MEM_STATIC unsigned MEM_isLittleEndian(void); |
50 | |
51 | /*=== Native unaligned read/write ===*/ |
52 | MEM_STATIC U16 MEM_read16(const void* memPtr); |
53 | MEM_STATIC U32 MEM_read32(const void* memPtr); |
54 | MEM_STATIC U64 MEM_read64(const void* memPtr); |
55 | MEM_STATIC size_t MEM_readST(const void* memPtr); |
56 | |
57 | MEM_STATIC void MEM_write16(void* memPtr, U16 value); |
58 | MEM_STATIC void MEM_write32(void* memPtr, U32 value); |
59 | MEM_STATIC void MEM_write64(void* memPtr, U64 value); |
60 | |
61 | /*=== Little endian unaligned read/write ===*/ |
62 | MEM_STATIC U16 MEM_readLE16(const void* memPtr); |
63 | MEM_STATIC U32 MEM_readLE24(const void* memPtr); |
64 | MEM_STATIC U32 MEM_readLE32(const void* memPtr); |
65 | MEM_STATIC U64 MEM_readLE64(const void* memPtr); |
66 | MEM_STATIC size_t MEM_readLEST(const void* memPtr); |
67 | |
68 | MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); |
69 | MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); |
70 | MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); |
71 | MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); |
72 | MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); |
73 | |
74 | /*=== Big endian unaligned read/write ===*/ |
75 | MEM_STATIC U32 MEM_readBE32(const void* memPtr); |
76 | MEM_STATIC U64 MEM_readBE64(const void* memPtr); |
77 | MEM_STATIC size_t MEM_readBEST(const void* memPtr); |
78 | |
79 | MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); |
80 | MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); |
81 | MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); |
82 | |
83 | /*=== Byteswap ===*/ |
84 | MEM_STATIC U32 MEM_swap32(U32 in); |
85 | MEM_STATIC U64 MEM_swap64(U64 in); |
86 | MEM_STATIC size_t MEM_swapST(size_t in); |
87 | |
88 | /*-************************************************************** |
89 | * Memory I/O Implementation |
90 | *****************************************************************/ |
91 | MEM_STATIC unsigned MEM_32bits(void) |
92 | { |
93 | return sizeof(size_t) == 4; |
94 | } |
95 | |
96 | MEM_STATIC unsigned MEM_64bits(void) |
97 | { |
98 | return sizeof(size_t) == 8; |
99 | } |
100 | |
101 | #if defined(__LITTLE_ENDIAN) |
102 | #define MEM_LITTLE_ENDIAN 1 |
103 | #else |
104 | #define MEM_LITTLE_ENDIAN 0 |
105 | #endif |
106 | |
107 | MEM_STATIC unsigned MEM_isLittleEndian(void) |
108 | { |
109 | return MEM_LITTLE_ENDIAN; |
110 | } |
111 | |
112 | MEM_STATIC U16 MEM_read16(const void *memPtr) |
113 | { |
114 | return get_unaligned((const U16 *)memPtr); |
115 | } |
116 | |
117 | MEM_STATIC U32 MEM_read32(const void *memPtr) |
118 | { |
119 | return get_unaligned((const U32 *)memPtr); |
120 | } |
121 | |
122 | MEM_STATIC U64 MEM_read64(const void *memPtr) |
123 | { |
124 | return get_unaligned((const U64 *)memPtr); |
125 | } |
126 | |
127 | MEM_STATIC size_t MEM_readST(const void *memPtr) |
128 | { |
129 | return get_unaligned((const size_t *)memPtr); |
130 | } |
131 | |
132 | MEM_STATIC void MEM_write16(void *memPtr, U16 value) |
133 | { |
134 | put_unaligned(value, (U16 *)memPtr); |
135 | } |
136 | |
137 | MEM_STATIC void MEM_write32(void *memPtr, U32 value) |
138 | { |
139 | put_unaligned(value, (U32 *)memPtr); |
140 | } |
141 | |
142 | MEM_STATIC void MEM_write64(void *memPtr, U64 value) |
143 | { |
144 | put_unaligned(value, (U64 *)memPtr); |
145 | } |
146 | |
147 | /*=== Little endian r/w ===*/ |
148 | |
149 | MEM_STATIC U16 MEM_readLE16(const void *memPtr) |
150 | { |
151 | return get_unaligned_le16(memPtr); |
152 | } |
153 | |
154 | MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val) |
155 | { |
156 | put_unaligned_le16(val, memPtr); |
157 | } |
158 | |
159 | MEM_STATIC U32 MEM_readLE24(const void *memPtr) |
160 | { |
161 | return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16); |
162 | } |
163 | |
164 | MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val) |
165 | { |
166 | MEM_writeLE16(memPtr, (U16)val); |
167 | ((BYTE *)memPtr)[2] = (BYTE)(val >> 16); |
168 | } |
169 | |
170 | MEM_STATIC U32 MEM_readLE32(const void *memPtr) |
171 | { |
172 | return get_unaligned_le32(memPtr); |
173 | } |
174 | |
175 | MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32) |
176 | { |
177 | put_unaligned_le32(val32, memPtr); |
178 | } |
179 | |
180 | MEM_STATIC U64 MEM_readLE64(const void *memPtr) |
181 | { |
182 | return get_unaligned_le64(memPtr); |
183 | } |
184 | |
185 | MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64) |
186 | { |
187 | put_unaligned_le64(val64, memPtr); |
188 | } |
189 | |
190 | MEM_STATIC size_t MEM_readLEST(const void *memPtr) |
191 | { |
192 | if (MEM_32bits()) |
193 | return (size_t)MEM_readLE32(memPtr); |
194 | else |
195 | return (size_t)MEM_readLE64(memPtr); |
196 | } |
197 | |
198 | MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val) |
199 | { |
200 | if (MEM_32bits()) |
201 | MEM_writeLE32(memPtr, (U32)val); |
202 | else |
203 | MEM_writeLE64(memPtr, (U64)val); |
204 | } |
205 | |
206 | /*=== Big endian r/w ===*/ |
207 | |
208 | MEM_STATIC U32 MEM_readBE32(const void *memPtr) |
209 | { |
210 | return get_unaligned_be32(memPtr); |
211 | } |
212 | |
213 | MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32) |
214 | { |
215 | put_unaligned_be32(val32, memPtr); |
216 | } |
217 | |
218 | MEM_STATIC U64 MEM_readBE64(const void *memPtr) |
219 | { |
220 | return get_unaligned_be64(memPtr); |
221 | } |
222 | |
223 | MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64) |
224 | { |
225 | put_unaligned_be64(val64, memPtr); |
226 | } |
227 | |
228 | MEM_STATIC size_t MEM_readBEST(const void *memPtr) |
229 | { |
230 | if (MEM_32bits()) |
231 | return (size_t)MEM_readBE32(memPtr); |
232 | else |
233 | return (size_t)MEM_readBE64(memPtr); |
234 | } |
235 | |
236 | MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val) |
237 | { |
238 | if (MEM_32bits()) |
239 | MEM_writeBE32(memPtr, (U32)val); |
240 | else |
241 | MEM_writeBE64(memPtr, (U64)val); |
242 | } |
243 | |
244 | MEM_STATIC U32 MEM_swap32(U32 in) |
245 | { |
246 | return swab32(in); |
247 | } |
248 | |
249 | MEM_STATIC U64 MEM_swap64(U64 in) |
250 | { |
251 | return swab64(in); |
252 | } |
253 | |
254 | MEM_STATIC size_t MEM_swapST(size_t in) |
255 | { |
256 | if (MEM_32bits()) |
257 | return (size_t)MEM_swap32((U32)in); |
258 | else |
259 | return (size_t)MEM_swap64((U64)in); |
260 | } |
261 | |
262 | #endif /* MEM_H_MODULE */ |