xref: /titanic_41/usr/src/uts/intel/ia32/ml/i86_subr.s (revision dd7afb26c5036958cddc0c2c1e499571664a6ed0)
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
5ee88d2b9Skchow * Common Development and Distribution License (the "License").
6ee88d2b9Skchow * 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 */
21ae115bc7Smrj
227c478bd9Sstevel@tonic-gate/*
237417cfdeSKuriakose Kuruvilla * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
24ecae7de2SMarcel Telka * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
25887cdfc7SMatthew Ahrens * Copyright (c) 2014 by Delphix. All rights reserved.
26*dd7afb26SPatrick Mooney * Copyright 2016 Joyent, Inc.
277c478bd9Sstevel@tonic-gate */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate/*
307c478bd9Sstevel@tonic-gate *  Copyright (c) 1990, 1991 UNIX System Laboratories, Inc.
317c478bd9Sstevel@tonic-gate *  Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T
327c478bd9Sstevel@tonic-gate *    All Rights Reserved
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate/*
367af88ac7SKuriakose Kuruvilla * Copyright (c) 2009, Intel Corporation.
377af88ac7SKuriakose Kuruvilla * All rights reserved.
387af88ac7SKuriakose Kuruvilla */
397af88ac7SKuriakose Kuruvilla
407af88ac7SKuriakose Kuruvilla/*
417c478bd9Sstevel@tonic-gate * General assembly language routines.
427c478bd9Sstevel@tonic-gate * It is the intent of this file to contain routines that are
437c478bd9Sstevel@tonic-gate * independent of the specific kernel architecture, and those that are
447c478bd9Sstevel@tonic-gate * common across kernel architectures.
457c478bd9Sstevel@tonic-gate * As architectures diverge, and implementations of specific
467c478bd9Sstevel@tonic-gate * architecture-dependent routines change, the routines should be moved
477c478bd9Sstevel@tonic-gate * from this file into the respective ../`arch -k`/subr.s file.
487c478bd9Sstevel@tonic-gate */
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
517c478bd9Sstevel@tonic-gate#include <sys/asm_misc.h>
527c478bd9Sstevel@tonic-gate#include <sys/panic.h>
537c478bd9Sstevel@tonic-gate#include <sys/ontrap.h>
547c478bd9Sstevel@tonic-gate#include <sys/regset.h>
557c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
567c478bd9Sstevel@tonic-gate#include <sys/reboot.h>
577c478bd9Sstevel@tonic-gate#include <sys/psw.h>
587c478bd9Sstevel@tonic-gate#include <sys/x86_archext.h>
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate#if defined(__lint)
617c478bd9Sstevel@tonic-gate#include <sys/types.h>
627c478bd9Sstevel@tonic-gate#include <sys/systm.h>
637c478bd9Sstevel@tonic-gate#include <sys/thread.h>
647c478bd9Sstevel@tonic-gate#include <sys/archsystm.h>
657c478bd9Sstevel@tonic-gate#include <sys/byteorder.h>
667c478bd9Sstevel@tonic-gate#include <sys/dtrace.h>
674df4bd60Sbs21162#include <sys/ftrace.h>
687c478bd9Sstevel@tonic-gate#else	/* __lint */
697c478bd9Sstevel@tonic-gate#include "assym.h"
707c478bd9Sstevel@tonic-gate#endif	/* __lint */
717c478bd9Sstevel@tonic-gate#include <sys/dditypes.h>
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate/*
747c478bd9Sstevel@tonic-gate * on_fault()
757c478bd9Sstevel@tonic-gate * Catch lofault faults. Like setjmp except it returns one
767c478bd9Sstevel@tonic-gate * if code following causes uncorrectable fault. Turned off
777c478bd9Sstevel@tonic-gate * by calling no_fault().
787c478bd9Sstevel@tonic-gate */
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate#if defined(__lint)
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate/* ARGSUSED */
837c478bd9Sstevel@tonic-gateint
847c478bd9Sstevel@tonic-gateon_fault(label_t *ljb)
857c478bd9Sstevel@tonic-gate{ return (0); }
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gatevoid
887c478bd9Sstevel@tonic-gateno_fault(void)
897c478bd9Sstevel@tonic-gate{}
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate#else	/* __lint */
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate#if defined(__amd64)
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate	ENTRY(on_fault)
967c478bd9Sstevel@tonic-gate	movq	%gs:CPU_THREAD, %rsi
977c478bd9Sstevel@tonic-gate	leaq	catch_fault(%rip), %rdx
987c478bd9Sstevel@tonic-gate	movq	%rdi, T_ONFAULT(%rsi)		/* jumpbuf in t_onfault */
997c478bd9Sstevel@tonic-gate	movq	%rdx, T_LOFAULT(%rsi)		/* catch_fault in t_lofault */
1007c478bd9Sstevel@tonic-gate	jmp	setjmp				/* let setjmp do the rest */
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gatecatch_fault:
1037c478bd9Sstevel@tonic-gate	movq	%gs:CPU_THREAD, %rsi
1047c478bd9Sstevel@tonic-gate	movq	T_ONFAULT(%rsi), %rdi		/* address of save area */
1057c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
1067c478bd9Sstevel@tonic-gate	movq	%rax, T_ONFAULT(%rsi)		/* turn off onfault */
1077c478bd9Sstevel@tonic-gate	movq	%rax, T_LOFAULT(%rsi)		/* turn off lofault */
1087c478bd9Sstevel@tonic-gate	jmp	longjmp				/* let longjmp do the rest */
1097c478bd9Sstevel@tonic-gate	SET_SIZE(on_fault)
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate	ENTRY(no_fault)
1127c478bd9Sstevel@tonic-gate	movq	%gs:CPU_THREAD, %rsi
1137c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
1147c478bd9Sstevel@tonic-gate	movq	%rax, T_ONFAULT(%rsi)		/* turn off onfault */
1157c478bd9Sstevel@tonic-gate	movq	%rax, T_LOFAULT(%rsi)		/* turn off lofault */
1167c478bd9Sstevel@tonic-gate	ret
1177c478bd9Sstevel@tonic-gate	SET_SIZE(no_fault)
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate#elif defined(__i386)
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate	ENTRY(on_fault)
1227c478bd9Sstevel@tonic-gate	movl	%gs:CPU_THREAD, %edx
1237c478bd9Sstevel@tonic-gate	movl	4(%esp), %eax			/* jumpbuf address */
1247c478bd9Sstevel@tonic-gate	leal	catch_fault, %ecx
1257c478bd9Sstevel@tonic-gate	movl	%eax, T_ONFAULT(%edx)		/* jumpbuf in t_onfault */
1267c478bd9Sstevel@tonic-gate	movl	%ecx, T_LOFAULT(%edx)		/* catch_fault in t_lofault */
1277c478bd9Sstevel@tonic-gate	jmp	setjmp				/* let setjmp do the rest */
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gatecatch_fault:
1307c478bd9Sstevel@tonic-gate	movl	%gs:CPU_THREAD, %edx
1317c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
1327c478bd9Sstevel@tonic-gate	movl	T_ONFAULT(%edx), %ecx		/* address of save area */
1337c478bd9Sstevel@tonic-gate	movl	%eax, T_ONFAULT(%edx)		/* turn off onfault */
1347c478bd9Sstevel@tonic-gate	movl	%eax, T_LOFAULT(%edx)		/* turn off lofault */
1357c478bd9Sstevel@tonic-gate	pushl	%ecx
1367c478bd9Sstevel@tonic-gate	call	longjmp				/* let longjmp do the rest */
1377c478bd9Sstevel@tonic-gate	SET_SIZE(on_fault)
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate	ENTRY(no_fault)
1407c478bd9Sstevel@tonic-gate	movl	%gs:CPU_THREAD, %edx
1417c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
1427c478bd9Sstevel@tonic-gate	movl	%eax, T_ONFAULT(%edx)		/* turn off onfault */
1437c478bd9Sstevel@tonic-gate	movl	%eax, T_LOFAULT(%edx)		/* turn off lofault */
1447c478bd9Sstevel@tonic-gate	ret
1457c478bd9Sstevel@tonic-gate	SET_SIZE(no_fault)
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate#endif	/* __i386 */
1487c478bd9Sstevel@tonic-gate#endif	/* __lint */
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate/*
1517c478bd9Sstevel@tonic-gate * Default trampoline code for on_trap() (see <sys/ontrap.h>).  We just
1527c478bd9Sstevel@tonic-gate * do a longjmp(&curthread->t_ontrap->ot_jmpbuf) if this is ever called.
1537c478bd9Sstevel@tonic-gate */
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate#if defined(lint)
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gatevoid
1587c478bd9Sstevel@tonic-gateon_trap_trampoline(void)
1597c478bd9Sstevel@tonic-gate{}
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate#else	/* __lint */
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate#if defined(__amd64)
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate	ENTRY(on_trap_trampoline)
1667c478bd9Sstevel@tonic-gate	movq	%gs:CPU_THREAD, %rsi
1677c478bd9Sstevel@tonic-gate	movq	T_ONTRAP(%rsi), %rdi
1687c478bd9Sstevel@tonic-gate	addq	$OT_JMPBUF, %rdi
1697c478bd9Sstevel@tonic-gate	jmp	longjmp
1707c478bd9Sstevel@tonic-gate	SET_SIZE(on_trap_trampoline)
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate#elif defined(__i386)
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate	ENTRY(on_trap_trampoline)
1757c478bd9Sstevel@tonic-gate	movl	%gs:CPU_THREAD, %eax
1767c478bd9Sstevel@tonic-gate	movl	T_ONTRAP(%eax), %eax
1777c478bd9Sstevel@tonic-gate	addl	$OT_JMPBUF, %eax
1787c478bd9Sstevel@tonic-gate	pushl	%eax
1797c478bd9Sstevel@tonic-gate	call	longjmp
1807c478bd9Sstevel@tonic-gate	SET_SIZE(on_trap_trampoline)
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate#endif	/* __i386 */
1837c478bd9Sstevel@tonic-gate#endif	/* __lint */
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate/*
1867c478bd9Sstevel@tonic-gate * Push a new element on to the t_ontrap stack.  Refer to <sys/ontrap.h> for
1877c478bd9Sstevel@tonic-gate * more information about the on_trap() mechanism.  If the on_trap_data is the
1887c478bd9Sstevel@tonic-gate * same as the topmost stack element, we just modify that element.
1897c478bd9Sstevel@tonic-gate */
1907c478bd9Sstevel@tonic-gate#if defined(lint)
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate/*ARGSUSED*/
1937c478bd9Sstevel@tonic-gateint
1947c478bd9Sstevel@tonic-gateon_trap(on_trap_data_t *otp, uint_t prot)
1957c478bd9Sstevel@tonic-gate{ return (0); }
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate#else	/* __lint */
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate#if defined(__amd64)
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate	ENTRY(on_trap)
2027c478bd9Sstevel@tonic-gate	movw	%si, OT_PROT(%rdi)		/* ot_prot = prot */
2037c478bd9Sstevel@tonic-gate	movw	$0, OT_TRAP(%rdi)		/* ot_trap = 0 */
2047c478bd9Sstevel@tonic-gate	leaq	on_trap_trampoline(%rip), %rdx	/* rdx = &on_trap_trampoline */
2057c478bd9Sstevel@tonic-gate	movq	%rdx, OT_TRAMPOLINE(%rdi)	/* ot_trampoline = rdx */
2067c478bd9Sstevel@tonic-gate	xorl	%ecx, %ecx
2077c478bd9Sstevel@tonic-gate	movq	%rcx, OT_HANDLE(%rdi)		/* ot_handle = NULL */
2087c478bd9Sstevel@tonic-gate	movq	%rcx, OT_PAD1(%rdi)		/* ot_pad1 = NULL */
2097c478bd9Sstevel@tonic-gate	movq	%gs:CPU_THREAD, %rdx		/* rdx = curthread */
2107c478bd9Sstevel@tonic-gate	movq	T_ONTRAP(%rdx), %rcx		/* rcx = curthread->t_ontrap */
2117c478bd9Sstevel@tonic-gate	cmpq	%rdi, %rcx			/* if (otp == %rcx)	*/
2127c478bd9Sstevel@tonic-gate	je	0f				/*	don't modify t_ontrap */
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate	movq	%rcx, OT_PREV(%rdi)		/* ot_prev = t_ontrap */
2157c478bd9Sstevel@tonic-gate	movq	%rdi, T_ONTRAP(%rdx)		/* curthread->t_ontrap = otp */
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate0:	addq	$OT_JMPBUF, %rdi		/* &ot_jmpbuf */
2187c478bd9Sstevel@tonic-gate	jmp	setjmp
2197c478bd9Sstevel@tonic-gate	SET_SIZE(on_trap)
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate#elif defined(__i386)
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate	ENTRY(on_trap)
2247c478bd9Sstevel@tonic-gate	movl	4(%esp), %eax			/* %eax = otp */
2257c478bd9Sstevel@tonic-gate	movl	8(%esp), %edx			/* %edx = prot */
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate	movw	%dx, OT_PROT(%eax)		/* ot_prot = prot */
2287c478bd9Sstevel@tonic-gate	movw	$0, OT_TRAP(%eax)		/* ot_trap = 0 */
2297c478bd9Sstevel@tonic-gate	leal	on_trap_trampoline, %edx	/* %edx = &on_trap_trampoline */
2307c478bd9Sstevel@tonic-gate	movl	%edx, OT_TRAMPOLINE(%eax)	/* ot_trampoline = %edx */
2317c478bd9Sstevel@tonic-gate	movl	$0, OT_HANDLE(%eax)		/* ot_handle = NULL */
2327c478bd9Sstevel@tonic-gate	movl	$0, OT_PAD1(%eax)		/* ot_pad1 = NULL */
2337c478bd9Sstevel@tonic-gate	movl	%gs:CPU_THREAD, %edx		/* %edx = curthread */
2347c478bd9Sstevel@tonic-gate	movl	T_ONTRAP(%edx), %ecx		/* %ecx = curthread->t_ontrap */
2357c478bd9Sstevel@tonic-gate	cmpl	%eax, %ecx			/* if (otp == %ecx) */
2367c478bd9Sstevel@tonic-gate	je	0f				/*    don't modify t_ontrap */
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate	movl	%ecx, OT_PREV(%eax)		/* ot_prev = t_ontrap */
2397c478bd9Sstevel@tonic-gate	movl	%eax, T_ONTRAP(%edx)		/* curthread->t_ontrap = otp */
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate0:	addl	$OT_JMPBUF, %eax		/* %eax = &ot_jmpbuf */
2427c478bd9Sstevel@tonic-gate	movl	%eax, 4(%esp)			/* put %eax back on the stack */
2437c478bd9Sstevel@tonic-gate	jmp	setjmp				/* let setjmp do the rest */
2447c478bd9Sstevel@tonic-gate	SET_SIZE(on_trap)
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate#endif	/* __i386 */
2477c478bd9Sstevel@tonic-gate#endif	/* __lint */
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate/*
2507c478bd9Sstevel@tonic-gate * Setjmp and longjmp implement non-local gotos using state vectors
2517c478bd9Sstevel@tonic-gate * type label_t.
2527c478bd9Sstevel@tonic-gate */
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate#if defined(__lint)
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate/* ARGSUSED */
2577c478bd9Sstevel@tonic-gateint
2587c478bd9Sstevel@tonic-gatesetjmp(label_t *lp)
2597c478bd9Sstevel@tonic-gate{ return (0); }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate/* ARGSUSED */
2627c478bd9Sstevel@tonic-gatevoid
2637c478bd9Sstevel@tonic-gatelongjmp(label_t *lp)
2647c478bd9Sstevel@tonic-gate{}
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate#else	/* __lint */
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate#if LABEL_PC != 0
2697c478bd9Sstevel@tonic-gate#error LABEL_PC MUST be defined as 0 for setjmp/longjmp to work as coded
2707c478bd9Sstevel@tonic-gate#endif	/* LABEL_PC != 0 */
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate#if defined(__amd64)
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate	ENTRY(setjmp)
2757c478bd9Sstevel@tonic-gate	movq	%rsp, LABEL_SP(%rdi)
2767c478bd9Sstevel@tonic-gate	movq	%rbp, LABEL_RBP(%rdi)
2777c478bd9Sstevel@tonic-gate	movq	%rbx, LABEL_RBX(%rdi)
2787c478bd9Sstevel@tonic-gate	movq	%r12, LABEL_R12(%rdi)
2797c478bd9Sstevel@tonic-gate	movq	%r13, LABEL_R13(%rdi)
2807c478bd9Sstevel@tonic-gate	movq	%r14, LABEL_R14(%rdi)
2817c478bd9Sstevel@tonic-gate	movq	%r15, LABEL_R15(%rdi)
2827c478bd9Sstevel@tonic-gate	movq	(%rsp), %rdx		/* return address */
2837c478bd9Sstevel@tonic-gate	movq	%rdx, (%rdi)		/* LABEL_PC is 0 */
2847c478bd9Sstevel@tonic-gate	xorl	%eax, %eax		/* return 0 */
2857c478bd9Sstevel@tonic-gate	ret
2867c478bd9Sstevel@tonic-gate	SET_SIZE(setjmp)
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate	ENTRY(longjmp)
2897c478bd9Sstevel@tonic-gate	movq	LABEL_SP(%rdi), %rsp
2907c478bd9Sstevel@tonic-gate	movq	LABEL_RBP(%rdi), %rbp
2917c478bd9Sstevel@tonic-gate	movq	LABEL_RBX(%rdi), %rbx
2927c478bd9Sstevel@tonic-gate	movq	LABEL_R12(%rdi), %r12
2937c478bd9Sstevel@tonic-gate	movq	LABEL_R13(%rdi), %r13
2947c478bd9Sstevel@tonic-gate	movq	LABEL_R14(%rdi), %r14
2957c478bd9Sstevel@tonic-gate	movq	LABEL_R15(%rdi), %r15
2967c478bd9Sstevel@tonic-gate	movq	(%rdi), %rdx		/* return address; LABEL_PC is 0 */
2977c478bd9Sstevel@tonic-gate	movq	%rdx, (%rsp)
2987c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
2997c478bd9Sstevel@tonic-gate	incl	%eax			/* return 1 */
3007c478bd9Sstevel@tonic-gate	ret
3017c478bd9Sstevel@tonic-gate	SET_SIZE(longjmp)
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate#elif defined(__i386)
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate	ENTRY(setjmp)
3067c478bd9Sstevel@tonic-gate	movl	4(%esp), %edx		/* address of save area */
3077c478bd9Sstevel@tonic-gate	movl	%ebp, LABEL_EBP(%edx)
3087c478bd9Sstevel@tonic-gate	movl	%ebx, LABEL_EBX(%edx)
3097c478bd9Sstevel@tonic-gate	movl	%esi, LABEL_ESI(%edx)
3107c478bd9Sstevel@tonic-gate	movl	%edi, LABEL_EDI(%edx)
3117c478bd9Sstevel@tonic-gate	movl	%esp, 4(%edx)
3127c478bd9Sstevel@tonic-gate	movl	(%esp), %ecx		/* %eip (return address) */
3137c478bd9Sstevel@tonic-gate	movl	%ecx, (%edx)		/* LABEL_PC is 0 */
3147c478bd9Sstevel@tonic-gate	subl	%eax, %eax		/* return 0 */
3157c478bd9Sstevel@tonic-gate	ret
3167c478bd9Sstevel@tonic-gate	SET_SIZE(setjmp)
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate	ENTRY(longjmp)
3197c478bd9Sstevel@tonic-gate	movl	4(%esp), %edx		/* address of save area */
3207c478bd9Sstevel@tonic-gate	movl	LABEL_EBP(%edx), %ebp
3217c478bd9Sstevel@tonic-gate	movl	LABEL_EBX(%edx), %ebx
3227c478bd9Sstevel@tonic-gate	movl	LABEL_ESI(%edx), %esi
3237c478bd9Sstevel@tonic-gate	movl	LABEL_EDI(%edx), %edi
3247c478bd9Sstevel@tonic-gate	movl	4(%edx), %esp
3257c478bd9Sstevel@tonic-gate	movl	(%edx), %ecx		/* %eip (return addr); LABEL_PC is 0 */
3267c478bd9Sstevel@tonic-gate	movl	$1, %eax
3277c478bd9Sstevel@tonic-gate	addl	$4, %esp		/* pop ret adr */
3287c478bd9Sstevel@tonic-gate	jmp	*%ecx			/* indirect */
3297c478bd9Sstevel@tonic-gate	SET_SIZE(longjmp)
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate#endif	/* __i386 */
3327c478bd9Sstevel@tonic-gate#endif	/* __lint */
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate/*
3357c478bd9Sstevel@tonic-gate * if a() calls b() calls caller(),
3367c478bd9Sstevel@tonic-gate * caller() returns return address in a().
3377c478bd9Sstevel@tonic-gate * (Note: We assume a() and b() are C routines which do the normal entry/exit
3387c478bd9Sstevel@tonic-gate *  sequence.)
3397c478bd9Sstevel@tonic-gate */
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate#if defined(__lint)
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gatecaddr_t
3447c478bd9Sstevel@tonic-gatecaller(void)
3457c478bd9Sstevel@tonic-gate{ return (0); }
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate#else	/* __lint */
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate#if defined(__amd64)
3507c478bd9Sstevel@tonic-gate
3517c478bd9Sstevel@tonic-gate	ENTRY(caller)
3527c478bd9Sstevel@tonic-gate	movq	8(%rbp), %rax		/* b()'s return pc, in a() */
3537c478bd9Sstevel@tonic-gate	ret
3547c478bd9Sstevel@tonic-gate	SET_SIZE(caller)
3557c478bd9Sstevel@tonic-gate
3567c478bd9Sstevel@tonic-gate#elif defined(__i386)
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate	ENTRY(caller)
3597c478bd9Sstevel@tonic-gate	movl	4(%ebp), %eax		/* b()'s return pc, in a() */
3607c478bd9Sstevel@tonic-gate	ret
3617c478bd9Sstevel@tonic-gate	SET_SIZE(caller)
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate#endif	/* __i386 */
3647c478bd9Sstevel@tonic-gate#endif	/* __lint */
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate/*
3677c478bd9Sstevel@tonic-gate * if a() calls callee(), callee() returns the
3687c478bd9Sstevel@tonic-gate * return address in a();
3697c478bd9Sstevel@tonic-gate */
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate#if defined(__lint)
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gatecaddr_t
3747c478bd9Sstevel@tonic-gatecallee(void)
3757c478bd9Sstevel@tonic-gate{ return (0); }
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate#else	/* __lint */
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate#if defined(__amd64)
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate	ENTRY(callee)
3827c478bd9Sstevel@tonic-gate	movq	(%rsp), %rax		/* callee()'s return pc, in a() */
3837c478bd9Sstevel@tonic-gate	ret
3847c478bd9Sstevel@tonic-gate	SET_SIZE(callee)
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate#elif defined(__i386)
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate	ENTRY(callee)
3897c478bd9Sstevel@tonic-gate	movl	(%esp), %eax		/* callee()'s return pc, in a() */
3907c478bd9Sstevel@tonic-gate	ret
3917c478bd9Sstevel@tonic-gate	SET_SIZE(callee)
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate#endif	/* __i386 */
3947c478bd9Sstevel@tonic-gate#endif	/* __lint */
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate/*
3977c478bd9Sstevel@tonic-gate * return the current frame pointer
3987c478bd9Sstevel@tonic-gate */
3997c478bd9Sstevel@tonic-gate
4007c478bd9Sstevel@tonic-gate#if defined(__lint)
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gategreg_t
4037c478bd9Sstevel@tonic-gategetfp(void)
4047c478bd9Sstevel@tonic-gate{ return (0); }
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate#else	/* __lint */
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate#if defined(__amd64)
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate	ENTRY(getfp)
4117c478bd9Sstevel@tonic-gate	movq	%rbp, %rax
4127c478bd9Sstevel@tonic-gate	ret
4137c478bd9Sstevel@tonic-gate	SET_SIZE(getfp)
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate#elif defined(__i386)
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate	ENTRY(getfp)
4187c478bd9Sstevel@tonic-gate	movl	%ebp, %eax
4197c478bd9Sstevel@tonic-gate	ret
4207c478bd9Sstevel@tonic-gate	SET_SIZE(getfp)
4217c478bd9Sstevel@tonic-gate
4227c478bd9Sstevel@tonic-gate#endif	/* __i386 */
4237c478bd9Sstevel@tonic-gate#endif	/* __lint */
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate/*
4267c478bd9Sstevel@tonic-gate * Invalidate a single page table entry in the TLB
4277c478bd9Sstevel@tonic-gate */
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate#if defined(__lint)
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate/* ARGSUSED */
4327c478bd9Sstevel@tonic-gatevoid
4337c478bd9Sstevel@tonic-gatemmu_tlbflush_entry(caddr_t m)
4347c478bd9Sstevel@tonic-gate{}
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate#else	/* __lint */
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate#if defined(__amd64)
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate	ENTRY(mmu_tlbflush_entry)
4417c478bd9Sstevel@tonic-gate	invlpg	(%rdi)
4427c478bd9Sstevel@tonic-gate	ret
4437c478bd9Sstevel@tonic-gate	SET_SIZE(mmu_tlbflush_entry)
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate#elif defined(__i386)
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate	ENTRY(mmu_tlbflush_entry)
4487c478bd9Sstevel@tonic-gate	movl	4(%esp), %eax
4497c478bd9Sstevel@tonic-gate	invlpg	(%eax)
4507c478bd9Sstevel@tonic-gate	ret
4517c478bd9Sstevel@tonic-gate	SET_SIZE(mmu_tlbflush_entry)
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate#endif	/* __i386 */
4547c478bd9Sstevel@tonic-gate#endif	/* __lint */
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate/*
4587c478bd9Sstevel@tonic-gate * Get/Set the value of various control registers
4597c478bd9Sstevel@tonic-gate */
4607c478bd9Sstevel@tonic-gate
4617c478bd9Sstevel@tonic-gate#if defined(__lint)
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gateulong_t
4647c478bd9Sstevel@tonic-gategetcr0(void)
4657c478bd9Sstevel@tonic-gate{ return (0); }
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate/* ARGSUSED */
4687c478bd9Sstevel@tonic-gatevoid
4697c478bd9Sstevel@tonic-gatesetcr0(ulong_t value)
4707c478bd9Sstevel@tonic-gate{}
4717c478bd9Sstevel@tonic-gate
4727c478bd9Sstevel@tonic-gateulong_t
4737c478bd9Sstevel@tonic-gategetcr2(void)
4747c478bd9Sstevel@tonic-gate{ return (0); }
4757c478bd9Sstevel@tonic-gate
4767c478bd9Sstevel@tonic-gateulong_t
4777c478bd9Sstevel@tonic-gategetcr3(void)
4787c478bd9Sstevel@tonic-gate{ return (0); }
4797c478bd9Sstevel@tonic-gate
480843e1988Sjohnlev#if !defined(__xpv)
4817c478bd9Sstevel@tonic-gate/* ARGSUSED */
4827c478bd9Sstevel@tonic-gatevoid
4837c478bd9Sstevel@tonic-gatesetcr3(ulong_t val)
4847c478bd9Sstevel@tonic-gate{}
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gatevoid
4877c478bd9Sstevel@tonic-gatereload_cr3(void)
4887c478bd9Sstevel@tonic-gate{}
489843e1988Sjohnlev#endif
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gateulong_t
4927c478bd9Sstevel@tonic-gategetcr4(void)
4937c478bd9Sstevel@tonic-gate{ return (0); }
4947c478bd9Sstevel@tonic-gate
4957c478bd9Sstevel@tonic-gate/* ARGSUSED */
4967c478bd9Sstevel@tonic-gatevoid
4977c478bd9Sstevel@tonic-gatesetcr4(ulong_t val)
4987c478bd9Sstevel@tonic-gate{}
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate#if defined(__amd64)
5017c478bd9Sstevel@tonic-gate
5027c478bd9Sstevel@tonic-gateulong_t
5037c478bd9Sstevel@tonic-gategetcr8(void)
5047c478bd9Sstevel@tonic-gate{ return (0); }
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate/* ARGSUSED */
5077c478bd9Sstevel@tonic-gatevoid
5087c478bd9Sstevel@tonic-gatesetcr8(ulong_t val)
5097c478bd9Sstevel@tonic-gate{}
5107c478bd9Sstevel@tonic-gate
5117c478bd9Sstevel@tonic-gate#endif	/* __amd64 */
5127c478bd9Sstevel@tonic-gate
5137c478bd9Sstevel@tonic-gate#else	/* __lint */
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate#if defined(__amd64)
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate	ENTRY(getcr0)
5187c478bd9Sstevel@tonic-gate	movq	%cr0, %rax
5197c478bd9Sstevel@tonic-gate	ret
5207c478bd9Sstevel@tonic-gate	SET_SIZE(getcr0)
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate	ENTRY(setcr0)
5237c478bd9Sstevel@tonic-gate	movq	%rdi, %cr0
5247c478bd9Sstevel@tonic-gate	ret
5257c478bd9Sstevel@tonic-gate	SET_SIZE(setcr0)
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate        ENTRY(getcr2)
528843e1988Sjohnlev#if defined(__xpv)
529843e1988Sjohnlev	movq	%gs:CPU_VCPU_INFO, %rax
530843e1988Sjohnlev	movq	VCPU_INFO_ARCH_CR2(%rax), %rax
531843e1988Sjohnlev#else
5327c478bd9Sstevel@tonic-gate        movq    %cr2, %rax
533843e1988Sjohnlev#endif
5347c478bd9Sstevel@tonic-gate        ret
5357c478bd9Sstevel@tonic-gate	SET_SIZE(getcr2)
5367c478bd9Sstevel@tonic-gate
5377c478bd9Sstevel@tonic-gate	ENTRY(getcr3)
5387c478bd9Sstevel@tonic-gate	movq    %cr3, %rax
5397c478bd9Sstevel@tonic-gate	ret
5407c478bd9Sstevel@tonic-gate	SET_SIZE(getcr3)
5417c478bd9Sstevel@tonic-gate
542843e1988Sjohnlev#if !defined(__xpv)
543843e1988Sjohnlev
5447c478bd9Sstevel@tonic-gate        ENTRY(setcr3)
5457c478bd9Sstevel@tonic-gate        movq    %rdi, %cr3
5467c478bd9Sstevel@tonic-gate        ret
5477c478bd9Sstevel@tonic-gate	SET_SIZE(setcr3)
5487c478bd9Sstevel@tonic-gate
5497c478bd9Sstevel@tonic-gate	ENTRY(reload_cr3)
5507c478bd9Sstevel@tonic-gate	movq	%cr3, %rdi
5517c478bd9Sstevel@tonic-gate	movq	%rdi, %cr3
5527c478bd9Sstevel@tonic-gate	ret
5537c478bd9Sstevel@tonic-gate	SET_SIZE(reload_cr3)
5547c478bd9Sstevel@tonic-gate
555843e1988Sjohnlev#endif	/* __xpv */
556843e1988Sjohnlev
5577c478bd9Sstevel@tonic-gate	ENTRY(getcr4)
5587c478bd9Sstevel@tonic-gate	movq	%cr4, %rax
5597c478bd9Sstevel@tonic-gate	ret
5607c478bd9Sstevel@tonic-gate	SET_SIZE(getcr4)
5617c478bd9Sstevel@tonic-gate
5627c478bd9Sstevel@tonic-gate	ENTRY(setcr4)
5637c478bd9Sstevel@tonic-gate	movq	%rdi, %cr4
5647c478bd9Sstevel@tonic-gate	ret
5657c478bd9Sstevel@tonic-gate	SET_SIZE(setcr4)
5667c478bd9Sstevel@tonic-gate
5677c478bd9Sstevel@tonic-gate	ENTRY(getcr8)
5687c478bd9Sstevel@tonic-gate	movq	%cr8, %rax
5697c478bd9Sstevel@tonic-gate	ret
5707c478bd9Sstevel@tonic-gate	SET_SIZE(getcr8)
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate	ENTRY(setcr8)
5737c478bd9Sstevel@tonic-gate	movq	%rdi, %cr8
5747c478bd9Sstevel@tonic-gate	ret
5757c478bd9Sstevel@tonic-gate	SET_SIZE(setcr8)
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate#elif defined(__i386)
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate        ENTRY(getcr0)
5807c478bd9Sstevel@tonic-gate        movl    %cr0, %eax
5817c478bd9Sstevel@tonic-gate        ret
5827c478bd9Sstevel@tonic-gate	SET_SIZE(getcr0)
5837c478bd9Sstevel@tonic-gate
5847c478bd9Sstevel@tonic-gate        ENTRY(setcr0)
5857c478bd9Sstevel@tonic-gate        movl    4(%esp), %eax
5867c478bd9Sstevel@tonic-gate        movl    %eax, %cr0
5877c478bd9Sstevel@tonic-gate        ret
5887c478bd9Sstevel@tonic-gate	SET_SIZE(setcr0)
5897c478bd9Sstevel@tonic-gate
5902ef50f01SJoe Bonasera	/*
5912ef50f01SJoe Bonasera	 * "lock mov %cr0" is used on processors which indicate it is
5922ef50f01SJoe Bonasera	 * supported via CPUID. Normally the 32 bit TPR is accessed via
5932ef50f01SJoe Bonasera	 * the local APIC.
5942ef50f01SJoe Bonasera	 */
5952ef50f01SJoe Bonasera	ENTRY(getcr8)
5962ef50f01SJoe Bonasera	lock
5972ef50f01SJoe Bonasera	movl	%cr0, %eax
5982ef50f01SJoe Bonasera	ret
5992ef50f01SJoe Bonasera	SET_SIZE(getcr8)
6002ef50f01SJoe Bonasera
6012ef50f01SJoe Bonasera	ENTRY(setcr8)
6022ef50f01SJoe Bonasera        movl    4(%esp), %eax
6032ef50f01SJoe Bonasera	lock
6042ef50f01SJoe Bonasera        movl    %eax, %cr0
6052ef50f01SJoe Bonasera	ret
6062ef50f01SJoe Bonasera	SET_SIZE(setcr8)
6072ef50f01SJoe Bonasera
6087c478bd9Sstevel@tonic-gate        ENTRY(getcr2)
609843e1988Sjohnlev#if defined(__xpv)
610843e1988Sjohnlev	movl	%gs:CPU_VCPU_INFO, %eax
611843e1988Sjohnlev	movl	VCPU_INFO_ARCH_CR2(%eax), %eax
612843e1988Sjohnlev#else
6137c478bd9Sstevel@tonic-gate        movl    %cr2, %eax
614843e1988Sjohnlev#endif
6157c478bd9Sstevel@tonic-gate        ret
6167c478bd9Sstevel@tonic-gate	SET_SIZE(getcr2)
6177c478bd9Sstevel@tonic-gate
6187c478bd9Sstevel@tonic-gate	ENTRY(getcr3)
6197c478bd9Sstevel@tonic-gate	movl    %cr3, %eax
6207c478bd9Sstevel@tonic-gate	ret
6217c478bd9Sstevel@tonic-gate	SET_SIZE(getcr3)
6227c478bd9Sstevel@tonic-gate
623843e1988Sjohnlev#if !defined(__xpv)
624843e1988Sjohnlev
6257c478bd9Sstevel@tonic-gate        ENTRY(setcr3)
6267c478bd9Sstevel@tonic-gate        movl    4(%esp), %eax
6277c478bd9Sstevel@tonic-gate        movl    %eax, %cr3
6287c478bd9Sstevel@tonic-gate        ret
6297c478bd9Sstevel@tonic-gate	SET_SIZE(setcr3)
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate	ENTRY(reload_cr3)
6327c478bd9Sstevel@tonic-gate	movl    %cr3, %eax
6337c478bd9Sstevel@tonic-gate	movl    %eax, %cr3
6347c478bd9Sstevel@tonic-gate	ret
6357c478bd9Sstevel@tonic-gate	SET_SIZE(reload_cr3)
6367c478bd9Sstevel@tonic-gate
637843e1988Sjohnlev#endif	/* __xpv */
638843e1988Sjohnlev
6397c478bd9Sstevel@tonic-gate	ENTRY(getcr4)
6407c478bd9Sstevel@tonic-gate	movl    %cr4, %eax
6417c478bd9Sstevel@tonic-gate	ret
6427c478bd9Sstevel@tonic-gate	SET_SIZE(getcr4)
6437c478bd9Sstevel@tonic-gate
6447c478bd9Sstevel@tonic-gate        ENTRY(setcr4)
6457c478bd9Sstevel@tonic-gate        movl    4(%esp), %eax
6467c478bd9Sstevel@tonic-gate        movl    %eax, %cr4
6477c478bd9Sstevel@tonic-gate        ret
6487c478bd9Sstevel@tonic-gate	SET_SIZE(setcr4)
6497c478bd9Sstevel@tonic-gate
6507c478bd9Sstevel@tonic-gate#endif	/* __i386 */
6517c478bd9Sstevel@tonic-gate#endif	/* __lint */
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate#if defined(__lint)
6547c478bd9Sstevel@tonic-gate
6557c478bd9Sstevel@tonic-gate/*ARGSUSED*/
6567c478bd9Sstevel@tonic-gateuint32_t
6578949bcd6Sandrei__cpuid_insn(struct cpuid_regs *regs)
6587c478bd9Sstevel@tonic-gate{ return (0); }
6597c478bd9Sstevel@tonic-gate
6607c478bd9Sstevel@tonic-gate#else	/* __lint */
6617c478bd9Sstevel@tonic-gate
6627c478bd9Sstevel@tonic-gate#if defined(__amd64)
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate	ENTRY(__cpuid_insn)
6658949bcd6Sandrei	movq	%rbx, %r8
6668949bcd6Sandrei	movq	%rcx, %r9
6678949bcd6Sandrei	movq	%rdx, %r11
6688949bcd6Sandrei	movl	(%rdi), %eax		/* %eax = regs->cp_eax */
6698949bcd6Sandrei	movl	0x4(%rdi), %ebx		/* %ebx = regs->cp_ebx */
6708949bcd6Sandrei	movl	0x8(%rdi), %ecx		/* %ecx = regs->cp_ecx */
6718949bcd6Sandrei	movl	0xc(%rdi), %edx		/* %edx = regs->cp_edx */
6727c478bd9Sstevel@tonic-gate	cpuid
6738949bcd6Sandrei	movl	%eax, (%rdi)		/* regs->cp_eax = %eax */
6748949bcd6Sandrei	movl	%ebx, 0x4(%rdi)		/* regs->cp_ebx = %ebx */
6758949bcd6Sandrei	movl	%ecx, 0x8(%rdi)		/* regs->cp_ecx = %ecx */
6768949bcd6Sandrei	movl	%edx, 0xc(%rdi)		/* regs->cp_edx = %edx */
6778949bcd6Sandrei	movq	%r8, %rbx
6788949bcd6Sandrei	movq	%r9, %rcx
6798949bcd6Sandrei	movq	%r11, %rdx
6807c478bd9Sstevel@tonic-gate	ret
6817c478bd9Sstevel@tonic-gate	SET_SIZE(__cpuid_insn)
6827c478bd9Sstevel@tonic-gate
6837c478bd9Sstevel@tonic-gate#elif defined(__i386)
6847c478bd9Sstevel@tonic-gate
6857c478bd9Sstevel@tonic-gate        ENTRY(__cpuid_insn)
6867c478bd9Sstevel@tonic-gate	pushl	%ebp
6878949bcd6Sandrei	movl	0x8(%esp), %ebp		/* %ebp = regs */
6887c478bd9Sstevel@tonic-gate	pushl	%ebx
6898949bcd6Sandrei	pushl	%ecx
6908949bcd6Sandrei	pushl	%edx
6918949bcd6Sandrei	movl	(%ebp), %eax		/* %eax = regs->cp_eax */
6928949bcd6Sandrei	movl	0x4(%ebp), %ebx		/* %ebx = regs->cp_ebx */
6938949bcd6Sandrei	movl	0x8(%ebp), %ecx		/* %ecx = regs->cp_ecx */
6948949bcd6Sandrei	movl	0xc(%ebp), %edx		/* %edx = regs->cp_edx */
6957c478bd9Sstevel@tonic-gate	cpuid
6968949bcd6Sandrei	movl	%eax, (%ebp)		/* regs->cp_eax = %eax */
6978949bcd6Sandrei	movl	%ebx, 0x4(%ebp)		/* regs->cp_ebx = %ebx */
6988949bcd6Sandrei	movl	%ecx, 0x8(%ebp)		/* regs->cp_ecx = %ecx */
6998949bcd6Sandrei	movl	%edx, 0xc(%ebp)		/* regs->cp_edx = %edx */
7008949bcd6Sandrei	popl	%edx
7018949bcd6Sandrei	popl	%ecx
7027c478bd9Sstevel@tonic-gate	popl	%ebx
7037c478bd9Sstevel@tonic-gate	popl	%ebp
7047c478bd9Sstevel@tonic-gate	ret
7057c478bd9Sstevel@tonic-gate	SET_SIZE(__cpuid_insn)
7067c478bd9Sstevel@tonic-gate
7077c478bd9Sstevel@tonic-gate#endif	/* __i386 */
7087c478bd9Sstevel@tonic-gate#endif	/* __lint */
7097c478bd9Sstevel@tonic-gate
710f98fbcecSbholler#if defined(__lint)
711f98fbcecSbholler
712f98fbcecSbholler/*ARGSUSED*/
713f98fbcecSbhollervoid
714f98fbcecSbholleri86_monitor(volatile uint32_t *addr, uint32_t extensions, uint32_t hints)
715f34a7178SJoe Bonasera{}
716f98fbcecSbholler
717f98fbcecSbholler#else   /* __lint */
718f98fbcecSbholler
719f98fbcecSbholler#if defined(__amd64)
720f98fbcecSbholler
721f98fbcecSbholler	ENTRY_NP(i86_monitor)
722f98fbcecSbholler	pushq	%rbp
723f98fbcecSbholler	movq	%rsp, %rbp
724f98fbcecSbholler	movq	%rdi, %rax		/* addr */
725f98fbcecSbholler	movq	%rsi, %rcx		/* extensions */
726f98fbcecSbholler	/* rdx contains input arg3: hints */
7271d1a3942SBill Holler	clflush	(%rax)
728f98fbcecSbholler	.byte	0x0f, 0x01, 0xc8	/* monitor */
729f98fbcecSbholler	leave
730f98fbcecSbholler	ret
731f98fbcecSbholler	SET_SIZE(i86_monitor)
732f98fbcecSbholler
733f98fbcecSbholler#elif defined(__i386)
734f98fbcecSbholler
735f98fbcecSbhollerENTRY_NP(i86_monitor)
736f98fbcecSbholler	pushl	%ebp
737f98fbcecSbholler	movl	%esp, %ebp
738e406c1a6Sbholler	movl	0x8(%ebp),%eax		/* addr */
739e406c1a6Sbholler	movl	0xc(%ebp),%ecx		/* extensions */
740e406c1a6Sbholler	movl	0x10(%ebp),%edx		/* hints */
7411d1a3942SBill Holler	clflush	(%eax)
742f98fbcecSbholler	.byte	0x0f, 0x01, 0xc8	/* monitor */
743f98fbcecSbholler	leave
744f98fbcecSbholler	ret
745f98fbcecSbholler	SET_SIZE(i86_monitor)
746f98fbcecSbholler
747f98fbcecSbholler#endif	/* __i386 */
748f98fbcecSbholler#endif	/* __lint */
749f98fbcecSbholler
750f98fbcecSbholler#if defined(__lint)
751f98fbcecSbholler
752f98fbcecSbholler/*ARGSUSED*/
753f98fbcecSbhollervoid
754f98fbcecSbholleri86_mwait(uint32_t data, uint32_t extensions)
755f34a7178SJoe Bonasera{}
756f98fbcecSbholler
757f98fbcecSbholler#else	/* __lint */
758f98fbcecSbholler
759f98fbcecSbholler#if defined(__amd64)
760f98fbcecSbholler
761f98fbcecSbholler	ENTRY_NP(i86_mwait)
762f98fbcecSbholler	pushq	%rbp
763f98fbcecSbholler	movq	%rsp, %rbp
764f98fbcecSbholler	movq	%rdi, %rax		/* data */
765f98fbcecSbholler	movq	%rsi, %rcx		/* extensions */
766f98fbcecSbholler	.byte	0x0f, 0x01, 0xc9	/* mwait */
767f98fbcecSbholler	leave
768f98fbcecSbholler	ret
769f98fbcecSbholler	SET_SIZE(i86_mwait)
770f98fbcecSbholler
771f98fbcecSbholler#elif defined(__i386)
772f98fbcecSbholler
773f98fbcecSbholler	ENTRY_NP(i86_mwait)
774f98fbcecSbholler	pushl	%ebp
775f98fbcecSbholler	movl	%esp, %ebp
776e406c1a6Sbholler	movl	0x8(%ebp),%eax		/* data */
777e406c1a6Sbholler	movl	0xc(%ebp),%ecx		/* extensions */
778f98fbcecSbholler	.byte	0x0f, 0x01, 0xc9	/* mwait */
779f98fbcecSbholler	leave
780f98fbcecSbholler	ret
781f98fbcecSbholler	SET_SIZE(i86_mwait)
782f98fbcecSbholler
783f98fbcecSbholler#endif	/* __i386 */
784f98fbcecSbholler#endif	/* __lint */
785ae115bc7Smrj
786f34a7178SJoe Bonasera#if defined(__xpv)
787f34a7178SJoe Bonasera	/*
788f34a7178SJoe Bonasera	 * Defined in C
789f34a7178SJoe Bonasera	 */
790f34a7178SJoe Bonasera#else
791f34a7178SJoe Bonasera
792ae115bc7Smrj#if defined(__lint)
793ae115bc7Smrj
794ae115bc7Smrjhrtime_t
795ae115bc7Smrjtsc_read(void)
796ae115bc7Smrj{
797ae115bc7Smrj	return (0);
798ae115bc7Smrj}
799ae115bc7Smrj
800ae115bc7Smrj#else	/* __lint */
801ae115bc7Smrj
802843e1988Sjohnlev#if defined(__amd64)
803843e1988Sjohnlev
804ae115bc7Smrj	ENTRY_NP(tsc_read)
805247dbb3dSsudheer	movq	%rbx, %r11
806247dbb3dSsudheer	movl	$0, %eax
807247dbb3dSsudheer	cpuid
808247dbb3dSsudheer	rdtsc
809247dbb3dSsudheer	movq	%r11, %rbx
810247dbb3dSsudheer	shlq	$32, %rdx
811247dbb3dSsudheer	orq	%rdx, %rax
812247dbb3dSsudheer	ret
813247dbb3dSsudheer	.globl _tsc_mfence_start
814247dbb3dSsudheer_tsc_mfence_start:
815247dbb3dSsudheer	mfence
816ae115bc7Smrj	rdtsc
817ae115bc7Smrj	shlq	$32, %rdx
818ae115bc7Smrj	orq	%rdx, %rax
819ae115bc7Smrj	ret
820247dbb3dSsudheer	.globl _tsc_mfence_end
821247dbb3dSsudheer_tsc_mfence_end:
822247dbb3dSsudheer	.globl _tscp_start
823247dbb3dSsudheer_tscp_start:
824247dbb3dSsudheer	.byte	0x0f, 0x01, 0xf9	/* rdtscp instruction */
825247dbb3dSsudheer	shlq	$32, %rdx
826247dbb3dSsudheer	orq	%rdx, %rax
827247dbb3dSsudheer	ret
828247dbb3dSsudheer	.globl _tscp_end
829247dbb3dSsudheer_tscp_end:
830247dbb3dSsudheer	.globl _no_rdtsc_start
831247dbb3dSsudheer_no_rdtsc_start:
832247dbb3dSsudheer	xorl	%edx, %edx
833247dbb3dSsudheer	xorl	%eax, %eax
834247dbb3dSsudheer	ret
835247dbb3dSsudheer	.globl _no_rdtsc_end
836247dbb3dSsudheer_no_rdtsc_end:
83715363b27Ssudheer	.globl _tsc_lfence_start
83815363b27Ssudheer_tsc_lfence_start:
83915363b27Ssudheer	lfence
84015363b27Ssudheer	rdtsc
84115363b27Ssudheer	shlq	$32, %rdx
84215363b27Ssudheer	orq	%rdx, %rax
84315363b27Ssudheer	ret
84415363b27Ssudheer	.globl _tsc_lfence_end
84515363b27Ssudheer_tsc_lfence_end:
846ae115bc7Smrj	SET_SIZE(tsc_read)
847ae115bc7Smrj
848843e1988Sjohnlev#else /* __i386 */
849843e1988Sjohnlev
850843e1988Sjohnlev	ENTRY_NP(tsc_read)
851247dbb3dSsudheer	pushl	%ebx
852247dbb3dSsudheer	movl	$0, %eax
853247dbb3dSsudheer	cpuid
854247dbb3dSsudheer	rdtsc
855247dbb3dSsudheer	popl	%ebx
856843e1988Sjohnlev	ret
857247dbb3dSsudheer	.globl _tsc_mfence_start
858247dbb3dSsudheer_tsc_mfence_start:
859247dbb3dSsudheer	mfence
860247dbb3dSsudheer	rdtsc
861247dbb3dSsudheer	ret
862247dbb3dSsudheer	.globl _tsc_mfence_end
863247dbb3dSsudheer_tsc_mfence_end:
864247dbb3dSsudheer	.globl	_tscp_start
865247dbb3dSsudheer_tscp_start:
866247dbb3dSsudheer	.byte	0x0f, 0x01, 0xf9	/* rdtscp instruction */
867247dbb3dSsudheer	ret
868247dbb3dSsudheer	.globl _tscp_end
869247dbb3dSsudheer_tscp_end:
870247dbb3dSsudheer	.globl _no_rdtsc_start
871247dbb3dSsudheer_no_rdtsc_start:
872247dbb3dSsudheer	xorl	%edx, %edx
873247dbb3dSsudheer	xorl	%eax, %eax
874247dbb3dSsudheer	ret
875247dbb3dSsudheer	.globl _no_rdtsc_end
876247dbb3dSsudheer_no_rdtsc_end:
87715363b27Ssudheer	.globl _tsc_lfence_start
87815363b27Ssudheer_tsc_lfence_start:
87915363b27Ssudheer	lfence
88015363b27Ssudheer	rdtsc
88115363b27Ssudheer	ret
88215363b27Ssudheer	.globl _tsc_lfence_end
88315363b27Ssudheer_tsc_lfence_end:
884843e1988Sjohnlev	SET_SIZE(tsc_read)
885843e1988Sjohnlev
886843e1988Sjohnlev#endif	/* __i386 */
887843e1988Sjohnlev
888ae115bc7Smrj#endif	/* __lint */
889ae115bc7Smrj
89006fb6a36Sdv142724
891843e1988Sjohnlev#endif	/* __xpv */
892843e1988Sjohnlev
89306fb6a36Sdv142724#ifdef __lint
89406fb6a36Sdv142724/*
89506fb6a36Sdv142724 * Do not use this function for obtaining clock tick.  This
89606fb6a36Sdv142724 * is called by callers who do not need to have a guarenteed
89706fb6a36Sdv142724 * correct tick value.  The proper routine to use is tsc_read().
89806fb6a36Sdv142724 */
899b52a336eSPavel Tatashinu_longlong_t
90006fb6a36Sdv142724randtick(void)
90106fb6a36Sdv142724{
90206fb6a36Sdv142724	return (0);
90306fb6a36Sdv142724}
90406fb6a36Sdv142724#else
90506fb6a36Sdv142724#if defined(__amd64)
90606fb6a36Sdv142724	ENTRY_NP(randtick)
90706fb6a36Sdv142724	rdtsc
90806fb6a36Sdv142724	shlq    $32, %rdx
90906fb6a36Sdv142724	orq     %rdx, %rax
91006fb6a36Sdv142724	ret
91106fb6a36Sdv142724	SET_SIZE(randtick)
91206fb6a36Sdv142724#else
91306fb6a36Sdv142724	ENTRY_NP(randtick)
91406fb6a36Sdv142724	rdtsc
91506fb6a36Sdv142724	ret
91606fb6a36Sdv142724	SET_SIZE(randtick)
91706fb6a36Sdv142724#endif /* __i386 */
91806fb6a36Sdv142724#endif /* __lint */
9197c478bd9Sstevel@tonic-gate/*
9207c478bd9Sstevel@tonic-gate * Insert entryp after predp in a doubly linked list.
9217c478bd9Sstevel@tonic-gate */
9227c478bd9Sstevel@tonic-gate
9237c478bd9Sstevel@tonic-gate#if defined(__lint)
9247c478bd9Sstevel@tonic-gate
9257c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9267c478bd9Sstevel@tonic-gatevoid
9277c478bd9Sstevel@tonic-gate_insque(caddr_t entryp, caddr_t predp)
9287c478bd9Sstevel@tonic-gate{}
9297c478bd9Sstevel@tonic-gate
9307c478bd9Sstevel@tonic-gate#else	/* __lint */
9317c478bd9Sstevel@tonic-gate
9327c478bd9Sstevel@tonic-gate#if defined(__amd64)
9337c478bd9Sstevel@tonic-gate
9347c478bd9Sstevel@tonic-gate	ENTRY(_insque)
9357c478bd9Sstevel@tonic-gate	movq	(%rsi), %rax		/* predp->forw			*/
9367c478bd9Sstevel@tonic-gate	movq	%rsi, CPTRSIZE(%rdi)	/* entryp->back = predp		*/
9377c478bd9Sstevel@tonic-gate	movq	%rax, (%rdi)		/* entryp->forw = predp->forw	*/
9387c478bd9Sstevel@tonic-gate	movq	%rdi, (%rsi)		/* predp->forw = entryp		*/
9397c478bd9Sstevel@tonic-gate	movq	%rdi, CPTRSIZE(%rax)	/* predp->forw->back = entryp	*/
9407c478bd9Sstevel@tonic-gate	ret
9417c478bd9Sstevel@tonic-gate	SET_SIZE(_insque)
9427c478bd9Sstevel@tonic-gate
9437c478bd9Sstevel@tonic-gate#elif defined(__i386)
9447c478bd9Sstevel@tonic-gate
9457c478bd9Sstevel@tonic-gate	ENTRY(_insque)
9467c478bd9Sstevel@tonic-gate	movl	8(%esp), %edx
9477c478bd9Sstevel@tonic-gate	movl	4(%esp), %ecx
9487c478bd9Sstevel@tonic-gate	movl	(%edx), %eax		/* predp->forw			*/
9497c478bd9Sstevel@tonic-gate	movl	%edx, CPTRSIZE(%ecx)	/* entryp->back = predp		*/
9507c478bd9Sstevel@tonic-gate	movl	%eax, (%ecx)		/* entryp->forw = predp->forw	*/
9517c478bd9Sstevel@tonic-gate	movl	%ecx, (%edx)		/* predp->forw = entryp		*/
9527c478bd9Sstevel@tonic-gate	movl	%ecx, CPTRSIZE(%eax)	/* predp->forw->back = entryp	*/
9537c478bd9Sstevel@tonic-gate	ret
9547c478bd9Sstevel@tonic-gate	SET_SIZE(_insque)
9557c478bd9Sstevel@tonic-gate
9567c478bd9Sstevel@tonic-gate#endif	/* __i386 */
9577c478bd9Sstevel@tonic-gate#endif	/* __lint */
9587c478bd9Sstevel@tonic-gate
9597c478bd9Sstevel@tonic-gate/*
9607c478bd9Sstevel@tonic-gate * Remove entryp from a doubly linked list
9617c478bd9Sstevel@tonic-gate */
9627c478bd9Sstevel@tonic-gate
9637c478bd9Sstevel@tonic-gate#if defined(__lint)
9647c478bd9Sstevel@tonic-gate
9657c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9667c478bd9Sstevel@tonic-gatevoid
9677c478bd9Sstevel@tonic-gate_remque(caddr_t entryp)
9687c478bd9Sstevel@tonic-gate{}
9697c478bd9Sstevel@tonic-gate
9707c478bd9Sstevel@tonic-gate#else	/* __lint */
9717c478bd9Sstevel@tonic-gate
9727c478bd9Sstevel@tonic-gate#if defined(__amd64)
9737c478bd9Sstevel@tonic-gate
9747c478bd9Sstevel@tonic-gate	ENTRY(_remque)
9757c478bd9Sstevel@tonic-gate	movq	(%rdi), %rax		/* entry->forw */
9767c478bd9Sstevel@tonic-gate	movq	CPTRSIZE(%rdi), %rdx	/* entry->back */
9777c478bd9Sstevel@tonic-gate	movq	%rax, (%rdx)		/* entry->back->forw = entry->forw */
9787c478bd9Sstevel@tonic-gate	movq	%rdx, CPTRSIZE(%rax)	/* entry->forw->back = entry->back */
9797c478bd9Sstevel@tonic-gate	ret
9807c478bd9Sstevel@tonic-gate	SET_SIZE(_remque)
9817c478bd9Sstevel@tonic-gate
9827c478bd9Sstevel@tonic-gate#elif defined(__i386)
9837c478bd9Sstevel@tonic-gate
9847c478bd9Sstevel@tonic-gate	ENTRY(_remque)
9857c478bd9Sstevel@tonic-gate	movl	4(%esp), %ecx
9867c478bd9Sstevel@tonic-gate	movl	(%ecx), %eax		/* entry->forw */
9877c478bd9Sstevel@tonic-gate	movl	CPTRSIZE(%ecx), %edx	/* entry->back */
9887c478bd9Sstevel@tonic-gate	movl	%eax, (%edx)		/* entry->back->forw = entry->forw */
9897c478bd9Sstevel@tonic-gate	movl	%edx, CPTRSIZE(%eax)	/* entry->forw->back = entry->back */
9907c478bd9Sstevel@tonic-gate	ret
9917c478bd9Sstevel@tonic-gate	SET_SIZE(_remque)
9927c478bd9Sstevel@tonic-gate
9937c478bd9Sstevel@tonic-gate#endif	/* __i386 */
9947c478bd9Sstevel@tonic-gate#endif	/* __lint */
9957c478bd9Sstevel@tonic-gate
9967c478bd9Sstevel@tonic-gate/*
9977c478bd9Sstevel@tonic-gate * Returns the number of
9987c478bd9Sstevel@tonic-gate * non-NULL bytes in string argument.
9997c478bd9Sstevel@tonic-gate */
10007c478bd9Sstevel@tonic-gate
10017c478bd9Sstevel@tonic-gate#if defined(__lint)
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate/* ARGSUSED */
10047c478bd9Sstevel@tonic-gatesize_t
10057c478bd9Sstevel@tonic-gatestrlen(const char *str)
10067c478bd9Sstevel@tonic-gate{ return (0); }
10077c478bd9Sstevel@tonic-gate
10087c478bd9Sstevel@tonic-gate#else	/* __lint */
10097c478bd9Sstevel@tonic-gate
10107c478bd9Sstevel@tonic-gate#if defined(__amd64)
10117c478bd9Sstevel@tonic-gate
10127c478bd9Sstevel@tonic-gate/*
10137c478bd9Sstevel@tonic-gate * This is close to a simple transliteration of a C version of this
10147c478bd9Sstevel@tonic-gate * routine.  We should either just -make- this be a C version, or
10157c478bd9Sstevel@tonic-gate * justify having it in assembler by making it significantly faster.
10167c478bd9Sstevel@tonic-gate *
10177c478bd9Sstevel@tonic-gate * size_t
10187c478bd9Sstevel@tonic-gate * strlen(const char *s)
10197c478bd9Sstevel@tonic-gate * {
10207c478bd9Sstevel@tonic-gate *	const char *s0;
10217c478bd9Sstevel@tonic-gate * #if defined(DEBUG)
10227c478bd9Sstevel@tonic-gate *	if ((uintptr_t)s < KERNELBASE)
10237c478bd9Sstevel@tonic-gate *		panic(.str_panic_msg);
10247c478bd9Sstevel@tonic-gate * #endif
10257c478bd9Sstevel@tonic-gate *	for (s0 = s; *s; s++)
10267c478bd9Sstevel@tonic-gate *		;
10277c478bd9Sstevel@tonic-gate *	return (s - s0);
10287c478bd9Sstevel@tonic-gate * }
10297c478bd9Sstevel@tonic-gate */
10307c478bd9Sstevel@tonic-gate
10317c478bd9Sstevel@tonic-gate	ENTRY(strlen)
10327c478bd9Sstevel@tonic-gate#ifdef DEBUG
1033ae115bc7Smrj	movq	postbootkernelbase(%rip), %rax
10347c478bd9Sstevel@tonic-gate	cmpq	%rax, %rdi
10357c478bd9Sstevel@tonic-gate	jae	str_valid
10367c478bd9Sstevel@tonic-gate	pushq	%rbp
10377c478bd9Sstevel@tonic-gate	movq	%rsp, %rbp
10387c478bd9Sstevel@tonic-gate	leaq	.str_panic_msg(%rip), %rdi
10397c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
10407c478bd9Sstevel@tonic-gate	call	panic
10417c478bd9Sstevel@tonic-gate#endif	/* DEBUG */
10427c478bd9Sstevel@tonic-gatestr_valid:
10437c478bd9Sstevel@tonic-gate	cmpb	$0, (%rdi)
10447c478bd9Sstevel@tonic-gate	movq	%rdi, %rax
10457c478bd9Sstevel@tonic-gate	je	.null_found
10467c478bd9Sstevel@tonic-gate	.align	4
10477c478bd9Sstevel@tonic-gate.strlen_loop:
10487c478bd9Sstevel@tonic-gate	incq	%rdi
10497c478bd9Sstevel@tonic-gate	cmpb	$0, (%rdi)
10507c478bd9Sstevel@tonic-gate	jne	.strlen_loop
10517c478bd9Sstevel@tonic-gate.null_found:
10527c478bd9Sstevel@tonic-gate	subq	%rax, %rdi
10537c478bd9Sstevel@tonic-gate	movq	%rdi, %rax
10547c478bd9Sstevel@tonic-gate	ret
10557c478bd9Sstevel@tonic-gate	SET_SIZE(strlen)
10567c478bd9Sstevel@tonic-gate
10577c478bd9Sstevel@tonic-gate#elif defined(__i386)
10587c478bd9Sstevel@tonic-gate
10597c478bd9Sstevel@tonic-gate	ENTRY(strlen)
10607c478bd9Sstevel@tonic-gate#ifdef DEBUG
1061ae115bc7Smrj	movl	postbootkernelbase, %eax
10627c478bd9Sstevel@tonic-gate	cmpl	%eax, 4(%esp)
10637c478bd9Sstevel@tonic-gate	jae	str_valid
10647c478bd9Sstevel@tonic-gate	pushl	%ebp
10657c478bd9Sstevel@tonic-gate	movl	%esp, %ebp
10667c478bd9Sstevel@tonic-gate	pushl	$.str_panic_msg
10677c478bd9Sstevel@tonic-gate	call	panic
10687c478bd9Sstevel@tonic-gate#endif /* DEBUG */
10697c478bd9Sstevel@tonic-gate
10707c478bd9Sstevel@tonic-gatestr_valid:
10717c478bd9Sstevel@tonic-gate	movl	4(%esp), %eax		/* %eax = string address */
10727c478bd9Sstevel@tonic-gate	testl	$3, %eax		/* if %eax not word aligned */
10737c478bd9Sstevel@tonic-gate	jnz	.not_word_aligned	/* goto .not_word_aligned */
10747c478bd9Sstevel@tonic-gate	.align	4
10757c478bd9Sstevel@tonic-gate.word_aligned:
10767c478bd9Sstevel@tonic-gate	movl	(%eax), %edx		/* move 1 word from (%eax) to %edx */
10777c478bd9Sstevel@tonic-gate	movl	$0x7f7f7f7f, %ecx
10787c478bd9Sstevel@tonic-gate	andl	%edx, %ecx		/* %ecx = %edx & 0x7f7f7f7f */
10797c478bd9Sstevel@tonic-gate	addl	$4, %eax		/* next word */
10807c478bd9Sstevel@tonic-gate	addl	$0x7f7f7f7f, %ecx	/* %ecx += 0x7f7f7f7f */
10817c478bd9Sstevel@tonic-gate	orl	%edx, %ecx		/* %ecx |= %edx */
10827c478bd9Sstevel@tonic-gate	andl	$0x80808080, %ecx	/* %ecx &= 0x80808080 */
10837c478bd9Sstevel@tonic-gate	cmpl	$0x80808080, %ecx	/* if no null byte in this word */
10847c478bd9Sstevel@tonic-gate	je	.word_aligned		/* goto .word_aligned */
10857c478bd9Sstevel@tonic-gate	subl	$4, %eax		/* post-incremented */
10867c478bd9Sstevel@tonic-gate.not_word_aligned:
10877c478bd9Sstevel@tonic-gate	cmpb	$0, (%eax)		/* if a byte in (%eax) is null */
10887c478bd9Sstevel@tonic-gate	je	.null_found		/* goto .null_found */
10897c478bd9Sstevel@tonic-gate	incl	%eax			/* next byte */
10907c478bd9Sstevel@tonic-gate	testl	$3, %eax		/* if %eax not word aligned */
10917c478bd9Sstevel@tonic-gate	jnz	.not_word_aligned	/* goto .not_word_aligned */
10927c478bd9Sstevel@tonic-gate	jmp	.word_aligned		/* goto .word_aligned */
10937c478bd9Sstevel@tonic-gate	.align	4
10947c478bd9Sstevel@tonic-gate.null_found:
10957c478bd9Sstevel@tonic-gate	subl	4(%esp), %eax		/* %eax -= string address */
10967c478bd9Sstevel@tonic-gate	ret
10977c478bd9Sstevel@tonic-gate	SET_SIZE(strlen)
10987c478bd9Sstevel@tonic-gate
10997c478bd9Sstevel@tonic-gate#endif	/* __i386 */
11007c478bd9Sstevel@tonic-gate
11017c478bd9Sstevel@tonic-gate#ifdef DEBUG
11027c478bd9Sstevel@tonic-gate	.text
11037c478bd9Sstevel@tonic-gate.str_panic_msg:
11047c478bd9Sstevel@tonic-gate	.string "strlen: argument below kernelbase"
11057c478bd9Sstevel@tonic-gate#endif /* DEBUG */
11067c478bd9Sstevel@tonic-gate
11077c478bd9Sstevel@tonic-gate#endif	/* __lint */
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate	/*
11104b56a003SDaniel Anderson	 * Berkeley 4.3 introduced symbolically named interrupt levels
11117c478bd9Sstevel@tonic-gate	 * as a way deal with priority in a machine independent fashion.
11127c478bd9Sstevel@tonic-gate	 * Numbered priorities are machine specific, and should be
11137c478bd9Sstevel@tonic-gate	 * discouraged where possible.
11147c478bd9Sstevel@tonic-gate	 *
11157c478bd9Sstevel@tonic-gate	 * Note, for the machine specific priorities there are
11167c478bd9Sstevel@tonic-gate	 * examples listed for devices that use a particular priority.
11177c478bd9Sstevel@tonic-gate	 * It should not be construed that all devices of that
11187c478bd9Sstevel@tonic-gate	 * type should be at that priority.  It is currently were
11197c478bd9Sstevel@tonic-gate	 * the current devices fit into the priority scheme based
11207c478bd9Sstevel@tonic-gate	 * upon time criticalness.
11217c478bd9Sstevel@tonic-gate	 *
11227c478bd9Sstevel@tonic-gate	 * The underlying assumption of these assignments is that
11237c478bd9Sstevel@tonic-gate	 * IPL 10 is the highest level from which a device
11247c478bd9Sstevel@tonic-gate	 * routine can call wakeup.  Devices that interrupt from higher
11257c478bd9Sstevel@tonic-gate	 * levels are restricted in what they can do.  If they need
11267c478bd9Sstevel@tonic-gate	 * kernels services they should schedule a routine at a lower
11277c478bd9Sstevel@tonic-gate	 * level (via software interrupt) to do the required
11287c478bd9Sstevel@tonic-gate	 * processing.
11297c478bd9Sstevel@tonic-gate	 *
11307c478bd9Sstevel@tonic-gate	 * Examples of this higher usage:
11317c478bd9Sstevel@tonic-gate	 *	Level	Usage
11327c478bd9Sstevel@tonic-gate	 *	14	Profiling clock (and PROM uart polling clock)
11337c478bd9Sstevel@tonic-gate	 *	12	Serial ports
11347c478bd9Sstevel@tonic-gate	 *
11357c478bd9Sstevel@tonic-gate	 * The serial ports request lower level processing on level 6.
11367c478bd9Sstevel@tonic-gate	 *
11377c478bd9Sstevel@tonic-gate	 * Also, almost all splN routines (where N is a number or a
11387c478bd9Sstevel@tonic-gate	 * mnemonic) will do a RAISE(), on the assumption that they are
11397c478bd9Sstevel@tonic-gate	 * never used to lower our priority.
11407c478bd9Sstevel@tonic-gate	 * The exceptions are:
11417c478bd9Sstevel@tonic-gate	 *	spl8()		Because you can't be above 15 to begin with!
11427c478bd9Sstevel@tonic-gate	 *	splzs()		Because this is used at boot time to lower our
11437c478bd9Sstevel@tonic-gate	 *			priority, to allow the PROM to poll the uart.
11447c478bd9Sstevel@tonic-gate	 *	spl0()		Used to lower priority to 0.
11457c478bd9Sstevel@tonic-gate	 */
11467c478bd9Sstevel@tonic-gate
11477c478bd9Sstevel@tonic-gate#if defined(__lint)
11487c478bd9Sstevel@tonic-gate
11497c478bd9Sstevel@tonic-gateint spl0(void)		{ return (0); }
11507c478bd9Sstevel@tonic-gateint spl6(void)		{ return (0); }
11517c478bd9Sstevel@tonic-gateint spl7(void)		{ return (0); }
11527c478bd9Sstevel@tonic-gateint spl8(void)		{ return (0); }
11537c478bd9Sstevel@tonic-gateint splhigh(void)	{ return (0); }
11547c478bd9Sstevel@tonic-gateint splhi(void)		{ return (0); }
11557c478bd9Sstevel@tonic-gateint splzs(void)		{ return (0); }
11567c478bd9Sstevel@tonic-gate
1157ae115bc7Smrj/* ARGSUSED */
1158ae115bc7Smrjvoid
1159ae115bc7Smrjsplx(int level)
1160ae115bc7Smrj{}
1161ae115bc7Smrj
11627c478bd9Sstevel@tonic-gate#else	/* __lint */
11637c478bd9Sstevel@tonic-gate
11647c478bd9Sstevel@tonic-gate#if defined(__amd64)
11657c478bd9Sstevel@tonic-gate
11667c478bd9Sstevel@tonic-gate#define	SETPRI(level) \
1167ae115bc7Smrj	movl	$/**/level, %edi;	/* new priority */		\
1168ae115bc7Smrj	jmp	do_splx			/* redirect to do_splx */
1169ae115bc7Smrj
1170ae115bc7Smrj#define	RAISE(level) \
1171ae115bc7Smrj	movl	$/**/level, %edi;	/* new priority */		\
1172ae115bc7Smrj	jmp	splr			/* redirect to splr */
11737c478bd9Sstevel@tonic-gate
11747c478bd9Sstevel@tonic-gate#elif defined(__i386)
11757c478bd9Sstevel@tonic-gate
11767c478bd9Sstevel@tonic-gate#define	SETPRI(level) \
1177ae115bc7Smrj	pushl	$/**/level;	/* new priority */			\
1178ae115bc7Smrj	call	do_splx;	/* invoke common splx code */		\
1179ae115bc7Smrj	addl	$4, %esp;	/* unstack arg */			\
1180ae115bc7Smrj	ret
1181ae115bc7Smrj
1182ae115bc7Smrj#define	RAISE(level) \
1183ae115bc7Smrj	pushl	$/**/level;	/* new priority */			\
1184ae115bc7Smrj	call	splr;		/* invoke common splr code */		\
1185ae115bc7Smrj	addl	$4, %esp;	/* unstack args */			\
1186ae115bc7Smrj	ret
11877c478bd9Sstevel@tonic-gate
11887c478bd9Sstevel@tonic-gate#endif	/* __i386 */
11897c478bd9Sstevel@tonic-gate
11907c478bd9Sstevel@tonic-gate	/* locks out all interrupts, including memory errors */
11917c478bd9Sstevel@tonic-gate	ENTRY(spl8)
11927c478bd9Sstevel@tonic-gate	SETPRI(15)
11937c478bd9Sstevel@tonic-gate	SET_SIZE(spl8)
11947c478bd9Sstevel@tonic-gate
11957c478bd9Sstevel@tonic-gate	/* just below the level that profiling runs */
11967c478bd9Sstevel@tonic-gate	ENTRY(spl7)
11977c478bd9Sstevel@tonic-gate	RAISE(13)
11987c478bd9Sstevel@tonic-gate	SET_SIZE(spl7)
11997c478bd9Sstevel@tonic-gate
12007c478bd9Sstevel@tonic-gate	/* sun specific - highest priority onboard serial i/o asy ports */
12017c478bd9Sstevel@tonic-gate	ENTRY(splzs)
12027c478bd9Sstevel@tonic-gate	SETPRI(12)	/* Can't be a RAISE, as it's used to lower us */
12037c478bd9Sstevel@tonic-gate	SET_SIZE(splzs)
12047c478bd9Sstevel@tonic-gate
12057c478bd9Sstevel@tonic-gate	ENTRY(splhi)
12067c478bd9Sstevel@tonic-gate	ALTENTRY(splhigh)
12077c478bd9Sstevel@tonic-gate	ALTENTRY(spl6)
12087c478bd9Sstevel@tonic-gate	ALTENTRY(i_ddi_splhigh)
12097c478bd9Sstevel@tonic-gate
1210ae115bc7Smrj	RAISE(DISP_LEVEL)
12117c478bd9Sstevel@tonic-gate
12127c478bd9Sstevel@tonic-gate	SET_SIZE(i_ddi_splhigh)
12137c478bd9Sstevel@tonic-gate	SET_SIZE(spl6)
12147c478bd9Sstevel@tonic-gate	SET_SIZE(splhigh)
12157c478bd9Sstevel@tonic-gate	SET_SIZE(splhi)
12167c478bd9Sstevel@tonic-gate
12177c478bd9Sstevel@tonic-gate	/* allow all interrupts */
12187c478bd9Sstevel@tonic-gate	ENTRY(spl0)
12197c478bd9Sstevel@tonic-gate	SETPRI(0)
12207c478bd9Sstevel@tonic-gate	SET_SIZE(spl0)
12217c478bd9Sstevel@tonic-gate
12227c478bd9Sstevel@tonic-gate
12234b56a003SDaniel Anderson	/* splx implementation */
12247c478bd9Sstevel@tonic-gate	ENTRY(splx)
1225ae115bc7Smrj	jmp	do_splx		/* redirect to common splx code */
12267c478bd9Sstevel@tonic-gate	SET_SIZE(splx)
12277c478bd9Sstevel@tonic-gate
12287c478bd9Sstevel@tonic-gate#endif	/* __lint */
12297c478bd9Sstevel@tonic-gate
12307c478bd9Sstevel@tonic-gate#if defined(__i386)
12317c478bd9Sstevel@tonic-gate
12327c478bd9Sstevel@tonic-gate/*
12337c478bd9Sstevel@tonic-gate * Read and write the %gs register
12347c478bd9Sstevel@tonic-gate */
12357c478bd9Sstevel@tonic-gate
12367c478bd9Sstevel@tonic-gate#if defined(__lint)
12377c478bd9Sstevel@tonic-gate
12387c478bd9Sstevel@tonic-gate/*ARGSUSED*/
12397c478bd9Sstevel@tonic-gateuint16_t
12407c478bd9Sstevel@tonic-gategetgs(void)
12417c478bd9Sstevel@tonic-gate{ return (0); }
12427c478bd9Sstevel@tonic-gate
12437c478bd9Sstevel@tonic-gate/*ARGSUSED*/
12447c478bd9Sstevel@tonic-gatevoid
12457c478bd9Sstevel@tonic-gatesetgs(uint16_t sel)
12467c478bd9Sstevel@tonic-gate{}
12477c478bd9Sstevel@tonic-gate
12487c478bd9Sstevel@tonic-gate#else	/* __lint */
12497c478bd9Sstevel@tonic-gate
12507c478bd9Sstevel@tonic-gate	ENTRY(getgs)
12517c478bd9Sstevel@tonic-gate	clr	%eax
12527c478bd9Sstevel@tonic-gate	movw	%gs, %ax
12537c478bd9Sstevel@tonic-gate	ret
12547c478bd9Sstevel@tonic-gate	SET_SIZE(getgs)
12557c478bd9Sstevel@tonic-gate
12567c478bd9Sstevel@tonic-gate	ENTRY(setgs)
12577c478bd9Sstevel@tonic-gate	movw	4(%esp), %gs
12587c478bd9Sstevel@tonic-gate	ret
12597c478bd9Sstevel@tonic-gate	SET_SIZE(setgs)
12607c478bd9Sstevel@tonic-gate
12617c478bd9Sstevel@tonic-gate#endif	/* __lint */
12627c478bd9Sstevel@tonic-gate#endif	/* __i386 */
12637c478bd9Sstevel@tonic-gate
12647c478bd9Sstevel@tonic-gate#if defined(__lint)
12657c478bd9Sstevel@tonic-gate
12667c478bd9Sstevel@tonic-gatevoid
12677c478bd9Sstevel@tonic-gatepc_reset(void)
12687c478bd9Sstevel@tonic-gate{}
12697c478bd9Sstevel@tonic-gate
1270f2be5148Sszhouvoid
1271f2be5148Sszhouefi_reset(void)
1272f2be5148Sszhou{}
1273f2be5148Sszhou
12747c478bd9Sstevel@tonic-gate#else	/* __lint */
12757c478bd9Sstevel@tonic-gate
1276085f98c4Ssethg	ENTRY(wait_500ms)
12771b30f017Sgvasick#if defined(__amd64)
12781b30f017Sgvasick	pushq	%rbx
12791b30f017Sgvasick#elif defined(__i386)
128032206069Ssethg	push	%ebx
12811b30f017Sgvasick#endif
128232206069Ssethg	movl	$50000, %ebx
1283085f98c4Ssethg1:
1284085f98c4Ssethg	call	tenmicrosec
128532206069Ssethg	decl	%ebx
128632206069Ssethg	jnz	1b
12871b30f017Sgvasick#if defined(__amd64)
12881b30f017Sgvasick	popq	%rbx
12891b30f017Sgvasick#elif defined(__i386)
129032206069Ssethg	pop	%ebx
12911b30f017Sgvasick#endif
1292085f98c4Ssethg	ret
1293085f98c4Ssethg	SET_SIZE(wait_500ms)
1294085f98c4Ssethg
1295085f98c4Ssethg#define	RESET_METHOD_KBC	1
1296085f98c4Ssethg#define	RESET_METHOD_PORT92	2
1297085f98c4Ssethg#define RESET_METHOD_PCI	4
1298085f98c4Ssethg
1299085f98c4Ssethg	DGDEF3(pc_reset_methods, 4, 8)
1300085f98c4Ssethg	.long RESET_METHOD_KBC|RESET_METHOD_PORT92|RESET_METHOD_PCI;
1301085f98c4Ssethg
13027c478bd9Sstevel@tonic-gate	ENTRY(pc_reset)
1303085f98c4Ssethg
130432206069Ssethg#if defined(__i386)
1305085f98c4Ssethg	testl	$RESET_METHOD_KBC, pc_reset_methods
130632206069Ssethg#elif defined(__amd64)
130732206069Ssethg	testl	$RESET_METHOD_KBC, pc_reset_methods(%rip)
130832206069Ssethg#endif
1309085f98c4Ssethg	jz	1f
1310085f98c4Ssethg
13117303b3c3Ssethg	/
13127303b3c3Ssethg	/ Try the classic keyboard controller-triggered reset.
13137303b3c3Ssethg	/
13147c478bd9Sstevel@tonic-gate	movw	$0x64, %dx
13157c478bd9Sstevel@tonic-gate	movb	$0xfe, %al
13167c478bd9Sstevel@tonic-gate	outb	(%dx)
13177303b3c3Ssethg
1318085f98c4Ssethg	/ Wait up to 500 milliseconds here for the keyboard controller
1319085f98c4Ssethg	/ to pull the reset line.  On some systems where the keyboard
1320085f98c4Ssethg	/ controller is slow to pull the reset line, the next reset method
1321085f98c4Ssethg	/ may be executed (which may be bad if those systems hang when the
1322085f98c4Ssethg	/ next reset method is used, e.g. Ferrari 3400 (doesn't like port 92),
1323085f98c4Ssethg	/ and Ferrari 4000 (doesn't like the cf9 reset method))
1324085f98c4Ssethg
1325085f98c4Ssethg	call	wait_500ms
1326085f98c4Ssethg
1327085f98c4Ssethg1:
132832206069Ssethg#if defined(__i386)
1329085f98c4Ssethg	testl	$RESET_METHOD_PORT92, pc_reset_methods
133032206069Ssethg#elif defined(__amd64)
133132206069Ssethg	testl	$RESET_METHOD_PORT92, pc_reset_methods(%rip)
133232206069Ssethg#endif
1333085f98c4Ssethg	jz	3f
1334085f98c4Ssethg
13357303b3c3Ssethg	/
13367303b3c3Ssethg	/ Try port 0x92 fast reset
13377303b3c3Ssethg	/
13387303b3c3Ssethg	movw	$0x92, %dx
13397303b3c3Ssethg	inb	(%dx)
13407303b3c3Ssethg	cmpb	$0xff, %al	/ If port's not there, we should get back 0xFF
13417303b3c3Ssethg	je	1f
13427303b3c3Ssethg	testb	$1, %al		/ If bit 0
13437303b3c3Ssethg	jz	2f		/ is clear, jump to perform the reset
13447303b3c3Ssethg	andb	$0xfe, %al	/ otherwise,
13457303b3c3Ssethg	outb	(%dx)		/ clear bit 0 first, then
13467303b3c3Ssethg2:
13477303b3c3Ssethg	orb	$1, %al		/ Set bit 0
13487303b3c3Ssethg	outb	(%dx)		/ and reset the system
13497303b3c3Ssethg1:
13501a48003fSsethg
1351085f98c4Ssethg	call	wait_500ms
1352085f98c4Ssethg
1353085f98c4Ssethg3:
135432206069Ssethg#if defined(__i386)
1355085f98c4Ssethg	testl	$RESET_METHOD_PCI, pc_reset_methods
135632206069Ssethg#elif defined(__amd64)
135732206069Ssethg	testl	$RESET_METHOD_PCI, pc_reset_methods(%rip)
135832206069Ssethg#endif
1359085f98c4Ssethg	jz	4f
1360085f98c4Ssethg
13611a48003fSsethg	/ Try the PCI (soft) reset vector (should work on all modern systems,
13621a48003fSsethg	/ but has been shown to cause problems on 450NX systems, and some newer
13631a48003fSsethg	/ systems (e.g. ATI IXP400-equipped systems))
13641a48003fSsethg	/ When resetting via this method, 2 writes are required.  The first
13651a48003fSsethg	/ targets bit 1 (0=hard reset without power cycle, 1=hard reset with
13661a48003fSsethg	/ power cycle).
13671a48003fSsethg	/ The reset occurs on the second write, during bit 2's transition from
13681a48003fSsethg	/ 0->1.
13691a48003fSsethg	movw	$0xcf9, %dx
13701a48003fSsethg	movb	$0x2, %al	/ Reset mode = hard, no power cycle
13711a48003fSsethg	outb	(%dx)
13721a48003fSsethg	movb	$0x6, %al
13731a48003fSsethg	outb	(%dx)
13741a48003fSsethg
1375085f98c4Ssethg	call	wait_500ms
1376085f98c4Ssethg
1377085f98c4Ssethg4:
13787303b3c3Ssethg	/
13791a48003fSsethg	/ port 0xcf9 failed also.  Last-ditch effort is to
13807303b3c3Ssethg	/ triple-fault the CPU.
1381f2be5148Sszhou	/ Also, use triple fault for EFI firmware
13827303b3c3Ssethg	/
1383f2be5148Sszhou	ENTRY(efi_reset)
13847303b3c3Ssethg#if defined(__amd64)
13857303b3c3Ssethg	pushq	$0x0
13867303b3c3Ssethg	pushq	$0x0		/ IDT base of 0, limit of 0 + 2 unused bytes
13877303b3c3Ssethg	lidt	(%rsp)
13887303b3c3Ssethg#elif defined(__i386)
13897303b3c3Ssethg	pushl	$0x0
13907303b3c3Ssethg	pushl	$0x0		/ IDT base of 0, limit of 0 + 2 unused bytes
13917303b3c3Ssethg	lidt	(%esp)
13927303b3c3Ssethg#endif
13937303b3c3Ssethg	int	$0x0		/ Trigger interrupt, generate triple-fault
1394085f98c4Ssethg
1395085f98c4Ssethg	cli
1396085f98c4Ssethg	hlt			/ Wait forever
13977c478bd9Sstevel@tonic-gate	/*NOTREACHED*/
1398f2be5148Sszhou	SET_SIZE(efi_reset)
13997c478bd9Sstevel@tonic-gate	SET_SIZE(pc_reset)
14007c478bd9Sstevel@tonic-gate
14017c478bd9Sstevel@tonic-gate#endif	/* __lint */
14027c478bd9Sstevel@tonic-gate
14037c478bd9Sstevel@tonic-gate/*
14047c478bd9Sstevel@tonic-gate * C callable in and out routines
14057c478bd9Sstevel@tonic-gate */
14067c478bd9Sstevel@tonic-gate
14077c478bd9Sstevel@tonic-gate#if defined(__lint)
14087c478bd9Sstevel@tonic-gate
14097c478bd9Sstevel@tonic-gate/* ARGSUSED */
14107c478bd9Sstevel@tonic-gatevoid
14117c478bd9Sstevel@tonic-gateoutl(int port_address, uint32_t val)
14127c478bd9Sstevel@tonic-gate{}
14137c478bd9Sstevel@tonic-gate
14147c478bd9Sstevel@tonic-gate#else	/* __lint */
14157c478bd9Sstevel@tonic-gate
14167c478bd9Sstevel@tonic-gate#if defined(__amd64)
14177c478bd9Sstevel@tonic-gate
14187c478bd9Sstevel@tonic-gate	ENTRY(outl)
14197c478bd9Sstevel@tonic-gate	movw	%di, %dx
14207c478bd9Sstevel@tonic-gate	movl	%esi, %eax
14217c478bd9Sstevel@tonic-gate	outl	(%dx)
14227c478bd9Sstevel@tonic-gate	ret
14237c478bd9Sstevel@tonic-gate	SET_SIZE(outl)
14247c478bd9Sstevel@tonic-gate
14257c478bd9Sstevel@tonic-gate#elif defined(__i386)
14267c478bd9Sstevel@tonic-gate
14277c478bd9Sstevel@tonic-gate	.set	PORT, 4
14287c478bd9Sstevel@tonic-gate	.set	VAL, 8
14297c478bd9Sstevel@tonic-gate
14307c478bd9Sstevel@tonic-gate	ENTRY(outl)
14317c478bd9Sstevel@tonic-gate	movw	PORT(%esp), %dx
14327c478bd9Sstevel@tonic-gate	movl	VAL(%esp), %eax
14337c478bd9Sstevel@tonic-gate	outl	(%dx)
14347c478bd9Sstevel@tonic-gate	ret
14357c478bd9Sstevel@tonic-gate	SET_SIZE(outl)
14367c478bd9Sstevel@tonic-gate
14377c478bd9Sstevel@tonic-gate#endif	/* __i386 */
14387c478bd9Sstevel@tonic-gate#endif	/* __lint */
14397c478bd9Sstevel@tonic-gate
14407c478bd9Sstevel@tonic-gate#if defined(__lint)
14417c478bd9Sstevel@tonic-gate
14427c478bd9Sstevel@tonic-gate/* ARGSUSED */
14437c478bd9Sstevel@tonic-gatevoid
14447c478bd9Sstevel@tonic-gateoutw(int port_address, uint16_t val)
14457c478bd9Sstevel@tonic-gate{}
14467c478bd9Sstevel@tonic-gate
14477c478bd9Sstevel@tonic-gate#else	/* __lint */
14487c478bd9Sstevel@tonic-gate
14497c478bd9Sstevel@tonic-gate#if defined(__amd64)
14507c478bd9Sstevel@tonic-gate
14517c478bd9Sstevel@tonic-gate	ENTRY(outw)
14527c478bd9Sstevel@tonic-gate	movw	%di, %dx
14537c478bd9Sstevel@tonic-gate	movw	%si, %ax
14547c478bd9Sstevel@tonic-gate	D16 outl (%dx)		/* XX64 why not outw? */
14557c478bd9Sstevel@tonic-gate	ret
14567c478bd9Sstevel@tonic-gate	SET_SIZE(outw)
14577c478bd9Sstevel@tonic-gate
14587c478bd9Sstevel@tonic-gate#elif defined(__i386)
14597c478bd9Sstevel@tonic-gate
14607c478bd9Sstevel@tonic-gate	ENTRY(outw)
14617c478bd9Sstevel@tonic-gate	movw	PORT(%esp), %dx
14627c478bd9Sstevel@tonic-gate	movw	VAL(%esp), %ax
14637c478bd9Sstevel@tonic-gate	D16 outl (%dx)
14647c478bd9Sstevel@tonic-gate	ret
14657c478bd9Sstevel@tonic-gate	SET_SIZE(outw)
14667c478bd9Sstevel@tonic-gate
14677c478bd9Sstevel@tonic-gate#endif	/* __i386 */
14687c478bd9Sstevel@tonic-gate#endif	/* __lint */
14697c478bd9Sstevel@tonic-gate
14707c478bd9Sstevel@tonic-gate#if defined(__lint)
14717c478bd9Sstevel@tonic-gate
14727c478bd9Sstevel@tonic-gate/* ARGSUSED */
14737c478bd9Sstevel@tonic-gatevoid
14747c478bd9Sstevel@tonic-gateoutb(int port_address, uint8_t val)
14757c478bd9Sstevel@tonic-gate{}
14767c478bd9Sstevel@tonic-gate
14777c478bd9Sstevel@tonic-gate#else	/* __lint */
14787c478bd9Sstevel@tonic-gate
14797c478bd9Sstevel@tonic-gate#if defined(__amd64)
14807c478bd9Sstevel@tonic-gate
14817c478bd9Sstevel@tonic-gate	ENTRY(outb)
14827c478bd9Sstevel@tonic-gate	movw	%di, %dx
14837c478bd9Sstevel@tonic-gate	movb	%sil, %al
14847c478bd9Sstevel@tonic-gate	outb	(%dx)
14857c478bd9Sstevel@tonic-gate	ret
14867c478bd9Sstevel@tonic-gate	SET_SIZE(outb)
14877c478bd9Sstevel@tonic-gate
14887c478bd9Sstevel@tonic-gate#elif defined(__i386)
14897c478bd9Sstevel@tonic-gate
14907c478bd9Sstevel@tonic-gate	ENTRY(outb)
14917c478bd9Sstevel@tonic-gate	movw	PORT(%esp), %dx
14927c478bd9Sstevel@tonic-gate	movb	VAL(%esp), %al
14937c478bd9Sstevel@tonic-gate	outb	(%dx)
14947c478bd9Sstevel@tonic-gate	ret
14957c478bd9Sstevel@tonic-gate	SET_SIZE(outb)
14967c478bd9Sstevel@tonic-gate
14977c478bd9Sstevel@tonic-gate#endif	/* __i386 */
14987c478bd9Sstevel@tonic-gate#endif	/* __lint */
14997c478bd9Sstevel@tonic-gate
15007c478bd9Sstevel@tonic-gate#if defined(__lint)
15017c478bd9Sstevel@tonic-gate
15027c478bd9Sstevel@tonic-gate/* ARGSUSED */
15037c478bd9Sstevel@tonic-gateuint32_t
15047c478bd9Sstevel@tonic-gateinl(int port_address)
15057c478bd9Sstevel@tonic-gate{ return (0); }
15067c478bd9Sstevel@tonic-gate
15077c478bd9Sstevel@tonic-gate#else	/* __lint */
15087c478bd9Sstevel@tonic-gate
15097c478bd9Sstevel@tonic-gate#if defined(__amd64)
15107c478bd9Sstevel@tonic-gate
15117c478bd9Sstevel@tonic-gate	ENTRY(inl)
15127c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
15137c478bd9Sstevel@tonic-gate	movw	%di, %dx
15147c478bd9Sstevel@tonic-gate	inl	(%dx)
15157c478bd9Sstevel@tonic-gate	ret
15167c478bd9Sstevel@tonic-gate	SET_SIZE(inl)
15177c478bd9Sstevel@tonic-gate
15187c478bd9Sstevel@tonic-gate#elif defined(__i386)
15197c478bd9Sstevel@tonic-gate
15207c478bd9Sstevel@tonic-gate	ENTRY(inl)
15217c478bd9Sstevel@tonic-gate	movw	PORT(%esp), %dx
15227c478bd9Sstevel@tonic-gate	inl	(%dx)
15237c478bd9Sstevel@tonic-gate	ret
15247c478bd9Sstevel@tonic-gate	SET_SIZE(inl)
15257c478bd9Sstevel@tonic-gate
15267c478bd9Sstevel@tonic-gate#endif	/* __i386 */
15277c478bd9Sstevel@tonic-gate#endif	/* __lint */
15287c478bd9Sstevel@tonic-gate
15297c478bd9Sstevel@tonic-gate#if defined(__lint)
15307c478bd9Sstevel@tonic-gate
15317c478bd9Sstevel@tonic-gate/* ARGSUSED */
15327c478bd9Sstevel@tonic-gateuint16_t
15337c478bd9Sstevel@tonic-gateinw(int port_address)
15347c478bd9Sstevel@tonic-gate{ return (0); }
15357c478bd9Sstevel@tonic-gate
15367c478bd9Sstevel@tonic-gate#else	/* __lint */
15377c478bd9Sstevel@tonic-gate
15387c478bd9Sstevel@tonic-gate#if defined(__amd64)
15397c478bd9Sstevel@tonic-gate
15407c478bd9Sstevel@tonic-gate	ENTRY(inw)
15417c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
15427c478bd9Sstevel@tonic-gate	movw	%di, %dx
15437c478bd9Sstevel@tonic-gate	D16 inl	(%dx)
15447c478bd9Sstevel@tonic-gate	ret
15457c478bd9Sstevel@tonic-gate	SET_SIZE(inw)
15467c478bd9Sstevel@tonic-gate
15477c478bd9Sstevel@tonic-gate#elif defined(__i386)
15487c478bd9Sstevel@tonic-gate
15497c478bd9Sstevel@tonic-gate	ENTRY(inw)
15507c478bd9Sstevel@tonic-gate	subl	%eax, %eax
15517c478bd9Sstevel@tonic-gate	movw	PORT(%esp), %dx
15527c478bd9Sstevel@tonic-gate	D16 inl	(%dx)
15537c478bd9Sstevel@tonic-gate	ret
15547c478bd9Sstevel@tonic-gate	SET_SIZE(inw)
15557c478bd9Sstevel@tonic-gate
15567c478bd9Sstevel@tonic-gate#endif	/* __i386 */
15577c478bd9Sstevel@tonic-gate#endif	/* __lint */
15587c478bd9Sstevel@tonic-gate
15597c478bd9Sstevel@tonic-gate
15607c478bd9Sstevel@tonic-gate#if defined(__lint)
15617c478bd9Sstevel@tonic-gate
15627c478bd9Sstevel@tonic-gate/* ARGSUSED */
15637c478bd9Sstevel@tonic-gateuint8_t
15647c478bd9Sstevel@tonic-gateinb(int port_address)
15657c478bd9Sstevel@tonic-gate{ return (0); }
15667c478bd9Sstevel@tonic-gate
15677c478bd9Sstevel@tonic-gate#else	/* __lint */
15687c478bd9Sstevel@tonic-gate
15697c478bd9Sstevel@tonic-gate#if defined(__amd64)
15707c478bd9Sstevel@tonic-gate
15717c478bd9Sstevel@tonic-gate	ENTRY(inb)
15727c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
15737c478bd9Sstevel@tonic-gate	movw	%di, %dx
15747c478bd9Sstevel@tonic-gate	inb	(%dx)
15757c478bd9Sstevel@tonic-gate	ret
15767c478bd9Sstevel@tonic-gate	SET_SIZE(inb)
15777c478bd9Sstevel@tonic-gate
15787c478bd9Sstevel@tonic-gate#elif defined(__i386)
15797c478bd9Sstevel@tonic-gate
15807c478bd9Sstevel@tonic-gate	ENTRY(inb)
15817c478bd9Sstevel@tonic-gate	subl    %eax, %eax
15827c478bd9Sstevel@tonic-gate	movw	PORT(%esp), %dx
15837c478bd9Sstevel@tonic-gate	inb	(%dx)
15847c478bd9Sstevel@tonic-gate	ret
15857c478bd9Sstevel@tonic-gate	SET_SIZE(inb)
15867c478bd9Sstevel@tonic-gate
15877c478bd9Sstevel@tonic-gate#endif	/* __i386 */
15887c478bd9Sstevel@tonic-gate#endif	/* __lint */
15897c478bd9Sstevel@tonic-gate
15907c478bd9Sstevel@tonic-gate
15917c478bd9Sstevel@tonic-gate#if defined(__lint)
15927c478bd9Sstevel@tonic-gate
15937c478bd9Sstevel@tonic-gate/* ARGSUSED */
15947c478bd9Sstevel@tonic-gatevoid
15957c478bd9Sstevel@tonic-gaterepoutsw(int port, uint16_t *addr, int cnt)
15967c478bd9Sstevel@tonic-gate{}
15977c478bd9Sstevel@tonic-gate
15987c478bd9Sstevel@tonic-gate#else	/* __lint */
15997c478bd9Sstevel@tonic-gate
16007c478bd9Sstevel@tonic-gate#if defined(__amd64)
16017c478bd9Sstevel@tonic-gate
16027c478bd9Sstevel@tonic-gate	ENTRY(repoutsw)
16037c478bd9Sstevel@tonic-gate	movl	%edx, %ecx
16047c478bd9Sstevel@tonic-gate	movw	%di, %dx
16057c478bd9Sstevel@tonic-gate	rep
16067c478bd9Sstevel@tonic-gate	  D16 outsl
16077c478bd9Sstevel@tonic-gate	ret
16087c478bd9Sstevel@tonic-gate	SET_SIZE(repoutsw)
16097c478bd9Sstevel@tonic-gate
16107c478bd9Sstevel@tonic-gate#elif defined(__i386)
16117c478bd9Sstevel@tonic-gate
16127c478bd9Sstevel@tonic-gate	/*
16137c478bd9Sstevel@tonic-gate	 * The arguments and saved registers are on the stack in the
16147c478bd9Sstevel@tonic-gate	 *  following order:
16157c478bd9Sstevel@tonic-gate	 *      |  cnt  |  +16
16167c478bd9Sstevel@tonic-gate	 *      | *addr |  +12
16177c478bd9Sstevel@tonic-gate	 *      | port  |  +8
16187c478bd9Sstevel@tonic-gate	 *      |  eip  |  +4
16197c478bd9Sstevel@tonic-gate	 *      |  esi  |  <-- %esp
16207c478bd9Sstevel@tonic-gate	 * If additional values are pushed onto the stack, make sure
16217c478bd9Sstevel@tonic-gate	 * to adjust the following constants accordingly.
16227c478bd9Sstevel@tonic-gate	 */
16237c478bd9Sstevel@tonic-gate	.set	PORT, 8
16247c478bd9Sstevel@tonic-gate	.set	ADDR, 12
16257c478bd9Sstevel@tonic-gate	.set	COUNT, 16
16267c478bd9Sstevel@tonic-gate
16277c478bd9Sstevel@tonic-gate	ENTRY(repoutsw)
16287c478bd9Sstevel@tonic-gate	pushl	%esi
16297c478bd9Sstevel@tonic-gate	movl	PORT(%esp), %edx
16307c478bd9Sstevel@tonic-gate	movl	ADDR(%esp), %esi
16317c478bd9Sstevel@tonic-gate	movl	COUNT(%esp), %ecx
16327c478bd9Sstevel@tonic-gate	rep
16337c478bd9Sstevel@tonic-gate	  D16 outsl
16347c478bd9Sstevel@tonic-gate	popl	%esi
16357c478bd9Sstevel@tonic-gate	ret
16367c478bd9Sstevel@tonic-gate	SET_SIZE(repoutsw)
16377c478bd9Sstevel@tonic-gate
16387c478bd9Sstevel@tonic-gate#endif	/* __i386 */
16397c478bd9Sstevel@tonic-gate#endif	/* __lint */
16407c478bd9Sstevel@tonic-gate
16417c478bd9Sstevel@tonic-gate
16427c478bd9Sstevel@tonic-gate#if defined(__lint)
16437c478bd9Sstevel@tonic-gate
16447c478bd9Sstevel@tonic-gate/* ARGSUSED */
16457c478bd9Sstevel@tonic-gatevoid
16467c478bd9Sstevel@tonic-gaterepinsw(int port_addr, uint16_t *addr, int cnt)
16477c478bd9Sstevel@tonic-gate{}
16487c478bd9Sstevel@tonic-gate
16497c478bd9Sstevel@tonic-gate#else	/* __lint */
16507c478bd9Sstevel@tonic-gate
16517c478bd9Sstevel@tonic-gate#if defined(__amd64)
16527c478bd9Sstevel@tonic-gate
16537c478bd9Sstevel@tonic-gate	ENTRY(repinsw)
16547c478bd9Sstevel@tonic-gate	movl	%edx, %ecx
16557c478bd9Sstevel@tonic-gate	movw	%di, %dx
16567c478bd9Sstevel@tonic-gate	rep
16577c478bd9Sstevel@tonic-gate	  D16 insl
16587c478bd9Sstevel@tonic-gate	ret
16597c478bd9Sstevel@tonic-gate	SET_SIZE(repinsw)
16607c478bd9Sstevel@tonic-gate
16617c478bd9Sstevel@tonic-gate#elif defined(__i386)
16627c478bd9Sstevel@tonic-gate
16637c478bd9Sstevel@tonic-gate	ENTRY(repinsw)
16647c478bd9Sstevel@tonic-gate	pushl	%edi
16657c478bd9Sstevel@tonic-gate	movl	PORT(%esp), %edx
16667c478bd9Sstevel@tonic-gate	movl	ADDR(%esp), %edi
16677c478bd9Sstevel@tonic-gate	movl	COUNT(%esp), %ecx
16687c478bd9Sstevel@tonic-gate	rep
16697c478bd9Sstevel@tonic-gate	  D16 insl
16707c478bd9Sstevel@tonic-gate	popl	%edi
16717c478bd9Sstevel@tonic-gate	ret
16727c478bd9Sstevel@tonic-gate	SET_SIZE(repinsw)
16737c478bd9Sstevel@tonic-gate
16747c478bd9Sstevel@tonic-gate#endif	/* __i386 */
16757c478bd9Sstevel@tonic-gate#endif	/* __lint */
16767c478bd9Sstevel@tonic-gate
16777c478bd9Sstevel@tonic-gate
16787c478bd9Sstevel@tonic-gate#if defined(__lint)
16797c478bd9Sstevel@tonic-gate
16807c478bd9Sstevel@tonic-gate/* ARGSUSED */
16817c478bd9Sstevel@tonic-gatevoid
16827c478bd9Sstevel@tonic-gaterepinsb(int port, uint8_t *addr, int count)
16837c478bd9Sstevel@tonic-gate{}
16847c478bd9Sstevel@tonic-gate
16857c478bd9Sstevel@tonic-gate#else	/* __lint */
16867c478bd9Sstevel@tonic-gate
16877c478bd9Sstevel@tonic-gate#if defined(__amd64)
16887c478bd9Sstevel@tonic-gate
16897c478bd9Sstevel@tonic-gate	ENTRY(repinsb)
16907c478bd9Sstevel@tonic-gate	movl	%edx, %ecx
16917c478bd9Sstevel@tonic-gate	movw	%di, %dx
16927c478bd9Sstevel@tonic-gate	movq	%rsi, %rdi
16937c478bd9Sstevel@tonic-gate	rep
16947c478bd9Sstevel@tonic-gate	  insb
16957c478bd9Sstevel@tonic-gate	ret
16967c478bd9Sstevel@tonic-gate	SET_SIZE(repinsb)
16977c478bd9Sstevel@tonic-gate
16987c478bd9Sstevel@tonic-gate#elif defined(__i386)
16997c478bd9Sstevel@tonic-gate
17007c478bd9Sstevel@tonic-gate	/*
17017c478bd9Sstevel@tonic-gate	 * The arguments and saved registers are on the stack in the
17027c478bd9Sstevel@tonic-gate	 *  following order:
17037c478bd9Sstevel@tonic-gate	 *      |  cnt  |  +16
17047c478bd9Sstevel@tonic-gate	 *      | *addr |  +12
17057c478bd9Sstevel@tonic-gate	 *      | port  |  +8
17067c478bd9Sstevel@tonic-gate	 *      |  eip  |  +4
17077c478bd9Sstevel@tonic-gate	 *      |  esi  |  <-- %esp
17087c478bd9Sstevel@tonic-gate	 * If additional values are pushed onto the stack, make sure
17097c478bd9Sstevel@tonic-gate	 * to adjust the following constants accordingly.
17107c478bd9Sstevel@tonic-gate	 */
17117c478bd9Sstevel@tonic-gate	.set	IO_PORT, 8
17127c478bd9Sstevel@tonic-gate	.set	IO_ADDR, 12
17137c478bd9Sstevel@tonic-gate	.set	IO_COUNT, 16
17147c478bd9Sstevel@tonic-gate
17157c478bd9Sstevel@tonic-gate	ENTRY(repinsb)
17167c478bd9Sstevel@tonic-gate	pushl	%edi
17177c478bd9Sstevel@tonic-gate	movl	IO_ADDR(%esp), %edi
17187c478bd9Sstevel@tonic-gate	movl	IO_COUNT(%esp), %ecx
17197c478bd9Sstevel@tonic-gate	movl	IO_PORT(%esp), %edx
17207c478bd9Sstevel@tonic-gate	rep
17217c478bd9Sstevel@tonic-gate	  insb
17227c478bd9Sstevel@tonic-gate	popl	%edi
17237c478bd9Sstevel@tonic-gate	ret
17247c478bd9Sstevel@tonic-gate	SET_SIZE(repinsb)
17257c478bd9Sstevel@tonic-gate
17267c478bd9Sstevel@tonic-gate#endif	/* __i386 */
17277c478bd9Sstevel@tonic-gate#endif	/* __lint */
17287c478bd9Sstevel@tonic-gate
17297c478bd9Sstevel@tonic-gate
17307c478bd9Sstevel@tonic-gate/*
17317c478bd9Sstevel@tonic-gate * Input a stream of 32-bit words.
17327c478bd9Sstevel@tonic-gate * NOTE: count is a DWORD count.
17337c478bd9Sstevel@tonic-gate */
17347c478bd9Sstevel@tonic-gate#if defined(__lint)
17357c478bd9Sstevel@tonic-gate
17367c478bd9Sstevel@tonic-gate/* ARGSUSED */
17377c478bd9Sstevel@tonic-gatevoid
17387c478bd9Sstevel@tonic-gaterepinsd(int port, uint32_t *addr, int count)
17397c478bd9Sstevel@tonic-gate{}
17407c478bd9Sstevel@tonic-gate
17417c478bd9Sstevel@tonic-gate#else	/* __lint */
17427c478bd9Sstevel@tonic-gate
17437c478bd9Sstevel@tonic-gate#if defined(__amd64)
17447c478bd9Sstevel@tonic-gate
17457c478bd9Sstevel@tonic-gate	ENTRY(repinsd)
17467c478bd9Sstevel@tonic-gate	movl	%edx, %ecx
17477c478bd9Sstevel@tonic-gate	movw	%di, %dx
17487c478bd9Sstevel@tonic-gate	movq	%rsi, %rdi
17497c478bd9Sstevel@tonic-gate	rep
17507c478bd9Sstevel@tonic-gate	  insl
17517c478bd9Sstevel@tonic-gate	ret
17527c478bd9Sstevel@tonic-gate	SET_SIZE(repinsd)
17537c478bd9Sstevel@tonic-gate
17547c478bd9Sstevel@tonic-gate#elif defined(__i386)
17557c478bd9Sstevel@tonic-gate
17567c478bd9Sstevel@tonic-gate	ENTRY(repinsd)
17577c478bd9Sstevel@tonic-gate	pushl	%edi
17587c478bd9Sstevel@tonic-gate	movl	IO_ADDR(%esp), %edi
17597c478bd9Sstevel@tonic-gate	movl	IO_COUNT(%esp), %ecx
17607c478bd9Sstevel@tonic-gate	movl	IO_PORT(%esp), %edx
17617c478bd9Sstevel@tonic-gate	rep
17627c478bd9Sstevel@tonic-gate	  insl
17637c478bd9Sstevel@tonic-gate	popl	%edi
17647c478bd9Sstevel@tonic-gate	ret
17657c478bd9Sstevel@tonic-gate	SET_SIZE(repinsd)
17667c478bd9Sstevel@tonic-gate
17677c478bd9Sstevel@tonic-gate#endif	/* __i386 */
17687c478bd9Sstevel@tonic-gate#endif	/* __lint */
17697c478bd9Sstevel@tonic-gate
17707c478bd9Sstevel@tonic-gate/*
17717c478bd9Sstevel@tonic-gate * Output a stream of bytes
17727c478bd9Sstevel@tonic-gate * NOTE: count is a byte count
17737c478bd9Sstevel@tonic-gate */
17747c478bd9Sstevel@tonic-gate#if defined(__lint)
17757c478bd9Sstevel@tonic-gate
17767c478bd9Sstevel@tonic-gate/* ARGSUSED */
17777c478bd9Sstevel@tonic-gatevoid
17787c478bd9Sstevel@tonic-gaterepoutsb(int port, uint8_t *addr, int count)
17797c478bd9Sstevel@tonic-gate{}
17807c478bd9Sstevel@tonic-gate
17817c478bd9Sstevel@tonic-gate#else	/* __lint */
17827c478bd9Sstevel@tonic-gate
17837c478bd9Sstevel@tonic-gate#if defined(__amd64)
17847c478bd9Sstevel@tonic-gate
17857c478bd9Sstevel@tonic-gate	ENTRY(repoutsb)
17867c478bd9Sstevel@tonic-gate	movl	%edx, %ecx
17877c478bd9Sstevel@tonic-gate	movw	%di, %dx
17887c478bd9Sstevel@tonic-gate	rep
17897c478bd9Sstevel@tonic-gate	  outsb
17907c478bd9Sstevel@tonic-gate	ret
17917c478bd9Sstevel@tonic-gate	SET_SIZE(repoutsb)
17927c478bd9Sstevel@tonic-gate
17937c478bd9Sstevel@tonic-gate#elif defined(__i386)
17947c478bd9Sstevel@tonic-gate
17957c478bd9Sstevel@tonic-gate	ENTRY(repoutsb)
17967c478bd9Sstevel@tonic-gate	pushl	%esi
17977c478bd9Sstevel@tonic-gate	movl	IO_ADDR(%esp), %esi
17987c478bd9Sstevel@tonic-gate	movl	IO_COUNT(%esp), %ecx
17997c478bd9Sstevel@tonic-gate	movl	IO_PORT(%esp), %edx
18007c478bd9Sstevel@tonic-gate	rep
18017c478bd9Sstevel@tonic-gate	  outsb
18027c478bd9Sstevel@tonic-gate	popl	%esi
18037c478bd9Sstevel@tonic-gate	ret
18047c478bd9Sstevel@tonic-gate	SET_SIZE(repoutsb)
18057c478bd9Sstevel@tonic-gate
18067c478bd9Sstevel@tonic-gate#endif	/* __i386 */
18077c478bd9Sstevel@tonic-gate#endif	/* __lint */
18087c478bd9Sstevel@tonic-gate
18097c478bd9Sstevel@tonic-gate/*
18107c478bd9Sstevel@tonic-gate * Output a stream of 32-bit words
18117c478bd9Sstevel@tonic-gate * NOTE: count is a DWORD count
18127c478bd9Sstevel@tonic-gate */
18137c478bd9Sstevel@tonic-gate#if defined(__lint)
18147c478bd9Sstevel@tonic-gate
18157c478bd9Sstevel@tonic-gate/* ARGSUSED */
18167c478bd9Sstevel@tonic-gatevoid
18177c478bd9Sstevel@tonic-gaterepoutsd(int port, uint32_t *addr, int count)
18187c478bd9Sstevel@tonic-gate{}
18197c478bd9Sstevel@tonic-gate
18207c478bd9Sstevel@tonic-gate#else	/* __lint */
18217c478bd9Sstevel@tonic-gate
18227c478bd9Sstevel@tonic-gate#if defined(__amd64)
18237c478bd9Sstevel@tonic-gate
18247c478bd9Sstevel@tonic-gate	ENTRY(repoutsd)
18257c478bd9Sstevel@tonic-gate	movl	%edx, %ecx
18267c478bd9Sstevel@tonic-gate	movw	%di, %dx
18277c478bd9Sstevel@tonic-gate	rep
18287c478bd9Sstevel@tonic-gate	  outsl
18297c478bd9Sstevel@tonic-gate	ret
18307c478bd9Sstevel@tonic-gate	SET_SIZE(repoutsd)
18317c478bd9Sstevel@tonic-gate
18327c478bd9Sstevel@tonic-gate#elif defined(__i386)
18337c478bd9Sstevel@tonic-gate
18347c478bd9Sstevel@tonic-gate	ENTRY(repoutsd)
18357c478bd9Sstevel@tonic-gate	pushl	%esi
18367c478bd9Sstevel@tonic-gate	movl	IO_ADDR(%esp), %esi
18377c478bd9Sstevel@tonic-gate	movl	IO_COUNT(%esp), %ecx
18387c478bd9Sstevel@tonic-gate	movl	IO_PORT(%esp), %edx
18397c478bd9Sstevel@tonic-gate	rep
18407c478bd9Sstevel@tonic-gate	  outsl
18417c478bd9Sstevel@tonic-gate	popl	%esi
18427c478bd9Sstevel@tonic-gate	ret
18437c478bd9Sstevel@tonic-gate	SET_SIZE(repoutsd)
18447c478bd9Sstevel@tonic-gate
18457c478bd9Sstevel@tonic-gate#endif	/* __i386 */
18467c478bd9Sstevel@tonic-gate#endif	/* __lint */
18477c478bd9Sstevel@tonic-gate
18487c478bd9Sstevel@tonic-gate/*
18497aec1d6eScindi * void int3(void)
18507aec1d6eScindi * void int18(void)
18517c478bd9Sstevel@tonic-gate * void int20(void)
1852e3d60c9bSAdrian Frost * void int_cmci(void)
18537c478bd9Sstevel@tonic-gate */
18547c478bd9Sstevel@tonic-gate
18557c478bd9Sstevel@tonic-gate#if defined(__lint)
18567c478bd9Sstevel@tonic-gate
18577c478bd9Sstevel@tonic-gatevoid
18587aec1d6eScindiint3(void)
18597aec1d6eScindi{}
18607aec1d6eScindi
18617aec1d6eScindivoid
18627aec1d6eScindiint18(void)
18637aec1d6eScindi{}
18647aec1d6eScindi
18657aec1d6eScindivoid
18667c478bd9Sstevel@tonic-gateint20(void)
18677c478bd9Sstevel@tonic-gate{}
18687c478bd9Sstevel@tonic-gate
1869e3d60c9bSAdrian Frostvoid
1870e3d60c9bSAdrian Frostint_cmci(void)
1871e3d60c9bSAdrian Frost{}
1872e3d60c9bSAdrian Frost
18737c478bd9Sstevel@tonic-gate#else	/* __lint */
18747c478bd9Sstevel@tonic-gate
18757aec1d6eScindi	ENTRY(int3)
18767aec1d6eScindi	int	$T_BPTFLT
18777aec1d6eScindi	ret
18787aec1d6eScindi	SET_SIZE(int3)
18797aec1d6eScindi
18807aec1d6eScindi	ENTRY(int18)
18817aec1d6eScindi	int	$T_MCE
18827aec1d6eScindi	ret
18837aec1d6eScindi	SET_SIZE(int18)
18847aec1d6eScindi
18857c478bd9Sstevel@tonic-gate	ENTRY(int20)
18867c478bd9Sstevel@tonic-gate	movl	boothowto, %eax
18877c478bd9Sstevel@tonic-gate	andl	$RB_DEBUG, %eax
18887c478bd9Sstevel@tonic-gate	jz	1f
18897c478bd9Sstevel@tonic-gate
18907aec1d6eScindi	int	$T_DBGENTR
18917c478bd9Sstevel@tonic-gate1:
189285641879Skalai	rep;	ret	/* use 2 byte return instruction when branch target */
189385641879Skalai			/* AMD Software Optimization Guide - Section 6.2 */
18947c478bd9Sstevel@tonic-gate	SET_SIZE(int20)
18957c478bd9Sstevel@tonic-gate
1896e3d60c9bSAdrian Frost	ENTRY(int_cmci)
1897e3d60c9bSAdrian Frost	int	$T_ENOEXTFLT
1898e3d60c9bSAdrian Frost	ret
1899e3d60c9bSAdrian Frost	SET_SIZE(int_cmci)
1900e3d60c9bSAdrian Frost
19017c478bd9Sstevel@tonic-gate#endif	/* __lint */
19027c478bd9Sstevel@tonic-gate
19037c478bd9Sstevel@tonic-gate#if defined(__lint)
19047c478bd9Sstevel@tonic-gate
19057c478bd9Sstevel@tonic-gate/* ARGSUSED */
19067c478bd9Sstevel@tonic-gateint
19077c478bd9Sstevel@tonic-gatescanc(size_t size, uchar_t *cp, uchar_t *table, uchar_t mask)
19087c478bd9Sstevel@tonic-gate{ return (0); }
19097c478bd9Sstevel@tonic-gate
19107c478bd9Sstevel@tonic-gate#else	/* __lint */
19117c478bd9Sstevel@tonic-gate
19127c478bd9Sstevel@tonic-gate#if defined(__amd64)
19137c478bd9Sstevel@tonic-gate
19147c478bd9Sstevel@tonic-gate	ENTRY(scanc)
19157c478bd9Sstevel@tonic-gate					/* rdi == size */
19167c478bd9Sstevel@tonic-gate					/* rsi == cp */
19177c478bd9Sstevel@tonic-gate					/* rdx == table */
19187c478bd9Sstevel@tonic-gate					/* rcx == mask */
19197c478bd9Sstevel@tonic-gate	addq	%rsi, %rdi		/* end = &cp[size] */
19207c478bd9Sstevel@tonic-gate.scanloop:
19217c478bd9Sstevel@tonic-gate	cmpq	%rdi, %rsi		/* while (cp < end */
19227c478bd9Sstevel@tonic-gate	jnb	.scandone
19237c478bd9Sstevel@tonic-gate	movzbq	(%rsi), %r8		/* %r8 = *cp */
19247c478bd9Sstevel@tonic-gate	incq	%rsi			/* cp++ */
19257c478bd9Sstevel@tonic-gate	testb	%cl, (%r8, %rdx)
19267c478bd9Sstevel@tonic-gate	jz	.scanloop		/*  && (table[*cp] & mask) == 0) */
19277c478bd9Sstevel@tonic-gate	decq	%rsi			/* (fix post-increment) */
19287c478bd9Sstevel@tonic-gate.scandone:
19297c478bd9Sstevel@tonic-gate	movl	%edi, %eax
19307c478bd9Sstevel@tonic-gate	subl	%esi, %eax		/* return (end - cp) */
19317c478bd9Sstevel@tonic-gate	ret
19327c478bd9Sstevel@tonic-gate	SET_SIZE(scanc)
19337c478bd9Sstevel@tonic-gate
19347c478bd9Sstevel@tonic-gate#elif defined(__i386)
19357c478bd9Sstevel@tonic-gate
19367c478bd9Sstevel@tonic-gate	ENTRY(scanc)
19377c478bd9Sstevel@tonic-gate	pushl	%edi
19387c478bd9Sstevel@tonic-gate	pushl	%esi
19397c478bd9Sstevel@tonic-gate	movb	24(%esp), %cl		/* mask = %cl */
19407c478bd9Sstevel@tonic-gate	movl	16(%esp), %esi		/* cp = %esi */
19417c478bd9Sstevel@tonic-gate	movl	20(%esp), %edx		/* table = %edx */
19427c478bd9Sstevel@tonic-gate	movl	%esi, %edi
19437c478bd9Sstevel@tonic-gate	addl	12(%esp), %edi		/* end = &cp[size]; */
19447c478bd9Sstevel@tonic-gate.scanloop:
19457c478bd9Sstevel@tonic-gate	cmpl	%edi, %esi		/* while (cp < end */
19467c478bd9Sstevel@tonic-gate	jnb	.scandone
19477c478bd9Sstevel@tonic-gate	movzbl	(%esi),  %eax		/* %al = *cp */
19487c478bd9Sstevel@tonic-gate	incl	%esi			/* cp++ */
19497c478bd9Sstevel@tonic-gate	movb	(%edx,  %eax), %al	/* %al = table[*cp] */
19507c478bd9Sstevel@tonic-gate	testb	%al, %cl
19517c478bd9Sstevel@tonic-gate	jz	.scanloop		/*   && (table[*cp] & mask) == 0) */
19527c478bd9Sstevel@tonic-gate	dec	%esi			/* post-incremented */
19537c478bd9Sstevel@tonic-gate.scandone:
19547c478bd9Sstevel@tonic-gate	movl	%edi, %eax
19557c478bd9Sstevel@tonic-gate	subl	%esi, %eax		/* return (end - cp) */
19567c478bd9Sstevel@tonic-gate	popl	%esi
19577c478bd9Sstevel@tonic-gate	popl	%edi
19587c478bd9Sstevel@tonic-gate	ret
19597c478bd9Sstevel@tonic-gate	SET_SIZE(scanc)
19607c478bd9Sstevel@tonic-gate
19617c478bd9Sstevel@tonic-gate#endif	/* __i386 */
19627c478bd9Sstevel@tonic-gate#endif	/* __lint */
19637c478bd9Sstevel@tonic-gate
19647c478bd9Sstevel@tonic-gate/*
19657c478bd9Sstevel@tonic-gate * Replacement functions for ones that are normally inlined.
19667c478bd9Sstevel@tonic-gate * In addition to the copy in i86.il, they are defined here just in case.
19677c478bd9Sstevel@tonic-gate */
19687c478bd9Sstevel@tonic-gate
19697c478bd9Sstevel@tonic-gate#if defined(__lint)
19707c478bd9Sstevel@tonic-gate
1971ae115bc7Smrjulong_t
19727c478bd9Sstevel@tonic-gateintr_clear(void)
1973ae115bc7Smrj{ return (0); }
19747c478bd9Sstevel@tonic-gate
1975ae115bc7Smrjulong_t
19767c478bd9Sstevel@tonic-gateclear_int_flag(void)
1977ae115bc7Smrj{ return (0); }
19787c478bd9Sstevel@tonic-gate
19797c478bd9Sstevel@tonic-gate#else	/* __lint */
19807c478bd9Sstevel@tonic-gate
19817c478bd9Sstevel@tonic-gate#if defined(__amd64)
19827c478bd9Sstevel@tonic-gate
19837c478bd9Sstevel@tonic-gate	ENTRY(intr_clear)
19847c478bd9Sstevel@tonic-gate	ENTRY(clear_int_flag)
19857c478bd9Sstevel@tonic-gate	pushfq
19867c478bd9Sstevel@tonic-gate	popq	%rax
1987843e1988Sjohnlev#if defined(__xpv)
1988843e1988Sjohnlev	leaq	xpv_panicking, %rdi
1989843e1988Sjohnlev	movl	(%rdi), %edi
1990843e1988Sjohnlev	cmpl	$0, %edi
1991843e1988Sjohnlev	jne	2f
1992843e1988Sjohnlev	CLIRET(%rdi, %dl)	/* returns event mask in %dl */
1993843e1988Sjohnlev	/*
1994843e1988Sjohnlev	 * Synthesize the PS_IE bit from the event mask bit
1995843e1988Sjohnlev	 */
1996843e1988Sjohnlev	andq    $_BITNOT(PS_IE), %rax
1997843e1988Sjohnlev	testb	$1, %dl
1998843e1988Sjohnlev	jnz	1f
1999843e1988Sjohnlev	orq	$PS_IE, %rax
2000843e1988Sjohnlev1:
2001843e1988Sjohnlev	ret
2002843e1988Sjohnlev2:
2003843e1988Sjohnlev#endif
2004ae115bc7Smrj	CLI(%rdi)
20057c478bd9Sstevel@tonic-gate	ret
20067c478bd9Sstevel@tonic-gate	SET_SIZE(clear_int_flag)
20077c478bd9Sstevel@tonic-gate	SET_SIZE(intr_clear)
20087c478bd9Sstevel@tonic-gate
20097c478bd9Sstevel@tonic-gate#elif defined(__i386)
20107c478bd9Sstevel@tonic-gate
20117c478bd9Sstevel@tonic-gate	ENTRY(intr_clear)
20127c478bd9Sstevel@tonic-gate	ENTRY(clear_int_flag)
20137c478bd9Sstevel@tonic-gate	pushfl
20147c478bd9Sstevel@tonic-gate	popl	%eax
2015843e1988Sjohnlev#if defined(__xpv)
2016843e1988Sjohnlev	leal	xpv_panicking, %edx
2017843e1988Sjohnlev	movl	(%edx), %edx
2018843e1988Sjohnlev	cmpl	$0, %edx
2019843e1988Sjohnlev	jne	2f
2020843e1988Sjohnlev	CLIRET(%edx, %cl)	/* returns event mask in %cl */
2021843e1988Sjohnlev	/*
2022843e1988Sjohnlev	 * Synthesize the PS_IE bit from the event mask bit
2023843e1988Sjohnlev	 */
2024843e1988Sjohnlev	andl    $_BITNOT(PS_IE), %eax
2025843e1988Sjohnlev	testb	$1, %cl
2026843e1988Sjohnlev	jnz	1f
2027843e1988Sjohnlev	orl	$PS_IE, %eax
2028843e1988Sjohnlev1:
2029843e1988Sjohnlev	ret
2030843e1988Sjohnlev2:
2031843e1988Sjohnlev#endif
2032ae115bc7Smrj	CLI(%edx)
20337c478bd9Sstevel@tonic-gate	ret
20347c478bd9Sstevel@tonic-gate	SET_SIZE(clear_int_flag)
20357c478bd9Sstevel@tonic-gate	SET_SIZE(intr_clear)
20367c478bd9Sstevel@tonic-gate
20377c478bd9Sstevel@tonic-gate#endif	/* __i386 */
20387c478bd9Sstevel@tonic-gate#endif	/* __lint */
20397c478bd9Sstevel@tonic-gate
20407c478bd9Sstevel@tonic-gate#if defined(__lint)
20417c478bd9Sstevel@tonic-gate
20427c478bd9Sstevel@tonic-gatestruct cpu *
20437c478bd9Sstevel@tonic-gatecurcpup(void)
20447c478bd9Sstevel@tonic-gate{ return 0; }
20457c478bd9Sstevel@tonic-gate
20467c478bd9Sstevel@tonic-gate#else	/* __lint */
20477c478bd9Sstevel@tonic-gate
20487c478bd9Sstevel@tonic-gate#if defined(__amd64)
20497c478bd9Sstevel@tonic-gate
20507c478bd9Sstevel@tonic-gate	ENTRY(curcpup)
20517c478bd9Sstevel@tonic-gate	movq	%gs:CPU_SELF, %rax
20527c478bd9Sstevel@tonic-gate	ret
20537c478bd9Sstevel@tonic-gate	SET_SIZE(curcpup)
20547c478bd9Sstevel@tonic-gate
20557c478bd9Sstevel@tonic-gate#elif defined(__i386)
20567c478bd9Sstevel@tonic-gate
20577c478bd9Sstevel@tonic-gate	ENTRY(curcpup)
20587c478bd9Sstevel@tonic-gate	movl	%gs:CPU_SELF, %eax
20597c478bd9Sstevel@tonic-gate	ret
20607c478bd9Sstevel@tonic-gate	SET_SIZE(curcpup)
20617c478bd9Sstevel@tonic-gate
20627c478bd9Sstevel@tonic-gate#endif	/* __i386 */
20637c478bd9Sstevel@tonic-gate#endif	/* __lint */
20647c478bd9Sstevel@tonic-gate
20654b56a003SDaniel Anderson/* htonll(), ntohll(), htonl(), ntohl(), htons(), ntohs()
20664b56a003SDaniel Anderson * These functions reverse the byte order of the input parameter and returns
20674b56a003SDaniel Anderson * the result.  This is to convert the byte order from host byte order
20684b56a003SDaniel Anderson * (little endian) to network byte order (big endian), or vice versa.
20694b56a003SDaniel Anderson */
20704b56a003SDaniel Anderson
20717c478bd9Sstevel@tonic-gate#if defined(__lint)
20727c478bd9Sstevel@tonic-gate
20734b56a003SDaniel Andersonuint64_t
20744b56a003SDaniel Andersonhtonll(uint64_t i)
20754b56a003SDaniel Anderson{ return (i); }
20764b56a003SDaniel Anderson
20774b56a003SDaniel Andersonuint64_t
20784b56a003SDaniel Andersonntohll(uint64_t i)
20794b56a003SDaniel Anderson{ return (i); }
20804b56a003SDaniel Anderson
20817c478bd9Sstevel@tonic-gateuint32_t
20827c478bd9Sstevel@tonic-gatehtonl(uint32_t i)
20834b56a003SDaniel Anderson{ return (i); }
20847c478bd9Sstevel@tonic-gate
20857c478bd9Sstevel@tonic-gateuint32_t
20867c478bd9Sstevel@tonic-gatentohl(uint32_t i)
20874b56a003SDaniel Anderson{ return (i); }
20884b56a003SDaniel Anderson
20894b56a003SDaniel Andersonuint16_t
20904b56a003SDaniel Andersonhtons(uint16_t i)
20914b56a003SDaniel Anderson{ return (i); }
20924b56a003SDaniel Anderson
20934b56a003SDaniel Andersonuint16_t
20944b56a003SDaniel Andersonntohs(uint16_t i)
20954b56a003SDaniel Anderson{ return (i); }
20967c478bd9Sstevel@tonic-gate
20977c478bd9Sstevel@tonic-gate#else	/* __lint */
20987c478bd9Sstevel@tonic-gate
20997c478bd9Sstevel@tonic-gate#if defined(__amd64)
21007c478bd9Sstevel@tonic-gate
21014b56a003SDaniel Anderson	ENTRY(htonll)
21024b56a003SDaniel Anderson	ALTENTRY(ntohll)
21034b56a003SDaniel Anderson	movq	%rdi, %rax
21044b56a003SDaniel Anderson	bswapq	%rax
21054b56a003SDaniel Anderson	ret
21064b56a003SDaniel Anderson	SET_SIZE(ntohll)
21074b56a003SDaniel Anderson	SET_SIZE(htonll)
21084b56a003SDaniel Anderson
21097c478bd9Sstevel@tonic-gate	/* XX64 there must be shorter sequences for this */
21107c478bd9Sstevel@tonic-gate	ENTRY(htonl)
21117c478bd9Sstevel@tonic-gate	ALTENTRY(ntohl)
21127c478bd9Sstevel@tonic-gate	movl	%edi, %eax
21137c478bd9Sstevel@tonic-gate	bswap	%eax
21147c478bd9Sstevel@tonic-gate	ret
21157c478bd9Sstevel@tonic-gate	SET_SIZE(ntohl)
21167c478bd9Sstevel@tonic-gate	SET_SIZE(htonl)
21177c478bd9Sstevel@tonic-gate
21187c478bd9Sstevel@tonic-gate	/* XX64 there must be better sequences for this */
21197c478bd9Sstevel@tonic-gate	ENTRY(htons)
21207c478bd9Sstevel@tonic-gate	ALTENTRY(ntohs)
21217c478bd9Sstevel@tonic-gate	movl	%edi, %eax
21227c478bd9Sstevel@tonic-gate	bswap	%eax
21237c478bd9Sstevel@tonic-gate	shrl	$16, %eax
21247c478bd9Sstevel@tonic-gate	ret
21257c478bd9Sstevel@tonic-gate	SET_SIZE(ntohs)
21267c478bd9Sstevel@tonic-gate	SET_SIZE(htons)
21277c478bd9Sstevel@tonic-gate
21287c478bd9Sstevel@tonic-gate#elif defined(__i386)
21297c478bd9Sstevel@tonic-gate
21304b56a003SDaniel Anderson	ENTRY(htonll)
21314b56a003SDaniel Anderson	ALTENTRY(ntohll)
21324b56a003SDaniel Anderson	movl	4(%esp), %edx
21334b56a003SDaniel Anderson	movl	8(%esp), %eax
21344b56a003SDaniel Anderson	bswap	%edx
21354b56a003SDaniel Anderson	bswap	%eax
21364b56a003SDaniel Anderson	ret
21374b56a003SDaniel Anderson	SET_SIZE(ntohll)
21384b56a003SDaniel Anderson	SET_SIZE(htonll)
21394b56a003SDaniel Anderson
21404b56a003SDaniel Anderson	ENTRY(htonl)
21414b56a003SDaniel Anderson	ALTENTRY(ntohl)
21424b56a003SDaniel Anderson	movl	4(%esp), %eax
21434b56a003SDaniel Anderson	bswap	%eax
21444b56a003SDaniel Anderson	ret
21454b56a003SDaniel Anderson	SET_SIZE(ntohl)
21464b56a003SDaniel Anderson	SET_SIZE(htonl)
21474b56a003SDaniel Anderson
21487c478bd9Sstevel@tonic-gate	ENTRY(htons)
21497c478bd9Sstevel@tonic-gate	ALTENTRY(ntohs)
21507c478bd9Sstevel@tonic-gate	movl	4(%esp), %eax
21517c478bd9Sstevel@tonic-gate	bswap	%eax
21527c478bd9Sstevel@tonic-gate	shrl	$16, %eax
21537c478bd9Sstevel@tonic-gate	ret
21547c478bd9Sstevel@tonic-gate	SET_SIZE(ntohs)
21557c478bd9Sstevel@tonic-gate	SET_SIZE(htons)
21567c478bd9Sstevel@tonic-gate
21577c478bd9Sstevel@tonic-gate#endif	/* __i386 */
21587c478bd9Sstevel@tonic-gate#endif	/* __lint */
21597c478bd9Sstevel@tonic-gate
21607c478bd9Sstevel@tonic-gate
21617c478bd9Sstevel@tonic-gate#if defined(__lint)
21627c478bd9Sstevel@tonic-gate
21637c478bd9Sstevel@tonic-gate/* ARGSUSED */
21647c478bd9Sstevel@tonic-gatevoid
2165ae115bc7Smrjintr_restore(ulong_t i)
21667c478bd9Sstevel@tonic-gate{ return; }
21677c478bd9Sstevel@tonic-gate
21687c478bd9Sstevel@tonic-gate/* ARGSUSED */
21697c478bd9Sstevel@tonic-gatevoid
2170ae115bc7Smrjrestore_int_flag(ulong_t i)
21717c478bd9Sstevel@tonic-gate{ return; }
21727c478bd9Sstevel@tonic-gate
21737c478bd9Sstevel@tonic-gate#else	/* __lint */
21747c478bd9Sstevel@tonic-gate
21757c478bd9Sstevel@tonic-gate#if defined(__amd64)
21767c478bd9Sstevel@tonic-gate
21777c478bd9Sstevel@tonic-gate	ENTRY(intr_restore)
21787c478bd9Sstevel@tonic-gate	ENTRY(restore_int_flag)
2179a563a037Sbholler	testq	$PS_IE, %rdi
2180a563a037Sbholler	jz	1f
2181843e1988Sjohnlev#if defined(__xpv)
2182843e1988Sjohnlev	leaq	xpv_panicking, %rsi
2183843e1988Sjohnlev	movl	(%rsi), %esi
2184843e1988Sjohnlev	cmpl	$0, %esi
2185843e1988Sjohnlev	jne	1f
2186843e1988Sjohnlev	/*
2187843e1988Sjohnlev	 * Since we're -really- running unprivileged, our attempt
2188843e1988Sjohnlev	 * to change the state of the IF bit will be ignored.
2189843e1988Sjohnlev	 * The virtual IF bit is tweaked by CLI and STI.
2190843e1988Sjohnlev	 */
2191843e1988Sjohnlev	IE_TO_EVENT_MASK(%rsi, %rdi)
2192a563a037Sbholler#else
2193a563a037Sbholler	sti
2194843e1988Sjohnlev#endif
2195a563a037Sbholler1:
21967c478bd9Sstevel@tonic-gate	ret
21977c478bd9Sstevel@tonic-gate	SET_SIZE(restore_int_flag)
21987c478bd9Sstevel@tonic-gate	SET_SIZE(intr_restore)
21997c478bd9Sstevel@tonic-gate
22007c478bd9Sstevel@tonic-gate#elif defined(__i386)
22017c478bd9Sstevel@tonic-gate
22027c478bd9Sstevel@tonic-gate	ENTRY(intr_restore)
22037c478bd9Sstevel@tonic-gate	ENTRY(restore_int_flag)
2204a563a037Sbholler	testl	$PS_IE, 4(%esp)
2205a563a037Sbholler	jz	1f
2206843e1988Sjohnlev#if defined(__xpv)
2207843e1988Sjohnlev	leal	xpv_panicking, %edx
2208843e1988Sjohnlev	movl	(%edx), %edx
2209843e1988Sjohnlev	cmpl	$0, %edx
2210843e1988Sjohnlev	jne	1f
2211843e1988Sjohnlev	/*
2212843e1988Sjohnlev	 * Since we're -really- running unprivileged, our attempt
2213843e1988Sjohnlev	 * to change the state of the IF bit will be ignored.
2214843e1988Sjohnlev	 * The virtual IF bit is tweaked by CLI and STI.
2215843e1988Sjohnlev	 */
2216cc7a88b5Smrj	IE_TO_EVENT_MASK(%edx, 4(%esp))
2217a563a037Sbholler#else
2218a563a037Sbholler	sti
2219843e1988Sjohnlev#endif
2220a563a037Sbholler1:
22217c478bd9Sstevel@tonic-gate	ret
22227c478bd9Sstevel@tonic-gate	SET_SIZE(restore_int_flag)
22237c478bd9Sstevel@tonic-gate	SET_SIZE(intr_restore)
22247c478bd9Sstevel@tonic-gate
22257c478bd9Sstevel@tonic-gate#endif	/* __i386 */
22267c478bd9Sstevel@tonic-gate#endif	/* __lint */
22277c478bd9Sstevel@tonic-gate
22287c478bd9Sstevel@tonic-gate#if defined(__lint)
22297c478bd9Sstevel@tonic-gate
22307c478bd9Sstevel@tonic-gatevoid
22317c478bd9Sstevel@tonic-gatesti(void)
22327c478bd9Sstevel@tonic-gate{}
22337c478bd9Sstevel@tonic-gate
2234ae115bc7Smrjvoid
2235ae115bc7Smrjcli(void)
2236ae115bc7Smrj{}
2237ae115bc7Smrj
22387c478bd9Sstevel@tonic-gate#else	/* __lint */
22397c478bd9Sstevel@tonic-gate
22407c478bd9Sstevel@tonic-gate	ENTRY(sti)
2241ae115bc7Smrj	STI
22427c478bd9Sstevel@tonic-gate	ret
22437c478bd9Sstevel@tonic-gate	SET_SIZE(sti)
22447c478bd9Sstevel@tonic-gate
2245ae115bc7Smrj	ENTRY(cli)
2246ae115bc7Smrj#if defined(__amd64)
2247ae115bc7Smrj	CLI(%rax)
2248ae115bc7Smrj#elif defined(__i386)
2249ae115bc7Smrj	CLI(%eax)
2250ae115bc7Smrj#endif	/* __i386 */
2251ae115bc7Smrj	ret
2252ae115bc7Smrj	SET_SIZE(cli)
2253ae115bc7Smrj
22547c478bd9Sstevel@tonic-gate#endif	/* __lint */
22557c478bd9Sstevel@tonic-gate
22567c478bd9Sstevel@tonic-gate#if defined(__lint)
22577c478bd9Sstevel@tonic-gate
22587c478bd9Sstevel@tonic-gatedtrace_icookie_t
22597c478bd9Sstevel@tonic-gatedtrace_interrupt_disable(void)
22607c478bd9Sstevel@tonic-gate{ return (0); }
22617c478bd9Sstevel@tonic-gate
22627c478bd9Sstevel@tonic-gate#else   /* __lint */
22637c478bd9Sstevel@tonic-gate
22647c478bd9Sstevel@tonic-gate#if defined(__amd64)
22657c478bd9Sstevel@tonic-gate
22667c478bd9Sstevel@tonic-gate	ENTRY(dtrace_interrupt_disable)
22677c478bd9Sstevel@tonic-gate	pushfq
22687c478bd9Sstevel@tonic-gate	popq	%rax
2269843e1988Sjohnlev#if defined(__xpv)
2270843e1988Sjohnlev	leaq	xpv_panicking, %rdi
2271843e1988Sjohnlev	movl	(%rdi), %edi
2272843e1988Sjohnlev	cmpl	$0, %edi
2273e4b86885SCheng Sean Ye	jne	.dtrace_interrupt_disable_done
2274843e1988Sjohnlev	CLIRET(%rdi, %dl)	/* returns event mask in %dl */
2275843e1988Sjohnlev	/*
2276843e1988Sjohnlev	 * Synthesize the PS_IE bit from the event mask bit
2277843e1988Sjohnlev	 */
2278843e1988Sjohnlev	andq    $_BITNOT(PS_IE), %rax
2279843e1988Sjohnlev	testb	$1, %dl
2280e4b86885SCheng Sean Ye	jnz	.dtrace_interrupt_disable_done
2281843e1988Sjohnlev	orq	$PS_IE, %rax
2282843e1988Sjohnlev#else
2283ae115bc7Smrj	CLI(%rdx)
2284843e1988Sjohnlev#endif
2285e4b86885SCheng Sean Ye.dtrace_interrupt_disable_done:
22867c478bd9Sstevel@tonic-gate	ret
22877c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_interrupt_disable)
22887c478bd9Sstevel@tonic-gate
22897c478bd9Sstevel@tonic-gate#elif defined(__i386)
22907c478bd9Sstevel@tonic-gate
22917c478bd9Sstevel@tonic-gate	ENTRY(dtrace_interrupt_disable)
22927c478bd9Sstevel@tonic-gate	pushfl
22937c478bd9Sstevel@tonic-gate	popl	%eax
2294843e1988Sjohnlev#if defined(__xpv)
2295843e1988Sjohnlev	leal	xpv_panicking, %edx
2296843e1988Sjohnlev	movl	(%edx), %edx
2297843e1988Sjohnlev	cmpl	$0, %edx
2298e4b86885SCheng Sean Ye	jne	.dtrace_interrupt_disable_done
2299843e1988Sjohnlev	CLIRET(%edx, %cl)	/* returns event mask in %cl */
2300843e1988Sjohnlev	/*
2301843e1988Sjohnlev	 * Synthesize the PS_IE bit from the event mask bit
2302843e1988Sjohnlev	 */
2303843e1988Sjohnlev	andl    $_BITNOT(PS_IE), %eax
2304843e1988Sjohnlev	testb	$1, %cl
2305e4b86885SCheng Sean Ye	jnz	.dtrace_interrupt_disable_done
2306843e1988Sjohnlev	orl	$PS_IE, %eax
2307843e1988Sjohnlev#else
2308ae115bc7Smrj	CLI(%edx)
2309843e1988Sjohnlev#endif
2310e4b86885SCheng Sean Ye.dtrace_interrupt_disable_done:
23117c478bd9Sstevel@tonic-gate	ret
23127c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_interrupt_disable)
23137c478bd9Sstevel@tonic-gate
23147c478bd9Sstevel@tonic-gate#endif	/* __i386 */
23157c478bd9Sstevel@tonic-gate#endif	/* __lint */
23167c478bd9Sstevel@tonic-gate
23177c478bd9Sstevel@tonic-gate#if defined(__lint)
23187c478bd9Sstevel@tonic-gate
23197c478bd9Sstevel@tonic-gate/*ARGSUSED*/
23207c478bd9Sstevel@tonic-gatevoid
23217c478bd9Sstevel@tonic-gatedtrace_interrupt_enable(dtrace_icookie_t cookie)
23227c478bd9Sstevel@tonic-gate{}
23237c478bd9Sstevel@tonic-gate
23247c478bd9Sstevel@tonic-gate#else	/* __lint */
23257c478bd9Sstevel@tonic-gate
23267c478bd9Sstevel@tonic-gate#if defined(__amd64)
23277c478bd9Sstevel@tonic-gate
23287c478bd9Sstevel@tonic-gate	ENTRY(dtrace_interrupt_enable)
23297c478bd9Sstevel@tonic-gate	pushq	%rdi
23307c478bd9Sstevel@tonic-gate	popfq
2331843e1988Sjohnlev#if defined(__xpv)
2332843e1988Sjohnlev	leaq	xpv_panicking, %rdx
2333843e1988Sjohnlev	movl	(%rdx), %edx
2334843e1988Sjohnlev	cmpl	$0, %edx
2335e4b86885SCheng Sean Ye	jne	.dtrace_interrupt_enable_done
2336843e1988Sjohnlev	/*
2337843e1988Sjohnlev	 * Since we're -really- running unprivileged, our attempt
2338843e1988Sjohnlev	 * to change the state of the IF bit will be ignored. The
2339843e1988Sjohnlev	 * virtual IF bit is tweaked by CLI and STI.
2340843e1988Sjohnlev	 */
2341843e1988Sjohnlev	IE_TO_EVENT_MASK(%rdx, %rdi)
2342843e1988Sjohnlev#endif
2343e4b86885SCheng Sean Ye.dtrace_interrupt_enable_done:
23447c478bd9Sstevel@tonic-gate	ret
23457c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_interrupt_enable)
23467c478bd9Sstevel@tonic-gate
23477c478bd9Sstevel@tonic-gate#elif defined(__i386)
23487c478bd9Sstevel@tonic-gate
23497c478bd9Sstevel@tonic-gate	ENTRY(dtrace_interrupt_enable)
23507c478bd9Sstevel@tonic-gate	movl	4(%esp), %eax
23517c478bd9Sstevel@tonic-gate	pushl	%eax
23527c478bd9Sstevel@tonic-gate	popfl
2353843e1988Sjohnlev#if defined(__xpv)
2354843e1988Sjohnlev	leal	xpv_panicking, %edx
2355843e1988Sjohnlev	movl	(%edx), %edx
2356843e1988Sjohnlev	cmpl	$0, %edx
2357e4b86885SCheng Sean Ye	jne	.dtrace_interrupt_enable_done
2358843e1988Sjohnlev	/*
2359843e1988Sjohnlev	 * Since we're -really- running unprivileged, our attempt
2360843e1988Sjohnlev	 * to change the state of the IF bit will be ignored. The
2361843e1988Sjohnlev	 * virtual IF bit is tweaked by CLI and STI.
2362843e1988Sjohnlev	 */
2363843e1988Sjohnlev	IE_TO_EVENT_MASK(%edx, %eax)
2364843e1988Sjohnlev#endif
2365e4b86885SCheng Sean Ye.dtrace_interrupt_enable_done:
23667c478bd9Sstevel@tonic-gate	ret
23677c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_interrupt_enable)
23687c478bd9Sstevel@tonic-gate
23697c478bd9Sstevel@tonic-gate#endif	/* __i386 */
23707c478bd9Sstevel@tonic-gate#endif	/* __lint */
23717c478bd9Sstevel@tonic-gate
23727c478bd9Sstevel@tonic-gate
23737c478bd9Sstevel@tonic-gate#if defined(lint)
23747c478bd9Sstevel@tonic-gate
23757c478bd9Sstevel@tonic-gatevoid
23767c478bd9Sstevel@tonic-gatedtrace_membar_producer(void)
23777c478bd9Sstevel@tonic-gate{}
23787c478bd9Sstevel@tonic-gate
23797c478bd9Sstevel@tonic-gatevoid
23807c478bd9Sstevel@tonic-gatedtrace_membar_consumer(void)
23817c478bd9Sstevel@tonic-gate{}
23827c478bd9Sstevel@tonic-gate
23837c478bd9Sstevel@tonic-gate#else	/* __lint */
23847c478bd9Sstevel@tonic-gate
23857c478bd9Sstevel@tonic-gate	ENTRY(dtrace_membar_producer)
238685641879Skalai	rep;	ret	/* use 2 byte return instruction when branch target */
238785641879Skalai			/* AMD Software Optimization Guide - Section 6.2 */
23887c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_membar_producer)
23897c478bd9Sstevel@tonic-gate
23907c478bd9Sstevel@tonic-gate	ENTRY(dtrace_membar_consumer)
239185641879Skalai	rep;	ret	/* use 2 byte return instruction when branch target */
239285641879Skalai			/* AMD Software Optimization Guide - Section 6.2 */
23937c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_membar_consumer)
23947c478bd9Sstevel@tonic-gate
23957c478bd9Sstevel@tonic-gate#endif	/* __lint */
23967c478bd9Sstevel@tonic-gate
23977c478bd9Sstevel@tonic-gate#if defined(__lint)
23987c478bd9Sstevel@tonic-gate
23997c478bd9Sstevel@tonic-gatekthread_id_t
24007c478bd9Sstevel@tonic-gatethreadp(void)
24017c478bd9Sstevel@tonic-gate{ return ((kthread_id_t)0); }
24027c478bd9Sstevel@tonic-gate
24037c478bd9Sstevel@tonic-gate#else	/* __lint */
24047c478bd9Sstevel@tonic-gate
24057c478bd9Sstevel@tonic-gate#if defined(__amd64)
24067c478bd9Sstevel@tonic-gate
24077c478bd9Sstevel@tonic-gate	ENTRY(threadp)
24087c478bd9Sstevel@tonic-gate	movq	%gs:CPU_THREAD, %rax
24097c478bd9Sstevel@tonic-gate	ret
24107c478bd9Sstevel@tonic-gate	SET_SIZE(threadp)
24117c478bd9Sstevel@tonic-gate
24127c478bd9Sstevel@tonic-gate#elif defined(__i386)
24137c478bd9Sstevel@tonic-gate
24147c478bd9Sstevel@tonic-gate	ENTRY(threadp)
24157c478bd9Sstevel@tonic-gate	movl	%gs:CPU_THREAD, %eax
24167c478bd9Sstevel@tonic-gate	ret
24177c478bd9Sstevel@tonic-gate	SET_SIZE(threadp)
24187c478bd9Sstevel@tonic-gate
24197c478bd9Sstevel@tonic-gate#endif	/* __i386 */
24207c478bd9Sstevel@tonic-gate#endif	/* __lint */
24217c478bd9Sstevel@tonic-gate
24227c478bd9Sstevel@tonic-gate/*
24237c478bd9Sstevel@tonic-gate *   Checksum routine for Internet Protocol Headers
24247c478bd9Sstevel@tonic-gate */
24257c478bd9Sstevel@tonic-gate
24267c478bd9Sstevel@tonic-gate#if defined(__lint)
24277c478bd9Sstevel@tonic-gate
24287c478bd9Sstevel@tonic-gate/* ARGSUSED */
24297c478bd9Sstevel@tonic-gateunsigned int
24307c478bd9Sstevel@tonic-gateip_ocsum(
24317c478bd9Sstevel@tonic-gate	ushort_t *address,	/* ptr to 1st message buffer */
24327c478bd9Sstevel@tonic-gate	int halfword_count,	/* length of data */
24337c478bd9Sstevel@tonic-gate	unsigned int sum)	/* partial checksum */
24347c478bd9Sstevel@tonic-gate{
24357c478bd9Sstevel@tonic-gate	int		i;
24367c478bd9Sstevel@tonic-gate	unsigned int	psum = 0;	/* partial sum */
24377c478bd9Sstevel@tonic-gate
24387c478bd9Sstevel@tonic-gate	for (i = 0; i < halfword_count; i++, address++) {
24397c478bd9Sstevel@tonic-gate		psum += *address;
24407c478bd9Sstevel@tonic-gate	}
24417c478bd9Sstevel@tonic-gate
24427c478bd9Sstevel@tonic-gate	while ((psum >> 16) != 0) {
24437c478bd9Sstevel@tonic-gate		psum = (psum & 0xffff) + (psum >> 16);
24447c478bd9Sstevel@tonic-gate	}
24457c478bd9Sstevel@tonic-gate
24467c478bd9Sstevel@tonic-gate	psum += sum;
24477c478bd9Sstevel@tonic-gate
24487c478bd9Sstevel@tonic-gate	while ((psum >> 16) != 0) {
24497c478bd9Sstevel@tonic-gate		psum = (psum & 0xffff) + (psum >> 16);
24507c478bd9Sstevel@tonic-gate	}
24517c478bd9Sstevel@tonic-gate
24527c478bd9Sstevel@tonic-gate	return (psum);
24537c478bd9Sstevel@tonic-gate}
24547c478bd9Sstevel@tonic-gate
24557c478bd9Sstevel@tonic-gate#else	/* __lint */
24567c478bd9Sstevel@tonic-gate
24577c478bd9Sstevel@tonic-gate#if defined(__amd64)
24587c478bd9Sstevel@tonic-gate
24597c478bd9Sstevel@tonic-gate	ENTRY(ip_ocsum)
24607c478bd9Sstevel@tonic-gate	pushq	%rbp
24617c478bd9Sstevel@tonic-gate	movq	%rsp, %rbp
24627c478bd9Sstevel@tonic-gate#ifdef DEBUG
2463ae115bc7Smrj	movq	postbootkernelbase(%rip), %rax
24647c478bd9Sstevel@tonic-gate	cmpq	%rax, %rdi
24657c478bd9Sstevel@tonic-gate	jnb	1f
24667c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
24677c478bd9Sstevel@tonic-gate	movq	%rdi, %rsi
24687c478bd9Sstevel@tonic-gate	leaq	.ip_ocsum_panic_msg(%rip), %rdi
24697c478bd9Sstevel@tonic-gate	call	panic
24707c478bd9Sstevel@tonic-gate	/*NOTREACHED*/
24717c478bd9Sstevel@tonic-gate.ip_ocsum_panic_msg:
24727c478bd9Sstevel@tonic-gate	.string	"ip_ocsum: address 0x%p below kernelbase\n"
24737c478bd9Sstevel@tonic-gate1:
24747c478bd9Sstevel@tonic-gate#endif
24757c478bd9Sstevel@tonic-gate	movl	%esi, %ecx	/* halfword_count */
24767c478bd9Sstevel@tonic-gate	movq	%rdi, %rsi	/* address */
24777c478bd9Sstevel@tonic-gate				/* partial sum in %edx */
24787c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
24797c478bd9Sstevel@tonic-gate	testl	%ecx, %ecx
24807c478bd9Sstevel@tonic-gate	jz	.ip_ocsum_done
24817c478bd9Sstevel@tonic-gate	testq	$3, %rsi
24827c478bd9Sstevel@tonic-gate	jnz	.ip_csum_notaligned
24837c478bd9Sstevel@tonic-gate.ip_csum_aligned:	/* XX64 opportunities for 8-byte operations? */
24847c478bd9Sstevel@tonic-gate.next_iter:
24857c478bd9Sstevel@tonic-gate	/* XX64 opportunities for prefetch? */
24867c478bd9Sstevel@tonic-gate	/* XX64 compute csum with 64 bit quantities? */
24877c478bd9Sstevel@tonic-gate	subl	$32, %ecx
24887c478bd9Sstevel@tonic-gate	jl	.less_than_32
24897c478bd9Sstevel@tonic-gate
24907c478bd9Sstevel@tonic-gate	addl	0(%rsi), %edx
24917c478bd9Sstevel@tonic-gate.only60:
24927c478bd9Sstevel@tonic-gate	adcl	4(%rsi), %eax
24937c478bd9Sstevel@tonic-gate.only56:
24947c478bd9Sstevel@tonic-gate	adcl	8(%rsi), %edx
24957c478bd9Sstevel@tonic-gate.only52:
24967c478bd9Sstevel@tonic-gate	adcl	12(%rsi), %eax
24977c478bd9Sstevel@tonic-gate.only48:
24987c478bd9Sstevel@tonic-gate	adcl	16(%rsi), %edx
24997c478bd9Sstevel@tonic-gate.only44:
25007c478bd9Sstevel@tonic-gate	adcl	20(%rsi), %eax
25017c478bd9Sstevel@tonic-gate.only40:
25027c478bd9Sstevel@tonic-gate	adcl	24(%rsi), %edx
25037c478bd9Sstevel@tonic-gate.only36:
25047c478bd9Sstevel@tonic-gate	adcl	28(%rsi), %eax
25057c478bd9Sstevel@tonic-gate.only32:
25067c478bd9Sstevel@tonic-gate	adcl	32(%rsi), %edx
25077c478bd9Sstevel@tonic-gate.only28:
25087c478bd9Sstevel@tonic-gate	adcl	36(%rsi), %eax
25097c478bd9Sstevel@tonic-gate.only24:
25107c478bd9Sstevel@tonic-gate	adcl	40(%rsi), %edx
25117c478bd9Sstevel@tonic-gate.only20:
25127c478bd9Sstevel@tonic-gate	adcl	44(%rsi), %eax
25137c478bd9Sstevel@tonic-gate.only16:
25147c478bd9Sstevel@tonic-gate	adcl	48(%rsi), %edx
25157c478bd9Sstevel@tonic-gate.only12:
25167c478bd9Sstevel@tonic-gate	adcl	52(%rsi), %eax
25177c478bd9Sstevel@tonic-gate.only8:
25187c478bd9Sstevel@tonic-gate	adcl	56(%rsi), %edx
25197c478bd9Sstevel@tonic-gate.only4:
25207c478bd9Sstevel@tonic-gate	adcl	60(%rsi), %eax	/* could be adding -1 and -1 with a carry */
25217c478bd9Sstevel@tonic-gate.only0:
25227c478bd9Sstevel@tonic-gate	adcl	$0, %eax	/* could be adding -1 in eax with a carry */
25237c478bd9Sstevel@tonic-gate	adcl	$0, %eax
25247c478bd9Sstevel@tonic-gate
25257c478bd9Sstevel@tonic-gate	addq	$64, %rsi
25267c478bd9Sstevel@tonic-gate	testl	%ecx, %ecx
25277c478bd9Sstevel@tonic-gate	jnz	.next_iter
25287c478bd9Sstevel@tonic-gate
25297c478bd9Sstevel@tonic-gate.ip_ocsum_done:
25307c478bd9Sstevel@tonic-gate	addl	%eax, %edx
25317c478bd9Sstevel@tonic-gate	adcl	$0, %edx
25327c478bd9Sstevel@tonic-gate	movl	%edx, %eax	/* form a 16 bit checksum by */
25337c478bd9Sstevel@tonic-gate	shrl	$16, %eax	/* adding two halves of 32 bit checksum */
25347c478bd9Sstevel@tonic-gate	addw	%dx, %ax
25357c478bd9Sstevel@tonic-gate	adcw	$0, %ax
25367c478bd9Sstevel@tonic-gate	andl	$0xffff, %eax
25377c478bd9Sstevel@tonic-gate	leave
25387c478bd9Sstevel@tonic-gate	ret
25397c478bd9Sstevel@tonic-gate
25407c478bd9Sstevel@tonic-gate.ip_csum_notaligned:
25417c478bd9Sstevel@tonic-gate	xorl	%edi, %edi
25427c478bd9Sstevel@tonic-gate	movw	(%rsi), %di
25437c478bd9Sstevel@tonic-gate	addl	%edi, %edx
25447c478bd9Sstevel@tonic-gate	adcl	$0, %edx
25457c478bd9Sstevel@tonic-gate	addq	$2, %rsi
25467c478bd9Sstevel@tonic-gate	decl	%ecx
25477c478bd9Sstevel@tonic-gate	jmp	.ip_csum_aligned
25487c478bd9Sstevel@tonic-gate
25497c478bd9Sstevel@tonic-gate.less_than_32:
25507c478bd9Sstevel@tonic-gate	addl	$32, %ecx
25517c478bd9Sstevel@tonic-gate	testl	$1, %ecx
25527c478bd9Sstevel@tonic-gate	jz	.size_aligned
25537c478bd9Sstevel@tonic-gate	andl	$0xfe, %ecx
25547c478bd9Sstevel@tonic-gate	movzwl	(%rsi, %rcx, 2), %edi
25557c478bd9Sstevel@tonic-gate	addl	%edi, %edx
25567c478bd9Sstevel@tonic-gate	adcl	$0, %edx
25577c478bd9Sstevel@tonic-gate.size_aligned:
25587c478bd9Sstevel@tonic-gate	movl	%ecx, %edi
25597c478bd9Sstevel@tonic-gate	shrl	$1, %ecx
25607c478bd9Sstevel@tonic-gate	shl	$1, %edi
25617c478bd9Sstevel@tonic-gate	subq	$64, %rdi
25627c478bd9Sstevel@tonic-gate	addq	%rdi, %rsi
25637c478bd9Sstevel@tonic-gate	leaq    .ip_ocsum_jmptbl(%rip), %rdi
25647c478bd9Sstevel@tonic-gate	leaq	(%rdi, %rcx, 8), %rdi
25657c478bd9Sstevel@tonic-gate	xorl	%ecx, %ecx
25667c478bd9Sstevel@tonic-gate	clc
25677c478bd9Sstevel@tonic-gate	jmp 	*(%rdi)
25687c478bd9Sstevel@tonic-gate
25697c478bd9Sstevel@tonic-gate	.align	8
25707c478bd9Sstevel@tonic-gate.ip_ocsum_jmptbl:
25717c478bd9Sstevel@tonic-gate	.quad	.only0, .only4, .only8, .only12, .only16, .only20
25727c478bd9Sstevel@tonic-gate	.quad	.only24, .only28, .only32, .only36, .only40, .only44
25737c478bd9Sstevel@tonic-gate	.quad	.only48, .only52, .only56, .only60
25747c478bd9Sstevel@tonic-gate	SET_SIZE(ip_ocsum)
25757c478bd9Sstevel@tonic-gate
25767c478bd9Sstevel@tonic-gate#elif defined(__i386)
25777c478bd9Sstevel@tonic-gate
25787c478bd9Sstevel@tonic-gate	ENTRY(ip_ocsum)
25797c478bd9Sstevel@tonic-gate	pushl	%ebp
25807c478bd9Sstevel@tonic-gate	movl	%esp, %ebp
25817c478bd9Sstevel@tonic-gate	pushl	%ebx
25827c478bd9Sstevel@tonic-gate	pushl	%esi
25837c478bd9Sstevel@tonic-gate	pushl	%edi
25847c478bd9Sstevel@tonic-gate	movl	12(%ebp), %ecx	/* count of half words */
25857c478bd9Sstevel@tonic-gate	movl	16(%ebp), %edx	/* partial checksum */
25867c478bd9Sstevel@tonic-gate	movl	8(%ebp), %esi
25877c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
25887c478bd9Sstevel@tonic-gate	testl	%ecx, %ecx
25897c478bd9Sstevel@tonic-gate	jz	.ip_ocsum_done
25907c478bd9Sstevel@tonic-gate
25917c478bd9Sstevel@tonic-gate	testl	$3, %esi
25927c478bd9Sstevel@tonic-gate	jnz	.ip_csum_notaligned
25937c478bd9Sstevel@tonic-gate.ip_csum_aligned:
25947c478bd9Sstevel@tonic-gate.next_iter:
25957c478bd9Sstevel@tonic-gate	subl	$32, %ecx
25967c478bd9Sstevel@tonic-gate	jl	.less_than_32
25977c478bd9Sstevel@tonic-gate
25987c478bd9Sstevel@tonic-gate	addl	0(%esi), %edx
25997c478bd9Sstevel@tonic-gate.only60:
26007c478bd9Sstevel@tonic-gate	adcl	4(%esi), %eax
26017c478bd9Sstevel@tonic-gate.only56:
26027c478bd9Sstevel@tonic-gate	adcl	8(%esi), %edx
26037c478bd9Sstevel@tonic-gate.only52:
26047c478bd9Sstevel@tonic-gate	adcl	12(%esi), %eax
26057c478bd9Sstevel@tonic-gate.only48:
26067c478bd9Sstevel@tonic-gate	adcl	16(%esi), %edx
26077c478bd9Sstevel@tonic-gate.only44:
26087c478bd9Sstevel@tonic-gate	adcl	20(%esi), %eax
26097c478bd9Sstevel@tonic-gate.only40:
26107c478bd9Sstevel@tonic-gate	adcl	24(%esi), %edx
26117c478bd9Sstevel@tonic-gate.only36:
26127c478bd9Sstevel@tonic-gate	adcl	28(%esi), %eax
26137c478bd9Sstevel@tonic-gate.only32:
26147c478bd9Sstevel@tonic-gate	adcl	32(%esi), %edx
26157c478bd9Sstevel@tonic-gate.only28:
26167c478bd9Sstevel@tonic-gate	adcl	36(%esi), %eax
26177c478bd9Sstevel@tonic-gate.only24:
26187c478bd9Sstevel@tonic-gate	adcl	40(%esi), %edx
26197c478bd9Sstevel@tonic-gate.only20:
26207c478bd9Sstevel@tonic-gate	adcl	44(%esi), %eax
26217c478bd9Sstevel@tonic-gate.only16:
26227c478bd9Sstevel@tonic-gate	adcl	48(%esi), %edx
26237c478bd9Sstevel@tonic-gate.only12:
26247c478bd9Sstevel@tonic-gate	adcl	52(%esi), %eax
26257c478bd9Sstevel@tonic-gate.only8:
26267c478bd9Sstevel@tonic-gate	adcl	56(%esi), %edx
26277c478bd9Sstevel@tonic-gate.only4:
26287c478bd9Sstevel@tonic-gate	adcl	60(%esi), %eax	/* We could be adding -1 and -1 with a carry */
26297c478bd9Sstevel@tonic-gate.only0:
26307c478bd9Sstevel@tonic-gate	adcl	$0, %eax	/* we could be adding -1 in eax with a carry */
26317c478bd9Sstevel@tonic-gate	adcl	$0, %eax
26327c478bd9Sstevel@tonic-gate
26337c478bd9Sstevel@tonic-gate	addl	$64, %esi
26347c478bd9Sstevel@tonic-gate	andl	%ecx, %ecx
26357c478bd9Sstevel@tonic-gate	jnz	.next_iter
26367c478bd9Sstevel@tonic-gate
26377c478bd9Sstevel@tonic-gate.ip_ocsum_done:
26387c478bd9Sstevel@tonic-gate	addl	%eax, %edx
26397c478bd9Sstevel@tonic-gate	adcl	$0, %edx
26407c478bd9Sstevel@tonic-gate	movl	%edx, %eax	/* form a 16 bit checksum by */
26417c478bd9Sstevel@tonic-gate	shrl	$16, %eax	/* adding two halves of 32 bit checksum */
26427c478bd9Sstevel@tonic-gate	addw	%dx, %ax
26437c478bd9Sstevel@tonic-gate	adcw	$0, %ax
26447c478bd9Sstevel@tonic-gate	andl	$0xffff, %eax
26457c478bd9Sstevel@tonic-gate	popl	%edi		/* restore registers */
26467c478bd9Sstevel@tonic-gate	popl	%esi
26477c478bd9Sstevel@tonic-gate	popl	%ebx
26487c478bd9Sstevel@tonic-gate	leave
26497c478bd9Sstevel@tonic-gate	ret
26507c478bd9Sstevel@tonic-gate
26517c478bd9Sstevel@tonic-gate.ip_csum_notaligned:
26527c478bd9Sstevel@tonic-gate	xorl	%edi, %edi
26537c478bd9Sstevel@tonic-gate	movw	(%esi), %di
26547c478bd9Sstevel@tonic-gate	addl	%edi, %edx
26557c478bd9Sstevel@tonic-gate	adcl	$0, %edx
26567c478bd9Sstevel@tonic-gate	addl	$2, %esi
26577c478bd9Sstevel@tonic-gate	decl	%ecx
26587c478bd9Sstevel@tonic-gate	jmp	.ip_csum_aligned
26597c478bd9Sstevel@tonic-gate
26607c478bd9Sstevel@tonic-gate.less_than_32:
26617c478bd9Sstevel@tonic-gate	addl	$32, %ecx
26627c478bd9Sstevel@tonic-gate	testl	$1, %ecx
26637c478bd9Sstevel@tonic-gate	jz	.size_aligned
26647c478bd9Sstevel@tonic-gate	andl	$0xfe, %ecx
26657c478bd9Sstevel@tonic-gate	movzwl	(%esi, %ecx, 2), %edi
26667c478bd9Sstevel@tonic-gate	addl	%edi, %edx
26677c478bd9Sstevel@tonic-gate	adcl	$0, %edx
26687c478bd9Sstevel@tonic-gate.size_aligned:
26697c478bd9Sstevel@tonic-gate	movl	%ecx, %edi
26707c478bd9Sstevel@tonic-gate	shrl	$1, %ecx
26717c478bd9Sstevel@tonic-gate	shl	$1, %edi
26727c478bd9Sstevel@tonic-gate	subl	$64, %edi
26737c478bd9Sstevel@tonic-gate	addl	%edi, %esi
26747c478bd9Sstevel@tonic-gate	movl	$.ip_ocsum_jmptbl, %edi
26757c478bd9Sstevel@tonic-gate	lea	(%edi, %ecx, 4), %edi
26767c478bd9Sstevel@tonic-gate	xorl	%ecx, %ecx
26777c478bd9Sstevel@tonic-gate	clc
26787c478bd9Sstevel@tonic-gate	jmp 	*(%edi)
26797c478bd9Sstevel@tonic-gate	SET_SIZE(ip_ocsum)
26807c478bd9Sstevel@tonic-gate
26817c478bd9Sstevel@tonic-gate	.data
26827c478bd9Sstevel@tonic-gate	.align	4
26837c478bd9Sstevel@tonic-gate
26847c478bd9Sstevel@tonic-gate.ip_ocsum_jmptbl:
26857c478bd9Sstevel@tonic-gate	.long	.only0, .only4, .only8, .only12, .only16, .only20
26867c478bd9Sstevel@tonic-gate	.long	.only24, .only28, .only32, .only36, .only40, .only44
26877c478bd9Sstevel@tonic-gate	.long	.only48, .only52, .only56, .only60
26887c478bd9Sstevel@tonic-gate
26897c478bd9Sstevel@tonic-gate
26907c478bd9Sstevel@tonic-gate#endif	/* __i386 */
26917c478bd9Sstevel@tonic-gate#endif	/* __lint */
26927c478bd9Sstevel@tonic-gate
26937c478bd9Sstevel@tonic-gate/*
26947c478bd9Sstevel@tonic-gate * multiply two long numbers and yield a u_longlong_t result, callable from C.
26957c478bd9Sstevel@tonic-gate * Provided to manipulate hrtime_t values.
26967c478bd9Sstevel@tonic-gate */
26977c478bd9Sstevel@tonic-gate#if defined(__lint)
26987c478bd9Sstevel@tonic-gate
26997c478bd9Sstevel@tonic-gate/* result = a * b; */
27007c478bd9Sstevel@tonic-gate
27017c478bd9Sstevel@tonic-gate/* ARGSUSED */
27027c478bd9Sstevel@tonic-gateunsigned long long
27037c478bd9Sstevel@tonic-gatemul32(uint_t a, uint_t b)
27047c478bd9Sstevel@tonic-gate{ return (0); }
27057c478bd9Sstevel@tonic-gate
27067c478bd9Sstevel@tonic-gate#else	/* __lint */
27077c478bd9Sstevel@tonic-gate
27087c478bd9Sstevel@tonic-gate#if defined(__amd64)
27097c478bd9Sstevel@tonic-gate
27107c478bd9Sstevel@tonic-gate	ENTRY(mul32)
27117c478bd9Sstevel@tonic-gate	xorl	%edx, %edx	/* XX64 joe, paranoia? */
27127c478bd9Sstevel@tonic-gate	movl	%edi, %eax
27137c478bd9Sstevel@tonic-gate	mull	%esi
27147c478bd9Sstevel@tonic-gate	shlq	$32, %rdx
27157c478bd9Sstevel@tonic-gate	orq	%rdx, %rax
27167c478bd9Sstevel@tonic-gate	ret
27177c478bd9Sstevel@tonic-gate	SET_SIZE(mul32)
27187c478bd9Sstevel@tonic-gate
27197c478bd9Sstevel@tonic-gate#elif defined(__i386)
27207c478bd9Sstevel@tonic-gate
27217c478bd9Sstevel@tonic-gate	ENTRY(mul32)
27227c478bd9Sstevel@tonic-gate	movl	8(%esp), %eax
27237c478bd9Sstevel@tonic-gate	movl	4(%esp), %ecx
27247c478bd9Sstevel@tonic-gate	mull	%ecx
27257c478bd9Sstevel@tonic-gate	ret
27267c478bd9Sstevel@tonic-gate	SET_SIZE(mul32)
27277c478bd9Sstevel@tonic-gate
27287c478bd9Sstevel@tonic-gate#endif	/* __i386 */
27297c478bd9Sstevel@tonic-gate#endif	/* __lint */
27307c478bd9Sstevel@tonic-gate
27317c478bd9Sstevel@tonic-gate#if defined(notused)
27327c478bd9Sstevel@tonic-gate#if defined(__lint)
27337c478bd9Sstevel@tonic-gate/* ARGSUSED */
27347c478bd9Sstevel@tonic-gatevoid
27357c478bd9Sstevel@tonic-gateload_pte64(uint64_t *pte, uint64_t pte_value)
27367c478bd9Sstevel@tonic-gate{}
27377c478bd9Sstevel@tonic-gate#else	/* __lint */
27387c478bd9Sstevel@tonic-gate	.globl load_pte64
27397c478bd9Sstevel@tonic-gateload_pte64:
27407c478bd9Sstevel@tonic-gate	movl	4(%esp), %eax
27417c478bd9Sstevel@tonic-gate	movl	8(%esp), %ecx
27427c478bd9Sstevel@tonic-gate	movl	12(%esp), %edx
27437c478bd9Sstevel@tonic-gate	movl	%edx, 4(%eax)
27447c478bd9Sstevel@tonic-gate	movl	%ecx, (%eax)
27457c478bd9Sstevel@tonic-gate	ret
27467c478bd9Sstevel@tonic-gate#endif	/* __lint */
27477c478bd9Sstevel@tonic-gate#endif	/* notused */
27487c478bd9Sstevel@tonic-gate
27497c478bd9Sstevel@tonic-gate#if defined(__lint)
27507c478bd9Sstevel@tonic-gate
27517c478bd9Sstevel@tonic-gate/*ARGSUSED*/
27527c478bd9Sstevel@tonic-gatevoid
27537c478bd9Sstevel@tonic-gatescan_memory(caddr_t addr, size_t size)
27547c478bd9Sstevel@tonic-gate{}
27557c478bd9Sstevel@tonic-gate
27567c478bd9Sstevel@tonic-gate#else	/* __lint */
27577c478bd9Sstevel@tonic-gate
27587c478bd9Sstevel@tonic-gate#if defined(__amd64)
27597c478bd9Sstevel@tonic-gate
27607c478bd9Sstevel@tonic-gate	ENTRY(scan_memory)
27617c478bd9Sstevel@tonic-gate	shrq	$3, %rsi	/* convert %rsi from byte to quadword count */
27627c478bd9Sstevel@tonic-gate	jz	.scanm_done
27637c478bd9Sstevel@tonic-gate	movq	%rsi, %rcx	/* move count into rep control register */
27647c478bd9Sstevel@tonic-gate	movq	%rdi, %rsi	/* move addr into lodsq control reg. */
27657c478bd9Sstevel@tonic-gate	rep lodsq		/* scan the memory range */
27667c478bd9Sstevel@tonic-gate.scanm_done:
276785641879Skalai	rep;	ret	/* use 2 byte return instruction when branch target */
276885641879Skalai			/* AMD Software Optimization Guide - Section 6.2 */
27697c478bd9Sstevel@tonic-gate	SET_SIZE(scan_memory)
27707c478bd9Sstevel@tonic-gate
27717c478bd9Sstevel@tonic-gate#elif defined(__i386)
27727c478bd9Sstevel@tonic-gate
27737c478bd9Sstevel@tonic-gate	ENTRY(scan_memory)
27747c478bd9Sstevel@tonic-gate	pushl	%ecx
27757c478bd9Sstevel@tonic-gate	pushl	%esi
27767c478bd9Sstevel@tonic-gate	movl	16(%esp), %ecx	/* move 2nd arg into rep control register */
27777c478bd9Sstevel@tonic-gate	shrl	$2, %ecx	/* convert from byte count to word count */
27787c478bd9Sstevel@tonic-gate	jz	.scanm_done
27797c478bd9Sstevel@tonic-gate	movl	12(%esp), %esi	/* move 1st arg into lodsw control register */
27807c478bd9Sstevel@tonic-gate	.byte	0xf3		/* rep prefix.  lame assembler.  sigh. */
27817c478bd9Sstevel@tonic-gate	lodsl
27827c478bd9Sstevel@tonic-gate.scanm_done:
27837c478bd9Sstevel@tonic-gate	popl	%esi
27847c478bd9Sstevel@tonic-gate	popl	%ecx
27857c478bd9Sstevel@tonic-gate	ret
27867c478bd9Sstevel@tonic-gate	SET_SIZE(scan_memory)
27877c478bd9Sstevel@tonic-gate
27887c478bd9Sstevel@tonic-gate#endif	/* __i386 */
27897c478bd9Sstevel@tonic-gate#endif	/* __lint */
27907c478bd9Sstevel@tonic-gate
27917c478bd9Sstevel@tonic-gate
27927c478bd9Sstevel@tonic-gate#if defined(__lint)
27937c478bd9Sstevel@tonic-gate
27947c478bd9Sstevel@tonic-gate/*ARGSUSED */
27957c478bd9Sstevel@tonic-gateint
27967c478bd9Sstevel@tonic-gatelowbit(ulong_t i)
27977c478bd9Sstevel@tonic-gate{ return (0); }
27987c478bd9Sstevel@tonic-gate
27997c478bd9Sstevel@tonic-gate#else	/* __lint */
28007c478bd9Sstevel@tonic-gate
28017c478bd9Sstevel@tonic-gate#if defined(__amd64)
28027c478bd9Sstevel@tonic-gate
28037c478bd9Sstevel@tonic-gate	ENTRY(lowbit)
28047c478bd9Sstevel@tonic-gate	movl	$-1, %eax
2805a2c1b589SJosef 'Jeff' Sipek	bsfq	%rdi, %rdi
2806a2c1b589SJosef 'Jeff' Sipek	cmovnz	%edi, %eax
28077c478bd9Sstevel@tonic-gate	incl	%eax
28087c478bd9Sstevel@tonic-gate	ret
28097c478bd9Sstevel@tonic-gate	SET_SIZE(lowbit)
28107c478bd9Sstevel@tonic-gate
28117c478bd9Sstevel@tonic-gate#elif defined(__i386)
28127c478bd9Sstevel@tonic-gate
28137c478bd9Sstevel@tonic-gate	ENTRY(lowbit)
28147c478bd9Sstevel@tonic-gate	bsfl	4(%esp), %eax
2815a2c1b589SJosef 'Jeff' Sipek	jz	0f
28167c478bd9Sstevel@tonic-gate	incl	%eax
28177c478bd9Sstevel@tonic-gate	ret
2818a2c1b589SJosef 'Jeff' Sipek0:
2819a2c1b589SJosef 'Jeff' Sipek	xorl	%eax, %eax
2820a2c1b589SJosef 'Jeff' Sipek	ret
28217c478bd9Sstevel@tonic-gate	SET_SIZE(lowbit)
28227c478bd9Sstevel@tonic-gate
28237c478bd9Sstevel@tonic-gate#endif	/* __i386 */
28247c478bd9Sstevel@tonic-gate#endif	/* __lint */
28257c478bd9Sstevel@tonic-gate
28267c478bd9Sstevel@tonic-gate#if defined(__lint)
28277c478bd9Sstevel@tonic-gate
28287c478bd9Sstevel@tonic-gate/*ARGSUSED*/
28297c478bd9Sstevel@tonic-gateint
28307c478bd9Sstevel@tonic-gatehighbit(ulong_t i)
28317c478bd9Sstevel@tonic-gate{ return (0); }
28327c478bd9Sstevel@tonic-gate
28337c478bd9Sstevel@tonic-gate/*ARGSUSED*/
2834887cdfc7SMatthew Ahrensint
2835887cdfc7SMatthew Ahrenshighbit64(uint64_t i)
2836887cdfc7SMatthew Ahrens{ return (0); }
2837887cdfc7SMatthew Ahrens
2838887cdfc7SMatthew Ahrens#else	/* __lint */
2839887cdfc7SMatthew Ahrens
2840887cdfc7SMatthew Ahrens#if defined(__amd64)
2841887cdfc7SMatthew Ahrens
2842a2c1b589SJosef 'Jeff' Sipek	ENTRY(highbit)
2843a2c1b589SJosef 'Jeff' Sipek	ALTENTRY(highbit64)
2844887cdfc7SMatthew Ahrens	movl	$-1, %eax
2845a2c1b589SJosef 'Jeff' Sipek	bsrq	%rdi, %rdi
2846a2c1b589SJosef 'Jeff' Sipek	cmovnz	%edi, %eax
2847887cdfc7SMatthew Ahrens	incl	%eax
2848887cdfc7SMatthew Ahrens	ret
2849887cdfc7SMatthew Ahrens	SET_SIZE(highbit64)
2850a2c1b589SJosef 'Jeff' Sipek	SET_SIZE(highbit)
2851887cdfc7SMatthew Ahrens
2852887cdfc7SMatthew Ahrens#elif defined(__i386)
2853887cdfc7SMatthew Ahrens
2854a2c1b589SJosef 'Jeff' Sipek	ENTRY(highbit)
2855a2c1b589SJosef 'Jeff' Sipek	bsrl	4(%esp), %eax
2856a2c1b589SJosef 'Jeff' Sipek	jz	0f
2857a2c1b589SJosef 'Jeff' Sipek	incl	%eax
2858a2c1b589SJosef 'Jeff' Sipek	ret
2859a2c1b589SJosef 'Jeff' Sipek0:
2860a2c1b589SJosef 'Jeff' Sipek	xorl	%eax, %eax
2861a2c1b589SJosef 'Jeff' Sipek	ret
2862a2c1b589SJosef 'Jeff' Sipek	SET_SIZE(highbit)
2863a2c1b589SJosef 'Jeff' Sipek
2864887cdfc7SMatthew Ahrens	ENTRY(highbit64)
2865887cdfc7SMatthew Ahrens	bsrl	8(%esp), %eax
2866a2c1b589SJosef 'Jeff' Sipek	jz	highbit
2867a2c1b589SJosef 'Jeff' Sipek	addl	$33, %eax
2868887cdfc7SMatthew Ahrens	ret
2869887cdfc7SMatthew Ahrens	SET_SIZE(highbit64)
2870887cdfc7SMatthew Ahrens
2871887cdfc7SMatthew Ahrens#endif	/* __i386 */
2872887cdfc7SMatthew Ahrens#endif	/* __lint */
2873887cdfc7SMatthew Ahrens
2874887cdfc7SMatthew Ahrens#if defined(__lint)
2875887cdfc7SMatthew Ahrens
2876887cdfc7SMatthew Ahrens/*ARGSUSED*/
28777c478bd9Sstevel@tonic-gateuint64_t
28780ac7d7d8Skucharskrdmsr(uint_t r)
28797c478bd9Sstevel@tonic-gate{ return (0); }
28807c478bd9Sstevel@tonic-gate
28817c478bd9Sstevel@tonic-gate/*ARGSUSED*/
28827c478bd9Sstevel@tonic-gatevoid
28830ac7d7d8Skucharskwrmsr(uint_t r, const uint64_t val)
28847c478bd9Sstevel@tonic-gate{}
28857c478bd9Sstevel@tonic-gate
2886ee88d2b9Skchow/*ARGSUSED*/
2887ee88d2b9Skchowuint64_t
2888ee88d2b9Skchowxrdmsr(uint_t r)
2889ee88d2b9Skchow{ return (0); }
2890ee88d2b9Skchow
2891ee88d2b9Skchow/*ARGSUSED*/
2892ee88d2b9Skchowvoid
2893ee88d2b9Skchowxwrmsr(uint_t r, const uint64_t val)
2894ee88d2b9Skchow{}
2895ee88d2b9Skchow
28967c478bd9Sstevel@tonic-gatevoid
28977c478bd9Sstevel@tonic-gateinvalidate_cache(void)
28987c478bd9Sstevel@tonic-gate{}
28997c478bd9Sstevel@tonic-gate
29007af88ac7SKuriakose Kuruvilla/*ARGSUSED*/
29017af88ac7SKuriakose Kuruvillauint64_t
29027af88ac7SKuriakose Kuruvillaget_xcr(uint_t r)
29037af88ac7SKuriakose Kuruvilla{ return (0); }
29047af88ac7SKuriakose Kuruvilla
29057af88ac7SKuriakose Kuruvilla/*ARGSUSED*/
29067af88ac7SKuriakose Kuruvillavoid
29077af88ac7SKuriakose Kuruvillaset_xcr(uint_t r, const uint64_t val)
29087af88ac7SKuriakose Kuruvilla{}
29097af88ac7SKuriakose Kuruvilla
29107c478bd9Sstevel@tonic-gate#else  /* __lint */
29117c478bd9Sstevel@tonic-gate
2912ee88d2b9Skchow#define	XMSR_ACCESS_VAL		$0x9c5a203a
29137c478bd9Sstevel@tonic-gate
2914ee88d2b9Skchow#if defined(__amd64)
2915ae115bc7Smrj
29167c478bd9Sstevel@tonic-gate	ENTRY(rdmsr)
29177c478bd9Sstevel@tonic-gate	movl	%edi, %ecx
29187c478bd9Sstevel@tonic-gate	rdmsr
29197c478bd9Sstevel@tonic-gate	shlq	$32, %rdx
29207c478bd9Sstevel@tonic-gate	orq	%rdx, %rax
29217c478bd9Sstevel@tonic-gate	ret
29227c478bd9Sstevel@tonic-gate	SET_SIZE(rdmsr)
29237c478bd9Sstevel@tonic-gate
29247c478bd9Sstevel@tonic-gate	ENTRY(wrmsr)
29250ac7d7d8Skucharsk	movq	%rsi, %rdx
29260ac7d7d8Skucharsk	shrq	$32, %rdx
29270ac7d7d8Skucharsk	movl	%esi, %eax
29287c478bd9Sstevel@tonic-gate	movl	%edi, %ecx
29297c478bd9Sstevel@tonic-gate	wrmsr
29307c478bd9Sstevel@tonic-gate	ret
29317c478bd9Sstevel@tonic-gate	SET_SIZE(wrmsr)
29327c478bd9Sstevel@tonic-gate
2933ee88d2b9Skchow	ENTRY(xrdmsr)
2934ae115bc7Smrj	pushq	%rbp
2935ae115bc7Smrj	movq	%rsp, %rbp
2936ee88d2b9Skchow	movl	%edi, %ecx
2937ee88d2b9Skchow	movl	XMSR_ACCESS_VAL, %edi	/* this value is needed to access MSR */
2938ee88d2b9Skchow	rdmsr
2939ee88d2b9Skchow	shlq	$32, %rdx
2940ee88d2b9Skchow	orq	%rdx, %rax
2941ae115bc7Smrj	leave
2942ee88d2b9Skchow	ret
2943ee88d2b9Skchow	SET_SIZE(xrdmsr)
2944ee88d2b9Skchow
2945ee88d2b9Skchow	ENTRY(xwrmsr)
2946ae115bc7Smrj	pushq	%rbp
2947ae115bc7Smrj	movq	%rsp, %rbp
2948ee88d2b9Skchow	movl	%edi, %ecx
2949ee88d2b9Skchow	movl	XMSR_ACCESS_VAL, %edi	/* this value is needed to access MSR */
2950ee88d2b9Skchow	movq	%rsi, %rdx
2951ee88d2b9Skchow	shrq	$32, %rdx
2952ee88d2b9Skchow	movl	%esi, %eax
2953ee88d2b9Skchow	wrmsr
2954ae115bc7Smrj	leave
2955ee88d2b9Skchow	ret
2956ee88d2b9Skchow	SET_SIZE(xwrmsr)
2957ee88d2b9Skchow
29587af88ac7SKuriakose Kuruvilla	ENTRY(get_xcr)
29597af88ac7SKuriakose Kuruvilla	movl	%edi, %ecx
29607af88ac7SKuriakose Kuruvilla	#xgetbv
29617af88ac7SKuriakose Kuruvilla	.byte	0x0f,0x01,0xd0
29627af88ac7SKuriakose Kuruvilla	shlq	$32, %rdx
29637af88ac7SKuriakose Kuruvilla	orq	%rdx, %rax
29647af88ac7SKuriakose Kuruvilla	ret
29657af88ac7SKuriakose Kuruvilla	SET_SIZE(get_xcr)
29667af88ac7SKuriakose Kuruvilla
29677af88ac7SKuriakose Kuruvilla	ENTRY(set_xcr)
29687af88ac7SKuriakose Kuruvilla	movq	%rsi, %rdx
29697af88ac7SKuriakose Kuruvilla	shrq	$32, %rdx
29707af88ac7SKuriakose Kuruvilla	movl	%esi, %eax
29717af88ac7SKuriakose Kuruvilla	movl	%edi, %ecx
29727af88ac7SKuriakose Kuruvilla	#xsetbv
29737af88ac7SKuriakose Kuruvilla	.byte	0x0f,0x01,0xd1
29747af88ac7SKuriakose Kuruvilla	ret
29757af88ac7SKuriakose Kuruvilla	SET_SIZE(set_xcr)
29767af88ac7SKuriakose Kuruvilla
29777c478bd9Sstevel@tonic-gate#elif defined(__i386)
29787c478bd9Sstevel@tonic-gate
29797c478bd9Sstevel@tonic-gate	ENTRY(rdmsr)
29807c478bd9Sstevel@tonic-gate	movl	4(%esp), %ecx
29817c478bd9Sstevel@tonic-gate	rdmsr
29827c478bd9Sstevel@tonic-gate	ret
29837c478bd9Sstevel@tonic-gate	SET_SIZE(rdmsr)
29847c478bd9Sstevel@tonic-gate
29857c478bd9Sstevel@tonic-gate	ENTRY(wrmsr)
29867c478bd9Sstevel@tonic-gate	movl	4(%esp), %ecx
29870ac7d7d8Skucharsk	movl	8(%esp), %eax
29880ac7d7d8Skucharsk	movl	12(%esp), %edx
29897c478bd9Sstevel@tonic-gate	wrmsr
29907c478bd9Sstevel@tonic-gate	ret
29917c478bd9Sstevel@tonic-gate	SET_SIZE(wrmsr)
29927c478bd9Sstevel@tonic-gate
2993ee88d2b9Skchow	ENTRY(xrdmsr)
2994ae115bc7Smrj	pushl	%ebp
2995ae115bc7Smrj	movl	%esp, %ebp
2996ae115bc7Smrj	movl	8(%esp), %ecx
2997ae115bc7Smrj	pushl	%edi
2998ee88d2b9Skchow	movl	XMSR_ACCESS_VAL, %edi	/* this value is needed to access MSR */
2999ee88d2b9Skchow	rdmsr
3000ae115bc7Smrj	popl	%edi
3001ae115bc7Smrj	leave
3002ee88d2b9Skchow	ret
3003ee88d2b9Skchow	SET_SIZE(xrdmsr)
3004ee88d2b9Skchow
3005ee88d2b9Skchow	ENTRY(xwrmsr)
3006ae115bc7Smrj	pushl	%ebp
3007ae115bc7Smrj	movl	%esp, %ebp
3008ae115bc7Smrj	movl	8(%esp), %ecx
3009ae115bc7Smrj	movl	12(%esp), %eax
3010ae115bc7Smrj	movl	16(%esp), %edx
3011ae115bc7Smrj	pushl	%edi
3012ee88d2b9Skchow	movl	XMSR_ACCESS_VAL, %edi	/* this value is needed to access MSR */
3013ee88d2b9Skchow	wrmsr
3014ae115bc7Smrj	popl	%edi
3015ae115bc7Smrj	leave
3016ee88d2b9Skchow	ret
3017ee88d2b9Skchow	SET_SIZE(xwrmsr)
3018ee88d2b9Skchow
30197af88ac7SKuriakose Kuruvilla	ENTRY(get_xcr)
30207af88ac7SKuriakose Kuruvilla	movl	4(%esp), %ecx
30217af88ac7SKuriakose Kuruvilla	#xgetbv
30227af88ac7SKuriakose Kuruvilla	.byte	0x0f,0x01,0xd0
30237af88ac7SKuriakose Kuruvilla	ret
30247af88ac7SKuriakose Kuruvilla	SET_SIZE(get_xcr)
30257af88ac7SKuriakose Kuruvilla
30267af88ac7SKuriakose Kuruvilla	ENTRY(set_xcr)
30277af88ac7SKuriakose Kuruvilla	movl	4(%esp), %ecx
30287af88ac7SKuriakose Kuruvilla	movl	8(%esp), %eax
30297af88ac7SKuriakose Kuruvilla	movl	12(%esp), %edx
30307af88ac7SKuriakose Kuruvilla	#xsetbv
30317af88ac7SKuriakose Kuruvilla	.byte	0x0f,0x01,0xd1
30327af88ac7SKuriakose Kuruvilla	ret
30337af88ac7SKuriakose Kuruvilla	SET_SIZE(set_xcr)
30347af88ac7SKuriakose Kuruvilla
30357c478bd9Sstevel@tonic-gate#endif	/* __i386 */
30367c478bd9Sstevel@tonic-gate
30377c478bd9Sstevel@tonic-gate	ENTRY(invalidate_cache)
30387c478bd9Sstevel@tonic-gate	wbinvd
30397c478bd9Sstevel@tonic-gate	ret
30407c478bd9Sstevel@tonic-gate	SET_SIZE(invalidate_cache)
30417c478bd9Sstevel@tonic-gate
30427c478bd9Sstevel@tonic-gate#endif	/* __lint */
30437c478bd9Sstevel@tonic-gate
30447c478bd9Sstevel@tonic-gate#if defined(__lint)
30457c478bd9Sstevel@tonic-gate
30467c478bd9Sstevel@tonic-gate/*ARGSUSED*/
3047ae115bc7Smrjvoid
3048ae115bc7Smrjgetcregs(struct cregs *crp)
30497c478bd9Sstevel@tonic-gate{}
30507c478bd9Sstevel@tonic-gate
30517c478bd9Sstevel@tonic-gate#else	/* __lint */
30527c478bd9Sstevel@tonic-gate
30537c478bd9Sstevel@tonic-gate#if defined(__amd64)
30547c478bd9Sstevel@tonic-gate
3055ae115bc7Smrj	ENTRY_NP(getcregs)
3056843e1988Sjohnlev#if defined(__xpv)
3057843e1988Sjohnlev	/*
3058843e1988Sjohnlev	 * Only a few of the hardware control registers or descriptor tables
3059843e1988Sjohnlev	 * are directly accessible to us, so just zero the structure.
3060843e1988Sjohnlev	 *
3061843e1988Sjohnlev	 * XXPV	Perhaps it would be helpful for the hypervisor to return
3062843e1988Sjohnlev	 *	virtualized versions of these for post-mortem use.
3063843e1988Sjohnlev	 *	(Need to reevaluate - perhaps it already does!)
3064843e1988Sjohnlev	 */
3065843e1988Sjohnlev	pushq	%rdi		/* save *crp */
3066843e1988Sjohnlev	movq	$CREGSZ, %rsi
3067843e1988Sjohnlev	call	bzero
3068843e1988Sjohnlev	popq	%rdi
3069843e1988Sjohnlev
3070843e1988Sjohnlev	/*
3071843e1988Sjohnlev	 * Dump what limited information we can
3072843e1988Sjohnlev	 */
3073843e1988Sjohnlev	movq	%cr0, %rax
3074843e1988Sjohnlev	movq	%rax, CREG_CR0(%rdi)	/* cr0 */
3075843e1988Sjohnlev	movq	%cr2, %rax
3076843e1988Sjohnlev	movq	%rax, CREG_CR2(%rdi)	/* cr2 */
3077843e1988Sjohnlev	movq	%cr3, %rax
3078843e1988Sjohnlev	movq	%rax, CREG_CR3(%rdi)	/* cr3 */
3079843e1988Sjohnlev	movq	%cr4, %rax
3080843e1988Sjohnlev	movq	%rax, CREG_CR4(%rdi)	/* cr4 */
3081843e1988Sjohnlev
3082843e1988Sjohnlev#else	/* __xpv */
3083ae115bc7Smrj
30847c478bd9Sstevel@tonic-gate#define	GETMSR(r, off, d)	\
30857c478bd9Sstevel@tonic-gate	movl	$r, %ecx;	\
30867c478bd9Sstevel@tonic-gate	rdmsr;			\
30877c478bd9Sstevel@tonic-gate	movl	%eax, off(d);	\
30887c478bd9Sstevel@tonic-gate	movl	%edx, off+4(d)
30897c478bd9Sstevel@tonic-gate
30907c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
30917c478bd9Sstevel@tonic-gate	movq	%rax, CREG_GDT+8(%rdi)
30927c478bd9Sstevel@tonic-gate	sgdt	CREG_GDT(%rdi)		/* 10 bytes */
30937c478bd9Sstevel@tonic-gate	movq	%rax, CREG_IDT+8(%rdi)
30947c478bd9Sstevel@tonic-gate	sidt	CREG_IDT(%rdi)		/* 10 bytes */
30957c478bd9Sstevel@tonic-gate	movq	%rax, CREG_LDT(%rdi)
30967c478bd9Sstevel@tonic-gate	sldt	CREG_LDT(%rdi)		/* 2 bytes */
30977c478bd9Sstevel@tonic-gate	movq	%rax, CREG_TASKR(%rdi)
30987c478bd9Sstevel@tonic-gate	str	CREG_TASKR(%rdi)	/* 2 bytes */
30997c478bd9Sstevel@tonic-gate	movq	%cr0, %rax
31007c478bd9Sstevel@tonic-gate	movq	%rax, CREG_CR0(%rdi)	/* cr0 */
31017c478bd9Sstevel@tonic-gate	movq	%cr2, %rax
31027c478bd9Sstevel@tonic-gate	movq	%rax, CREG_CR2(%rdi)	/* cr2 */
31037c478bd9Sstevel@tonic-gate	movq	%cr3, %rax
31047c478bd9Sstevel@tonic-gate	movq	%rax, CREG_CR3(%rdi)	/* cr3 */
31057c478bd9Sstevel@tonic-gate	movq	%cr4, %rax
3106ae115bc7Smrj	movq	%rax, CREG_CR4(%rdi)	/* cr4 */
31077c478bd9Sstevel@tonic-gate	movq	%cr8, %rax
31087c478bd9Sstevel@tonic-gate	movq	%rax, CREG_CR8(%rdi)	/* cr8 */
31097c478bd9Sstevel@tonic-gate	GETMSR(MSR_AMD_KGSBASE, CREG_KGSBASE, %rdi)
31107c478bd9Sstevel@tonic-gate	GETMSR(MSR_AMD_EFER, CREG_EFER, %rdi)
3111843e1988Sjohnlev#endif	/* __xpv */
3112ae115bc7Smrj	ret
31137c478bd9Sstevel@tonic-gate	SET_SIZE(getcregs)
31147c478bd9Sstevel@tonic-gate
31157c478bd9Sstevel@tonic-gate#undef GETMSR
31167c478bd9Sstevel@tonic-gate
31177c478bd9Sstevel@tonic-gate#elif defined(__i386)
31187c478bd9Sstevel@tonic-gate
31197c478bd9Sstevel@tonic-gate	ENTRY_NP(getcregs)
3120843e1988Sjohnlev#if defined(__xpv)
3121843e1988Sjohnlev	/*
3122843e1988Sjohnlev	 * Only a few of the hardware control registers or descriptor tables
3123843e1988Sjohnlev	 * are directly accessible to us, so just zero the structure.
3124843e1988Sjohnlev	 *
3125843e1988Sjohnlev	 * XXPV	Perhaps it would be helpful for the hypervisor to return
3126843e1988Sjohnlev	 *	virtualized versions of these for post-mortem use.
3127843e1988Sjohnlev	 *	(Need to reevaluate - perhaps it already does!)
3128843e1988Sjohnlev	 */
3129843e1988Sjohnlev	movl	4(%esp), %edx
3130843e1988Sjohnlev	pushl	$CREGSZ
3131843e1988Sjohnlev	pushl	%edx
3132843e1988Sjohnlev	call	bzero
3133843e1988Sjohnlev	addl	$8, %esp
3134843e1988Sjohnlev	movl	4(%esp), %edx
3135843e1988Sjohnlev
3136843e1988Sjohnlev	/*
3137843e1988Sjohnlev	 * Dump what limited information we can
3138843e1988Sjohnlev	 */
3139843e1988Sjohnlev	movl	%cr0, %eax
3140843e1988Sjohnlev	movl	%eax, CREG_CR0(%edx)	/* cr0 */
3141843e1988Sjohnlev	movl	%cr2, %eax
3142843e1988Sjohnlev	movl	%eax, CREG_CR2(%edx)	/* cr2 */
3143843e1988Sjohnlev	movl	%cr3, %eax
3144843e1988Sjohnlev	movl	%eax, CREG_CR3(%edx)	/* cr3 */
3145843e1988Sjohnlev	movl	%cr4, %eax
3146843e1988Sjohnlev	movl	%eax, CREG_CR4(%edx)	/* cr4 */
3147843e1988Sjohnlev
3148843e1988Sjohnlev#else	/* __xpv */
3149843e1988Sjohnlev
31507c478bd9Sstevel@tonic-gate	movl	4(%esp), %edx
31517c478bd9Sstevel@tonic-gate	movw	$0, CREG_GDT+6(%edx)
31527c478bd9Sstevel@tonic-gate	movw	$0, CREG_IDT+6(%edx)
31537c478bd9Sstevel@tonic-gate	sgdt	CREG_GDT(%edx)		/* gdt */
31547c478bd9Sstevel@tonic-gate	sidt	CREG_IDT(%edx)		/* idt */
31557c478bd9Sstevel@tonic-gate	sldt	CREG_LDT(%edx)		/* ldt */
31567c478bd9Sstevel@tonic-gate	str	CREG_TASKR(%edx)	/* task */
31577c478bd9Sstevel@tonic-gate	movl	%cr0, %eax
31587c478bd9Sstevel@tonic-gate	movl	%eax, CREG_CR0(%edx)	/* cr0 */
31597c478bd9Sstevel@tonic-gate	movl	%cr2, %eax
31607c478bd9Sstevel@tonic-gate	movl	%eax, CREG_CR2(%edx)	/* cr2 */
31617c478bd9Sstevel@tonic-gate	movl	%cr3, %eax
31627c478bd9Sstevel@tonic-gate	movl	%eax, CREG_CR3(%edx)	/* cr3 */
31637417cfdeSKuriakose Kuruvilla	bt	$X86FSET_LARGEPAGE, x86_featureset
31647417cfdeSKuriakose Kuruvilla	jnc	.nocr4
31657c478bd9Sstevel@tonic-gate	movl	%cr4, %eax
31667c478bd9Sstevel@tonic-gate	movl	%eax, CREG_CR4(%edx)	/* cr4 */
31677c478bd9Sstevel@tonic-gate	jmp	.skip
31687c478bd9Sstevel@tonic-gate.nocr4:
31697c478bd9Sstevel@tonic-gate	movl	$0, CREG_CR4(%edx)
31707c478bd9Sstevel@tonic-gate.skip:
3171843e1988Sjohnlev#endif
3172ae115bc7Smrj	ret
31737c478bd9Sstevel@tonic-gate	SET_SIZE(getcregs)
31747c478bd9Sstevel@tonic-gate
31757c478bd9Sstevel@tonic-gate#endif	/* __i386 */
31767c478bd9Sstevel@tonic-gate#endif	/* __lint */
31777c478bd9Sstevel@tonic-gate
31787c478bd9Sstevel@tonic-gate
31797c478bd9Sstevel@tonic-gate/*
31807c478bd9Sstevel@tonic-gate * A panic trigger is a word which is updated atomically and can only be set
31817c478bd9Sstevel@tonic-gate * once.  We atomically store 0xDEFACEDD and load the old value.  If the
31827c478bd9Sstevel@tonic-gate * previous value was 0, we succeed and return 1; otherwise return 0.
31837c478bd9Sstevel@tonic-gate * This allows a partially corrupt trigger to still trigger correctly.  DTrace
31847c478bd9Sstevel@tonic-gate * has its own version of this function to allow it to panic correctly from
31857c478bd9Sstevel@tonic-gate * probe context.
31867c478bd9Sstevel@tonic-gate */
31877c478bd9Sstevel@tonic-gate#if defined(__lint)
31887c478bd9Sstevel@tonic-gate
31897c478bd9Sstevel@tonic-gate/*ARGSUSED*/
31907c478bd9Sstevel@tonic-gateint
31917c478bd9Sstevel@tonic-gatepanic_trigger(int *tp)
31927c478bd9Sstevel@tonic-gate{ return (0); }
31937c478bd9Sstevel@tonic-gate
31947c478bd9Sstevel@tonic-gate/*ARGSUSED*/
31957c478bd9Sstevel@tonic-gateint
31967c478bd9Sstevel@tonic-gatedtrace_panic_trigger(int *tp)
31977c478bd9Sstevel@tonic-gate{ return (0); }
31987c478bd9Sstevel@tonic-gate
31997c478bd9Sstevel@tonic-gate#else	/* __lint */
32007c478bd9Sstevel@tonic-gate
32017c478bd9Sstevel@tonic-gate#if defined(__amd64)
32027c478bd9Sstevel@tonic-gate
32037c478bd9Sstevel@tonic-gate	ENTRY_NP(panic_trigger)
32047c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
32057c478bd9Sstevel@tonic-gate	movl	$0xdefacedd, %edx
32067c478bd9Sstevel@tonic-gate	lock
32077c478bd9Sstevel@tonic-gate	  xchgl	%edx, (%rdi)
32087c478bd9Sstevel@tonic-gate	cmpl	$0, %edx
32097c478bd9Sstevel@tonic-gate	je	0f
32107c478bd9Sstevel@tonic-gate	movl	$0, %eax
32117c478bd9Sstevel@tonic-gate	ret
32127c478bd9Sstevel@tonic-gate0:	movl	$1, %eax
32137c478bd9Sstevel@tonic-gate	ret
32147c478bd9Sstevel@tonic-gate	SET_SIZE(panic_trigger)
32157c478bd9Sstevel@tonic-gate
32167c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_panic_trigger)
32177c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
32187c478bd9Sstevel@tonic-gate	movl	$0xdefacedd, %edx
32197c478bd9Sstevel@tonic-gate	lock
32207c478bd9Sstevel@tonic-gate	  xchgl	%edx, (%rdi)
32217c478bd9Sstevel@tonic-gate	cmpl	$0, %edx
32227c478bd9Sstevel@tonic-gate	je	0f
32237c478bd9Sstevel@tonic-gate	movl	$0, %eax
32247c478bd9Sstevel@tonic-gate	ret
32257c478bd9Sstevel@tonic-gate0:	movl	$1, %eax
32267c478bd9Sstevel@tonic-gate	ret
32277c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_panic_trigger)
32287c478bd9Sstevel@tonic-gate
32297c478bd9Sstevel@tonic-gate#elif defined(__i386)
32307c478bd9Sstevel@tonic-gate
32317c478bd9Sstevel@tonic-gate	ENTRY_NP(panic_trigger)
32327c478bd9Sstevel@tonic-gate	movl	4(%esp), %edx		/ %edx = address of trigger
32337c478bd9Sstevel@tonic-gate	movl	$0xdefacedd, %eax	/ %eax = 0xdefacedd
32347c478bd9Sstevel@tonic-gate	lock				/ assert lock
32357c478bd9Sstevel@tonic-gate	xchgl %eax, (%edx)		/ exchange %eax and the trigger
32367c478bd9Sstevel@tonic-gate	cmpl	$0, %eax		/ if (%eax == 0x0)
32377c478bd9Sstevel@tonic-gate	je	0f			/   return (1);
32387c478bd9Sstevel@tonic-gate	movl	$0, %eax		/ else
32397c478bd9Sstevel@tonic-gate	ret				/   return (0);
32407c478bd9Sstevel@tonic-gate0:	movl	$1, %eax
32417c478bd9Sstevel@tonic-gate	ret
32427c478bd9Sstevel@tonic-gate	SET_SIZE(panic_trigger)
32437c478bd9Sstevel@tonic-gate
32447c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_panic_trigger)
32457c478bd9Sstevel@tonic-gate	movl	4(%esp), %edx		/ %edx = address of trigger
32467c478bd9Sstevel@tonic-gate	movl	$0xdefacedd, %eax	/ %eax = 0xdefacedd
32477c478bd9Sstevel@tonic-gate	lock				/ assert lock
32487c478bd9Sstevel@tonic-gate	xchgl %eax, (%edx)		/ exchange %eax and the trigger
32497c478bd9Sstevel@tonic-gate	cmpl	$0, %eax		/ if (%eax == 0x0)
32507c478bd9Sstevel@tonic-gate	je	0f			/   return (1);
32517c478bd9Sstevel@tonic-gate	movl	$0, %eax		/ else
32527c478bd9Sstevel@tonic-gate	ret				/   return (0);
32537c478bd9Sstevel@tonic-gate0:	movl	$1, %eax
32547c478bd9Sstevel@tonic-gate	ret
32557c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_panic_trigger)
32567c478bd9Sstevel@tonic-gate
32577c478bd9Sstevel@tonic-gate#endif	/* __i386 */
32587c478bd9Sstevel@tonic-gate#endif	/* __lint */
32597c478bd9Sstevel@tonic-gate
32607c478bd9Sstevel@tonic-gate/*
32617c478bd9Sstevel@tonic-gate * The panic() and cmn_err() functions invoke vpanic() as a common entry point
32627c478bd9Sstevel@tonic-gate * into the panic code implemented in panicsys().  vpanic() is responsible
32637c478bd9Sstevel@tonic-gate * for passing through the format string and arguments, and constructing a
32647c478bd9Sstevel@tonic-gate * regs structure on the stack into which it saves the current register
32657c478bd9Sstevel@tonic-gate * values.  If we are not dying due to a fatal trap, these registers will
32667c478bd9Sstevel@tonic-gate * then be preserved in panicbuf as the current processor state.  Before
32677c478bd9Sstevel@tonic-gate * invoking panicsys(), vpanic() activates the first panic trigger (see
32687c478bd9Sstevel@tonic-gate * common/os/panic.c) and switches to the panic_stack if successful.  Note that
32697c478bd9Sstevel@tonic-gate * DTrace takes a slightly different panic path if it must panic from probe
32707c478bd9Sstevel@tonic-gate * context.  Instead of calling panic, it calls into dtrace_vpanic(), which
32717c478bd9Sstevel@tonic-gate * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
32727c478bd9Sstevel@tonic-gate * branches back into vpanic().
32737c478bd9Sstevel@tonic-gate */
32747c478bd9Sstevel@tonic-gate#if defined(__lint)
32757c478bd9Sstevel@tonic-gate
32767c478bd9Sstevel@tonic-gate/*ARGSUSED*/
32777c478bd9Sstevel@tonic-gatevoid
32787c478bd9Sstevel@tonic-gatevpanic(const char *format, va_list alist)
32797c478bd9Sstevel@tonic-gate{}
32807c478bd9Sstevel@tonic-gate
32817c478bd9Sstevel@tonic-gate/*ARGSUSED*/
32827c478bd9Sstevel@tonic-gatevoid
32837c478bd9Sstevel@tonic-gatedtrace_vpanic(const char *format, va_list alist)
32847c478bd9Sstevel@tonic-gate{}
32857c478bd9Sstevel@tonic-gate
32867c478bd9Sstevel@tonic-gate#else	/* __lint */
32877c478bd9Sstevel@tonic-gate
32887c478bd9Sstevel@tonic-gate#if defined(__amd64)
32897c478bd9Sstevel@tonic-gate
32907c478bd9Sstevel@tonic-gate	ENTRY_NP(vpanic)			/* Initial stack layout: */
32917c478bd9Sstevel@tonic-gate
32927c478bd9Sstevel@tonic-gate	pushq	%rbp				/* | %rip | 	0x60	*/
32937c478bd9Sstevel@tonic-gate	movq	%rsp, %rbp			/* | %rbp |	0x58	*/
32947c478bd9Sstevel@tonic-gate	pushfq					/* | rfl  |	0x50	*/
32957c478bd9Sstevel@tonic-gate	pushq	%r11				/* | %r11 |	0x48	*/
32967c478bd9Sstevel@tonic-gate	pushq	%r10				/* | %r10 |	0x40	*/
32977c478bd9Sstevel@tonic-gate	pushq	%rbx				/* | %rbx |	0x38	*/
32987c478bd9Sstevel@tonic-gate	pushq	%rax				/* | %rax |	0x30	*/
32997c478bd9Sstevel@tonic-gate	pushq	%r9				/* | %r9  |	0x28	*/
33007c478bd9Sstevel@tonic-gate	pushq	%r8				/* | %r8  |	0x20	*/
33017c478bd9Sstevel@tonic-gate	pushq	%rcx				/* | %rcx |	0x18	*/
33027c478bd9Sstevel@tonic-gate	pushq	%rdx				/* | %rdx |	0x10	*/
33037c478bd9Sstevel@tonic-gate	pushq	%rsi				/* | %rsi |	0x8 alist */
33047c478bd9Sstevel@tonic-gate	pushq	%rdi				/* | %rdi |	0x0 format */
33057c478bd9Sstevel@tonic-gate
33067c478bd9Sstevel@tonic-gate	movq	%rsp, %rbx			/* %rbx = current %rsp */
33077c478bd9Sstevel@tonic-gate
33087c478bd9Sstevel@tonic-gate	leaq	panic_quiesce(%rip), %rdi	/* %rdi = &panic_quiesce */
33097c478bd9Sstevel@tonic-gate	call	panic_trigger			/* %eax = panic_trigger() */
33107c478bd9Sstevel@tonic-gate
33117c478bd9Sstevel@tonic-gatevpanic_common:
331252d60c84Sgavinm	/*
331352d60c84Sgavinm	 * The panic_trigger result is in %eax from the call above, and
331452d60c84Sgavinm	 * dtrace_panic places it in %eax before branching here.
331552d60c84Sgavinm	 * The rdmsr instructions that follow below will clobber %eax so
331652d60c84Sgavinm	 * we stash the panic_trigger result in %r11d.
331752d60c84Sgavinm	 */
331852d60c84Sgavinm	movl	%eax, %r11d
331952d60c84Sgavinm	cmpl	$0, %r11d
33207c478bd9Sstevel@tonic-gate	je	0f
33217c478bd9Sstevel@tonic-gate
33227c478bd9Sstevel@tonic-gate	/*
33237c478bd9Sstevel@tonic-gate	 * If panic_trigger() was successful, we are the first to initiate a
33247c478bd9Sstevel@tonic-gate	 * panic: we now switch to the reserved panic_stack before continuing.
33257c478bd9Sstevel@tonic-gate	 */
33267c478bd9Sstevel@tonic-gate	leaq	panic_stack(%rip), %rsp
33277c478bd9Sstevel@tonic-gate	addq	$PANICSTKSIZE, %rsp
33287c478bd9Sstevel@tonic-gate0:	subq	$REGSIZE, %rsp
33297c478bd9Sstevel@tonic-gate	/*
33307c478bd9Sstevel@tonic-gate	 * Now that we've got everything set up, store the register values as
33317c478bd9Sstevel@tonic-gate	 * they were when we entered vpanic() to the designated location in
33327c478bd9Sstevel@tonic-gate	 * the regs structure we allocated on the stack.
33337c478bd9Sstevel@tonic-gate	 */
33347c478bd9Sstevel@tonic-gate	movq	0x0(%rbx), %rcx
33357c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RDI(%rsp)
33367c478bd9Sstevel@tonic-gate	movq	0x8(%rbx), %rcx
33377c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RSI(%rsp)
33387c478bd9Sstevel@tonic-gate	movq	0x10(%rbx), %rcx
33397c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RDX(%rsp)
33407c478bd9Sstevel@tonic-gate	movq	0x18(%rbx), %rcx
33417c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RCX(%rsp)
33427c478bd9Sstevel@tonic-gate	movq	0x20(%rbx), %rcx
33437c478bd9Sstevel@tonic-gate
33447c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_R8(%rsp)
33457c478bd9Sstevel@tonic-gate	movq	0x28(%rbx), %rcx
33467c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_R9(%rsp)
33477c478bd9Sstevel@tonic-gate	movq	0x30(%rbx), %rcx
33487c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RAX(%rsp)
33497c478bd9Sstevel@tonic-gate	movq	0x38(%rbx), %rcx
33502d596601Ssethg	movq	%rcx, REGOFF_RBX(%rsp)
33517c478bd9Sstevel@tonic-gate	movq	0x58(%rbx), %rcx
33527c478bd9Sstevel@tonic-gate
33537c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RBP(%rsp)
33547c478bd9Sstevel@tonic-gate	movq	0x40(%rbx), %rcx
33557c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_R10(%rsp)
33567c478bd9Sstevel@tonic-gate	movq	0x48(%rbx), %rcx
33577c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_R11(%rsp)
33587c478bd9Sstevel@tonic-gate	movq	%r12, REGOFF_R12(%rsp)
33597c478bd9Sstevel@tonic-gate
33607c478bd9Sstevel@tonic-gate	movq	%r13, REGOFF_R13(%rsp)
33617c478bd9Sstevel@tonic-gate	movq	%r14, REGOFF_R14(%rsp)
33627c478bd9Sstevel@tonic-gate	movq	%r15, REGOFF_R15(%rsp)
33637c478bd9Sstevel@tonic-gate
33647c478bd9Sstevel@tonic-gate	xorl	%ecx, %ecx
33657c478bd9Sstevel@tonic-gate	movw	%ds, %cx
33667c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_DS(%rsp)
33677c478bd9Sstevel@tonic-gate	movw	%es, %cx
33687c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_ES(%rsp)
33697c478bd9Sstevel@tonic-gate	movw	%fs, %cx
33707c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_FS(%rsp)
33717c478bd9Sstevel@tonic-gate	movw	%gs, %cx
33727c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_GS(%rsp)
33737c478bd9Sstevel@tonic-gate
33747c478bd9Sstevel@tonic-gate	movq	$0, REGOFF_TRAPNO(%rsp)
33757c478bd9Sstevel@tonic-gate
33767c478bd9Sstevel@tonic-gate	movq	$0, REGOFF_ERR(%rsp)
33777c478bd9Sstevel@tonic-gate	leaq	vpanic(%rip), %rcx
33787c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RIP(%rsp)
33797c478bd9Sstevel@tonic-gate	movw	%cs, %cx
33807c478bd9Sstevel@tonic-gate	movzwq	%cx, %rcx
33817c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_CS(%rsp)
33827c478bd9Sstevel@tonic-gate	movq	0x50(%rbx), %rcx
33837c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RFL(%rsp)
33847c478bd9Sstevel@tonic-gate	movq	%rbx, %rcx
33857c478bd9Sstevel@tonic-gate	addq	$0x60, %rcx
33867c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_RSP(%rsp)
33877c478bd9Sstevel@tonic-gate	movw	%ss, %cx
33887c478bd9Sstevel@tonic-gate	movzwq	%cx, %rcx
33897c478bd9Sstevel@tonic-gate	movq	%rcx, REGOFF_SS(%rsp)
33907c478bd9Sstevel@tonic-gate
33917c478bd9Sstevel@tonic-gate	/*
33927c478bd9Sstevel@tonic-gate	 * panicsys(format, alist, rp, on_panic_stack)
33937c478bd9Sstevel@tonic-gate	 */
33947c478bd9Sstevel@tonic-gate	movq	REGOFF_RDI(%rsp), %rdi		/* format */
33957c478bd9Sstevel@tonic-gate	movq	REGOFF_RSI(%rsp), %rsi		/* alist */
33967c478bd9Sstevel@tonic-gate	movq	%rsp, %rdx			/* struct regs */
339752d60c84Sgavinm	movl	%r11d, %ecx			/* on_panic_stack */
33987c478bd9Sstevel@tonic-gate	call	panicsys
33997c478bd9Sstevel@tonic-gate	addq	$REGSIZE, %rsp
34007c478bd9Sstevel@tonic-gate	popq	%rdi
34017c478bd9Sstevel@tonic-gate	popq	%rsi
34027c478bd9Sstevel@tonic-gate	popq	%rdx
34037c478bd9Sstevel@tonic-gate	popq	%rcx
34047c478bd9Sstevel@tonic-gate	popq	%r8
34057c478bd9Sstevel@tonic-gate	popq	%r9
34067c478bd9Sstevel@tonic-gate	popq	%rax
34077c478bd9Sstevel@tonic-gate	popq	%rbx
34087c478bd9Sstevel@tonic-gate	popq	%r10
34097c478bd9Sstevel@tonic-gate	popq	%r11
34107c478bd9Sstevel@tonic-gate	popfq
34117c478bd9Sstevel@tonic-gate	leave
34127c478bd9Sstevel@tonic-gate	ret
34137c478bd9Sstevel@tonic-gate	SET_SIZE(vpanic)
34147c478bd9Sstevel@tonic-gate
34157c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_vpanic)			/* Initial stack layout: */
34167c478bd9Sstevel@tonic-gate
34177c478bd9Sstevel@tonic-gate	pushq	%rbp				/* | %rip | 	0x60	*/
34187c478bd9Sstevel@tonic-gate	movq	%rsp, %rbp			/* | %rbp |	0x58	*/
34197c478bd9Sstevel@tonic-gate	pushfq					/* | rfl  |	0x50	*/
34207c478bd9Sstevel@tonic-gate	pushq	%r11				/* | %r11 |	0x48	*/
34217c478bd9Sstevel@tonic-gate	pushq	%r10				/* | %r10 |	0x40	*/
34227c478bd9Sstevel@tonic-gate	pushq	%rbx				/* | %rbx |	0x38	*/
34237c478bd9Sstevel@tonic-gate	pushq	%rax				/* | %rax |	0x30	*/
34247c478bd9Sstevel@tonic-gate	pushq	%r9				/* | %r9  |	0x28	*/
34257c478bd9Sstevel@tonic-gate	pushq	%r8				/* | %r8  |	0x20	*/
34267c478bd9Sstevel@tonic-gate	pushq	%rcx				/* | %rcx |	0x18	*/
34277c478bd9Sstevel@tonic-gate	pushq	%rdx				/* | %rdx |	0x10	*/
34287c478bd9Sstevel@tonic-gate	pushq	%rsi				/* | %rsi |	0x8 alist */
34297c478bd9Sstevel@tonic-gate	pushq	%rdi				/* | %rdi |	0x0 format */
34307c478bd9Sstevel@tonic-gate
34317c478bd9Sstevel@tonic-gate	movq	%rsp, %rbx			/* %rbx = current %rsp */
34327c478bd9Sstevel@tonic-gate
34337c478bd9Sstevel@tonic-gate	leaq	panic_quiesce(%rip), %rdi	/* %rdi = &panic_quiesce */
34347c478bd9Sstevel@tonic-gate	call	dtrace_panic_trigger	/* %eax = dtrace_panic_trigger() */
34357c478bd9Sstevel@tonic-gate	jmp	vpanic_common
34367c478bd9Sstevel@tonic-gate
34377c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_vpanic)
34387c478bd9Sstevel@tonic-gate
34397c478bd9Sstevel@tonic-gate#elif defined(__i386)
34407c478bd9Sstevel@tonic-gate
34417c478bd9Sstevel@tonic-gate	ENTRY_NP(vpanic)			/ Initial stack layout:
34427c478bd9Sstevel@tonic-gate
34437c478bd9Sstevel@tonic-gate	pushl	%ebp				/ | %eip | 20
34447c478bd9Sstevel@tonic-gate	movl	%esp, %ebp			/ | %ebp | 16
34457c478bd9Sstevel@tonic-gate	pushl	%eax				/ | %eax | 12
34467c478bd9Sstevel@tonic-gate	pushl	%ebx				/ | %ebx |  8
34477c478bd9Sstevel@tonic-gate	pushl	%ecx				/ | %ecx |  4
34487c478bd9Sstevel@tonic-gate	pushl	%edx				/ | %edx |  0
34497c478bd9Sstevel@tonic-gate
34507c478bd9Sstevel@tonic-gate	movl	%esp, %ebx			/ %ebx = current stack pointer
34517c478bd9Sstevel@tonic-gate
34527c478bd9Sstevel@tonic-gate	lea	panic_quiesce, %eax		/ %eax = &panic_quiesce
34537c478bd9Sstevel@tonic-gate	pushl	%eax				/ push &panic_quiesce
34547c478bd9Sstevel@tonic-gate	call	panic_trigger			/ %eax = panic_trigger()
34557c478bd9Sstevel@tonic-gate	addl	$4, %esp			/ reset stack pointer
34567c478bd9Sstevel@tonic-gate
34577c478bd9Sstevel@tonic-gatevpanic_common:
34587c478bd9Sstevel@tonic-gate	cmpl	$0, %eax			/ if (%eax == 0)
34597c478bd9Sstevel@tonic-gate	je	0f				/   goto 0f;
34607c478bd9Sstevel@tonic-gate
34617c478bd9Sstevel@tonic-gate	/*
34627c478bd9Sstevel@tonic-gate	 * If panic_trigger() was successful, we are the first to initiate a
34637c478bd9Sstevel@tonic-gate	 * panic: we now switch to the reserved panic_stack before continuing.
34647c478bd9Sstevel@tonic-gate	 */
34657c478bd9Sstevel@tonic-gate	lea	panic_stack, %esp		/ %esp  = panic_stack
34667c478bd9Sstevel@tonic-gate	addl	$PANICSTKSIZE, %esp		/ %esp += PANICSTKSIZE
34677c478bd9Sstevel@tonic-gate
34687c478bd9Sstevel@tonic-gate0:	subl	$REGSIZE, %esp			/ allocate struct regs
34697c478bd9Sstevel@tonic-gate
34707c478bd9Sstevel@tonic-gate	/*
34717c478bd9Sstevel@tonic-gate	 * Now that we've got everything set up, store the register values as
34727c478bd9Sstevel@tonic-gate	 * they were when we entered vpanic() to the designated location in
34737c478bd9Sstevel@tonic-gate	 * the regs structure we allocated on the stack.
34747c478bd9Sstevel@tonic-gate	 */
34757c478bd9Sstevel@tonic-gate#if !defined(__GNUC_AS__)
34767c478bd9Sstevel@tonic-gate	movw	%gs, %edx
34777c478bd9Sstevel@tonic-gate	movl	%edx, REGOFF_GS(%esp)
34787c478bd9Sstevel@tonic-gate	movw	%fs, %edx
34797c478bd9Sstevel@tonic-gate	movl	%edx, REGOFF_FS(%esp)
34807c478bd9Sstevel@tonic-gate	movw	%es, %edx
34817c478bd9Sstevel@tonic-gate	movl	%edx, REGOFF_ES(%esp)
34827c478bd9Sstevel@tonic-gate	movw	%ds, %edx
34837c478bd9Sstevel@tonic-gate	movl	%edx, REGOFF_DS(%esp)
34847c478bd9Sstevel@tonic-gate#else	/* __GNUC_AS__ */
34857c478bd9Sstevel@tonic-gate	mov	%gs, %edx
34867c478bd9Sstevel@tonic-gate	mov	%edx, REGOFF_GS(%esp)
34877c478bd9Sstevel@tonic-gate	mov	%fs, %edx
34887c478bd9Sstevel@tonic-gate	mov	%edx, REGOFF_FS(%esp)
34897c478bd9Sstevel@tonic-gate	mov	%es, %edx
34907c478bd9Sstevel@tonic-gate	mov	%edx, REGOFF_ES(%esp)
34917c478bd9Sstevel@tonic-gate	mov	%ds, %edx
34927c478bd9Sstevel@tonic-gate	mov	%edx, REGOFF_DS(%esp)
34937c478bd9Sstevel@tonic-gate#endif	/* __GNUC_AS__ */
34947c478bd9Sstevel@tonic-gate	movl	%edi, REGOFF_EDI(%esp)
34957c478bd9Sstevel@tonic-gate	movl	%esi, REGOFF_ESI(%esp)
34967c478bd9Sstevel@tonic-gate	movl	16(%ebx), %ecx
34977c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_EBP(%esp)
34987c478bd9Sstevel@tonic-gate	movl	%ebx, %ecx
34997c478bd9Sstevel@tonic-gate	addl	$20, %ecx
35007c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_ESP(%esp)
35017c478bd9Sstevel@tonic-gate	movl	8(%ebx), %ecx
35027c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_EBX(%esp)
35037c478bd9Sstevel@tonic-gate	movl	0(%ebx), %ecx
35047c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_EDX(%esp)
35057c478bd9Sstevel@tonic-gate	movl	4(%ebx), %ecx
35067c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_ECX(%esp)
35077c478bd9Sstevel@tonic-gate	movl	12(%ebx), %ecx
35087c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_EAX(%esp)
35097c478bd9Sstevel@tonic-gate	movl	$0, REGOFF_TRAPNO(%esp)
35107c478bd9Sstevel@tonic-gate	movl	$0, REGOFF_ERR(%esp)
35117c478bd9Sstevel@tonic-gate	lea	vpanic, %ecx
35127c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_EIP(%esp)
35137c478bd9Sstevel@tonic-gate#if !defined(__GNUC_AS__)
35147c478bd9Sstevel@tonic-gate	movw	%cs, %edx
35157c478bd9Sstevel@tonic-gate#else	/* __GNUC_AS__ */
35167c478bd9Sstevel@tonic-gate	mov	%cs, %edx
35177c478bd9Sstevel@tonic-gate#endif	/* __GNUC_AS__ */
35187c478bd9Sstevel@tonic-gate	movl	%edx, REGOFF_CS(%esp)
35197c478bd9Sstevel@tonic-gate	pushfl
35207c478bd9Sstevel@tonic-gate	popl	%ecx
3521843e1988Sjohnlev#if defined(__xpv)
3522843e1988Sjohnlev	/*
3523843e1988Sjohnlev	 * Synthesize the PS_IE bit from the event mask bit
3524843e1988Sjohnlev	 */
3525843e1988Sjohnlev	CURTHREAD(%edx)
3526843e1988Sjohnlev	KPREEMPT_DISABLE(%edx)
3527843e1988Sjohnlev	EVENT_MASK_TO_IE(%edx, %ecx)
3528843e1988Sjohnlev	CURTHREAD(%edx)
3529843e1988Sjohnlev	KPREEMPT_ENABLE_NOKP(%edx)
3530843e1988Sjohnlev#endif
35317c478bd9Sstevel@tonic-gate	movl	%ecx, REGOFF_EFL(%esp)
35327c478bd9Sstevel@tonic-gate	movl	$0, REGOFF_UESP(%esp)
35337c478bd9Sstevel@tonic-gate#if !defined(__GNUC_AS__)
35347c478bd9Sstevel@tonic-gate	movw	%ss, %edx
35357c478bd9Sstevel@tonic-gate#else	/* __GNUC_AS__ */
35367c478bd9Sstevel@tonic-gate	mov	%ss, %edx
35377c478bd9Sstevel@tonic-gate#endif	/* __GNUC_AS__ */
35387c478bd9Sstevel@tonic-gate	movl	%edx, REGOFF_SS(%esp)
35397c478bd9Sstevel@tonic-gate
35407c478bd9Sstevel@tonic-gate	movl	%esp, %ecx			/ %ecx = &regs
35417c478bd9Sstevel@tonic-gate	pushl	%eax				/ push on_panic_stack
35427c478bd9Sstevel@tonic-gate	pushl	%ecx				/ push &regs
35437c478bd9Sstevel@tonic-gate	movl	12(%ebp), %ecx			/ %ecx = alist
35447c478bd9Sstevel@tonic-gate	pushl	%ecx				/ push alist
35457c478bd9Sstevel@tonic-gate	movl	8(%ebp), %ecx			/ %ecx = format
35467c478bd9Sstevel@tonic-gate	pushl	%ecx				/ push format
35477c478bd9Sstevel@tonic-gate	call	panicsys			/ panicsys();
35487c478bd9Sstevel@tonic-gate	addl	$16, %esp			/ pop arguments
35497c478bd9Sstevel@tonic-gate
35507c478bd9Sstevel@tonic-gate	addl	$REGSIZE, %esp
35517c478bd9Sstevel@tonic-gate	popl	%edx
35527c478bd9Sstevel@tonic-gate	popl	%ecx
35537c478bd9Sstevel@tonic-gate	popl	%ebx
35547c478bd9Sstevel@tonic-gate	popl	%eax
35557c478bd9Sstevel@tonic-gate	leave
35567c478bd9Sstevel@tonic-gate	ret
35577c478bd9Sstevel@tonic-gate	SET_SIZE(vpanic)
35587c478bd9Sstevel@tonic-gate
35597c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_vpanic)			/ Initial stack layout:
35607c478bd9Sstevel@tonic-gate
35617c478bd9Sstevel@tonic-gate	pushl	%ebp				/ | %eip | 20
35627c478bd9Sstevel@tonic-gate	movl	%esp, %ebp			/ | %ebp | 16
35637c478bd9Sstevel@tonic-gate	pushl	%eax				/ | %eax | 12
35647c478bd9Sstevel@tonic-gate	pushl	%ebx				/ | %ebx |  8
35657c478bd9Sstevel@tonic-gate	pushl	%ecx				/ | %ecx |  4
35667c478bd9Sstevel@tonic-gate	pushl	%edx				/ | %edx |  0
35677c478bd9Sstevel@tonic-gate
35687c478bd9Sstevel@tonic-gate	movl	%esp, %ebx			/ %ebx = current stack pointer
35697c478bd9Sstevel@tonic-gate
35707c478bd9Sstevel@tonic-gate	lea	panic_quiesce, %eax		/ %eax = &panic_quiesce
35717c478bd9Sstevel@tonic-gate	pushl	%eax				/ push &panic_quiesce
35727c478bd9Sstevel@tonic-gate	call	dtrace_panic_trigger		/ %eax = dtrace_panic_trigger()
35737c478bd9Sstevel@tonic-gate	addl	$4, %esp			/ reset stack pointer
35747c478bd9Sstevel@tonic-gate	jmp	vpanic_common			/ jump back to common code
35757c478bd9Sstevel@tonic-gate
35767c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_vpanic)
35777c478bd9Sstevel@tonic-gate
35787c478bd9Sstevel@tonic-gate#endif	/* __i386 */
35797c478bd9Sstevel@tonic-gate#endif	/* __lint */
35807c478bd9Sstevel@tonic-gate
35817c478bd9Sstevel@tonic-gate#if defined(__lint)
35827c478bd9Sstevel@tonic-gate
35837c478bd9Sstevel@tonic-gatevoid
35847c478bd9Sstevel@tonic-gatehres_tick(void)
35857c478bd9Sstevel@tonic-gate{}
35867c478bd9Sstevel@tonic-gate
35877c478bd9Sstevel@tonic-gateint64_t timedelta;
35887c478bd9Sstevel@tonic-gatehrtime_t hrtime_base;
35897c478bd9Sstevel@tonic-gate
35907c478bd9Sstevel@tonic-gate#else	/* __lint */
35917c478bd9Sstevel@tonic-gate
35927c478bd9Sstevel@tonic-gate	DGDEF3(timedelta, 8, 8)
35937c478bd9Sstevel@tonic-gate	.long	0, 0
35947c478bd9Sstevel@tonic-gate
35957c478bd9Sstevel@tonic-gate	/*
35967c478bd9Sstevel@tonic-gate	 * initialized to a non zero value to make pc_gethrtime()
35977c478bd9Sstevel@tonic-gate	 * work correctly even before clock is initialized
35987c478bd9Sstevel@tonic-gate	 */
35997c478bd9Sstevel@tonic-gate	DGDEF3(hrtime_base, 8, 8)
36007c478bd9Sstevel@tonic-gate	.long	_MUL(NSEC_PER_CLOCK_TICK, 6), 0
36017c478bd9Sstevel@tonic-gate
36027c478bd9Sstevel@tonic-gate	DGDEF3(adj_shift, 4, 4)
36037c478bd9Sstevel@tonic-gate	.long	ADJ_SHIFT
36047c478bd9Sstevel@tonic-gate
36057c478bd9Sstevel@tonic-gate#if defined(__amd64)
36067c478bd9Sstevel@tonic-gate
36077c478bd9Sstevel@tonic-gate	ENTRY_NP(hres_tick)
36087c478bd9Sstevel@tonic-gate	pushq	%rbp
36097c478bd9Sstevel@tonic-gate	movq	%rsp, %rbp
36107c478bd9Sstevel@tonic-gate
36117c478bd9Sstevel@tonic-gate	/*
36127c478bd9Sstevel@tonic-gate	 * We need to call *gethrtimef before picking up CLOCK_LOCK (obviously,
36137c478bd9Sstevel@tonic-gate	 * hres_last_tick can only be modified while holding CLOCK_LOCK).
36147c478bd9Sstevel@tonic-gate	 * At worst, performing this now instead of under CLOCK_LOCK may
36157c478bd9Sstevel@tonic-gate	 * introduce some jitter in pc_gethrestime().
36167c478bd9Sstevel@tonic-gate	 */
36177c478bd9Sstevel@tonic-gate	call	*gethrtimef(%rip)
36187c478bd9Sstevel@tonic-gate	movq	%rax, %r8
36197c478bd9Sstevel@tonic-gate
36207c478bd9Sstevel@tonic-gate	leaq	hres_lock(%rip), %rax
36217c478bd9Sstevel@tonic-gate	movb	$-1, %dl
36227c478bd9Sstevel@tonic-gate.CL1:
36237c478bd9Sstevel@tonic-gate	xchgb	%dl, (%rax)
36247c478bd9Sstevel@tonic-gate	testb	%dl, %dl
36257c478bd9Sstevel@tonic-gate	jz	.CL3			/* got it */
36267c478bd9Sstevel@tonic-gate.CL2:
36277c478bd9Sstevel@tonic-gate	cmpb	$0, (%rax)		/* possible to get lock? */
36287c478bd9Sstevel@tonic-gate	pause
36297c478bd9Sstevel@tonic-gate	jne	.CL2
36307c478bd9Sstevel@tonic-gate	jmp	.CL1			/* yes, try again */
36317c478bd9Sstevel@tonic-gate.CL3:
36327c478bd9Sstevel@tonic-gate	/*
36337c478bd9Sstevel@tonic-gate	 * compute the interval since last time hres_tick was called
36347c478bd9Sstevel@tonic-gate	 * and adjust hrtime_base and hrestime accordingly
36357c478bd9Sstevel@tonic-gate	 * hrtime_base is an 8 byte value (in nsec), hrestime is
36367c478bd9Sstevel@tonic-gate	 * a timestruc_t (sec, nsec)
36377c478bd9Sstevel@tonic-gate	 */
36387c478bd9Sstevel@tonic-gate	leaq	hres_last_tick(%rip), %rax
36397c478bd9Sstevel@tonic-gate	movq	%r8, %r11
36407c478bd9Sstevel@tonic-gate	subq	(%rax), %r8
36417c478bd9Sstevel@tonic-gate	addq	%r8, hrtime_base(%rip)	/* add interval to hrtime_base */
36427c478bd9Sstevel@tonic-gate	addq	%r8, hrestime+8(%rip)	/* add interval to hrestime.tv_nsec */
36437c478bd9Sstevel@tonic-gate	/*
36447c478bd9Sstevel@tonic-gate	 * Now that we have CLOCK_LOCK, we can update hres_last_tick
36457c478bd9Sstevel@tonic-gate	 */
36467c478bd9Sstevel@tonic-gate	movq	%r11, (%rax)
36477c478bd9Sstevel@tonic-gate
36487c478bd9Sstevel@tonic-gate	call	__adj_hrestime
36497c478bd9Sstevel@tonic-gate
36507c478bd9Sstevel@tonic-gate	/*
36517c478bd9Sstevel@tonic-gate	 * release the hres_lock
36527c478bd9Sstevel@tonic-gate	 */
36537c478bd9Sstevel@tonic-gate	incl	hres_lock(%rip)
36547c478bd9Sstevel@tonic-gate	leave
36557c478bd9Sstevel@tonic-gate	ret
36567c478bd9Sstevel@tonic-gate	SET_SIZE(hres_tick)
36577c478bd9Sstevel@tonic-gate
36587c478bd9Sstevel@tonic-gate#elif defined(__i386)
36597c478bd9Sstevel@tonic-gate
36607c478bd9Sstevel@tonic-gate	ENTRY_NP(hres_tick)
36617c478bd9Sstevel@tonic-gate	pushl	%ebp
36627c478bd9Sstevel@tonic-gate	movl	%esp, %ebp
36637c478bd9Sstevel@tonic-gate	pushl	%esi
36647c478bd9Sstevel@tonic-gate	pushl	%ebx
36657c478bd9Sstevel@tonic-gate
36667c478bd9Sstevel@tonic-gate	/*
36677c478bd9Sstevel@tonic-gate	 * We need to call *gethrtimef before picking up CLOCK_LOCK (obviously,
36687c478bd9Sstevel@tonic-gate	 * hres_last_tick can only be modified while holding CLOCK_LOCK).
36697c478bd9Sstevel@tonic-gate	 * At worst, performing this now instead of under CLOCK_LOCK may
36707c478bd9Sstevel@tonic-gate	 * introduce some jitter in pc_gethrestime().
36717c478bd9Sstevel@tonic-gate	 */
36727c478bd9Sstevel@tonic-gate	call	*gethrtimef
36737c478bd9Sstevel@tonic-gate	movl	%eax, %ebx
36747c478bd9Sstevel@tonic-gate	movl	%edx, %esi
36757c478bd9Sstevel@tonic-gate
36767c478bd9Sstevel@tonic-gate	movl	$hres_lock, %eax
36777c478bd9Sstevel@tonic-gate	movl	$-1, %edx
36787c478bd9Sstevel@tonic-gate.CL1:
36797c478bd9Sstevel@tonic-gate	xchgb	%dl, (%eax)
36807c478bd9Sstevel@tonic-gate	testb	%dl, %dl
36817c478bd9Sstevel@tonic-gate	jz	.CL3			/ got it
36827c478bd9Sstevel@tonic-gate.CL2:
36837c478bd9Sstevel@tonic-gate	cmpb	$0, (%eax)		/ possible to get lock?
36847c478bd9Sstevel@tonic-gate	pause
36857c478bd9Sstevel@tonic-gate	jne	.CL2
36867c478bd9Sstevel@tonic-gate	jmp	.CL1			/ yes, try again
36877c478bd9Sstevel@tonic-gate.CL3:
36887c478bd9Sstevel@tonic-gate	/*
36897c478bd9Sstevel@tonic-gate	 * compute the interval since last time hres_tick was called
36907c478bd9Sstevel@tonic-gate	 * and adjust hrtime_base and hrestime accordingly
36917c478bd9Sstevel@tonic-gate	 * hrtime_base is an 8 byte value (in nsec), hrestime is
36927c478bd9Sstevel@tonic-gate	 * timestruc_t (sec, nsec)
36937c478bd9Sstevel@tonic-gate	 */
36947c478bd9Sstevel@tonic-gate
36957c478bd9Sstevel@tonic-gate	lea	hres_last_tick, %eax
36967c478bd9Sstevel@tonic-gate
36977c478bd9Sstevel@tonic-gate	movl	%ebx, %edx
36987c478bd9Sstevel@tonic-gate	movl	%esi, %ecx
36997c478bd9Sstevel@tonic-gate
37007c478bd9Sstevel@tonic-gate	subl 	(%eax), %edx
37017c478bd9Sstevel@tonic-gate	sbbl 	4(%eax), %ecx
37027c478bd9Sstevel@tonic-gate
37037c478bd9Sstevel@tonic-gate	addl	%edx, hrtime_base	/ add interval to hrtime_base
37047c478bd9Sstevel@tonic-gate	adcl	%ecx, hrtime_base+4
37057c478bd9Sstevel@tonic-gate
37067c478bd9Sstevel@tonic-gate	addl 	%edx, hrestime+4	/ add interval to hrestime.tv_nsec
37077c478bd9Sstevel@tonic-gate
37087c478bd9Sstevel@tonic-gate	/
37097c478bd9Sstevel@tonic-gate	/ Now that we have CLOCK_LOCK, we can update hres_last_tick.
37107c478bd9Sstevel@tonic-gate	/
37117c478bd9Sstevel@tonic-gate	movl	%ebx, (%eax)
37127c478bd9Sstevel@tonic-gate	movl	%esi,  4(%eax)
37137c478bd9Sstevel@tonic-gate
37147c478bd9Sstevel@tonic-gate	/ get hrestime at this moment. used as base for pc_gethrestime
37157c478bd9Sstevel@tonic-gate	/
37167c478bd9Sstevel@tonic-gate	/ Apply adjustment, if any
37177c478bd9Sstevel@tonic-gate	/
37187c478bd9Sstevel@tonic-gate	/ #define HRES_ADJ	(NSEC_PER_CLOCK_TICK >> ADJ_SHIFT)
37197c478bd9Sstevel@tonic-gate	/ (max_hres_adj)
37207c478bd9Sstevel@tonic-gate	/
37217c478bd9Sstevel@tonic-gate	/ void
37227c478bd9Sstevel@tonic-gate	/ adj_hrestime()
37237c478bd9Sstevel@tonic-gate	/ {
37247c478bd9Sstevel@tonic-gate	/	long long adj;
37257c478bd9Sstevel@tonic-gate	/
37267c478bd9Sstevel@tonic-gate	/	if (hrestime_adj == 0)
37277c478bd9Sstevel@tonic-gate	/		adj = 0;
37287c478bd9Sstevel@tonic-gate	/	else if (hrestime_adj > 0) {
37297c478bd9Sstevel@tonic-gate	/		if (hrestime_adj < HRES_ADJ)
37307c478bd9Sstevel@tonic-gate	/			adj = hrestime_adj;
37317c478bd9Sstevel@tonic-gate	/		else
37327c478bd9Sstevel@tonic-gate	/			adj = HRES_ADJ;
37337c478bd9Sstevel@tonic-gate	/	}
37347c478bd9Sstevel@tonic-gate	/	else {
37357c478bd9Sstevel@tonic-gate	/		if (hrestime_adj < -(HRES_ADJ))
37367c478bd9Sstevel@tonic-gate	/			adj = -(HRES_ADJ);
37377c478bd9Sstevel@tonic-gate	/		else
37387c478bd9Sstevel@tonic-gate	/			adj = hrestime_adj;
37397c478bd9Sstevel@tonic-gate	/	}
37407c478bd9Sstevel@tonic-gate	/
37417c478bd9Sstevel@tonic-gate	/	timedelta -= adj;
37427c478bd9Sstevel@tonic-gate	/	hrestime_adj = timedelta;
37437c478bd9Sstevel@tonic-gate	/	hrestime.tv_nsec += adj;
37447c478bd9Sstevel@tonic-gate	/
37457c478bd9Sstevel@tonic-gate	/	while (hrestime.tv_nsec >= NANOSEC) {
37467c478bd9Sstevel@tonic-gate	/		one_sec++;
37477c478bd9Sstevel@tonic-gate	/		hrestime.tv_sec++;
37487c478bd9Sstevel@tonic-gate	/		hrestime.tv_nsec -= NANOSEC;
37497c478bd9Sstevel@tonic-gate	/	}
37507c478bd9Sstevel@tonic-gate	/ }
37517c478bd9Sstevel@tonic-gate__adj_hrestime:
37527c478bd9Sstevel@tonic-gate	movl	hrestime_adj, %esi	/ if (hrestime_adj == 0)
37537c478bd9Sstevel@tonic-gate	movl	hrestime_adj+4, %edx
37547c478bd9Sstevel@tonic-gate	andl	%esi, %esi
37557c478bd9Sstevel@tonic-gate	jne	.CL4			/ no
37567c478bd9Sstevel@tonic-gate	andl	%edx, %edx
37577c478bd9Sstevel@tonic-gate	jne	.CL4			/ no
37587c478bd9Sstevel@tonic-gate	subl	%ecx, %ecx		/ yes, adj = 0;
37597c478bd9Sstevel@tonic-gate	subl	%edx, %edx
37607c478bd9Sstevel@tonic-gate	jmp	.CL5
37617c478bd9Sstevel@tonic-gate.CL4:
37627c478bd9Sstevel@tonic-gate	subl	%ecx, %ecx
37637c478bd9Sstevel@tonic-gate	subl	%eax, %eax
37647c478bd9Sstevel@tonic-gate	subl	%esi, %ecx
37657c478bd9Sstevel@tonic-gate	sbbl	%edx, %eax
37667c478bd9Sstevel@tonic-gate	andl	%eax, %eax		/ if (hrestime_adj > 0)
37677c478bd9Sstevel@tonic-gate	jge	.CL6
37687c478bd9Sstevel@tonic-gate
37697c478bd9Sstevel@tonic-gate	/ In the following comments, HRES_ADJ is used, while in the code
37707c478bd9Sstevel@tonic-gate	/ max_hres_adj is used.
37717c478bd9Sstevel@tonic-gate	/
37727c478bd9Sstevel@tonic-gate	/ The test for "hrestime_adj < HRES_ADJ" is complicated because
37737c478bd9Sstevel@tonic-gate	/ hrestime_adj is 64-bits, while HRES_ADJ is 32-bits.  We rely
37747c478bd9Sstevel@tonic-gate	/ on the logical equivalence of:
37757c478bd9Sstevel@tonic-gate	/
37767c478bd9Sstevel@tonic-gate	/	!(hrestime_adj < HRES_ADJ)
37777c478bd9Sstevel@tonic-gate	/
37787c478bd9Sstevel@tonic-gate	/ and the two step sequence:
37797c478bd9Sstevel@tonic-gate	/
37807c478bd9Sstevel@tonic-gate	/	(HRES_ADJ - lsw(hrestime_adj)) generates a Borrow/Carry
37817c478bd9Sstevel@tonic-gate	/
37827c478bd9Sstevel@tonic-gate	/ which computes whether or not the least significant 32-bits
37837c478bd9Sstevel@tonic-gate	/ of hrestime_adj is greater than HRES_ADJ, followed by:
37847c478bd9Sstevel@tonic-gate	/
37857c478bd9Sstevel@tonic-gate	/	Previous Borrow/Carry + -1 + msw(hrestime_adj) generates a Carry
37867c478bd9Sstevel@tonic-gate	/
37877c478bd9Sstevel@tonic-gate	/ which generates a carry whenever step 1 is true or the most
37887c478bd9Sstevel@tonic-gate	/ significant long of the longlong hrestime_adj is non-zero.
37897c478bd9Sstevel@tonic-gate
37907c478bd9Sstevel@tonic-gate	movl	max_hres_adj, %ecx	/ hrestime_adj is positive
37917c478bd9Sstevel@tonic-gate	subl	%esi, %ecx
37927c478bd9Sstevel@tonic-gate	movl	%edx, %eax
37937c478bd9Sstevel@tonic-gate	adcl	$-1, %eax
37947c478bd9Sstevel@tonic-gate	jnc	.CL7
37957c478bd9Sstevel@tonic-gate	movl	max_hres_adj, %ecx	/ adj = HRES_ADJ;
37967c478bd9Sstevel@tonic-gate	subl	%edx, %edx
37977c478bd9Sstevel@tonic-gate	jmp	.CL5
37987c478bd9Sstevel@tonic-gate
37997c478bd9Sstevel@tonic-gate	/ The following computation is similar to the one above.
38007c478bd9Sstevel@tonic-gate	/
38017c478bd9Sstevel@tonic-gate	/ The test for "hrestime_adj < -(HRES_ADJ)" is complicated because
38027c478bd9Sstevel@tonic-gate	/ hrestime_adj is 64-bits, while HRES_ADJ is 32-bits.  We rely
38037c478bd9Sstevel@tonic-gate	/ on the logical equivalence of:
38047c478bd9Sstevel@tonic-gate	/
38057c478bd9Sstevel@tonic-gate	/	(hrestime_adj > -HRES_ADJ)
38067c478bd9Sstevel@tonic-gate	/
38077c478bd9Sstevel@tonic-gate	/ and the two step sequence:
38087c478bd9Sstevel@tonic-gate	/
38097c478bd9Sstevel@tonic-gate	/	(HRES_ADJ + lsw(hrestime_adj)) generates a Carry
38107c478bd9Sstevel@tonic-gate	/
38117c478bd9Sstevel@tonic-gate	/ which means the least significant 32-bits of hrestime_adj is
38127c478bd9Sstevel@tonic-gate	/ greater than -HRES_ADJ, followed by:
38137c478bd9Sstevel@tonic-gate	/
38147c478bd9Sstevel@tonic-gate	/	Previous Carry + 0 + msw(hrestime_adj) generates a Carry
38157c478bd9Sstevel@tonic-gate	/
38167c478bd9Sstevel@tonic-gate	/ which generates a carry only when step 1 is true and the most
38177c478bd9Sstevel@tonic-gate	/ significant long of the longlong hrestime_adj is -1.
38187c478bd9Sstevel@tonic-gate
38197c478bd9Sstevel@tonic-gate.CL6:					/ hrestime_adj is negative
38207c478bd9Sstevel@tonic-gate	movl	%esi, %ecx
38217c478bd9Sstevel@tonic-gate	addl	max_hres_adj, %ecx
38227c478bd9Sstevel@tonic-gate	movl	%edx, %eax
38237c478bd9Sstevel@tonic-gate	adcl	$0, %eax
38247c478bd9Sstevel@tonic-gate	jc	.CL7
38257c478bd9Sstevel@tonic-gate	xor	%ecx, %ecx
38267c478bd9Sstevel@tonic-gate	subl	max_hres_adj, %ecx	/ adj = -(HRES_ADJ);
38277c478bd9Sstevel@tonic-gate	movl	$-1, %edx
38287c478bd9Sstevel@tonic-gate	jmp	.CL5
38297c478bd9Sstevel@tonic-gate.CL7:
38307c478bd9Sstevel@tonic-gate	movl	%esi, %ecx		/ adj = hrestime_adj;
38317c478bd9Sstevel@tonic-gate.CL5:
38327c478bd9Sstevel@tonic-gate	movl	timedelta, %esi
38337c478bd9Sstevel@tonic-gate	subl	%ecx, %esi
38347c478bd9Sstevel@tonic-gate	movl	timedelta+4, %eax
38357c478bd9Sstevel@tonic-gate	sbbl	%edx, %eax
38367c478bd9Sstevel@tonic-gate	movl	%esi, timedelta
38377c478bd9Sstevel@tonic-gate	movl	%eax, timedelta+4	/ timedelta -= adj;
38387c478bd9Sstevel@tonic-gate	movl	%esi, hrestime_adj
38397c478bd9Sstevel@tonic-gate	movl	%eax, hrestime_adj+4	/ hrestime_adj = timedelta;
38407c478bd9Sstevel@tonic-gate	addl	hrestime+4, %ecx
38417c478bd9Sstevel@tonic-gate
38427c478bd9Sstevel@tonic-gate	movl	%ecx, %eax		/ eax = tv_nsec
38437c478bd9Sstevel@tonic-gate1:
38447c478bd9Sstevel@tonic-gate	cmpl	$NANOSEC, %eax		/ if ((unsigned long)tv_nsec >= NANOSEC)
38457c478bd9Sstevel@tonic-gate	jb	.CL8			/ no
38467c478bd9Sstevel@tonic-gate	incl	one_sec			/ yes,  one_sec++;
38477c478bd9Sstevel@tonic-gate	incl	hrestime		/ hrestime.tv_sec++;
38487c478bd9Sstevel@tonic-gate	addl	$-NANOSEC, %eax		/ tv_nsec -= NANOSEC
38497c478bd9Sstevel@tonic-gate	jmp	1b			/ check for more seconds
38507c478bd9Sstevel@tonic-gate
38517c478bd9Sstevel@tonic-gate.CL8:
38527c478bd9Sstevel@tonic-gate	movl	%eax, hrestime+4	/ store final into hrestime.tv_nsec
38537c478bd9Sstevel@tonic-gate	incl	hres_lock		/ release the hres_lock
38547c478bd9Sstevel@tonic-gate
38557c478bd9Sstevel@tonic-gate	popl	%ebx
38567c478bd9Sstevel@tonic-gate	popl	%esi
38577c478bd9Sstevel@tonic-gate	leave
38587c478bd9Sstevel@tonic-gate	ret
38597c478bd9Sstevel@tonic-gate	SET_SIZE(hres_tick)
38607c478bd9Sstevel@tonic-gate
38617c478bd9Sstevel@tonic-gate#endif	/* __i386 */
38627c478bd9Sstevel@tonic-gate#endif	/* __lint */
38637c478bd9Sstevel@tonic-gate
38647c478bd9Sstevel@tonic-gate/*
38657c478bd9Sstevel@tonic-gate * void prefetch_smap_w(void *)
38667c478bd9Sstevel@tonic-gate *
38677c478bd9Sstevel@tonic-gate * Prefetch ahead within a linear list of smap structures.
38687c478bd9Sstevel@tonic-gate * Not implemented for ia32.  Stub for compatibility.
38697c478bd9Sstevel@tonic-gate */
38707c478bd9Sstevel@tonic-gate
38717c478bd9Sstevel@tonic-gate#if defined(__lint)
38727c478bd9Sstevel@tonic-gate
38737c478bd9Sstevel@tonic-gate/*ARGSUSED*/
38747c478bd9Sstevel@tonic-gatevoid prefetch_smap_w(void *smp)
38757c478bd9Sstevel@tonic-gate{}
38767c478bd9Sstevel@tonic-gate
38777c478bd9Sstevel@tonic-gate#else	/* __lint */
38787c478bd9Sstevel@tonic-gate
38797c478bd9Sstevel@tonic-gate	ENTRY(prefetch_smap_w)
388085641879Skalai	rep;	ret	/* use 2 byte return instruction when branch target */
388185641879Skalai			/* AMD Software Optimization Guide - Section 6.2 */
38827c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_smap_w)
38837c478bd9Sstevel@tonic-gate
38847c478bd9Sstevel@tonic-gate#endif	/* __lint */
38857c478bd9Sstevel@tonic-gate
38867c478bd9Sstevel@tonic-gate/*
38877c478bd9Sstevel@tonic-gate * prefetch_page_r(page_t *)
38887c478bd9Sstevel@tonic-gate * issue prefetch instructions for a page_t
38897c478bd9Sstevel@tonic-gate */
38907c478bd9Sstevel@tonic-gate#if defined(__lint)
38917c478bd9Sstevel@tonic-gate
38927c478bd9Sstevel@tonic-gate/*ARGSUSED*/
38937c478bd9Sstevel@tonic-gatevoid
38947c478bd9Sstevel@tonic-gateprefetch_page_r(void *pp)
38957c478bd9Sstevel@tonic-gate{}
38967c478bd9Sstevel@tonic-gate
38977c478bd9Sstevel@tonic-gate#else	/* __lint */
38987c478bd9Sstevel@tonic-gate
38997c478bd9Sstevel@tonic-gate	ENTRY(prefetch_page_r)
390085641879Skalai	rep;	ret	/* use 2 byte return instruction when branch target */
390185641879Skalai			/* AMD Software Optimization Guide - Section 6.2 */
39027c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_page_r)
39037c478bd9Sstevel@tonic-gate
39047c478bd9Sstevel@tonic-gate#endif	/* __lint */
39057c478bd9Sstevel@tonic-gate
39067c478bd9Sstevel@tonic-gate#if defined(__lint)
39077c478bd9Sstevel@tonic-gate
39087c478bd9Sstevel@tonic-gate/*ARGSUSED*/
39097c478bd9Sstevel@tonic-gateint
39107c478bd9Sstevel@tonic-gatebcmp(const void *s1, const void *s2, size_t count)
39117c478bd9Sstevel@tonic-gate{ return (0); }
39127c478bd9Sstevel@tonic-gate
39137c478bd9Sstevel@tonic-gate#else   /* __lint */
39147c478bd9Sstevel@tonic-gate
39157c478bd9Sstevel@tonic-gate#if defined(__amd64)
39167c478bd9Sstevel@tonic-gate
39177c478bd9Sstevel@tonic-gate	ENTRY(bcmp)
39187c478bd9Sstevel@tonic-gate	pushq	%rbp
39197c478bd9Sstevel@tonic-gate	movq	%rsp, %rbp
39207c478bd9Sstevel@tonic-gate#ifdef DEBUG
3921ecae7de2SMarcel Telka	testq	%rdx,%rdx
3922ecae7de2SMarcel Telka	je	1f
3923ae115bc7Smrj	movq	postbootkernelbase(%rip), %r11
39247c478bd9Sstevel@tonic-gate	cmpq	%r11, %rdi
39257c478bd9Sstevel@tonic-gate	jb	0f
39267c478bd9Sstevel@tonic-gate	cmpq	%r11, %rsi
39277c478bd9Sstevel@tonic-gate	jnb	1f
39287c478bd9Sstevel@tonic-gate0:	leaq	.bcmp_panic_msg(%rip), %rdi
39297c478bd9Sstevel@tonic-gate	xorl	%eax, %eax
39307c478bd9Sstevel@tonic-gate	call	panic
39317c478bd9Sstevel@tonic-gate1:
39327c478bd9Sstevel@tonic-gate#endif	/* DEBUG */
39337c478bd9Sstevel@tonic-gate	call	memcmp
39347c478bd9Sstevel@tonic-gate	testl	%eax, %eax
39357c478bd9Sstevel@tonic-gate	setne	%dl
39367c478bd9Sstevel@tonic-gate	leave
39377c478bd9Sstevel@tonic-gate	movzbl	%dl, %eax
39387c478bd9Sstevel@tonic-gate	ret
39397c478bd9Sstevel@tonic-gate	SET_SIZE(bcmp)
39407c478bd9Sstevel@tonic-gate
39417c478bd9Sstevel@tonic-gate#elif defined(__i386)
39427c478bd9Sstevel@tonic-gate
39437c478bd9Sstevel@tonic-gate#define	ARG_S1		8
39447c478bd9Sstevel@tonic-gate#define	ARG_S2		12
39457c478bd9Sstevel@tonic-gate#define	ARG_LENGTH	16
39467c478bd9Sstevel@tonic-gate
39477c478bd9Sstevel@tonic-gate	ENTRY(bcmp)
39487c478bd9Sstevel@tonic-gate	pushl	%ebp
39496ea6f6c0Sjj204856	movl	%esp, %ebp	/ create new stack frame
39506ea6f6c0Sjj204856#ifdef DEBUG
3951ecae7de2SMarcel Telka	cmpl	$0, ARG_LENGTH(%ebp)
3952ecae7de2SMarcel Telka	je	1f
3953ae115bc7Smrj	movl    postbootkernelbase, %eax
39547c478bd9Sstevel@tonic-gate	cmpl    %eax, ARG_S1(%ebp)
39557c478bd9Sstevel@tonic-gate	jb	0f
39567c478bd9Sstevel@tonic-gate	cmpl    %eax, ARG_S2(%ebp)
39577c478bd9Sstevel@tonic-gate	jnb	1f
39587c478bd9Sstevel@tonic-gate0:	pushl   $.bcmp_panic_msg
39597c478bd9Sstevel@tonic-gate	call    panic
39606ea6f6c0Sjj2048561:
39617c478bd9Sstevel@tonic-gate#endif	/* DEBUG */
39627c478bd9Sstevel@tonic-gate
39637c478bd9Sstevel@tonic-gate	pushl	%edi		/ save register variable
39646ea6f6c0Sjj204856	movl	ARG_S1(%ebp), %eax	/ %eax = address of string 1
39656ea6f6c0Sjj204856	movl	ARG_S2(%ebp), %ecx	/ %ecx = address of string 2
39667c478bd9Sstevel@tonic-gate	cmpl	%eax, %ecx	/ if the same string
39677c478bd9Sstevel@tonic-gate	je	.equal		/ goto .equal
39686ea6f6c0Sjj204856	movl	ARG_LENGTH(%ebp), %edi	/ %edi = length in bytes
39697c478bd9Sstevel@tonic-gate	cmpl	$4, %edi	/ if %edi < 4
39707c478bd9Sstevel@tonic-gate	jb	.byte_check	/ goto .byte_check
39717c478bd9Sstevel@tonic-gate	.align	4
39727c478bd9Sstevel@tonic-gate.word_loop:
39737c478bd9Sstevel@tonic-gate	movl	(%ecx), %edx	/ move 1 word from (%ecx) to %edx
39747c478bd9Sstevel@tonic-gate	leal	-4(%edi), %edi	/ %edi -= 4
39757c478bd9Sstevel@tonic-gate	cmpl	(%eax), %edx	/ compare 1 word from (%eax) with %edx
39767c478bd9Sstevel@tonic-gate	jne	.word_not_equal	/ if not equal, goto .word_not_equal
39777c478bd9Sstevel@tonic-gate	leal	4(%ecx), %ecx	/ %ecx += 4 (next word)
39787c478bd9Sstevel@tonic-gate	leal	4(%eax), %eax	/ %eax += 4 (next word)
39797c478bd9Sstevel@tonic-gate	cmpl	$4, %edi	/ if %edi >= 4
39807c478bd9Sstevel@tonic-gate	jae	.word_loop	/ goto .word_loop
39817c478bd9Sstevel@tonic-gate.byte_check:
39827c478bd9Sstevel@tonic-gate	cmpl	$0, %edi	/ if %edi == 0
39837c478bd9Sstevel@tonic-gate	je	.equal		/ goto .equal
39847c478bd9Sstevel@tonic-gate	jmp	.byte_loop	/ goto .byte_loop (checks in bytes)
39857c478bd9Sstevel@tonic-gate.word_not_equal:
39867c478bd9Sstevel@tonic-gate	leal	4(%edi), %edi	/ %edi += 4 (post-decremented)
39877c478bd9Sstevel@tonic-gate	.align	4
39887c478bd9Sstevel@tonic-gate.byte_loop:
39897c478bd9Sstevel@tonic-gate	movb	(%ecx),	%dl	/ move 1 byte from (%ecx) to %dl
39907c478bd9Sstevel@tonic-gate	cmpb	%dl, (%eax)	/ compare %dl with 1 byte from (%eax)
39917c478bd9Sstevel@tonic-gate	jne	.not_equal	/ if not equal, goto .not_equal
39927c478bd9Sstevel@tonic-gate	incl	%ecx		/ %ecx++ (next byte)
39937c478bd9Sstevel@tonic-gate	incl	%eax		/ %eax++ (next byte)
39947c478bd9Sstevel@tonic-gate	decl	%edi		/ %edi--
39957c478bd9Sstevel@tonic-gate	jnz	.byte_loop	/ if not zero, goto .byte_loop
39967c478bd9Sstevel@tonic-gate.equal:
39977c478bd9Sstevel@tonic-gate	xorl	%eax, %eax	/ %eax = 0
39987c478bd9Sstevel@tonic-gate	popl	%edi		/ restore register variable
39996ea6f6c0Sjj204856	leave			/ restore old stack frame
40007c478bd9Sstevel@tonic-gate	ret			/ return (NULL)
40017c478bd9Sstevel@tonic-gate	.align	4
40027c478bd9Sstevel@tonic-gate.not_equal:
40037c478bd9Sstevel@tonic-gate	movl	$1, %eax	/ return 1
40047c478bd9Sstevel@tonic-gate	popl	%edi		/ restore register variable
40056ea6f6c0Sjj204856	leave			/ restore old stack frame
40067c478bd9Sstevel@tonic-gate	ret			/ return (NULL)
40077c478bd9Sstevel@tonic-gate	SET_SIZE(bcmp)
40087c478bd9Sstevel@tonic-gate
40097c478bd9Sstevel@tonic-gate#endif	/* __i386 */
40107c478bd9Sstevel@tonic-gate
40117c478bd9Sstevel@tonic-gate#ifdef DEBUG
40127c478bd9Sstevel@tonic-gate	.text
40137c478bd9Sstevel@tonic-gate.bcmp_panic_msg:
40147c478bd9Sstevel@tonic-gate	.string "bcmp: arguments below kernelbase"
40157c478bd9Sstevel@tonic-gate#endif	/* DEBUG */
40167c478bd9Sstevel@tonic-gate
40177c478bd9Sstevel@tonic-gate#endif	/* __lint */
4018ae115bc7Smrj
4019ae115bc7Smrj#if defined(__lint)
4020ae115bc7Smrj
4021ae115bc7Smrjuint_t
4022ae115bc7Smrjbsrw_insn(uint16_t mask)
4023ae115bc7Smrj{
4024ae115bc7Smrj	uint_t index = sizeof (mask) * NBBY - 1;
4025ae115bc7Smrj
4026ae115bc7Smrj	while ((mask & (1 << index)) == 0)
4027ae115bc7Smrj		index--;
4028ae115bc7Smrj	return (index);
4029ae115bc7Smrj}
4030ae115bc7Smrj
4031ae115bc7Smrj#else	/* __lint */
4032ae115bc7Smrj
4033ae115bc7Smrj#if defined(__amd64)
4034ae115bc7Smrj
4035ae115bc7Smrj	ENTRY_NP(bsrw_insn)
4036ae115bc7Smrj	xorl	%eax, %eax
4037ae115bc7Smrj	bsrw	%di, %ax
4038ae115bc7Smrj	ret
4039ae115bc7Smrj	SET_SIZE(bsrw_insn)
4040ae115bc7Smrj
4041ae115bc7Smrj#elif defined(__i386)
4042ae115bc7Smrj
4043ae115bc7Smrj	ENTRY_NP(bsrw_insn)
4044ae115bc7Smrj	movw	4(%esp), %cx
4045ae115bc7Smrj	xorl	%eax, %eax
4046ae115bc7Smrj	bsrw	%cx, %ax
4047ae115bc7Smrj	ret
4048ae115bc7Smrj	SET_SIZE(bsrw_insn)
4049ae115bc7Smrj
4050ae115bc7Smrj#endif	/* __i386 */
4051ae115bc7Smrj#endif	/* __lint */
4052ae115bc7Smrj
4053ae115bc7Smrj#if defined(__lint)
4054ae115bc7Smrj
4055ae115bc7Smrjuint_t
4056ae115bc7Smrjatomic_btr32(uint32_t *pending, uint_t pil)
4057ae115bc7Smrj{
4058ae115bc7Smrj	return (*pending &= ~(1 << pil));
4059ae115bc7Smrj}
4060ae115bc7Smrj
4061ae115bc7Smrj#else	/* __lint */
4062ae115bc7Smrj
4063ae115bc7Smrj#if defined(__i386)
4064ae115bc7Smrj
4065ae115bc7Smrj	ENTRY_NP(atomic_btr32)
4066ae115bc7Smrj	movl	4(%esp), %ecx
4067ae115bc7Smrj	movl	8(%esp), %edx
4068ae115bc7Smrj	xorl	%eax, %eax
4069ae115bc7Smrj	lock
4070ae115bc7Smrj	btrl	%edx, (%ecx)
4071ae115bc7Smrj	setc	%al
4072ae115bc7Smrj	ret
4073ae115bc7Smrj	SET_SIZE(atomic_btr32)
4074ae115bc7Smrj
4075ae115bc7Smrj#endif	/* __i386 */
4076ae115bc7Smrj#endif	/* __lint */
4077ae115bc7Smrj
4078ae115bc7Smrj#if defined(__lint)
4079ae115bc7Smrj
4080ae115bc7Smrj/*ARGSUSED*/
4081ae115bc7Smrjvoid
4082ae115bc7Smrjswitch_sp_and_call(void *newsp, void (*func)(uint_t, uint_t), uint_t arg1,
4083ae115bc7Smrj	    uint_t arg2)
4084ae115bc7Smrj{}
4085ae115bc7Smrj
4086ae115bc7Smrj#else	/* __lint */
4087ae115bc7Smrj
4088ae115bc7Smrj#if defined(__amd64)
4089ae115bc7Smrj
4090ae115bc7Smrj	ENTRY_NP(switch_sp_and_call)
4091ae115bc7Smrj	pushq	%rbp
4092ae115bc7Smrj	movq	%rsp, %rbp		/* set up stack frame */
4093ae115bc7Smrj	movq	%rdi, %rsp		/* switch stack pointer */
4094ae115bc7Smrj	movq	%rdx, %rdi		/* pass func arg 1 */
4095ae115bc7Smrj	movq	%rsi, %r11		/* save function to call */
4096ae115bc7Smrj	movq	%rcx, %rsi		/* pass func arg 2 */
4097ae115bc7Smrj	call	*%r11			/* call function */
4098ae115bc7Smrj	leave				/* restore stack */
4099ae115bc7Smrj	ret
4100ae115bc7Smrj	SET_SIZE(switch_sp_and_call)
4101ae115bc7Smrj
4102ae115bc7Smrj#elif defined(__i386)
4103ae115bc7Smrj
4104ae115bc7Smrj	ENTRY_NP(switch_sp_and_call)
4105ae115bc7Smrj	pushl	%ebp
4106ae115bc7Smrj	mov	%esp, %ebp		/* set up stack frame */
4107ae115bc7Smrj	movl	8(%ebp), %esp		/* switch stack pointer */
4108ae115bc7Smrj	pushl	20(%ebp)		/* push func arg 2 */
4109ae115bc7Smrj	pushl	16(%ebp)		/* push func arg 1 */
4110ae115bc7Smrj	call	*12(%ebp)		/* call function */
4111ae115bc7Smrj	addl	$8, %esp		/* pop arguments */
4112ae115bc7Smrj	leave				/* restore stack */
4113ae115bc7Smrj	ret
4114ae115bc7Smrj	SET_SIZE(switch_sp_and_call)
4115ae115bc7Smrj
4116ae115bc7Smrj#endif	/* __i386 */
4117ae115bc7Smrj#endif	/* __lint */
4118ae115bc7Smrj
4119ae115bc7Smrj#if defined(__lint)
4120ae115bc7Smrj
4121ae115bc7Smrjvoid
4122ae115bc7Smrjkmdb_enter(void)
4123ae115bc7Smrj{}
4124ae115bc7Smrj
4125ae115bc7Smrj#else	/* __lint */
4126ae115bc7Smrj
4127ae115bc7Smrj#if defined(__amd64)
4128ae115bc7Smrj
4129ae115bc7Smrj	ENTRY_NP(kmdb_enter)
4130ae115bc7Smrj	pushq	%rbp
4131ae115bc7Smrj	movq	%rsp, %rbp
4132ae115bc7Smrj
4133ae115bc7Smrj	/*
4134ae115bc7Smrj	 * Save flags, do a 'cli' then return the saved flags
4135ae115bc7Smrj	 */
4136ae115bc7Smrj	call	intr_clear
4137ae115bc7Smrj
4138ae115bc7Smrj	int	$T_DBGENTR
4139ae115bc7Smrj
4140ae115bc7Smrj	/*
4141ae115bc7Smrj	 * Restore the saved flags
4142ae115bc7Smrj	 */
4143ae115bc7Smrj	movq	%rax, %rdi
4144ae115bc7Smrj	call	intr_restore
4145ae115bc7Smrj
4146ae115bc7Smrj	leave
4147ae115bc7Smrj	ret
4148ae115bc7Smrj	SET_SIZE(kmdb_enter)
4149ae115bc7Smrj
4150ae115bc7Smrj#elif defined(__i386)
4151ae115bc7Smrj
4152ae115bc7Smrj	ENTRY_NP(kmdb_enter)
4153ae115bc7Smrj	pushl	%ebp
4154ae115bc7Smrj	movl	%esp, %ebp
4155ae115bc7Smrj
4156ae115bc7Smrj	/*
4157ae115bc7Smrj	 * Save flags, do a 'cli' then return the saved flags
4158ae115bc7Smrj	 */
4159ae115bc7Smrj	call	intr_clear
4160ae115bc7Smrj
4161ae115bc7Smrj	int	$T_DBGENTR
4162ae115bc7Smrj
4163ae115bc7Smrj	/*
4164ae115bc7Smrj	 * Restore the saved flags
4165ae115bc7Smrj	 */
4166ae115bc7Smrj	pushl	%eax
4167ae115bc7Smrj	call	intr_restore
4168ae115bc7Smrj	addl	$4, %esp
4169ae115bc7Smrj
4170ae115bc7Smrj	leave
4171ae115bc7Smrj	ret
4172ae115bc7Smrj	SET_SIZE(kmdb_enter)
4173ae115bc7Smrj
4174ae115bc7Smrj#endif	/* __i386 */
4175ae115bc7Smrj#endif	/* __lint */
4176ae115bc7Smrj
4177ae115bc7Smrj#if defined(__lint)
4178ae115bc7Smrj
4179ae115bc7Smrjvoid
4180ae115bc7Smrjreturn_instr(void)
4181ae115bc7Smrj{}
4182ae115bc7Smrj
4183ae115bc7Smrj#else	/* __lint */
4184ae115bc7Smrj
4185ae115bc7Smrj	ENTRY_NP(return_instr)
4186ae115bc7Smrj	rep;	ret	/* use 2 byte instruction when branch target */
4187ae115bc7Smrj			/* AMD Software Optimization Guide - Section 6.2 */
4188ae115bc7Smrj	SET_SIZE(return_instr)
4189ae115bc7Smrj
4190ae115bc7Smrj#endif	/* __lint */
4191ae115bc7Smrj
4192ae115bc7Smrj#if defined(__lint)
4193ae115bc7Smrj
4194ae115bc7Smrjulong_t
4195ae115bc7Smrjgetflags(void)
4196ae115bc7Smrj{
4197ae115bc7Smrj	return (0);
4198ae115bc7Smrj}
4199ae115bc7Smrj
4200ae115bc7Smrj#else	/* __lint */
4201ae115bc7Smrj
4202ae115bc7Smrj#if defined(__amd64)
4203ae115bc7Smrj
4204ae115bc7Smrj	ENTRY(getflags)
4205ae115bc7Smrj	pushfq
4206ae115bc7Smrj	popq	%rax
4207843e1988Sjohnlev#if defined(__xpv)
4208843e1988Sjohnlev	CURTHREAD(%rdi)
4209843e1988Sjohnlev	KPREEMPT_DISABLE(%rdi)
4210843e1988Sjohnlev	/*
4211843e1988Sjohnlev	 * Synthesize the PS_IE bit from the event mask bit
4212843e1988Sjohnlev	 */
4213843e1988Sjohnlev	CURVCPU(%r11)
4214843e1988Sjohnlev	andq    $_BITNOT(PS_IE), %rax
4215843e1988Sjohnlev	XEN_TEST_UPCALL_MASK(%r11)
4216843e1988Sjohnlev	jnz	1f
4217843e1988Sjohnlev	orq	$PS_IE, %rax
4218843e1988Sjohnlev1:
4219843e1988Sjohnlev	KPREEMPT_ENABLE_NOKP(%rdi)
4220843e1988Sjohnlev#endif
4221ae115bc7Smrj	ret
4222ae115bc7Smrj	SET_SIZE(getflags)
4223ae115bc7Smrj
4224ae115bc7Smrj#elif defined(__i386)
4225ae115bc7Smrj
4226ae115bc7Smrj	ENTRY(getflags)
4227ae115bc7Smrj	pushfl
4228ae115bc7Smrj	popl	%eax
4229843e1988Sjohnlev#if defined(__xpv)
4230843e1988Sjohnlev	CURTHREAD(%ecx)
4231843e1988Sjohnlev	KPREEMPT_DISABLE(%ecx)
4232843e1988Sjohnlev	/*
4233843e1988Sjohnlev	 * Synthesize the PS_IE bit from the event mask bit
4234843e1988Sjohnlev	 */
4235843e1988Sjohnlev	CURVCPU(%edx)
4236843e1988Sjohnlev	andl    $_BITNOT(PS_IE), %eax
4237843e1988Sjohnlev	XEN_TEST_UPCALL_MASK(%edx)
4238843e1988Sjohnlev	jnz	1f
4239843e1988Sjohnlev	orl	$PS_IE, %eax
4240843e1988Sjohnlev1:
4241843e1988Sjohnlev	KPREEMPT_ENABLE_NOKP(%ecx)
4242843e1988Sjohnlev#endif
4243ae115bc7Smrj	ret
4244ae115bc7Smrj	SET_SIZE(getflags)
4245ae115bc7Smrj
4246ae115bc7Smrj#endif	/* __i386 */
4247ae115bc7Smrj
4248ae115bc7Smrj#endif	/* __lint */
42494df4bd60Sbs21162
42504df4bd60Sbs21162#if defined(__lint)
42514df4bd60Sbs21162
42524df4bd60Sbs21162ftrace_icookie_t
42534df4bd60Sbs21162ftrace_interrupt_disable(void)
42544df4bd60Sbs21162{ return (0); }
42554df4bd60Sbs21162
42564df4bd60Sbs21162#else   /* __lint */
42574df4bd60Sbs21162
42584df4bd60Sbs21162#if defined(__amd64)
42594df4bd60Sbs21162
42604df4bd60Sbs21162	ENTRY(ftrace_interrupt_disable)
42614df4bd60Sbs21162	pushfq
42624df4bd60Sbs21162	popq	%rax
42634df4bd60Sbs21162	CLI(%rdx)
42644df4bd60Sbs21162	ret
42654df4bd60Sbs21162	SET_SIZE(ftrace_interrupt_disable)
42664df4bd60Sbs21162
42674df4bd60Sbs21162#elif defined(__i386)
42684df4bd60Sbs21162
42694df4bd60Sbs21162	ENTRY(ftrace_interrupt_disable)
42704df4bd60Sbs21162	pushfl
42714df4bd60Sbs21162	popl	%eax
42724df4bd60Sbs21162	CLI(%edx)
42734df4bd60Sbs21162	ret
42744df4bd60Sbs21162	SET_SIZE(ftrace_interrupt_disable)
42754df4bd60Sbs21162
42764df4bd60Sbs21162#endif	/* __i386 */
42774df4bd60Sbs21162#endif	/* __lint */
42784df4bd60Sbs21162
42794df4bd60Sbs21162#if defined(__lint)
42804df4bd60Sbs21162
42814df4bd60Sbs21162/*ARGSUSED*/
42824df4bd60Sbs21162void
42834df4bd60Sbs21162ftrace_interrupt_enable(ftrace_icookie_t cookie)
42844df4bd60Sbs21162{}
42854df4bd60Sbs21162
42864df4bd60Sbs21162#else	/* __lint */
42874df4bd60Sbs21162
42884df4bd60Sbs21162#if defined(__amd64)
42894df4bd60Sbs21162
42904df4bd60Sbs21162	ENTRY(ftrace_interrupt_enable)
42914df4bd60Sbs21162	pushq	%rdi
42924df4bd60Sbs21162	popfq
42934df4bd60Sbs21162	ret
42944df4bd60Sbs21162	SET_SIZE(ftrace_interrupt_enable)
42954df4bd60Sbs21162
42964df4bd60Sbs21162#elif defined(__i386)
42974df4bd60Sbs21162
42984df4bd60Sbs21162	ENTRY(ftrace_interrupt_enable)
42994df4bd60Sbs21162	movl	4(%esp), %eax
43004df4bd60Sbs21162	pushl	%eax
43014df4bd60Sbs21162	popfl
43024df4bd60Sbs21162	ret
43034df4bd60Sbs21162	SET_SIZE(ftrace_interrupt_enable)
43044df4bd60Sbs21162
43054df4bd60Sbs21162#endif	/* __i386 */
43064df4bd60Sbs21162#endif	/* __lint */
430786c1f4dcSVikram Hegde
430886c1f4dcSVikram Hegde#if defined (__lint)
430986c1f4dcSVikram Hegde
431086c1f4dcSVikram Hegde/*ARGSUSED*/
431186c1f4dcSVikram Hegdevoid
431286c1f4dcSVikram Hegdeclflush_insn(caddr_t addr)
431386c1f4dcSVikram Hegde{}
431486c1f4dcSVikram Hegde
431586c1f4dcSVikram Hegde#else /* __lint */
431686c1f4dcSVikram Hegde
431786c1f4dcSVikram Hegde#if defined (__amd64)
431886c1f4dcSVikram Hegde	ENTRY(clflush_insn)
431986c1f4dcSVikram Hegde	clflush (%rdi)
432086c1f4dcSVikram Hegde	ret
432186c1f4dcSVikram Hegde	SET_SIZE(clflush_insn)
432286c1f4dcSVikram Hegde#elif defined (__i386)
432386c1f4dcSVikram Hegde	ENTRY(clflush_insn)
432486c1f4dcSVikram Hegde	movl	4(%esp), %eax
432586c1f4dcSVikram Hegde	clflush (%eax)
432686c1f4dcSVikram Hegde	ret
432786c1f4dcSVikram Hegde	SET_SIZE(clflush_insn)
432886c1f4dcSVikram Hegde
432986c1f4dcSVikram Hegde#endif /* __i386 */
433086c1f4dcSVikram Hegde#endif /* __lint */
433186c1f4dcSVikram Hegde
433286c1f4dcSVikram Hegde#if defined (__lint)
433386c1f4dcSVikram Hegde/*ARGSUSED*/
433486c1f4dcSVikram Hegdevoid
433586c1f4dcSVikram Hegdemfence_insn(void)
433686c1f4dcSVikram Hegde{}
433786c1f4dcSVikram Hegde
433886c1f4dcSVikram Hegde#else /* __lint */
433986c1f4dcSVikram Hegde
434086c1f4dcSVikram Hegde#if defined (__amd64)
434186c1f4dcSVikram Hegde	ENTRY(mfence_insn)
434286c1f4dcSVikram Hegde	mfence
434386c1f4dcSVikram Hegde	ret
434486c1f4dcSVikram Hegde	SET_SIZE(mfence_insn)
434586c1f4dcSVikram Hegde#elif defined (__i386)
434686c1f4dcSVikram Hegde	ENTRY(mfence_insn)
434786c1f4dcSVikram Hegde	mfence
434886c1f4dcSVikram Hegde	ret
434986c1f4dcSVikram Hegde	SET_SIZE(mfence_insn)
435086c1f4dcSVikram Hegde
435186c1f4dcSVikram Hegde#endif /* __i386 */
435286c1f4dcSVikram Hegde#endif /* __lint */
43537997e108SSurya Prakki
43547997e108SSurya Prakki/*
435579ec9da8SYuri Pankov * VMware implements an I/O port that programs can query to detect if software
435679ec9da8SYuri Pankov * is running in a VMware hypervisor. This hypervisor port behaves differently
435779ec9da8SYuri Pankov * depending on magic values in certain registers and modifies some registers
435879ec9da8SYuri Pankov * as a side effect.
435979ec9da8SYuri Pankov *
436079ec9da8SYuri Pankov * References: http://kb.vmware.com/kb/1009458
43617997e108SSurya Prakki */
436279ec9da8SYuri Pankov
43637997e108SSurya Prakki#if defined(__lint)
43647997e108SSurya Prakki
436579ec9da8SYuri Pankov/* ARGSUSED */
436679ec9da8SYuri Pankovvoid
436779ec9da8SYuri Pankovvmware_port(int cmd, uint32_t *regs) { return; }
43687997e108SSurya Prakki
43697997e108SSurya Prakki#else
43707997e108SSurya Prakki
43717997e108SSurya Prakki#if defined(__amd64)
43727997e108SSurya Prakki
437379ec9da8SYuri Pankov	ENTRY(vmware_port)
43747997e108SSurya Prakki	pushq	%rbx
437579ec9da8SYuri Pankov	movl	$VMWARE_HVMAGIC, %eax
437679ec9da8SYuri Pankov	movl	$0xffffffff, %ebx
437779ec9da8SYuri Pankov	movl	%edi, %ecx
437879ec9da8SYuri Pankov	movl	$VMWARE_HVPORT, %edx
43797997e108SSurya Prakki	inl	(%dx)
438079ec9da8SYuri Pankov	movl	%eax, (%rsi)
438179ec9da8SYuri Pankov	movl	%ebx, 4(%rsi)
438279ec9da8SYuri Pankov	movl	%ecx, 8(%rsi)
438379ec9da8SYuri Pankov	movl	%edx, 12(%rsi)
43847997e108SSurya Prakki	popq	%rbx
43857997e108SSurya Prakki	ret
438679ec9da8SYuri Pankov	SET_SIZE(vmware_port)
43877997e108SSurya Prakki
43887997e108SSurya Prakki#elif defined(__i386)
43897997e108SSurya Prakki
439079ec9da8SYuri Pankov	ENTRY(vmware_port)
43917997e108SSurya Prakki	pushl	%ebx
439279ec9da8SYuri Pankov	pushl	%esi
439379ec9da8SYuri Pankov	movl	$VMWARE_HVMAGIC, %eax
439479ec9da8SYuri Pankov	movl	$0xffffffff, %ebx
439579ec9da8SYuri Pankov	movl	12(%esp), %ecx
439679ec9da8SYuri Pankov	movl	$VMWARE_HVPORT, %edx
43977997e108SSurya Prakki	inl	(%dx)
439879ec9da8SYuri Pankov	movl	16(%esp), %esi
439979ec9da8SYuri Pankov	movl	%eax, (%esi)
440079ec9da8SYuri Pankov	movl	%ebx, 4(%esi)
440179ec9da8SYuri Pankov	movl	%ecx, 8(%esi)
440279ec9da8SYuri Pankov	movl	%edx, 12(%esi)
440379ec9da8SYuri Pankov	popl	%esi
44047997e108SSurya Prakki	popl	%ebx
44057997e108SSurya Prakki	ret
440679ec9da8SYuri Pankov	SET_SIZE(vmware_port)
44077997e108SSurya Prakki
44087997e108SSurya Prakki#endif /* __i386 */
44097997e108SSurya Prakki#endif /* __lint */
4410