From 02a2fe7907d94694dbbdee0eefc63368c25551be Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 1 Dec 2025 15:45:15 -0800 Subject: [PATCH] Merge coreboot and libpayload into commonlib We've accumulated a number of endianness-handling and related macros that are duplicated between coreboot and libpayload. This patch reduces duplication by merging them into a commonlib header. This has the added side-benefit of bringing the coreboot implementation of beXXenc/dec() functions to libpayload, which lead to better code generation by avoiding https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92716. Keep the htobell()-style functions in libpayload only since they're not needed in coreboot and not preferred. Keep the cpu_to_beXX()-style functions in coreboot only -- maybe we should deprecate those eventually. This patch is explicitly copying and relicensing some of the code I originally added as GPLv2 in commit e8e92d60c4e2 ("endian.h: Add be32dec/be32enc family of functions") to BSD-3. Change-Id: I5eb83d44a98b3aa59bba65b8e22df668874d2668 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/90308 Reviewed-by: Maximilian Brune Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- payloads/libpayload/include/endian.h | 218 +----------------- .../bsd/include/commonlib/bsd/_endian.h | 170 ++++++++++++++ src/include/device/mmio.h | 73 ------ src/include/endian.h | 181 ++------------- 4 files changed, 192 insertions(+), 450 deletions(-) create mode 100644 src/commonlib/bsd/include/commonlib/bsd/_endian.h diff --git a/payloads/libpayload/include/endian.h b/payloads/libpayload/include/endian.h index fd59af1b5c..46e5dfe6eb 100644 --- a/payloads/libpayload/include/endian.h +++ b/payloads/libpayload/include/endian.h @@ -32,152 +32,20 @@ #include #include #include +#include -/* Endian functions from glibc 2.9 / BSD "endian.h" */ +#define swab16(x) __builtin_bswap16(x) +#define swab32(x) __builtin_bswap32(x) +#define swab64(x) __builtin_bswap64(x) #if CONFIG(LP_BIG_ENDIAN) - -#define htobe16(in) (in) -#define htobe32(in) (in) -#define htobe64(in) (in) - -#define htole16(in) ((uint16_t)__builtin_bswap16(in)) -#define htole32(in) ((uint32_t)__builtin_bswap32(in)) -#define htole64(in) ((uint64_t)__builtin_bswap64(in)) - +#define __BIG_ENDIAN #elif CONFIG(LP_LITTLE_ENDIAN) - -#define htobe16(in) ((uint16_t)__builtin_bswap16(in)) -#define htobe32(in) ((uint32_t)__builtin_bswap32(in)) -#define htobe64(in) ((uint64_t)__builtin_bswap64(in)) - -#define htole16(in) (in) -#define htole32(in) (in) -#define htole64(in) (in) - -#else - -#error Cant tell if the CPU is little or big endian. - +#define __LITTLE_ENDIAN #endif /* CONFIG_*_ENDIAN */ -#define be16toh(in) htobe16(in) -#define be32toh(in) htobe32(in) -#define be64toh(in) htobe64(in) - -#define le16toh(in) htole16(in) -#define le32toh(in) htole32(in) -#define le64toh(in) htole64(in) - -#define htonw(in) htobe16(in) -#define htonl(in) htobe32(in) -#define htonll(in) htobe64(in) - -#define ntohw(in) be16toh(in) -#define ntohl(in) be32toh(in) -#define ntohll(in) be64toh(in) - -/* - * Alignment-agnostic encode/decode bytestream to/from little/big endian. - */ - -static inline uint16_t be16dec(const void *pp) -{ - uint8_t const *p = (uint8_t const *)pp; - - return (uint16_t)((p[0] << 8) | p[1]); -} - -static inline uint32_t be32dec(const void *pp) -{ - uint8_t const *p = (uint8_t const *)pp; - - return (((uint32_t)p[0] << 24) | (uint32_t)(p[1] << 16) | - (uint32_t)(p[2] << 8) | p[3]); -} - -static inline uint64_t be64dec(const void *pp) -{ - uint8_t const *p = (uint8_t const *)pp; - - return (((uint64_t)p[0] << 56) | ((uint64_t)p[1] << 48) | - ((uint64_t)p[2] << 40) | ((uint64_t)p[3] << 32) | - ((uint64_t)p[4] << 24) | ((uint64_t)p[5] << 16) | - ((uint64_t)p[6] << 8) | p[7]); -} - -static inline uint16_t le16dec(const void *pp) -{ - uint8_t const *p = (uint8_t const *)pp; - - return (uint16_t)((p[1] << 8) | p[0]); -} - -static inline uint32_t le32dec(const void *pp) -{ - uint8_t const *p = (uint8_t const *)pp; - - return ((uint32_t)(p[3] << 24) | (uint32_t)(p[2] << 16) | - (uint32_t)(p[1] << 8) | p[0]); -} - -static inline uint64_t le64dec(const void *pp) -{ - uint8_t const *p = (uint8_t const *)pp; - - return (((uint64_t)p[7] << 56) | ((uint64_t)p[6] << 48) | - ((uint64_t)p[5] << 40) | ((uint64_t)p[4] << 32) | - ((uint64_t)p[3] << 24) | ((uint64_t)p[2] << 16) | - ((uint64_t)p[1] << 8) | p[0]); -} - -static inline void bebitenc(void *pp, uint32_t u, uint8_t b) -{ - uint8_t *p = (uint8_t *)pp; - int i; - - for (i = 0; i < b; i++) - p[(b - 1) - i] = (u >> i*8) & 0xFF; -} - -static inline void be16enc(void *pp, uint16_t u) -{ - bebitenc(pp, u, 2); -} - -static inline void be32enc(void *pp, uint32_t u) -{ - bebitenc(pp, u, 4); -} - -static inline void be64enc(void *pp, uint32_t u) -{ - bebitenc(pp, u, 8); -} - -static inline void lebitenc(void *pp, uint32_t u, uint8_t b) -{ - uint8_t *p = (uint8_t *)pp; - int i; - - for (i = 0; i < b; i++) - p[i] = (u >> i*8) & 0xFF; -} - -static inline void le16enc(void *pp, uint16_t u) -{ - lebitenc(pp, u, 2); -} - -static inline void le32enc(void *pp, uint32_t u) -{ - lebitenc(pp, u, 4); -} - -static inline void le64enc(void *pp, uint32_t u) -{ - lebitenc(pp, u, 8); -} +/* This include depends on previous definitions, do not move to the top. */ +#include /* Deprecated names (not in glibc / BSD) */ #define htobew(in) htobe16(in) @@ -193,74 +61,4 @@ static inline void le64enc(void *pp, uint32_t u) #define letohl(in) le32toh(in) #define letohll(in) le64toh(in) -/* read/write with uintptr_t address */ -#define read8p(addr) read8((void *)((uintptr_t)(addr))) -#define read16p(addr) read16((void *)((uintptr_t)(addr))) -#define read32p(addr) read32((void *)((uintptr_t)(addr))) -#define read64p(addr) read64((void *)((uintptr_t)(addr))) -#define write8p(addr, value) write8((void *)((uintptr_t)(addr)), value) -#define write16p(addr, value) write16((void *)((uintptr_t)(addr)), value) -#define write32p(addr, value) write32((void *)((uintptr_t)(addr)), value) -#define write64p(addr, value) write64((void *)((uintptr_t)(addr)), value) - -/* Handy bit manipulation macros */ - -#define __clrsetbits(endian, bits, addr, clear, set) \ - write##bits(addr, hto##endian##bits((endian##bits##toh( \ - read##bits(addr)) & ~((uint##bits##_t)(clear))) | (set))) - -#define clrbits_le64(addr, clear) __clrsetbits(le, 64, addr, clear, 0) -#define clrbits_be64(addr, clear) __clrsetbits(be, 64, addr, clear, 0) -#define clrbits_le32(addr, clear) __clrsetbits(le, 32, addr, clear, 0) -#define clrbits_be32(addr, clear) __clrsetbits(be, 32, addr, clear, 0) -#define clrbits_le16(addr, clear) __clrsetbits(le, 16, addr, clear, 0) -#define clrbits_be16(addr, clear) __clrsetbits(be, 16, addr, clear, 0) - -#define setbits_le64(addr, set) __clrsetbits(le, 64, addr, 0, set) -#define setbits_be64(addr, set) __clrsetbits(be, 64, addr, 0, set) -#define setbits_le32(addr, set) __clrsetbits(le, 32, addr, 0, set) -#define setbits_be32(addr, set) __clrsetbits(be, 32, addr, 0, set) -#define setbits_le16(addr, set) __clrsetbits(le, 16, addr, 0, set) -#define setbits_be16(addr, set) __clrsetbits(be, 16, addr, 0, set) - -#define clrsetbits_le64(addr, clear, set) __clrsetbits(le, 64, addr, clear, set) -#define clrsetbits_be64(addr, clear, set) __clrsetbits(be, 64, addr, clear, set) -#define clrsetbits_le32(addr, clear, set) __clrsetbits(le, 32, addr, clear, set) -#define clrsetbits_be32(addr, clear, set) __clrsetbits(be, 32, addr, clear, set) -#define clrsetbits_le16(addr, clear, set) __clrsetbits(le, 16, addr, clear, set) -#define clrsetbits_be16(addr, clear, set) __clrsetbits(be, 16, addr, clear, set) - -#define __clrsetbits_impl(bits, addr, clear, set) write##bits(addr, \ - (read##bits(addr) & ~((uint##bits##_t)(clear))) | (set)) - -#define clrsetbits8(addr, clear, set) __clrsetbits_impl(8, addr, clear, set) -#define clrsetbits16(addr, clear, set) __clrsetbits_impl(16, addr, clear, set) -#define clrsetbits32(addr, clear, set) __clrsetbits_impl(32, addr, clear, set) -#define clrsetbits64(addr, clear, set) __clrsetbits_impl(64, addr, clear, set) - -#define setbits8(addr, set) clrsetbits8(addr, 0, set) -#define setbits16(addr, set) clrsetbits16(addr, 0, set) -#define setbits32(addr, set) clrsetbits32(addr, 0, set) -#define setbits64(addr, set) clrsetbits64(addr, 0, set) - -#define clrbits8(addr, clear) clrsetbits8(addr, clear, 0) -#define clrbits16(addr, clear) clrsetbits16(addr, clear, 0) -#define clrbits32(addr, clear) clrsetbits32(addr, clear, 0) -#define clrbits64(addr, clear) clrsetbits64(addr, clear, 0) - -#define clrsetbits8p(addr, clear, set) clrsetbits8((void *)((uintptr_t)(addr)), clear, set) -#define clrsetbits16p(addr, clear, set) clrsetbits16((void *)((uintptr_t)(addr)), clear, set) -#define clrsetbits32p(addr, clear, set) clrsetbits32((void *)((uintptr_t)(addr)), clear, set) -#define clrsetbits64p(addr, clear, set) clrsetbits64((void *)((uintptr_t)(addr)), clear, set) - -#define setbits8p(addr, set) clrsetbits8((void *)((uintptr_t)(addr)), 0, set) -#define setbits16p(addr, set) clrsetbits16((void *)((uintptr_t)(addr)), 0, set) -#define setbits32p(addr, set) clrsetbits32((void *)((uintptr_t)(addr)), 0, set) -#define setbits64p(addr, set) clrsetbits64((void *)((uintptr_t)(addr)), 0, set) - -#define clrbits8p(addr, clear) clrsetbits8((void *)((uintptr_t)(addr)), clear, 0) -#define clrbits16p(addr, clear) clrsetbits16((void *)((uintptr_t)(addr)), clear, 0) -#define clrbits32p(addr, clear) clrsetbits32((void *)((uintptr_t)(addr)), clear, 0) -#define clrbits64p(addr, clear) clrsetbits64((void *)((uintptr_t)(addr)), clear, 0) - #endif /* _ENDIAN_H_ */ diff --git a/src/commonlib/bsd/include/commonlib/bsd/_endian.h b/src/commonlib/bsd/include/commonlib/bsd/_endian.h new file mode 100644 index 0000000000..d0d5be9f9f --- /dev/null +++ b/src/commonlib/bsd/include/commonlib/bsd/_endian.h @@ -0,0 +1,170 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef _COMMONLIB_BSD__ENDIAN_H_ +#define _COMMONLIB_BSD__ENDIAN_H_ + +/* + * This header should not be included directly. Including source must define + * prerequisites like uintXX_t types, the byteswap functions swabXX(), + * __BIG_ENDIAN or __LITTLE_ENDIAN and I/O accessors readXX()/writeXX(). + */ + +/* Endian functions from glibc 2.9 / BSD "endian.h" */ + +#if defined(__BIG_ENDIAN) + #define htobe16(in) (in) + #define htobe32(in) (in) + #define htobe64(in) (in) + #define htole16(in) ((uint16_t)swab16(in)) + #define htole32(in) ((uint32_t)swab32(in)) + #define htole64(in) ((uint64_t)swab64(in)) +#elif defined(__LITTLE_ENDIAN) + #define htobe16(in) ((uint16_t)swab16(in)) + #define htobe32(in) ((uint32_t)swab32(in)) + #define htobe64(in) ((uint64_t)swab64(in)) + #define htole16(in) (in) + #define htole32(in) (in) + #define htole64(in) (in) +#else + #error "Including source must #define __LITTLE_ENDIAN or __BIG_ENDIAN" +#endif + +#define be16toh(in) htobe16(in) +#define be32toh(in) htobe32(in) +#define be64toh(in) htobe64(in) + +#define le16toh(in) htole16(in) +#define le32toh(in) htole32(in) +#define le64toh(in) htole64(in) + +#define htonw(in) htobe16(in) +#define htonl(in) htobe32(in) +#define htonll(in) htobe64(in) + +#define ntohw(in) be16toh(in) +#define ntohl(in) be32toh(in) +#define ntohll(in) be64toh(in) + +/* + * RISC-V doesn't support misaligned access so it must use memcpy(). + */ +#if defined(__COREBOOT__) && ENV_RISCV +#define __ENDIAN_RISCV_WORKAROUND 1 +#else +#define __ENDIAN_RISCV_WORKAROUND 0 +#endif + +/* + * be16dec/be32dec/be64dec/le16dec/le32dec/le64dec family of functions. + */ +#define DEFINE_ENDIAN_DEC(endian, width) \ + static inline uint##width##_t endian##width##dec(const void *p) \ + { \ + if (__ENDIAN_RISCV_WORKAROUND) { \ + uint##width##_t val; \ + memcpy(&val, p, sizeof(val)); \ + return endian##width##toh(val); \ + } else { \ + return endian##width##toh(*(uint##width##_t *)p); \ + } \ + } + +DEFINE_ENDIAN_DEC(be, 16) +DEFINE_ENDIAN_DEC(be, 32) +DEFINE_ENDIAN_DEC(be, 64) +DEFINE_ENDIAN_DEC(le, 16) +DEFINE_ENDIAN_DEC(le, 32) +DEFINE_ENDIAN_DEC(le, 64) + +/* + * be16enc/be32enc/be64enc/le16enc/le32enc/le64enc family of functions. + */ +#define DEFINE_ENDIAN_ENC(endian, width) \ + static inline void endian##width##enc(void *p, uint##width##_t u) \ + { \ + if (__ENDIAN_RISCV_WORKAROUND) { \ + uint##width##_t val = hto##endian##width(u); \ + memcpy(p, &val, sizeof(val)); \ + } else { \ + *(uint##width##_t *)p = hto##endian##width(u); \ + } \ + } + +DEFINE_ENDIAN_ENC(be, 16) +DEFINE_ENDIAN_ENC(be, 32) +DEFINE_ENDIAN_ENC(be, 64) +DEFINE_ENDIAN_ENC(le, 16) +DEFINE_ENDIAN_ENC(le, 32) +DEFINE_ENDIAN_ENC(le, 64) + +/* read/write with uintptr_t address */ +#define read8p(addr) read8((void *)((uintptr_t)(addr))) +#define read16p(addr) read16((void *)((uintptr_t)(addr))) +#define read32p(addr) read32((void *)((uintptr_t)(addr))) +#define read64p(addr) read64((void *)((uintptr_t)(addr))) +#define write8p(addr, value) write8((void *)((uintptr_t)(addr)), value) +#define write16p(addr, value) write16((void *)((uintptr_t)(addr)), value) +#define write32p(addr, value) write32((void *)((uintptr_t)(addr)), value) +#define write64p(addr, value) write64((void *)((uintptr_t)(addr)), value) + +/* Handy bit manipulation macros */ + +#define __clrsetbits(endian, bits, addr, clear, set) \ + write##bits(addr, hto##endian##bits((endian##bits##toh( \ + read##bits(addr)) & ~((uint##bits##_t)(clear))) | (set))) + +#define clrbits_le64(addr, clear) __clrsetbits(le, 64, addr, clear, 0) +#define clrbits_be64(addr, clear) __clrsetbits(be, 64, addr, clear, 0) +#define clrbits_le32(addr, clear) __clrsetbits(le, 32, addr, clear, 0) +#define clrbits_be32(addr, clear) __clrsetbits(be, 32, addr, clear, 0) +#define clrbits_le16(addr, clear) __clrsetbits(le, 16, addr, clear, 0) +#define clrbits_be16(addr, clear) __clrsetbits(be, 16, addr, clear, 0) + +#define setbits_le64(addr, set) __clrsetbits(le, 64, addr, 0, set) +#define setbits_be64(addr, set) __clrsetbits(be, 64, addr, 0, set) +#define setbits_le32(addr, set) __clrsetbits(le, 32, addr, 0, set) +#define setbits_be32(addr, set) __clrsetbits(be, 32, addr, 0, set) +#define setbits_le16(addr, set) __clrsetbits(le, 16, addr, 0, set) +#define setbits_be16(addr, set) __clrsetbits(be, 16, addr, 0, set) + +#define clrsetbits_le64(addr, clear, set) __clrsetbits(le, 64, addr, clear, set) +#define clrsetbits_be64(addr, clear, set) __clrsetbits(be, 64, addr, clear, set) +#define clrsetbits_le32(addr, clear, set) __clrsetbits(le, 32, addr, clear, set) +#define clrsetbits_be32(addr, clear, set) __clrsetbits(be, 32, addr, clear, set) +#define clrsetbits_le16(addr, clear, set) __clrsetbits(le, 16, addr, clear, set) +#define clrsetbits_be16(addr, clear, set) __clrsetbits(be, 16, addr, clear, set) + +#define __clrsetbits_impl(bits, addr, clear, set) write##bits(addr, \ + (read##bits(addr) & ~((uint##bits##_t)(clear))) | (set)) + +#define clrsetbits8(addr, clear, set) __clrsetbits_impl(8, addr, clear, set) +#define clrsetbits16(addr, clear, set) __clrsetbits_impl(16, addr, clear, set) +#define clrsetbits32(addr, clear, set) __clrsetbits_impl(32, addr, clear, set) +#define clrsetbits64(addr, clear, set) __clrsetbits_impl(64, addr, clear, set) + +#define setbits8(addr, set) clrsetbits8(addr, 0, set) +#define setbits16(addr, set) clrsetbits16(addr, 0, set) +#define setbits32(addr, set) clrsetbits32(addr, 0, set) +#define setbits64(addr, set) clrsetbits64(addr, 0, set) + +#define clrbits8(addr, clear) clrsetbits8(addr, clear, 0) +#define clrbits16(addr, clear) clrsetbits16(addr, clear, 0) +#define clrbits32(addr, clear) clrsetbits32(addr, clear, 0) +#define clrbits64(addr, clear) clrsetbits64(addr, clear, 0) + +#define clrsetbits8p(addr, clear, set) clrsetbits8((void *)((uintptr_t)(addr)), clear, set) +#define clrsetbits16p(addr, clear, set) clrsetbits16((void *)((uintptr_t)(addr)), clear, set) +#define clrsetbits32p(addr, clear, set) clrsetbits32((void *)((uintptr_t)(addr)), clear, set) +#define clrsetbits64p(addr, clear, set) clrsetbits64((void *)((uintptr_t)(addr)), clear, set) + +#define setbits8p(addr, set) clrsetbits8((void *)((uintptr_t)(addr)), 0, set) +#define setbits16p(addr, set) clrsetbits16((void *)((uintptr_t)(addr)), 0, set) +#define setbits32p(addr, set) clrsetbits32((void *)((uintptr_t)(addr)), 0, set) +#define setbits64p(addr, set) clrsetbits64((void *)((uintptr_t)(addr)), 0, set) + +#define clrbits8p(addr, clear) clrsetbits8((void *)((uintptr_t)(addr)), clear, 0) +#define clrbits16p(addr, clear) clrsetbits16((void *)((uintptr_t)(addr)), clear, 0) +#define clrbits32p(addr, clear) clrsetbits32((void *)((uintptr_t)(addr)), clear, 0) +#define clrbits64p(addr, clear) clrsetbits64((void *)((uintptr_t)(addr)), clear, 0) + +#endif /* _COMMONLIB_BSD__ENDIAN_H_ */ diff --git a/src/include/device/mmio.h b/src/include/device/mmio.h index 2b9949e05a..d6b8b26398 100644 --- a/src/include/device/mmio.h +++ b/src/include/device/mmio.h @@ -8,39 +8,6 @@ #include #include -#define __clrsetbits_impl(bits, addr, clear, set) write##bits(addr, \ - (read##bits(addr) & ~((uint##bits##_t)(clear))) | (set)) - -#define clrsetbits8(addr, clear, set) __clrsetbits_impl(8, addr, clear, set) -#define clrsetbits16(addr, clear, set) __clrsetbits_impl(16, addr, clear, set) -#define clrsetbits32(addr, clear, set) __clrsetbits_impl(32, addr, clear, set) -#define clrsetbits64(addr, clear, set) __clrsetbits_impl(64, addr, clear, set) - -#define setbits8(addr, set) clrsetbits8(addr, 0, set) -#define setbits16(addr, set) clrsetbits16(addr, 0, set) -#define setbits32(addr, set) clrsetbits32(addr, 0, set) -#define setbits64(addr, set) clrsetbits64(addr, 0, set) - -#define clrbits8(addr, clear) clrsetbits8(addr, clear, 0) -#define clrbits16(addr, clear) clrsetbits16(addr, clear, 0) -#define clrbits32(addr, clear) clrsetbits32(addr, clear, 0) -#define clrbits64(addr, clear) clrsetbits64(addr, clear, 0) - -#define clrsetbits8p(addr, clear, set) clrsetbits8((void *)((uintptr_t)addr), clear, set) -#define clrsetbits16p(addr, clear, set) clrsetbits16((void *)((uintptr_t)addr), clear, set) -#define clrsetbits32p(addr, clear, set) clrsetbits32((void *)((uintptr_t)addr), clear, set) -#define clrsetbits64p(addr, clear, set) clrsetbits64((void *)((uintptr_t)addr), clear, set) - -#define setbits8p(addr, set) clrsetbits8((void *)((uintptr_t)addr), 0, set) -#define setbits16p(addr, set) clrsetbits16((void *)((uintptr_t)addr), 0, set) -#define setbits32p(addr, set) clrsetbits32((void *)((uintptr_t)addr), 0, set) -#define setbits64p(addr, set) clrsetbits64((void *)((uintptr_t)addr), 0, set) - -#define clrbits8p(addr, clear) clrsetbits8((void *)((uintptr_t)addr), clear, 0) -#define clrbits16p(addr, clear) clrsetbits16((void *)((uintptr_t)addr), clear, 0) -#define clrbits32p(addr, clear) clrsetbits32((void *)((uintptr_t)addr), clear, 0) -#define clrbits64p(addr, clear) clrsetbits64((void *)((uintptr_t)addr), clear, 0) - /* * Reads a transfer buffer from 32-bit FIFO registers. fifo_stride is the * distance in bytes between registers (e.g. pass 4 for a normal array of 32-bit @@ -222,44 +189,4 @@ static inline void buffer_to_fifo32(const void *buffer, size_t size, void *fifo, #define READ32_BITFIELD(addr, name) \ EXTRACT_BITFIELD(read32(addr), name) -static __always_inline uint8_t read8p(const uintptr_t addr) -{ - return read8((void *)addr); -} - -static __always_inline uint16_t read16p(const uintptr_t addr) -{ - return read16((void *)addr); -} - -static __always_inline uint32_t read32p(const uintptr_t addr) -{ - return read32((void *)addr); -} - -static __always_inline uint64_t read64p(const uintptr_t addr) -{ - return read64((void *)addr); -} - -static __always_inline void write8p(const uintptr_t addr, const uint8_t value) -{ - write8((void *)addr, value); -} - -static __always_inline void write16p(const uintptr_t addr, const uint16_t value) -{ - write16((void *)addr, value); -} - -static __always_inline void write32p(const uintptr_t addr, const uint32_t value) -{ - write32((void *)addr, value); -} - -static __always_inline void write64p(const uintptr_t addr, const uint64_t value) -{ - write64((void *)addr, value); -} - #endif /* __DEVICE_MMIO_H__ */ diff --git a/src/include/endian.h b/src/include/endian.h index 5cdcb2db54..efc56dd7be 100644 --- a/src/include/endian.h +++ b/src/include/endian.h @@ -8,173 +8,20 @@ #include #include -#if defined(__LITTLE_ENDIAN) - #define cpu_to_le64(x) ((uint64_t)(x)) - #define le64_to_cpu(x) ((uint64_t)(x)) - #define cpu_to_le32(x) ((uint32_t)(x)) - #define le32_to_cpu(x) ((uint32_t)(x)) - #define cpu_to_le16(x) ((uint16_t)(x)) - #define le16_to_cpu(x) ((uint16_t)(x)) - #define cpu_to_be64(x) swab64(x) - #define be64_to_cpu(x) swab64(x) - #define cpu_to_be32(x) swab32(x) - #define be32_to_cpu(x) swab32(x) - #define cpu_to_be16(x) swab16(x) - #define be16_to_cpu(x) swab16(x) -#elif defined(__BIG_ENDIAN) - #define cpu_to_le64(x) swab64(x) - #define le64_to_cpu(x) swab64(x) - #define cpu_to_le32(x) swab32(x) - #define le32_to_cpu(x) swab32(x) - #define cpu_to_le16(x) swab16(x) - #define le16_to_cpu(x) swab16(x) - #define cpu_to_be64(x) ((uint64_t)(x)) - #define be64_to_cpu(x) ((uint64_t)(x)) - #define cpu_to_be32(x) ((uint32_t)(x)) - #define be32_to_cpu(x) ((uint32_t)(x)) - #define cpu_to_be16(x) ((uint16_t)(x)) - #define be16_to_cpu(x) ((uint16_t)(x)) -#else - #error " must #define __LITTLE_ENDIAN or __BIG_ENDIAN" -#endif +/* This include depends on previous ones, do not reorder. */ +#include -#define ntohll(x) be64_to_cpu(x) -#define htonll(x) cpu_to_be64(x) -#define ntohl(x) be32_to_cpu(x) -#define htonl(x) cpu_to_be32(x) - -#define __clrsetbits(endian, bits, addr, clear, set) \ - write##bits(addr, cpu_to_##endian##bits((endian##bits##_to_cpu( \ - read##bits(addr)) & ~((uint##bits##_t)(clear))) | (set))) - -#define clrbits_le64(addr, clear) __clrsetbits(le, 64, addr, clear, 0) -#define clrbits_be64(addr, clear) __clrsetbits(be, 64, addr, clear, 0) -#define clrbits_le32(addr, clear) __clrsetbits(le, 32, addr, clear, 0) -#define clrbits_be32(addr, clear) __clrsetbits(be, 32, addr, clear, 0) -#define clrbits_le16(addr, clear) __clrsetbits(le, 16, addr, clear, 0) -#define clrbits_be16(addr, clear) __clrsetbits(be, 16, addr, clear, 0) - -#define setbits_le64(addr, set) __clrsetbits(le, 64, addr, 0, set) -#define setbits_be64(addr, set) __clrsetbits(be, 64, addr, 0, set) -#define setbits_le32(addr, set) __clrsetbits(le, 32, addr, 0, set) -#define setbits_be32(addr, set) __clrsetbits(be, 32, addr, 0, set) -#define setbits_le16(addr, set) __clrsetbits(le, 16, addr, 0, set) -#define setbits_be16(addr, set) __clrsetbits(be, 16, addr, 0, set) - -#define clrsetbits_le64(addr, clear, set) __clrsetbits(le, 64, addr, clear, set) -#define clrsetbits_be64(addr, clear, set) __clrsetbits(be, 64, addr, clear, set) -#define clrsetbits_le32(addr, clear, set) __clrsetbits(le, 32, addr, clear, set) -#define clrsetbits_be32(addr, clear, set) __clrsetbits(be, 32, addr, clear, set) -#define clrsetbits_le16(addr, clear, set) __clrsetbits(le, 16, addr, clear, set) -#define clrsetbits_be16(addr, clear, set) __clrsetbits(be, 16, addr, clear, set) - -/* - * be16dec/be32dec/be64dec/le16dec/le32dec/le64dec family of functions. - * RISC-V doesn't support misaligned access so decode it byte by byte. - */ -#define DEFINE_ENDIAN_DEC(endian, width) \ - static inline uint##width##_t endian##width##dec(const void *p) \ - { \ - if (ENV_RISCV) { \ - uint##width##_t val; \ - memcpy(&val, p, sizeof(val)); \ - return endian##width##_to_cpu(val); \ - } else { \ - return endian##width##_to_cpu(*(uint##width##_t *)p); \ - } \ - } - -DEFINE_ENDIAN_DEC(be, 16) -DEFINE_ENDIAN_DEC(be, 32) -DEFINE_ENDIAN_DEC(be, 64) -DEFINE_ENDIAN_DEC(le, 16) -DEFINE_ENDIAN_DEC(le, 32) -DEFINE_ENDIAN_DEC(le, 64) - -/* - * be16enc/be32enc/be64enc/le16enc/le32enc/le64enc family of functions. - * RISC-V doesn't support misaligned access so encode it byte by byte. - */ -#define DEFINE_ENDIAN_ENC(endian, width) \ - static inline void endian##width##enc(void *p, uint##width##_t u) \ - { \ - if (ENV_RISCV) { \ - uint##width##_t val = cpu_to_##endian##width(u); \ - memcpy(p, &val, sizeof(val)); \ - } else { \ - *(uint##width##_t *)p = cpu_to_##endian##width(u); \ - } \ - } - -DEFINE_ENDIAN_ENC(be, 16) -DEFINE_ENDIAN_ENC(be, 32) -DEFINE_ENDIAN_ENC(be, 64) -DEFINE_ENDIAN_ENC(le, 16) -DEFINE_ENDIAN_ENC(le, 32) -DEFINE_ENDIAN_ENC(le, 64) - -/* - * Portable (API) endian support that can be used in code that is shared - * with userspace (man 3 endian) tools. - */ -static inline uint16_t htobe16(uint16_t host_16bits) -{ - return cpu_to_be16(host_16bits); -} - -static inline uint16_t htole16(uint16_t host_16bits) -{ - return cpu_to_le16(host_16bits); -} - -static inline uint16_t be16toh(uint16_t big_endian_16bits) -{ - return be16_to_cpu(big_endian_16bits); -} - -static inline uint16_t le16toh(uint16_t little_endian_16bits) -{ - return le16_to_cpu(little_endian_16bits); -} - -static inline uint32_t htobe32(uint32_t host_32bits) -{ - return cpu_to_be32(host_32bits); -} - -static inline uint32_t htole32(uint32_t host_32bits) -{ - return cpu_to_le32(host_32bits); -} - -static inline uint32_t be32toh(uint32_t big_endian_32bits) -{ - return be32_to_cpu(big_endian_32bits); -} - -static inline uint32_t le32toh(uint32_t little_endian_32bits) -{ - return le32_to_cpu(little_endian_32bits); -} - -static inline uint64_t htobe64(uint64_t host_64bits) -{ - return cpu_to_be64(host_64bits); -} - -static inline uint64_t htole64(uint64_t host_64bits) -{ - return cpu_to_le64(host_64bits); -} - -static inline uint64_t be64toh(uint64_t big_endian_64bits) -{ - return be64_to_cpu(big_endian_64bits); -} - -static inline uint64_t le64toh(uint64_t little_endian_64bits) -{ - return le64_to_cpu(little_endian_64bits); -} +#define be64_to_cpu(x) be64toh(x) +#define be32_to_cpu(x) be32toh(x) +#define be16_to_cpu(x) be16toh(x) +#define le64_to_cpu(x) le64toh(x) +#define le32_to_cpu(x) le32toh(x) +#define le16_to_cpu(x) le16toh(x) +#define cpu_to_be64(x) htobe64(x) +#define cpu_to_be32(x) htobe32(x) +#define cpu_to_be16(x) htobe16(x) +#define cpu_to_le64(x) htole64(x) +#define cpu_to_le32(x) htole32(x) +#define cpu_to_le16(x) htole16(x) #endif