2021-05-13 20:29:44 +08:00

97 lines
3.4 KiB
C

/*
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
* You can use this software according to the terms and conditions of the Mulan PSL v1.
* You may obtain a copy of Mulan PSL v1 at:
* http://license.coscl.org.cn/MulanPSL
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v1 for more details.
*/
#pragma once
#include <common/types.h>
#define COMPILER_BARRIER() asm volatile("":::"memory")
#define sev() asm volatile("sev" : : : "memory")
#define wfe() asm volatile("wfe" : : : "memory")
#define wfi() asm volatile("wfi" : : : "memory")
#define isb() asm volatile("isb" : : : "memory")
#define dmb(opt) asm volatile("dmb " #opt : : : "memory")
#define dsb(opt) asm volatile("dsb " #opt : : : "memory")
#define mb() dsb(sy)
#define rmb() dsb(ld)
#define wmb() dsb(st)
#define smp_mb() dmb(ish)
#define smp_rmb() smp_mb()
#define smp_wmb() dmb(ishst)
#define dma_rmb() dmb(oshld)
#define dma_wmb() dmb(oshst)
#define ldar_32(ptr, value) asm volatile("ldar %w0, [%1]" : "=r" (value) : "r" (ptr))
#define stlr_32(ptr, value) asm volatile("stlr %w0, [%1]" : : "rZ" (value) , "r" (ptr))
#define ldar_64(ptr, value) asm volatile("ldar %x0, [%1]" : "=r" (value) : "r" (ptr))
#define stlr_64(ptr, value) asm volatile("stlr %x0, [%1]" : : "rZ" (value) , "r" (ptr))
#define __atomic_compare_exchange(ptr, compare, exchange, len, width) \
({ \
u##len oldval; \
u32 ret; \
asm volatile ("1: ldaxr %"#width"0, %2\n" \
" cmp %"#width"0, %"#width"3\n" \
" b.ne 2f\n" \
" stlxr %w1, %"#width"4, %2\n" \
" cbnz %w1, 1b\n" \
"2:":"=&r" (oldval), "=&r"(ret), "+Q"(*ptr) \
:"r"(compare), "r"(exchange) \
); \
oldval; \
})
#define atomic_compare_exchange_64(ptr, compare, exchange) \
__atomic_compare_exchange(ptr, compare, exchange, 64, x)
#define atomic_compare_exchange_32(ptr, compare, exchange) \
__atomic_compare_exchange(ptr, compare, exchange, 32, w)
static inline s64 atomic_exchange_64(s64 * ptr, s64 exchange)
{
s64 oldval;
s32 ret;
asm volatile ("1: ldaxr %x0, %2\n"
" stlxr %w1, %x3, %2\n"
" cbnz %w1, 1b\n"
"2:":"=&r" (oldval), "=&r"(ret), "+Q"(*ptr)
:"r"(exchange)
);
return oldval;
}
#define __atomic_fetch_op(ptr, val, len, width, op) \
({ \
u##len oldval, newval; \
u32 ret; \
asm volatile ("1: ldaxr %"#width"0, %3\n" \
" "#op" %"#width"1, %"#width"0, %"#width"4\n" \
" stlxr %w2, %"#width"1, %3\n" \
" cbnz %w2, 1b\n" \
"2:":"=&r" (oldval), "=&r"(newval), \
"=&r"(ret), "+Q"(*ptr) \
:"r"(val) \
); \
oldval; \
})
#define atomic_fetch_sub_32(ptr, val) __atomic_fetch_op(ptr, val, 32, w, sub)
#define atomic_fetch_sub_64(ptr, val) __atomic_fetch_op(ptr, val, 64, x, sub)
#define atomic_fetch_add_32(ptr, val) __atomic_fetch_op(ptr, val, 32, w, add)
#define atomic_fetch_add_64(ptr, val) __atomic_fetch_op(ptr, val, 64, x, add)
#define atomic_set_bit_32(ptr, val) __atomic_fetch_op(ptr, 1<<(val), 32, w, or)