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 <k...@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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to