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 1028b1a824SVincenzo Frascino #include <asm/unistd.h> 1128b1a824SVincenzo Frascino #include <uapi/linux/time.h> 1228b1a824SVincenzo Frascino 1327e11a9fSVincenzo Frascino #define __VDSO_USE_SYSCALL ULLONG_MAX 1427e11a9fSVincenzo Frascino 1528b1a824SVincenzo Frascino #define VDSO_HAS_CLOCK_GETRES 1 1628b1a824SVincenzo Frascino 1728b1a824SVincenzo Frascino static __always_inline 1828b1a824SVincenzo Frascino int gettimeofday_fallback(struct __kernel_old_timeval *_tv, 1928b1a824SVincenzo Frascino struct timezone *_tz) 2028b1a824SVincenzo Frascino { 2128b1a824SVincenzo Frascino register struct timezone *tz asm("x1") = _tz; 2228b1a824SVincenzo Frascino register struct __kernel_old_timeval *tv asm("x0") = _tv; 2328b1a824SVincenzo Frascino register long ret asm ("x0"); 2428b1a824SVincenzo Frascino register long nr asm("x8") = __NR_gettimeofday; 2528b1a824SVincenzo Frascino 2628b1a824SVincenzo Frascino asm volatile( 2728b1a824SVincenzo Frascino " svc #0\n" 2828b1a824SVincenzo Frascino : "=r" (ret) 2928b1a824SVincenzo Frascino : "r" (tv), "r" (tz), "r" (nr) 3028b1a824SVincenzo Frascino : "memory"); 3128b1a824SVincenzo Frascino 3228b1a824SVincenzo Frascino return ret; 3328b1a824SVincenzo Frascino } 3428b1a824SVincenzo Frascino 3528b1a824SVincenzo Frascino static __always_inline 3628b1a824SVincenzo Frascino long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) 3728b1a824SVincenzo Frascino { 3828b1a824SVincenzo Frascino register struct __kernel_timespec *ts asm("x1") = _ts; 3928b1a824SVincenzo Frascino register clockid_t clkid asm("x0") = _clkid; 4028b1a824SVincenzo Frascino register long ret asm ("x0"); 4128b1a824SVincenzo Frascino register long nr asm("x8") = __NR_clock_gettime; 4228b1a824SVincenzo Frascino 4328b1a824SVincenzo Frascino asm volatile( 4428b1a824SVincenzo Frascino " svc #0\n" 4528b1a824SVincenzo Frascino : "=r" (ret) 4628b1a824SVincenzo Frascino : "r" (clkid), "r" (ts), "r" (nr) 4728b1a824SVincenzo Frascino : "memory"); 4828b1a824SVincenzo Frascino 4928b1a824SVincenzo Frascino return ret; 5028b1a824SVincenzo Frascino } 5128b1a824SVincenzo Frascino 5228b1a824SVincenzo Frascino static __always_inline 5328b1a824SVincenzo Frascino int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) 5428b1a824SVincenzo Frascino { 5528b1a824SVincenzo Frascino register struct __kernel_timespec *ts asm("x1") = _ts; 5628b1a824SVincenzo Frascino register clockid_t clkid asm("x0") = _clkid; 5728b1a824SVincenzo Frascino register long ret asm ("x0"); 5828b1a824SVincenzo Frascino register long nr asm("x8") = __NR_clock_getres; 5928b1a824SVincenzo Frascino 6028b1a824SVincenzo Frascino asm volatile( 6128b1a824SVincenzo Frascino " svc #0\n" 6228b1a824SVincenzo Frascino : "=r" (ret) 6328b1a824SVincenzo Frascino : "r" (clkid), "r" (ts), "r" (nr) 6428b1a824SVincenzo Frascino : "memory"); 6528b1a824SVincenzo Frascino 6628b1a824SVincenzo Frascino return ret; 6728b1a824SVincenzo Frascino } 6828b1a824SVincenzo Frascino 6928b1a824SVincenzo Frascino static __always_inline u64 __arch_get_hw_counter(s32 clock_mode) 7028b1a824SVincenzo Frascino { 7128b1a824SVincenzo Frascino u64 res; 7228b1a824SVincenzo Frascino 7327e11a9fSVincenzo Frascino /* 7427e11a9fSVincenzo Frascino * clock_mode == 0 implies that vDSO are enabled otherwise 7527e11a9fSVincenzo Frascino * fallback on syscall. 7627e11a9fSVincenzo Frascino */ 7727e11a9fSVincenzo Frascino if (clock_mode) 7827e11a9fSVincenzo Frascino return __VDSO_USE_SYSCALL; 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"); 8627e11a9fSVincenzo Frascino /* 8727e11a9fSVincenzo Frascino * This isb() is required to prevent that the seq lock is 8827e11a9fSVincenzo Frascino * speculated.# 8927e11a9fSVincenzo Frascino */ 9027e11a9fSVincenzo Frascino isb(); 9128b1a824SVincenzo Frascino 9228b1a824SVincenzo Frascino return res; 9328b1a824SVincenzo Frascino } 9428b1a824SVincenzo Frascino 9528b1a824SVincenzo Frascino static __always_inline 9628b1a824SVincenzo Frascino const struct vdso_data *__arch_get_vdso_data(void) 9728b1a824SVincenzo Frascino { 9828b1a824SVincenzo Frascino return _vdso_data; 9928b1a824SVincenzo Frascino } 10028b1a824SVincenzo Frascino 10128b1a824SVincenzo Frascino #endif /* !__ASSEMBLY__ */ 10228b1a824SVincenzo Frascino 10328b1a824SVincenzo Frascino #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ 104