97 lines
3.4 KiB
C
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)
|