10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51582Skchow * Common Development and Distribution License (the "License"). 61582Skchow * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 213446Smrj 220Sstevel@tonic-gate/* 2312826Skuriakose.kuruvilla@oracle.com * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate/* 270Sstevel@tonic-gate * Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. 280Sstevel@tonic-gate * Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T 290Sstevel@tonic-gate * All Rights Reserved 300Sstevel@tonic-gate */ 310Sstevel@tonic-gate 320Sstevel@tonic-gate/* 33*13134Skuriakose.kuruvilla@oracle.com * Copyright (c) 2009, Intel Corporation. 34*13134Skuriakose.kuruvilla@oracle.com * All rights reserved. 35*13134Skuriakose.kuruvilla@oracle.com */ 36*13134Skuriakose.kuruvilla@oracle.com 37*13134Skuriakose.kuruvilla@oracle.com/* 380Sstevel@tonic-gate * General assembly language routines. 390Sstevel@tonic-gate * It is the intent of this file to contain routines that are 400Sstevel@tonic-gate * independent of the specific kernel architecture, and those that are 410Sstevel@tonic-gate * common across kernel architectures. 420Sstevel@tonic-gate * As architectures diverge, and implementations of specific 430Sstevel@tonic-gate * architecture-dependent routines change, the routines should be moved 440Sstevel@tonic-gate * from this file into the respective ../`arch -k`/subr.s file. 450Sstevel@tonic-gate */ 460Sstevel@tonic-gate 470Sstevel@tonic-gate#include <sys/asm_linkage.h> 480Sstevel@tonic-gate#include <sys/asm_misc.h> 490Sstevel@tonic-gate#include <sys/panic.h> 500Sstevel@tonic-gate#include <sys/ontrap.h> 510Sstevel@tonic-gate#include <sys/regset.h> 520Sstevel@tonic-gate#include <sys/privregs.h> 530Sstevel@tonic-gate#include <sys/reboot.h> 540Sstevel@tonic-gate#include <sys/psw.h> 550Sstevel@tonic-gate#include <sys/x86_archext.h> 560Sstevel@tonic-gate 570Sstevel@tonic-gate#if defined(__lint) 580Sstevel@tonic-gate#include <sys/types.h> 590Sstevel@tonic-gate#include <sys/systm.h> 600Sstevel@tonic-gate#include <sys/thread.h> 610Sstevel@tonic-gate#include <sys/archsystm.h> 620Sstevel@tonic-gate#include <sys/byteorder.h> 630Sstevel@tonic-gate#include <sys/dtrace.h> 643647Sbs21162#include <sys/ftrace.h> 650Sstevel@tonic-gate#else /* __lint */ 660Sstevel@tonic-gate#include "assym.h" 670Sstevel@tonic-gate#endif /* __lint */ 680Sstevel@tonic-gate#include <sys/dditypes.h> 690Sstevel@tonic-gate 700Sstevel@tonic-gate/* 710Sstevel@tonic-gate * on_fault() 720Sstevel@tonic-gate * Catch lofault faults. Like setjmp except it returns one 730Sstevel@tonic-gate * if code following causes uncorrectable fault. Turned off 740Sstevel@tonic-gate * by calling no_fault(). 750Sstevel@tonic-gate */ 760Sstevel@tonic-gate 770Sstevel@tonic-gate#if defined(__lint) 780Sstevel@tonic-gate 790Sstevel@tonic-gate/* ARGSUSED */ 800Sstevel@tonic-gateint 810Sstevel@tonic-gateon_fault(label_t *ljb) 820Sstevel@tonic-gate{ return (0); } 830Sstevel@tonic-gate 840Sstevel@tonic-gatevoid 850Sstevel@tonic-gateno_fault(void) 860Sstevel@tonic-gate{} 870Sstevel@tonic-gate 880Sstevel@tonic-gate#else /* __lint */ 890Sstevel@tonic-gate 900Sstevel@tonic-gate#if defined(__amd64) 910Sstevel@tonic-gate 920Sstevel@tonic-gate ENTRY(on_fault) 930Sstevel@tonic-gate movq %gs:CPU_THREAD, %rsi 940Sstevel@tonic-gate leaq catch_fault(%rip), %rdx 950Sstevel@tonic-gate movq %rdi, T_ONFAULT(%rsi) /* jumpbuf in t_onfault */ 960Sstevel@tonic-gate movq %rdx, T_LOFAULT(%rsi) /* catch_fault in t_lofault */ 970Sstevel@tonic-gate jmp setjmp /* let setjmp do the rest */ 980Sstevel@tonic-gate 990Sstevel@tonic-gatecatch_fault: 1000Sstevel@tonic-gate movq %gs:CPU_THREAD, %rsi 1010Sstevel@tonic-gate movq T_ONFAULT(%rsi), %rdi /* address of save area */ 1020Sstevel@tonic-gate xorl %eax, %eax 1030Sstevel@tonic-gate movq %rax, T_ONFAULT(%rsi) /* turn off onfault */ 1040Sstevel@tonic-gate movq %rax, T_LOFAULT(%rsi) /* turn off lofault */ 1050Sstevel@tonic-gate jmp longjmp /* let longjmp do the rest */ 1060Sstevel@tonic-gate SET_SIZE(on_fault) 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate ENTRY(no_fault) 1090Sstevel@tonic-gate movq %gs:CPU_THREAD, %rsi 1100Sstevel@tonic-gate xorl %eax, %eax 1110Sstevel@tonic-gate movq %rax, T_ONFAULT(%rsi) /* turn off onfault */ 1120Sstevel@tonic-gate movq %rax, T_LOFAULT(%rsi) /* turn off lofault */ 1130Sstevel@tonic-gate ret 1140Sstevel@tonic-gate SET_SIZE(no_fault) 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate#elif defined(__i386) 1177421SDaniel.Anderson@Sun.COM 1180Sstevel@tonic-gate ENTRY(on_fault) 1190Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 1200Sstevel@tonic-gate movl 4(%esp), %eax /* jumpbuf address */ 1210Sstevel@tonic-gate leal catch_fault, %ecx 1220Sstevel@tonic-gate movl %eax, T_ONFAULT(%edx) /* jumpbuf in t_onfault */ 1230Sstevel@tonic-gate movl %ecx, T_LOFAULT(%edx) /* catch_fault in t_lofault */ 1240Sstevel@tonic-gate jmp setjmp /* let setjmp do the rest */ 1250Sstevel@tonic-gate 1260Sstevel@tonic-gatecatch_fault: 1270Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 1280Sstevel@tonic-gate xorl %eax, %eax 1290Sstevel@tonic-gate movl T_ONFAULT(%edx), %ecx /* address of save area */ 1300Sstevel@tonic-gate movl %eax, T_ONFAULT(%edx) /* turn off onfault */ 1310Sstevel@tonic-gate movl %eax, T_LOFAULT(%edx) /* turn off lofault */ 1320Sstevel@tonic-gate pushl %ecx 1330Sstevel@tonic-gate call longjmp /* let longjmp do the rest */ 1340Sstevel@tonic-gate SET_SIZE(on_fault) 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate ENTRY(no_fault) 1370Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 1380Sstevel@tonic-gate xorl %eax, %eax 1390Sstevel@tonic-gate movl %eax, T_ONFAULT(%edx) /* turn off onfault */ 1400Sstevel@tonic-gate movl %eax, T_LOFAULT(%edx) /* turn off lofault */ 1410Sstevel@tonic-gate ret 1420Sstevel@tonic-gate SET_SIZE(no_fault) 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate#endif /* __i386 */ 1450Sstevel@tonic-gate#endif /* __lint */ 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate/* 1480Sstevel@tonic-gate * Default trampoline code for on_trap() (see <sys/ontrap.h>). We just 1490Sstevel@tonic-gate * do a longjmp(&curthread->t_ontrap->ot_jmpbuf) if this is ever called. 1500Sstevel@tonic-gate */ 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate#if defined(lint) 1530Sstevel@tonic-gate 1540Sstevel@tonic-gatevoid 1550Sstevel@tonic-gateon_trap_trampoline(void) 1560Sstevel@tonic-gate{} 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate#else /* __lint */ 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate#if defined(__amd64) 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate ENTRY(on_trap_trampoline) 1630Sstevel@tonic-gate movq %gs:CPU_THREAD, %rsi 1640Sstevel@tonic-gate movq T_ONTRAP(%rsi), %rdi 1650Sstevel@tonic-gate addq $OT_JMPBUF, %rdi 1660Sstevel@tonic-gate jmp longjmp 1670Sstevel@tonic-gate SET_SIZE(on_trap_trampoline) 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate#elif defined(__i386) 1700Sstevel@tonic-gate 1710Sstevel@tonic-gate ENTRY(on_trap_trampoline) 1720Sstevel@tonic-gate movl %gs:CPU_THREAD, %eax 1730Sstevel@tonic-gate movl T_ONTRAP(%eax), %eax 1740Sstevel@tonic-gate addl $OT_JMPBUF, %eax 1750Sstevel@tonic-gate pushl %eax 1760Sstevel@tonic-gate call longjmp 1770Sstevel@tonic-gate SET_SIZE(on_trap_trampoline) 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate#endif /* __i386 */ 1800Sstevel@tonic-gate#endif /* __lint */ 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate/* 1830Sstevel@tonic-gate * Push a new element on to the t_ontrap stack. Refer to <sys/ontrap.h> for 1840Sstevel@tonic-gate * more information about the on_trap() mechanism. If the on_trap_data is the 1850Sstevel@tonic-gate * same as the topmost stack element, we just modify that element. 1860Sstevel@tonic-gate */ 1870Sstevel@tonic-gate#if defined(lint) 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate/*ARGSUSED*/ 1900Sstevel@tonic-gateint 1910Sstevel@tonic-gateon_trap(on_trap_data_t *otp, uint_t prot) 1920Sstevel@tonic-gate{ return (0); } 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate#else /* __lint */ 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate#if defined(__amd64) 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate ENTRY(on_trap) 1990Sstevel@tonic-gate movw %si, OT_PROT(%rdi) /* ot_prot = prot */ 2000Sstevel@tonic-gate movw $0, OT_TRAP(%rdi) /* ot_trap = 0 */ 2010Sstevel@tonic-gate leaq on_trap_trampoline(%rip), %rdx /* rdx = &on_trap_trampoline */ 2020Sstevel@tonic-gate movq %rdx, OT_TRAMPOLINE(%rdi) /* ot_trampoline = rdx */ 2030Sstevel@tonic-gate xorl %ecx, %ecx 2040Sstevel@tonic-gate movq %rcx, OT_HANDLE(%rdi) /* ot_handle = NULL */ 2050Sstevel@tonic-gate movq %rcx, OT_PAD1(%rdi) /* ot_pad1 = NULL */ 2060Sstevel@tonic-gate movq %gs:CPU_THREAD, %rdx /* rdx = curthread */ 2070Sstevel@tonic-gate movq T_ONTRAP(%rdx), %rcx /* rcx = curthread->t_ontrap */ 2080Sstevel@tonic-gate cmpq %rdi, %rcx /* if (otp == %rcx) */ 2090Sstevel@tonic-gate je 0f /* don't modify t_ontrap */ 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate movq %rcx, OT_PREV(%rdi) /* ot_prev = t_ontrap */ 2120Sstevel@tonic-gate movq %rdi, T_ONTRAP(%rdx) /* curthread->t_ontrap = otp */ 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate0: addq $OT_JMPBUF, %rdi /* &ot_jmpbuf */ 2150Sstevel@tonic-gate jmp setjmp 2160Sstevel@tonic-gate SET_SIZE(on_trap) 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate#elif defined(__i386) 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate ENTRY(on_trap) 2210Sstevel@tonic-gate movl 4(%esp), %eax /* %eax = otp */ 2220Sstevel@tonic-gate movl 8(%esp), %edx /* %edx = prot */ 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate movw %dx, OT_PROT(%eax) /* ot_prot = prot */ 2250Sstevel@tonic-gate movw $0, OT_TRAP(%eax) /* ot_trap = 0 */ 2260Sstevel@tonic-gate leal on_trap_trampoline, %edx /* %edx = &on_trap_trampoline */ 2270Sstevel@tonic-gate movl %edx, OT_TRAMPOLINE(%eax) /* ot_trampoline = %edx */ 2280Sstevel@tonic-gate movl $0, OT_HANDLE(%eax) /* ot_handle = NULL */ 2290Sstevel@tonic-gate movl $0, OT_PAD1(%eax) /* ot_pad1 = NULL */ 2300Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx /* %edx = curthread */ 2310Sstevel@tonic-gate movl T_ONTRAP(%edx), %ecx /* %ecx = curthread->t_ontrap */ 2320Sstevel@tonic-gate cmpl %eax, %ecx /* if (otp == %ecx) */ 2330Sstevel@tonic-gate je 0f /* don't modify t_ontrap */ 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate movl %ecx, OT_PREV(%eax) /* ot_prev = t_ontrap */ 2360Sstevel@tonic-gate movl %eax, T_ONTRAP(%edx) /* curthread->t_ontrap = otp */ 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate0: addl $OT_JMPBUF, %eax /* %eax = &ot_jmpbuf */ 2390Sstevel@tonic-gate movl %eax, 4(%esp) /* put %eax back on the stack */ 2400Sstevel@tonic-gate jmp setjmp /* let setjmp do the rest */ 2410Sstevel@tonic-gate SET_SIZE(on_trap) 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate#endif /* __i386 */ 2440Sstevel@tonic-gate#endif /* __lint */ 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate/* 2470Sstevel@tonic-gate * Setjmp and longjmp implement non-local gotos using state vectors 2480Sstevel@tonic-gate * type label_t. 2490Sstevel@tonic-gate */ 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate#if defined(__lint) 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate/* ARGSUSED */ 2540Sstevel@tonic-gateint 2550Sstevel@tonic-gatesetjmp(label_t *lp) 2560Sstevel@tonic-gate{ return (0); } 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate/* ARGSUSED */ 2590Sstevel@tonic-gatevoid 2600Sstevel@tonic-gatelongjmp(label_t *lp) 2610Sstevel@tonic-gate{} 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate#else /* __lint */ 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate#if LABEL_PC != 0 2660Sstevel@tonic-gate#error LABEL_PC MUST be defined as 0 for setjmp/longjmp to work as coded 2670Sstevel@tonic-gate#endif /* LABEL_PC != 0 */ 2680Sstevel@tonic-gate 2690Sstevel@tonic-gate#if defined(__amd64) 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate ENTRY(setjmp) 2720Sstevel@tonic-gate movq %rsp, LABEL_SP(%rdi) 2730Sstevel@tonic-gate movq %rbp, LABEL_RBP(%rdi) 2740Sstevel@tonic-gate movq %rbx, LABEL_RBX(%rdi) 2750Sstevel@tonic-gate movq %r12, LABEL_R12(%rdi) 2760Sstevel@tonic-gate movq %r13, LABEL_R13(%rdi) 2770Sstevel@tonic-gate movq %r14, LABEL_R14(%rdi) 2780Sstevel@tonic-gate movq %r15, LABEL_R15(%rdi) 2790Sstevel@tonic-gate movq (%rsp), %rdx /* return address */ 2800Sstevel@tonic-gate movq %rdx, (%rdi) /* LABEL_PC is 0 */ 2810Sstevel@tonic-gate xorl %eax, %eax /* return 0 */ 2820Sstevel@tonic-gate ret 2830Sstevel@tonic-gate SET_SIZE(setjmp) 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate ENTRY(longjmp) 2860Sstevel@tonic-gate movq LABEL_SP(%rdi), %rsp 2870Sstevel@tonic-gate movq LABEL_RBP(%rdi), %rbp 2880Sstevel@tonic-gate movq LABEL_RBX(%rdi), %rbx 2890Sstevel@tonic-gate movq LABEL_R12(%rdi), %r12 2900Sstevel@tonic-gate movq LABEL_R13(%rdi), %r13 2910Sstevel@tonic-gate movq LABEL_R14(%rdi), %r14 2920Sstevel@tonic-gate movq LABEL_R15(%rdi), %r15 2930Sstevel@tonic-gate movq (%rdi), %rdx /* return address; LABEL_PC is 0 */ 2940Sstevel@tonic-gate movq %rdx, (%rsp) 2950Sstevel@tonic-gate xorl %eax, %eax 2960Sstevel@tonic-gate incl %eax /* return 1 */ 2970Sstevel@tonic-gate ret 2980Sstevel@tonic-gate SET_SIZE(longjmp) 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate#elif defined(__i386) 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate ENTRY(setjmp) 3030Sstevel@tonic-gate movl 4(%esp), %edx /* address of save area */ 3040Sstevel@tonic-gate movl %ebp, LABEL_EBP(%edx) 3050Sstevel@tonic-gate movl %ebx, LABEL_EBX(%edx) 3060Sstevel@tonic-gate movl %esi, LABEL_ESI(%edx) 3070Sstevel@tonic-gate movl %edi, LABEL_EDI(%edx) 3080Sstevel@tonic-gate movl %esp, 4(%edx) 3090Sstevel@tonic-gate movl (%esp), %ecx /* %eip (return address) */ 3100Sstevel@tonic-gate movl %ecx, (%edx) /* LABEL_PC is 0 */ 3110Sstevel@tonic-gate subl %eax, %eax /* return 0 */ 3120Sstevel@tonic-gate ret 3130Sstevel@tonic-gate SET_SIZE(setjmp) 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate ENTRY(longjmp) 3160Sstevel@tonic-gate movl 4(%esp), %edx /* address of save area */ 3170Sstevel@tonic-gate movl LABEL_EBP(%edx), %ebp 3180Sstevel@tonic-gate movl LABEL_EBX(%edx), %ebx 3190Sstevel@tonic-gate movl LABEL_ESI(%edx), %esi 3200Sstevel@tonic-gate movl LABEL_EDI(%edx), %edi 3210Sstevel@tonic-gate movl 4(%edx), %esp 3220Sstevel@tonic-gate movl (%edx), %ecx /* %eip (return addr); LABEL_PC is 0 */ 3230Sstevel@tonic-gate movl $1, %eax 3240Sstevel@tonic-gate addl $4, %esp /* pop ret adr */ 3250Sstevel@tonic-gate jmp *%ecx /* indirect */ 3260Sstevel@tonic-gate SET_SIZE(longjmp) 3270Sstevel@tonic-gate 3280Sstevel@tonic-gate#endif /* __i386 */ 3290Sstevel@tonic-gate#endif /* __lint */ 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate/* 3320Sstevel@tonic-gate * if a() calls b() calls caller(), 3330Sstevel@tonic-gate * caller() returns return address in a(). 3340Sstevel@tonic-gate * (Note: We assume a() and b() are C routines which do the normal entry/exit 3350Sstevel@tonic-gate * sequence.) 3360Sstevel@tonic-gate */ 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate#if defined(__lint) 3390Sstevel@tonic-gate 3400Sstevel@tonic-gatecaddr_t 3410Sstevel@tonic-gatecaller(void) 3420Sstevel@tonic-gate{ return (0); } 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate#else /* __lint */ 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate#if defined(__amd64) 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate ENTRY(caller) 3490Sstevel@tonic-gate movq 8(%rbp), %rax /* b()'s return pc, in a() */ 3500Sstevel@tonic-gate ret 3510Sstevel@tonic-gate SET_SIZE(caller) 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate#elif defined(__i386) 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate ENTRY(caller) 3560Sstevel@tonic-gate movl 4(%ebp), %eax /* b()'s return pc, in a() */ 3570Sstevel@tonic-gate ret 3580Sstevel@tonic-gate SET_SIZE(caller) 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate#endif /* __i386 */ 3610Sstevel@tonic-gate#endif /* __lint */ 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate/* 3640Sstevel@tonic-gate * if a() calls callee(), callee() returns the 3650Sstevel@tonic-gate * return address in a(); 3660Sstevel@tonic-gate */ 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate#if defined(__lint) 3690Sstevel@tonic-gate 3700Sstevel@tonic-gatecaddr_t 3710Sstevel@tonic-gatecallee(void) 3720Sstevel@tonic-gate{ return (0); } 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate#else /* __lint */ 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate#if defined(__amd64) 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate ENTRY(callee) 3790Sstevel@tonic-gate movq (%rsp), %rax /* callee()'s return pc, in a() */ 3800Sstevel@tonic-gate ret 3810Sstevel@tonic-gate SET_SIZE(callee) 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate#elif defined(__i386) 3840Sstevel@tonic-gate 3850Sstevel@tonic-gate ENTRY(callee) 3860Sstevel@tonic-gate movl (%esp), %eax /* callee()'s return pc, in a() */ 3870Sstevel@tonic-gate ret 3880Sstevel@tonic-gate SET_SIZE(callee) 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate#endif /* __i386 */ 3910Sstevel@tonic-gate#endif /* __lint */ 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate/* 3940Sstevel@tonic-gate * return the current frame pointer 3950Sstevel@tonic-gate */ 3960Sstevel@tonic-gate 3970Sstevel@tonic-gate#if defined(__lint) 3980Sstevel@tonic-gate 3990Sstevel@tonic-gategreg_t 4000Sstevel@tonic-gategetfp(void) 4010Sstevel@tonic-gate{ return (0); } 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate#else /* __lint */ 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate#if defined(__amd64) 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate ENTRY(getfp) 4080Sstevel@tonic-gate movq %rbp, %rax 4090Sstevel@tonic-gate ret 4100Sstevel@tonic-gate SET_SIZE(getfp) 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate#elif defined(__i386) 4130Sstevel@tonic-gate 4140Sstevel@tonic-gate ENTRY(getfp) 4150Sstevel@tonic-gate movl %ebp, %eax 4160Sstevel@tonic-gate ret 4170Sstevel@tonic-gate SET_SIZE(getfp) 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate#endif /* __i386 */ 4200Sstevel@tonic-gate#endif /* __lint */ 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate/* 4230Sstevel@tonic-gate * Invalidate a single page table entry in the TLB 4240Sstevel@tonic-gate */ 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate#if defined(__lint) 4270Sstevel@tonic-gate 4280Sstevel@tonic-gate/* ARGSUSED */ 4290Sstevel@tonic-gatevoid 4300Sstevel@tonic-gatemmu_tlbflush_entry(caddr_t m) 4310Sstevel@tonic-gate{} 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate#else /* __lint */ 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate#if defined(__amd64) 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate ENTRY(mmu_tlbflush_entry) 4380Sstevel@tonic-gate invlpg (%rdi) 4390Sstevel@tonic-gate ret 4400Sstevel@tonic-gate SET_SIZE(mmu_tlbflush_entry) 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate#elif defined(__i386) 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate ENTRY(mmu_tlbflush_entry) 4450Sstevel@tonic-gate movl 4(%esp), %eax 4460Sstevel@tonic-gate invlpg (%eax) 4470Sstevel@tonic-gate ret 4480Sstevel@tonic-gate SET_SIZE(mmu_tlbflush_entry) 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate#endif /* __i386 */ 4510Sstevel@tonic-gate#endif /* __lint */ 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate 4540Sstevel@tonic-gate/* 4550Sstevel@tonic-gate * Get/Set the value of various control registers 4560Sstevel@tonic-gate */ 4570Sstevel@tonic-gate 4580Sstevel@tonic-gate#if defined(__lint) 4590Sstevel@tonic-gate 4600Sstevel@tonic-gateulong_t 4610Sstevel@tonic-gategetcr0(void) 4620Sstevel@tonic-gate{ return (0); } 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate/* ARGSUSED */ 4650Sstevel@tonic-gatevoid 4660Sstevel@tonic-gatesetcr0(ulong_t value) 4670Sstevel@tonic-gate{} 4680Sstevel@tonic-gate 4690Sstevel@tonic-gateulong_t 4700Sstevel@tonic-gategetcr2(void) 4710Sstevel@tonic-gate{ return (0); } 4720Sstevel@tonic-gate 4730Sstevel@tonic-gateulong_t 4740Sstevel@tonic-gategetcr3(void) 4750Sstevel@tonic-gate{ return (0); } 4760Sstevel@tonic-gate 4775084Sjohnlev#if !defined(__xpv) 4780Sstevel@tonic-gate/* ARGSUSED */ 4790Sstevel@tonic-gatevoid 4800Sstevel@tonic-gatesetcr3(ulong_t val) 4810Sstevel@tonic-gate{} 4820Sstevel@tonic-gate 4830Sstevel@tonic-gatevoid 4840Sstevel@tonic-gatereload_cr3(void) 4850Sstevel@tonic-gate{} 4865084Sjohnlev#endif 4870Sstevel@tonic-gate 4880Sstevel@tonic-gateulong_t 4890Sstevel@tonic-gategetcr4(void) 4900Sstevel@tonic-gate{ return (0); } 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate/* ARGSUSED */ 4930Sstevel@tonic-gatevoid 4940Sstevel@tonic-gatesetcr4(ulong_t val) 4950Sstevel@tonic-gate{} 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate#if defined(__amd64) 4980Sstevel@tonic-gate 4990Sstevel@tonic-gateulong_t 5000Sstevel@tonic-gategetcr8(void) 5010Sstevel@tonic-gate{ return (0); } 5020Sstevel@tonic-gate 5030Sstevel@tonic-gate/* ARGSUSED */ 5040Sstevel@tonic-gatevoid 5050Sstevel@tonic-gatesetcr8(ulong_t val) 5060Sstevel@tonic-gate{} 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate#endif /* __amd64 */ 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate#else /* __lint */ 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate#if defined(__amd64) 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate ENTRY(getcr0) 5150Sstevel@tonic-gate movq %cr0, %rax 5160Sstevel@tonic-gate ret 5170Sstevel@tonic-gate SET_SIZE(getcr0) 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate ENTRY(setcr0) 5200Sstevel@tonic-gate movq %rdi, %cr0 5210Sstevel@tonic-gate ret 5220Sstevel@tonic-gate SET_SIZE(setcr0) 5230Sstevel@tonic-gate 5243446Smrj ENTRY(getcr2) 5255084Sjohnlev#if defined(__xpv) 5265084Sjohnlev movq %gs:CPU_VCPU_INFO, %rax 5275084Sjohnlev movq VCPU_INFO_ARCH_CR2(%rax), %rax 5285084Sjohnlev#else 5293446Smrj movq %cr2, %rax 5305084Sjohnlev#endif 5313446Smrj ret 5320Sstevel@tonic-gate SET_SIZE(getcr2) 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate ENTRY(getcr3) 5353446Smrj movq %cr3, %rax 5360Sstevel@tonic-gate ret 5370Sstevel@tonic-gate SET_SIZE(getcr3) 5380Sstevel@tonic-gate 5395084Sjohnlev#if !defined(__xpv) 5405084Sjohnlev 5413446Smrj ENTRY(setcr3) 5423446Smrj movq %rdi, %cr3 5433446Smrj ret 5440Sstevel@tonic-gate SET_SIZE(setcr3) 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate ENTRY(reload_cr3) 5470Sstevel@tonic-gate movq %cr3, %rdi 5480Sstevel@tonic-gate movq %rdi, %cr3 5490Sstevel@tonic-gate ret 5500Sstevel@tonic-gate SET_SIZE(reload_cr3) 5510Sstevel@tonic-gate 5525084Sjohnlev#endif /* __xpv */ 5535084Sjohnlev 5540Sstevel@tonic-gate ENTRY(getcr4) 5550Sstevel@tonic-gate movq %cr4, %rax 5560Sstevel@tonic-gate ret 5570Sstevel@tonic-gate SET_SIZE(getcr4) 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate ENTRY(setcr4) 5600Sstevel@tonic-gate movq %rdi, %cr4 5610Sstevel@tonic-gate ret 5620Sstevel@tonic-gate SET_SIZE(setcr4) 5630Sstevel@tonic-gate 5640Sstevel@tonic-gate ENTRY(getcr8) 5650Sstevel@tonic-gate movq %cr8, %rax 5660Sstevel@tonic-gate ret 5670Sstevel@tonic-gate SET_SIZE(getcr8) 5680Sstevel@tonic-gate 5690Sstevel@tonic-gate ENTRY(setcr8) 5700Sstevel@tonic-gate movq %rdi, %cr8 5710Sstevel@tonic-gate ret 5720Sstevel@tonic-gate SET_SIZE(setcr8) 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate#elif defined(__i386) 5750Sstevel@tonic-gate 5760Sstevel@tonic-gate ENTRY(getcr0) 5770Sstevel@tonic-gate movl %cr0, %eax 5780Sstevel@tonic-gate ret 5790Sstevel@tonic-gate SET_SIZE(getcr0) 5800Sstevel@tonic-gate 5810Sstevel@tonic-gate ENTRY(setcr0) 5820Sstevel@tonic-gate movl 4(%esp), %eax 5830Sstevel@tonic-gate movl %eax, %cr0 5840Sstevel@tonic-gate ret 5850Sstevel@tonic-gate SET_SIZE(setcr0) 5860Sstevel@tonic-gate 58710080SJoe.Bonasera@sun.com /* 58810080SJoe.Bonasera@sun.com * "lock mov %cr0" is used on processors which indicate it is 58910080SJoe.Bonasera@sun.com * supported via CPUID. Normally the 32 bit TPR is accessed via 59010080SJoe.Bonasera@sun.com * the local APIC. 59110080SJoe.Bonasera@sun.com */ 59210080SJoe.Bonasera@sun.com ENTRY(getcr8) 59310080SJoe.Bonasera@sun.com lock 59410080SJoe.Bonasera@sun.com movl %cr0, %eax 59510080SJoe.Bonasera@sun.com ret 59610080SJoe.Bonasera@sun.com SET_SIZE(getcr8) 59710080SJoe.Bonasera@sun.com 59810080SJoe.Bonasera@sun.com ENTRY(setcr8) 59910080SJoe.Bonasera@sun.com movl 4(%esp), %eax 60010080SJoe.Bonasera@sun.com lock 60110080SJoe.Bonasera@sun.com movl %eax, %cr0 60210080SJoe.Bonasera@sun.com ret 60310080SJoe.Bonasera@sun.com SET_SIZE(setcr8) 60410080SJoe.Bonasera@sun.com 6050Sstevel@tonic-gate ENTRY(getcr2) 6065084Sjohnlev#if defined(__xpv) 6075084Sjohnlev movl %gs:CPU_VCPU_INFO, %eax 6085084Sjohnlev movl VCPU_INFO_ARCH_CR2(%eax), %eax 6095084Sjohnlev#else 6100Sstevel@tonic-gate movl %cr2, %eax 6115084Sjohnlev#endif 6120Sstevel@tonic-gate ret 6130Sstevel@tonic-gate SET_SIZE(getcr2) 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate ENTRY(getcr3) 6160Sstevel@tonic-gate movl %cr3, %eax 6170Sstevel@tonic-gate ret 6180Sstevel@tonic-gate SET_SIZE(getcr3) 6190Sstevel@tonic-gate 6205084Sjohnlev#if !defined(__xpv) 6215084Sjohnlev 6220Sstevel@tonic-gate ENTRY(setcr3) 6230Sstevel@tonic-gate movl 4(%esp), %eax 6240Sstevel@tonic-gate movl %eax, %cr3 6250Sstevel@tonic-gate ret 6260Sstevel@tonic-gate SET_SIZE(setcr3) 6270Sstevel@tonic-gate 6280Sstevel@tonic-gate ENTRY(reload_cr3) 6290Sstevel@tonic-gate movl %cr3, %eax 6300Sstevel@tonic-gate movl %eax, %cr3 6310Sstevel@tonic-gate ret 6320Sstevel@tonic-gate SET_SIZE(reload_cr3) 6330Sstevel@tonic-gate 6345084Sjohnlev#endif /* __xpv */ 6355084Sjohnlev 6360Sstevel@tonic-gate ENTRY(getcr4) 6370Sstevel@tonic-gate movl %cr4, %eax 6380Sstevel@tonic-gate ret 6390Sstevel@tonic-gate SET_SIZE(getcr4) 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate ENTRY(setcr4) 6420Sstevel@tonic-gate movl 4(%esp), %eax 6430Sstevel@tonic-gate movl %eax, %cr4 6440Sstevel@tonic-gate ret 6450Sstevel@tonic-gate SET_SIZE(setcr4) 6460Sstevel@tonic-gate 6470Sstevel@tonic-gate#endif /* __i386 */ 6480Sstevel@tonic-gate#endif /* __lint */ 6490Sstevel@tonic-gate 6500Sstevel@tonic-gate#if defined(__lint) 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate/*ARGSUSED*/ 6530Sstevel@tonic-gateuint32_t 6541228Sandrei__cpuid_insn(struct cpuid_regs *regs) 6550Sstevel@tonic-gate{ return (0); } 6560Sstevel@tonic-gate 6570Sstevel@tonic-gate#else /* __lint */ 6580Sstevel@tonic-gate 6590Sstevel@tonic-gate#if defined(__amd64) 6600Sstevel@tonic-gate 6610Sstevel@tonic-gate ENTRY(__cpuid_insn) 6621228Sandrei movq %rbx, %r8 6631228Sandrei movq %rcx, %r9 6641228Sandrei movq %rdx, %r11 6651228Sandrei movl (%rdi), %eax /* %eax = regs->cp_eax */ 6661228Sandrei movl 0x4(%rdi), %ebx /* %ebx = regs->cp_ebx */ 6671228Sandrei movl 0x8(%rdi), %ecx /* %ecx = regs->cp_ecx */ 6681228Sandrei movl 0xc(%rdi), %edx /* %edx = regs->cp_edx */ 6690Sstevel@tonic-gate cpuid 6701228Sandrei movl %eax, (%rdi) /* regs->cp_eax = %eax */ 6711228Sandrei movl %ebx, 0x4(%rdi) /* regs->cp_ebx = %ebx */ 6721228Sandrei movl %ecx, 0x8(%rdi) /* regs->cp_ecx = %ecx */ 6731228Sandrei movl %edx, 0xc(%rdi) /* regs->cp_edx = %edx */ 6741228Sandrei movq %r8, %rbx 6751228Sandrei movq %r9, %rcx 6761228Sandrei movq %r11, %rdx 6770Sstevel@tonic-gate ret 6780Sstevel@tonic-gate SET_SIZE(__cpuid_insn) 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate#elif defined(__i386) 6810Sstevel@tonic-gate 6820Sstevel@tonic-gate ENTRY(__cpuid_insn) 6830Sstevel@tonic-gate pushl %ebp 6841228Sandrei movl 0x8(%esp), %ebp /* %ebp = regs */ 6850Sstevel@tonic-gate pushl %ebx 6861228Sandrei pushl %ecx 6871228Sandrei pushl %edx 6881228Sandrei movl (%ebp), %eax /* %eax = regs->cp_eax */ 6891228Sandrei movl 0x4(%ebp), %ebx /* %ebx = regs->cp_ebx */ 6901228Sandrei movl 0x8(%ebp), %ecx /* %ecx = regs->cp_ecx */ 6911228Sandrei movl 0xc(%ebp), %edx /* %edx = regs->cp_edx */ 6920Sstevel@tonic-gate cpuid 6931228Sandrei movl %eax, (%ebp) /* regs->cp_eax = %eax */ 6941228Sandrei movl %ebx, 0x4(%ebp) /* regs->cp_ebx = %ebx */ 6951228Sandrei movl %ecx, 0x8(%ebp) /* regs->cp_ecx = %ecx */ 6961228Sandrei movl %edx, 0xc(%ebp) /* regs->cp_edx = %edx */ 6971228Sandrei popl %edx 6981228Sandrei popl %ecx 6990Sstevel@tonic-gate popl %ebx 7000Sstevel@tonic-gate popl %ebp 7010Sstevel@tonic-gate ret 7020Sstevel@tonic-gate SET_SIZE(__cpuid_insn) 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate#endif /* __i386 */ 7050Sstevel@tonic-gate#endif /* __lint */ 7060Sstevel@tonic-gate 7074481Sbholler#if defined(__lint) 7084481Sbholler 7094481Sbholler/*ARGSUSED*/ 7104481Sbhollervoid 7114481Sbholleri86_monitor(volatile uint32_t *addr, uint32_t extensions, uint32_t hints) 7129489SJoe.Bonasera@sun.com{} 7134481Sbholler 7144481Sbholler#else /* __lint */ 7154481Sbholler 7164481Sbholler#if defined(__amd64) 7174481Sbholler 7184481Sbholler ENTRY_NP(i86_monitor) 7194481Sbholler pushq %rbp 7204481Sbholler movq %rsp, %rbp 7214481Sbholler movq %rdi, %rax /* addr */ 7224481Sbholler movq %rsi, %rcx /* extensions */ 7234481Sbholler /* rdx contains input arg3: hints */ 7247716SBill.Holler@Sun.COM clflush (%rax) 7254481Sbholler .byte 0x0f, 0x01, 0xc8 /* monitor */ 7264481Sbholler leave 7274481Sbholler ret 7284481Sbholler SET_SIZE(i86_monitor) 7294481Sbholler 7304481Sbholler#elif defined(__i386) 7314481Sbholler 7324481SbhollerENTRY_NP(i86_monitor) 7334481Sbholler pushl %ebp 7344481Sbholler movl %esp, %ebp 7354501Sbholler movl 0x8(%ebp),%eax /* addr */ 7364501Sbholler movl 0xc(%ebp),%ecx /* extensions */ 7374501Sbholler movl 0x10(%ebp),%edx /* hints */ 7387716SBill.Holler@Sun.COM clflush (%eax) 7394481Sbholler .byte 0x0f, 0x01, 0xc8 /* monitor */ 7404481Sbholler leave 7414481Sbholler ret 7424481Sbholler SET_SIZE(i86_monitor) 7434481Sbholler 7444481Sbholler#endif /* __i386 */ 7454481Sbholler#endif /* __lint */ 7464481Sbholler 7474481Sbholler#if defined(__lint) 7484481Sbholler 7494481Sbholler/*ARGSUSED*/ 7504481Sbhollervoid 7514481Sbholleri86_mwait(uint32_t data, uint32_t extensions) 7529489SJoe.Bonasera@sun.com{} 7534481Sbholler 7544481Sbholler#else /* __lint */ 7554481Sbholler 7564481Sbholler#if defined(__amd64) 7574481Sbholler 7584481Sbholler ENTRY_NP(i86_mwait) 7594481Sbholler pushq %rbp 7604481Sbholler movq %rsp, %rbp 7614481Sbholler movq %rdi, %rax /* data */ 7624481Sbholler movq %rsi, %rcx /* extensions */ 7634481Sbholler .byte 0x0f, 0x01, 0xc9 /* mwait */ 7644481Sbholler leave 7654481Sbholler ret 7664481Sbholler SET_SIZE(i86_mwait) 7674481Sbholler 7684481Sbholler#elif defined(__i386) 7694481Sbholler 7704481Sbholler ENTRY_NP(i86_mwait) 7714481Sbholler pushl %ebp 7724481Sbholler movl %esp, %ebp 7734501Sbholler movl 0x8(%ebp),%eax /* data */ 7744501Sbholler movl 0xc(%ebp),%ecx /* extensions */ 7754481Sbholler .byte 0x0f, 0x01, 0xc9 /* mwait */ 7764481Sbholler leave 7774481Sbholler ret 7784481Sbholler SET_SIZE(i86_mwait) 7794481Sbholler 7804481Sbholler#endif /* __i386 */ 7814481Sbholler#endif /* __lint */ 7823446Smrj 7839489SJoe.Bonasera@sun.com#if defined(__xpv) 7849489SJoe.Bonasera@sun.com /* 7859489SJoe.Bonasera@sun.com * Defined in C 7869489SJoe.Bonasera@sun.com */ 7879489SJoe.Bonasera@sun.com#else 7889489SJoe.Bonasera@sun.com 7893446Smrj#if defined(__lint) 7903446Smrj 7913446Smrjhrtime_t 7923446Smrjtsc_read(void) 7933446Smrj{ 7943446Smrj return (0); 7953446Smrj} 7963446Smrj 7973446Smrj#else /* __lint */ 7983446Smrj 7995084Sjohnlev#if defined(__amd64) 8005084Sjohnlev 8013446Smrj ENTRY_NP(tsc_read) 8025322Ssudheer movq %rbx, %r11 8035322Ssudheer movl $0, %eax 8045322Ssudheer cpuid 8055322Ssudheer rdtsc 8065322Ssudheer movq %r11, %rbx 8075322Ssudheer shlq $32, %rdx 8085322Ssudheer orq %rdx, %rax 8095322Ssudheer ret 8105322Ssudheer .globl _tsc_mfence_start 8115322Ssudheer_tsc_mfence_start: 8125322Ssudheer mfence 8133446Smrj rdtsc 8143446Smrj shlq $32, %rdx 8153446Smrj orq %rdx, %rax 8163446Smrj ret 8175322Ssudheer .globl _tsc_mfence_end 8185322Ssudheer_tsc_mfence_end: 8195322Ssudheer .globl _tscp_start 8205322Ssudheer_tscp_start: 8215322Ssudheer .byte 0x0f, 0x01, 0xf9 /* rdtscp instruction */ 8225322Ssudheer shlq $32, %rdx 8235322Ssudheer orq %rdx, %rax 8245322Ssudheer ret 8255322Ssudheer .globl _tscp_end 8265322Ssudheer_tscp_end: 8275322Ssudheer .globl _no_rdtsc_start 8285322Ssudheer_no_rdtsc_start: 8295322Ssudheer xorl %edx, %edx 8305322Ssudheer xorl %eax, %eax 8315322Ssudheer ret 8325322Ssudheer .globl _no_rdtsc_end 8335322Ssudheer_no_rdtsc_end: 8346642Ssudheer .globl _tsc_lfence_start 8356642Ssudheer_tsc_lfence_start: 8366642Ssudheer lfence 8376642Ssudheer rdtsc 8386642Ssudheer shlq $32, %rdx 8396642Ssudheer orq %rdx, %rax 8406642Ssudheer ret 8416642Ssudheer .globl _tsc_lfence_end 8426642Ssudheer_tsc_lfence_end: 8433446Smrj SET_SIZE(tsc_read) 8443446Smrj 8455322Ssudheer#else /* __i386 */ 8465084Sjohnlev 8475084Sjohnlev ENTRY_NP(tsc_read) 8485322Ssudheer pushl %ebx 8495322Ssudheer movl $0, %eax 8505322Ssudheer cpuid 8515322Ssudheer rdtsc 8525322Ssudheer popl %ebx 8535322Ssudheer ret 8545322Ssudheer .globl _tsc_mfence_start 8555322Ssudheer_tsc_mfence_start: 8565322Ssudheer mfence 8575322Ssudheer rdtsc 8585322Ssudheer ret 8595322Ssudheer .globl _tsc_mfence_end 8605322Ssudheer_tsc_mfence_end: 8615322Ssudheer .globl _tscp_start 8625322Ssudheer_tscp_start: 8635322Ssudheer .byte 0x0f, 0x01, 0xf9 /* rdtscp instruction */ 8645322Ssudheer ret 8655322Ssudheer .globl _tscp_end 8665322Ssudheer_tscp_end: 8675322Ssudheer .globl _no_rdtsc_start 8685322Ssudheer_no_rdtsc_start: 8695084Sjohnlev xorl %edx, %edx 8705322Ssudheer xorl %eax, %eax 8715084Sjohnlev ret 8725322Ssudheer .globl _no_rdtsc_end 8735322Ssudheer_no_rdtsc_end: 8746642Ssudheer .globl _tsc_lfence_start 8756642Ssudheer_tsc_lfence_start: 8766642Ssudheer lfence 8776642Ssudheer rdtsc 8786642Ssudheer ret 8796642Ssudheer .globl _tsc_lfence_end 8806642Ssudheer_tsc_lfence_end: 8815084Sjohnlev SET_SIZE(tsc_read) 8825084Sjohnlev 8835322Ssudheer#endif /* __i386 */ 8845084Sjohnlev 8853446Smrj#endif /* __lint */ 8863446Smrj 8876880Sdv142724 8885084Sjohnlev#endif /* __xpv */ 8895084Sjohnlev 8906880Sdv142724#ifdef __lint 8916880Sdv142724/* 8926880Sdv142724 * Do not use this function for obtaining clock tick. This 8936880Sdv142724 * is called by callers who do not need to have a guarenteed 8946880Sdv142724 * correct tick value. The proper routine to use is tsc_read(). 8956880Sdv142724 */ 89612908SPavel.Tatashin@Sun.COMu_longlong_t 8976880Sdv142724randtick(void) 8986880Sdv142724{ 8996880Sdv142724 return (0); 9006880Sdv142724} 9016880Sdv142724#else 9026880Sdv142724#if defined(__amd64) 9036880Sdv142724 ENTRY_NP(randtick) 9046880Sdv142724 rdtsc 9056880Sdv142724 shlq $32, %rdx 9066880Sdv142724 orq %rdx, %rax 9076880Sdv142724 ret 9086880Sdv142724 SET_SIZE(randtick) 9096880Sdv142724#else 9106880Sdv142724 ENTRY_NP(randtick) 9116880Sdv142724 rdtsc 9126880Sdv142724 ret 9136880Sdv142724 SET_SIZE(randtick) 9146880Sdv142724#endif /* __i386 */ 9156880Sdv142724#endif /* __lint */ 9160Sstevel@tonic-gate/* 9170Sstevel@tonic-gate * Insert entryp after predp in a doubly linked list. 9180Sstevel@tonic-gate */ 9190Sstevel@tonic-gate 9200Sstevel@tonic-gate#if defined(__lint) 9210Sstevel@tonic-gate 9220Sstevel@tonic-gate/*ARGSUSED*/ 9230Sstevel@tonic-gatevoid 9240Sstevel@tonic-gate_insque(caddr_t entryp, caddr_t predp) 9250Sstevel@tonic-gate{} 9260Sstevel@tonic-gate 9270Sstevel@tonic-gate#else /* __lint */ 9280Sstevel@tonic-gate 9290Sstevel@tonic-gate#if defined(__amd64) 9300Sstevel@tonic-gate 9310Sstevel@tonic-gate ENTRY(_insque) 9327421SDaniel.Anderson@Sun.COM movq (%rsi), %rax /* predp->forw */ 9330Sstevel@tonic-gate movq %rsi, CPTRSIZE(%rdi) /* entryp->back = predp */ 9340Sstevel@tonic-gate movq %rax, (%rdi) /* entryp->forw = predp->forw */ 9350Sstevel@tonic-gate movq %rdi, (%rsi) /* predp->forw = entryp */ 9360Sstevel@tonic-gate movq %rdi, CPTRSIZE(%rax) /* predp->forw->back = entryp */ 9370Sstevel@tonic-gate ret 9380Sstevel@tonic-gate SET_SIZE(_insque) 9390Sstevel@tonic-gate 9400Sstevel@tonic-gate#elif defined(__i386) 9410Sstevel@tonic-gate 9420Sstevel@tonic-gate ENTRY(_insque) 9430Sstevel@tonic-gate movl 8(%esp), %edx 9440Sstevel@tonic-gate movl 4(%esp), %ecx 9450Sstevel@tonic-gate movl (%edx), %eax /* predp->forw */ 9460Sstevel@tonic-gate movl %edx, CPTRSIZE(%ecx) /* entryp->back = predp */ 9470Sstevel@tonic-gate movl %eax, (%ecx) /* entryp->forw = predp->forw */ 9480Sstevel@tonic-gate movl %ecx, (%edx) /* predp->forw = entryp */ 9490Sstevel@tonic-gate movl %ecx, CPTRSIZE(%eax) /* predp->forw->back = entryp */ 9500Sstevel@tonic-gate ret 9510Sstevel@tonic-gate SET_SIZE(_insque) 9520Sstevel@tonic-gate 9530Sstevel@tonic-gate#endif /* __i386 */ 9540Sstevel@tonic-gate#endif /* __lint */ 9550Sstevel@tonic-gate 9560Sstevel@tonic-gate/* 9570Sstevel@tonic-gate * Remove entryp from a doubly linked list 9580Sstevel@tonic-gate */ 9590Sstevel@tonic-gate 9600Sstevel@tonic-gate#if defined(__lint) 9610Sstevel@tonic-gate 9620Sstevel@tonic-gate/*ARGSUSED*/ 9630Sstevel@tonic-gatevoid 9640Sstevel@tonic-gate_remque(caddr_t entryp) 9650Sstevel@tonic-gate{} 9660Sstevel@tonic-gate 9670Sstevel@tonic-gate#else /* __lint */ 9680Sstevel@tonic-gate 9690Sstevel@tonic-gate#if defined(__amd64) 9700Sstevel@tonic-gate 9710Sstevel@tonic-gate ENTRY(_remque) 9720Sstevel@tonic-gate movq (%rdi), %rax /* entry->forw */ 9730Sstevel@tonic-gate movq CPTRSIZE(%rdi), %rdx /* entry->back */ 9740Sstevel@tonic-gate movq %rax, (%rdx) /* entry->back->forw = entry->forw */ 9750Sstevel@tonic-gate movq %rdx, CPTRSIZE(%rax) /* entry->forw->back = entry->back */ 9760Sstevel@tonic-gate ret 9770Sstevel@tonic-gate SET_SIZE(_remque) 9780Sstevel@tonic-gate 9790Sstevel@tonic-gate#elif defined(__i386) 9800Sstevel@tonic-gate 9810Sstevel@tonic-gate ENTRY(_remque) 9820Sstevel@tonic-gate movl 4(%esp), %ecx 9830Sstevel@tonic-gate movl (%ecx), %eax /* entry->forw */ 9840Sstevel@tonic-gate movl CPTRSIZE(%ecx), %edx /* entry->back */ 9850Sstevel@tonic-gate movl %eax, (%edx) /* entry->back->forw = entry->forw */ 9860Sstevel@tonic-gate movl %edx, CPTRSIZE(%eax) /* entry->forw->back = entry->back */ 9870Sstevel@tonic-gate ret 9880Sstevel@tonic-gate SET_SIZE(_remque) 9890Sstevel@tonic-gate 9900Sstevel@tonic-gate#endif /* __i386 */ 9910Sstevel@tonic-gate#endif /* __lint */ 9920Sstevel@tonic-gate 9930Sstevel@tonic-gate/* 9940Sstevel@tonic-gate * Returns the number of 9950Sstevel@tonic-gate * non-NULL bytes in string argument. 9960Sstevel@tonic-gate */ 9970Sstevel@tonic-gate 9980Sstevel@tonic-gate#if defined(__lint) 9990Sstevel@tonic-gate 10000Sstevel@tonic-gate/* ARGSUSED */ 10010Sstevel@tonic-gatesize_t 10020Sstevel@tonic-gatestrlen(const char *str) 10030Sstevel@tonic-gate{ return (0); } 10040Sstevel@tonic-gate 10050Sstevel@tonic-gate#else /* __lint */ 10060Sstevel@tonic-gate 10070Sstevel@tonic-gate#if defined(__amd64) 10080Sstevel@tonic-gate 10090Sstevel@tonic-gate/* 10100Sstevel@tonic-gate * This is close to a simple transliteration of a C version of this 10110Sstevel@tonic-gate * routine. We should either just -make- this be a C version, or 10120Sstevel@tonic-gate * justify having it in assembler by making it significantly faster. 10130Sstevel@tonic-gate * 10140Sstevel@tonic-gate * size_t 10150Sstevel@tonic-gate * strlen(const char *s) 10160Sstevel@tonic-gate * { 10170Sstevel@tonic-gate * const char *s0; 10180Sstevel@tonic-gate * #if defined(DEBUG) 10190Sstevel@tonic-gate * if ((uintptr_t)s < KERNELBASE) 10200Sstevel@tonic-gate * panic(.str_panic_msg); 10210Sstevel@tonic-gate * #endif 10220Sstevel@tonic-gate * for (s0 = s; *s; s++) 10230Sstevel@tonic-gate * ; 10240Sstevel@tonic-gate * return (s - s0); 10250Sstevel@tonic-gate * } 10260Sstevel@tonic-gate */ 10270Sstevel@tonic-gate 10280Sstevel@tonic-gate ENTRY(strlen) 10290Sstevel@tonic-gate#ifdef DEBUG 10303446Smrj movq postbootkernelbase(%rip), %rax 10310Sstevel@tonic-gate cmpq %rax, %rdi 10320Sstevel@tonic-gate jae str_valid 10330Sstevel@tonic-gate pushq %rbp 10340Sstevel@tonic-gate movq %rsp, %rbp 10350Sstevel@tonic-gate leaq .str_panic_msg(%rip), %rdi 10360Sstevel@tonic-gate xorl %eax, %eax 10370Sstevel@tonic-gate call panic 10380Sstevel@tonic-gate#endif /* DEBUG */ 10390Sstevel@tonic-gatestr_valid: 10400Sstevel@tonic-gate cmpb $0, (%rdi) 10410Sstevel@tonic-gate movq %rdi, %rax 10420Sstevel@tonic-gate je .null_found 10430Sstevel@tonic-gate .align 4 10440Sstevel@tonic-gate.strlen_loop: 10450Sstevel@tonic-gate incq %rdi 10460Sstevel@tonic-gate cmpb $0, (%rdi) 10470Sstevel@tonic-gate jne .strlen_loop 10480Sstevel@tonic-gate.null_found: 10490Sstevel@tonic-gate subq %rax, %rdi 10500Sstevel@tonic-gate movq %rdi, %rax 10510Sstevel@tonic-gate ret 10520Sstevel@tonic-gate SET_SIZE(strlen) 10530Sstevel@tonic-gate 10540Sstevel@tonic-gate#elif defined(__i386) 10550Sstevel@tonic-gate 10560Sstevel@tonic-gate ENTRY(strlen) 10570Sstevel@tonic-gate#ifdef DEBUG 10583446Smrj movl postbootkernelbase, %eax 10590Sstevel@tonic-gate cmpl %eax, 4(%esp) 10600Sstevel@tonic-gate jae str_valid 10610Sstevel@tonic-gate pushl %ebp 10620Sstevel@tonic-gate movl %esp, %ebp 10630Sstevel@tonic-gate pushl $.str_panic_msg 10640Sstevel@tonic-gate call panic 10650Sstevel@tonic-gate#endif /* DEBUG */ 10660Sstevel@tonic-gate 10670Sstevel@tonic-gatestr_valid: 10680Sstevel@tonic-gate movl 4(%esp), %eax /* %eax = string address */ 10690Sstevel@tonic-gate testl $3, %eax /* if %eax not word aligned */ 10700Sstevel@tonic-gate jnz .not_word_aligned /* goto .not_word_aligned */ 10710Sstevel@tonic-gate .align 4 10720Sstevel@tonic-gate.word_aligned: 10730Sstevel@tonic-gate movl (%eax), %edx /* move 1 word from (%eax) to %edx */ 10740Sstevel@tonic-gate movl $0x7f7f7f7f, %ecx 10750Sstevel@tonic-gate andl %edx, %ecx /* %ecx = %edx & 0x7f7f7f7f */ 10760Sstevel@tonic-gate addl $4, %eax /* next word */ 10770Sstevel@tonic-gate addl $0x7f7f7f7f, %ecx /* %ecx += 0x7f7f7f7f */ 10780Sstevel@tonic-gate orl %edx, %ecx /* %ecx |= %edx */ 10790Sstevel@tonic-gate andl $0x80808080, %ecx /* %ecx &= 0x80808080 */ 10800Sstevel@tonic-gate cmpl $0x80808080, %ecx /* if no null byte in this word */ 10810Sstevel@tonic-gate je .word_aligned /* goto .word_aligned */ 10820Sstevel@tonic-gate subl $4, %eax /* post-incremented */ 10830Sstevel@tonic-gate.not_word_aligned: 10840Sstevel@tonic-gate cmpb $0, (%eax) /* if a byte in (%eax) is null */ 10850Sstevel@tonic-gate je .null_found /* goto .null_found */ 10860Sstevel@tonic-gate incl %eax /* next byte */ 10870Sstevel@tonic-gate testl $3, %eax /* if %eax not word aligned */ 10880Sstevel@tonic-gate jnz .not_word_aligned /* goto .not_word_aligned */ 10890Sstevel@tonic-gate jmp .word_aligned /* goto .word_aligned */ 10900Sstevel@tonic-gate .align 4 10910Sstevel@tonic-gate.null_found: 10920Sstevel@tonic-gate subl 4(%esp), %eax /* %eax -= string address */ 10930Sstevel@tonic-gate ret 10940Sstevel@tonic-gate SET_SIZE(strlen) 10950Sstevel@tonic-gate 10960Sstevel@tonic-gate#endif /* __i386 */ 10970Sstevel@tonic-gate 10980Sstevel@tonic-gate#ifdef DEBUG 10990Sstevel@tonic-gate .text 11000Sstevel@tonic-gate.str_panic_msg: 11010Sstevel@tonic-gate .string "strlen: argument below kernelbase" 11020Sstevel@tonic-gate#endif /* DEBUG */ 11030Sstevel@tonic-gate 11040Sstevel@tonic-gate#endif /* __lint */ 11050Sstevel@tonic-gate 11060Sstevel@tonic-gate /* 11077421SDaniel.Anderson@Sun.COM * Berkeley 4.3 introduced symbolically named interrupt levels 11080Sstevel@tonic-gate * as a way deal with priority in a machine independent fashion. 11090Sstevel@tonic-gate * Numbered priorities are machine specific, and should be 11100Sstevel@tonic-gate * discouraged where possible. 11110Sstevel@tonic-gate * 11120Sstevel@tonic-gate * Note, for the machine specific priorities there are 11130Sstevel@tonic-gate * examples listed for devices that use a particular priority. 11140Sstevel@tonic-gate * It should not be construed that all devices of that 11150Sstevel@tonic-gate * type should be at that priority. It is currently were 11160Sstevel@tonic-gate * the current devices fit into the priority scheme based 11170Sstevel@tonic-gate * upon time criticalness. 11180Sstevel@tonic-gate * 11190Sstevel@tonic-gate * The underlying assumption of these assignments is that 11200Sstevel@tonic-gate * IPL 10 is the highest level from which a device 11210Sstevel@tonic-gate * routine can call wakeup. Devices that interrupt from higher 11220Sstevel@tonic-gate * levels are restricted in what they can do. If they need 11230Sstevel@tonic-gate * kernels services they should schedule a routine at a lower 11240Sstevel@tonic-gate * level (via software interrupt) to do the required 11250Sstevel@tonic-gate * processing. 11260Sstevel@tonic-gate * 11270Sstevel@tonic-gate * Examples of this higher usage: 11280Sstevel@tonic-gate * Level Usage 11290Sstevel@tonic-gate * 14 Profiling clock (and PROM uart polling clock) 11300Sstevel@tonic-gate * 12 Serial ports 11310Sstevel@tonic-gate * 11320Sstevel@tonic-gate * The serial ports request lower level processing on level 6. 11330Sstevel@tonic-gate * 11340Sstevel@tonic-gate * Also, almost all splN routines (where N is a number or a 11350Sstevel@tonic-gate * mnemonic) will do a RAISE(), on the assumption that they are 11360Sstevel@tonic-gate * never used to lower our priority. 11370Sstevel@tonic-gate * The exceptions are: 11380Sstevel@tonic-gate * spl8() Because you can't be above 15 to begin with! 11390Sstevel@tonic-gate * splzs() Because this is used at boot time to lower our 11400Sstevel@tonic-gate * priority, to allow the PROM to poll the uart. 11410Sstevel@tonic-gate * spl0() Used to lower priority to 0. 11420Sstevel@tonic-gate */ 11430Sstevel@tonic-gate 11440Sstevel@tonic-gate#if defined(__lint) 11450Sstevel@tonic-gate 11460Sstevel@tonic-gateint spl0(void) { return (0); } 11470Sstevel@tonic-gateint spl6(void) { return (0); } 11480Sstevel@tonic-gateint spl7(void) { return (0); } 11490Sstevel@tonic-gateint spl8(void) { return (0); } 11500Sstevel@tonic-gateint splhigh(void) { return (0); } 11510Sstevel@tonic-gateint splhi(void) { return (0); } 11520Sstevel@tonic-gateint splzs(void) { return (0); } 11530Sstevel@tonic-gate 11543446Smrj/* ARGSUSED */ 11553446Smrjvoid 11563446Smrjsplx(int level) 11573446Smrj{} 11583446Smrj 11590Sstevel@tonic-gate#else /* __lint */ 11600Sstevel@tonic-gate 11610Sstevel@tonic-gate#if defined(__amd64) 11620Sstevel@tonic-gate 11630Sstevel@tonic-gate#define SETPRI(level) \ 11643446Smrj movl $/**/level, %edi; /* new priority */ \ 11653446Smrj jmp do_splx /* redirect to do_splx */ 11663446Smrj 11673446Smrj#define RAISE(level) \ 11683446Smrj movl $/**/level, %edi; /* new priority */ \ 11693446Smrj jmp splr /* redirect to splr */ 11700Sstevel@tonic-gate 11710Sstevel@tonic-gate#elif defined(__i386) 11720Sstevel@tonic-gate 11733446Smrj#define SETPRI(level) \ 11743446Smrj pushl $/**/level; /* new priority */ \ 11753446Smrj call do_splx; /* invoke common splx code */ \ 11763446Smrj addl $4, %esp; /* unstack arg */ \ 11773446Smrj ret 11783446Smrj 11793446Smrj#define RAISE(level) \ 11803446Smrj pushl $/**/level; /* new priority */ \ 11813446Smrj call splr; /* invoke common splr code */ \ 11823446Smrj addl $4, %esp; /* unstack args */ \ 11833446Smrj ret 11840Sstevel@tonic-gate 11850Sstevel@tonic-gate#endif /* __i386 */ 11860Sstevel@tonic-gate 11870Sstevel@tonic-gate /* locks out all interrupts, including memory errors */ 11880Sstevel@tonic-gate ENTRY(spl8) 11890Sstevel@tonic-gate SETPRI(15) 11900Sstevel@tonic-gate SET_SIZE(spl8) 11910Sstevel@tonic-gate 11920Sstevel@tonic-gate /* just below the level that profiling runs */ 11930Sstevel@tonic-gate ENTRY(spl7) 11940Sstevel@tonic-gate RAISE(13) 11950Sstevel@tonic-gate SET_SIZE(spl7) 11960Sstevel@tonic-gate 11970Sstevel@tonic-gate /* sun specific - highest priority onboard serial i/o asy ports */ 11980Sstevel@tonic-gate ENTRY(splzs) 11990Sstevel@tonic-gate SETPRI(12) /* Can't be a RAISE, as it's used to lower us */ 12000Sstevel@tonic-gate SET_SIZE(splzs) 12010Sstevel@tonic-gate 12020Sstevel@tonic-gate ENTRY(splhi) 12030Sstevel@tonic-gate ALTENTRY(splhigh) 12040Sstevel@tonic-gate ALTENTRY(spl6) 12050Sstevel@tonic-gate ALTENTRY(i_ddi_splhigh) 12063446Smrj 12073446Smrj RAISE(DISP_LEVEL) 12080Sstevel@tonic-gate 12090Sstevel@tonic-gate SET_SIZE(i_ddi_splhigh) 12100Sstevel@tonic-gate SET_SIZE(spl6) 12110Sstevel@tonic-gate SET_SIZE(splhigh) 12120Sstevel@tonic-gate SET_SIZE(splhi) 12130Sstevel@tonic-gate 12140Sstevel@tonic-gate /* allow all interrupts */ 12150Sstevel@tonic-gate ENTRY(spl0) 12160Sstevel@tonic-gate SETPRI(0) 12170Sstevel@tonic-gate SET_SIZE(spl0) 12180Sstevel@tonic-gate 12193446Smrj 12207421SDaniel.Anderson@Sun.COM /* splx implementation */ 12210Sstevel@tonic-gate ENTRY(splx) 12223446Smrj jmp do_splx /* redirect to common splx code */ 12230Sstevel@tonic-gate SET_SIZE(splx) 12240Sstevel@tonic-gate 12250Sstevel@tonic-gate#endif /* __lint */ 12260Sstevel@tonic-gate 12270Sstevel@tonic-gate#if defined(__i386) 12280Sstevel@tonic-gate 12290Sstevel@tonic-gate/* 12300Sstevel@tonic-gate * Read and write the %gs register 12310Sstevel@tonic-gate */ 12320Sstevel@tonic-gate 12330Sstevel@tonic-gate#if defined(__lint) 12340Sstevel@tonic-gate 12350Sstevel@tonic-gate/*ARGSUSED*/ 12360Sstevel@tonic-gateuint16_t 12370Sstevel@tonic-gategetgs(void) 12380Sstevel@tonic-gate{ return (0); } 12390Sstevel@tonic-gate 12400Sstevel@tonic-gate/*ARGSUSED*/ 12410Sstevel@tonic-gatevoid 12420Sstevel@tonic-gatesetgs(uint16_t sel) 12430Sstevel@tonic-gate{} 12440Sstevel@tonic-gate 12450Sstevel@tonic-gate#else /* __lint */ 12460Sstevel@tonic-gate 12470Sstevel@tonic-gate ENTRY(getgs) 12480Sstevel@tonic-gate clr %eax 12490Sstevel@tonic-gate movw %gs, %ax 12500Sstevel@tonic-gate ret 12510Sstevel@tonic-gate SET_SIZE(getgs) 12520Sstevel@tonic-gate 12530Sstevel@tonic-gate ENTRY(setgs) 12540Sstevel@tonic-gate movw 4(%esp), %gs 12550Sstevel@tonic-gate ret 12560Sstevel@tonic-gate SET_SIZE(setgs) 12570Sstevel@tonic-gate 12580Sstevel@tonic-gate#endif /* __lint */ 12590Sstevel@tonic-gate#endif /* __i386 */ 12600Sstevel@tonic-gate 12610Sstevel@tonic-gate#if defined(__lint) 12620Sstevel@tonic-gate 12630Sstevel@tonic-gatevoid 12640Sstevel@tonic-gatepc_reset(void) 12650Sstevel@tonic-gate{} 12660Sstevel@tonic-gate 12672866Sszhouvoid 12682866Sszhouefi_reset(void) 12692866Sszhou{} 12702866Sszhou 12710Sstevel@tonic-gate#else /* __lint */ 12720Sstevel@tonic-gate 12731072Ssethg ENTRY(wait_500ms) 12749291SGeorge.Vasick@Sun.COM#if defined(__amd64) 12759291SGeorge.Vasick@Sun.COM pushq %rbx 12769291SGeorge.Vasick@Sun.COM#elif defined(__i386) 12771176Ssethg push %ebx 12789291SGeorge.Vasick@Sun.COM#endif 12791176Ssethg movl $50000, %ebx 12801072Ssethg1: 12811072Ssethg call tenmicrosec 12821176Ssethg decl %ebx 12831176Ssethg jnz 1b 12849291SGeorge.Vasick@Sun.COM#if defined(__amd64) 12859291SGeorge.Vasick@Sun.COM popq %rbx 12869291SGeorge.Vasick@Sun.COM#elif defined(__i386) 12871176Ssethg pop %ebx 12889291SGeorge.Vasick@Sun.COM#endif 12891072Ssethg ret 12901072Ssethg SET_SIZE(wait_500ms) 12911072Ssethg 12921072Ssethg#define RESET_METHOD_KBC 1 12931072Ssethg#define RESET_METHOD_PORT92 2 12941072Ssethg#define RESET_METHOD_PCI 4 12951072Ssethg 12961072Ssethg DGDEF3(pc_reset_methods, 4, 8) 12971072Ssethg .long RESET_METHOD_KBC|RESET_METHOD_PORT92|RESET_METHOD_PCI; 12981072Ssethg 12990Sstevel@tonic-gate ENTRY(pc_reset) 13001072Ssethg 13011176Ssethg#if defined(__i386) 13021072Ssethg testl $RESET_METHOD_KBC, pc_reset_methods 13031176Ssethg#elif defined(__amd64) 13041176Ssethg testl $RESET_METHOD_KBC, pc_reset_methods(%rip) 13051176Ssethg#endif 13061072Ssethg jz 1f 13071072Ssethg 1308886Ssethg / 1309886Ssethg / Try the classic keyboard controller-triggered reset. 1310886Ssethg / 13110Sstevel@tonic-gate movw $0x64, %dx 13120Sstevel@tonic-gate movb $0xfe, %al 13130Sstevel@tonic-gate outb (%dx) 1314886Ssethg 13151072Ssethg / Wait up to 500 milliseconds here for the keyboard controller 13161072Ssethg / to pull the reset line. On some systems where the keyboard 13171072Ssethg / controller is slow to pull the reset line, the next reset method 13181072Ssethg / may be executed (which may be bad if those systems hang when the 13191072Ssethg / next reset method is used, e.g. Ferrari 3400 (doesn't like port 92), 13201072Ssethg / and Ferrari 4000 (doesn't like the cf9 reset method)) 13211072Ssethg 13221072Ssethg call wait_500ms 13231072Ssethg 13241072Ssethg1: 13251176Ssethg#if defined(__i386) 13261072Ssethg testl $RESET_METHOD_PORT92, pc_reset_methods 13271176Ssethg#elif defined(__amd64) 13281176Ssethg testl $RESET_METHOD_PORT92, pc_reset_methods(%rip) 13291176Ssethg#endif 13301072Ssethg jz 3f 13311072Ssethg 1332886Ssethg / 1333886Ssethg / Try port 0x92 fast reset 1334886Ssethg / 1335886Ssethg movw $0x92, %dx 1336886Ssethg inb (%dx) 1337886Ssethg cmpb $0xff, %al / If port's not there, we should get back 0xFF 1338886Ssethg je 1f 1339886Ssethg testb $1, %al / If bit 0 1340886Ssethg jz 2f / is clear, jump to perform the reset 1341886Ssethg andb $0xfe, %al / otherwise, 1342886Ssethg outb (%dx) / clear bit 0 first, then 1343886Ssethg2: 1344886Ssethg orb $1, %al / Set bit 0 1345886Ssethg outb (%dx) / and reset the system 1346886Ssethg1: 1347985Ssethg 13481072Ssethg call wait_500ms 13491072Ssethg 13501072Ssethg3: 13511176Ssethg#if defined(__i386) 13521072Ssethg testl $RESET_METHOD_PCI, pc_reset_methods 13531176Ssethg#elif defined(__amd64) 13541176Ssethg testl $RESET_METHOD_PCI, pc_reset_methods(%rip) 13551176Ssethg#endif 13561072Ssethg jz 4f 13571072Ssethg 1358985Ssethg / Try the PCI (soft) reset vector (should work on all modern systems, 1359985Ssethg / but has been shown to cause problems on 450NX systems, and some newer 1360985Ssethg / systems (e.g. ATI IXP400-equipped systems)) 1361985Ssethg / When resetting via this method, 2 writes are required. The first 1362985Ssethg / targets bit 1 (0=hard reset without power cycle, 1=hard reset with 1363985Ssethg / power cycle). 1364985Ssethg / The reset occurs on the second write, during bit 2's transition from 1365985Ssethg / 0->1. 1366985Ssethg movw $0xcf9, %dx 1367985Ssethg movb $0x2, %al / Reset mode = hard, no power cycle 1368985Ssethg outb (%dx) 1369985Ssethg movb $0x6, %al 1370985Ssethg outb (%dx) 1371985Ssethg 13721072Ssethg call wait_500ms 13731072Ssethg 13741072Ssethg4: 1375886Ssethg / 1376985Ssethg / port 0xcf9 failed also. Last-ditch effort is to 1377886Ssethg / triple-fault the CPU. 13782866Sszhou / Also, use triple fault for EFI firmware 1379886Ssethg / 13802866Sszhou ENTRY(efi_reset) 1381886Ssethg#if defined(__amd64) 1382886Ssethg pushq $0x0 1383886Ssethg pushq $0x0 / IDT base of 0, limit of 0 + 2 unused bytes 1384886Ssethg lidt (%rsp) 1385886Ssethg#elif defined(__i386) 1386886Ssethg pushl $0x0 1387886Ssethg pushl $0x0 / IDT base of 0, limit of 0 + 2 unused bytes 1388886Ssethg lidt (%esp) 1389886Ssethg#endif 1390886Ssethg int $0x0 / Trigger interrupt, generate triple-fault 13911072Ssethg 13921072Ssethg cli 13931072Ssethg hlt / Wait forever 13940Sstevel@tonic-gate /*NOTREACHED*/ 13952866Sszhou SET_SIZE(efi_reset) 13960Sstevel@tonic-gate SET_SIZE(pc_reset) 13970Sstevel@tonic-gate 13980Sstevel@tonic-gate#endif /* __lint */ 13990Sstevel@tonic-gate 14000Sstevel@tonic-gate/* 14010Sstevel@tonic-gate * C callable in and out routines 14020Sstevel@tonic-gate */ 14030Sstevel@tonic-gate 14040Sstevel@tonic-gate#if defined(__lint) 14050Sstevel@tonic-gate 14060Sstevel@tonic-gate/* ARGSUSED */ 14070Sstevel@tonic-gatevoid 14080Sstevel@tonic-gateoutl(int port_address, uint32_t val) 14090Sstevel@tonic-gate{} 14100Sstevel@tonic-gate 14110Sstevel@tonic-gate#else /* __lint */ 14120Sstevel@tonic-gate 14130Sstevel@tonic-gate#if defined(__amd64) 14140Sstevel@tonic-gate 14150Sstevel@tonic-gate ENTRY(outl) 14160Sstevel@tonic-gate movw %di, %dx 14170Sstevel@tonic-gate movl %esi, %eax 14180Sstevel@tonic-gate outl (%dx) 14190Sstevel@tonic-gate ret 14200Sstevel@tonic-gate SET_SIZE(outl) 14210Sstevel@tonic-gate 14220Sstevel@tonic-gate#elif defined(__i386) 14230Sstevel@tonic-gate 14240Sstevel@tonic-gate .set PORT, 4 14250Sstevel@tonic-gate .set VAL, 8 14260Sstevel@tonic-gate 14270Sstevel@tonic-gate ENTRY(outl) 14280Sstevel@tonic-gate movw PORT(%esp), %dx 14290Sstevel@tonic-gate movl VAL(%esp), %eax 14300Sstevel@tonic-gate outl (%dx) 14310Sstevel@tonic-gate ret 14320Sstevel@tonic-gate SET_SIZE(outl) 14330Sstevel@tonic-gate 14340Sstevel@tonic-gate#endif /* __i386 */ 14350Sstevel@tonic-gate#endif /* __lint */ 14360Sstevel@tonic-gate 14370Sstevel@tonic-gate#if defined(__lint) 14380Sstevel@tonic-gate 14390Sstevel@tonic-gate/* ARGSUSED */ 14400Sstevel@tonic-gatevoid 14410Sstevel@tonic-gateoutw(int port_address, uint16_t val) 14420Sstevel@tonic-gate{} 14430Sstevel@tonic-gate 14440Sstevel@tonic-gate#else /* __lint */ 14450Sstevel@tonic-gate 14460Sstevel@tonic-gate#if defined(__amd64) 14470Sstevel@tonic-gate 14480Sstevel@tonic-gate ENTRY(outw) 14490Sstevel@tonic-gate movw %di, %dx 14500Sstevel@tonic-gate movw %si, %ax 14510Sstevel@tonic-gate D16 outl (%dx) /* XX64 why not outw? */ 14520Sstevel@tonic-gate ret 14530Sstevel@tonic-gate SET_SIZE(outw) 14540Sstevel@tonic-gate 14550Sstevel@tonic-gate#elif defined(__i386) 14560Sstevel@tonic-gate 14570Sstevel@tonic-gate ENTRY(outw) 14580Sstevel@tonic-gate movw PORT(%esp), %dx 14590Sstevel@tonic-gate movw VAL(%esp), %ax 14600Sstevel@tonic-gate D16 outl (%dx) 14610Sstevel@tonic-gate ret 14620Sstevel@tonic-gate SET_SIZE(outw) 14630Sstevel@tonic-gate 14640Sstevel@tonic-gate#endif /* __i386 */ 14650Sstevel@tonic-gate#endif /* __lint */ 14660Sstevel@tonic-gate 14670Sstevel@tonic-gate#if defined(__lint) 14680Sstevel@tonic-gate 14690Sstevel@tonic-gate/* ARGSUSED */ 14700Sstevel@tonic-gatevoid 14710Sstevel@tonic-gateoutb(int port_address, uint8_t val) 14720Sstevel@tonic-gate{} 14730Sstevel@tonic-gate 14740Sstevel@tonic-gate#else /* __lint */ 14750Sstevel@tonic-gate 14760Sstevel@tonic-gate#if defined(__amd64) 14770Sstevel@tonic-gate 14780Sstevel@tonic-gate ENTRY(outb) 14790Sstevel@tonic-gate movw %di, %dx 14800Sstevel@tonic-gate movb %sil, %al 14810Sstevel@tonic-gate outb (%dx) 14820Sstevel@tonic-gate ret 14830Sstevel@tonic-gate SET_SIZE(outb) 14840Sstevel@tonic-gate 14850Sstevel@tonic-gate#elif defined(__i386) 14860Sstevel@tonic-gate 14870Sstevel@tonic-gate ENTRY(outb) 14880Sstevel@tonic-gate movw PORT(%esp), %dx 14890Sstevel@tonic-gate movb VAL(%esp), %al 14900Sstevel@tonic-gate outb (%dx) 14910Sstevel@tonic-gate ret 14920Sstevel@tonic-gate SET_SIZE(outb) 14930Sstevel@tonic-gate 14940Sstevel@tonic-gate#endif /* __i386 */ 14950Sstevel@tonic-gate#endif /* __lint */ 14960Sstevel@tonic-gate 14970Sstevel@tonic-gate#if defined(__lint) 14980Sstevel@tonic-gate 14990Sstevel@tonic-gate/* ARGSUSED */ 15000Sstevel@tonic-gateuint32_t 15010Sstevel@tonic-gateinl(int port_address) 15020Sstevel@tonic-gate{ return (0); } 15030Sstevel@tonic-gate 15040Sstevel@tonic-gate#else /* __lint */ 15050Sstevel@tonic-gate 15060Sstevel@tonic-gate#if defined(__amd64) 15070Sstevel@tonic-gate 15080Sstevel@tonic-gate ENTRY(inl) 15090Sstevel@tonic-gate xorl %eax, %eax 15100Sstevel@tonic-gate movw %di, %dx 15110Sstevel@tonic-gate inl (%dx) 15120Sstevel@tonic-gate ret 15130Sstevel@tonic-gate SET_SIZE(inl) 15140Sstevel@tonic-gate 15150Sstevel@tonic-gate#elif defined(__i386) 15160Sstevel@tonic-gate 15170Sstevel@tonic-gate ENTRY(inl) 15180Sstevel@tonic-gate movw PORT(%esp), %dx 15190Sstevel@tonic-gate inl (%dx) 15200Sstevel@tonic-gate ret 15210Sstevel@tonic-gate SET_SIZE(inl) 15220Sstevel@tonic-gate 15230Sstevel@tonic-gate#endif /* __i386 */ 15240Sstevel@tonic-gate#endif /* __lint */ 15250Sstevel@tonic-gate 15260Sstevel@tonic-gate#if defined(__lint) 15270Sstevel@tonic-gate 15280Sstevel@tonic-gate/* ARGSUSED */ 15290Sstevel@tonic-gateuint16_t 15300Sstevel@tonic-gateinw(int port_address) 15310Sstevel@tonic-gate{ return (0); } 15320Sstevel@tonic-gate 15330Sstevel@tonic-gate#else /* __lint */ 15340Sstevel@tonic-gate 15350Sstevel@tonic-gate#if defined(__amd64) 15360Sstevel@tonic-gate 15370Sstevel@tonic-gate ENTRY(inw) 15380Sstevel@tonic-gate xorl %eax, %eax 15390Sstevel@tonic-gate movw %di, %dx 15400Sstevel@tonic-gate D16 inl (%dx) 15410Sstevel@tonic-gate ret 15420Sstevel@tonic-gate SET_SIZE(inw) 15430Sstevel@tonic-gate 15440Sstevel@tonic-gate#elif defined(__i386) 15450Sstevel@tonic-gate 15460Sstevel@tonic-gate ENTRY(inw) 15470Sstevel@tonic-gate subl %eax, %eax 15480Sstevel@tonic-gate movw PORT(%esp), %dx 15490Sstevel@tonic-gate D16 inl (%dx) 15500Sstevel@tonic-gate ret 15510Sstevel@tonic-gate SET_SIZE(inw) 15520Sstevel@tonic-gate 15530Sstevel@tonic-gate#endif /* __i386 */ 15540Sstevel@tonic-gate#endif /* __lint */ 15550Sstevel@tonic-gate 15560Sstevel@tonic-gate 15570Sstevel@tonic-gate#if defined(__lint) 15580Sstevel@tonic-gate 15590Sstevel@tonic-gate/* ARGSUSED */ 15600Sstevel@tonic-gateuint8_t 15610Sstevel@tonic-gateinb(int port_address) 15620Sstevel@tonic-gate{ return (0); } 15630Sstevel@tonic-gate 15640Sstevel@tonic-gate#else /* __lint */ 15650Sstevel@tonic-gate 15660Sstevel@tonic-gate#if defined(__amd64) 15670Sstevel@tonic-gate 15680Sstevel@tonic-gate ENTRY(inb) 15690Sstevel@tonic-gate xorl %eax, %eax 15700Sstevel@tonic-gate movw %di, %dx 15710Sstevel@tonic-gate inb (%dx) 15720Sstevel@tonic-gate ret 15730Sstevel@tonic-gate SET_SIZE(inb) 15740Sstevel@tonic-gate 15750Sstevel@tonic-gate#elif defined(__i386) 15760Sstevel@tonic-gate 15770Sstevel@tonic-gate ENTRY(inb) 15780Sstevel@tonic-gate subl %eax, %eax 15790Sstevel@tonic-gate movw PORT(%esp), %dx 15800Sstevel@tonic-gate inb (%dx) 15810Sstevel@tonic-gate ret 15820Sstevel@tonic-gate SET_SIZE(inb) 15830Sstevel@tonic-gate 15840Sstevel@tonic-gate#endif /* __i386 */ 15850Sstevel@tonic-gate#endif /* __lint */ 15860Sstevel@tonic-gate 15870Sstevel@tonic-gate 15880Sstevel@tonic-gate#if defined(__lint) 15890Sstevel@tonic-gate 15900Sstevel@tonic-gate/* ARGSUSED */ 15910Sstevel@tonic-gatevoid 15920Sstevel@tonic-gaterepoutsw(int port, uint16_t *addr, int cnt) 15930Sstevel@tonic-gate{} 15940Sstevel@tonic-gate 15950Sstevel@tonic-gate#else /* __lint */ 15960Sstevel@tonic-gate 15970Sstevel@tonic-gate#if defined(__amd64) 15980Sstevel@tonic-gate 15990Sstevel@tonic-gate ENTRY(repoutsw) 16000Sstevel@tonic-gate movl %edx, %ecx 16010Sstevel@tonic-gate movw %di, %dx 16020Sstevel@tonic-gate rep 16030Sstevel@tonic-gate D16 outsl 16040Sstevel@tonic-gate ret 16050Sstevel@tonic-gate SET_SIZE(repoutsw) 16060Sstevel@tonic-gate 16070Sstevel@tonic-gate#elif defined(__i386) 16080Sstevel@tonic-gate 16090Sstevel@tonic-gate /* 16100Sstevel@tonic-gate * The arguments and saved registers are on the stack in the 16110Sstevel@tonic-gate * following order: 16120Sstevel@tonic-gate * | cnt | +16 16130Sstevel@tonic-gate * | *addr | +12 16140Sstevel@tonic-gate * | port | +8 16150Sstevel@tonic-gate * | eip | +4 16160Sstevel@tonic-gate * | esi | <-- %esp 16170Sstevel@tonic-gate * If additional values are pushed onto the stack, make sure 16180Sstevel@tonic-gate * to adjust the following constants accordingly. 16190Sstevel@tonic-gate */ 16200Sstevel@tonic-gate .set PORT, 8 16210Sstevel@tonic-gate .set ADDR, 12 16220Sstevel@tonic-gate .set COUNT, 16 16230Sstevel@tonic-gate 16240Sstevel@tonic-gate ENTRY(repoutsw) 16250Sstevel@tonic-gate pushl %esi 16260Sstevel@tonic-gate movl PORT(%esp), %edx 16270Sstevel@tonic-gate movl ADDR(%esp), %esi 16280Sstevel@tonic-gate movl COUNT(%esp), %ecx 16290Sstevel@tonic-gate rep 16300Sstevel@tonic-gate D16 outsl 16310Sstevel@tonic-gate popl %esi 16320Sstevel@tonic-gate ret 16330Sstevel@tonic-gate SET_SIZE(repoutsw) 16340Sstevel@tonic-gate 16350Sstevel@tonic-gate#endif /* __i386 */ 16360Sstevel@tonic-gate#endif /* __lint */ 16370Sstevel@tonic-gate 16380Sstevel@tonic-gate 16390Sstevel@tonic-gate#if defined(__lint) 16400Sstevel@tonic-gate 16410Sstevel@tonic-gate/* ARGSUSED */ 16420Sstevel@tonic-gatevoid 16430Sstevel@tonic-gaterepinsw(int port_addr, uint16_t *addr, int cnt) 16440Sstevel@tonic-gate{} 16450Sstevel@tonic-gate 16460Sstevel@tonic-gate#else /* __lint */ 16470Sstevel@tonic-gate 16480Sstevel@tonic-gate#if defined(__amd64) 16490Sstevel@tonic-gate 16500Sstevel@tonic-gate ENTRY(repinsw) 16510Sstevel@tonic-gate movl %edx, %ecx 16520Sstevel@tonic-gate movw %di, %dx 16530Sstevel@tonic-gate rep 16540Sstevel@tonic-gate D16 insl 16550Sstevel@tonic-gate ret 16560Sstevel@tonic-gate SET_SIZE(repinsw) 16570Sstevel@tonic-gate 16580Sstevel@tonic-gate#elif defined(__i386) 16590Sstevel@tonic-gate 16600Sstevel@tonic-gate ENTRY(repinsw) 16610Sstevel@tonic-gate pushl %edi 16620Sstevel@tonic-gate movl PORT(%esp), %edx 16630Sstevel@tonic-gate movl ADDR(%esp), %edi 16640Sstevel@tonic-gate movl COUNT(%esp), %ecx 16650Sstevel@tonic-gate rep 16660Sstevel@tonic-gate D16 insl 16670Sstevel@tonic-gate popl %edi 16680Sstevel@tonic-gate ret 16690Sstevel@tonic-gate SET_SIZE(repinsw) 16700Sstevel@tonic-gate 16710Sstevel@tonic-gate#endif /* __i386 */ 16720Sstevel@tonic-gate#endif /* __lint */ 16730Sstevel@tonic-gate 16740Sstevel@tonic-gate 16750Sstevel@tonic-gate#if defined(__lint) 16760Sstevel@tonic-gate 16770Sstevel@tonic-gate/* ARGSUSED */ 16780Sstevel@tonic-gatevoid 16790Sstevel@tonic-gaterepinsb(int port, uint8_t *addr, int count) 16800Sstevel@tonic-gate{} 16810Sstevel@tonic-gate 16820Sstevel@tonic-gate#else /* __lint */ 16830Sstevel@tonic-gate 16840Sstevel@tonic-gate#if defined(__amd64) 16850Sstevel@tonic-gate 16860Sstevel@tonic-gate ENTRY(repinsb) 16870Sstevel@tonic-gate movl %edx, %ecx 16880Sstevel@tonic-gate movw %di, %dx 16890Sstevel@tonic-gate movq %rsi, %rdi 16900Sstevel@tonic-gate rep 16910Sstevel@tonic-gate insb 16920Sstevel@tonic-gate ret 16930Sstevel@tonic-gate SET_SIZE(repinsb) 16940Sstevel@tonic-gate 16950Sstevel@tonic-gate#elif defined(__i386) 16960Sstevel@tonic-gate 16970Sstevel@tonic-gate /* 16980Sstevel@tonic-gate * The arguments and saved registers are on the stack in the 16990Sstevel@tonic-gate * following order: 17000Sstevel@tonic-gate * | cnt | +16 17010Sstevel@tonic-gate * | *addr | +12 17020Sstevel@tonic-gate * | port | +8 17030Sstevel@tonic-gate * | eip | +4 17040Sstevel@tonic-gate * | esi | <-- %esp 17050Sstevel@tonic-gate * If additional values are pushed onto the stack, make sure 17060Sstevel@tonic-gate * to adjust the following constants accordingly. 17070Sstevel@tonic-gate */ 17080Sstevel@tonic-gate .set IO_PORT, 8 17090Sstevel@tonic-gate .set IO_ADDR, 12 17100Sstevel@tonic-gate .set IO_COUNT, 16 17110Sstevel@tonic-gate 17120Sstevel@tonic-gate ENTRY(repinsb) 17130Sstevel@tonic-gate pushl %edi 17140Sstevel@tonic-gate movl IO_ADDR(%esp), %edi 17150Sstevel@tonic-gate movl IO_COUNT(%esp), %ecx 17160Sstevel@tonic-gate movl IO_PORT(%esp), %edx 17170Sstevel@tonic-gate rep 17180Sstevel@tonic-gate insb 17190Sstevel@tonic-gate popl %edi 17200Sstevel@tonic-gate ret 17210Sstevel@tonic-gate SET_SIZE(repinsb) 17220Sstevel@tonic-gate 17230Sstevel@tonic-gate#endif /* __i386 */ 17240Sstevel@tonic-gate#endif /* __lint */ 17250Sstevel@tonic-gate 17260Sstevel@tonic-gate 17270Sstevel@tonic-gate/* 17280Sstevel@tonic-gate * Input a stream of 32-bit words. 17290Sstevel@tonic-gate * NOTE: count is a DWORD count. 17300Sstevel@tonic-gate */ 17310Sstevel@tonic-gate#if defined(__lint) 17320Sstevel@tonic-gate 17330Sstevel@tonic-gate/* ARGSUSED */ 17340Sstevel@tonic-gatevoid 17350Sstevel@tonic-gaterepinsd(int port, uint32_t *addr, int count) 17360Sstevel@tonic-gate{} 17370Sstevel@tonic-gate 17380Sstevel@tonic-gate#else /* __lint */ 17390Sstevel@tonic-gate 17400Sstevel@tonic-gate#if defined(__amd64) 17410Sstevel@tonic-gate 17420Sstevel@tonic-gate ENTRY(repinsd) 17430Sstevel@tonic-gate movl %edx, %ecx 17440Sstevel@tonic-gate movw %di, %dx 17450Sstevel@tonic-gate movq %rsi, %rdi 17460Sstevel@tonic-gate rep 17470Sstevel@tonic-gate insl 17480Sstevel@tonic-gate ret 17490Sstevel@tonic-gate SET_SIZE(repinsd) 17500Sstevel@tonic-gate 17510Sstevel@tonic-gate#elif defined(__i386) 17520Sstevel@tonic-gate 17530Sstevel@tonic-gate ENTRY(repinsd) 17540Sstevel@tonic-gate pushl %edi 17550Sstevel@tonic-gate movl IO_ADDR(%esp), %edi 17560Sstevel@tonic-gate movl IO_COUNT(%esp), %ecx 17570Sstevel@tonic-gate movl IO_PORT(%esp), %edx 17580Sstevel@tonic-gate rep 17590Sstevel@tonic-gate insl 17600Sstevel@tonic-gate popl %edi 17610Sstevel@tonic-gate ret 17620Sstevel@tonic-gate SET_SIZE(repinsd) 17630Sstevel@tonic-gate 17640Sstevel@tonic-gate#endif /* __i386 */ 17650Sstevel@tonic-gate#endif /* __lint */ 17660Sstevel@tonic-gate 17670Sstevel@tonic-gate/* 17680Sstevel@tonic-gate * Output a stream of bytes 17690Sstevel@tonic-gate * NOTE: count is a byte count 17700Sstevel@tonic-gate */ 17710Sstevel@tonic-gate#if defined(__lint) 17720Sstevel@tonic-gate 17730Sstevel@tonic-gate/* ARGSUSED */ 17740Sstevel@tonic-gatevoid 17750Sstevel@tonic-gaterepoutsb(int port, uint8_t *addr, int count) 17760Sstevel@tonic-gate{} 17770Sstevel@tonic-gate 17780Sstevel@tonic-gate#else /* __lint */ 17790Sstevel@tonic-gate 17800Sstevel@tonic-gate#if defined(__amd64) 17810Sstevel@tonic-gate 17820Sstevel@tonic-gate ENTRY(repoutsb) 17830Sstevel@tonic-gate movl %edx, %ecx 17840Sstevel@tonic-gate movw %di, %dx 17850Sstevel@tonic-gate rep 17860Sstevel@tonic-gate outsb 17870Sstevel@tonic-gate ret 17880Sstevel@tonic-gate SET_SIZE(repoutsb) 17890Sstevel@tonic-gate 17900Sstevel@tonic-gate#elif defined(__i386) 17910Sstevel@tonic-gate 17920Sstevel@tonic-gate ENTRY(repoutsb) 17930Sstevel@tonic-gate pushl %esi 17940Sstevel@tonic-gate movl IO_ADDR(%esp), %esi 17950Sstevel@tonic-gate movl IO_COUNT(%esp), %ecx 17960Sstevel@tonic-gate movl IO_PORT(%esp), %edx 17970Sstevel@tonic-gate rep 17980Sstevel@tonic-gate outsb 17990Sstevel@tonic-gate popl %esi 18000Sstevel@tonic-gate ret 18010Sstevel@tonic-gate SET_SIZE(repoutsb) 18020Sstevel@tonic-gate 18030Sstevel@tonic-gate#endif /* __i386 */ 18040Sstevel@tonic-gate#endif /* __lint */ 18050Sstevel@tonic-gate 18060Sstevel@tonic-gate/* 18070Sstevel@tonic-gate * Output a stream of 32-bit words 18080Sstevel@tonic-gate * NOTE: count is a DWORD count 18090Sstevel@tonic-gate */ 18100Sstevel@tonic-gate#if defined(__lint) 18110Sstevel@tonic-gate 18120Sstevel@tonic-gate/* ARGSUSED */ 18130Sstevel@tonic-gatevoid 18140Sstevel@tonic-gaterepoutsd(int port, uint32_t *addr, int count) 18150Sstevel@tonic-gate{} 18160Sstevel@tonic-gate 18170Sstevel@tonic-gate#else /* __lint */ 18180Sstevel@tonic-gate 18190Sstevel@tonic-gate#if defined(__amd64) 18200Sstevel@tonic-gate 18210Sstevel@tonic-gate ENTRY(repoutsd) 18220Sstevel@tonic-gate movl %edx, %ecx 18230Sstevel@tonic-gate movw %di, %dx 18240Sstevel@tonic-gate rep 18250Sstevel@tonic-gate outsl 18260Sstevel@tonic-gate ret 18270Sstevel@tonic-gate SET_SIZE(repoutsd) 18280Sstevel@tonic-gate 18290Sstevel@tonic-gate#elif defined(__i386) 18300Sstevel@tonic-gate 18310Sstevel@tonic-gate ENTRY(repoutsd) 18320Sstevel@tonic-gate pushl %esi 18330Sstevel@tonic-gate movl IO_ADDR(%esp), %esi 18340Sstevel@tonic-gate movl IO_COUNT(%esp), %ecx 18350Sstevel@tonic-gate movl IO_PORT(%esp), %edx 18360Sstevel@tonic-gate rep 18370Sstevel@tonic-gate outsl 18380Sstevel@tonic-gate popl %esi 18390Sstevel@tonic-gate ret 18400Sstevel@tonic-gate SET_SIZE(repoutsd) 18410Sstevel@tonic-gate 18420Sstevel@tonic-gate#endif /* __i386 */ 18430Sstevel@tonic-gate#endif /* __lint */ 18440Sstevel@tonic-gate 18450Sstevel@tonic-gate/* 18461414Scindi * void int3(void) 18471414Scindi * void int18(void) 18480Sstevel@tonic-gate * void int20(void) 18497349SAdrian.Frost@Sun.COM * void int_cmci(void) 18500Sstevel@tonic-gate */ 18510Sstevel@tonic-gate 18520Sstevel@tonic-gate#if defined(__lint) 18530Sstevel@tonic-gate 18540Sstevel@tonic-gatevoid 18551414Scindiint3(void) 18561414Scindi{} 18571414Scindi 18581414Scindivoid 18591414Scindiint18(void) 18601414Scindi{} 18611414Scindi 18621414Scindivoid 18630Sstevel@tonic-gateint20(void) 18640Sstevel@tonic-gate{} 18650Sstevel@tonic-gate 18667349SAdrian.Frost@Sun.COMvoid 18677349SAdrian.Frost@Sun.COMint_cmci(void) 18687349SAdrian.Frost@Sun.COM{} 18697349SAdrian.Frost@Sun.COM 18700Sstevel@tonic-gate#else /* __lint */ 18710Sstevel@tonic-gate 18721414Scindi ENTRY(int3) 18731414Scindi int $T_BPTFLT 18741414Scindi ret 18751414Scindi SET_SIZE(int3) 18761414Scindi 18771414Scindi ENTRY(int18) 18781414Scindi int $T_MCE 18791414Scindi ret 18801414Scindi SET_SIZE(int18) 18811414Scindi 18820Sstevel@tonic-gate ENTRY(int20) 18830Sstevel@tonic-gate movl boothowto, %eax 18840Sstevel@tonic-gate andl $RB_DEBUG, %eax 18850Sstevel@tonic-gate jz 1f 18860Sstevel@tonic-gate 18871414Scindi int $T_DBGENTR 18880Sstevel@tonic-gate1: 1889545Skalai rep; ret /* use 2 byte return instruction when branch target */ 1890545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 18910Sstevel@tonic-gate SET_SIZE(int20) 18920Sstevel@tonic-gate 18937349SAdrian.Frost@Sun.COM ENTRY(int_cmci) 18947349SAdrian.Frost@Sun.COM int $T_ENOEXTFLT 18957349SAdrian.Frost@Sun.COM ret 18967349SAdrian.Frost@Sun.COM SET_SIZE(int_cmci) 18977349SAdrian.Frost@Sun.COM 18980Sstevel@tonic-gate#endif /* __lint */ 18990Sstevel@tonic-gate 19000Sstevel@tonic-gate#if defined(__lint) 19010Sstevel@tonic-gate 19020Sstevel@tonic-gate/* ARGSUSED */ 19030Sstevel@tonic-gateint 19040Sstevel@tonic-gatescanc(size_t size, uchar_t *cp, uchar_t *table, uchar_t mask) 19050Sstevel@tonic-gate{ return (0); } 19060Sstevel@tonic-gate 19070Sstevel@tonic-gate#else /* __lint */ 19080Sstevel@tonic-gate 19090Sstevel@tonic-gate#if defined(__amd64) 19100Sstevel@tonic-gate 19110Sstevel@tonic-gate ENTRY(scanc) 19120Sstevel@tonic-gate /* rdi == size */ 19130Sstevel@tonic-gate /* rsi == cp */ 19140Sstevel@tonic-gate /* rdx == table */ 19150Sstevel@tonic-gate /* rcx == mask */ 19160Sstevel@tonic-gate addq %rsi, %rdi /* end = &cp[size] */ 19177421SDaniel.Anderson@Sun.COM.scanloop: 19180Sstevel@tonic-gate cmpq %rdi, %rsi /* while (cp < end */ 19190Sstevel@tonic-gate jnb .scandone 19200Sstevel@tonic-gate movzbq (%rsi), %r8 /* %r8 = *cp */ 19210Sstevel@tonic-gate incq %rsi /* cp++ */ 19220Sstevel@tonic-gate testb %cl, (%r8, %rdx) 19230Sstevel@tonic-gate jz .scanloop /* && (table[*cp] & mask) == 0) */ 19240Sstevel@tonic-gate decq %rsi /* (fix post-increment) */ 19250Sstevel@tonic-gate.scandone: 19260Sstevel@tonic-gate movl %edi, %eax 19270Sstevel@tonic-gate subl %esi, %eax /* return (end - cp) */ 19280Sstevel@tonic-gate ret 19290Sstevel@tonic-gate SET_SIZE(scanc) 19300Sstevel@tonic-gate 19310Sstevel@tonic-gate#elif defined(__i386) 19327421SDaniel.Anderson@Sun.COM 19330Sstevel@tonic-gate ENTRY(scanc) 19340Sstevel@tonic-gate pushl %edi 19350Sstevel@tonic-gate pushl %esi 19360Sstevel@tonic-gate movb 24(%esp), %cl /* mask = %cl */ 19370Sstevel@tonic-gate movl 16(%esp), %esi /* cp = %esi */ 19380Sstevel@tonic-gate movl 20(%esp), %edx /* table = %edx */ 19390Sstevel@tonic-gate movl %esi, %edi 19400Sstevel@tonic-gate addl 12(%esp), %edi /* end = &cp[size]; */ 19410Sstevel@tonic-gate.scanloop: 19420Sstevel@tonic-gate cmpl %edi, %esi /* while (cp < end */ 19430Sstevel@tonic-gate jnb .scandone 19440Sstevel@tonic-gate movzbl (%esi), %eax /* %al = *cp */ 19450Sstevel@tonic-gate incl %esi /* cp++ */ 19460Sstevel@tonic-gate movb (%edx, %eax), %al /* %al = table[*cp] */ 19470Sstevel@tonic-gate testb %al, %cl 19480Sstevel@tonic-gate jz .scanloop /* && (table[*cp] & mask) == 0) */ 19490Sstevel@tonic-gate dec %esi /* post-incremented */ 19500Sstevel@tonic-gate.scandone: 19510Sstevel@tonic-gate movl %edi, %eax 19520Sstevel@tonic-gate subl %esi, %eax /* return (end - cp) */ 19530Sstevel@tonic-gate popl %esi 19540Sstevel@tonic-gate popl %edi 19550Sstevel@tonic-gate ret 19560Sstevel@tonic-gate SET_SIZE(scanc) 19570Sstevel@tonic-gate 19587421SDaniel.Anderson@Sun.COM#endif /* __i386 */ 19590Sstevel@tonic-gate#endif /* __lint */ 19600Sstevel@tonic-gate 19610Sstevel@tonic-gate/* 19620Sstevel@tonic-gate * Replacement functions for ones that are normally inlined. 19630Sstevel@tonic-gate * In addition to the copy in i86.il, they are defined here just in case. 19640Sstevel@tonic-gate */ 19650Sstevel@tonic-gate 19660Sstevel@tonic-gate#if defined(__lint) 19670Sstevel@tonic-gate 19683446Smrjulong_t 19690Sstevel@tonic-gateintr_clear(void) 19703446Smrj{ return (0); } 19713446Smrj 19723446Smrjulong_t 19730Sstevel@tonic-gateclear_int_flag(void) 19743446Smrj{ return (0); } 19750Sstevel@tonic-gate 19760Sstevel@tonic-gate#else /* __lint */ 19770Sstevel@tonic-gate 19780Sstevel@tonic-gate#if defined(__amd64) 19790Sstevel@tonic-gate 19800Sstevel@tonic-gate ENTRY(intr_clear) 19810Sstevel@tonic-gate ENTRY(clear_int_flag) 19820Sstevel@tonic-gate pushfq 19830Sstevel@tonic-gate popq %rax 19845084Sjohnlev#if defined(__xpv) 19855084Sjohnlev leaq xpv_panicking, %rdi 19865084Sjohnlev movl (%rdi), %edi 19875084Sjohnlev cmpl $0, %edi 19885084Sjohnlev jne 2f 19895084Sjohnlev CLIRET(%rdi, %dl) /* returns event mask in %dl */ 19905084Sjohnlev /* 19915084Sjohnlev * Synthesize the PS_IE bit from the event mask bit 19925084Sjohnlev */ 19935084Sjohnlev andq $_BITNOT(PS_IE), %rax 19945084Sjohnlev testb $1, %dl 19955084Sjohnlev jnz 1f 19965084Sjohnlev orq $PS_IE, %rax 19975084Sjohnlev1: 19985084Sjohnlev ret 19995084Sjohnlev2: 20005084Sjohnlev#endif 20013446Smrj CLI(%rdi) 20020Sstevel@tonic-gate ret 20030Sstevel@tonic-gate SET_SIZE(clear_int_flag) 20040Sstevel@tonic-gate SET_SIZE(intr_clear) 20050Sstevel@tonic-gate 20060Sstevel@tonic-gate#elif defined(__i386) 20070Sstevel@tonic-gate 20080Sstevel@tonic-gate ENTRY(intr_clear) 20090Sstevel@tonic-gate ENTRY(clear_int_flag) 20100Sstevel@tonic-gate pushfl 20110Sstevel@tonic-gate popl %eax 20125084Sjohnlev#if defined(__xpv) 20135084Sjohnlev leal xpv_panicking, %edx 20145084Sjohnlev movl (%edx), %edx 20155084Sjohnlev cmpl $0, %edx 20165084Sjohnlev jne 2f 20175084Sjohnlev CLIRET(%edx, %cl) /* returns event mask in %cl */ 20185084Sjohnlev /* 20195084Sjohnlev * Synthesize the PS_IE bit from the event mask bit 20205084Sjohnlev */ 20215084Sjohnlev andl $_BITNOT(PS_IE), %eax 20225084Sjohnlev testb $1, %cl 20235084Sjohnlev jnz 1f 20245084Sjohnlev orl $PS_IE, %eax 20255084Sjohnlev1: 20265084Sjohnlev ret 20275084Sjohnlev2: 20285084Sjohnlev#endif 20293446Smrj CLI(%edx) 20300Sstevel@tonic-gate ret 20310Sstevel@tonic-gate SET_SIZE(clear_int_flag) 20320Sstevel@tonic-gate SET_SIZE(intr_clear) 20330Sstevel@tonic-gate 20340Sstevel@tonic-gate#endif /* __i386 */ 20350Sstevel@tonic-gate#endif /* __lint */ 20360Sstevel@tonic-gate 20370Sstevel@tonic-gate#if defined(__lint) 20380Sstevel@tonic-gate 20390Sstevel@tonic-gatestruct cpu * 20400Sstevel@tonic-gatecurcpup(void) 20410Sstevel@tonic-gate{ return 0; } 20420Sstevel@tonic-gate 20430Sstevel@tonic-gate#else /* __lint */ 20440Sstevel@tonic-gate 20450Sstevel@tonic-gate#if defined(__amd64) 20460Sstevel@tonic-gate 20470Sstevel@tonic-gate ENTRY(curcpup) 20480Sstevel@tonic-gate movq %gs:CPU_SELF, %rax 20490Sstevel@tonic-gate ret 20500Sstevel@tonic-gate SET_SIZE(curcpup) 20510Sstevel@tonic-gate 20520Sstevel@tonic-gate#elif defined(__i386) 20530Sstevel@tonic-gate 20540Sstevel@tonic-gate ENTRY(curcpup) 20550Sstevel@tonic-gate movl %gs:CPU_SELF, %eax 20560Sstevel@tonic-gate ret 20570Sstevel@tonic-gate SET_SIZE(curcpup) 20580Sstevel@tonic-gate 20590Sstevel@tonic-gate#endif /* __i386 */ 20600Sstevel@tonic-gate#endif /* __lint */ 20610Sstevel@tonic-gate 20627421SDaniel.Anderson@Sun.COM/* htonll(), ntohll(), htonl(), ntohl(), htons(), ntohs() 20637421SDaniel.Anderson@Sun.COM * These functions reverse the byte order of the input parameter and returns 20647421SDaniel.Anderson@Sun.COM * the result. This is to convert the byte order from host byte order 20657421SDaniel.Anderson@Sun.COM * (little endian) to network byte order (big endian), or vice versa. 20667421SDaniel.Anderson@Sun.COM */ 20677421SDaniel.Anderson@Sun.COM 20680Sstevel@tonic-gate#if defined(__lint) 20690Sstevel@tonic-gate 20707421SDaniel.Anderson@Sun.COMuint64_t 20717421SDaniel.Anderson@Sun.COMhtonll(uint64_t i) 20727421SDaniel.Anderson@Sun.COM{ return (i); } 20737421SDaniel.Anderson@Sun.COM 20747421SDaniel.Anderson@Sun.COMuint64_t 20757421SDaniel.Anderson@Sun.COMntohll(uint64_t i) 20767421SDaniel.Anderson@Sun.COM{ return (i); } 20777421SDaniel.Anderson@Sun.COM 20780Sstevel@tonic-gateuint32_t 20790Sstevel@tonic-gatehtonl(uint32_t i) 20807421SDaniel.Anderson@Sun.COM{ return (i); } 20817421SDaniel.Anderson@Sun.COM 20820Sstevel@tonic-gateuint32_t 20830Sstevel@tonic-gatentohl(uint32_t i) 20847421SDaniel.Anderson@Sun.COM{ return (i); } 20857421SDaniel.Anderson@Sun.COM 20867421SDaniel.Anderson@Sun.COMuint16_t 20877421SDaniel.Anderson@Sun.COMhtons(uint16_t i) 20887421SDaniel.Anderson@Sun.COM{ return (i); } 20897421SDaniel.Anderson@Sun.COM 20907421SDaniel.Anderson@Sun.COMuint16_t 20917421SDaniel.Anderson@Sun.COMntohs(uint16_t i) 20927421SDaniel.Anderson@Sun.COM{ return (i); } 20930Sstevel@tonic-gate 20940Sstevel@tonic-gate#else /* __lint */ 20950Sstevel@tonic-gate 20960Sstevel@tonic-gate#if defined(__amd64) 20970Sstevel@tonic-gate 20987421SDaniel.Anderson@Sun.COM ENTRY(htonll) 20997421SDaniel.Anderson@Sun.COM ALTENTRY(ntohll) 21007421SDaniel.Anderson@Sun.COM movq %rdi, %rax 21017421SDaniel.Anderson@Sun.COM bswapq %rax 21027421SDaniel.Anderson@Sun.COM ret 21037421SDaniel.Anderson@Sun.COM SET_SIZE(ntohll) 21047421SDaniel.Anderson@Sun.COM SET_SIZE(htonll) 21057421SDaniel.Anderson@Sun.COM 21060Sstevel@tonic-gate /* XX64 there must be shorter sequences for this */ 21070Sstevel@tonic-gate ENTRY(htonl) 21080Sstevel@tonic-gate ALTENTRY(ntohl) 21090Sstevel@tonic-gate movl %edi, %eax 21100Sstevel@tonic-gate bswap %eax 21110Sstevel@tonic-gate ret 21120Sstevel@tonic-gate SET_SIZE(ntohl) 21130Sstevel@tonic-gate SET_SIZE(htonl) 21140Sstevel@tonic-gate 21157421SDaniel.Anderson@Sun.COM /* XX64 there must be better sequences for this */ 21167421SDaniel.Anderson@Sun.COM ENTRY(htons) 21177421SDaniel.Anderson@Sun.COM ALTENTRY(ntohs) 21187421SDaniel.Anderson@Sun.COM movl %edi, %eax 21197421SDaniel.Anderson@Sun.COM bswap %eax 21207421SDaniel.Anderson@Sun.COM shrl $16, %eax 21217421SDaniel.Anderson@Sun.COM ret 21227421SDaniel.Anderson@Sun.COM SET_SIZE(ntohs) 21237421SDaniel.Anderson@Sun.COM SET_SIZE(htons) 21247421SDaniel.Anderson@Sun.COM 21250Sstevel@tonic-gate#elif defined(__i386) 21260Sstevel@tonic-gate 21277421SDaniel.Anderson@Sun.COM ENTRY(htonll) 21287421SDaniel.Anderson@Sun.COM ALTENTRY(ntohll) 21297421SDaniel.Anderson@Sun.COM movl 4(%esp), %edx 21307421SDaniel.Anderson@Sun.COM movl 8(%esp), %eax 21317421SDaniel.Anderson@Sun.COM bswap %edx 21327421SDaniel.Anderson@Sun.COM bswap %eax 21337421SDaniel.Anderson@Sun.COM ret 21347421SDaniel.Anderson@Sun.COM SET_SIZE(ntohll) 21357421SDaniel.Anderson@Sun.COM SET_SIZE(htonll) 21367421SDaniel.Anderson@Sun.COM 21370Sstevel@tonic-gate ENTRY(htonl) 21380Sstevel@tonic-gate ALTENTRY(ntohl) 21390Sstevel@tonic-gate movl 4(%esp), %eax 21400Sstevel@tonic-gate bswap %eax 21410Sstevel@tonic-gate ret 21420Sstevel@tonic-gate SET_SIZE(ntohl) 21430Sstevel@tonic-gate SET_SIZE(htonl) 21440Sstevel@tonic-gate 21450Sstevel@tonic-gate ENTRY(htons) 21460Sstevel@tonic-gate ALTENTRY(ntohs) 21470Sstevel@tonic-gate movl 4(%esp), %eax 21480Sstevel@tonic-gate bswap %eax 21490Sstevel@tonic-gate shrl $16, %eax 21500Sstevel@tonic-gate ret 21510Sstevel@tonic-gate SET_SIZE(ntohs) 21520Sstevel@tonic-gate SET_SIZE(htons) 21530Sstevel@tonic-gate 21540Sstevel@tonic-gate#endif /* __i386 */ 21550Sstevel@tonic-gate#endif /* __lint */ 21560Sstevel@tonic-gate 21570Sstevel@tonic-gate 21580Sstevel@tonic-gate#if defined(__lint) 21590Sstevel@tonic-gate 21600Sstevel@tonic-gate/* ARGSUSED */ 21610Sstevel@tonic-gatevoid 21623446Smrjintr_restore(ulong_t i) 21630Sstevel@tonic-gate{ return; } 21640Sstevel@tonic-gate 21650Sstevel@tonic-gate/* ARGSUSED */ 21660Sstevel@tonic-gatevoid 21673446Smrjrestore_int_flag(ulong_t i) 21680Sstevel@tonic-gate{ return; } 21690Sstevel@tonic-gate 21700Sstevel@tonic-gate#else /* __lint */ 21710Sstevel@tonic-gate 21720Sstevel@tonic-gate#if defined(__amd64) 21730Sstevel@tonic-gate 21740Sstevel@tonic-gate ENTRY(intr_restore) 21750Sstevel@tonic-gate ENTRY(restore_int_flag) 21766336Sbholler testq $PS_IE, %rdi 21776336Sbholler jz 1f 21785084Sjohnlev#if defined(__xpv) 21795084Sjohnlev leaq xpv_panicking, %rsi 21805084Sjohnlev movl (%rsi), %esi 21815084Sjohnlev cmpl $0, %esi 21825084Sjohnlev jne 1f 21835084Sjohnlev /* 21845084Sjohnlev * Since we're -really- running unprivileged, our attempt 21855084Sjohnlev * to change the state of the IF bit will be ignored. 21865084Sjohnlev * The virtual IF bit is tweaked by CLI and STI. 21875084Sjohnlev */ 21885084Sjohnlev IE_TO_EVENT_MASK(%rsi, %rdi) 21896336Sbholler#else 21906336Sbholler sti 21916336Sbholler#endif 21925084Sjohnlev1: 21930Sstevel@tonic-gate ret 21940Sstevel@tonic-gate SET_SIZE(restore_int_flag) 21950Sstevel@tonic-gate SET_SIZE(intr_restore) 21960Sstevel@tonic-gate 21970Sstevel@tonic-gate#elif defined(__i386) 21980Sstevel@tonic-gate 21990Sstevel@tonic-gate ENTRY(intr_restore) 22000Sstevel@tonic-gate ENTRY(restore_int_flag) 22016336Sbholler testl $PS_IE, 4(%esp) 22026336Sbholler jz 1f 22035084Sjohnlev#if defined(__xpv) 22045084Sjohnlev leal xpv_panicking, %edx 22055084Sjohnlev movl (%edx), %edx 22065084Sjohnlev cmpl $0, %edx 22075084Sjohnlev jne 1f 22085084Sjohnlev /* 22095084Sjohnlev * Since we're -really- running unprivileged, our attempt 22105084Sjohnlev * to change the state of the IF bit will be ignored. 22115084Sjohnlev * The virtual IF bit is tweaked by CLI and STI. 22125084Sjohnlev */ 22136356Smrj IE_TO_EVENT_MASK(%edx, 4(%esp)) 22146336Sbholler#else 22156336Sbholler sti 22166336Sbholler#endif 22175084Sjohnlev1: 22180Sstevel@tonic-gate ret 22190Sstevel@tonic-gate SET_SIZE(restore_int_flag) 22200Sstevel@tonic-gate SET_SIZE(intr_restore) 22210Sstevel@tonic-gate 22220Sstevel@tonic-gate#endif /* __i386 */ 22230Sstevel@tonic-gate#endif /* __lint */ 22240Sstevel@tonic-gate 22250Sstevel@tonic-gate#if defined(__lint) 22260Sstevel@tonic-gate 22270Sstevel@tonic-gatevoid 22280Sstevel@tonic-gatesti(void) 22290Sstevel@tonic-gate{} 22300Sstevel@tonic-gate 22313446Smrjvoid 22323446Smrjcli(void) 22333446Smrj{} 22343446Smrj 22350Sstevel@tonic-gate#else /* __lint */ 22360Sstevel@tonic-gate 22370Sstevel@tonic-gate ENTRY(sti) 22383446Smrj STI 22390Sstevel@tonic-gate ret 22400Sstevel@tonic-gate SET_SIZE(sti) 22410Sstevel@tonic-gate 22423446Smrj ENTRY(cli) 22433446Smrj#if defined(__amd64) 22443446Smrj CLI(%rax) 22453446Smrj#elif defined(__i386) 22463446Smrj CLI(%eax) 22473446Smrj#endif /* __i386 */ 22483446Smrj ret 22493446Smrj SET_SIZE(cli) 22503446Smrj 22510Sstevel@tonic-gate#endif /* __lint */ 22520Sstevel@tonic-gate 22530Sstevel@tonic-gate#if defined(__lint) 22540Sstevel@tonic-gate 22550Sstevel@tonic-gatedtrace_icookie_t 22560Sstevel@tonic-gatedtrace_interrupt_disable(void) 22570Sstevel@tonic-gate{ return (0); } 22580Sstevel@tonic-gate 22590Sstevel@tonic-gate#else /* __lint */ 22600Sstevel@tonic-gate 22610Sstevel@tonic-gate#if defined(__amd64) 22620Sstevel@tonic-gate 22630Sstevel@tonic-gate ENTRY(dtrace_interrupt_disable) 22640Sstevel@tonic-gate pushfq 22650Sstevel@tonic-gate popq %rax 22665084Sjohnlev#if defined(__xpv) 22675084Sjohnlev leaq xpv_panicking, %rdi 22685084Sjohnlev movl (%rdi), %edi 22695084Sjohnlev cmpl $0, %edi 22707532SSean.Ye@Sun.COM jne .dtrace_interrupt_disable_done 22715084Sjohnlev CLIRET(%rdi, %dl) /* returns event mask in %dl */ 22725084Sjohnlev /* 22735084Sjohnlev * Synthesize the PS_IE bit from the event mask bit 22745084Sjohnlev */ 22755084Sjohnlev andq $_BITNOT(PS_IE), %rax 22765084Sjohnlev testb $1, %dl 22777532SSean.Ye@Sun.COM jnz .dtrace_interrupt_disable_done 22785084Sjohnlev orq $PS_IE, %rax 22795084Sjohnlev#else 22803446Smrj CLI(%rdx) 22815084Sjohnlev#endif 22827532SSean.Ye@Sun.COM.dtrace_interrupt_disable_done: 22830Sstevel@tonic-gate ret 22840Sstevel@tonic-gate SET_SIZE(dtrace_interrupt_disable) 22850Sstevel@tonic-gate 22860Sstevel@tonic-gate#elif defined(__i386) 22870Sstevel@tonic-gate 22880Sstevel@tonic-gate ENTRY(dtrace_interrupt_disable) 22890Sstevel@tonic-gate pushfl 22900Sstevel@tonic-gate popl %eax 22915084Sjohnlev#if defined(__xpv) 22925084Sjohnlev leal xpv_panicking, %edx 22935084Sjohnlev movl (%edx), %edx 22945084Sjohnlev cmpl $0, %edx 22957532SSean.Ye@Sun.COM jne .dtrace_interrupt_disable_done 22965084Sjohnlev CLIRET(%edx, %cl) /* returns event mask in %cl */ 22975084Sjohnlev /* 22985084Sjohnlev * Synthesize the PS_IE bit from the event mask bit 22995084Sjohnlev */ 23005084Sjohnlev andl $_BITNOT(PS_IE), %eax 23015084Sjohnlev testb $1, %cl 23027532SSean.Ye@Sun.COM jnz .dtrace_interrupt_disable_done 23035084Sjohnlev orl $PS_IE, %eax 23045084Sjohnlev#else 23053446Smrj CLI(%edx) 23065084Sjohnlev#endif 23077532SSean.Ye@Sun.COM.dtrace_interrupt_disable_done: 23080Sstevel@tonic-gate ret 23090Sstevel@tonic-gate SET_SIZE(dtrace_interrupt_disable) 23100Sstevel@tonic-gate 23110Sstevel@tonic-gate#endif /* __i386 */ 23120Sstevel@tonic-gate#endif /* __lint */ 23130Sstevel@tonic-gate 23140Sstevel@tonic-gate#if defined(__lint) 23150Sstevel@tonic-gate 23160Sstevel@tonic-gate/*ARGSUSED*/ 23170Sstevel@tonic-gatevoid 23180Sstevel@tonic-gatedtrace_interrupt_enable(dtrace_icookie_t cookie) 23190Sstevel@tonic-gate{} 23200Sstevel@tonic-gate 23210Sstevel@tonic-gate#else /* __lint */ 23220Sstevel@tonic-gate 23230Sstevel@tonic-gate#if defined(__amd64) 23240Sstevel@tonic-gate 23250Sstevel@tonic-gate ENTRY(dtrace_interrupt_enable) 23260Sstevel@tonic-gate pushq %rdi 23270Sstevel@tonic-gate popfq 23285084Sjohnlev#if defined(__xpv) 23295084Sjohnlev leaq xpv_panicking, %rdx 23305084Sjohnlev movl (%rdx), %edx 23315084Sjohnlev cmpl $0, %edx 23327532SSean.Ye@Sun.COM jne .dtrace_interrupt_enable_done 23335084Sjohnlev /* 23345084Sjohnlev * Since we're -really- running unprivileged, our attempt 23355084Sjohnlev * to change the state of the IF bit will be ignored. The 23365084Sjohnlev * virtual IF bit is tweaked by CLI and STI. 23375084Sjohnlev */ 23385084Sjohnlev IE_TO_EVENT_MASK(%rdx, %rdi) 23395084Sjohnlev#endif 23407532SSean.Ye@Sun.COM.dtrace_interrupt_enable_done: 23410Sstevel@tonic-gate ret 23420Sstevel@tonic-gate SET_SIZE(dtrace_interrupt_enable) 23430Sstevel@tonic-gate 23440Sstevel@tonic-gate#elif defined(__i386) 23450Sstevel@tonic-gate 23460Sstevel@tonic-gate ENTRY(dtrace_interrupt_enable) 23470Sstevel@tonic-gate movl 4(%esp), %eax 23480Sstevel@tonic-gate pushl %eax 23490Sstevel@tonic-gate popfl 23505084Sjohnlev#if defined(__xpv) 23515084Sjohnlev leal xpv_panicking, %edx 23525084Sjohnlev movl (%edx), %edx 23535084Sjohnlev cmpl $0, %edx 23547532SSean.Ye@Sun.COM jne .dtrace_interrupt_enable_done 23555084Sjohnlev /* 23565084Sjohnlev * Since we're -really- running unprivileged, our attempt 23575084Sjohnlev * to change the state of the IF bit will be ignored. The 23585084Sjohnlev * virtual IF bit is tweaked by CLI and STI. 23595084Sjohnlev */ 23605084Sjohnlev IE_TO_EVENT_MASK(%edx, %eax) 23615084Sjohnlev#endif 23627532SSean.Ye@Sun.COM.dtrace_interrupt_enable_done: 23630Sstevel@tonic-gate ret 23640Sstevel@tonic-gate SET_SIZE(dtrace_interrupt_enable) 23650Sstevel@tonic-gate 23660Sstevel@tonic-gate#endif /* __i386 */ 23670Sstevel@tonic-gate#endif /* __lint */ 23680Sstevel@tonic-gate 23690Sstevel@tonic-gate 23700Sstevel@tonic-gate#if defined(lint) 23710Sstevel@tonic-gate 23720Sstevel@tonic-gatevoid 23730Sstevel@tonic-gatedtrace_membar_producer(void) 23740Sstevel@tonic-gate{} 23750Sstevel@tonic-gate 23760Sstevel@tonic-gatevoid 23770Sstevel@tonic-gatedtrace_membar_consumer(void) 23780Sstevel@tonic-gate{} 23790Sstevel@tonic-gate 23800Sstevel@tonic-gate#else /* __lint */ 23810Sstevel@tonic-gate 23820Sstevel@tonic-gate ENTRY(dtrace_membar_producer) 2383545Skalai rep; ret /* use 2 byte return instruction when branch target */ 2384545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 23850Sstevel@tonic-gate SET_SIZE(dtrace_membar_producer) 23860Sstevel@tonic-gate 23870Sstevel@tonic-gate ENTRY(dtrace_membar_consumer) 2388545Skalai rep; ret /* use 2 byte return instruction when branch target */ 2389545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 23900Sstevel@tonic-gate SET_SIZE(dtrace_membar_consumer) 23910Sstevel@tonic-gate 23920Sstevel@tonic-gate#endif /* __lint */ 23930Sstevel@tonic-gate 23940Sstevel@tonic-gate#if defined(__lint) 23950Sstevel@tonic-gate 23960Sstevel@tonic-gatekthread_id_t 23970Sstevel@tonic-gatethreadp(void) 23980Sstevel@tonic-gate{ return ((kthread_id_t)0); } 23990Sstevel@tonic-gate 24000Sstevel@tonic-gate#else /* __lint */ 24010Sstevel@tonic-gate 24020Sstevel@tonic-gate#if defined(__amd64) 24030Sstevel@tonic-gate 24040Sstevel@tonic-gate ENTRY(threadp) 24050Sstevel@tonic-gate movq %gs:CPU_THREAD, %rax 24060Sstevel@tonic-gate ret 24070Sstevel@tonic-gate SET_SIZE(threadp) 24080Sstevel@tonic-gate 24090Sstevel@tonic-gate#elif defined(__i386) 24100Sstevel@tonic-gate 24110Sstevel@tonic-gate ENTRY(threadp) 24120Sstevel@tonic-gate movl %gs:CPU_THREAD, %eax 24130Sstevel@tonic-gate ret 24140Sstevel@tonic-gate SET_SIZE(threadp) 24150Sstevel@tonic-gate 24160Sstevel@tonic-gate#endif /* __i386 */ 24170Sstevel@tonic-gate#endif /* __lint */ 24180Sstevel@tonic-gate 24190Sstevel@tonic-gate/* 24200Sstevel@tonic-gate * Checksum routine for Internet Protocol Headers 24210Sstevel@tonic-gate */ 24220Sstevel@tonic-gate 24230Sstevel@tonic-gate#if defined(__lint) 24240Sstevel@tonic-gate 24250Sstevel@tonic-gate/* ARGSUSED */ 24260Sstevel@tonic-gateunsigned int 24270Sstevel@tonic-gateip_ocsum( 24280Sstevel@tonic-gate ushort_t *address, /* ptr to 1st message buffer */ 24290Sstevel@tonic-gate int halfword_count, /* length of data */ 24300Sstevel@tonic-gate unsigned int sum) /* partial checksum */ 24310Sstevel@tonic-gate{ 24320Sstevel@tonic-gate int i; 24330Sstevel@tonic-gate unsigned int psum = 0; /* partial sum */ 24340Sstevel@tonic-gate 24350Sstevel@tonic-gate for (i = 0; i < halfword_count; i++, address++) { 24360Sstevel@tonic-gate psum += *address; 24370Sstevel@tonic-gate } 24380Sstevel@tonic-gate 24390Sstevel@tonic-gate while ((psum >> 16) != 0) { 24400Sstevel@tonic-gate psum = (psum & 0xffff) + (psum >> 16); 24410Sstevel@tonic-gate } 24420Sstevel@tonic-gate 24430Sstevel@tonic-gate psum += sum; 24440Sstevel@tonic-gate 24450Sstevel@tonic-gate while ((psum >> 16) != 0) { 24460Sstevel@tonic-gate psum = (psum & 0xffff) + (psum >> 16); 24470Sstevel@tonic-gate } 24480Sstevel@tonic-gate 24490Sstevel@tonic-gate return (psum); 24500Sstevel@tonic-gate} 24510Sstevel@tonic-gate 24520Sstevel@tonic-gate#else /* __lint */ 24530Sstevel@tonic-gate 24540Sstevel@tonic-gate#if defined(__amd64) 24550Sstevel@tonic-gate 24560Sstevel@tonic-gate ENTRY(ip_ocsum) 24570Sstevel@tonic-gate pushq %rbp 24580Sstevel@tonic-gate movq %rsp, %rbp 24590Sstevel@tonic-gate#ifdef DEBUG 24603446Smrj movq postbootkernelbase(%rip), %rax 24610Sstevel@tonic-gate cmpq %rax, %rdi 24620Sstevel@tonic-gate jnb 1f 24630Sstevel@tonic-gate xorl %eax, %eax 24640Sstevel@tonic-gate movq %rdi, %rsi 24650Sstevel@tonic-gate leaq .ip_ocsum_panic_msg(%rip), %rdi 24660Sstevel@tonic-gate call panic 24670Sstevel@tonic-gate /*NOTREACHED*/ 24680Sstevel@tonic-gate.ip_ocsum_panic_msg: 24690Sstevel@tonic-gate .string "ip_ocsum: address 0x%p below kernelbase\n" 24700Sstevel@tonic-gate1: 24710Sstevel@tonic-gate#endif 24720Sstevel@tonic-gate movl %esi, %ecx /* halfword_count */ 24730Sstevel@tonic-gate movq %rdi, %rsi /* address */ 24740Sstevel@tonic-gate /* partial sum in %edx */ 24750Sstevel@tonic-gate xorl %eax, %eax 24760Sstevel@tonic-gate testl %ecx, %ecx 24770Sstevel@tonic-gate jz .ip_ocsum_done 24780Sstevel@tonic-gate testq $3, %rsi 24790Sstevel@tonic-gate jnz .ip_csum_notaligned 24800Sstevel@tonic-gate.ip_csum_aligned: /* XX64 opportunities for 8-byte operations? */ 24810Sstevel@tonic-gate.next_iter: 24820Sstevel@tonic-gate /* XX64 opportunities for prefetch? */ 24830Sstevel@tonic-gate /* XX64 compute csum with 64 bit quantities? */ 24840Sstevel@tonic-gate subl $32, %ecx 24850Sstevel@tonic-gate jl .less_than_32 24860Sstevel@tonic-gate 24870Sstevel@tonic-gate addl 0(%rsi), %edx 24880Sstevel@tonic-gate.only60: 24890Sstevel@tonic-gate adcl 4(%rsi), %eax 24900Sstevel@tonic-gate.only56: 24910Sstevel@tonic-gate adcl 8(%rsi), %edx 24920Sstevel@tonic-gate.only52: 24930Sstevel@tonic-gate adcl 12(%rsi), %eax 24940Sstevel@tonic-gate.only48: 24950Sstevel@tonic-gate adcl 16(%rsi), %edx 24960Sstevel@tonic-gate.only44: 24970Sstevel@tonic-gate adcl 20(%rsi), %eax 24980Sstevel@tonic-gate.only40: 24990Sstevel@tonic-gate adcl 24(%rsi), %edx 25000Sstevel@tonic-gate.only36: 25010Sstevel@tonic-gate adcl 28(%rsi), %eax 25020Sstevel@tonic-gate.only32: 25030Sstevel@tonic-gate adcl 32(%rsi), %edx 25040Sstevel@tonic-gate.only28: 25050Sstevel@tonic-gate adcl 36(%rsi), %eax 25060Sstevel@tonic-gate.only24: 25070Sstevel@tonic-gate adcl 40(%rsi), %edx 25080Sstevel@tonic-gate.only20: 25090Sstevel@tonic-gate adcl 44(%rsi), %eax 25100Sstevel@tonic-gate.only16: 25110Sstevel@tonic-gate adcl 48(%rsi), %edx 25120Sstevel@tonic-gate.only12: 25130Sstevel@tonic-gate adcl 52(%rsi), %eax 25140Sstevel@tonic-gate.only8: 25150Sstevel@tonic-gate adcl 56(%rsi), %edx 25160Sstevel@tonic-gate.only4: 25170Sstevel@tonic-gate adcl 60(%rsi), %eax /* could be adding -1 and -1 with a carry */ 25180Sstevel@tonic-gate.only0: 25190Sstevel@tonic-gate adcl $0, %eax /* could be adding -1 in eax with a carry */ 25200Sstevel@tonic-gate adcl $0, %eax 25210Sstevel@tonic-gate 25220Sstevel@tonic-gate addq $64, %rsi 25230Sstevel@tonic-gate testl %ecx, %ecx 25240Sstevel@tonic-gate jnz .next_iter 25250Sstevel@tonic-gate 25260Sstevel@tonic-gate.ip_ocsum_done: 25270Sstevel@tonic-gate addl %eax, %edx 25280Sstevel@tonic-gate adcl $0, %edx 25290Sstevel@tonic-gate movl %edx, %eax /* form a 16 bit checksum by */ 25300Sstevel@tonic-gate shrl $16, %eax /* adding two halves of 32 bit checksum */ 25310Sstevel@tonic-gate addw %dx, %ax 25320Sstevel@tonic-gate adcw $0, %ax 25330Sstevel@tonic-gate andl $0xffff, %eax 25340Sstevel@tonic-gate leave 25350Sstevel@tonic-gate ret 25360Sstevel@tonic-gate 25370Sstevel@tonic-gate.ip_csum_notaligned: 25380Sstevel@tonic-gate xorl %edi, %edi 25390Sstevel@tonic-gate movw (%rsi), %di 25400Sstevel@tonic-gate addl %edi, %edx 25410Sstevel@tonic-gate adcl $0, %edx 25420Sstevel@tonic-gate addq $2, %rsi 25430Sstevel@tonic-gate decl %ecx 25440Sstevel@tonic-gate jmp .ip_csum_aligned 25450Sstevel@tonic-gate 25460Sstevel@tonic-gate.less_than_32: 25470Sstevel@tonic-gate addl $32, %ecx 25480Sstevel@tonic-gate testl $1, %ecx 25490Sstevel@tonic-gate jz .size_aligned 25500Sstevel@tonic-gate andl $0xfe, %ecx 25510Sstevel@tonic-gate movzwl (%rsi, %rcx, 2), %edi 25520Sstevel@tonic-gate addl %edi, %edx 25530Sstevel@tonic-gate adcl $0, %edx 25540Sstevel@tonic-gate.size_aligned: 25550Sstevel@tonic-gate movl %ecx, %edi 25560Sstevel@tonic-gate shrl $1, %ecx 25570Sstevel@tonic-gate shl $1, %edi 25580Sstevel@tonic-gate subq $64, %rdi 25590Sstevel@tonic-gate addq %rdi, %rsi 25600Sstevel@tonic-gate leaq .ip_ocsum_jmptbl(%rip), %rdi 25610Sstevel@tonic-gate leaq (%rdi, %rcx, 8), %rdi 25620Sstevel@tonic-gate xorl %ecx, %ecx 25630Sstevel@tonic-gate clc 25640Sstevel@tonic-gate jmp *(%rdi) 25650Sstevel@tonic-gate 25660Sstevel@tonic-gate .align 8 25670Sstevel@tonic-gate.ip_ocsum_jmptbl: 25680Sstevel@tonic-gate .quad .only0, .only4, .only8, .only12, .only16, .only20 25690Sstevel@tonic-gate .quad .only24, .only28, .only32, .only36, .only40, .only44 25700Sstevel@tonic-gate .quad .only48, .only52, .only56, .only60 25710Sstevel@tonic-gate SET_SIZE(ip_ocsum) 25720Sstevel@tonic-gate 25730Sstevel@tonic-gate#elif defined(__i386) 25740Sstevel@tonic-gate 25750Sstevel@tonic-gate ENTRY(ip_ocsum) 25760Sstevel@tonic-gate pushl %ebp 25770Sstevel@tonic-gate movl %esp, %ebp 25780Sstevel@tonic-gate pushl %ebx 25790Sstevel@tonic-gate pushl %esi 25800Sstevel@tonic-gate pushl %edi 25810Sstevel@tonic-gate movl 12(%ebp), %ecx /* count of half words */ 25820Sstevel@tonic-gate movl 16(%ebp), %edx /* partial checksum */ 25830Sstevel@tonic-gate movl 8(%ebp), %esi 25840Sstevel@tonic-gate xorl %eax, %eax 25850Sstevel@tonic-gate testl %ecx, %ecx 25860Sstevel@tonic-gate jz .ip_ocsum_done 25870Sstevel@tonic-gate 25880Sstevel@tonic-gate testl $3, %esi 25890Sstevel@tonic-gate jnz .ip_csum_notaligned 25900Sstevel@tonic-gate.ip_csum_aligned: 25910Sstevel@tonic-gate.next_iter: 25920Sstevel@tonic-gate subl $32, %ecx 25930Sstevel@tonic-gate jl .less_than_32 25940Sstevel@tonic-gate 25950Sstevel@tonic-gate addl 0(%esi), %edx 25960Sstevel@tonic-gate.only60: 25970Sstevel@tonic-gate adcl 4(%esi), %eax 25980Sstevel@tonic-gate.only56: 25990Sstevel@tonic-gate adcl 8(%esi), %edx 26000Sstevel@tonic-gate.only52: 26010Sstevel@tonic-gate adcl 12(%esi), %eax 26020Sstevel@tonic-gate.only48: 26030Sstevel@tonic-gate adcl 16(%esi), %edx 26040Sstevel@tonic-gate.only44: 26050Sstevel@tonic-gate adcl 20(%esi), %eax 26060Sstevel@tonic-gate.only40: 26070Sstevel@tonic-gate adcl 24(%esi), %edx 26080Sstevel@tonic-gate.only36: 26090Sstevel@tonic-gate adcl 28(%esi), %eax 26100Sstevel@tonic-gate.only32: 26110Sstevel@tonic-gate adcl 32(%esi), %edx 26120Sstevel@tonic-gate.only28: 26130Sstevel@tonic-gate adcl 36(%esi), %eax 26140Sstevel@tonic-gate.only24: 26150Sstevel@tonic-gate adcl 40(%esi), %edx 26160Sstevel@tonic-gate.only20: 26170Sstevel@tonic-gate adcl 44(%esi), %eax 26180Sstevel@tonic-gate.only16: 26190Sstevel@tonic-gate adcl 48(%esi), %edx 26200Sstevel@tonic-gate.only12: 26210Sstevel@tonic-gate adcl 52(%esi), %eax 26220Sstevel@tonic-gate.only8: 26230Sstevel@tonic-gate adcl 56(%esi), %edx 26240Sstevel@tonic-gate.only4: 26250Sstevel@tonic-gate adcl 60(%esi), %eax /* We could be adding -1 and -1 with a carry */ 26260Sstevel@tonic-gate.only0: 26270Sstevel@tonic-gate adcl $0, %eax /* we could be adding -1 in eax with a carry */ 26280Sstevel@tonic-gate adcl $0, %eax 26290Sstevel@tonic-gate 26300Sstevel@tonic-gate addl $64, %esi 26310Sstevel@tonic-gate andl %ecx, %ecx 26320Sstevel@tonic-gate jnz .next_iter 26330Sstevel@tonic-gate 26340Sstevel@tonic-gate.ip_ocsum_done: 26350Sstevel@tonic-gate addl %eax, %edx 26360Sstevel@tonic-gate adcl $0, %edx 26370Sstevel@tonic-gate movl %edx, %eax /* form a 16 bit checksum by */ 26380Sstevel@tonic-gate shrl $16, %eax /* adding two halves of 32 bit checksum */ 26390Sstevel@tonic-gate addw %dx, %ax 26400Sstevel@tonic-gate adcw $0, %ax 26410Sstevel@tonic-gate andl $0xffff, %eax 26420Sstevel@tonic-gate popl %edi /* restore registers */ 26430Sstevel@tonic-gate popl %esi 26440Sstevel@tonic-gate popl %ebx 26450Sstevel@tonic-gate leave 26460Sstevel@tonic-gate ret 26470Sstevel@tonic-gate 26480Sstevel@tonic-gate.ip_csum_notaligned: 26490Sstevel@tonic-gate xorl %edi, %edi 26500Sstevel@tonic-gate movw (%esi), %di 26510Sstevel@tonic-gate addl %edi, %edx 26520Sstevel@tonic-gate adcl $0, %edx 26530Sstevel@tonic-gate addl $2, %esi 26540Sstevel@tonic-gate decl %ecx 26550Sstevel@tonic-gate jmp .ip_csum_aligned 26560Sstevel@tonic-gate 26570Sstevel@tonic-gate.less_than_32: 26580Sstevel@tonic-gate addl $32, %ecx 26590Sstevel@tonic-gate testl $1, %ecx 26600Sstevel@tonic-gate jz .size_aligned 26610Sstevel@tonic-gate andl $0xfe, %ecx 26620Sstevel@tonic-gate movzwl (%esi, %ecx, 2), %edi 26630Sstevel@tonic-gate addl %edi, %edx 26640Sstevel@tonic-gate adcl $0, %edx 26650Sstevel@tonic-gate.size_aligned: 26660Sstevel@tonic-gate movl %ecx, %edi 26670Sstevel@tonic-gate shrl $1, %ecx 26680Sstevel@tonic-gate shl $1, %edi 26690Sstevel@tonic-gate subl $64, %edi 26700Sstevel@tonic-gate addl %edi, %esi 26710Sstevel@tonic-gate movl $.ip_ocsum_jmptbl, %edi 26720Sstevel@tonic-gate lea (%edi, %ecx, 4), %edi 26730Sstevel@tonic-gate xorl %ecx, %ecx 26740Sstevel@tonic-gate clc 26750Sstevel@tonic-gate jmp *(%edi) 26760Sstevel@tonic-gate SET_SIZE(ip_ocsum) 26770Sstevel@tonic-gate 26780Sstevel@tonic-gate .data 26790Sstevel@tonic-gate .align 4 26800Sstevel@tonic-gate 26810Sstevel@tonic-gate.ip_ocsum_jmptbl: 26820Sstevel@tonic-gate .long .only0, .only4, .only8, .only12, .only16, .only20 26830Sstevel@tonic-gate .long .only24, .only28, .only32, .only36, .only40, .only44 26840Sstevel@tonic-gate .long .only48, .only52, .only56, .only60 26850Sstevel@tonic-gate 26860Sstevel@tonic-gate 26870Sstevel@tonic-gate#endif /* __i386 */ 26880Sstevel@tonic-gate#endif /* __lint */ 26890Sstevel@tonic-gate 26900Sstevel@tonic-gate/* 26910Sstevel@tonic-gate * multiply two long numbers and yield a u_longlong_t result, callable from C. 26920Sstevel@tonic-gate * Provided to manipulate hrtime_t values. 26930Sstevel@tonic-gate */ 26940Sstevel@tonic-gate#if defined(__lint) 26950Sstevel@tonic-gate 26960Sstevel@tonic-gate/* result = a * b; */ 26970Sstevel@tonic-gate 26980Sstevel@tonic-gate/* ARGSUSED */ 26990Sstevel@tonic-gateunsigned long long 27000Sstevel@tonic-gatemul32(uint_t a, uint_t b) 27010Sstevel@tonic-gate{ return (0); } 27020Sstevel@tonic-gate 27030Sstevel@tonic-gate#else /* __lint */ 27040Sstevel@tonic-gate 27050Sstevel@tonic-gate#if defined(__amd64) 27060Sstevel@tonic-gate 27070Sstevel@tonic-gate ENTRY(mul32) 27080Sstevel@tonic-gate xorl %edx, %edx /* XX64 joe, paranoia? */ 27090Sstevel@tonic-gate movl %edi, %eax 27100Sstevel@tonic-gate mull %esi 27110Sstevel@tonic-gate shlq $32, %rdx 27120Sstevel@tonic-gate orq %rdx, %rax 27130Sstevel@tonic-gate ret 27140Sstevel@tonic-gate SET_SIZE(mul32) 27150Sstevel@tonic-gate 27160Sstevel@tonic-gate#elif defined(__i386) 27170Sstevel@tonic-gate 27180Sstevel@tonic-gate ENTRY(mul32) 27190Sstevel@tonic-gate movl 8(%esp), %eax 27200Sstevel@tonic-gate movl 4(%esp), %ecx 27210Sstevel@tonic-gate mull %ecx 27220Sstevel@tonic-gate ret 27230Sstevel@tonic-gate SET_SIZE(mul32) 27240Sstevel@tonic-gate 27250Sstevel@tonic-gate#endif /* __i386 */ 27260Sstevel@tonic-gate#endif /* __lint */ 27270Sstevel@tonic-gate 27280Sstevel@tonic-gate#if defined(notused) 27290Sstevel@tonic-gate#if defined(__lint) 27300Sstevel@tonic-gate/* ARGSUSED */ 27310Sstevel@tonic-gatevoid 27320Sstevel@tonic-gateload_pte64(uint64_t *pte, uint64_t pte_value) 27330Sstevel@tonic-gate{} 27340Sstevel@tonic-gate#else /* __lint */ 27350Sstevel@tonic-gate .globl load_pte64 27360Sstevel@tonic-gateload_pte64: 27370Sstevel@tonic-gate movl 4(%esp), %eax 27380Sstevel@tonic-gate movl 8(%esp), %ecx 27390Sstevel@tonic-gate movl 12(%esp), %edx 27400Sstevel@tonic-gate movl %edx, 4(%eax) 27410Sstevel@tonic-gate movl %ecx, (%eax) 27420Sstevel@tonic-gate ret 27430Sstevel@tonic-gate#endif /* __lint */ 27440Sstevel@tonic-gate#endif /* notused */ 27450Sstevel@tonic-gate 27460Sstevel@tonic-gate#if defined(__lint) 27470Sstevel@tonic-gate 27480Sstevel@tonic-gate/*ARGSUSED*/ 27490Sstevel@tonic-gatevoid 27500Sstevel@tonic-gatescan_memory(caddr_t addr, size_t size) 27510Sstevel@tonic-gate{} 27520Sstevel@tonic-gate 27530Sstevel@tonic-gate#else /* __lint */ 27540Sstevel@tonic-gate 27550Sstevel@tonic-gate#if defined(__amd64) 27560Sstevel@tonic-gate 27570Sstevel@tonic-gate ENTRY(scan_memory) 27580Sstevel@tonic-gate shrq $3, %rsi /* convert %rsi from byte to quadword count */ 27590Sstevel@tonic-gate jz .scanm_done 27600Sstevel@tonic-gate movq %rsi, %rcx /* move count into rep control register */ 27610Sstevel@tonic-gate movq %rdi, %rsi /* move addr into lodsq control reg. */ 27620Sstevel@tonic-gate rep lodsq /* scan the memory range */ 27630Sstevel@tonic-gate.scanm_done: 2764545Skalai rep; ret /* use 2 byte return instruction when branch target */ 2765545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 27660Sstevel@tonic-gate SET_SIZE(scan_memory) 27670Sstevel@tonic-gate 27680Sstevel@tonic-gate#elif defined(__i386) 27690Sstevel@tonic-gate 27700Sstevel@tonic-gate ENTRY(scan_memory) 27710Sstevel@tonic-gate pushl %ecx 27720Sstevel@tonic-gate pushl %esi 27730Sstevel@tonic-gate movl 16(%esp), %ecx /* move 2nd arg into rep control register */ 27740Sstevel@tonic-gate shrl $2, %ecx /* convert from byte count to word count */ 27750Sstevel@tonic-gate jz .scanm_done 27760Sstevel@tonic-gate movl 12(%esp), %esi /* move 1st arg into lodsw control register */ 27770Sstevel@tonic-gate .byte 0xf3 /* rep prefix. lame assembler. sigh. */ 27780Sstevel@tonic-gate lodsl 27790Sstevel@tonic-gate.scanm_done: 27800Sstevel@tonic-gate popl %esi 27810Sstevel@tonic-gate popl %ecx 27820Sstevel@tonic-gate ret 27830Sstevel@tonic-gate SET_SIZE(scan_memory) 27840Sstevel@tonic-gate 27850Sstevel@tonic-gate#endif /* __i386 */ 27860Sstevel@tonic-gate#endif /* __lint */ 27870Sstevel@tonic-gate 27880Sstevel@tonic-gate 27890Sstevel@tonic-gate#if defined(__lint) 27900Sstevel@tonic-gate 27910Sstevel@tonic-gate/*ARGSUSED */ 27920Sstevel@tonic-gateint 27930Sstevel@tonic-gatelowbit(ulong_t i) 27940Sstevel@tonic-gate{ return (0); } 27950Sstevel@tonic-gate 27960Sstevel@tonic-gate#else /* __lint */ 27970Sstevel@tonic-gate 27980Sstevel@tonic-gate#if defined(__amd64) 27990Sstevel@tonic-gate 28000Sstevel@tonic-gate ENTRY(lowbit) 28010Sstevel@tonic-gate movl $-1, %eax 28020Sstevel@tonic-gate bsfq %rdi, %rax 28030Sstevel@tonic-gate incl %eax 28040Sstevel@tonic-gate ret 28050Sstevel@tonic-gate SET_SIZE(lowbit) 28060Sstevel@tonic-gate 28070Sstevel@tonic-gate#elif defined(__i386) 28080Sstevel@tonic-gate 28090Sstevel@tonic-gate ENTRY(lowbit) 28100Sstevel@tonic-gate movl $-1, %eax 28110Sstevel@tonic-gate bsfl 4(%esp), %eax 28120Sstevel@tonic-gate incl %eax 28130Sstevel@tonic-gate ret 28140Sstevel@tonic-gate SET_SIZE(lowbit) 28150Sstevel@tonic-gate 28160Sstevel@tonic-gate#endif /* __i386 */ 28170Sstevel@tonic-gate#endif /* __lint */ 28180Sstevel@tonic-gate 28190Sstevel@tonic-gate#if defined(__lint) 28200Sstevel@tonic-gate 28210Sstevel@tonic-gate/*ARGSUSED*/ 28220Sstevel@tonic-gateint 28230Sstevel@tonic-gatehighbit(ulong_t i) 28240Sstevel@tonic-gate{ return (0); } 28250Sstevel@tonic-gate 28260Sstevel@tonic-gate#else /* __lint */ 28270Sstevel@tonic-gate 28280Sstevel@tonic-gate#if defined(__amd64) 28290Sstevel@tonic-gate 28300Sstevel@tonic-gate ENTRY(highbit) 28310Sstevel@tonic-gate movl $-1, %eax 28320Sstevel@tonic-gate bsrq %rdi, %rax 28330Sstevel@tonic-gate incl %eax 28340Sstevel@tonic-gate ret 28350Sstevel@tonic-gate SET_SIZE(highbit) 28360Sstevel@tonic-gate 28370Sstevel@tonic-gate#elif defined(__i386) 28380Sstevel@tonic-gate 28390Sstevel@tonic-gate ENTRY(highbit) 28400Sstevel@tonic-gate movl $-1, %eax 28410Sstevel@tonic-gate bsrl 4(%esp), %eax 28420Sstevel@tonic-gate incl %eax 28430Sstevel@tonic-gate ret 28440Sstevel@tonic-gate SET_SIZE(highbit) 28450Sstevel@tonic-gate 28460Sstevel@tonic-gate#endif /* __i386 */ 28470Sstevel@tonic-gate#endif /* __lint */ 28480Sstevel@tonic-gate 28490Sstevel@tonic-gate#if defined(__lint) 28500Sstevel@tonic-gate 28510Sstevel@tonic-gate/*ARGSUSED*/ 28520Sstevel@tonic-gateuint64_t 2853770Skucharskrdmsr(uint_t r) 28540Sstevel@tonic-gate{ return (0); } 28550Sstevel@tonic-gate 28560Sstevel@tonic-gate/*ARGSUSED*/ 28570Sstevel@tonic-gatevoid 2858770Skucharskwrmsr(uint_t r, const uint64_t val) 28590Sstevel@tonic-gate{} 28600Sstevel@tonic-gate 28611582Skchow/*ARGSUSED*/ 28621582Skchowuint64_t 28631582Skchowxrdmsr(uint_t r) 28641582Skchow{ return (0); } 28651582Skchow 28661582Skchow/*ARGSUSED*/ 28671582Skchowvoid 28681582Skchowxwrmsr(uint_t r, const uint64_t val) 28691582Skchow{} 28701582Skchow 28710Sstevel@tonic-gatevoid 28720Sstevel@tonic-gateinvalidate_cache(void) 28730Sstevel@tonic-gate{} 28740Sstevel@tonic-gate 2875*13134Skuriakose.kuruvilla@oracle.com/*ARGSUSED*/ 2876*13134Skuriakose.kuruvilla@oracle.comuint64_t 2877*13134Skuriakose.kuruvilla@oracle.comget_xcr(uint_t r) 2878*13134Skuriakose.kuruvilla@oracle.com{ return (0); } 2879*13134Skuriakose.kuruvilla@oracle.com 2880*13134Skuriakose.kuruvilla@oracle.com/*ARGSUSED*/ 2881*13134Skuriakose.kuruvilla@oracle.comvoid 2882*13134Skuriakose.kuruvilla@oracle.comset_xcr(uint_t r, const uint64_t val) 2883*13134Skuriakose.kuruvilla@oracle.com{} 2884*13134Skuriakose.kuruvilla@oracle.com 28850Sstevel@tonic-gate#else /* __lint */ 28860Sstevel@tonic-gate 28871582Skchow#define XMSR_ACCESS_VAL $0x9c5a203a 28881582Skchow 28890Sstevel@tonic-gate#if defined(__amd64) 28903446Smrj 28910Sstevel@tonic-gate ENTRY(rdmsr) 28920Sstevel@tonic-gate movl %edi, %ecx 28930Sstevel@tonic-gate rdmsr 28940Sstevel@tonic-gate shlq $32, %rdx 28950Sstevel@tonic-gate orq %rdx, %rax 28960Sstevel@tonic-gate ret 28970Sstevel@tonic-gate SET_SIZE(rdmsr) 28980Sstevel@tonic-gate 28990Sstevel@tonic-gate ENTRY(wrmsr) 2900770Skucharsk movq %rsi, %rdx 2901770Skucharsk shrq $32, %rdx 2902770Skucharsk movl %esi, %eax 29030Sstevel@tonic-gate movl %edi, %ecx 29040Sstevel@tonic-gate wrmsr 29050Sstevel@tonic-gate ret 29060Sstevel@tonic-gate SET_SIZE(wrmsr) 29070Sstevel@tonic-gate 29081582Skchow ENTRY(xrdmsr) 29093446Smrj pushq %rbp 29103446Smrj movq %rsp, %rbp 29111582Skchow movl %edi, %ecx 29121582Skchow movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */ 29131582Skchow rdmsr 29141582Skchow shlq $32, %rdx 29151582Skchow orq %rdx, %rax 29163446Smrj leave 29171582Skchow ret 29181582Skchow SET_SIZE(xrdmsr) 29191582Skchow 29201582Skchow ENTRY(xwrmsr) 29213446Smrj pushq %rbp 29223446Smrj movq %rsp, %rbp 29231582Skchow movl %edi, %ecx 29241582Skchow movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */ 29251582Skchow movq %rsi, %rdx 29261582Skchow shrq $32, %rdx 29271582Skchow movl %esi, %eax 29281582Skchow wrmsr 29293446Smrj leave 29301582Skchow ret 29311582Skchow SET_SIZE(xwrmsr) 2932*13134Skuriakose.kuruvilla@oracle.com 2933*13134Skuriakose.kuruvilla@oracle.com ENTRY(get_xcr) 2934*13134Skuriakose.kuruvilla@oracle.com movl %edi, %ecx 2935*13134Skuriakose.kuruvilla@oracle.com #xgetbv 2936*13134Skuriakose.kuruvilla@oracle.com .byte 0x0f,0x01,0xd0 2937*13134Skuriakose.kuruvilla@oracle.com shlq $32, %rdx 2938*13134Skuriakose.kuruvilla@oracle.com orq %rdx, %rax 2939*13134Skuriakose.kuruvilla@oracle.com ret 2940*13134Skuriakose.kuruvilla@oracle.com SET_SIZE(get_xcr) 2941*13134Skuriakose.kuruvilla@oracle.com 2942*13134Skuriakose.kuruvilla@oracle.com ENTRY(set_xcr) 2943*13134Skuriakose.kuruvilla@oracle.com movq %rsi, %rdx 2944*13134Skuriakose.kuruvilla@oracle.com shrq $32, %rdx 2945*13134Skuriakose.kuruvilla@oracle.com movl %esi, %eax 2946*13134Skuriakose.kuruvilla@oracle.com movl %edi, %ecx 2947*13134Skuriakose.kuruvilla@oracle.com #xsetbv 2948*13134Skuriakose.kuruvilla@oracle.com .byte 0x0f,0x01,0xd1 2949*13134Skuriakose.kuruvilla@oracle.com ret 2950*13134Skuriakose.kuruvilla@oracle.com SET_SIZE(set_xcr) 2951*13134Skuriakose.kuruvilla@oracle.com 29520Sstevel@tonic-gate#elif defined(__i386) 29530Sstevel@tonic-gate 29540Sstevel@tonic-gate ENTRY(rdmsr) 29550Sstevel@tonic-gate movl 4(%esp), %ecx 29560Sstevel@tonic-gate rdmsr 29570Sstevel@tonic-gate ret 29580Sstevel@tonic-gate SET_SIZE(rdmsr) 29590Sstevel@tonic-gate 29600Sstevel@tonic-gate ENTRY(wrmsr) 29610Sstevel@tonic-gate movl 4(%esp), %ecx 2962770Skucharsk movl 8(%esp), %eax 2963770Skucharsk movl 12(%esp), %edx 29640Sstevel@tonic-gate wrmsr 29650Sstevel@tonic-gate ret 29660Sstevel@tonic-gate SET_SIZE(wrmsr) 29670Sstevel@tonic-gate 29681582Skchow ENTRY(xrdmsr) 29693446Smrj pushl %ebp 29703446Smrj movl %esp, %ebp 29713446Smrj movl 8(%esp), %ecx 29723446Smrj pushl %edi 29731582Skchow movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */ 29741582Skchow rdmsr 29753446Smrj popl %edi 29763446Smrj leave 29771582Skchow ret 29781582Skchow SET_SIZE(xrdmsr) 29791582Skchow 29801582Skchow ENTRY(xwrmsr) 29813446Smrj pushl %ebp 29823446Smrj movl %esp, %ebp 29833446Smrj movl 8(%esp), %ecx 29843446Smrj movl 12(%esp), %eax 29853446Smrj movl 16(%esp), %edx 29863446Smrj pushl %edi 29871582Skchow movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */ 29881582Skchow wrmsr 29893446Smrj popl %edi 29903446Smrj leave 29911582Skchow ret 29921582Skchow SET_SIZE(xwrmsr) 29931582Skchow 2994*13134Skuriakose.kuruvilla@oracle.com ENTRY(get_xcr) 2995*13134Skuriakose.kuruvilla@oracle.com movl 4(%esp), %ecx 2996*13134Skuriakose.kuruvilla@oracle.com #xgetbv 2997*13134Skuriakose.kuruvilla@oracle.com .byte 0x0f,0x01,0xd0 2998*13134Skuriakose.kuruvilla@oracle.com ret 2999*13134Skuriakose.kuruvilla@oracle.com SET_SIZE(get_xcr) 3000*13134Skuriakose.kuruvilla@oracle.com 3001*13134Skuriakose.kuruvilla@oracle.com ENTRY(set_xcr) 3002*13134Skuriakose.kuruvilla@oracle.com movl 4(%esp), %ecx 3003*13134Skuriakose.kuruvilla@oracle.com movl 8(%esp), %eax 3004*13134Skuriakose.kuruvilla@oracle.com movl 12(%esp), %edx 3005*13134Skuriakose.kuruvilla@oracle.com #xsetbv 3006*13134Skuriakose.kuruvilla@oracle.com .byte 0x0f,0x01,0xd1 3007*13134Skuriakose.kuruvilla@oracle.com ret 3008*13134Skuriakose.kuruvilla@oracle.com SET_SIZE(set_xcr) 3009*13134Skuriakose.kuruvilla@oracle.com 30100Sstevel@tonic-gate#endif /* __i386 */ 30110Sstevel@tonic-gate 30120Sstevel@tonic-gate ENTRY(invalidate_cache) 30130Sstevel@tonic-gate wbinvd 30140Sstevel@tonic-gate ret 30150Sstevel@tonic-gate SET_SIZE(invalidate_cache) 30160Sstevel@tonic-gate 30170Sstevel@tonic-gate#endif /* __lint */ 30180Sstevel@tonic-gate 30190Sstevel@tonic-gate#if defined(__lint) 30200Sstevel@tonic-gate 30210Sstevel@tonic-gate/*ARGSUSED*/ 30223446Smrjvoid 30233446Smrjgetcregs(struct cregs *crp) 30240Sstevel@tonic-gate{} 30250Sstevel@tonic-gate 30260Sstevel@tonic-gate#else /* __lint */ 30270Sstevel@tonic-gate 30280Sstevel@tonic-gate#if defined(__amd64) 30290Sstevel@tonic-gate 30303446Smrj ENTRY_NP(getcregs) 30315084Sjohnlev#if defined(__xpv) 30325084Sjohnlev /* 30335084Sjohnlev * Only a few of the hardware control registers or descriptor tables 30345084Sjohnlev * are directly accessible to us, so just zero the structure. 30355084Sjohnlev * 30365084Sjohnlev * XXPV Perhaps it would be helpful for the hypervisor to return 30375084Sjohnlev * virtualized versions of these for post-mortem use. 30385084Sjohnlev * (Need to reevaluate - perhaps it already does!) 30395084Sjohnlev */ 30405084Sjohnlev pushq %rdi /* save *crp */ 30415084Sjohnlev movq $CREGSZ, %rsi 30425084Sjohnlev call bzero 30435084Sjohnlev popq %rdi 30445084Sjohnlev 30455084Sjohnlev /* 30465084Sjohnlev * Dump what limited information we can 30475084Sjohnlev */ 30485084Sjohnlev movq %cr0, %rax 30495084Sjohnlev movq %rax, CREG_CR0(%rdi) /* cr0 */ 30505084Sjohnlev movq %cr2, %rax 30515084Sjohnlev movq %rax, CREG_CR2(%rdi) /* cr2 */ 30525084Sjohnlev movq %cr3, %rax 30535084Sjohnlev movq %rax, CREG_CR3(%rdi) /* cr3 */ 30545084Sjohnlev movq %cr4, %rax 30555084Sjohnlev movq %rax, CREG_CR4(%rdi) /* cr4 */ 30565084Sjohnlev 30575084Sjohnlev#else /* __xpv */ 30583446Smrj 30590Sstevel@tonic-gate#define GETMSR(r, off, d) \ 30600Sstevel@tonic-gate movl $r, %ecx; \ 30610Sstevel@tonic-gate rdmsr; \ 30620Sstevel@tonic-gate movl %eax, off(d); \ 30630Sstevel@tonic-gate movl %edx, off+4(d) 30640Sstevel@tonic-gate 30650Sstevel@tonic-gate xorl %eax, %eax 30660Sstevel@tonic-gate movq %rax, CREG_GDT+8(%rdi) 30670Sstevel@tonic-gate sgdt CREG_GDT(%rdi) /* 10 bytes */ 30680Sstevel@tonic-gate movq %rax, CREG_IDT+8(%rdi) 30690Sstevel@tonic-gate sidt CREG_IDT(%rdi) /* 10 bytes */ 30700Sstevel@tonic-gate movq %rax, CREG_LDT(%rdi) 30710Sstevel@tonic-gate sldt CREG_LDT(%rdi) /* 2 bytes */ 30720Sstevel@tonic-gate movq %rax, CREG_TASKR(%rdi) 30730Sstevel@tonic-gate str CREG_TASKR(%rdi) /* 2 bytes */ 30740Sstevel@tonic-gate movq %cr0, %rax 30750Sstevel@tonic-gate movq %rax, CREG_CR0(%rdi) /* cr0 */ 30760Sstevel@tonic-gate movq %cr2, %rax 30770Sstevel@tonic-gate movq %rax, CREG_CR2(%rdi) /* cr2 */ 30780Sstevel@tonic-gate movq %cr3, %rax 30790Sstevel@tonic-gate movq %rax, CREG_CR3(%rdi) /* cr3 */ 30800Sstevel@tonic-gate movq %cr4, %rax 30813446Smrj movq %rax, CREG_CR4(%rdi) /* cr4 */ 30820Sstevel@tonic-gate movq %cr8, %rax 30830Sstevel@tonic-gate movq %rax, CREG_CR8(%rdi) /* cr8 */ 30840Sstevel@tonic-gate GETMSR(MSR_AMD_KGSBASE, CREG_KGSBASE, %rdi) 30850Sstevel@tonic-gate GETMSR(MSR_AMD_EFER, CREG_EFER, %rdi) 30865084Sjohnlev#endif /* __xpv */ 30873446Smrj ret 30880Sstevel@tonic-gate SET_SIZE(getcregs) 30890Sstevel@tonic-gate 30900Sstevel@tonic-gate#undef GETMSR 30910Sstevel@tonic-gate 30920Sstevel@tonic-gate#elif defined(__i386) 30930Sstevel@tonic-gate 30940Sstevel@tonic-gate ENTRY_NP(getcregs) 30955084Sjohnlev#if defined(__xpv) 30965084Sjohnlev /* 30975084Sjohnlev * Only a few of the hardware control registers or descriptor tables 30985084Sjohnlev * are directly accessible to us, so just zero the structure. 30995084Sjohnlev * 31005084Sjohnlev * XXPV Perhaps it would be helpful for the hypervisor to return 31015084Sjohnlev * virtualized versions of these for post-mortem use. 31025084Sjohnlev * (Need to reevaluate - perhaps it already does!) 31035084Sjohnlev */ 31045084Sjohnlev movl 4(%esp), %edx 31055084Sjohnlev pushl $CREGSZ 31065084Sjohnlev pushl %edx 31075084Sjohnlev call bzero 31085084Sjohnlev addl $8, %esp 31095084Sjohnlev movl 4(%esp), %edx 31105084Sjohnlev 31115084Sjohnlev /* 31125084Sjohnlev * Dump what limited information we can 31135084Sjohnlev */ 31145084Sjohnlev movl %cr0, %eax 31155084Sjohnlev movl %eax, CREG_CR0(%edx) /* cr0 */ 31165084Sjohnlev movl %cr2, %eax 31175084Sjohnlev movl %eax, CREG_CR2(%edx) /* cr2 */ 31185084Sjohnlev movl %cr3, %eax 31195084Sjohnlev movl %eax, CREG_CR3(%edx) /* cr3 */ 31205084Sjohnlev movl %cr4, %eax 31215084Sjohnlev movl %eax, CREG_CR4(%edx) /* cr4 */ 31225084Sjohnlev 31235084Sjohnlev#else /* __xpv */ 31245084Sjohnlev 31250Sstevel@tonic-gate movl 4(%esp), %edx 31260Sstevel@tonic-gate movw $0, CREG_GDT+6(%edx) 31270Sstevel@tonic-gate movw $0, CREG_IDT+6(%edx) 31280Sstevel@tonic-gate sgdt CREG_GDT(%edx) /* gdt */ 31290Sstevel@tonic-gate sidt CREG_IDT(%edx) /* idt */ 31300Sstevel@tonic-gate sldt CREG_LDT(%edx) /* ldt */ 31310Sstevel@tonic-gate str CREG_TASKR(%edx) /* task */ 31320Sstevel@tonic-gate movl %cr0, %eax 31330Sstevel@tonic-gate movl %eax, CREG_CR0(%edx) /* cr0 */ 31340Sstevel@tonic-gate movl %cr2, %eax 31350Sstevel@tonic-gate movl %eax, CREG_CR2(%edx) /* cr2 */ 31360Sstevel@tonic-gate movl %cr3, %eax 31370Sstevel@tonic-gate movl %eax, CREG_CR3(%edx) /* cr3 */ 313812826Skuriakose.kuruvilla@oracle.com bt $X86FSET_LARGEPAGE, x86_featureset 313912826Skuriakose.kuruvilla@oracle.com jnc .nocr4 31400Sstevel@tonic-gate movl %cr4, %eax 31410Sstevel@tonic-gate movl %eax, CREG_CR4(%edx) /* cr4 */ 31420Sstevel@tonic-gate jmp .skip 31430Sstevel@tonic-gate.nocr4: 31440Sstevel@tonic-gate movl $0, CREG_CR4(%edx) 31450Sstevel@tonic-gate.skip: 31465084Sjohnlev#endif 31473446Smrj ret 31480Sstevel@tonic-gate SET_SIZE(getcregs) 31490Sstevel@tonic-gate 31500Sstevel@tonic-gate#endif /* __i386 */ 31510Sstevel@tonic-gate#endif /* __lint */ 31520Sstevel@tonic-gate 31530Sstevel@tonic-gate 31540Sstevel@tonic-gate/* 31550Sstevel@tonic-gate * A panic trigger is a word which is updated atomically and can only be set 31560Sstevel@tonic-gate * once. We atomically store 0xDEFACEDD and load the old value. If the 31570Sstevel@tonic-gate * previous value was 0, we succeed and return 1; otherwise return 0. 31580Sstevel@tonic-gate * This allows a partially corrupt trigger to still trigger correctly. DTrace 31590Sstevel@tonic-gate * has its own version of this function to allow it to panic correctly from 31600Sstevel@tonic-gate * probe context. 31610Sstevel@tonic-gate */ 31620Sstevel@tonic-gate#if defined(__lint) 31630Sstevel@tonic-gate 31640Sstevel@tonic-gate/*ARGSUSED*/ 31650Sstevel@tonic-gateint 31660Sstevel@tonic-gatepanic_trigger(int *tp) 31670Sstevel@tonic-gate{ return (0); } 31680Sstevel@tonic-gate 31690Sstevel@tonic-gate/*ARGSUSED*/ 31700Sstevel@tonic-gateint 31710Sstevel@tonic-gatedtrace_panic_trigger(int *tp) 31720Sstevel@tonic-gate{ return (0); } 31730Sstevel@tonic-gate 31740Sstevel@tonic-gate#else /* __lint */ 31750Sstevel@tonic-gate 31760Sstevel@tonic-gate#if defined(__amd64) 31770Sstevel@tonic-gate 31780Sstevel@tonic-gate ENTRY_NP(panic_trigger) 31790Sstevel@tonic-gate xorl %eax, %eax 31800Sstevel@tonic-gate movl $0xdefacedd, %edx 31810Sstevel@tonic-gate lock 31820Sstevel@tonic-gate xchgl %edx, (%rdi) 31830Sstevel@tonic-gate cmpl $0, %edx 31840Sstevel@tonic-gate je 0f 31850Sstevel@tonic-gate movl $0, %eax 31860Sstevel@tonic-gate ret 31870Sstevel@tonic-gate0: movl $1, %eax 31880Sstevel@tonic-gate ret 31890Sstevel@tonic-gate SET_SIZE(panic_trigger) 31900Sstevel@tonic-gate 31910Sstevel@tonic-gate ENTRY_NP(dtrace_panic_trigger) 31920Sstevel@tonic-gate xorl %eax, %eax 31930Sstevel@tonic-gate movl $0xdefacedd, %edx 31940Sstevel@tonic-gate lock 31950Sstevel@tonic-gate xchgl %edx, (%rdi) 31960Sstevel@tonic-gate cmpl $0, %edx 31970Sstevel@tonic-gate je 0f 31980Sstevel@tonic-gate movl $0, %eax 31990Sstevel@tonic-gate ret 32000Sstevel@tonic-gate0: movl $1, %eax 32010Sstevel@tonic-gate ret 32020Sstevel@tonic-gate SET_SIZE(dtrace_panic_trigger) 32030Sstevel@tonic-gate 32040Sstevel@tonic-gate#elif defined(__i386) 32050Sstevel@tonic-gate 32060Sstevel@tonic-gate ENTRY_NP(panic_trigger) 32070Sstevel@tonic-gate movl 4(%esp), %edx / %edx = address of trigger 32080Sstevel@tonic-gate movl $0xdefacedd, %eax / %eax = 0xdefacedd 32090Sstevel@tonic-gate lock / assert lock 32100Sstevel@tonic-gate xchgl %eax, (%edx) / exchange %eax and the trigger 32110Sstevel@tonic-gate cmpl $0, %eax / if (%eax == 0x0) 32120Sstevel@tonic-gate je 0f / return (1); 32130Sstevel@tonic-gate movl $0, %eax / else 32140Sstevel@tonic-gate ret / return (0); 32150Sstevel@tonic-gate0: movl $1, %eax 32160Sstevel@tonic-gate ret 32170Sstevel@tonic-gate SET_SIZE(panic_trigger) 32180Sstevel@tonic-gate 32190Sstevel@tonic-gate ENTRY_NP(dtrace_panic_trigger) 32200Sstevel@tonic-gate movl 4(%esp), %edx / %edx = address of trigger 32210Sstevel@tonic-gate movl $0xdefacedd, %eax / %eax = 0xdefacedd 32220Sstevel@tonic-gate lock / assert lock 32230Sstevel@tonic-gate xchgl %eax, (%edx) / exchange %eax and the trigger 32240Sstevel@tonic-gate cmpl $0, %eax / if (%eax == 0x0) 32250Sstevel@tonic-gate je 0f / return (1); 32260Sstevel@tonic-gate movl $0, %eax / else 32270Sstevel@tonic-gate ret / return (0); 32280Sstevel@tonic-gate0: movl $1, %eax 32290Sstevel@tonic-gate ret 32300Sstevel@tonic-gate SET_SIZE(dtrace_panic_trigger) 32310Sstevel@tonic-gate 32320Sstevel@tonic-gate#endif /* __i386 */ 32330Sstevel@tonic-gate#endif /* __lint */ 32340Sstevel@tonic-gate 32350Sstevel@tonic-gate/* 32360Sstevel@tonic-gate * The panic() and cmn_err() functions invoke vpanic() as a common entry point 32370Sstevel@tonic-gate * into the panic code implemented in panicsys(). vpanic() is responsible 32380Sstevel@tonic-gate * for passing through the format string and arguments, and constructing a 32390Sstevel@tonic-gate * regs structure on the stack into which it saves the current register 32400Sstevel@tonic-gate * values. If we are not dying due to a fatal trap, these registers will 32410Sstevel@tonic-gate * then be preserved in panicbuf as the current processor state. Before 32420Sstevel@tonic-gate * invoking panicsys(), vpanic() activates the first panic trigger (see 32430Sstevel@tonic-gate * common/os/panic.c) and switches to the panic_stack if successful. Note that 32440Sstevel@tonic-gate * DTrace takes a slightly different panic path if it must panic from probe 32450Sstevel@tonic-gate * context. Instead of calling panic, it calls into dtrace_vpanic(), which 32460Sstevel@tonic-gate * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and 32470Sstevel@tonic-gate * branches back into vpanic(). 32480Sstevel@tonic-gate */ 32490Sstevel@tonic-gate#if defined(__lint) 32500Sstevel@tonic-gate 32510Sstevel@tonic-gate/*ARGSUSED*/ 32520Sstevel@tonic-gatevoid 32530Sstevel@tonic-gatevpanic(const char *format, va_list alist) 32540Sstevel@tonic-gate{} 32550Sstevel@tonic-gate 32560Sstevel@tonic-gate/*ARGSUSED*/ 32570Sstevel@tonic-gatevoid 32580Sstevel@tonic-gatedtrace_vpanic(const char *format, va_list alist) 32590Sstevel@tonic-gate{} 32600Sstevel@tonic-gate 32610Sstevel@tonic-gate#else /* __lint */ 32620Sstevel@tonic-gate 32630Sstevel@tonic-gate#if defined(__amd64) 32640Sstevel@tonic-gate 32650Sstevel@tonic-gate ENTRY_NP(vpanic) /* Initial stack layout: */ 32660Sstevel@tonic-gate 32670Sstevel@tonic-gate pushq %rbp /* | %rip | 0x60 */ 32680Sstevel@tonic-gate movq %rsp, %rbp /* | %rbp | 0x58 */ 32690Sstevel@tonic-gate pushfq /* | rfl | 0x50 */ 32700Sstevel@tonic-gate pushq %r11 /* | %r11 | 0x48 */ 32710Sstevel@tonic-gate pushq %r10 /* | %r10 | 0x40 */ 32720Sstevel@tonic-gate pushq %rbx /* | %rbx | 0x38 */ 32730Sstevel@tonic-gate pushq %rax /* | %rax | 0x30 */ 32740Sstevel@tonic-gate pushq %r9 /* | %r9 | 0x28 */ 32750Sstevel@tonic-gate pushq %r8 /* | %r8 | 0x20 */ 32760Sstevel@tonic-gate pushq %rcx /* | %rcx | 0x18 */ 32770Sstevel@tonic-gate pushq %rdx /* | %rdx | 0x10 */ 32780Sstevel@tonic-gate pushq %rsi /* | %rsi | 0x8 alist */ 32790Sstevel@tonic-gate pushq %rdi /* | %rdi | 0x0 format */ 32800Sstevel@tonic-gate 32810Sstevel@tonic-gate movq %rsp, %rbx /* %rbx = current %rsp */ 32820Sstevel@tonic-gate 32830Sstevel@tonic-gate leaq panic_quiesce(%rip), %rdi /* %rdi = &panic_quiesce */ 32840Sstevel@tonic-gate call panic_trigger /* %eax = panic_trigger() */ 32850Sstevel@tonic-gate 32860Sstevel@tonic-gatevpanic_common: 32871784Sgavinm /* 32881784Sgavinm * The panic_trigger result is in %eax from the call above, and 32891784Sgavinm * dtrace_panic places it in %eax before branching here. 32901784Sgavinm * The rdmsr instructions that follow below will clobber %eax so 32911784Sgavinm * we stash the panic_trigger result in %r11d. 32921784Sgavinm */ 32931784Sgavinm movl %eax, %r11d 32941784Sgavinm cmpl $0, %r11d 32950Sstevel@tonic-gate je 0f 32960Sstevel@tonic-gate 32970Sstevel@tonic-gate /* 32980Sstevel@tonic-gate * If panic_trigger() was successful, we are the first to initiate a 32990Sstevel@tonic-gate * panic: we now switch to the reserved panic_stack before continuing. 33000Sstevel@tonic-gate */ 33010Sstevel@tonic-gate leaq panic_stack(%rip), %rsp 33020Sstevel@tonic-gate addq $PANICSTKSIZE, %rsp 33030Sstevel@tonic-gate0: subq $REGSIZE, %rsp 33040Sstevel@tonic-gate /* 33050Sstevel@tonic-gate * Now that we've got everything set up, store the register values as 33060Sstevel@tonic-gate * they were when we entered vpanic() to the designated location in 33070Sstevel@tonic-gate * the regs structure we allocated on the stack. 33080Sstevel@tonic-gate */ 33090Sstevel@tonic-gate movq 0x0(%rbx), %rcx 33100Sstevel@tonic-gate movq %rcx, REGOFF_RDI(%rsp) 33110Sstevel@tonic-gate movq 0x8(%rbx), %rcx 33120Sstevel@tonic-gate movq %rcx, REGOFF_RSI(%rsp) 33130Sstevel@tonic-gate movq 0x10(%rbx), %rcx 33140Sstevel@tonic-gate movq %rcx, REGOFF_RDX(%rsp) 33150Sstevel@tonic-gate movq 0x18(%rbx), %rcx 33160Sstevel@tonic-gate movq %rcx, REGOFF_RCX(%rsp) 33170Sstevel@tonic-gate movq 0x20(%rbx), %rcx 33180Sstevel@tonic-gate 33190Sstevel@tonic-gate movq %rcx, REGOFF_R8(%rsp) 33200Sstevel@tonic-gate movq 0x28(%rbx), %rcx 33210Sstevel@tonic-gate movq %rcx, REGOFF_R9(%rsp) 33220Sstevel@tonic-gate movq 0x30(%rbx), %rcx 33230Sstevel@tonic-gate movq %rcx, REGOFF_RAX(%rsp) 33240Sstevel@tonic-gate movq 0x38(%rbx), %rcx 33252195Ssethg movq %rcx, REGOFF_RBX(%rsp) 33260Sstevel@tonic-gate movq 0x58(%rbx), %rcx 33270Sstevel@tonic-gate 33280Sstevel@tonic-gate movq %rcx, REGOFF_RBP(%rsp) 33290Sstevel@tonic-gate movq 0x40(%rbx), %rcx 33300Sstevel@tonic-gate movq %rcx, REGOFF_R10(%rsp) 33310Sstevel@tonic-gate movq 0x48(%rbx), %rcx 33320Sstevel@tonic-gate movq %rcx, REGOFF_R11(%rsp) 33330Sstevel@tonic-gate movq %r12, REGOFF_R12(%rsp) 33340Sstevel@tonic-gate 33350Sstevel@tonic-gate movq %r13, REGOFF_R13(%rsp) 33360Sstevel@tonic-gate movq %r14, REGOFF_R14(%rsp) 33370Sstevel@tonic-gate movq %r15, REGOFF_R15(%rsp) 33380Sstevel@tonic-gate 33390Sstevel@tonic-gate xorl %ecx, %ecx 33400Sstevel@tonic-gate movw %ds, %cx 33410Sstevel@tonic-gate movq %rcx, REGOFF_DS(%rsp) 33420Sstevel@tonic-gate movw %es, %cx 33430Sstevel@tonic-gate movq %rcx, REGOFF_ES(%rsp) 33440Sstevel@tonic-gate movw %fs, %cx 33450Sstevel@tonic-gate movq %rcx, REGOFF_FS(%rsp) 33460Sstevel@tonic-gate movw %gs, %cx 33470Sstevel@tonic-gate movq %rcx, REGOFF_GS(%rsp) 33480Sstevel@tonic-gate 33490Sstevel@tonic-gate movq $0, REGOFF_TRAPNO(%rsp) 33500Sstevel@tonic-gate 33510Sstevel@tonic-gate movq $0, REGOFF_ERR(%rsp) 33520Sstevel@tonic-gate leaq vpanic(%rip), %rcx 33530Sstevel@tonic-gate movq %rcx, REGOFF_RIP(%rsp) 33540Sstevel@tonic-gate movw %cs, %cx 33550Sstevel@tonic-gate movzwq %cx, %rcx 33560Sstevel@tonic-gate movq %rcx, REGOFF_CS(%rsp) 33570Sstevel@tonic-gate movq 0x50(%rbx), %rcx 33580Sstevel@tonic-gate movq %rcx, REGOFF_RFL(%rsp) 33590Sstevel@tonic-gate movq %rbx, %rcx 33600Sstevel@tonic-gate addq $0x60, %rcx 33610Sstevel@tonic-gate movq %rcx, REGOFF_RSP(%rsp) 33620Sstevel@tonic-gate movw %ss, %cx 33630Sstevel@tonic-gate movzwq %cx, %rcx 33640Sstevel@tonic-gate movq %rcx, REGOFF_SS(%rsp) 33650Sstevel@tonic-gate 33660Sstevel@tonic-gate /* 33670Sstevel@tonic-gate * panicsys(format, alist, rp, on_panic_stack) 33680Sstevel@tonic-gate */ 33690Sstevel@tonic-gate movq REGOFF_RDI(%rsp), %rdi /* format */ 33700Sstevel@tonic-gate movq REGOFF_RSI(%rsp), %rsi /* alist */ 33710Sstevel@tonic-gate movq %rsp, %rdx /* struct regs */ 33721784Sgavinm movl %r11d, %ecx /* on_panic_stack */ 33730Sstevel@tonic-gate call panicsys 33740Sstevel@tonic-gate addq $REGSIZE, %rsp 33750Sstevel@tonic-gate popq %rdi 33760Sstevel@tonic-gate popq %rsi 33770Sstevel@tonic-gate popq %rdx 33780Sstevel@tonic-gate popq %rcx 33790Sstevel@tonic-gate popq %r8 33800Sstevel@tonic-gate popq %r9 33810Sstevel@tonic-gate popq %rax 33820Sstevel@tonic-gate popq %rbx 33830Sstevel@tonic-gate popq %r10 33840Sstevel@tonic-gate popq %r11 33850Sstevel@tonic-gate popfq 33860Sstevel@tonic-gate leave 33870Sstevel@tonic-gate ret 33880Sstevel@tonic-gate SET_SIZE(vpanic) 33890Sstevel@tonic-gate 33900Sstevel@tonic-gate ENTRY_NP(dtrace_vpanic) /* Initial stack layout: */ 33910Sstevel@tonic-gate 33920Sstevel@tonic-gate pushq %rbp /* | %rip | 0x60 */ 33930Sstevel@tonic-gate movq %rsp, %rbp /* | %rbp | 0x58 */ 33940Sstevel@tonic-gate pushfq /* | rfl | 0x50 */ 33950Sstevel@tonic-gate pushq %r11 /* | %r11 | 0x48 */ 33960Sstevel@tonic-gate pushq %r10 /* | %r10 | 0x40 */ 33970Sstevel@tonic-gate pushq %rbx /* | %rbx | 0x38 */ 33980Sstevel@tonic-gate pushq %rax /* | %rax | 0x30 */ 33990Sstevel@tonic-gate pushq %r9 /* | %r9 | 0x28 */ 34000Sstevel@tonic-gate pushq %r8 /* | %r8 | 0x20 */ 34010Sstevel@tonic-gate pushq %rcx /* | %rcx | 0x18 */ 34020Sstevel@tonic-gate pushq %rdx /* | %rdx | 0x10 */ 34030Sstevel@tonic-gate pushq %rsi /* | %rsi | 0x8 alist */ 34040Sstevel@tonic-gate pushq %rdi /* | %rdi | 0x0 format */ 34050Sstevel@tonic-gate 34060Sstevel@tonic-gate movq %rsp, %rbx /* %rbx = current %rsp */ 34070Sstevel@tonic-gate 34080Sstevel@tonic-gate leaq panic_quiesce(%rip), %rdi /* %rdi = &panic_quiesce */ 34090Sstevel@tonic-gate call dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */ 34100Sstevel@tonic-gate jmp vpanic_common 34110Sstevel@tonic-gate 34120Sstevel@tonic-gate SET_SIZE(dtrace_vpanic) 34130Sstevel@tonic-gate 34140Sstevel@tonic-gate#elif defined(__i386) 34150Sstevel@tonic-gate 34160Sstevel@tonic-gate ENTRY_NP(vpanic) / Initial stack layout: 34170Sstevel@tonic-gate 34180Sstevel@tonic-gate pushl %ebp / | %eip | 20 34190Sstevel@tonic-gate movl %esp, %ebp / | %ebp | 16 34200Sstevel@tonic-gate pushl %eax / | %eax | 12 34210Sstevel@tonic-gate pushl %ebx / | %ebx | 8 34220Sstevel@tonic-gate pushl %ecx / | %ecx | 4 34230Sstevel@tonic-gate pushl %edx / | %edx | 0 34240Sstevel@tonic-gate 34250Sstevel@tonic-gate movl %esp, %ebx / %ebx = current stack pointer 34260Sstevel@tonic-gate 34270Sstevel@tonic-gate lea panic_quiesce, %eax / %eax = &panic_quiesce 34280Sstevel@tonic-gate pushl %eax / push &panic_quiesce 34290Sstevel@tonic-gate call panic_trigger / %eax = panic_trigger() 34300Sstevel@tonic-gate addl $4, %esp / reset stack pointer 34310Sstevel@tonic-gate 34320Sstevel@tonic-gatevpanic_common: 34330Sstevel@tonic-gate cmpl $0, %eax / if (%eax == 0) 34340Sstevel@tonic-gate je 0f / goto 0f; 34350Sstevel@tonic-gate 34360Sstevel@tonic-gate /* 34370Sstevel@tonic-gate * If panic_trigger() was successful, we are the first to initiate a 34380Sstevel@tonic-gate * panic: we now switch to the reserved panic_stack before continuing. 34390Sstevel@tonic-gate */ 34400Sstevel@tonic-gate lea panic_stack, %esp / %esp = panic_stack 34410Sstevel@tonic-gate addl $PANICSTKSIZE, %esp / %esp += PANICSTKSIZE 34420Sstevel@tonic-gate 34430Sstevel@tonic-gate0: subl $REGSIZE, %esp / allocate struct regs 34440Sstevel@tonic-gate 34450Sstevel@tonic-gate /* 34460Sstevel@tonic-gate * Now that we've got everything set up, store the register values as 34470Sstevel@tonic-gate * they were when we entered vpanic() to the designated location in 34480Sstevel@tonic-gate * the regs structure we allocated on the stack. 34490Sstevel@tonic-gate */ 34500Sstevel@tonic-gate#if !defined(__GNUC_AS__) 34510Sstevel@tonic-gate movw %gs, %edx 34520Sstevel@tonic-gate movl %edx, REGOFF_GS(%esp) 34530Sstevel@tonic-gate movw %fs, %edx 34540Sstevel@tonic-gate movl %edx, REGOFF_FS(%esp) 34550Sstevel@tonic-gate movw %es, %edx 34560Sstevel@tonic-gate movl %edx, REGOFF_ES(%esp) 34570Sstevel@tonic-gate movw %ds, %edx 34580Sstevel@tonic-gate movl %edx, REGOFF_DS(%esp) 34590Sstevel@tonic-gate#else /* __GNUC_AS__ */ 34600Sstevel@tonic-gate mov %gs, %edx 34610Sstevel@tonic-gate mov %edx, REGOFF_GS(%esp) 34620Sstevel@tonic-gate mov %fs, %edx 34630Sstevel@tonic-gate mov %edx, REGOFF_FS(%esp) 34640Sstevel@tonic-gate mov %es, %edx 34650Sstevel@tonic-gate mov %edx, REGOFF_ES(%esp) 34660Sstevel@tonic-gate mov %ds, %edx 34670Sstevel@tonic-gate mov %edx, REGOFF_DS(%esp) 34680Sstevel@tonic-gate#endif /* __GNUC_AS__ */ 34690Sstevel@tonic-gate movl %edi, REGOFF_EDI(%esp) 34700Sstevel@tonic-gate movl %esi, REGOFF_ESI(%esp) 34710Sstevel@tonic-gate movl 16(%ebx), %ecx 34720Sstevel@tonic-gate movl %ecx, REGOFF_EBP(%esp) 34730Sstevel@tonic-gate movl %ebx, %ecx 34740Sstevel@tonic-gate addl $20, %ecx 34750Sstevel@tonic-gate movl %ecx, REGOFF_ESP(%esp) 34760Sstevel@tonic-gate movl 8(%ebx), %ecx 34770Sstevel@tonic-gate movl %ecx, REGOFF_EBX(%esp) 34780Sstevel@tonic-gate movl 0(%ebx), %ecx 34790Sstevel@tonic-gate movl %ecx, REGOFF_EDX(%esp) 34800Sstevel@tonic-gate movl 4(%ebx), %ecx 34810Sstevel@tonic-gate movl %ecx, REGOFF_ECX(%esp) 34820Sstevel@tonic-gate movl 12(%ebx), %ecx 34830Sstevel@tonic-gate movl %ecx, REGOFF_EAX(%esp) 34840Sstevel@tonic-gate movl $0, REGOFF_TRAPNO(%esp) 34850Sstevel@tonic-gate movl $0, REGOFF_ERR(%esp) 34860Sstevel@tonic-gate lea vpanic, %ecx 34870Sstevel@tonic-gate movl %ecx, REGOFF_EIP(%esp) 34880Sstevel@tonic-gate#if !defined(__GNUC_AS__) 34890Sstevel@tonic-gate movw %cs, %edx 34900Sstevel@tonic-gate#else /* __GNUC_AS__ */ 34910Sstevel@tonic-gate mov %cs, %edx 34920Sstevel@tonic-gate#endif /* __GNUC_AS__ */ 34930Sstevel@tonic-gate movl %edx, REGOFF_CS(%esp) 34940Sstevel@tonic-gate pushfl 34950Sstevel@tonic-gate popl %ecx 34965084Sjohnlev#if defined(__xpv) 34975084Sjohnlev /* 34985084Sjohnlev * Synthesize the PS_IE bit from the event mask bit 34995084Sjohnlev */ 35005084Sjohnlev CURTHREAD(%edx) 35015084Sjohnlev KPREEMPT_DISABLE(%edx) 35025084Sjohnlev EVENT_MASK_TO_IE(%edx, %ecx) 35035084Sjohnlev CURTHREAD(%edx) 35045084Sjohnlev KPREEMPT_ENABLE_NOKP(%edx) 35055084Sjohnlev#endif 35060Sstevel@tonic-gate movl %ecx, REGOFF_EFL(%esp) 35070Sstevel@tonic-gate movl $0, REGOFF_UESP(%esp) 35080Sstevel@tonic-gate#if !defined(__GNUC_AS__) 35090Sstevel@tonic-gate movw %ss, %edx 35100Sstevel@tonic-gate#else /* __GNUC_AS__ */ 35110Sstevel@tonic-gate mov %ss, %edx 35120Sstevel@tonic-gate#endif /* __GNUC_AS__ */ 35130Sstevel@tonic-gate movl %edx, REGOFF_SS(%esp) 35140Sstevel@tonic-gate 35150Sstevel@tonic-gate movl %esp, %ecx / %ecx = ®s 35160Sstevel@tonic-gate pushl %eax / push on_panic_stack 35170Sstevel@tonic-gate pushl %ecx / push ®s 35180Sstevel@tonic-gate movl 12(%ebp), %ecx / %ecx = alist 35190Sstevel@tonic-gate pushl %ecx / push alist 35200Sstevel@tonic-gate movl 8(%ebp), %ecx / %ecx = format 35210Sstevel@tonic-gate pushl %ecx / push format 35220Sstevel@tonic-gate call panicsys / panicsys(); 35230Sstevel@tonic-gate addl $16, %esp / pop arguments 35240Sstevel@tonic-gate 35250Sstevel@tonic-gate addl $REGSIZE, %esp 35260Sstevel@tonic-gate popl %edx 35270Sstevel@tonic-gate popl %ecx 35280Sstevel@tonic-gate popl %ebx 35290Sstevel@tonic-gate popl %eax 35300Sstevel@tonic-gate leave 35310Sstevel@tonic-gate ret 35320Sstevel@tonic-gate SET_SIZE(vpanic) 35330Sstevel@tonic-gate 35340Sstevel@tonic-gate ENTRY_NP(dtrace_vpanic) / Initial stack layout: 35350Sstevel@tonic-gate 35360Sstevel@tonic-gate pushl %ebp / | %eip | 20 35370Sstevel@tonic-gate movl %esp, %ebp / | %ebp | 16 35380Sstevel@tonic-gate pushl %eax / | %eax | 12 35390Sstevel@tonic-gate pushl %ebx / | %ebx | 8 35400Sstevel@tonic-gate pushl %ecx / | %ecx | 4 35410Sstevel@tonic-gate pushl %edx / | %edx | 0 35420Sstevel@tonic-gate 35430Sstevel@tonic-gate movl %esp, %ebx / %ebx = current stack pointer 35440Sstevel@tonic-gate 35450Sstevel@tonic-gate lea panic_quiesce, %eax / %eax = &panic_quiesce 35460Sstevel@tonic-gate pushl %eax / push &panic_quiesce 35470Sstevel@tonic-gate call dtrace_panic_trigger / %eax = dtrace_panic_trigger() 35480Sstevel@tonic-gate addl $4, %esp / reset stack pointer 35490Sstevel@tonic-gate jmp vpanic_common / jump back to common code 35500Sstevel@tonic-gate 35510Sstevel@tonic-gate SET_SIZE(dtrace_vpanic) 35520Sstevel@tonic-gate 35530Sstevel@tonic-gate#endif /* __i386 */ 35540Sstevel@tonic-gate#endif /* __lint */ 35550Sstevel@tonic-gate 35560Sstevel@tonic-gate#if defined(__lint) 35570Sstevel@tonic-gate 35580Sstevel@tonic-gatevoid 35590Sstevel@tonic-gatehres_tick(void) 35600Sstevel@tonic-gate{} 35610Sstevel@tonic-gate 35620Sstevel@tonic-gateint64_t timedelta; 35630Sstevel@tonic-gatehrtime_t hres_last_tick; 35644551Ssudheervolatile timestruc_t hrestime; 35650Sstevel@tonic-gateint64_t hrestime_adj; 35660Sstevel@tonic-gatevolatile int hres_lock; 35670Sstevel@tonic-gatehrtime_t hrtime_base; 35680Sstevel@tonic-gate 35690Sstevel@tonic-gate#else /* __lint */ 35700Sstevel@tonic-gate 35710Sstevel@tonic-gate DGDEF3(hrestime, _MUL(2, CLONGSIZE), 8) 35720Sstevel@tonic-gate .NWORD 0, 0 35730Sstevel@tonic-gate 35740Sstevel@tonic-gate DGDEF3(hrestime_adj, 8, 8) 35750Sstevel@tonic-gate .long 0, 0 35760Sstevel@tonic-gate 35770Sstevel@tonic-gate DGDEF3(hres_last_tick, 8, 8) 35780Sstevel@tonic-gate .long 0, 0 35790Sstevel@tonic-gate 35800Sstevel@tonic-gate DGDEF3(timedelta, 8, 8) 35810Sstevel@tonic-gate .long 0, 0 35820Sstevel@tonic-gate 35830Sstevel@tonic-gate DGDEF3(hres_lock, 4, 8) 35840Sstevel@tonic-gate .long 0 35850Sstevel@tonic-gate 35860Sstevel@tonic-gate /* 35870Sstevel@tonic-gate * initialized to a non zero value to make pc_gethrtime() 35880Sstevel@tonic-gate * work correctly even before clock is initialized 35890Sstevel@tonic-gate */ 35900Sstevel@tonic-gate DGDEF3(hrtime_base, 8, 8) 35910Sstevel@tonic-gate .long _MUL(NSEC_PER_CLOCK_TICK, 6), 0 35920Sstevel@tonic-gate 35930Sstevel@tonic-gate DGDEF3(adj_shift, 4, 4) 35940Sstevel@tonic-gate .long ADJ_SHIFT 35950Sstevel@tonic-gate 35960Sstevel@tonic-gate#if defined(__amd64) 35970Sstevel@tonic-gate 35980Sstevel@tonic-gate ENTRY_NP(hres_tick) 35990Sstevel@tonic-gate pushq %rbp 36000Sstevel@tonic-gate movq %rsp, %rbp 36010Sstevel@tonic-gate 36020Sstevel@tonic-gate /* 36030Sstevel@tonic-gate * We need to call *gethrtimef before picking up CLOCK_LOCK (obviously, 36040Sstevel@tonic-gate * hres_last_tick can only be modified while holding CLOCK_LOCK). 36050Sstevel@tonic-gate * At worst, performing this now instead of under CLOCK_LOCK may 36060Sstevel@tonic-gate * introduce some jitter in pc_gethrestime(). 36070Sstevel@tonic-gate */ 36080Sstevel@tonic-gate call *gethrtimef(%rip) 36090Sstevel@tonic-gate movq %rax, %r8 36100Sstevel@tonic-gate 36110Sstevel@tonic-gate leaq hres_lock(%rip), %rax 36120Sstevel@tonic-gate movb $-1, %dl 36130Sstevel@tonic-gate.CL1: 36140Sstevel@tonic-gate xchgb %dl, (%rax) 36150Sstevel@tonic-gate testb %dl, %dl 36160Sstevel@tonic-gate jz .CL3 /* got it */ 36170Sstevel@tonic-gate.CL2: 36180Sstevel@tonic-gate cmpb $0, (%rax) /* possible to get lock? */ 36190Sstevel@tonic-gate pause 36200Sstevel@tonic-gate jne .CL2 36210Sstevel@tonic-gate jmp .CL1 /* yes, try again */ 36220Sstevel@tonic-gate.CL3: 36230Sstevel@tonic-gate /* 36240Sstevel@tonic-gate * compute the interval since last time hres_tick was called 36250Sstevel@tonic-gate * and adjust hrtime_base and hrestime accordingly 36260Sstevel@tonic-gate * hrtime_base is an 8 byte value (in nsec), hrestime is 36270Sstevel@tonic-gate * a timestruc_t (sec, nsec) 36280Sstevel@tonic-gate */ 36290Sstevel@tonic-gate leaq hres_last_tick(%rip), %rax 36300Sstevel@tonic-gate movq %r8, %r11 36310Sstevel@tonic-gate subq (%rax), %r8 36320Sstevel@tonic-gate addq %r8, hrtime_base(%rip) /* add interval to hrtime_base */ 36330Sstevel@tonic-gate addq %r8, hrestime+8(%rip) /* add interval to hrestime.tv_nsec */ 36340Sstevel@tonic-gate /* 36350Sstevel@tonic-gate * Now that we have CLOCK_LOCK, we can update hres_last_tick 36360Sstevel@tonic-gate */ 36370Sstevel@tonic-gate movq %r11, (%rax) 36380Sstevel@tonic-gate 36390Sstevel@tonic-gate call __adj_hrestime 36400Sstevel@tonic-gate 36410Sstevel@tonic-gate /* 36420Sstevel@tonic-gate * release the hres_lock 36430Sstevel@tonic-gate */ 36440Sstevel@tonic-gate incl hres_lock(%rip) 36450Sstevel@tonic-gate leave 36460Sstevel@tonic-gate ret 36470Sstevel@tonic-gate SET_SIZE(hres_tick) 36480Sstevel@tonic-gate 36490Sstevel@tonic-gate#elif defined(__i386) 36500Sstevel@tonic-gate 36510Sstevel@tonic-gate ENTRY_NP(hres_tick) 36520Sstevel@tonic-gate pushl %ebp 36530Sstevel@tonic-gate movl %esp, %ebp 36540Sstevel@tonic-gate pushl %esi 36550Sstevel@tonic-gate pushl %ebx 36560Sstevel@tonic-gate 36570Sstevel@tonic-gate /* 36580Sstevel@tonic-gate * We need to call *gethrtimef before picking up CLOCK_LOCK (obviously, 36590Sstevel@tonic-gate * hres_last_tick can only be modified while holding CLOCK_LOCK). 36600Sstevel@tonic-gate * At worst, performing this now instead of under CLOCK_LOCK may 36610Sstevel@tonic-gate * introduce some jitter in pc_gethrestime(). 36620Sstevel@tonic-gate */ 36630Sstevel@tonic-gate call *gethrtimef 36640Sstevel@tonic-gate movl %eax, %ebx 36650Sstevel@tonic-gate movl %edx, %esi 36660Sstevel@tonic-gate 36670Sstevel@tonic-gate movl $hres_lock, %eax 36680Sstevel@tonic-gate movl $-1, %edx 36690Sstevel@tonic-gate.CL1: 36700Sstevel@tonic-gate xchgb %dl, (%eax) 36710Sstevel@tonic-gate testb %dl, %dl 36720Sstevel@tonic-gate jz .CL3 / got it 36730Sstevel@tonic-gate.CL2: 36740Sstevel@tonic-gate cmpb $0, (%eax) / possible to get lock? 36750Sstevel@tonic-gate pause 36760Sstevel@tonic-gate jne .CL2 36770Sstevel@tonic-gate jmp .CL1 / yes, try again 36780Sstevel@tonic-gate.CL3: 36790Sstevel@tonic-gate /* 36800Sstevel@tonic-gate * compute the interval since last time hres_tick was called 36810Sstevel@tonic-gate * and adjust hrtime_base and hrestime accordingly 36820Sstevel@tonic-gate * hrtime_base is an 8 byte value (in nsec), hrestime is 36830Sstevel@tonic-gate * timestruc_t (sec, nsec) 36840Sstevel@tonic-gate */ 36850Sstevel@tonic-gate 36860Sstevel@tonic-gate lea hres_last_tick, %eax 36870Sstevel@tonic-gate 36880Sstevel@tonic-gate movl %ebx, %edx 36890Sstevel@tonic-gate movl %esi, %ecx 36900Sstevel@tonic-gate 36910Sstevel@tonic-gate subl (%eax), %edx 36920Sstevel@tonic-gate sbbl 4(%eax), %ecx 36930Sstevel@tonic-gate 36940Sstevel@tonic-gate addl %edx, hrtime_base / add interval to hrtime_base 36950Sstevel@tonic-gate adcl %ecx, hrtime_base+4 36960Sstevel@tonic-gate 36970Sstevel@tonic-gate addl %edx, hrestime+4 / add interval to hrestime.tv_nsec 36980Sstevel@tonic-gate 36990Sstevel@tonic-gate / 37000Sstevel@tonic-gate / Now that we have CLOCK_LOCK, we can update hres_last_tick. 37010Sstevel@tonic-gate / 37020Sstevel@tonic-gate movl %ebx, (%eax) 37030Sstevel@tonic-gate movl %esi, 4(%eax) 37040Sstevel@tonic-gate 37050Sstevel@tonic-gate / get hrestime at this moment. used as base for pc_gethrestime 37060Sstevel@tonic-gate / 37070Sstevel@tonic-gate / Apply adjustment, if any 37080Sstevel@tonic-gate / 37090Sstevel@tonic-gate / #define HRES_ADJ (NSEC_PER_CLOCK_TICK >> ADJ_SHIFT) 37100Sstevel@tonic-gate / (max_hres_adj) 37110Sstevel@tonic-gate / 37120Sstevel@tonic-gate / void 37130Sstevel@tonic-gate / adj_hrestime() 37140Sstevel@tonic-gate / { 37150Sstevel@tonic-gate / long long adj; 37160Sstevel@tonic-gate / 37170Sstevel@tonic-gate / if (hrestime_adj == 0) 37180Sstevel@tonic-gate / adj = 0; 37190Sstevel@tonic-gate / else if (hrestime_adj > 0) { 37200Sstevel@tonic-gate / if (hrestime_adj < HRES_ADJ) 37210Sstevel@tonic-gate / adj = hrestime_adj; 37220Sstevel@tonic-gate / else 37230Sstevel@tonic-gate / adj = HRES_ADJ; 37240Sstevel@tonic-gate / } 37250Sstevel@tonic-gate / else { 37260Sstevel@tonic-gate / if (hrestime_adj < -(HRES_ADJ)) 37270Sstevel@tonic-gate / adj = -(HRES_ADJ); 37280Sstevel@tonic-gate / else 37290Sstevel@tonic-gate / adj = hrestime_adj; 37300Sstevel@tonic-gate / } 37310Sstevel@tonic-gate / 37320Sstevel@tonic-gate / timedelta -= adj; 37330Sstevel@tonic-gate / hrestime_adj = timedelta; 37340Sstevel@tonic-gate / hrestime.tv_nsec += adj; 37350Sstevel@tonic-gate / 37360Sstevel@tonic-gate / while (hrestime.tv_nsec >= NANOSEC) { 37370Sstevel@tonic-gate / one_sec++; 37380Sstevel@tonic-gate / hrestime.tv_sec++; 37390Sstevel@tonic-gate / hrestime.tv_nsec -= NANOSEC; 37400Sstevel@tonic-gate / } 37410Sstevel@tonic-gate / } 37420Sstevel@tonic-gate__adj_hrestime: 37430Sstevel@tonic-gate movl hrestime_adj, %esi / if (hrestime_adj == 0) 37440Sstevel@tonic-gate movl hrestime_adj+4, %edx 37450Sstevel@tonic-gate andl %esi, %esi 37460Sstevel@tonic-gate jne .CL4 / no 37470Sstevel@tonic-gate andl %edx, %edx 37480Sstevel@tonic-gate jne .CL4 / no 37490Sstevel@tonic-gate subl %ecx, %ecx / yes, adj = 0; 37500Sstevel@tonic-gate subl %edx, %edx 37510Sstevel@tonic-gate jmp .CL5 37520Sstevel@tonic-gate.CL4: 37530Sstevel@tonic-gate subl %ecx, %ecx 37540Sstevel@tonic-gate subl %eax, %eax 37550Sstevel@tonic-gate subl %esi, %ecx 37560Sstevel@tonic-gate sbbl %edx, %eax 37570Sstevel@tonic-gate andl %eax, %eax / if (hrestime_adj > 0) 37580Sstevel@tonic-gate jge .CL6 37590Sstevel@tonic-gate 37600Sstevel@tonic-gate / In the following comments, HRES_ADJ is used, while in the code 37610Sstevel@tonic-gate / max_hres_adj is used. 37620Sstevel@tonic-gate / 37630Sstevel@tonic-gate / The test for "hrestime_adj < HRES_ADJ" is complicated because 37640Sstevel@tonic-gate / hrestime_adj is 64-bits, while HRES_ADJ is 32-bits. We rely 37650Sstevel@tonic-gate / on the logical equivalence of: 37660Sstevel@tonic-gate / 37670Sstevel@tonic-gate / !(hrestime_adj < HRES_ADJ) 37680Sstevel@tonic-gate / 37690Sstevel@tonic-gate / and the two step sequence: 37700Sstevel@tonic-gate / 37710Sstevel@tonic-gate / (HRES_ADJ - lsw(hrestime_adj)) generates a Borrow/Carry 37720Sstevel@tonic-gate / 37730Sstevel@tonic-gate / which computes whether or not the least significant 32-bits 37740Sstevel@tonic-gate / of hrestime_adj is greater than HRES_ADJ, followed by: 37750Sstevel@tonic-gate / 37760Sstevel@tonic-gate / Previous Borrow/Carry + -1 + msw(hrestime_adj) generates a Carry 37770Sstevel@tonic-gate / 37780Sstevel@tonic-gate / which generates a carry whenever step 1 is true or the most 37790Sstevel@tonic-gate / significant long of the longlong hrestime_adj is non-zero. 37800Sstevel@tonic-gate 37810Sstevel@tonic-gate movl max_hres_adj, %ecx / hrestime_adj is positive 37820Sstevel@tonic-gate subl %esi, %ecx 37830Sstevel@tonic-gate movl %edx, %eax 37840Sstevel@tonic-gate adcl $-1, %eax 37850Sstevel@tonic-gate jnc .CL7 37860Sstevel@tonic-gate movl max_hres_adj, %ecx / adj = HRES_ADJ; 37870Sstevel@tonic-gate subl %edx, %edx 37880Sstevel@tonic-gate jmp .CL5 37890Sstevel@tonic-gate 37900Sstevel@tonic-gate / The following computation is similar to the one above. 37910Sstevel@tonic-gate / 37920Sstevel@tonic-gate / The test for "hrestime_adj < -(HRES_ADJ)" is complicated because 37930Sstevel@tonic-gate / hrestime_adj is 64-bits, while HRES_ADJ is 32-bits. We rely 37940Sstevel@tonic-gate / on the logical equivalence of: 37950Sstevel@tonic-gate / 37960Sstevel@tonic-gate / (hrestime_adj > -HRES_ADJ) 37970Sstevel@tonic-gate / 37980Sstevel@tonic-gate / and the two step sequence: 37990Sstevel@tonic-gate / 38000Sstevel@tonic-gate / (HRES_ADJ + lsw(hrestime_adj)) generates a Carry 38010Sstevel@tonic-gate / 38020Sstevel@tonic-gate / which means the least significant 32-bits of hrestime_adj is 38030Sstevel@tonic-gate / greater than -HRES_ADJ, followed by: 38040Sstevel@tonic-gate / 38050Sstevel@tonic-gate / Previous Carry + 0 + msw(hrestime_adj) generates a Carry 38060Sstevel@tonic-gate / 38070Sstevel@tonic-gate / which generates a carry only when step 1 is true and the most 38080Sstevel@tonic-gate / significant long of the longlong hrestime_adj is -1. 38090Sstevel@tonic-gate 38100Sstevel@tonic-gate.CL6: / hrestime_adj is negative 38110Sstevel@tonic-gate movl %esi, %ecx 38120Sstevel@tonic-gate addl max_hres_adj, %ecx 38130Sstevel@tonic-gate movl %edx, %eax 38140Sstevel@tonic-gate adcl $0, %eax 38150Sstevel@tonic-gate jc .CL7 38160Sstevel@tonic-gate xor %ecx, %ecx 38170Sstevel@tonic-gate subl max_hres_adj, %ecx / adj = -(HRES_ADJ); 38180Sstevel@tonic-gate movl $-1, %edx 38190Sstevel@tonic-gate jmp .CL5 38200Sstevel@tonic-gate.CL7: 38210Sstevel@tonic-gate movl %esi, %ecx / adj = hrestime_adj; 38220Sstevel@tonic-gate.CL5: 38230Sstevel@tonic-gate movl timedelta, %esi 38240Sstevel@tonic-gate subl %ecx, %esi 38250Sstevel@tonic-gate movl timedelta+4, %eax 38260Sstevel@tonic-gate sbbl %edx, %eax 38270Sstevel@tonic-gate movl %esi, timedelta 38280Sstevel@tonic-gate movl %eax, timedelta+4 / timedelta -= adj; 38290Sstevel@tonic-gate movl %esi, hrestime_adj 38300Sstevel@tonic-gate movl %eax, hrestime_adj+4 / hrestime_adj = timedelta; 38310Sstevel@tonic-gate addl hrestime+4, %ecx 38320Sstevel@tonic-gate 38330Sstevel@tonic-gate movl %ecx, %eax / eax = tv_nsec 38340Sstevel@tonic-gate1: 38350Sstevel@tonic-gate cmpl $NANOSEC, %eax / if ((unsigned long)tv_nsec >= NANOSEC) 38360Sstevel@tonic-gate jb .CL8 / no 38370Sstevel@tonic-gate incl one_sec / yes, one_sec++; 38380Sstevel@tonic-gate incl hrestime / hrestime.tv_sec++; 38390Sstevel@tonic-gate addl $-NANOSEC, %eax / tv_nsec -= NANOSEC 38400Sstevel@tonic-gate jmp 1b / check for more seconds 38410Sstevel@tonic-gate 38420Sstevel@tonic-gate.CL8: 38430Sstevel@tonic-gate movl %eax, hrestime+4 / store final into hrestime.tv_nsec 38440Sstevel@tonic-gate incl hres_lock / release the hres_lock 38450Sstevel@tonic-gate 38460Sstevel@tonic-gate popl %ebx 38470Sstevel@tonic-gate popl %esi 38480Sstevel@tonic-gate leave 38490Sstevel@tonic-gate ret 38500Sstevel@tonic-gate SET_SIZE(hres_tick) 38510Sstevel@tonic-gate 38520Sstevel@tonic-gate#endif /* __i386 */ 38530Sstevel@tonic-gate#endif /* __lint */ 38540Sstevel@tonic-gate 38550Sstevel@tonic-gate/* 38560Sstevel@tonic-gate * void prefetch_smap_w(void *) 38570Sstevel@tonic-gate * 38580Sstevel@tonic-gate * Prefetch ahead within a linear list of smap structures. 38590Sstevel@tonic-gate * Not implemented for ia32. Stub for compatibility. 38600Sstevel@tonic-gate */ 38610Sstevel@tonic-gate 38620Sstevel@tonic-gate#if defined(__lint) 38630Sstevel@tonic-gate 38640Sstevel@tonic-gate/*ARGSUSED*/ 38650Sstevel@tonic-gatevoid prefetch_smap_w(void *smp) 38660Sstevel@tonic-gate{} 38670Sstevel@tonic-gate 38680Sstevel@tonic-gate#else /* __lint */ 38690Sstevel@tonic-gate 38700Sstevel@tonic-gate ENTRY(prefetch_smap_w) 3871545Skalai rep; ret /* use 2 byte return instruction when branch target */ 3872545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 38730Sstevel@tonic-gate SET_SIZE(prefetch_smap_w) 38740Sstevel@tonic-gate 38750Sstevel@tonic-gate#endif /* __lint */ 38760Sstevel@tonic-gate 38770Sstevel@tonic-gate/* 38780Sstevel@tonic-gate * prefetch_page_r(page_t *) 38790Sstevel@tonic-gate * issue prefetch instructions for a page_t 38800Sstevel@tonic-gate */ 38810Sstevel@tonic-gate#if defined(__lint) 38820Sstevel@tonic-gate 38830Sstevel@tonic-gate/*ARGSUSED*/ 38840Sstevel@tonic-gatevoid 38850Sstevel@tonic-gateprefetch_page_r(void *pp) 38860Sstevel@tonic-gate{} 38870Sstevel@tonic-gate 38880Sstevel@tonic-gate#else /* __lint */ 38890Sstevel@tonic-gate 38900Sstevel@tonic-gate ENTRY(prefetch_page_r) 3891545Skalai rep; ret /* use 2 byte return instruction when branch target */ 3892545Skalai /* AMD Software Optimization Guide - Section 6.2 */ 38930Sstevel@tonic-gate SET_SIZE(prefetch_page_r) 38940Sstevel@tonic-gate 38950Sstevel@tonic-gate#endif /* __lint */ 38960Sstevel@tonic-gate 38970Sstevel@tonic-gate#if defined(__lint) 38980Sstevel@tonic-gate 38990Sstevel@tonic-gate/*ARGSUSED*/ 39000Sstevel@tonic-gateint 39010Sstevel@tonic-gatebcmp(const void *s1, const void *s2, size_t count) 39020Sstevel@tonic-gate{ return (0); } 39030Sstevel@tonic-gate 39040Sstevel@tonic-gate#else /* __lint */ 39050Sstevel@tonic-gate 39060Sstevel@tonic-gate#if defined(__amd64) 39070Sstevel@tonic-gate 39080Sstevel@tonic-gate ENTRY(bcmp) 39090Sstevel@tonic-gate pushq %rbp 39100Sstevel@tonic-gate movq %rsp, %rbp 39110Sstevel@tonic-gate#ifdef DEBUG 39123446Smrj movq postbootkernelbase(%rip), %r11 39130Sstevel@tonic-gate cmpq %r11, %rdi 39140Sstevel@tonic-gate jb 0f 39150Sstevel@tonic-gate cmpq %r11, %rsi 39160Sstevel@tonic-gate jnb 1f 39170Sstevel@tonic-gate0: leaq .bcmp_panic_msg(%rip), %rdi 39180Sstevel@tonic-gate xorl %eax, %eax 39190Sstevel@tonic-gate call panic 39200Sstevel@tonic-gate1: 39210Sstevel@tonic-gate#endif /* DEBUG */ 39220Sstevel@tonic-gate call memcmp 39230Sstevel@tonic-gate testl %eax, %eax 39240Sstevel@tonic-gate setne %dl 39250Sstevel@tonic-gate leave 39260Sstevel@tonic-gate movzbl %dl, %eax 39270Sstevel@tonic-gate ret 39280Sstevel@tonic-gate SET_SIZE(bcmp) 39290Sstevel@tonic-gate 39300Sstevel@tonic-gate#elif defined(__i386) 39310Sstevel@tonic-gate 39320Sstevel@tonic-gate#define ARG_S1 8 39330Sstevel@tonic-gate#define ARG_S2 12 39340Sstevel@tonic-gate#define ARG_LENGTH 16 39350Sstevel@tonic-gate 39360Sstevel@tonic-gate ENTRY(bcmp) 39373412Sjj204856 pushl %ebp 39383412Sjj204856 movl %esp, %ebp / create new stack frame 39390Sstevel@tonic-gate#ifdef DEBUG 39403446Smrj movl postbootkernelbase, %eax 39410Sstevel@tonic-gate cmpl %eax, ARG_S1(%ebp) 39420Sstevel@tonic-gate jb 0f 39430Sstevel@tonic-gate cmpl %eax, ARG_S2(%ebp) 39440Sstevel@tonic-gate jnb 1f 39450Sstevel@tonic-gate0: pushl $.bcmp_panic_msg 39460Sstevel@tonic-gate call panic 39473412Sjj2048561: 39480Sstevel@tonic-gate#endif /* DEBUG */ 39490Sstevel@tonic-gate 39500Sstevel@tonic-gate pushl %edi / save register variable 39513412Sjj204856 movl ARG_S1(%ebp), %eax / %eax = address of string 1 39523412Sjj204856 movl ARG_S2(%ebp), %ecx / %ecx = address of string 2 39530Sstevel@tonic-gate cmpl %eax, %ecx / if the same string 39540Sstevel@tonic-gate je .equal / goto .equal 39553412Sjj204856 movl ARG_LENGTH(%ebp), %edi / %edi = length in bytes 39560Sstevel@tonic-gate cmpl $4, %edi / if %edi < 4 39570Sstevel@tonic-gate jb .byte_check / goto .byte_check 39580Sstevel@tonic-gate .align 4 39590Sstevel@tonic-gate.word_loop: 39600Sstevel@tonic-gate movl (%ecx), %edx / move 1 word from (%ecx) to %edx 39610Sstevel@tonic-gate leal -4(%edi), %edi / %edi -= 4 39620Sstevel@tonic-gate cmpl (%eax), %edx / compare 1 word from (%eax) with %edx 39630Sstevel@tonic-gate jne .word_not_equal / if not equal, goto .word_not_equal 39640Sstevel@tonic-gate leal 4(%ecx), %ecx / %ecx += 4 (next word) 39650Sstevel@tonic-gate leal 4(%eax), %eax / %eax += 4 (next word) 39660Sstevel@tonic-gate cmpl $4, %edi / if %edi >= 4 39670Sstevel@tonic-gate jae .word_loop / goto .word_loop 39680Sstevel@tonic-gate.byte_check: 39690Sstevel@tonic-gate cmpl $0, %edi / if %edi == 0 39700Sstevel@tonic-gate je .equal / goto .equal 39710Sstevel@tonic-gate jmp .byte_loop / goto .byte_loop (checks in bytes) 39720Sstevel@tonic-gate.word_not_equal: 39730Sstevel@tonic-gate leal 4(%edi), %edi / %edi += 4 (post-decremented) 39740Sstevel@tonic-gate .align 4 39750Sstevel@tonic-gate.byte_loop: 39760Sstevel@tonic-gate movb (%ecx), %dl / move 1 byte from (%ecx) to %dl 39770Sstevel@tonic-gate cmpb %dl, (%eax) / compare %dl with 1 byte from (%eax) 39780Sstevel@tonic-gate jne .not_equal / if not equal, goto .not_equal 39790Sstevel@tonic-gate incl %ecx / %ecx++ (next byte) 39800Sstevel@tonic-gate incl %eax / %eax++ (next byte) 39810Sstevel@tonic-gate decl %edi / %edi-- 39820Sstevel@tonic-gate jnz .byte_loop / if not zero, goto .byte_loop 39830Sstevel@tonic-gate.equal: 39840Sstevel@tonic-gate xorl %eax, %eax / %eax = 0 39850Sstevel@tonic-gate popl %edi / restore register variable 39863412Sjj204856 leave / restore old stack frame 39870Sstevel@tonic-gate ret / return (NULL) 39880Sstevel@tonic-gate .align 4 39890Sstevel@tonic-gate.not_equal: 39900Sstevel@tonic-gate movl $1, %eax / return 1 39910Sstevel@tonic-gate popl %edi / restore register variable 39923412Sjj204856 leave / restore old stack frame 39930Sstevel@tonic-gate ret / return (NULL) 39940Sstevel@tonic-gate SET_SIZE(bcmp) 39950Sstevel@tonic-gate 39960Sstevel@tonic-gate#endif /* __i386 */ 39970Sstevel@tonic-gate 39980Sstevel@tonic-gate#ifdef DEBUG 39990Sstevel@tonic-gate .text 40000Sstevel@tonic-gate.bcmp_panic_msg: 40010Sstevel@tonic-gate .string "bcmp: arguments below kernelbase" 40020Sstevel@tonic-gate#endif /* DEBUG */ 40030Sstevel@tonic-gate 40040Sstevel@tonic-gate#endif /* __lint */ 40053446Smrj 40063446Smrj#if defined(__lint) 40073446Smrj 40083446Smrjuint_t 40093446Smrjbsrw_insn(uint16_t mask) 40103446Smrj{ 40113446Smrj uint_t index = sizeof (mask) * NBBY - 1; 40123446Smrj 40133446Smrj while ((mask & (1 << index)) == 0) 40143446Smrj index--; 40153446Smrj return (index); 40163446Smrj} 40173446Smrj 40183446Smrj#else /* __lint */ 40193446Smrj 40203446Smrj#if defined(__amd64) 40213446Smrj 40223446Smrj ENTRY_NP(bsrw_insn) 40233446Smrj xorl %eax, %eax 40243446Smrj bsrw %di, %ax 40253446Smrj ret 40263446Smrj SET_SIZE(bsrw_insn) 40273446Smrj 40283446Smrj#elif defined(__i386) 40293446Smrj 40303446Smrj ENTRY_NP(bsrw_insn) 40313446Smrj movw 4(%esp), %cx 40323446Smrj xorl %eax, %eax 40333446Smrj bsrw %cx, %ax 40343446Smrj ret 40353446Smrj SET_SIZE(bsrw_insn) 40363446Smrj 40373446Smrj#endif /* __i386 */ 40383446Smrj#endif /* __lint */ 40393446Smrj 40403446Smrj#if defined(__lint) 40413446Smrj 40423446Smrjuint_t 40433446Smrjatomic_btr32(uint32_t *pending, uint_t pil) 40443446Smrj{ 40453446Smrj return (*pending &= ~(1 << pil)); 40463446Smrj} 40473446Smrj 40483446Smrj#else /* __lint */ 40493446Smrj 40503446Smrj#if defined(__i386) 40513446Smrj 40523446Smrj ENTRY_NP(atomic_btr32) 40533446Smrj movl 4(%esp), %ecx 40543446Smrj movl 8(%esp), %edx 40553446Smrj xorl %eax, %eax 40563446Smrj lock 40573446Smrj btrl %edx, (%ecx) 40583446Smrj setc %al 40593446Smrj ret 40603446Smrj SET_SIZE(atomic_btr32) 40613446Smrj 40623446Smrj#endif /* __i386 */ 40633446Smrj#endif /* __lint */ 40643446Smrj 40653446Smrj#if defined(__lint) 40663446Smrj 40673446Smrj/*ARGSUSED*/ 40683446Smrjvoid 40693446Smrjswitch_sp_and_call(void *newsp, void (*func)(uint_t, uint_t), uint_t arg1, 40703446Smrj uint_t arg2) 40713446Smrj{} 40723446Smrj 40733446Smrj#else /* __lint */ 40743446Smrj 40753446Smrj#if defined(__amd64) 40763446Smrj 40773446Smrj ENTRY_NP(switch_sp_and_call) 40783446Smrj pushq %rbp 40793446Smrj movq %rsp, %rbp /* set up stack frame */ 40803446Smrj movq %rdi, %rsp /* switch stack pointer */ 40813446Smrj movq %rdx, %rdi /* pass func arg 1 */ 40823446Smrj movq %rsi, %r11 /* save function to call */ 40833446Smrj movq %rcx, %rsi /* pass func arg 2 */ 40843446Smrj call *%r11 /* call function */ 40853446Smrj leave /* restore stack */ 40863446Smrj ret 40873446Smrj SET_SIZE(switch_sp_and_call) 40883446Smrj 40893446Smrj#elif defined(__i386) 40903446Smrj 40913446Smrj ENTRY_NP(switch_sp_and_call) 40923446Smrj pushl %ebp 40933446Smrj mov %esp, %ebp /* set up stack frame */ 40943446Smrj movl 8(%ebp), %esp /* switch stack pointer */ 40953446Smrj pushl 20(%ebp) /* push func arg 2 */ 40963446Smrj pushl 16(%ebp) /* push func arg 1 */ 40973446Smrj call *12(%ebp) /* call function */ 40983446Smrj addl $8, %esp /* pop arguments */ 40993446Smrj leave /* restore stack */ 41003446Smrj ret 41013446Smrj SET_SIZE(switch_sp_and_call) 41023446Smrj 41033446Smrj#endif /* __i386 */ 41043446Smrj#endif /* __lint */ 41053446Smrj 41063446Smrj#if defined(__lint) 41073446Smrj 41083446Smrjvoid 41093446Smrjkmdb_enter(void) 41103446Smrj{} 41113446Smrj 41123446Smrj#else /* __lint */ 41133446Smrj 41143446Smrj#if defined(__amd64) 41153446Smrj 41163446Smrj ENTRY_NP(kmdb_enter) 41173446Smrj pushq %rbp 41183446Smrj movq %rsp, %rbp 41193446Smrj 41203446Smrj /* 41213446Smrj * Save flags, do a 'cli' then return the saved flags 41223446Smrj */ 41233446Smrj call intr_clear 41243446Smrj 41253446Smrj int $T_DBGENTR 41263446Smrj 41273446Smrj /* 41283446Smrj * Restore the saved flags 41293446Smrj */ 41303446Smrj movq %rax, %rdi 41313446Smrj call intr_restore 41323446Smrj 41333446Smrj leave 41343446Smrj ret 41353446Smrj SET_SIZE(kmdb_enter) 41363446Smrj 41373446Smrj#elif defined(__i386) 41383446Smrj 41393446Smrj ENTRY_NP(kmdb_enter) 41403446Smrj pushl %ebp 41413446Smrj movl %esp, %ebp 41423446Smrj 41433446Smrj /* 41443446Smrj * Save flags, do a 'cli' then return the saved flags 41453446Smrj */ 41463446Smrj call intr_clear 41473446Smrj 41483446Smrj int $T_DBGENTR 41493446Smrj 41503446Smrj /* 41513446Smrj * Restore the saved flags 41523446Smrj */ 41533446Smrj pushl %eax 41543446Smrj call intr_restore 41553446Smrj addl $4, %esp 41563446Smrj 41573446Smrj leave 41583446Smrj ret 41593446Smrj SET_SIZE(kmdb_enter) 41603446Smrj 41613446Smrj#endif /* __i386 */ 41623446Smrj#endif /* __lint */ 41633446Smrj 41643446Smrj#if defined(__lint) 41653446Smrj 41663446Smrjvoid 41673446Smrjreturn_instr(void) 41683446Smrj{} 41693446Smrj 41703446Smrj#else /* __lint */ 41713446Smrj 41723446Smrj ENTRY_NP(return_instr) 41733446Smrj rep; ret /* use 2 byte instruction when branch target */ 41743446Smrj /* AMD Software Optimization Guide - Section 6.2 */ 41753446Smrj SET_SIZE(return_instr) 41763446Smrj 41773446Smrj#endif /* __lint */ 41783446Smrj 41793446Smrj#if defined(__lint) 41803446Smrj 41813446Smrjulong_t 41823446Smrjgetflags(void) 41833446Smrj{ 41843446Smrj return (0); 41853446Smrj} 41863446Smrj 41873446Smrj#else /* __lint */ 41883446Smrj 41893446Smrj#if defined(__amd64) 41903446Smrj 41913446Smrj ENTRY(getflags) 41923446Smrj pushfq 41933446Smrj popq %rax 41945084Sjohnlev#if defined(__xpv) 41955084Sjohnlev CURTHREAD(%rdi) 41965084Sjohnlev KPREEMPT_DISABLE(%rdi) 41975084Sjohnlev /* 41985084Sjohnlev * Synthesize the PS_IE bit from the event mask bit 41995084Sjohnlev */ 42005084Sjohnlev CURVCPU(%r11) 42015084Sjohnlev andq $_BITNOT(PS_IE), %rax 42025084Sjohnlev XEN_TEST_UPCALL_MASK(%r11) 42035084Sjohnlev jnz 1f 42045084Sjohnlev orq $PS_IE, %rax 42055084Sjohnlev1: 42065084Sjohnlev KPREEMPT_ENABLE_NOKP(%rdi) 42075084Sjohnlev#endif 42083446Smrj ret 42093446Smrj SET_SIZE(getflags) 42103446Smrj 42113446Smrj#elif defined(__i386) 42123446Smrj 42133446Smrj ENTRY(getflags) 42143446Smrj pushfl 42153446Smrj popl %eax 42165084Sjohnlev#if defined(__xpv) 42175084Sjohnlev CURTHREAD(%ecx) 42185084Sjohnlev KPREEMPT_DISABLE(%ecx) 42195084Sjohnlev /* 42205084Sjohnlev * Synthesize the PS_IE bit from the event mask bit 42215084Sjohnlev */ 42225084Sjohnlev CURVCPU(%edx) 42235084Sjohnlev andl $_BITNOT(PS_IE), %eax 42245084Sjohnlev XEN_TEST_UPCALL_MASK(%edx) 42255084Sjohnlev jnz 1f 42265084Sjohnlev orl $PS_IE, %eax 42275084Sjohnlev1: 42285084Sjohnlev KPREEMPT_ENABLE_NOKP(%ecx) 42295084Sjohnlev#endif 42303446Smrj ret 42313446Smrj SET_SIZE(getflags) 42323446Smrj 42333446Smrj#endif /* __i386 */ 42343446Smrj 42353446Smrj#endif /* __lint */ 42363647Sbs21162 42373647Sbs21162#if defined(__lint) 42383647Sbs21162 42393647Sbs21162ftrace_icookie_t 42403647Sbs21162ftrace_interrupt_disable(void) 42413647Sbs21162{ return (0); } 42423647Sbs21162 42433647Sbs21162#else /* __lint */ 42443647Sbs21162 42453647Sbs21162#if defined(__amd64) 42463647Sbs21162 42473647Sbs21162 ENTRY(ftrace_interrupt_disable) 42483647Sbs21162 pushfq 42493647Sbs21162 popq %rax 42503647Sbs21162 CLI(%rdx) 42513647Sbs21162 ret 42523647Sbs21162 SET_SIZE(ftrace_interrupt_disable) 42533647Sbs21162 42543647Sbs21162#elif defined(__i386) 42553647Sbs21162 42563647Sbs21162 ENTRY(ftrace_interrupt_disable) 42573647Sbs21162 pushfl 42583647Sbs21162 popl %eax 42593647Sbs21162 CLI(%edx) 42603647Sbs21162 ret 42613647Sbs21162 SET_SIZE(ftrace_interrupt_disable) 42623647Sbs21162 42633647Sbs21162#endif /* __i386 */ 42643647Sbs21162#endif /* __lint */ 42653647Sbs21162 42663647Sbs21162#if defined(__lint) 42673647Sbs21162 42683647Sbs21162/*ARGSUSED*/ 42693647Sbs21162void 42703647Sbs21162ftrace_interrupt_enable(ftrace_icookie_t cookie) 42713647Sbs21162{} 42723647Sbs21162 42733647Sbs21162#else /* __lint */ 42743647Sbs21162 42753647Sbs21162#if defined(__amd64) 42763647Sbs21162 42773647Sbs21162 ENTRY(ftrace_interrupt_enable) 42783647Sbs21162 pushq %rdi 42793647Sbs21162 popfq 42803647Sbs21162 ret 42813647Sbs21162 SET_SIZE(ftrace_interrupt_enable) 42823647Sbs21162 42833647Sbs21162#elif defined(__i386) 42843647Sbs21162 42853647Sbs21162 ENTRY(ftrace_interrupt_enable) 42863647Sbs21162 movl 4(%esp), %eax 42873647Sbs21162 pushl %eax 42883647Sbs21162 popfl 42893647Sbs21162 ret 42903647Sbs21162 SET_SIZE(ftrace_interrupt_enable) 42913647Sbs21162 42927589SVikram.Hegde@Sun.COM#endif /* __i386 */ 42933647Sbs21162#endif /* __lint */ 42947589SVikram.Hegde@Sun.COM 42957589SVikram.Hegde@Sun.COM#if defined (__lint) 42967589SVikram.Hegde@Sun.COM 42977589SVikram.Hegde@Sun.COM/*ARGSUSED*/ 42987589SVikram.Hegde@Sun.COMvoid 42997589SVikram.Hegde@Sun.COMclflush_insn(caddr_t addr) 43007589SVikram.Hegde@Sun.COM{} 43017589SVikram.Hegde@Sun.COM 43027589SVikram.Hegde@Sun.COM#else /* __lint */ 43037589SVikram.Hegde@Sun.COM 43047589SVikram.Hegde@Sun.COM#if defined (__amd64) 43057589SVikram.Hegde@Sun.COM ENTRY(clflush_insn) 43067589SVikram.Hegde@Sun.COM clflush (%rdi) 43077589SVikram.Hegde@Sun.COM ret 43087589SVikram.Hegde@Sun.COM SET_SIZE(clflush_insn) 43097589SVikram.Hegde@Sun.COM#elif defined (__i386) 43107589SVikram.Hegde@Sun.COM ENTRY(clflush_insn) 43117589SVikram.Hegde@Sun.COM movl 4(%esp), %eax 43127589SVikram.Hegde@Sun.COM clflush (%eax) 43137589SVikram.Hegde@Sun.COM ret 43147589SVikram.Hegde@Sun.COM SET_SIZE(clflush_insn) 43157589SVikram.Hegde@Sun.COM 43167589SVikram.Hegde@Sun.COM#endif /* __i386 */ 43177589SVikram.Hegde@Sun.COM#endif /* __lint */ 43187589SVikram.Hegde@Sun.COM 43197589SVikram.Hegde@Sun.COM#if defined (__lint) 43207589SVikram.Hegde@Sun.COM/*ARGSUSED*/ 43217589SVikram.Hegde@Sun.COMvoid 43227589SVikram.Hegde@Sun.COMmfence_insn(void) 43237589SVikram.Hegde@Sun.COM{} 43247589SVikram.Hegde@Sun.COM 43257589SVikram.Hegde@Sun.COM#else /* __lint */ 43267589SVikram.Hegde@Sun.COM 43277589SVikram.Hegde@Sun.COM#if defined (__amd64) 43287589SVikram.Hegde@Sun.COM ENTRY(mfence_insn) 43297589SVikram.Hegde@Sun.COM mfence 43307589SVikram.Hegde@Sun.COM ret 43317589SVikram.Hegde@Sun.COM SET_SIZE(mfence_insn) 43327589SVikram.Hegde@Sun.COM#elif defined (__i386) 43337589SVikram.Hegde@Sun.COM ENTRY(mfence_insn) 43347589SVikram.Hegde@Sun.COM mfence 43357589SVikram.Hegde@Sun.COM ret 43367589SVikram.Hegde@Sun.COM SET_SIZE(mfence_insn) 43377589SVikram.Hegde@Sun.COM 43387589SVikram.Hegde@Sun.COM#endif /* __i386 */ 43397589SVikram.Hegde@Sun.COM#endif /* __lint */ 43408990SSurya.Prakki@Sun.COM 43418990SSurya.Prakki@Sun.COM/* 43428990SSurya.Prakki@Sun.COM * This is how VMware lets the guests figure that they are running 43438990SSurya.Prakki@Sun.COM * on top of VMWare platform : 43448990SSurya.Prakki@Sun.COM * Write 0xA in the ECX register and put the I/O port address value of 43458990SSurya.Prakki@Sun.COM * 0x564D5868 in the EAX register. Then read a word from port 0x5658. 43468990SSurya.Prakki@Sun.COM * If VMWare is installed than this code will be executed correctly and 43478990SSurya.Prakki@Sun.COM * the EBX register will contain the same I/O port address value of 0x564D5868. 43488990SSurya.Prakki@Sun.COM * If VMWare is not installed then OS will return an exception on port access. 43498990SSurya.Prakki@Sun.COM */ 43508990SSurya.Prakki@Sun.COM#if defined(__lint) 43518990SSurya.Prakki@Sun.COM 43528990SSurya.Prakki@Sun.COMint 43538990SSurya.Prakki@Sun.COMvmware_platform(void) { return (1); } 43548990SSurya.Prakki@Sun.COM 43558990SSurya.Prakki@Sun.COM#else 43568990SSurya.Prakki@Sun.COM 43578990SSurya.Prakki@Sun.COM#if defined(__amd64) 43588990SSurya.Prakki@Sun.COM 43598990SSurya.Prakki@Sun.COM ENTRY(vmware_platform) 43608990SSurya.Prakki@Sun.COM pushq %rbx 43618990SSurya.Prakki@Sun.COM xorl %ebx, %ebx 43628990SSurya.Prakki@Sun.COM movl $0x564d5868, %eax 43638990SSurya.Prakki@Sun.COM movl $0xa, %ecx 43648990SSurya.Prakki@Sun.COM movl $0x5658, %edx 43658990SSurya.Prakki@Sun.COM inl (%dx) 43668990SSurya.Prakki@Sun.COM movl $0x564d5868, %ecx 43678990SSurya.Prakki@Sun.COM xorl %eax, %eax 43688990SSurya.Prakki@Sun.COM cmpl %ecx, %ebx 43698990SSurya.Prakki@Sun.COM jne 1f 43708990SSurya.Prakki@Sun.COM incl %eax 43718990SSurya.Prakki@Sun.COM1: 43728990SSurya.Prakki@Sun.COM popq %rbx 43738990SSurya.Prakki@Sun.COM ret 43748990SSurya.Prakki@Sun.COM SET_SIZE(vmware_platform) 43758990SSurya.Prakki@Sun.COM 43768990SSurya.Prakki@Sun.COM#elif defined(__i386) 43778990SSurya.Prakki@Sun.COM 43788990SSurya.Prakki@Sun.COM ENTRY(vmware_platform) 43798990SSurya.Prakki@Sun.COM pushl %ebx 43808990SSurya.Prakki@Sun.COM pushl %ecx 43818990SSurya.Prakki@Sun.COM pushl %edx 43828990SSurya.Prakki@Sun.COM xorl %ebx, %ebx 43838990SSurya.Prakki@Sun.COM movl $0x564d5868, %eax 43848990SSurya.Prakki@Sun.COM movl $0xa, %ecx 43858990SSurya.Prakki@Sun.COM movl $0x5658, %edx 43868990SSurya.Prakki@Sun.COM inl (%dx) 43878990SSurya.Prakki@Sun.COM movl $0x564d5868, %ecx 43888990SSurya.Prakki@Sun.COM xorl %eax, %eax 43898990SSurya.Prakki@Sun.COM cmpl %ecx, %ebx 43908990SSurya.Prakki@Sun.COM jne 1f 43918990SSurya.Prakki@Sun.COM incl %eax 43928990SSurya.Prakki@Sun.COM1: 43938990SSurya.Prakki@Sun.COM popl %edx 43948990SSurya.Prakki@Sun.COM popl %ecx 43958990SSurya.Prakki@Sun.COM popl %ebx 43968990SSurya.Prakki@Sun.COM ret 43978990SSurya.Prakki@Sun.COM SET_SIZE(vmware_platform) 43988990SSurya.Prakki@Sun.COM 43998990SSurya.Prakki@Sun.COM#endif /* __i386 */ 44008990SSurya.Prakki@Sun.COM#endif /* __lint */ 4401