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