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/errno.h>
0012 #include <asm/unistd.h>
0013 #include <asm/vdso/cp15.h>
0014 #include <uapi/linux/time.h>
0015 
0016 #define VDSO_HAS_CLOCK_GETRES       1
0017 
0018 extern struct vdso_data *__get_datapage(void);
0019 
0020 static __always_inline int gettimeofday_fallback(
0021                 struct __kernel_old_timeval *_tv,
0022                 struct timezone *_tz)
0023 {
0024     register struct timezone *tz asm("r1") = _tz;
0025     register struct __kernel_old_timeval *tv asm("r0") = _tv;
0026     register long ret asm ("r0");
0027     register long nr asm("r7") = __NR_gettimeofday;
0028 
0029     asm volatile(
0030     "   swi #0\n"
0031     : "=r" (ret)
0032     : "r" (tv), "r" (tz), "r" (nr)
0033     : "memory");
0034 
0035     return ret;
0036 }
0037 
0038 static __always_inline long clock_gettime_fallback(
0039                     clockid_t _clkid,
0040                     struct __kernel_timespec *_ts)
0041 {
0042     register struct __kernel_timespec *ts asm("r1") = _ts;
0043     register clockid_t clkid asm("r0") = _clkid;
0044     register long ret asm ("r0");
0045     register long nr asm("r7") = __NR_clock_gettime64;
0046 
0047     asm volatile(
0048     "   swi #0\n"
0049     : "=r" (ret)
0050     : "r" (clkid), "r" (ts), "r" (nr)
0051     : "memory");
0052 
0053     return ret;
0054 }
0055 
0056 static __always_inline long clock_gettime32_fallback(
0057                     clockid_t _clkid,
0058                     struct old_timespec32 *_ts)
0059 {
0060     register struct old_timespec32 *ts asm("r1") = _ts;
0061     register clockid_t clkid asm("r0") = _clkid;
0062     register long ret asm ("r0");
0063     register long nr asm("r7") = __NR_clock_gettime;
0064 
0065     asm volatile(
0066     "   swi #0\n"
0067     : "=r" (ret)
0068     : "r" (clkid), "r" (ts), "r" (nr)
0069     : "memory");
0070 
0071     return ret;
0072 }
0073 
0074 static __always_inline int clock_getres_fallback(
0075                     clockid_t _clkid,
0076                     struct __kernel_timespec *_ts)
0077 {
0078     register struct __kernel_timespec *ts asm("r1") = _ts;
0079     register clockid_t clkid asm("r0") = _clkid;
0080     register long ret asm ("r0");
0081     register long nr asm("r7") = __NR_clock_getres_time64;
0082 
0083     asm volatile(
0084     "       swi #0\n"
0085     : "=r" (ret)
0086     : "r" (clkid), "r" (ts), "r" (nr)
0087     : "memory");
0088 
0089     return ret;
0090 }
0091 
0092 static __always_inline int clock_getres32_fallback(
0093                     clockid_t _clkid,
0094                     struct old_timespec32 *_ts)
0095 {
0096     register struct old_timespec32 *ts asm("r1") = _ts;
0097     register clockid_t clkid asm("r0") = _clkid;
0098     register long ret asm ("r0");
0099     register long nr asm("r7") = __NR_clock_getres;
0100 
0101     asm volatile(
0102     "       swi #0\n"
0103     : "=r" (ret)
0104     : "r" (clkid), "r" (ts), "r" (nr)
0105     : "memory");
0106 
0107     return ret;
0108 }
0109 
0110 static inline bool arm_vdso_hres_capable(void)
0111 {
0112     return IS_ENABLED(CONFIG_ARM_ARCH_TIMER);
0113 }
0114 #define __arch_vdso_hres_capable arm_vdso_hres_capable
0115 
0116 static __always_inline u64 __arch_get_hw_counter(int clock_mode,
0117                          const struct vdso_data *vd)
0118 {
0119 #ifdef CONFIG_ARM_ARCH_TIMER
0120     u64 cycle_now;
0121 
0122     /*
0123      * Core checks for mode already, so this raced against a concurrent
0124      * update. Return something. Core will do another round and then
0125      * see the mode change and fallback to the syscall.
0126      */
0127     if (clock_mode == VDSO_CLOCKMODE_NONE)
0128         return 0;
0129 
0130     isb();
0131     cycle_now = read_sysreg(CNTVCT);
0132 
0133     return cycle_now;
0134 #else
0135     /* Make GCC happy. This is compiled out anyway */
0136     return 0;
0137 #endif
0138 }
0139 
0140 static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
0141 {
0142     return __get_datapage();
0143 }
0144 
0145 #endif /* !__ASSEMBLY__ */
0146 
0147 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */