Date: Fri, 16 Sep 2016 10:04:28 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r305866 - in stable/11: lib/libc lib/libc/aarch64/sys lib/libc/amd64/sys lib/libc/arm/sys lib/libc/i386/sys lib/libc/sys lib/libc/x86 sys/arm/arm sys/arm/include sys/arm64/arm64 sys/arm... Message-ID: <201609161004.u8GA4SUY059878@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Fri Sep 16 10:04:28 2016 New Revision: 305866 URL: https://svnweb.freebsd.org/changeset/base/305866 Log: MFC r304285: Implement userspace gettimeofday(2) with HPET timecounter. Added: stable/11/lib/libc/x86/ - copied from r304285, head/lib/libc/x86/ Deleted: stable/11/lib/libc/amd64/sys/__vdso_gettc.c stable/11/lib/libc/i386/sys/__vdso_gettc.c Modified: stable/11/lib/libc/Makefile stable/11/lib/libc/aarch64/sys/__vdso_gettc.c stable/11/lib/libc/amd64/sys/Makefile.inc stable/11/lib/libc/arm/sys/__vdso_gettc.c stable/11/lib/libc/i386/sys/Makefile.inc stable/11/lib/libc/sys/__vdso_gettimeofday.c stable/11/lib/libc/sys/trivial-vdso_tc.c stable/11/sys/arm/arm/generic_timer.c stable/11/sys/arm/arm/machdep.c stable/11/sys/arm/include/md_var.h stable/11/sys/arm/include/vdso.h stable/11/sys/arm64/arm64/machdep.c stable/11/sys/arm64/include/md_var.h stable/11/sys/arm64/include/vdso.h stable/11/sys/dev/acpica/acpi_hpet.c stable/11/sys/dev/acpica/acpi_hpet.h stable/11/sys/kern/kern_tc.c stable/11/sys/sys/timetc.h stable/11/sys/sys/vdso.h stable/11/sys/x86/include/vdso.h stable/11/sys/x86/x86/tsc.c Directory Properties: stable/11/ (props changed) Modified: stable/11/lib/libc/Makefile ============================================================================== --- stable/11/lib/libc/Makefile Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/lib/libc/Makefile Fri Sep 16 10:04:28 2016 (r305866) @@ -110,6 +110,9 @@ NOASM= ${LIBC_ARCH} == "mips" .include "${LIBC_SRCTOP}/softfloat/Makefile.inc" .endif +.if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64" +.include "${LIBC_SRCTOP}/x86/sys/Makefile.inc" +.endif .if ${MK_NIS} != "no" CFLAGS+= -DYP .include "${LIBC_SRCTOP}/yp/Makefile.inc" Modified: stable/11/lib/libc/aarch64/sys/__vdso_gettc.c ============================================================================== --- stable/11/lib/libc/aarch64/sys/__vdso_gettc.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/lib/libc/aarch64/sys/__vdso_gettc.c Fri Sep 16 10:04:28 2016 (r305866) @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/time.h> #include <sys/vdso.h> #include <machine/cpufunc.h> +#include <errno.h> #include "libc_private.h" static inline uint64_t @@ -55,14 +56,15 @@ cp15_cntpct_get(void) } #pragma weak __vdso_gettc -u_int -__vdso_gettc(const struct vdso_timehands *th) +int +__vdso_gettc(const struct vdso_timehands *th, u_int *tc) { - uint64_t val; + if (th->th_algo != VDSO_TH_ALGO_ARM_GENTIM) + return (ENOSYS); __asm __volatile("isb" : : : "memory"); - val = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get(); - return (val); + *tc = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get(); + return (0); } #pragma weak __vdso_gettimekeep Modified: stable/11/lib/libc/amd64/sys/Makefile.inc ============================================================================== --- stable/11/lib/libc/amd64/sys/Makefile.inc Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/lib/libc/amd64/sys/Makefile.inc Fri Sep 16 10:04:28 2016 (r305866) @@ -2,7 +2,7 @@ # $FreeBSD$ SRCS+= amd64_get_fsbase.c amd64_get_gsbase.c amd64_set_fsbase.c \ - amd64_set_gsbase.c __vdso_gettc.c + amd64_set_gsbase.c MDASM= vfork.S brk.S cerror.S exect.S getcontext.S \ sbrk.S setlogin.S sigreturn.S Modified: stable/11/lib/libc/arm/sys/__vdso_gettc.c ============================================================================== --- stable/11/lib/libc/arm/sys/__vdso_gettc.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/lib/libc/arm/sys/__vdso_gettc.c Fri Sep 16 10:04:28 2016 (r305866) @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/vdso.h> #include <machine/cpufunc.h> #include <machine/acle-compat.h> +#include <errno.h> #include "libc_private.h" #if __ARM_ARCH >= 6 @@ -58,11 +59,12 @@ cp15_cntpct_get(void) #endif #pragma weak __vdso_gettc -u_int -__vdso_gettc(const struct vdso_timehands *th) +int +__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 /* * Userspace gettimeofday() is only enabled on ARMv7 CPUs, but @@ -70,11 +72,12 @@ __vdso_gettc(const struct vdso_timehands * armv7-a directive does not work. */ __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 - val = 0; + *tc = 0; + return (ENOSYS); #endif - return (val); } #pragma weak __vdso_gettimekeep Modified: stable/11/lib/libc/i386/sys/Makefile.inc ============================================================================== --- stable/11/lib/libc/i386/sys/Makefile.inc Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/lib/libc/i386/sys/Makefile.inc Fri Sep 16 10:04:28 2016 (r305866) @@ -5,8 +5,7 @@ SRCS+= i386_clr_watch.c i386_set_watch.c i386_vm86.c .endif SRCS+= i386_get_fsbase.c i386_get_gsbase.c i386_get_ioperm.c i386_get_ldt.c \ - i386_set_fsbase.c i386_set_gsbase.c i386_set_ioperm.c i386_set_ldt.c \ - __vdso_gettc.c + i386_set_fsbase.c i386_set_gsbase.c i386_set_ioperm.c i386_set_ldt.c MDASM= Ovfork.S brk.S cerror.S exect.S getcontext.S \ sbrk.S setlogin.S sigreturn.S syscall.S Modified: stable/11/lib/libc/sys/__vdso_gettimeofday.c ============================================================================== --- stable/11/lib/libc/sys/__vdso_gettimeofday.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/lib/libc/sys/__vdso_gettimeofday.c Fri Sep 16 10:04:28 2016 (r305866) @@ -34,12 +34,16 @@ __FBSDID("$FreeBSD$"); #include <machine/atomic.h> #include "libc_private.h" -static u_int -tc_delta(const struct vdso_timehands *th) +static int +tc_delta(const struct vdso_timehands *th, u_int *delta) { + int error; + u_int tc; - return ((__vdso_gettc(th) - th->th_offset_count) & - th->th_counter_mask); + error = __vdso_gettc(th, &tc); + if (error == 0) + *delta = (tc - th->th_offset_count) & th->th_counter_mask; + return (error); } /* @@ -56,6 +60,8 @@ binuptime(struct bintime *bt, struct vds { struct vdso_timehands *th; uint32_t curr, gen; + u_int delta; + int error; do { if (!tk->tk_enabled) @@ -63,11 +69,14 @@ binuptime(struct bintime *bt, struct vds curr = atomic_load_acq_32(&tk->tk_current); th = &tk->tk_th[curr]; - if (th->th_algo != VDSO_TH_ALGO_1) - return (ENOSYS); gen = atomic_load_acq_32(&th->th_gen); *bt = th->th_offset; - bintime_addx(bt, th->th_scale * tc_delta(th)); + error = tc_delta(th, &delta); + if (error == EAGAIN) + continue; + if (error != 0) + return (error); + bintime_addx(bt, th->th_scale * delta); if (abs) bintime_add(bt, &th->th_boottime); Modified: stable/11/lib/libc/sys/trivial-vdso_tc.c ============================================================================== --- stable/11/lib/libc/sys/trivial-vdso_tc.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/lib/libc/sys/trivial-vdso_tc.c Fri Sep 16 10:04:28 2016 (r305866) @@ -32,11 +32,11 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #pragma weak __vdso_gettc -u_int -__vdso_gettc(const struct vdso_timehands *th) +int +__vdso_gettc(const struct vdso_timehands *th, u_int *tc) { - return (0); + return (ENOSYS); } #pragma weak __vdso_gettimekeep Modified: stable/11/sys/arm/arm/generic_timer.c ============================================================================== --- stable/11/sys/arm/arm/generic_timer.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/arm/arm/generic_timer.c Fri Sep 16 10:04:28 2016 (r305866) @@ -105,6 +105,10 @@ static struct resource_spec timer_spec[] { -1, 0 } }; +static uint32_t arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th, + struct timecounter *tc); +static void arm_tmr_do_delay(int usec, void *); + static timecounter_get_t arm_tmr_get_timecount; static struct timecounter arm_tmr_timecount = { @@ -114,6 +118,7 @@ static struct timecounter arm_tmr_timeco .tc_counter_mask = ~0u, .tc_frequency = 0, .tc_quality = 1000, + .tc_fill_vdso_timehands = arm_tmr_fill_vdso_timehands, }; #ifdef __arm__ @@ -128,10 +133,6 @@ static struct timecounter arm_tmr_timeco #define set_el1(x, val) WRITE_SPECIALREG(x ##_el1, val) #endif -static uint32_t arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th, - struct timecounter *tc); -static void arm_tmr_do_delay(int usec, void *); - static int get_freq(void) { @@ -412,8 +413,6 @@ arm_tmr_attach(device_t dev) } } - arm_cpu_fill_vdso_timehands = arm_tmr_fill_vdso_timehands; - arm_tmr_timecount.tc_frequency = sc->clkfreq; tc_init(&arm_tmr_timecount); @@ -535,7 +534,8 @@ arm_tmr_fill_vdso_timehands(struct vdso_ struct timecounter *tc) { + vdso_th->th_algo = VDSO_TH_ALGO_ARM_GENTIM; vdso_th->th_physical = arm_tmr_sc->physical; bzero(vdso_th->th_res, sizeof(vdso_th->th_res)); - return (tc == &arm_tmr_timecount); + return (1); } Modified: stable/11/sys/arm/arm/machdep.c ============================================================================== --- stable/11/sys/arm/arm/machdep.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/arm/arm/machdep.c Fri Sep 16 10:04:28 2016 (r305866) @@ -1996,14 +1996,3 @@ initarm(struct arm_boot_params *abp) #endif /* __ARM_ARCH < 6 */ #endif /* FDT */ - -uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *, - struct timecounter *); - -uint32_t -cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc) -{ - - return (arm_cpu_fill_vdso_timehands != NULL ? - arm_cpu_fill_vdso_timehands(vdso_th, tc) : 0); -} Modified: stable/11/sys/arm/include/md_var.h ============================================================================== --- stable/11/sys/arm/include/md_var.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/arm/include/md_var.h Fri Sep 16 10:04:28 2016 (r305866) @@ -45,11 +45,6 @@ extern int (*_arm_bzero)(void *, int, in extern int _min_memcpy_size; extern int _min_bzero_size; -struct vdso_timehands; -struct timecounter; -extern uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *, - struct timecounter *); - #define DST_IS_USER 0x1 #define SRC_IS_USER 0x2 #define IS_PHYSICAL 0x4 Modified: stable/11/sys/arm/include/vdso.h ============================================================================== --- stable/11/sys/arm/include/vdso.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/arm/include/vdso.h Fri Sep 16 10:04:28 2016 (r305866) @@ -32,4 +32,6 @@ uint32_t th_physical; \ uint32_t th_res[7]; +#define VDSO_TH_ALGO_ARM_GENTIM VDSO_TH_ALGO_1 + #endif Modified: stable/11/sys/arm64/arm64/machdep.c ============================================================================== --- stable/11/sys/arm64/arm64/machdep.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/arm64/arm64/machdep.c Fri Sep 16 10:04:28 2016 (r305866) @@ -927,17 +927,6 @@ initarm(struct arm64_bootparams *abp) early_boot = 0; } -uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *, - struct timecounter *); - -uint32_t -cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc) -{ - - return (arm_cpu_fill_vdso_timehands != NULL ? - arm_cpu_fill_vdso_timehands(vdso_th, tc) : 0); -} - #ifdef DDB #include <ddb/ddb.h> Modified: stable/11/sys/arm64/include/md_var.h ============================================================================== --- stable/11/sys/arm64/include/md_var.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/arm64/include/md_var.h Fri Sep 16 10:04:28 2016 (r305866) @@ -47,9 +47,4 @@ void dump_add_page(vm_paddr_t); void dump_drop_page(vm_paddr_t); int minidumpsys(struct dumperinfo *); -struct vdso_timehands; -struct timecounter; -extern uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *, - struct timecounter *); - #endif /* !_MACHINE_MD_VAR_H_ */ Modified: stable/11/sys/arm64/include/vdso.h ============================================================================== --- stable/11/sys/arm64/include/vdso.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/arm64/include/vdso.h Fri Sep 16 10:04:28 2016 (r305866) @@ -32,4 +32,6 @@ uint32_t th_physical; \ uint32_t th_res[7]; +#define VDSO_TH_ALGO_ARM_GENTIM VDSO_TH_ALGO_1 + #endif /* !_MACHINE_VDSO_H_ */ Modified: stable/11/sys/dev/acpica/acpi_hpet.c ============================================================================== --- stable/11/sys/dev/acpica/acpi_hpet.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/dev/acpica/acpi_hpet.c Fri Sep 16 10:04:28 2016 (r305866) @@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$"); #include "opt_acpi.h" +#include "opt_compat.h" + #if defined(__amd64__) #define DEV_APIC #else @@ -47,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/timeet.h> #include <sys/timetc.h> +#include <sys/vdso.h> #include <contrib/dev/acpica/include/acpi.h> #include <contrib/dev/acpica/include/accommon.h> @@ -141,6 +144,35 @@ hpet_get_timecount(struct timecounter *t return (bus_read_4(sc->mem_res, HPET_MAIN_COUNTER)); } +uint32_t +hpet_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc) +{ + struct hpet_softc *sc; + + sc = tc->tc_priv; + vdso_th->th_algo = VDSO_TH_ALGO_X86_HPET; + vdso_th->th_x86_shift = 0; + vdso_th->th_x86_hpet_idx = device_get_unit(sc->dev); + bzero(vdso_th->th_res, sizeof(vdso_th->th_res)); + return (sc->mmap_allow != 0); +} + +#ifdef COMPAT_FREEBSD32 +uint32_t +hpet_vdso_timehands32(struct vdso_timehands32 *vdso_th32, + struct timecounter *tc) +{ + struct hpet_softc *sc; + + sc = tc->tc_priv; + vdso_th32->th_algo = VDSO_TH_ALGO_X86_HPET; + vdso_th32->th_x86_shift = 0; + vdso_th32->th_x86_hpet_idx = device_get_unit(sc->dev); + bzero(vdso_th32->th_res, sizeof(vdso_th32->th_res)); + return (sc->mmap_allow != 0); +} +#endif + static void hpet_enable(struct hpet_softc *sc) { @@ -537,6 +569,10 @@ hpet_attach(device_t dev) sc->tc.tc_quality = 950, sc->tc.tc_frequency = sc->freq; sc->tc.tc_priv = sc; + sc->tc.tc_fill_vdso_timehands = hpet_vdso_timehands; +#ifdef COMPAT_FREEBSD32 + sc->tc.tc_fill_vdso_timehands32 = hpet_vdso_timehands32; +#endif tc_init(&sc->tc); } /* If not disabled - setup and announce event timers. */ Modified: stable/11/sys/dev/acpica/acpi_hpet.h ============================================================================== --- stable/11/sys/dev/acpica/acpi_hpet.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/dev/acpica/acpi_hpet.h Fri Sep 16 10:04:28 2016 (r305866) @@ -64,4 +64,15 @@ #define HPET_MIN_CYCLES 128 /* Period considered reliable. */ +#ifdef _KERNEL +struct timecounter; +struct vdso_timehands; +struct vdso_timehands32; + +uint32_t hpet_vdso_timehands(struct vdso_timehands *vdso_th, + struct timecounter *tc); +uint32_t hpet_vdso_timehands32(struct vdso_timehands32 *vdso_th32, + struct timecounter *tc); +#endif + #endif /* !__ACPI_HPET_H__ */ Modified: stable/11/sys/kern/kern_tc.c ============================================================================== --- stable/11/sys/kern/kern_tc.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/kern/kern_tc.c Fri Sep 16 10:04:28 2016 (r305866) @@ -6,11 +6,14 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * Copyright (c) 2011 The FreeBSD Foundation + * Copyright (c) 2011, 2015, 2016 The FreeBSD Foundation * All rights reserved. * * Portions of this software were developed by Julien Ridoux at the University * of Melbourne under sponsorship from the FreeBSD Foundation. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. */ #include <sys/cdefs.h> @@ -2134,13 +2137,16 @@ tc_fill_vdso_timehands(struct vdso_timeh uint32_t enabled; th = timehands; - vdso_th->th_algo = VDSO_TH_ALGO_1; vdso_th->th_scale = th->th_scale; vdso_th->th_offset_count = th->th_offset_count; vdso_th->th_counter_mask = th->th_counter->tc_counter_mask; vdso_th->th_offset = th->th_offset; vdso_th->th_boottime = th->th_boottime; - enabled = cpu_fill_vdso_timehands(vdso_th, th->th_counter); + if (th->th_counter->tc_fill_vdso_timehands != NULL) { + enabled = th->th_counter->tc_fill_vdso_timehands(vdso_th, + th->th_counter); + } else + enabled = 0; if (!vdso_th_enable) enabled = 0; return (enabled); @@ -2154,7 +2160,6 @@ tc_fill_vdso_timehands32(struct vdso_tim uint32_t enabled; th = timehands; - vdso_th32->th_algo = VDSO_TH_ALGO_1; *(uint64_t *)&vdso_th32->th_scale[0] = th->th_scale; vdso_th32->th_offset_count = th->th_offset_count; vdso_th32->th_counter_mask = th->th_counter->tc_counter_mask; @@ -2162,7 +2167,11 @@ tc_fill_vdso_timehands32(struct vdso_tim *(uint64_t *)&vdso_th32->th_offset.frac[0] = th->th_offset.frac; vdso_th32->th_boottime.sec = th->th_boottime.sec; *(uint64_t *)&vdso_th32->th_boottime.frac[0] = th->th_boottime.frac; - enabled = cpu_fill_vdso_timehands32(vdso_th32, th->th_counter); + if (th->th_counter->tc_fill_vdso_timehands32 != NULL) { + enabled = th->th_counter->tc_fill_vdso_timehands32(vdso_th32, + th->th_counter); + } else + enabled = 0; if (!vdso_th_enable) enabled = 0; return (enabled); Modified: stable/11/sys/sys/timetc.h ============================================================================== --- stable/11/sys/sys/timetc.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/sys/timetc.h Fri Sep 16 10:04:28 2016 (r305866) @@ -28,8 +28,14 @@ */ struct timecounter; +struct vdso_timehands; +struct vdso_timehands32; typedef u_int timecounter_get_t(struct timecounter *); typedef void timecounter_pps_t(struct timecounter *); +typedef uint32_t timecounter_fill_vdso_timehands_t(struct vdso_timehands *, + struct timecounter *); +typedef uint32_t timecounter_fill_vdso_timehands32_t(struct vdso_timehands32 *, + struct timecounter *); struct timecounter { timecounter_get_t *tc_get_timecount; @@ -68,6 +74,8 @@ struct timecounter { /* Pointer to the timecounter's private parts. */ struct timecounter *tc_next; /* Pointer to the next timecounter. */ + timecounter_fill_vdso_timehands_t *tc_fill_vdso_timehands; + timecounter_fill_vdso_timehands32_t *tc_fill_vdso_timehands32; }; extern struct timecounter *timecounter; Modified: stable/11/sys/sys/vdso.h ============================================================================== --- stable/11/sys/sys/vdso.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/sys/vdso.h Fri Sep 16 10:04:28 2016 (r305866) @@ -53,6 +53,7 @@ struct vdso_timekeep { #define VDSO_TK_VER_1 0x1 #define VDSO_TK_VER_CURR VDSO_TK_VER_1 #define VDSO_TH_ALGO_1 0x1 +#define VDSO_TH_ALGO_2 0x2 #ifndef _KERNEL @@ -62,7 +63,7 @@ struct timezone; int __vdso_clock_gettime(clockid_t clock_id, struct timespec *ts); int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz); -u_int __vdso_gettc(const struct vdso_timehands *vdso_th); +int __vdso_gettc(const struct vdso_timehands *vdso_th, u_int *tc); int __vdso_gettimekeep(struct vdso_timekeep **tk); #endif Modified: stable/11/sys/x86/include/vdso.h ============================================================================== --- stable/11/sys/x86/include/vdso.h Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/x86/include/vdso.h Fri Sep 16 10:04:28 2016 (r305866) @@ -1,7 +1,11 @@ /*- * Copyright 2012 Konstantin Belousov <kib@FreeBSD.ORG>. + * Copyright 2016 The FreeBSD Foundation. * All rights reserved. * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -30,7 +34,11 @@ #define VDSO_TIMEHANDS_MD \ uint32_t th_x86_shift; \ - uint32_t th_res[7]; + uint32_t th_x86_hpet_idx; \ + uint32_t th_res[6]; + +#define VDSO_TH_ALGO_X86_TSC VDSO_TH_ALGO_1 +#define VDSO_TH_ALGO_X86_HPET VDSO_TH_ALGO_2 #ifdef _KERNEL #ifdef COMPAT_FREEBSD32 Modified: stable/11/sys/x86/x86/tsc.c ============================================================================== --- stable/11/sys/x86/x86/tsc.c Fri Sep 16 07:09:35 2016 (r305865) +++ stable/11/sys/x86/x86/tsc.c Fri Sep 16 10:04:28 2016 (r305866) @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include <machine/md_var.h> #include <machine/specialreg.h> #include <x86/vmware.h> +#include <dev/acpica/acpi_hpet.h> #include "cpufreq_if.h" @@ -93,14 +94,22 @@ static unsigned tsc_get_timecount_low_lf static unsigned tsc_get_timecount_mfence(struct timecounter *tc); static unsigned tsc_get_timecount_low_mfence(struct timecounter *tc); static void tsc_levels_changed(void *arg, int unit); +static uint32_t x86_tsc_vdso_timehands(struct vdso_timehands *vdso_th, + struct timecounter *tc); +#ifdef COMPAT_FREEBSD32 +static uint32_t x86_tsc_vdso_timehands32(struct vdso_timehands32 *vdso_th32, + struct timecounter *tc); +#endif static struct timecounter tsc_timecounter = { - tsc_get_timecount, /* get_timecount */ - 0, /* no poll_pps */ - ~0u, /* counter_mask */ - 0, /* frequency */ - "TSC", /* name */ - 800, /* quality (adjusted in code) */ + .tc_get_timecount = tsc_get_timecount, + .tc_counter_mask = ~0u, + .tc_name = "TSC", + .tc_quality = 800, /* adjusted in code */ + .tc_fill_vdso_timehands = x86_tsc_vdso_timehands, +#ifdef COMPAT_FREEBSD32 + .tc_fill_vdso_timehands32 = x86_tsc_vdso_timehands32, +#endif }; static void @@ -724,23 +733,27 @@ tsc_get_timecount_low_mfence(struct time return (tsc_get_timecount_low(tc)); } -uint32_t -cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc) +static uint32_t +x86_tsc_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc) { + vdso_th->th_algo = VDSO_TH_ALGO_X86_TSC; vdso_th->th_x86_shift = (int)(intptr_t)tc->tc_priv; + vdso_th->th_x86_hpet_idx = 0xffffffff; bzero(vdso_th->th_res, sizeof(vdso_th->th_res)); - return (tc == &tsc_timecounter); + return (1); } #ifdef COMPAT_FREEBSD32 -uint32_t -cpu_fill_vdso_timehands32(struct vdso_timehands32 *vdso_th32, +static uint32_t +x86_tsc_vdso_timehands32(struct vdso_timehands32 *vdso_th32, struct timecounter *tc) { + vdso_th32->th_algo = VDSO_TH_ALGO_X86_TSC; vdso_th32->th_x86_shift = (int)(intptr_t)tc->tc_priv; + vdso_th32->th_x86_hpet_idx = 0xffffffff; bzero(vdso_th32->th_res, sizeof(vdso_th32->th_res)); - return (tc == &tsc_timecounter); + return (1); } #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609161004.u8GA4SUY059878>