cache.c raw

   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
  51