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. 24549e8c97SMarcel Telka * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 25bf16b11eSMatthew Ahrens * Copyright (c) 2014 by Delphix. All rights reserved. 26*263f549eSPatrick 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 2805fdb8cf8cSJosef 'Jeff' Sipek bsfq %rdi, %rdi 2806fdb8cf8cSJosef '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 2815fdb8cf8cSJosef 'Jeff' Sipek jz 0f 28167c478bd9Sstevel@tonic-gate incl %eax 28177c478bd9Sstevel@tonic-gate ret 2818fdb8cf8cSJosef 'Jeff' Sipek0: 2819fdb8cf8cSJosef 'Jeff' Sipek xorl %eax, %eax 2820fdb8cf8cSJosef '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*/ 2834bf16b11eSMatthew Ahrensint 2835bf16b11eSMatthew Ahrenshighbit64(uint64_t i) 2836bf16b11eSMatthew Ahrens{ return (0); } 2837bf16b11eSMatthew Ahrens 2838bf16b11eSMatthew Ahrens#else /* __lint */ 2839bf16b11eSMatthew Ahrens 2840bf16b11eSMatthew Ahrens#if defined(__amd64) 2841bf16b11eSMatthew Ahrens 2842fdb8cf8cSJosef 'Jeff' Sipek ENTRY(highbit) 2843fdb8cf8cSJosef 'Jeff' Sipek ALTENTRY(highbit64) 2844bf16b11eSMatthew Ahrens movl $-1, %eax 2845fdb8cf8cSJosef 'Jeff' Sipek bsrq %rdi, %rdi 2846fdb8cf8cSJosef 'Jeff' Sipek cmovnz %edi, %eax 2847bf16b11eSMatthew Ahrens incl %eax 2848bf16b11eSMatthew Ahrens ret 2849bf16b11eSMatthew Ahrens SET_SIZE(highbit64) 2850fdb8cf8cSJosef 'Jeff' Sipek SET_SIZE(highbit) 2851bf16b11eSMatthew Ahrens 2852bf16b11eSMatthew Ahrens#elif defined(__i386) 2853bf16b11eSMatthew Ahrens 2854fdb8cf8cSJosef 'Jeff' Sipek ENTRY(highbit) 2855fdb8cf8cSJosef 'Jeff' Sipek bsrl 4(%esp), %eax 2856fdb8cf8cSJosef 'Jeff' Sipek jz 0f 2857fdb8cf8cSJosef 'Jeff' Sipek incl %eax 2858fdb8cf8cSJosef 'Jeff' Sipek ret 2859fdb8cf8cSJosef 'Jeff' Sipek0: 2860fdb8cf8cSJosef 'Jeff' Sipek xorl %eax, %eax 2861fdb8cf8cSJosef 'Jeff' Sipek ret 2862fdb8cf8cSJosef 'Jeff' Sipek SET_SIZE(highbit) 2863fdb8cf8cSJosef 'Jeff' Sipek 2864bf16b11eSMatthew Ahrens ENTRY(highbit64) 2865bf16b11eSMatthew Ahrens bsrl 8(%esp), %eax 2866fdb8cf8cSJosef 'Jeff' Sipek jz highbit 2867fdb8cf8cSJosef 'Jeff' Sipek addl $33, %eax 2868bf16b11eSMatthew Ahrens ret 2869bf16b11eSMatthew Ahrens SET_SIZE(highbit64) 2870bf16b11eSMatthew Ahrens 2871bf16b11eSMatthew Ahrens#endif /* __i386 */ 2872bf16b11eSMatthew Ahrens#endif /* __lint */ 2873bf16b11eSMatthew Ahrens 2874bf16b11eSMatthew Ahrens#if defined(__lint) 2875bf16b11eSMatthew Ahrens 2876bf16b11eSMatthew 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 = ®s 35417c478bd9Sstevel@tonic-gate pushl %eax / push on_panic_stack 35427c478bd9Sstevel@tonic-gate pushl %ecx / push ®s 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 3921549e8c97SMarcel Telka testq %rdx,%rdx 3922549e8c97SMarcel 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 3951549e8c97SMarcel Telka cmpl $0, ARG_LENGTH(%ebp) 3952549e8c97SMarcel 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