0001
0002
0003
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
0124
0125
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
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
0146
0147 #endif