The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/x86/linux/linux_vdso_gettc_x86.inc

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org>
    5  * Copyright (c) 2016, 2017, 2019 The FreeBSD Foundation
    6  * Copyright (c) 2021 Dmitry Chagin <dchagin@FreeBSD.org>
    7  *
    8  * Portions of this software were developed by Konstantin Belousov
    9  * under sponsorship from the FreeBSD Foundation.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 static inline u_int
   34 rdtsc_low(const struct vdso_timehands *th)
   35 {
   36         u_int rv;
   37 
   38         __asm __volatile("rdtsc; shrd %%cl, %%edx, %0"
   39             : "=a" (rv) : "c" (th->th_x86_shift) : "edx");
   40         return (rv);
   41 }
   42 
   43 static inline u_int
   44 rdtscp_low(const struct vdso_timehands *th)
   45 {
   46         u_int rv;
   47 
   48         __asm __volatile("rdtscp; movl %%edi,%%ecx; shrd %%cl, %%edx, %0"
   49             : "=a" (rv) : "D" (th->th_x86_shift) : "ecx", "edx");
   50         return (rv);
   51 }
   52 
   53 static u_int
   54 rdtsc_low_mb_lfence(const struct vdso_timehands *th)
   55 {
   56         lfence();
   57         return (rdtsc_low(th));
   58 }
   59 
   60 static u_int
   61 rdtsc_low_mb_mfence(const struct vdso_timehands *th)
   62 {
   63         mfence();
   64         return (rdtsc_low(th));
   65 }
   66 
   67 static u_int
   68 rdtsc_low_mb_none(const struct vdso_timehands *th)
   69 {
   70         return (rdtsc_low(th));
   71 }
   72 
   73 static u_int
   74 rdtsc32_mb_lfence(void)
   75 {
   76         lfence();
   77         return (rdtsc32());
   78 }
   79 
   80 static u_int
   81 rdtsc32_mb_mfence(void)
   82 {
   83         mfence();
   84         return (rdtsc32());
   85 }
   86 
   87 static u_int
   88 rdtsc32_mb_none(void)
   89 {
   90         return (rdtsc32());
   91 }
   92 
   93 static u_int
   94 rdtscp32_(void)
   95 {
   96         return (rdtscp32());
   97 }
   98 
   99 struct tsc_selector_tag {
  100         u_int (*ts_rdtsc32)(void);
  101         u_int (*ts_rdtsc_low)(const struct vdso_timehands *);
  102 };
  103 
  104 static const struct tsc_selector_tag tsc_selector[] = {
  105         [0] = {                         /* Intel, LFENCE */
  106                 .ts_rdtsc32 =   rdtsc32_mb_lfence,
  107                 .ts_rdtsc_low = rdtsc_low_mb_lfence,
  108         },
  109         [1] = {                         /* AMD, MFENCE */
  110                 .ts_rdtsc32 =   rdtsc32_mb_mfence,
  111                 .ts_rdtsc_low = rdtsc_low_mb_mfence,
  112         },
  113         [2] = {                         /* No SSE2 */
  114                 .ts_rdtsc32 = rdtsc32_mb_none,
  115                 .ts_rdtsc_low = rdtsc_low_mb_none,
  116         },
  117         [3] = {                         /* RDTSCP */
  118                 .ts_rdtsc32 =   rdtscp32_,
  119                 .ts_rdtsc_low = rdtscp_low,
  120         },
  121 };
  122 
  123 static u_int
  124 __vdso_gettc_rdtsc_low(const struct vdso_timehands *th)
  125 {
  126 
  127         return (tsc_selector[kern_tsc_selector].ts_rdtsc_low(th));
  128 }
  129 
  130 static u_int
  131 __vdso_gettc_rdtsc32(void)
  132 {
  133 
  134         return (tsc_selector[kern_tsc_selector].ts_rdtsc32());
  135 }
  136 
  137 int
  138 __vdso_gettc(const struct vdso_timehands *th, u_int *tc)
  139 {
  140 
  141         switch (th->th_algo) {
  142         case VDSO_TH_ALGO_X86_TSC:
  143                 *tc = th->th_x86_shift > 0 ? __vdso_gettc_rdtsc_low(th) :
  144                     __vdso_gettc_rdtsc32();
  145                 return (0);
  146         case VDSO_TH_ALGO_X86_HPET:
  147                 /* TODO */
  148         default:
  149                 return (ENOSYS);
  150         }
  151 }

Cache object: 74e09cec8a3401093b0e8ad404a1c89b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.