xref: /aosp_15_r20/external/ublksrv/include/ublksrv_tgt_endian.h (revision 94c4a1e103eb1715230460aab379dff275992c20)
1 // SPDX-License-Identifier: GPL-2.0
2 #ifndef UBLK_TGT_ENDIAN_H
3 #define UBLK_TGT_ENDIAN_H
4 
5 #include <byteswap.h>
6 
7 /* ublksrv target code private header, not for libublksrv user */
8 
bswap16(uint16_t x)9 static inline uint16_t bswap16(uint16_t x)
10 {
11     return bswap_16(x);
12 }
bswap32(uint32_t x)13 static inline uint32_t bswap32(uint32_t x)
14 {
15     return bswap_32(x);
16 }
bswap64(uint64_t x)17 static inline uint64_t bswap64(uint64_t x)
18 {
19     return bswap_64(x);
20 }
21 
bswap16s(uint16_t * s)22 static inline void bswap16s(uint16_t *s)
23 {
24     *s = bswap16(*s);
25 }
26 
bswap32s(uint32_t * s)27 static inline void bswap32s(uint32_t *s)
28 {
29     *s = bswap32(*s);
30 }
31 
bswap64s(uint64_t * s)32 static inline void bswap64s(uint64_t *s)
33 {
34     *s = bswap64(*s);
35 }
36 
37 #ifndef glue
38 #define xglue(x, y) x ## y
39 #define glue(x, y) xglue(x, y)
40 #endif
41 
42 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
43 #define be_bswap(v, size) (v)
44 #define le_bswap(v, size) glue(bswap, size)(v)
45 #define be_bswaps(v, size)
46 #define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
47 #else
48 #define le_bswap(v, size) (v)
49 #define be_bswap(v, size) glue(bswap, size)(v)
50 #define le_bswaps(v, size)
51 #define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
52 #endif
53 
54 /**
55  * Endianness conversion functions between host cpu and specified endianness.
56  * (We list the complete set of prototypes produced by the macros below
57  * to assist people who search the headers to find their definitions.)
58  *
59  * uint16_t le16_to_cpu(uint16_t v);
60  * uint32_t le32_to_cpu(uint32_t v);
61  * uint64_t le64_to_cpu(uint64_t v);
62  * uint16_t be16_to_cpu(uint16_t v);
63  * uint32_t be32_to_cpu(uint32_t v);
64  * uint64_t be64_to_cpu(uint64_t v);
65  *
66  * Convert the value @v from the specified format to the native
67  * endianness of the host CPU by byteswapping if necessary, and
68  * return the converted value.
69  *
70  * uint16_t cpu_to_le16(uint16_t v);
71  * uint32_t cpu_to_le32(uint32_t v);
72  * uint64_t cpu_to_le64(uint64_t v);
73  * uint16_t cpu_to_be16(uint16_t v);
74  * uint32_t cpu_to_be32(uint32_t v);
75  * uint64_t cpu_to_be64(uint64_t v);
76  *
77  * Convert the value @v from the native endianness of the host CPU to
78  * the specified format by byteswapping if necessary, and return
79  * the converted value.
80  *
81  * void le16_to_cpus(uint16_t *v);
82  * void le32_to_cpus(uint32_t *v);
83  * void le64_to_cpus(uint64_t *v);
84  * void be16_to_cpus(uint16_t *v);
85  * void be32_to_cpus(uint32_t *v);
86  * void be64_to_cpus(uint64_t *v);
87  *
88  * Do an in-place conversion of the value pointed to by @v from the
89  * specified format to the native endianness of the host CPU.
90  *
91  * void cpu_to_le16s(uint16_t *v);
92  * void cpu_to_le32s(uint32_t *v);
93  * void cpu_to_le64s(uint64_t *v);
94  * void cpu_to_be16s(uint16_t *v);
95  * void cpu_to_be32s(uint32_t *v);
96  * void cpu_to_be64s(uint64_t *v);
97  *
98  * Do an in-place conversion of the value pointed to by @v from the
99  * native endianness of the host CPU to the specified format.
100  *
101  * Both X_to_cpu() and cpu_to_X() perform the same operation; you
102  * should use whichever one is better documenting of the function your
103  * code is performing.
104  *
105  * Do not use these functions for conversion of values which are in guest
106  * memory, since the data may not be sufficiently aligned for the host CPU's
107  * load and store instructions. Instead you should use the ld*_p() and
108  * st*_p() functions, which perform loads and stores of data of any
109  * required size and endianness and handle possible misalignment.
110  */
111 
112 #define CPU_CONVERT(endian, size, type)\
113 static inline type endian ## size ## _to_cpu(type v)\
114 {\
115     return glue(endian, _bswap)(v, size);\
116 }\
117 \
118 static inline type cpu_to_ ## endian ## size(type v)\
119 {\
120     return glue(endian, _bswap)(v, size);\
121 }\
122 \
123 static inline void endian ## size ## _to_cpus(type *p)\
124 {\
125     glue(endian, _bswaps)(p, size);\
126 }\
127 \
128 static inline void cpu_to_ ## endian ## size ## s(type *p)\
129 {\
130     glue(endian, _bswaps)(p, size);\
131 }
132 
133 CPU_CONVERT(be, 16, uint16_t)
134 CPU_CONVERT(be, 32, uint32_t)
135 CPU_CONVERT(be, 64, uint64_t)
136 
137 CPU_CONVERT(le, 16, uint16_t)
138 CPU_CONVERT(le, 32, uint32_t)
139 CPU_CONVERT(le, 64, uint64_t)
140 
141 #endif
142