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