| /** @file |
| * @brief Byte order helpers. |
| */ |
| |
| /* |
| * Copyright (c) 2015-2016, Intel Corporation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <stdint.h> |
| |
| /* Internal helpers only used by the sys_* APIs further below */ |
| #define __bswap_16(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) |
| #define __bswap_32(x) ((uint32_t) ((((x) >> 24) & 0xff) | \ |
| (((x) >> 8) & 0xff00) | \ |
| (((x) & 0xff00) << 8) | \ |
| (((x) & 0xff) << 24))) |
| |
| /** @def sys_le16_to_cpu |
| * @brief Convert 16-bit integer from little-endian to host endianness. |
| * |
| * @param val 16-bit integer in little-endian format. |
| * |
| * @return 16-bit integer in host endianness. |
| */ |
| |
| /** @def sys_cpu_to_le16 |
| * @brief Convert 16-bit integer from host endianness to little-endian. |
| * |
| * @param val 16-bit integer in host endianness. |
| * |
| * @return 16-bit integer in little-endian format. |
| */ |
| |
| /** @def sys_be16_to_cpu |
| * @brief Convert 16-bit integer from big-endian to host endianness. |
| * |
| * @param val 16-bit integer in big-endian format. |
| * |
| * @return 16-bit integer in host endianness. |
| */ |
| |
| /** @def sys_cpu_to_be16 |
| * @brief Convert 16-bit integer from host endianness to big-endian. |
| * |
| * @param val 16-bit integer in host endianness. |
| * |
| * @return 16-bit integer in big-endian format. |
| */ |
| |
| /** @def sys_le32_to_cpu |
| * @brief Convert 32-bit integer from little-endian to host endianness. |
| * |
| * @param val 32-bit integer in little-endian format. |
| * |
| * @return 32-bit integer in host endianness. |
| */ |
| |
| /** @def sys_cpu_to_le32 |
| * @brief Convert 32-bit integer from host endianness to little-endian. |
| * |
| * @param val 32-bit integer in host endianness. |
| * |
| * @return 32-bit integer in little-endian format. |
| */ |
| |
| /** @def sys_be32_to_cpu |
| * @brief Convert 32-bit integer from big-endian to host endianness. |
| * |
| * @param val 32-bit integer in big-endian format. |
| * |
| * @return 32-bit integer in host endianness. |
| */ |
| |
| /** @def sys_cpu_to_be32 |
| * @brief Convert 32-bit integer from host endianness to big-endian. |
| * |
| * @param val 32-bit integer in host endianness. |
| * |
| * @return 32-bit integer in big-endian format. |
| */ |
| |
| #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
| #define sys_le16_to_cpu(val) (val) |
| #define sys_cpu_to_le16(val) (val) |
| #define sys_be16_to_cpu(val) __bswap_16(val) |
| #define sys_cpu_to_be16(val) __bswap_16(val) |
| #define sys_le32_to_cpu(val) (val) |
| #define sys_cpu_to_le32(val) (val) |
| #define sys_be32_to_cpu(val) __bswap_32(val) |
| #define sys_cpu_to_be32(val) __bswap_32(val) |
| #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
| #define sys_le16_to_cpu(val) __bswap_16(val) |
| #define sys_cpu_to_le16(val) __bswap_16(val) |
| #define sys_be16_to_cpu(val) (val) |
| #define sys_cpu_to_be16(val) (val) |
| #define sys_le32_to_cpu(val) __bswap_32(val) |
| #define sys_cpu_to_le32(val) __bswap_32(val) |
| #define sys_be32_to_cpu(val) (val) |
| #define sys_cpu_to_be32(val) (val) |
| #else |
| #error "Unknown byte order" |
| #endif |
| |
| /** |
| * @brief Put a 16-bit intger as big-endian to arbitrary location. |
| * |
| * Put a 16-bit integer, originally in host endianness, to a |
| * potentially unaligned memory location in big-endian format. |
| * |
| * @param val 16-bit integer in host endianness. |
| * @param dst Destination memory address to store the result. |
| */ |
| static inline void sys_put_be16(uint16_t val, uint8_t dst[2]) |
| { |
| dst[0] = val >> 8; |
| dst[1] = val; |
| } |
| |
| /** |
| * @brief Put a 32-bit intger as big-endian to arbitrary location. |
| * |
| * Put a 32-bit integer, originally in host endianness, to a |
| * potentially unaligned memory location in big-endian format. |
| * |
| * @param val 32-bit integer in host endianness. |
| * @param dst Destination memory address to store the result. |
| */ |
| static inline void sys_put_be32(uint32_t val, uint8_t dst[4]) |
| { |
| sys_put_be16(val >> 16, dst); |
| sys_put_be16(val, &dst[2]); |
| } |
| |
| /** |
| * @brief Put a 16-bit intger as little-endian to arbitrary location. |
| * |
| * Put a 16-bit integer, originally in host endianness, to a |
| * potentially unaligned memory location in little-endian format. |
| * |
| * @param val 16-bit integer in host endianness. |
| * @param dst Destination memory address to store the result. |
| */ |
| static inline void sys_put_le16(uint16_t val, uint8_t dst[2]) |
| { |
| dst[0] = val; |
| dst[1] = val >> 8; |
| } |
| |
| /** |
| * @brief Put a 32-bit intger as little-endian to arbitrary location. |
| * |
| * Put a 32-bit integer, originally in host endianness, to a |
| * potentially unaligned memory location in little-endian format. |
| * |
| * @param val 32-bit integer in host endianness. |
| * @param dst Destination memory address to store the result. |
| */ |
| static inline void sys_put_le32(uint32_t val, uint8_t dst[4]) |
| { |
| sys_put_le16(val, dst); |
| sys_put_le16(val >> 16, &dst[2]); |
| } |
| |
| /** |
| * @brief Get a 16-bit intger stored in big-endian format. |
| * |
| * Get a 16-bit integer, stored in big-endian format in a potentially |
| * unaligned memory location, and convert it to the host endianness. |
| * |
| * @param src Location of the big-endian 16-bit integer to get. |
| * |
| * @return 16-bit integer in host endianness. |
| */ |
| static inline uint16_t sys_get_be16(const uint8_t src[2]) |
| { |
| return ((uint16_t)src[0] << 8) | src[1]; |
| } |
| |
| /** |
| * @brief Get a 32-bit intger stored in big-endian format. |
| * |
| * Get a 32-bit integer, stored in big-endian format in a potentially |
| * unaligned memory location, and convert it to the host endianness. |
| * |
| * @param src Location of the big-endian 32-bit integer to get. |
| * |
| * @return 32-bit integer in host endianness. |
| */ |
| static inline uint32_t sys_get_be32(const uint8_t src[4]) |
| { |
| return ((uint32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]); |
| } |
| |
| /** |
| * @brief Get a 16-bit intger stored in little-endian format. |
| * |
| * Get a 16-bit integer, stored in little-endian format in a potentially |
| * unaligned memory location, and convert it to the host endianness. |
| * |
| * @param src Location of the little-endian 16-bit integer to get. |
| * |
| * @return 16-bit integer in host endianness. |
| */ |
| static inline uint16_t sys_get_le16(const uint8_t src[2]) |
| { |
| return ((uint16_t)src[1] << 8) | src[0]; |
| } |
| |
| /** |
| * @brief Get a 32-bit intger stored in little-endian format. |
| * |
| * Get a 32-bit integer, stored in little-endian format in a potentially |
| * unaligned memory location, and convert it to the host endianness. |
| * |
| * @param src Location of the little-endian 32-bit integer to get. |
| * |
| * @return 32-bit integer in host endianness. |
| */ |
| static inline uint32_t sys_get_le32(const uint8_t src[4]) |
| { |
| return ((uint32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]); |
| } |