GNU Linux-libre 5.4.274-gnu1
[releases.git] / arch / arm64 / include / asm / vdso / gettimeofday.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2018 ARM Limited
4  */
5 #ifndef __ASM_VDSO_GETTIMEOFDAY_H
6 #define __ASM_VDSO_GETTIMEOFDAY_H
7
8 #ifndef __ASSEMBLY__
9
10 #include <asm/unistd.h>
11 #include <uapi/linux/time.h>
12
13 #include <asm/vdso/clocksource.h>
14
15 #define __VDSO_USE_SYSCALL              ULLONG_MAX
16
17 #define VDSO_HAS_CLOCK_GETRES           1
18
19 static __always_inline
20 int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
21                           struct timezone *_tz)
22 {
23         register struct timezone *tz asm("x1") = _tz;
24         register struct __kernel_old_timeval *tv asm("x0") = _tv;
25         register long ret asm ("x0");
26         register long nr asm("x8") = __NR_gettimeofday;
27
28         asm volatile(
29         "       svc #0\n"
30         : "=r" (ret)
31         : "r" (tv), "r" (tz), "r" (nr)
32         : "memory");
33
34         return ret;
35 }
36
37 static __always_inline
38 long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
39 {
40         register struct __kernel_timespec *ts asm("x1") = _ts;
41         register clockid_t clkid asm("x0") = _clkid;
42         register long ret asm ("x0");
43         register long nr asm("x8") = __NR_clock_gettime;
44
45         asm volatile(
46         "       svc #0\n"
47         : "=r" (ret)
48         : "r" (clkid), "r" (ts), "r" (nr)
49         : "memory");
50
51         return ret;
52 }
53
54 static __always_inline
55 int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
56 {
57         register struct __kernel_timespec *ts asm("x1") = _ts;
58         register clockid_t clkid asm("x0") = _clkid;
59         register long ret asm ("x0");
60         register long nr asm("x8") = __NR_clock_getres;
61
62         asm volatile(
63         "       svc #0\n"
64         : "=r" (ret)
65         : "r" (clkid), "r" (ts), "r" (nr)
66         : "memory");
67
68         return ret;
69 }
70
71 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
72 {
73         u64 res;
74
75         /*
76          * clock_mode != NONE implies that vDSO are enabled otherwise
77          * fallback on syscall.
78          */
79         if (clock_mode == VDSO_CLOCKMODE_NONE)
80                 return __VDSO_USE_SYSCALL;
81
82         /*
83          * This isb() is required to prevent that the counter value
84          * is speculated.
85          */
86         isb();
87         asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
88         arch_counter_enforce_ordering(res);
89
90         return res;
91 }
92
93 static __always_inline
94 const struct vdso_data *__arch_get_vdso_data(void)
95 {
96         return _vdso_data;
97 }
98
99 #endif /* !__ASSEMBLY__ */
100
101 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */