github.com/afumu/libc@v0.0.6/musl/src/linux/cache.c (about)

     1  #include <errno.h>
     2  #include "syscall.h"
     3  #include "atomic.h"
     4  
     5  #ifdef SYS_cacheflush
     6  int _flush_cache(void *addr, int len, int op)
     7  {
     8  	return syscall(SYS_cacheflush, addr, len, op);
     9  }
    10  weak_alias(_flush_cache, cacheflush);
    11  #endif
    12  
    13  #ifdef SYS_cachectl
    14  int __cachectl(void *addr, int len, int op)
    15  {
    16  	return syscall(SYS_cachectl, addr, len, op);
    17  }
    18  weak_alias(__cachectl, cachectl);
    19  #endif
    20  
    21  #ifdef SYS_riscv_flush_icache
    22  
    23  #define VDSO_FLUSH_ICACHE_SYM "__vdso_flush_icache"
    24  #define VDSO_FLUSH_ICACHE_VER "LINUX_4.5"
    25  
    26  static void *volatile vdso_func;
    27  
    28  static int flush_icache_init(void *start, void *end, unsigned long int flags)
    29  {
    30  	void *p = __vdsosym(VDSO_FLUSH_ICACHE_VER, VDSO_FLUSH_ICACHE_SYM);
    31  	int (*f)(void *, void *, unsigned long int) =
    32  		(int (*)(void *, void *, unsigned long int))p;
    33  	a_cas_p(&vdso_func, (void *)flush_icache_init, p);
    34  	return f ? f(start, end, flags) : -ENOSYS;
    35  }
    36  
    37  static void *volatile vdso_func = (void *)flush_icache_init;
    38  
    39  int __riscv_flush_icache(void *start, void *end, unsigned long int flags) 
    40  {
    41  	int (*f)(void *, void *, unsigned long int) =
    42  		(int (*)(void *, void *, unsigned long int))vdso_func;
    43  	if (f) {
    44  		int r = f(start, end, flags);
    45  		if (!r) return r;
    46  		if (r != -ENOSYS) return __syscall_ret(r);
    47  	}
    48  }
    49  weak_alias(__riscv_flush_icache, riscv_flush_icache);
    50  #endif