1 /** @file
2  *  @brief Byte order helpers.
3  */
4 
5 /*
6  * Copyright (c) 2015-2016, Intel Corporation.
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #ifndef ZEPHYR_INCLUDE_SYS_BYTEORDER_H_
12 #define ZEPHYR_INCLUDE_SYS_BYTEORDER_H_
13 
14 #include <zephyr/types.h>
15 #include <stddef.h>
16 #include <zephyr/sys/__assert.h>
17 #include <zephyr/toolchain.h>
18 
19 #define BSWAP_16(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
20 #define BSWAP_24(x) ((uint32_t) ((((x) >> 16) & 0xff) | \
21 				   (((x)) & 0xff00) | \
22 				   (((x) & 0xff) << 16)))
23 #define BSWAP_32(x) ((uint32_t) ((((x) >> 24) & 0xff) | \
24 				   (((x) >> 8) & 0xff00) | \
25 				   (((x) & 0xff00) << 8) | \
26 				   (((x) & 0xff) << 24)))
27 #define BSWAP_48(x) ((uint64_t) ((((x) >> 40) & 0xff) | \
28 				   (((x) >> 24) & 0xff00) | \
29 				   (((x) >> 8) & 0xff0000) | \
30 				   (((x) & 0xff0000) << 8) | \
31 				   (((x) & 0xff00) << 24) | \
32 				   (((x) & 0xff) << 40)))
33 #define BSWAP_64(x) ((uint64_t) ((((x) >> 56) & 0xff) | \
34 				   (((x) >> 40) & 0xff00) | \
35 				   (((x) >> 24) & 0xff0000) | \
36 				   (((x) >> 8) & 0xff000000) | \
37 				   (((x) & 0xff000000) << 8) | \
38 				   (((x) & 0xff0000) << 24) | \
39 				   (((x) & 0xff00) << 40) | \
40 				   (((x) & 0xff) << 56)))
41 
42 /** @def sys_le16_to_cpu
43  *  @brief Convert 16-bit integer from little-endian to host endianness.
44  *
45  *  @param val 16-bit integer in little-endian format.
46  *
47  *  @return 16-bit integer in host endianness.
48  */
49 
50 /** @def sys_cpu_to_le16
51  *  @brief Convert 16-bit integer from host endianness to little-endian.
52  *
53  *  @param val 16-bit integer in host endianness.
54  *
55  *  @return 16-bit integer in little-endian format.
56  */
57 
58 /** @def sys_le24_to_cpu
59  *  @brief Convert 24-bit integer from little-endian to host endianness.
60  *
61  *  @param val 24-bit integer in little-endian format.
62  *
63  *  @return 24-bit integer in host endianness.
64  */
65 
66 /** @def sys_cpu_to_le24
67  *  @brief Convert 24-bit integer from host endianness to little-endian.
68  *
69  *  @param val 24-bit integer in host endianness.
70  *
71  *  @return 24-bit integer in little-endian format.
72  */
73 
74 /** @def sys_le32_to_cpu
75  *  @brief Convert 32-bit integer from little-endian to host endianness.
76  *
77  *  @param val 32-bit integer in little-endian format.
78  *
79  *  @return 32-bit integer in host endianness.
80  */
81 
82 /** @def sys_cpu_to_le32
83  *  @brief Convert 32-bit integer from host endianness to little-endian.
84  *
85  *  @param val 32-bit integer in host endianness.
86  *
87  *  @return 32-bit integer in little-endian format.
88  */
89 
90 /** @def sys_le48_to_cpu
91  *  @brief Convert 48-bit integer from little-endian to host endianness.
92  *
93  *  @param val 48-bit integer in little-endian format.
94  *
95  *  @return 48-bit integer in host endianness.
96  */
97 
98 /** @def sys_cpu_to_le48
99  *  @brief Convert 48-bit integer from host endianness to little-endian.
100  *
101  *  @param val 48-bit integer in host endianness.
102  *
103  *  @return 48-bit integer in little-endian format.
104  */
105 
106 /** @def sys_be16_to_cpu
107  *  @brief Convert 16-bit integer from big-endian to host endianness.
108  *
109  *  @param val 16-bit integer in big-endian format.
110  *
111  *  @return 16-bit integer in host endianness.
112  */
113 
114 /** @def sys_cpu_to_be16
115  *  @brief Convert 16-bit integer from host endianness to big-endian.
116  *
117  *  @param val 16-bit integer in host endianness.
118  *
119  *  @return 16-bit integer in big-endian format.
120  */
121 
122 /** @def sys_be24_to_cpu
123  *  @brief Convert 24-bit integer from big-endian to host endianness.
124  *
125  *  @param val 24-bit integer in big-endian format.
126  *
127  *  @return 24-bit integer in host endianness.
128  */
129 
130 /** @def sys_cpu_to_be24
131  *  @brief Convert 24-bit integer from host endianness to big-endian.
132  *
133  *  @param val 24-bit integer in host endianness.
134  *
135  *  @return 24-bit integer in big-endian format.
136  */
137 
138 /** @def sys_be32_to_cpu
139  *  @brief Convert 32-bit integer from big-endian to host endianness.
140  *
141  *  @param val 32-bit integer in big-endian format.
142  *
143  *  @return 32-bit integer in host endianness.
144  */
145 
146 /** @def sys_cpu_to_be32
147  *  @brief Convert 32-bit integer from host endianness to big-endian.
148  *
149  *  @param val 32-bit integer in host endianness.
150  *
151  *  @return 32-bit integer in big-endian format.
152  */
153 
154 /** @def sys_be48_to_cpu
155  *  @brief Convert 48-bit integer from big-endian to host endianness.
156  *
157  *  @param val 48-bit integer in big-endian format.
158  *
159  *  @return 48-bit integer in host endianness.
160  */
161 
162 /** @def sys_cpu_to_be48
163  *  @brief Convert 48-bit integer from host endianness to big-endian.
164  *
165  *  @param val 48-bit integer in host endianness.
166  *
167  *  @return 48-bit integer in big-endian format.
168  */
169 
170 /** @def sys_uint16_to_array
171  *  @brief Convert 16-bit unsigned integer to byte array.
172  *
173  *  @details Byte order aware macro to treat an unsigned integer
174  *           as an array, rather than an integer literal. For example,
175  *           `0x0123` would be converted to `{0x01, 0x23}` for big endian
176  *           machines, and `{0x23, 0x01}` for little endian machines.
177  *
178  *  @param val 16-bit unsigned integer.
179  *
180  *  @return 16-bit unsigned integer as byte array.
181  */
182 
183 /** @def sys_uint32_to_array
184  *  @brief Convert 32-bit unsigned integer to byte array.
185  *
186  *  @details Byte order aware macro to treat an unsigned integer
187  *           as an array, rather than an integer literal. For example,
188  *           `0x01234567` would be converted to `{0x01, 0x23, 0x45, 0x67}`
189  *           for big endian machines, and `{0x67, 0x45, 0x23, 0x01}` for
190  *           little endian machines.
191  *
192  *  @param val 32-bit unsigned integer.
193  *
194  *  @return 32-bit unsigned integer as byte array.
195  */
196 
197 /** @def sys_uint64_to_array
198  *  @brief Convert 64-bit unsigned integer to byte array.
199  *
200  *  @details Byte order aware macro to treat an unsigned integer
201  *           as an array, rather than an integer literal. For example,
202  *           `0x0123456789abcdef` would be converted to
203  *           `{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}`
204  *           for big endian machines, and
205  *           `{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01}` for
206  *           little endian machines.
207  *
208  *  @param val 64-bit unsigned integer.
209  *
210  *  @return 64-bit unsigned integer as byte array.
211  */
212 
213 #ifdef CONFIG_LITTLE_ENDIAN
214 #define sys_le16_to_cpu(val) (val)
215 #define sys_cpu_to_le16(val) (val)
216 #define sys_le24_to_cpu(val) (val)
217 #define sys_cpu_to_le24(val) (val)
218 #define sys_le32_to_cpu(val) (val)
219 #define sys_cpu_to_le32(val) (val)
220 #define sys_le48_to_cpu(val) (val)
221 #define sys_cpu_to_le48(val) (val)
222 #define sys_le64_to_cpu(val) (val)
223 #define sys_cpu_to_le64(val) (val)
224 #define sys_be16_to_cpu(val) BSWAP_16(val)
225 #define sys_cpu_to_be16(val) BSWAP_16(val)
226 #define sys_be24_to_cpu(val) BSWAP_24(val)
227 #define sys_cpu_to_be24(val) BSWAP_24(val)
228 #define sys_be32_to_cpu(val) BSWAP_32(val)
229 #define sys_cpu_to_be32(val) BSWAP_32(val)
230 #define sys_be48_to_cpu(val) BSWAP_48(val)
231 #define sys_cpu_to_be48(val) BSWAP_48(val)
232 #define sys_be64_to_cpu(val) BSWAP_64(val)
233 #define sys_cpu_to_be64(val) BSWAP_64(val)
234 
235 #define sys_uint16_to_array(val) {		\
236 	((val) & 0xff),				\
237 	(((val) >> 8) & 0xff)}
238 
239 #define sys_uint32_to_array(val) {		\
240 	((val) & 0xff),				\
241 	(((val) >> 8) & 0xff),			\
242 	(((val) >> 16) & 0xff),			\
243 	(((val) >> 24) & 0xff)}
244 
245 #define sys_uint64_to_array(val) {		\
246 	((val) & 0xff),				\
247 	(((val) >> 8) & 0xff),			\
248 	(((val) >> 16) & 0xff),			\
249 	(((val) >> 24) & 0xff),			\
250 	(((val) >> 32) & 0xff),			\
251 	(((val) >> 40) & 0xff),			\
252 	(((val) >> 48) & 0xff),			\
253 	(((val) >> 56) & 0xff)}
254 
255 #else
256 #define sys_le16_to_cpu(val) BSWAP_16(val)
257 #define sys_cpu_to_le16(val) BSWAP_16(val)
258 #define sys_le24_to_cpu(val) BSWAP_24(val)
259 #define sys_cpu_to_le24(val) BSWAP_24(val)
260 #define sys_le32_to_cpu(val) BSWAP_32(val)
261 #define sys_cpu_to_le32(val) BSWAP_32(val)
262 #define sys_le48_to_cpu(val) BSWAP_48(val)
263 #define sys_cpu_to_le48(val) BSWAP_48(val)
264 #define sys_le64_to_cpu(val) BSWAP_64(val)
265 #define sys_cpu_to_le64(val) BSWAP_64(val)
266 #define sys_be16_to_cpu(val) (val)
267 #define sys_cpu_to_be16(val) (val)
268 #define sys_be24_to_cpu(val) (val)
269 #define sys_cpu_to_be24(val) (val)
270 #define sys_be32_to_cpu(val) (val)
271 #define sys_cpu_to_be32(val) (val)
272 #define sys_be48_to_cpu(val) (val)
273 #define sys_cpu_to_be48(val) (val)
274 #define sys_be64_to_cpu(val) (val)
275 #define sys_cpu_to_be64(val) (val)
276 
277 #define sys_uint16_to_array(val) {		\
278 	(((val) >> 8) & 0xff),			\
279 	((val) & 0xff)}
280 
281 #define sys_uint32_to_array(val) {		\
282 	(((val) >> 24) & 0xff),			\
283 	(((val) >> 16) & 0xff),			\
284 	(((val) >> 8) & 0xff),			\
285 	((val) & 0xff)}
286 
287 #define sys_uint64_to_array(val) {		\
288 	(((val) >> 56) & 0xff),			\
289 	(((val) >> 48) & 0xff),			\
290 	(((val) >> 40) & 0xff),			\
291 	(((val) >> 32) & 0xff),			\
292 	(((val) >> 24) & 0xff),			\
293 	(((val) >> 16) & 0xff),			\
294 	(((val) >> 8) & 0xff),			\
295 	((val) & 0xff)}
296 
297 #endif
298 
299 /**
300  *  @brief Put a 16-bit integer as big-endian to arbitrary location.
301  *
302  *  Put a 16-bit integer, originally in host endianness, to a
303  *  potentially unaligned memory location in big-endian format.
304  *
305  *  @param val 16-bit integer in host endianness.
306  *  @param dst Destination memory address to store the result.
307  */
sys_put_be16(uint16_t val,uint8_t dst[2])308 static inline void sys_put_be16(uint16_t val, uint8_t dst[2])
309 {
310 	dst[0] = val >> 8;
311 	dst[1] = val;
312 }
313 
314 /**
315  *  @brief Put a 24-bit integer as big-endian to arbitrary location.
316  *
317  *  Put a 24-bit integer, originally in host endianness, to a
318  *  potentially unaligned memory location in big-endian format.
319  *
320  *  @param val 24-bit integer in host endianness.
321  *  @param dst Destination memory address to store the result.
322  */
sys_put_be24(uint32_t val,uint8_t dst[3])323 static inline void sys_put_be24(uint32_t val, uint8_t dst[3])
324 {
325 	dst[0] = val >> 16;
326 	sys_put_be16(val, &dst[1]);
327 }
328 
329 /**
330  *  @brief Put a 32-bit integer as big-endian to arbitrary location.
331  *
332  *  Put a 32-bit integer, originally in host endianness, to a
333  *  potentially unaligned memory location in big-endian format.
334  *
335  *  @param val 32-bit integer in host endianness.
336  *  @param dst Destination memory address to store the result.
337  */
sys_put_be32(uint32_t val,uint8_t dst[4])338 static inline void sys_put_be32(uint32_t val, uint8_t dst[4])
339 {
340 	sys_put_be16(val >> 16, dst);
341 	sys_put_be16(val, &dst[2]);
342 }
343 
344 /**
345  *  @brief Put a 48-bit integer as big-endian to arbitrary location.
346  *
347  *  Put a 48-bit integer, originally in host endianness, to a
348  *  potentially unaligned memory location in big-endian format.
349  *
350  *  @param val 48-bit integer in host endianness.
351  *  @param dst Destination memory address to store the result.
352  */
sys_put_be48(uint64_t val,uint8_t dst[6])353 static inline void sys_put_be48(uint64_t val, uint8_t dst[6])
354 {
355 	sys_put_be16(val >> 32, dst);
356 	sys_put_be32(val, &dst[2]);
357 }
358 
359 /**
360  *  @brief Put a 64-bit integer as big-endian to arbitrary location.
361  *
362  *  Put a 64-bit integer, originally in host endianness, to a
363  *  potentially unaligned memory location in big-endian format.
364  *
365  *  @param val 64-bit integer in host endianness.
366  *  @param dst Destination memory address to store the result.
367  */
sys_put_be64(uint64_t val,uint8_t dst[8])368 static inline void sys_put_be64(uint64_t val, uint8_t dst[8])
369 {
370 	sys_put_be32(val >> 32, dst);
371 	sys_put_be32(val, &dst[4]);
372 }
373 
374 /**
375  *  @brief Put a 16-bit integer as little-endian to arbitrary location.
376  *
377  *  Put a 16-bit integer, originally in host endianness, to a
378  *  potentially unaligned memory location in little-endian format.
379  *
380  *  @param val 16-bit integer in host endianness.
381  *  @param dst Destination memory address to store the result.
382  */
sys_put_le16(uint16_t val,uint8_t dst[2])383 static inline void sys_put_le16(uint16_t val, uint8_t dst[2])
384 {
385 	dst[0] = val;
386 	dst[1] = val >> 8;
387 }
388 
389 /**
390  *  @brief Put a 24-bit integer as little-endian to arbitrary location.
391  *
392  *  Put a 24-bit integer, originally in host endianness, to a
393  *  potentially unaligned memory location in little-endian format.
394  *
395  *  @param val 24-bit integer in host endianness.
396  *  @param dst Destination memory address to store the result.
397  */
sys_put_le24(uint32_t val,uint8_t dst[3])398 static inline void sys_put_le24(uint32_t val, uint8_t dst[3])
399 {
400 	sys_put_le16(val, dst);
401 	dst[2] = val >> 16;
402 }
403 
404 /**
405  *  @brief Put a 32-bit integer as little-endian to arbitrary location.
406  *
407  *  Put a 32-bit integer, originally in host endianness, to a
408  *  potentially unaligned memory location in little-endian format.
409  *
410  *  @param val 32-bit integer in host endianness.
411  *  @param dst Destination memory address to store the result.
412  */
sys_put_le32(uint32_t val,uint8_t dst[4])413 static inline void sys_put_le32(uint32_t val, uint8_t dst[4])
414 {
415 	sys_put_le16(val, dst);
416 	sys_put_le16(val >> 16, &dst[2]);
417 }
418 
419 /**
420  *  @brief Put a 48-bit integer as little-endian to arbitrary location.
421  *
422  *  Put a 48-bit integer, originally in host endianness, to a
423  *  potentially unaligned memory location in little-endian format.
424  *
425  *  @param val 48-bit integer in host endianness.
426  *  @param dst Destination memory address to store the result.
427  */
sys_put_le48(uint64_t val,uint8_t dst[6])428 static inline void sys_put_le48(uint64_t val, uint8_t dst[6])
429 {
430 	sys_put_le32(val, dst);
431 	sys_put_le16(val >> 32, &dst[4]);
432 }
433 
434 /**
435  *  @brief Put a 64-bit integer as little-endian to arbitrary location.
436  *
437  *  Put a 64-bit integer, originally in host endianness, to a
438  *  potentially unaligned memory location in little-endian format.
439  *
440  *  @param val 64-bit integer in host endianness.
441  *  @param dst Destination memory address to store the result.
442  */
sys_put_le64(uint64_t val,uint8_t dst[8])443 static inline void sys_put_le64(uint64_t val, uint8_t dst[8])
444 {
445 	sys_put_le32(val, dst);
446 	sys_put_le32(val >> 32, &dst[4]);
447 }
448 
449 /**
450  *  @brief Get a 16-bit integer stored in big-endian format.
451  *
452  *  Get a 16-bit integer, stored in big-endian format in a potentially
453  *  unaligned memory location, and convert it to the host endianness.
454  *
455  *  @param src Location of the big-endian 16-bit integer to get.
456  *
457  *  @return 16-bit integer in host endianness.
458  */
sys_get_be16(const uint8_t src[2])459 static inline uint16_t sys_get_be16(const uint8_t src[2])
460 {
461 	return ((uint16_t)src[0] << 8) | src[1];
462 }
463 
464 /**
465  *  @brief Get a 24-bit integer stored in big-endian format.
466  *
467  *  Get a 24-bit integer, stored in big-endian format in a potentially
468  *  unaligned memory location, and convert it to the host endianness.
469  *
470  *  @param src Location of the big-endian 24-bit integer to get.
471  *
472  *  @return 24-bit integer in host endianness.
473  */
sys_get_be24(const uint8_t src[3])474 static inline uint32_t sys_get_be24(const uint8_t src[3])
475 {
476 	return ((uint32_t)src[0] << 16) | sys_get_be16(&src[1]);
477 }
478 
479 /**
480  *  @brief Get a 32-bit integer stored in big-endian format.
481  *
482  *  Get a 32-bit integer, stored in big-endian format in a potentially
483  *  unaligned memory location, and convert it to the host endianness.
484  *
485  *  @param src Location of the big-endian 32-bit integer to get.
486  *
487  *  @return 32-bit integer in host endianness.
488  */
sys_get_be32(const uint8_t src[4])489 static inline uint32_t sys_get_be32(const uint8_t src[4])
490 {
491 	return ((uint32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]);
492 }
493 
494 /**
495  *  @brief Get a 48-bit integer stored in big-endian format.
496  *
497  *  Get a 48-bit integer, stored in big-endian format in a potentially
498  *  unaligned memory location, and convert it to the host endianness.
499  *
500  *  @param src Location of the big-endian 48-bit integer to get.
501  *
502  *  @return 48-bit integer in host endianness.
503  */
sys_get_be48(const uint8_t src[6])504 static inline uint64_t sys_get_be48(const uint8_t src[6])
505 {
506 	return ((uint64_t)sys_get_be32(&src[0]) << 16) | sys_get_be16(&src[4]);
507 }
508 
509 /**
510  *  @brief Get a 64-bit integer stored in big-endian format.
511  *
512  *  Get a 64-bit integer, stored in big-endian format in a potentially
513  *  unaligned memory location, and convert it to the host endianness.
514  *
515  *  @param src Location of the big-endian 64-bit integer to get.
516  *
517  *  @return 64-bit integer in host endianness.
518  */
sys_get_be64(const uint8_t src[8])519 static inline uint64_t sys_get_be64(const uint8_t src[8])
520 {
521 	return ((uint64_t)sys_get_be32(&src[0]) << 32) | sys_get_be32(&src[4]);
522 }
523 
524 /**
525  *  @brief Get a 16-bit integer stored in little-endian format.
526  *
527  *  Get a 16-bit integer, stored in little-endian format in a potentially
528  *  unaligned memory location, and convert it to the host endianness.
529  *
530  *  @param src Location of the little-endian 16-bit integer to get.
531  *
532  *  @return 16-bit integer in host endianness.
533  */
sys_get_le16(const uint8_t src[2])534 static inline uint16_t sys_get_le16(const uint8_t src[2])
535 {
536 	return ((uint16_t)src[1] << 8) | src[0];
537 }
538 
539 /**
540  *  @brief Get a 24-bit integer stored in little-endian format.
541  *
542  *  Get a 24-bit integer, stored in little-endian format in a potentially
543  *  unaligned memory location, and convert it to the host endianness.
544  *
545  *  @param src Location of the little-endian 24-bit integer to get.
546  *
547  *  @return 24-bit integer in host endianness.
548  */
sys_get_le24(const uint8_t src[3])549 static inline uint32_t sys_get_le24(const uint8_t src[3])
550 {
551 	return ((uint32_t)src[2] << 16) | sys_get_le16(&src[0]);
552 }
553 
554 /**
555  *  @brief Get a 32-bit integer stored in little-endian format.
556  *
557  *  Get a 32-bit integer, stored in little-endian format in a potentially
558  *  unaligned memory location, and convert it to the host endianness.
559  *
560  *  @param src Location of the little-endian 32-bit integer to get.
561  *
562  *  @return 32-bit integer in host endianness.
563  */
sys_get_le32(const uint8_t src[4])564 static inline uint32_t sys_get_le32(const uint8_t src[4])
565 {
566 	return ((uint32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]);
567 }
568 
569 /**
570  *  @brief Get a 48-bit integer stored in little-endian format.
571  *
572  *  Get a 48-bit integer, stored in little-endian format in a potentially
573  *  unaligned memory location, and convert it to the host endianness.
574  *
575  *  @param src Location of the little-endian 48-bit integer to get.
576  *
577  *  @return 48-bit integer in host endianness.
578  */
sys_get_le48(const uint8_t src[6])579 static inline uint64_t sys_get_le48(const uint8_t src[6])
580 {
581 	return ((uint64_t)sys_get_le32(&src[2]) << 16) | sys_get_le16(&src[0]);
582 }
583 
584 /**
585  *  @brief Get a 64-bit integer stored in little-endian format.
586  *
587  *  Get a 64-bit integer, stored in little-endian format in a potentially
588  *  unaligned memory location, and convert it to the host endianness.
589  *
590  *  @param src Location of the little-endian 64-bit integer to get.
591  *
592  *  @return 64-bit integer in host endianness.
593  */
sys_get_le64(const uint8_t src[8])594 static inline uint64_t sys_get_le64(const uint8_t src[8])
595 {
596 	return ((uint64_t)sys_get_le32(&src[4]) << 32) | sys_get_le32(&src[0]);
597 }
598 
599 /**
600  * @brief Swap one buffer content into another
601  *
602  * Copy the content of src buffer into dst buffer in reversed order,
603  * i.e.: src[n] will be put in dst[end-n]
604  * Where n is an index and 'end' the last index in both arrays.
605  * The 2 memory pointers must be pointing to different areas, and have
606  * a minimum size of given length.
607  *
608  * @param dst A valid pointer on a memory area where to copy the data in
609  * @param src A valid pointer on a memory area where to copy the data from
610  * @param length Size of both dst and src memory areas
611  */
sys_memcpy_swap(void * dst,const void * src,size_t length)612 static inline void sys_memcpy_swap(void *dst, const void *src, size_t length)
613 {
614 	uint8_t *pdst = (uint8_t *)dst;
615 	const uint8_t *psrc = (const uint8_t *)src;
616 
617 	__ASSERT(((psrc < pdst && (psrc + length) <= pdst) ||
618 		  (psrc > pdst && (pdst + length) <= psrc)),
619 		 "Source and destination buffers must not overlap");
620 
621 	psrc += length - 1;
622 
623 	for (; length > 0; length--) {
624 		*pdst++ = *psrc--;
625 	}
626 }
627 
628 /**
629  * @brief Swap buffer content
630  *
631  * In-place memory swap, where final content will be reversed.
632  * I.e.: buf[n] will be put in buf[end-n]
633  * Where n is an index and 'end' the last index of buf.
634  *
635  * @param buf A valid pointer on a memory area to swap
636  * @param length Size of buf memory area
637  */
sys_mem_swap(void * buf,size_t length)638 static inline void sys_mem_swap(void *buf, size_t length)
639 {
640 	size_t i;
641 
642 	for (i = 0; i < (length/2); i++) {
643 		uint8_t tmp = ((uint8_t *)buf)[i];
644 
645 		((uint8_t *)buf)[i] = ((uint8_t *)buf)[length - 1 - i];
646 		((uint8_t *)buf)[length - 1 - i] = tmp;
647 	}
648 }
649 
650 #endif /* ZEPHYR_INCLUDE_SYS_BYTEORDER_H_ */
651