blob: 552ce0025eec34d5accfc651fc6a38690c5850d5 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Hung-Te Lin6fe0cab2013-01-22 18:57:56 +08002
3#ifndef _ENDIAN_H_
4#define _ENDIAN_H_
5
6#include <arch/byteorder.h>
Julius Werner9ff8f6f2015-02-23 14:31:09 -08007#include <stdint.h>
8#include <swab.h>
9
10#if defined(__LITTLE_ENDIAN)
11 #define cpu_to_le64(x) ((uint64_t)(x))
12 #define le64_to_cpu(x) ((uint64_t)(x))
13 #define cpu_to_le32(x) ((uint32_t)(x))
14 #define le32_to_cpu(x) ((uint32_t)(x))
15 #define cpu_to_le16(x) ((uint16_t)(x))
16 #define le16_to_cpu(x) ((uint16_t)(x))
17 #define cpu_to_be64(x) swab64(x)
18 #define be64_to_cpu(x) swab64(x)
19 #define cpu_to_be32(x) swab32(x)
20 #define be32_to_cpu(x) swab32(x)
21 #define cpu_to_be16(x) swab16(x)
22 #define be16_to_cpu(x) swab16(x)
23#elif defined(__BIG_ENDIAN)
24 #define cpu_to_le64(x) swab64(x)
25 #define le64_to_cpu(x) swab64(x)
26 #define cpu_to_le32(x) swab32(x)
27 #define le32_to_cpu(x) swab32(x)
28 #define cpu_to_le16(x) swab16(x)
29 #define le16_to_cpu(x) swab16(x)
30 #define cpu_to_be64(x) ((uint64_t)(x))
31 #define be64_to_cpu(x) ((uint64_t)(x))
32 #define cpu_to_be32(x) ((uint32_t)(x))
33 #define be32_to_cpu(x) ((uint32_t)(x))
34 #define cpu_to_be16(x) ((uint16_t)(x))
35 #define be16_to_cpu(x) ((uint16_t)(x))
36#else
37 #error "<arch/byteorder.h> must #define __LITTLE_ENDIAN or __BIG_ENDIAN"
38#endif
39
40#define ntohll(x) be64_to_cpu(x)
41#define htonll(x) cpu_to_be64(x)
42#define ntohl(x) be32_to_cpu(x)
43#define htonl(x) cpu_to_be32(x)
44
45#define __clrsetbits(endian, bits, addr, clear, set) \
46 write##bits(addr, cpu_to_##endian##bits((endian##bits##_to_cpu( \
47 read##bits(addr)) & ~((uint##bits##_t)(clear))) | (set)))
48
49#define clrbits_le64(addr, clear) __clrsetbits(le, 64, addr, clear, 0)
50#define clrbits_be64(addr, clear) __clrsetbits(be, 64, addr, clear, 0)
51#define clrbits_le32(addr, clear) __clrsetbits(le, 32, addr, clear, 0)
52#define clrbits_be32(addr, clear) __clrsetbits(be, 32, addr, clear, 0)
53#define clrbits_le16(addr, clear) __clrsetbits(le, 16, addr, clear, 0)
54#define clrbits_be16(addr, clear) __clrsetbits(be, 16, addr, clear, 0)
55
56#define setbits_le64(addr, set) __clrsetbits(le, 64, addr, 0, set)
57#define setbits_be64(addr, set) __clrsetbits(be, 64, addr, 0, set)
58#define setbits_le32(addr, set) __clrsetbits(le, 32, addr, 0, set)
59#define setbits_be32(addr, set) __clrsetbits(be, 32, addr, 0, set)
60#define setbits_le16(addr, set) __clrsetbits(le, 16, addr, 0, set)
61#define setbits_be16(addr, set) __clrsetbits(be, 16, addr, 0, set)
62
63#define clrsetbits_le64(addr, clear, set) __clrsetbits(le, 64, addr, clear, set)
64#define clrsetbits_be64(addr, clear, set) __clrsetbits(be, 64, addr, clear, set)
65#define clrsetbits_le32(addr, clear, set) __clrsetbits(le, 32, addr, clear, set)
66#define clrsetbits_be32(addr, clear, set) __clrsetbits(be, 32, addr, clear, set)
67#define clrsetbits_le16(addr, clear, set) __clrsetbits(le, 16, addr, clear, set)
68#define clrsetbits_be16(addr, clear, set) __clrsetbits(be, 16, addr, clear, set)
69
Julius Wernere8e92d62019-05-07 17:29:21 -070070/* be16dec/be32dec/be64dec/le16dec/le32dec/le64dec family of functions. */
71#define DEFINE_ENDIAN_DEC(endian, width) \
72 static inline uint##width##_t endian##width##dec(const void *p) \
73 { \
74 return endian##width##_to_cpu(*(uint##width##_t *)p); \
75 }
76DEFINE_ENDIAN_DEC(be, 16)
77DEFINE_ENDIAN_DEC(be, 32)
78DEFINE_ENDIAN_DEC(be, 64)
79DEFINE_ENDIAN_DEC(le, 16)
80DEFINE_ENDIAN_DEC(le, 32)
81DEFINE_ENDIAN_DEC(le, 64)
82
83/* be16enc/be32enc/be64enc/le16enc/le32enc/le64enc family of functions. */
84#define DEFINE_ENDIAN_ENC(endian, width) \
85 static inline void endian##width##enc(void *p, uint##width##_t u) \
86 { \
87 *(uint##width##_t *)p = cpu_to_##endian##width(u); \
88 }
89DEFINE_ENDIAN_ENC(be, 16)
90DEFINE_ENDIAN_ENC(be, 32)
91DEFINE_ENDIAN_ENC(be, 64)
92DEFINE_ENDIAN_ENC(le, 16)
93DEFINE_ENDIAN_ENC(le, 32)
94DEFINE_ENDIAN_ENC(le, 64)
95
Aaron Durbin94a74992015-09-10 12:08:34 -050096/*
97 * Portable (API) endian support that can be used in code that is shared
98 * with userspace (man 3 endian) tools.
99 */
100static inline uint16_t htobe16(uint16_t host_16bits)
101{
102 return cpu_to_be16(host_16bits);
103}
104
105static inline uint16_t htole16(uint16_t host_16bits)
106{
107 return cpu_to_le16(host_16bits);
108}
109
110static inline uint16_t be16toh(uint16_t big_endian_16bits)
111{
112 return be16_to_cpu(big_endian_16bits);
113}
114
115static inline uint16_t le16toh(uint16_t little_endian_16bits)
116{
117 return le16_to_cpu(little_endian_16bits);
118}
119
120static inline uint32_t htobe32(uint32_t host_32bits)
121{
122 return cpu_to_be32(host_32bits);
123}
124
125static inline uint32_t htole32(uint32_t host_32bits)
126{
127 return cpu_to_le32(host_32bits);
128}
129
130static inline uint32_t be32toh(uint32_t big_endian_32bits)
131{
132 return be32_to_cpu(big_endian_32bits);
133}
134
135static inline uint32_t le32toh(uint32_t little_endian_32bits)
136{
137 return le32_to_cpu(little_endian_32bits);
138}
139
140static inline uint64_t htobe64(uint64_t host_64bits)
141{
142 return cpu_to_be64(host_64bits);
143}
144
145static inline uint64_t htole64(uint64_t host_64bits)
146{
147 return cpu_to_le64(host_64bits);
148}
149
150static inline uint64_t be64toh(uint64_t big_endian_64bits)
151{
152 return be64_to_cpu(big_endian_64bits);
153}
154
155static inline uint64_t le64toh(uint64_t little_endian_64bits)
156{
Aaron Durbin113d8212015-09-10 22:27:55 -0500157 return le64_to_cpu(little_endian_64bits);
Aaron Durbin94a74992015-09-10 12:08:34 -0500158}
Aaron Durbin94a74992015-09-10 12:08:34 -0500159
Hung-Te Lin6fe0cab2013-01-22 18:57:56 +0800160#endif