128b1a824SVincenzo Frascino /* SPDX-License-Identifier: GPL-2.0 */ 228b1a824SVincenzo Frascino /* 328b1a824SVincenzo Frascino * Copyright (C) 2018 ARM Limited 428b1a824SVincenzo Frascino */ 528b1a824SVincenzo Frascino #ifndef __ASM_VDSO_GETTIMEOFDAY_H 628b1a824SVincenzo Frascino #define __ASM_VDSO_GETTIMEOFDAY_H 728b1a824SVincenzo Frascino 828b1a824SVincenzo Frascino #ifndef __ASSEMBLY__ 928b1a824SVincenzo Frascino 10002dff36SWill Deacon #include <asm/barrier.h> 1128b1a824SVincenzo Frascino #include <asm/unistd.h> 1228b1a824SVincenzo Frascino 1328b1a824SVincenzo Frascino #define VDSO_HAS_CLOCK_GETRES 1 1428b1a824SVincenzo Frascino 1528b1a824SVincenzo Frascino static __always_inline 1628b1a824SVincenzo Frascino int gettimeofday_fallback(struct __kernel_old_timeval *_tv, 1728b1a824SVincenzo Frascino struct timezone *_tz) 1828b1a824SVincenzo Frascino { 1928b1a824SVincenzo Frascino register struct timezone *tz asm("x1") = _tz; 2028b1a824SVincenzo Frascino register struct __kernel_old_timeval *tv asm("x0") = _tv; 2128b1a824SVincenzo Frascino register long ret asm ("x0"); 2228b1a824SVincenzo Frascino register long nr asm("x8") = __NR_gettimeofday; 2328b1a824SVincenzo Frascino 2428b1a824SVincenzo Frascino asm volatile( 2528b1a824SVincenzo Frascino " svc #0\n" 2628b1a824SVincenzo Frascino : "=r" (ret) 2728b1a824SVincenzo Frascino : "r" (tv), "r" (tz), "r" (nr) 2828b1a824SVincenzo Frascino : "memory"); 2928b1a824SVincenzo Frascino 3028b1a824SVincenzo Frascino return ret; 3128b1a824SVincenzo Frascino } 3228b1a824SVincenzo Frascino 3328b1a824SVincenzo Frascino static __always_inline 3428b1a824SVincenzo Frascino long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) 3528b1a824SVincenzo Frascino { 3628b1a824SVincenzo Frascino register struct __kernel_timespec *ts asm("x1") = _ts; 3728b1a824SVincenzo Frascino register clockid_t clkid asm("x0") = _clkid; 3828b1a824SVincenzo Frascino register long ret asm ("x0"); 3928b1a824SVincenzo Frascino register long nr asm("x8") = __NR_clock_gettime; 4028b1a824SVincenzo Frascino 4128b1a824SVincenzo Frascino asm volatile( 4228b1a824SVincenzo Frascino " svc #0\n" 4328b1a824SVincenzo Frascino : "=r" (ret) 4428b1a824SVincenzo Frascino : "r" (clkid), "r" (ts), "r" (nr) 4528b1a824SVincenzo Frascino : "memory"); 4628b1a824SVincenzo Frascino 4728b1a824SVincenzo Frascino return ret; 4828b1a824SVincenzo Frascino } 4928b1a824SVincenzo Frascino 5028b1a824SVincenzo Frascino static __always_inline 5128b1a824SVincenzo Frascino int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) 5228b1a824SVincenzo Frascino { 5328b1a824SVincenzo Frascino register struct __kernel_timespec *ts asm("x1") = _ts; 5428b1a824SVincenzo Frascino register clockid_t clkid asm("x0") = _clkid; 5528b1a824SVincenzo Frascino register long ret asm ("x0"); 5628b1a824SVincenzo Frascino register long nr asm("x8") = __NR_clock_getres; 5728b1a824SVincenzo Frascino 5828b1a824SVincenzo Frascino asm volatile( 5928b1a824SVincenzo Frascino " svc #0\n" 6028b1a824SVincenzo Frascino : "=r" (ret) 6128b1a824SVincenzo Frascino : "r" (clkid), "r" (ts), "r" (nr) 6228b1a824SVincenzo Frascino : "memory"); 6328b1a824SVincenzo Frascino 6428b1a824SVincenzo Frascino return ret; 6528b1a824SVincenzo Frascino } 6628b1a824SVincenzo Frascino 674c5a116aSThomas Gleixner static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, 684c5a116aSThomas Gleixner const struct vdso_data *vd) 6928b1a824SVincenzo Frascino { 7028b1a824SVincenzo Frascino u64 res; 7128b1a824SVincenzo Frascino 7227e11a9fSVincenzo Frascino /* 735e3c6a31SThomas Gleixner * Core checks for mode already, so this raced against a concurrent 745e3c6a31SThomas Gleixner * update. Return something. Core will do another round and then 755e3c6a31SThomas Gleixner * see the mode change and fallback to the syscall. 7627e11a9fSVincenzo Frascino */ 775e3c6a31SThomas Gleixner if (clock_mode == VDSO_CLOCKMODE_NONE) 785e3c6a31SThomas Gleixner return 0; 7927e11a9fSVincenzo Frascino 8027e11a9fSVincenzo Frascino /* 8127e11a9fSVincenzo Frascino * This isb() is required to prevent that the counter value 8227e11a9fSVincenzo Frascino * is speculated. 8327e11a9fSVincenzo Frascino */ 8427e11a9fSVincenzo Frascino isb(); 8528b1a824SVincenzo Frascino asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); 86*77ec4625SWill Deacon arch_counter_enforce_ordering(res); 8728b1a824SVincenzo Frascino 8828b1a824SVincenzo Frascino return res; 8928b1a824SVincenzo Frascino } 9028b1a824SVincenzo Frascino 9128b1a824SVincenzo Frascino static __always_inline 9228b1a824SVincenzo Frascino const struct vdso_data *__arch_get_vdso_data(void) 9328b1a824SVincenzo Frascino { 9428b1a824SVincenzo Frascino return _vdso_data; 9528b1a824SVincenzo Frascino } 9628b1a824SVincenzo Frascino 973503d56cSAndrei Vagin #ifdef CONFIG_TIME_NS 983503d56cSAndrei Vagin static __always_inline 993503d56cSAndrei Vagin const struct vdso_data *__arch_get_timens_vdso_data(void) 1003503d56cSAndrei Vagin { 1013503d56cSAndrei Vagin return _timens_data; 1023503d56cSAndrei Vagin } 1033503d56cSAndrei Vagin #endif 1043503d56cSAndrei Vagin 10528b1a824SVincenzo Frascino #endif /* !__ASSEMBLY__ */ 10628b1a824SVincenzo Frascino 10728b1a824SVincenzo Frascino #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ 108