Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (C) 2018 ARM Limited
0004  */
0005 #ifndef __ASM_VDSO_GETTIMEOFDAY_H
0006 #define __ASM_VDSO_GETTIMEOFDAY_H
0007 
0008 #ifndef __ASSEMBLY__
0009 
0010 #include <asm/barrier.h>
0011 #include <asm/unistd.h>
0012 
0013 #define VDSO_HAS_CLOCK_GETRES       1
0014 
0015 static __always_inline
0016 int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
0017               struct timezone *_tz)
0018 {
0019     register struct timezone *tz asm("x1") = _tz;
0020     register struct __kernel_old_timeval *tv asm("x0") = _tv;
0021     register long ret asm ("x0");
0022     register long nr asm("x8") = __NR_gettimeofday;
0023 
0024     asm volatile(
0025     "       svc #0\n"
0026     : "=r" (ret)
0027     : "r" (tv), "r" (tz), "r" (nr)
0028     : "memory");
0029 
0030     return ret;
0031 }
0032 
0033 static __always_inline
0034 long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
0035 {
0036     register struct __kernel_timespec *ts asm("x1") = _ts;
0037     register clockid_t clkid asm("x0") = _clkid;
0038     register long ret asm ("x0");
0039     register long nr asm("x8") = __NR_clock_gettime;
0040 
0041     asm volatile(
0042     "       svc #0\n"
0043     : "=r" (ret)
0044     : "r" (clkid), "r" (ts), "r" (nr)
0045     : "memory");
0046 
0047     return ret;
0048 }
0049 
0050 static __always_inline
0051 int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
0052 {
0053     register struct __kernel_timespec *ts asm("x1") = _ts;
0054     register clockid_t clkid asm("x0") = _clkid;
0055     register long ret asm ("x0");
0056     register long nr asm("x8") = __NR_clock_getres;
0057 
0058     asm volatile(
0059     "       svc #0\n"
0060     : "=r" (ret)
0061     : "r" (clkid), "r" (ts), "r" (nr)
0062     : "memory");
0063 
0064     return ret;
0065 }
0066 
0067 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
0068                          const struct vdso_data *vd)
0069 {
0070     u64 res;
0071 
0072     /*
0073      * Core checks for mode already, so this raced against a concurrent
0074      * update. Return something. Core will do another round and then
0075      * see the mode change and fallback to the syscall.
0076      */
0077     if (clock_mode == VDSO_CLOCKMODE_NONE)
0078         return 0;
0079 
0080     /*
0081      * This isb() is required to prevent that the counter value
0082      * is speculated.
0083      */
0084     isb();
0085     asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
0086     arch_counter_enforce_ordering(res);
0087 
0088     return res;
0089 }
0090 
0091 static __always_inline
0092 const struct vdso_data *__arch_get_vdso_data(void)
0093 {
0094     return _vdso_data;
0095 }
0096 
0097 #ifdef CONFIG_TIME_NS
0098 static __always_inline
0099 const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
0100 {
0101     return _timens_data;
0102 }
0103 #endif
0104 
0105 #endif /* !__ASSEMBLY__ */
0106 
0107 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */