xref: /illumos-gate/usr/src/uts/intel/asm/mmu.h (revision 74ecdb51)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5843e1988Sjohnlev  * Common Development and Distribution License (the "License").
6843e1988Sjohnlev  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22843e1988Sjohnlev  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*74ecdb51SJohn Levon  *
25*74ecdb51SJohn Levon  * Copyright 2018 Joyent, Inc.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #ifndef _ASM_MMU_H
297c478bd9Sstevel@tonic-gate #define	_ASM_MMU_H
307c478bd9Sstevel@tonic-gate 
316b7143d7SRichard Lowe #include <sys/ccompile.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
357c478bd9Sstevel@tonic-gate extern "C" {
367c478bd9Sstevel@tonic-gate #endif
377c478bd9Sstevel@tonic-gate 
38*74ecdb51SJohn Levon #if defined(__GNUC__)
397c478bd9Sstevel@tonic-gate 
40*74ecdb51SJohn Levon #if !defined(__xpv)
417c478bd9Sstevel@tonic-gate 
426b7143d7SRichard Lowe extern __GNU_INLINE ulong_t
getcr3(void)436b7143d7SRichard Lowe getcr3(void)
447c478bd9Sstevel@tonic-gate {
457c478bd9Sstevel@tonic-gate 	uint64_t value;
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate 	__asm__ __volatile__(
48843e1988Sjohnlev 	    "movq %%cr3, %0"
49843e1988Sjohnlev 	    : "=r" (value));
507c478bd9Sstevel@tonic-gate 	return (value);
517c478bd9Sstevel@tonic-gate }
527c478bd9Sstevel@tonic-gate 
536b7143d7SRichard Lowe extern __GNU_INLINE void
setcr3(ulong_t value)546b7143d7SRichard Lowe setcr3(ulong_t value)
557c478bd9Sstevel@tonic-gate {
567c478bd9Sstevel@tonic-gate 	__asm__ __volatile__(
57843e1988Sjohnlev 	    "movq %0, %%cr3"
58843e1988Sjohnlev 	    : /* no output */
59843e1988Sjohnlev 	    : "r" (value));
607c478bd9Sstevel@tonic-gate }
617c478bd9Sstevel@tonic-gate 
626b7143d7SRichard Lowe extern __GNU_INLINE ulong_t
getcr4(void)63*74ecdb51SJohn Levon getcr4(void)
647c478bd9Sstevel@tonic-gate {
65*74ecdb51SJohn Levon 	uint64_t value;
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 	__asm__ __volatile__(
68*74ecdb51SJohn Levon 	    "movq %%cr4, %0"
69843e1988Sjohnlev 	    : "=r" (value));
707c478bd9Sstevel@tonic-gate 	return (value);
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate 
736b7143d7SRichard Lowe extern __GNU_INLINE void
setcr4(ulong_t value)74*74ecdb51SJohn Levon setcr4(ulong_t value)
757c478bd9Sstevel@tonic-gate {
767c478bd9Sstevel@tonic-gate 	__asm__ __volatile__(
77*74ecdb51SJohn Levon 	    "movq %0, %%cr4"
78843e1988Sjohnlev 	    : /* no output */
79843e1988Sjohnlev 	    : "r" (value));
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate 
826b7143d7SRichard Lowe extern __GNU_INLINE void
reload_cr3(void)836b7143d7SRichard Lowe reload_cr3(void)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate 	setcr3(getcr3());
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate 
88*74ecdb51SJohn Levon /*
89*74ecdb51SJohn Levon  * We clobber memory: we're not writing anything, but we don't want to
90*74ecdb51SJohn Levon  * potentially get re-ordered beyond the TLB flush.
91*74ecdb51SJohn Levon  */
92*74ecdb51SJohn Levon extern __GNU_INLINE void
invpcid_insn(uint64_t type,uint64_t pcid,uintptr_t addr)93*74ecdb51SJohn Levon invpcid_insn(uint64_t type, uint64_t pcid, uintptr_t addr)
94*74ecdb51SJohn Levon {
95*74ecdb51SJohn Levon 	uint64_t pcid_desc[2] = { pcid, addr };
96*74ecdb51SJohn Levon 	__asm__ __volatile__(
97*74ecdb51SJohn Levon 	    "invpcid %0, %1"
98*74ecdb51SJohn Levon 	    : /* no output */
99*74ecdb51SJohn Levon 	    : "m" (*pcid_desc), "r" (type)
100*74ecdb51SJohn Levon 	    : "memory");
101*74ecdb51SJohn Levon }
102*74ecdb51SJohn Levon 
103*74ecdb51SJohn Levon #endif /* !__xpv */
104*74ecdb51SJohn Levon 
105*74ecdb51SJohn Levon extern __GNU_INLINE void
mmu_invlpg(caddr_t addr)106*74ecdb51SJohn Levon mmu_invlpg(caddr_t addr)
107*74ecdb51SJohn Levon {
108*74ecdb51SJohn Levon 	__asm__ __volatile__(
109*74ecdb51SJohn Levon 	    "invlpg %0"
110*74ecdb51SJohn Levon 	    : "=m" (*addr)
111*74ecdb51SJohn Levon 	    : "m" (*addr));
112*74ecdb51SJohn Levon }
1137c478bd9Sstevel@tonic-gate 
114*74ecdb51SJohn Levon #endif /* __GNUC__ */
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate #ifdef __cplusplus
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate #endif
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate #endif	/* _ASM_MMU_H */
121