From d99143cd65e0d0879764e4524316bdf3dac2d0c2 Mon Sep 17 00:00:00 2001 From: Zheng Zhang Date: Fri, 29 Aug 2025 16:48:21 +0800 Subject: [PATCH] util: Add mmio helpers functions for riscv Fix the issue where using intrinsics to generate atomic load/store instructions on RISC-V caused SEGFAULT when accessing MMIO regions, by adding a RISC-V specific implementation to resolve the problem. Signed-off-by: Zheng Zhang --- util/mmio.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/util/mmio.h b/util/mmio.h index 9af35099d..89936fe92 100644 --- a/util/mmio.h +++ b/util/mmio.h @@ -124,7 +124,53 @@ static inline uint8_t mmio_read8(const void *addr) return res; } -#else /* __s390x__ */ +#elif defined(__riscv) + +#define MAKE_WRITE(_NAME_, _SZ_) \ + static inline void _NAME_##_be(void *addr, __be##_SZ_ val) \ + { \ + __atomic_thread_fence(__ATOMIC_RELEASE); \ + *(volatile uint##_SZ_##_t *)addr = (uint##_SZ_##_t) val; \ + __atomic_thread_fence(__ATOMIC_SEQ_CST); \ + } \ + static inline void _NAME_##_le(void *addr, __le##_SZ_ val) \ + { \ + __atomic_thread_fence(__ATOMIC_RELEASE); \ + *(volatile uint##_SZ_##_t *)addr = (uint##_SZ_##_t) val; \ + __atomic_thread_fence(__ATOMIC_SEQ_CST); \ + } + +#define MAKE_READ(_NAME_, _SZ_) \ + static inline __be##_SZ_ _NAME_##_be(const void *addr) \ + { \ + __atomic_thread_fence(__ATOMIC_RELEASE); \ + __be##_SZ_ val = *(const uint##_SZ_##_t *)addr; \ + __atomic_thread_fence(__ATOMIC_SEQ_CST); \ + return val; \ + } \ + static inline __le##_SZ_ _NAME_##_le(const void *addr) \ + { \ + __atomic_thread_fence(__ATOMIC_RELEASE); \ + __le##_SZ_ val = *(const uint##_SZ_##_t *)addr; \ + __atomic_thread_fence(__ATOMIC_SEQ_CST); \ + return val; \ + } + +static inline void mmio_write8(void *addr, uint8_t val) +{ + __atomic_thread_fence(__ATOMIC_RELEASE); + *(uint8_t *)addr = val; + __atomic_thread_fence(__ATOMIC_SEQ_CST); +} +static inline uint8_t mmio_read8(const void *addr) +{ + __atomic_thread_fence(__ATOMIC_RELEASE); + uint8_t val = *(uint8_t *)addr; + __atomic_thread_fence(__ATOMIC_SEQ_CST); + return val; +} + +#else #define MAKE_WRITE(_NAME_, _SZ_) \ static inline void _NAME_##_be(void *addr, __be##_SZ_ value) \ @@ -161,7 +207,7 @@ static inline uint8_t mmio_read8(const void *addr) return atomic_load_explicit((_Atomic(uint8_t) *)addr, memory_order_relaxed); } -#endif /* __s390x__ */ +#endif MAKE_WRITE(mmio_write16, 16) MAKE_WRITE(mmio_write32, 32)