Maximilian Brune has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/86609?usp=email )
Change subject: include/endian.h: Add 'always aligned access' support ......................................................................
include/endian.h: Add 'always aligned access' support
RISC-V doesn't support unaligned access, so check for that before decoding and encoding. It is not perfectly performant, but still much better then invoking the misaligned exception handler every time there is a misaligned access. We can't modify our whole codebase to always do aligned access, because it is neither feasable in long term nor is fair to add that perfomance penalty onto other architectures that do support unaligned access. So this is the next best thing.
On architectures that do support unaligned access the compiler will just optimize the RISCV_ENV part out and should result in the exact same binary.
tested: identical binary on QEMU-aarch64 and QEMU-q35.
Change-Id: I4dfccfdc2b302dd30b7ce5a29520c86add13169d --- M .gitignore M 3rdparty/arm-trusted-firmware M src/include/endian.h 3 files changed, 27 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/09/86609/1
diff --git a/.gitignore b/.gitignore index e813493..de29581 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ *~ *.kate-swp *.kdev4 +.aider* diff --git a/3rdparty/arm-trusted-firmware b/3rdparty/arm-trusted-firmware index 15e5c6c..8fb9178 160000 --- a/3rdparty/arm-trusted-firmware +++ b/3rdparty/arm-trusted-firmware @@ -1 +1 @@ -Subproject commit 15e5c6c91d483aa52908154cc80e48956e234232 +Subproject commit 8fb91783ffa96343dd8ebad9773d7c2055ea4496 diff --git a/src/include/endian.h b/src/include/endian.h index 552ce002..c9df74d 100644 --- a/src/include/endian.h +++ b/src/include/endian.h @@ -5,7 +5,9 @@
#include <arch/byteorder.h> #include <stdint.h> +#include <string.h> #include <swab.h> +#include <rules.h>
#if defined(__LITTLE_ENDIAN) #define cpu_to_le64(x) ((uint64_t)(x)) @@ -67,12 +69,22 @@ #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. */ +/* + * 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) \ { \ - return endian##width##_to_cpu(*(uint##width##_t *)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) @@ -80,12 +92,21 @@ DEFINE_ENDIAN_DEC(le, 32) DEFINE_ENDIAN_DEC(le, 64)
-/* be16enc/be32enc/be64enc/le16enc/le32enc/le64enc family of functions. */ +/* + * 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) \ { \ - *(uint##width##_t *)p = cpu_to_##endian##width(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)