LCOV - code coverage report
Current view: top level - arch/amd64/compile/GENERIC.MP.kcov/obj/machine - cpufunc.h (source / functions) Hit Total Coverage
Test: 6.4 Lines: 1 109 0.9 %
Date: 2018-10-19 03:25:38 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: cpufunc.h,v 1.30 2018/07/27 21:11:31 kettenis Exp $   */
       2             : /*      $NetBSD: cpufunc.h,v 1.3 2003/05/08 10:27:43 fvdl Exp $ */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 1998 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Charles M. Hannum.
      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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      21             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      22             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      23             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      24             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30             :  * POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : #ifndef _MACHINE_CPUFUNC_H_
      34             : #define _MACHINE_CPUFUNC_H_
      35             : 
      36             : /*
      37             :  * Functions to provide access to i386-specific instructions.
      38             :  */
      39             : 
      40             : #include <sys/types.h>
      41             : 
      42             : #include <machine/specialreg.h>
      43             : 
      44             : #if defined(_KERNEL) && !defined (_STANDALONE)
      45             : 
      46             : extern int cpu_feature;
      47             : 
      48             : static __inline void 
      49           0 : invlpg(u_int64_t addr)
      50             : { 
      51          60 :         __asm volatile("invlpg (%0)" : : "r" (addr) : "memory");
      52           0 : }  
      53             : 
      54             : static __inline void
      55           0 : lidt(void *p)
      56             : {
      57           0 :         __asm volatile("lidt (%0)" : : "r" (p) : "memory");
      58           0 : }
      59             : 
      60             : static __inline void
      61           0 : lldt(u_short sel)
      62             : {
      63           0 :         __asm volatile("lldt %0" : : "r" (sel));
      64           0 : }
      65             : 
      66             : static __inline void
      67           0 : ltr(u_short sel)
      68             : {
      69           0 :         __asm volatile("ltr %0" : : "r" (sel));
      70           0 : }
      71             : 
      72             : static __inline void
      73           0 : lcr8(u_int val)
      74             : {
      75           0 :         u_int64_t val64 = val;
      76           0 :         __asm volatile("movq %0,%%cr8" : : "r" (val64));
      77           0 : }
      78             : 
      79             : /*
      80             :  * Upper 32 bits are reserved anyway, so just keep this 32bits.
      81             :  */
      82             : static __inline void
      83           0 : lcr0(u_int val)
      84             : {
      85           0 :         u_int64_t val64 = val;
      86           0 :         __asm volatile("movq %0,%%cr0" : : "r" (val64));
      87           0 : }
      88             : 
      89             : static __inline u_int
      90           0 : rcr0(void)
      91             : {
      92             :         u_int64_t val64;
      93             :         u_int val;
      94           0 :         __asm volatile("movq %%cr0,%0" : "=r" (val64));
      95           0 :         val = val64;
      96           0 :         return val;
      97             : }
      98             : 
      99             : static __inline u_int64_t
     100           0 : rcr2(void)
     101             : {
     102             :         u_int64_t val;
     103           0 :         __asm volatile("movq %%cr2,%0" : "=r" (val));
     104           0 :         return val;
     105             : }
     106             : 
     107             : static __inline void
     108           0 : lcr3(u_int64_t val)
     109             : {
     110           0 :         __asm volatile("movq %0,%%cr3" : : "r" (val));
     111           0 : }
     112             : 
     113             : static __inline u_int64_t
     114           0 : rcr3(void)
     115             : {
     116             :         u_int64_t val;
     117           0 :         __asm volatile("movq %%cr3,%0" : "=r" (val));
     118           0 :         return val;
     119             : }
     120             : 
     121             : /*
     122             :  * Same as for cr0. Don't touch upper 32 bits.
     123             :  */
     124             : static __inline void
     125           0 : lcr4(u_int val)
     126             : {
     127           0 :         u_int64_t val64 = val;
     128             : 
     129           0 :         __asm volatile("movq %0,%%cr4" : : "r" (val64));
     130           0 : }
     131             : 
     132             : static __inline u_int
     133           0 : rcr4(void)
     134             : {
     135             :         u_int64_t val64;
     136           0 :         __asm volatile("movq %%cr4,%0" : "=r" (val64));
     137           0 :         return (u_int) val64;
     138             : }
     139             : 
     140             : static __inline void
     141           0 : tlbflush(void)
     142             : {
     143             :         u_int64_t val;
     144           0 :         __asm volatile("movq %%cr3,%0" : "=r" (val));
     145           0 :         __asm volatile("movq %0,%%cr3" : : "r" (val));
     146           0 : }
     147             : 
     148             : #ifdef notyet
     149             : void    setidt(int idx, /*XXX*/caddr_t func, int typ, int dpl);
     150             : #endif
     151             : 
     152             : 
     153             : /* XXXX ought to be in psl.h with spl() functions */
     154             : 
     155             : static __inline u_long
     156           0 : read_rflags(void)
     157             : {
     158             :         u_long  ef;
     159             : 
     160           0 :         __asm volatile("pushfq; popq %0" : "=r" (ef));
     161           0 :         return (ef);
     162             : }
     163             : 
     164             : static __inline void
     165           0 : write_rflags(u_long ef)
     166             : {
     167           0 :         __asm volatile("pushq %0; popfq" : : "r" (ef));
     168           0 : }
     169             : 
     170             : static __inline void
     171           0 : intr_enable(void)
     172             : {
     173           0 :         __asm volatile("sti");
     174           0 : }
     175             : 
     176             : static __inline u_long
     177           0 : intr_disable(void)
     178             : {
     179             :         u_long ef;
     180             : 
     181           0 :         ef = read_rflags();
     182           0 :         __asm volatile("cli");
     183           0 :         return (ef);
     184             : }
     185             : 
     186             : static __inline void
     187           0 : intr_restore(u_long ef)
     188             : {
     189           0 :         write_rflags(ef);
     190           0 : }
     191             : 
     192             : static __inline u_int64_t
     193           0 : rdmsr(u_int msr)
     194             : {
     195             :         uint32_t hi, lo;
     196           0 :         __asm volatile("rdmsr" : "=d" (hi), "=a" (lo) : "c" (msr));
     197           0 :         return (((uint64_t)hi << 32) | (uint64_t) lo);
     198             : }
     199             : 
     200             : static __inline void
     201           0 : wrmsr(u_int msr, u_int64_t newval)
     202             : {
     203           0 :         __asm volatile("wrmsr" :
     204           0 :             : "a" (newval & 0xffffffff), "d" (newval >> 32), "c" (msr));
     205           0 : }
     206             : 
     207             : /* 
     208             :  * Some of the undocumented AMD64 MSRs need a 'passcode' to access.
     209             :  *
     210             :  * See LinuxBIOSv2: src/cpu/amd/model_fxx/model_fxx_init.c
     211             :  */
     212             : 
     213             : #define OPTERON_MSR_PASSCODE    0x9c5a203a
     214             :  
     215             : static __inline u_int64_t
     216           0 : rdmsr_locked(u_int msr, u_int code)
     217             : {
     218             :         uint32_t hi, lo;
     219           0 :         __asm volatile("rdmsr"
     220             :             : "=d" (hi), "=a" (lo)
     221             :             : "c" (msr), "D" (code));
     222           0 :         return (((uint64_t)hi << 32) | (uint64_t) lo);
     223             : }
     224             : 
     225             : static __inline void
     226           0 : wrmsr_locked(u_int msr, u_int code, u_int64_t newval)
     227             : {
     228           0 :         __asm volatile("wrmsr" :
     229           0 :             : "a" (newval & 0xffffffff), "d" (newval >> 32), "c" (msr), "D" (code));
     230           0 : }
     231             : 
     232             : static __inline void
     233           0 : wbinvd(void)
     234             : {
     235           0 :         __asm volatile("wbinvd");
     236           0 : }
     237             : 
     238             : static __inline void
     239           0 : clflush(u_int64_t addr)
     240             : {
     241           0 :         __asm volatile("clflush %0" : "+m" (*(volatile char *)addr));
     242           0 : }
     243             : 
     244             : static __inline void
     245           0 : mfence(void)
     246             : {
     247           0 :         __asm volatile("mfence" : : : "memory");
     248           0 : }
     249             : 
     250             : static __inline u_int64_t
     251           0 : rdtsc(void)
     252             : {
     253             :         uint32_t hi, lo;
     254             : 
     255           0 :         __asm volatile("rdtsc" : "=d" (hi), "=a" (lo));
     256           0 :         return (((uint64_t)hi << 32) | (uint64_t) lo);
     257             : }
     258             : 
     259             : static __inline u_int64_t
     260             : rdpmc(u_int pmc)
     261             : {
     262             :         uint32_t hi, lo;
     263             : 
     264             :         __asm volatile("rdpmc" : "=d" (hi), "=a" (lo) : "c" (pmc));
     265             :         return (((uint64_t)hi << 32) | (uint64_t) lo);
     266             : }
     267             : 
     268             : static __inline void
     269           0 : monitor(const volatile void *addr, u_long extensions, u_int hints)
     270             : {
     271             : 
     272           0 :         __asm volatile("monitor"
     273             :             : : "a" (addr), "c" (extensions), "d" (hints));
     274           0 : }
     275             : 
     276             : static __inline void
     277           0 : mwait(u_long extensions, u_int hints)
     278             : {
     279             : 
     280           0 :         __asm volatile(
     281             :                 "  mwait                   ;"
     282             :                 "  mov     $8,%%rcx        ;"
     283             :                 "  .align  16,0x90         ;"
     284             :                 "3:        call    5f              ;"
     285             :                 "4:        pause                   ;"
     286             :                 "  lfence                  ;"
     287             :                 "  call    4b              ;"
     288             :                 "  .align  16,0xcc         ;"
     289             :                 "5:        call    7f              ;"
     290             :                 "6:        pause                   ;"
     291             :                 "  lfence                  ;"
     292             :                 "  call    6b              ;"
     293             :                 "  .align  16,0xcc         ;"
     294             :                 "7:        loop    3b              ;"
     295             :                 "  add     $(16*8),%%rsp"
     296             :             : "+c" (extensions) : "a" (hints));
     297           0 : }
     298             : 
     299             : static __inline void
     300           0 : xsetbv(uint32_t reg, uint64_t mask)
     301             : {
     302             :         uint32_t lo, hi;
     303             : 
     304           0 :         lo = mask;
     305           0 :         hi = mask >> 32;
     306           0 :         __asm volatile("xsetbv" :: "c" (reg), "a" (lo), "d" (hi) : "memory");
     307           0 : }
     308             : 
     309             : static __inline uint64_t
     310           0 : xgetbv(uint32_t reg)
     311             : {
     312             :         uint32_t lo, hi;
     313             : 
     314           0 :         __asm volatile("xgetbv" : "=a" (lo), "=d" (hi) : "c" (reg));
     315             : 
     316           0 :         return (((uint64_t)hi << 32) | (uint64_t)lo);
     317             : }
     318             : 
     319             : static __inline void
     320           0 : stgi(void)
     321             : {
     322           0 :         __asm volatile("stgi");
     323           0 : }
     324             : 
     325             : static __inline void
     326           0 : clgi(void)
     327             : {
     328           0 :         __asm volatile("clgi");
     329           0 : }
     330             : 
     331             : /* Break into DDB. */
     332             : static __inline void
     333           0 : breakpoint(void)
     334             : {
     335           0 :         __asm volatile("int $3");
     336           0 : }
     337             : 
     338             : void amd64_errata(struct cpu_info *);
     339             : void cpu_ucode_setup(void);
     340             : void cpu_ucode_apply(struct cpu_info *);
     341             : 
     342             : struct cpu_info_full;
     343             : void cpu_enter_pages(struct cpu_info_full *);
     344             : 
     345             : #endif /* _KERNEL */
     346             : 
     347             : #endif /* !_MACHINE_CPUFUNC_H_ */

Generated by: LCOV version 1.13