1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2018 Joyent, Inc.
  26  */
  27 
  28 #ifndef _ASM_MMU_H
  29 #define _ASM_MMU_H
  30 
  31 #include <sys/ccompile.h>
  32 #include <sys/types.h>
  33 
  34 #ifdef  __cplusplus
  35 extern "C" {
  36 #endif
  37 
  38 #if defined(__GNUC__)
  39 
  40 #if !defined(__xpv)
  41 
  42 extern __GNU_INLINE ulong_t
  43 getcr3(void)
  44 {
  45         uint64_t value;
  46 
  47         __asm__ __volatile__(
  48             "movq %%cr3, %0"
  49             : "=r" (value));
  50         return (value);
  51 }
  52 
  53 extern __GNU_INLINE void
  54 setcr3(ulong_t value)
  55 {
  56         __asm__ __volatile__(
  57             "movq %0, %%cr3"
  58             : /* no output */
  59             : "r" (value));
  60 }
  61 
  62 extern __GNU_INLINE ulong_t
  63 getcr4(void)
  64 {
  65         uint64_t value;
  66 
  67         __asm__ __volatile__(
  68             "movq %%cr4, %0"
  69             : "=r" (value));
  70         return (value);
  71 }
  72 
  73 extern __GNU_INLINE void
  74 setcr4(ulong_t value)
  75 {
  76         __asm__ __volatile__(
  77             "movq %0, %%cr4"
  78             : /* no output */
  79             : "r" (value));
  80 }
  81 
  82 extern __GNU_INLINE void
  83 reload_cr3(void)
  84 {
  85         setcr3(getcr3());
  86 }
  87 
  88 /*
  89  * We clobber memory: we're not writing anything, but we don't want to
  90  * potentially get re-ordered beyond the TLB flush.
  91  */
  92 extern __GNU_INLINE void
  93 invpcid_insn(uint64_t type, uint64_t pcid, uintptr_t addr)
  94 {
  95         uint64_t pcid_desc[2] = { pcid, addr };
  96         __asm__ __volatile__(
  97             "invpcid %0, %1"
  98             : /* no output */
  99             : "m" (*pcid_desc), "r" (type)
 100             : "memory");
 101 }
 102 
 103 #endif /* !__xpv */
 104 
 105 extern __GNU_INLINE void
 106 mmu_invlpg(caddr_t addr)
 107 {
 108         __asm__ __volatile__(
 109             "invlpg %0"
 110             : "=m" (*addr)
 111             : "m" (*addr));
 112 }
 113 
 114 #endif /* __GNUC__ */
 115 
 116 #ifdef __cplusplus
 117 }
 118 #endif
 119 
 120 #endif  /* _ASM_MMU_H */