[PATCH v2] atomics: fix AMO test macros

Anup Patel anup at brainfault.org
Sun Dec 28 07:16:46 PST 2025


On Sun, Dec 28, 2025 at 1:03 PM Vladimir Kondratiev
<vladimir.kondratiev at mobileye.com> wrote:
>
> The "RISC-V C API" [1] defines architecture extension test macros
> says naming rule for the test macros is __riscv_<ext_name>,
> where <ext_name> is all lower-case.
> 3 extensions dealing with atomics implementation,
> "zaamo" consists of AMO instructions, "zalrsc" - LR/SC,
> "a" extension means both "zaamo" and "zalrsc"
> Test macros are __riscv_a, __riscv_zaamo and __riscv_zalrsc.
> Alternative to the __riscv_a macro name, __riscv_atomic, is deprecated.
>
> Use correct test macro __riscv_zaamo for the AMO variant of atomics.
> It used to be __riscv_atomic that is both deprecated and incorrect
> because it tests for the "a" extension; i.e. both "zaamo" and "zalrsc"
> If ISA enables only zaamo but not zalrsc, code as it was would not compile.
>
> Older toolchains may have neither __riscv_zaamo nor __riscv_zalrsc, so
> query __riscv_atomic - it should be treated as both __riscv_zaamo and
> __riscv_zalrsc, in all present cases __riscv_zaamo is more favorable
> so take is as alternative for __riscv_zaamo
>
> [1] https://github.com/riscv-non-isa/riscv-c-api-doc
>
> Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev at mobileye.com>

I did some minor cosmetic changes to commit description
at the time of merging this patch.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
>  firmware/fw_base.S            |  4 ++--
>  firmware/payloads/test_head.S |  4 ++--
>  lib/sbi/riscv_atomic.c        | 16 ++++++++--------
>  lib/sbi/riscv_locks.c         |  6 +++---
>  lib/sbi/sbi_illegal_atomic.c  |  8 ++++----
>  5 files changed, 19 insertions(+), 19 deletions(-)
>
> diff --git a/firmware/fw_base.S b/firmware/fw_base.S
> index 5300ecf22e0c..bce9e2268424 100644
> --- a/firmware/fw_base.S
> +++ b/firmware/fw_base.S
> @@ -59,10 +59,10 @@ _try_lottery:
>         /* Jump to relocation wait loop if we don't get relocation lottery */
>         lla     a6, _boot_lottery
>         li      a7, BOOT_LOTTERY_ACQUIRED
> -#ifdef __riscv_atomic
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
>         amoswap.w a6, a7, (a6)
>         bnez    a6, _wait_for_boot_hart
> -#elif __riscv_zalrsc
> +#elif defined(__riscv_zalrsc)
>  _sc_fail:
>         lr.w    t0, (a6)
>         sc.w    t1, a7, (a6)
> diff --git a/firmware/payloads/test_head.S b/firmware/payloads/test_head.S
> index 070ce8aa98be..9a87e56fcf5d 100644
> --- a/firmware/payloads/test_head.S
> +++ b/firmware/payloads/test_head.S
> @@ -30,9 +30,9 @@ _start:
>         /* Pick one hart to run the main boot sequence */
>         lla     a3, _hart_lottery
>         li      a2, 1
> -#ifdef __riscv_atomic
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
>         amoadd.w a3, a2, (a3)
> -#elif __riscv_zalrsc
> +#elif defined(__riscv_zalrsc)
>  _sc_fail:
>         lr.w    t0, (a3)
>         addw    t1, t0, a2
> diff --git a/lib/sbi/riscv_atomic.c b/lib/sbi/riscv_atomic.c
> index df16a2eb159e..a7756a00c35c 100644
> --- a/lib/sbi/riscv_atomic.c
> +++ b/lib/sbi/riscv_atomic.c
> @@ -12,8 +12,8 @@
>  #include <sbi/riscv_atomic.h>
>  #include <sbi/riscv_barrier.h>
>
> -#if !defined(__riscv_atomic) && !defined(__riscv_zalrsc)
> -#error "opensbi strongly relies on the A extension of RISC-V"
> +#if !defined(__riscv_atomic) && !defined(__riscv_zaamo) && !defined(__riscv_zalrsc)
> +#error "opensbi strongly relies on the zaamo or zalrsc extension of RISC-V"
>  #endif
>
>  long atomic_read(atomic_t *atom)
> @@ -31,7 +31,7 @@ void atomic_write(atomic_t *atom, long value)
>
>  long atomic_add_return(atomic_t *atom, long value)
>  {
> -#ifdef __riscv_atomic
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
>         long ret;
>  #if __SIZEOF_LONG__ == 4
>         __asm__ __volatile__("  amoadd.w.aqrl  %1, %2, %0"
> @@ -44,7 +44,7 @@ long atomic_add_return(atomic_t *atom, long value)
>                              : "r"(value)
>                              : "memory");
>  #endif
> -#elif __riscv_zalrsc
> +#elif defined(__riscv_zalrsc)
>         long ret, temp;
>  #if __SIZEOF_LONG__ == 4
>         __asm__ __volatile__("1:lr.w.aqrl       %1,%0\n"
> @@ -64,7 +64,7 @@ long atomic_add_return(atomic_t *atom, long value)
>                              : "memory");
>  #endif
>  #else
> -#error "need a or zalrsc"
> +#error "need a/zaamo or zalrsc"
>  #endif
>
>         return ret + value;
> @@ -75,7 +75,7 @@ long atomic_sub_return(atomic_t *atom, long value)
>         return atomic_add_return(atom, -value);
>  }
>
> -#ifdef __riscv_atomic
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
>  #define __axchg(ptr, new, size)                                                        \
>         ({                                                                      \
>                 __typeof__(ptr) __ptr = (ptr);                                  \
> @@ -101,7 +101,7 @@ long atomic_sub_return(atomic_t *atom, long value)
>                 }                                                               \
>                 __ret;                                                          \
>         })
> -#elif __riscv_zalrsc
> +#elif defined(__riscv_zalrsc)
>  #define __axchg(ptr, new, size)                                                        \
>         ({                                                                      \
>                 __typeof__(ptr) __ptr = (ptr);                                  \
> @@ -132,7 +132,7 @@ long atomic_sub_return(atomic_t *atom, long value)
>                 __ret;                                                          \
>         })
>  #else
> -#error "need a or zalrsc"
> +#error "need a/zaamo or zalrsc"
>  #endif
>
>  #define axchg(ptr, x)                                                          \
> diff --git a/lib/sbi/riscv_locks.c b/lib/sbi/riscv_locks.c
> index 41e8fabd08be..02ecb4e4189b 100644
> --- a/lib/sbi/riscv_locks.c
> +++ b/lib/sbi/riscv_locks.c
> @@ -53,15 +53,15 @@ void spin_lock(spinlock_t *lock)
>
>         __asm__ __volatile__(
>                 /* Atomically increment the next ticket. */
> -#ifdef __riscv_atomic
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
>                 "       amoadd.w.aqrl   %0, %4, %3\n"
> -#elif __riscv_zalrsc
> +#elif defined(__riscv_zalrsc)
>                 "3:     lr.w.aqrl       %0, %3\n"
>                 "       addw    %1, %0, %4\n"
>                 "       sc.w.aqrl       %1, %1, %3\n"
>                 "       bnez    %1, 3b\n"
>  #else
> -#error "need a or zalrsc"
> +#error "need a/zaamo or zalrsc"
>  #endif
>
>                 /* Did we get the lock? */
> diff --git a/lib/sbi/sbi_illegal_atomic.c b/lib/sbi/sbi_illegal_atomic.c
> index 8fd6c5575bfb..dd4ea2ed34c1 100644
> --- a/lib/sbi/sbi_illegal_atomic.c
> +++ b/lib/sbi/sbi_illegal_atomic.c
> @@ -11,18 +11,18 @@
>  #include <sbi/sbi_illegal_atomic.h>
>  #include <sbi/sbi_illegal_insn.h>
>
> -#if !defined(__riscv_atomic) && !defined(__riscv_zalrsc)
> -#error "opensbi strongly relies on the A extension of RISC-V"
> +#if !defined(__riscv_atomic) && !defined(__riscv_zaamo) && !defined(__riscv_zalrsc)
> +#error "opensbi strongly relies on the zaamo or zalrsc extension of RISC-V"
>  #endif
>
> -#ifdef __riscv_atomic
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
>
>  int sbi_illegal_atomic(ulong insn, struct sbi_trap_regs *regs)
>  {
>         return truly_illegal_insn(insn, regs);
>  }
>
> -#elif __riscv_zalrsc
> +#elif defined(__riscv_zalrsc)
>
>  #define DEFINE_UNPRIVILEGED_LR_FUNCTION(type, aqrl, insn)                      \
>         static type lr_##type##aqrl(const type *addr,                           \
> --
> 2.43.0
>



More information about the opensbi mailing list