162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __ASM_VDSO_GETTIMEOFDAY_H 362306a36Sopenharmony_ci#define __ASM_VDSO_GETTIMEOFDAY_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <asm/barrier.h> 862306a36Sopenharmony_ci#include <asm/unistd.h> 962306a36Sopenharmony_ci#include <asm/csr.h> 1062306a36Sopenharmony_ci#include <uapi/linux/time.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* 1362306a36Sopenharmony_ci * 32-bit land is lacking generic time vsyscalls as well as the legacy 32-bit 1462306a36Sopenharmony_ci * time syscalls like gettimeofday. Skip these definitions since on 32-bit. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci#ifdef CONFIG_GENERIC_TIME_VSYSCALL 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define VDSO_HAS_CLOCK_GETRES 1 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic __always_inline 2162306a36Sopenharmony_ciint gettimeofday_fallback(struct __kernel_old_timeval *_tv, 2262306a36Sopenharmony_ci struct timezone *_tz) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci register struct __kernel_old_timeval *tv asm("a0") = _tv; 2562306a36Sopenharmony_ci register struct timezone *tz asm("a1") = _tz; 2662306a36Sopenharmony_ci register long ret asm("a0"); 2762306a36Sopenharmony_ci register long nr asm("a7") = __NR_gettimeofday; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci asm volatile ("ecall\n" 3062306a36Sopenharmony_ci : "=r" (ret) 3162306a36Sopenharmony_ci : "r"(tv), "r"(tz), "r"(nr) 3262306a36Sopenharmony_ci : "memory"); 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci return ret; 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic __always_inline 3862306a36Sopenharmony_cilong clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci register clockid_t clkid asm("a0") = _clkid; 4162306a36Sopenharmony_ci register struct __kernel_timespec *ts asm("a1") = _ts; 4262306a36Sopenharmony_ci register long ret asm("a0"); 4362306a36Sopenharmony_ci register long nr asm("a7") = __NR_clock_gettime; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci asm volatile ("ecall\n" 4662306a36Sopenharmony_ci : "=r" (ret) 4762306a36Sopenharmony_ci : "r"(clkid), "r"(ts), "r"(nr) 4862306a36Sopenharmony_ci : "memory"); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci return ret; 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistatic __always_inline 5462306a36Sopenharmony_ciint clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci register clockid_t clkid asm("a0") = _clkid; 5762306a36Sopenharmony_ci register struct __kernel_timespec *ts asm("a1") = _ts; 5862306a36Sopenharmony_ci register long ret asm("a0"); 5962306a36Sopenharmony_ci register long nr asm("a7") = __NR_clock_getres; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci asm volatile ("ecall\n" 6262306a36Sopenharmony_ci : "=r" (ret) 6362306a36Sopenharmony_ci : "r"(clkid), "r"(ts), "r"(nr) 6462306a36Sopenharmony_ci : "memory"); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci return ret; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#endif /* CONFIG_GENERIC_TIME_VSYSCALL */ 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic __always_inline u64 __arch_get_hw_counter(s32 clock_mode, 7262306a36Sopenharmony_ci const struct vdso_data *vd) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci /* 7562306a36Sopenharmony_ci * The purpose of csr_read(CSR_TIME) is to trap the system into 7662306a36Sopenharmony_ci * M-mode to obtain the value of CSR_TIME. Hence, unlike other 7762306a36Sopenharmony_ci * architecture, no fence instructions surround the csr_read() 7862306a36Sopenharmony_ci */ 7962306a36Sopenharmony_ci return csr_read(CSR_TIME); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic __always_inline const struct vdso_data *__arch_get_vdso_data(void) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci return _vdso_data; 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#ifdef CONFIG_TIME_NS 8862306a36Sopenharmony_cistatic __always_inline 8962306a36Sopenharmony_ciconst struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci return _timens_data; 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci#endif 9462306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#endif /* __ASM_VDSO_GETTIMEOFDAY_H */ 97