Merge coreboot and libpayload <endian.h> 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 e8e92d60c4 ("endian.h: Add
be32dec/be32enc family of functions") to BSD-3.
Change-Id: I5eb83d44a98b3aa59bba65b8e22df668874d2668
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90308
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
5eb7b8bd34
commit
02a2fe7907
4 changed files with 193 additions and 451 deletions
|
|
@ -8,39 +8,6 @@
|
|||
#include <endian.h>
|
||||
#include <types.h>
|
||||
|
||||
#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__ */
|
||||
|
|
|
|||
|
|
@ -8,173 +8,20 @@
|
|||
#include <string.h>
|
||||
#include <swab.h>
|
||||
|
||||
#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 "<arch/byteorder.h> must #define __LITTLE_ENDIAN or __BIG_ENDIAN"
|
||||
#endif
|
||||
/* This include depends on previous ones, do not reorder. */
|
||||
#include <commonlib/bsd/_endian.h>
|
||||
|
||||
#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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue