0001
0002 #ifndef _ASM_POWERPC_VDSO_GETTIMEOFDAY_H
0003 #define _ASM_POWERPC_VDSO_GETTIMEOFDAY_H
0004
0005 #ifndef __ASSEMBLY__
0006
0007 #include <asm/page.h>
0008 #include <asm/vdso/timebase.h>
0009 #include <asm/barrier.h>
0010 #include <asm/unistd.h>
0011 #include <uapi/linux/time.h>
0012
0013 #define VDSO_HAS_CLOCK_GETRES 1
0014
0015 #define VDSO_HAS_TIME 1
0016
0017 static __always_inline int do_syscall_2(const unsigned long _r0, const unsigned long _r3,
0018 const unsigned long _r4)
0019 {
0020 register long r0 asm("r0") = _r0;
0021 register unsigned long r3 asm("r3") = _r3;
0022 register unsigned long r4 asm("r4") = _r4;
0023 register int ret asm ("r3");
0024
0025 asm volatile(
0026 " sc\n"
0027 " bns+ 1f\n"
0028 " neg %0, %0\n"
0029 "1:\n"
0030 : "=r" (ret), "+r" (r4), "+r" (r0)
0031 : "r" (r3)
0032 : "memory", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cr0", "ctr");
0033
0034 return ret;
0035 }
0036
0037 static __always_inline
0038 int gettimeofday_fallback(struct __kernel_old_timeval *_tv, struct timezone *_tz)
0039 {
0040 return do_syscall_2(__NR_gettimeofday, (unsigned long)_tv, (unsigned long)_tz);
0041 }
0042
0043 #ifdef __powerpc64__
0044
0045 static __always_inline
0046 int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
0047 {
0048 return do_syscall_2(__NR_clock_gettime, _clkid, (unsigned long)_ts);
0049 }
0050
0051 static __always_inline
0052 int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
0053 {
0054 return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts);
0055 }
0056
0057 #else
0058
0059 #define BUILD_VDSO32 1
0060
0061 static __always_inline
0062 int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
0063 {
0064 return do_syscall_2(__NR_clock_gettime64, _clkid, (unsigned long)_ts);
0065 }
0066
0067 static __always_inline
0068 int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
0069 {
0070 return do_syscall_2(__NR_clock_getres_time64, _clkid, (unsigned long)_ts);
0071 }
0072
0073 static __always_inline
0074 int clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
0075 {
0076 return do_syscall_2(__NR_clock_gettime, _clkid, (unsigned long)_ts);
0077 }
0078
0079 static __always_inline
0080 int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
0081 {
0082 return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts);
0083 }
0084 #endif
0085
0086 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
0087 const struct vdso_data *vd)
0088 {
0089 return get_tb();
0090 }
0091
0092 const struct vdso_data *__arch_get_vdso_data(void);
0093
0094 #ifdef CONFIG_TIME_NS
0095 static __always_inline
0096 const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
0097 {
0098 return (void *)vd + PAGE_SIZE;
0099 }
0100 #endif
0101
0102 static inline bool vdso_clocksource_ok(const struct vdso_data *vd)
0103 {
0104 return true;
0105 }
0106 #define vdso_clocksource_ok vdso_clocksource_ok
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 static __always_inline u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
0118 {
0119 return (cycles - last) * mult;
0120 }
0121 #define vdso_calc_delta vdso_calc_delta
0122
0123 #ifndef __powerpc64__
0124 static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift)
0125 {
0126 u32 hi = ns >> 32;
0127 u32 lo = ns;
0128
0129 lo >>= shift;
0130 lo |= hi << (32 - shift);
0131 hi >>= shift;
0132
0133 if (likely(hi == 0))
0134 return lo;
0135
0136 return ((u64)hi << 32) | lo;
0137 }
0138 #define vdso_shift_ns vdso_shift_ns
0139 #endif
0140
0141 #ifdef __powerpc64__
0142 int __c_kernel_clock_gettime(clockid_t clock, struct __kernel_timespec *ts,
0143 const struct vdso_data *vd);
0144 int __c_kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res,
0145 const struct vdso_data *vd);
0146 #else
0147 int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts,
0148 const struct vdso_data *vd);
0149 int __c_kernel_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts,
0150 const struct vdso_data *vd);
0151 int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res,
0152 const struct vdso_data *vd);
0153 #endif
0154 int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz,
0155 const struct vdso_data *vd);
0156 __kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time,
0157 const struct vdso_data *vd);
0158 #endif
0159
0160 #endif