120e2fc42SVincenzo Frascino /* SPDX-License-Identifier: GPL-2.0 */ 220e2fc42SVincenzo Frascino /* 320e2fc42SVincenzo Frascino * Copyright (C) 2018 ARM Limited 420e2fc42SVincenzo Frascino */ 520e2fc42SVincenzo Frascino #ifndef __ASM_VDSO_GETTIMEOFDAY_H 620e2fc42SVincenzo Frascino #define __ASM_VDSO_GETTIMEOFDAY_H 720e2fc42SVincenzo Frascino 820e2fc42SVincenzo Frascino #ifndef __ASSEMBLY__ 920e2fc42SVincenzo Frascino 1020e2fc42SVincenzo Frascino #include <asm/barrier.h> 1120e2fc42SVincenzo Frascino #include <asm/cp15.h> 1220e2fc42SVincenzo Frascino #include <asm/unistd.h> 1320e2fc42SVincenzo Frascino #include <uapi/linux/time.h> 1420e2fc42SVincenzo Frascino 15052e76a3SVincenzo Frascino #define VDSO_HAS_CLOCK_GETRES 1 16052e76a3SVincenzo Frascino 1720e2fc42SVincenzo Frascino extern struct vdso_data *__get_datapage(void); 1820e2fc42SVincenzo Frascino 1920e2fc42SVincenzo Frascino static __always_inline int gettimeofday_fallback( 2020e2fc42SVincenzo Frascino struct __kernel_old_timeval *_tv, 2120e2fc42SVincenzo Frascino struct timezone *_tz) 2220e2fc42SVincenzo Frascino { 2320e2fc42SVincenzo Frascino register struct timezone *tz asm("r1") = _tz; 2420e2fc42SVincenzo Frascino register struct __kernel_old_timeval *tv asm("r0") = _tv; 2520e2fc42SVincenzo Frascino register long ret asm ("r0"); 2620e2fc42SVincenzo Frascino register long nr asm("r7") = __NR_gettimeofday; 2720e2fc42SVincenzo Frascino 2820e2fc42SVincenzo Frascino asm volatile( 2920e2fc42SVincenzo Frascino " swi #0\n" 3020e2fc42SVincenzo Frascino : "=r" (ret) 3120e2fc42SVincenzo Frascino : "r" (tv), "r" (tz), "r" (nr) 3220e2fc42SVincenzo Frascino : "memory"); 3320e2fc42SVincenzo Frascino 3420e2fc42SVincenzo Frascino return ret; 3520e2fc42SVincenzo Frascino } 3620e2fc42SVincenzo Frascino 3720e2fc42SVincenzo Frascino static __always_inline long clock_gettime_fallback( 3820e2fc42SVincenzo Frascino clockid_t _clkid, 3920e2fc42SVincenzo Frascino struct __kernel_timespec *_ts) 4020e2fc42SVincenzo Frascino { 4120e2fc42SVincenzo Frascino register struct __kernel_timespec *ts asm("r1") = _ts; 4220e2fc42SVincenzo Frascino register clockid_t clkid asm("r0") = _clkid; 4320e2fc42SVincenzo Frascino register long ret asm ("r0"); 4420e2fc42SVincenzo Frascino register long nr asm("r7") = __NR_clock_gettime64; 4520e2fc42SVincenzo Frascino 4620e2fc42SVincenzo Frascino asm volatile( 4720e2fc42SVincenzo Frascino " swi #0\n" 4820e2fc42SVincenzo Frascino : "=r" (ret) 4920e2fc42SVincenzo Frascino : "r" (clkid), "r" (ts), "r" (nr) 5020e2fc42SVincenzo Frascino : "memory"); 5120e2fc42SVincenzo Frascino 5220e2fc42SVincenzo Frascino return ret; 5320e2fc42SVincenzo Frascino } 5420e2fc42SVincenzo Frascino 55715f23b6SThomas Gleixner static __always_inline long clock_gettime32_fallback( 56715f23b6SThomas Gleixner clockid_t _clkid, 57715f23b6SThomas Gleixner struct old_timespec32 *_ts) 58715f23b6SThomas Gleixner { 59715f23b6SThomas Gleixner register struct old_timespec32 *ts asm("r1") = _ts; 60715f23b6SThomas Gleixner register clockid_t clkid asm("r0") = _clkid; 61715f23b6SThomas Gleixner register long ret asm ("r0"); 62715f23b6SThomas Gleixner register long nr asm("r7") = __NR_clock_gettime; 63715f23b6SThomas Gleixner 64715f23b6SThomas Gleixner asm volatile( 65715f23b6SThomas Gleixner " swi #0\n" 66715f23b6SThomas Gleixner : "=r" (ret) 67715f23b6SThomas Gleixner : "r" (clkid), "r" (ts), "r" (nr) 68715f23b6SThomas Gleixner : "memory"); 69715f23b6SThomas Gleixner 70715f23b6SThomas Gleixner return ret; 71715f23b6SThomas Gleixner } 72715f23b6SThomas Gleixner 73052e76a3SVincenzo Frascino static __always_inline int clock_getres_fallback( 74052e76a3SVincenzo Frascino clockid_t _clkid, 75052e76a3SVincenzo Frascino struct __kernel_timespec *_ts) 76052e76a3SVincenzo Frascino { 77052e76a3SVincenzo Frascino register struct __kernel_timespec *ts asm("r1") = _ts; 78052e76a3SVincenzo Frascino register clockid_t clkid asm("r0") = _clkid; 79052e76a3SVincenzo Frascino register long ret asm ("r0"); 80052e76a3SVincenzo Frascino register long nr asm("r7") = __NR_clock_getres_time64; 81052e76a3SVincenzo Frascino 82052e76a3SVincenzo Frascino asm volatile( 83052e76a3SVincenzo Frascino " swi #0\n" 84052e76a3SVincenzo Frascino : "=r" (ret) 85052e76a3SVincenzo Frascino : "r" (clkid), "r" (ts), "r" (nr) 86052e76a3SVincenzo Frascino : "memory"); 87052e76a3SVincenzo Frascino 88052e76a3SVincenzo Frascino return ret; 89052e76a3SVincenzo Frascino } 90052e76a3SVincenzo Frascino 91715f23b6SThomas Gleixner static __always_inline int clock_getres32_fallback( 92715f23b6SThomas Gleixner clockid_t _clkid, 93715f23b6SThomas Gleixner struct old_timespec32 *_ts) 94715f23b6SThomas Gleixner { 95715f23b6SThomas Gleixner register struct old_timespec32 *ts asm("r1") = _ts; 96715f23b6SThomas Gleixner register clockid_t clkid asm("r0") = _clkid; 97715f23b6SThomas Gleixner register long ret asm ("r0"); 98715f23b6SThomas Gleixner register long nr asm("r7") = __NR_clock_getres; 99715f23b6SThomas Gleixner 100715f23b6SThomas Gleixner asm volatile( 101715f23b6SThomas Gleixner " swi #0\n" 102715f23b6SThomas Gleixner : "=r" (ret) 103715f23b6SThomas Gleixner : "r" (clkid), "r" (ts), "r" (nr) 104715f23b6SThomas Gleixner : "memory"); 105715f23b6SThomas Gleixner 106715f23b6SThomas Gleixner return ret; 107715f23b6SThomas Gleixner } 108715f23b6SThomas Gleixner 10920e2fc42SVincenzo Frascino static __always_inline u64 __arch_get_hw_counter(int clock_mode) 11020e2fc42SVincenzo Frascino { 11120e2fc42SVincenzo Frascino #ifdef CONFIG_ARM_ARCH_TIMER 11220e2fc42SVincenzo Frascino u64 cycle_now; 11320e2fc42SVincenzo Frascino 11404bb9642SVincenzo Frascino if (!clock_mode) 11504bb9642SVincenzo Frascino return -EINVAL; 11604bb9642SVincenzo Frascino 11720e2fc42SVincenzo Frascino isb(); 11820e2fc42SVincenzo Frascino cycle_now = read_sysreg(CNTVCT); 11920e2fc42SVincenzo Frascino 12020e2fc42SVincenzo Frascino return cycle_now; 12120e2fc42SVincenzo Frascino #else 12220e2fc42SVincenzo Frascino return -EINVAL; /* use fallback */ 12320e2fc42SVincenzo Frascino #endif 12420e2fc42SVincenzo Frascino } 12520e2fc42SVincenzo Frascino 12620e2fc42SVincenzo Frascino static __always_inline const struct vdso_data *__arch_get_vdso_data(void) 12720e2fc42SVincenzo Frascino { 12820e2fc42SVincenzo Frascino return __get_datapage(); 12920e2fc42SVincenzo Frascino } 13020e2fc42SVincenzo Frascino 13120e2fc42SVincenzo Frascino #endif /* !__ASSEMBLY__ */ 13220e2fc42SVincenzo Frascino 13320e2fc42SVincenzo Frascino #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ 134