Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libc/arm/sys/__vdso_gettc.c
Show All 29 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/elf.h> | #include <sys/elf.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/vdso.h> | #include <sys/vdso.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
#include <machine/acle-compat.h> | #include <machine/acle-compat.h> | ||||
#include <errno.h> | |||||
#include "libc_private.h" | #include "libc_private.h" | ||||
#if __ARM_ARCH >= 6 | #if __ARM_ARCH >= 6 | ||||
static inline uint64_t | static inline uint64_t | ||||
cp15_cntvct_get(void) | cp15_cntvct_get(void) | ||||
{ | { | ||||
uint64_t reg; | uint64_t reg; | ||||
__asm __volatile("mrrc\tp15, 1, %Q0, %R0, c14" : "=r" (reg)); | __asm __volatile("mrrc\tp15, 1, %Q0, %R0, c14" : "=r" (reg)); | ||||
return (reg); | return (reg); | ||||
} | } | ||||
static inline uint64_t | static inline uint64_t | ||||
cp15_cntpct_get(void) | cp15_cntpct_get(void) | ||||
{ | { | ||||
uint64_t reg; | uint64_t reg; | ||||
__asm __volatile("mrrc\tp15, 0, %Q0, %R0, c14" : "=r" (reg)); | __asm __volatile("mrrc\tp15, 0, %Q0, %R0, c14" : "=r" (reg)); | ||||
return (reg); | return (reg); | ||||
} | } | ||||
#endif | #endif | ||||
#pragma weak __vdso_gettc | #pragma weak __vdso_gettc | ||||
u_int | int | ||||
__vdso_gettc(const struct vdso_timehands *th) | __vdso_gettc(const struct vdso_timehands *th, u_int *tc) | ||||
{ | { | ||||
uint64_t val; | |||||
if (th->th_algo != VDSO_TH_ALGO_ARM_GENTIM) | |||||
return (ENOSYS); | |||||
#if __ARM_ARCH >= 6 | #if __ARM_ARCH >= 6 | ||||
/* | /* | ||||
* Userspace gettimeofday() is only enabled on ARMv7 CPUs, but | * Userspace gettimeofday() is only enabled on ARMv7 CPUs, but | ||||
* libc is compiled for ARMv6. Due to clang issues, .arch | * libc is compiled for ARMv6. Due to clang issues, .arch | ||||
* armv7-a directive does not work. | * armv7-a directive does not work. | ||||
*/ | */ | ||||
__asm __volatile(".word\t0xf57ff06f" : : : "memory"); /* isb */ | __asm __volatile(".word\t0xf57ff06f" : : : "memory"); /* isb */ | ||||
val = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get(); | *tc = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get(); | ||||
return (0); | |||||
#else | #else | ||||
val = 0; | *tc = 0; | ||||
return (ENOSYS); | |||||
#endif | #endif | ||||
return (val); | |||||
} | } | ||||
#pragma weak __vdso_gettimekeep | #pragma weak __vdso_gettimekeep | ||||
int | int | ||||
__vdso_gettimekeep(struct vdso_timekeep **tk) | __vdso_gettimekeep(struct vdso_timekeep **tk) | ||||
{ | { | ||||
return (_elf_aux_info(AT_TIMEKEEP, tk, sizeof(*tk))); | return (_elf_aux_info(AT_TIMEKEEP, tk, sizeof(*tk))); | ||||
} | } |