1ae115bc7Smrj/* 2ae115bc7Smrj * CDDL HEADER START 3ae115bc7Smrj * 4ae115bc7Smrj * The contents of this file are subject to the terms of the 5*db2bae30SDana Myers * Common Development and Distribution License (the "License"). 6*db2bae30SDana Myers * You may not use this file except in compliance with the License. 7ae115bc7Smrj * 8ae115bc7Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9ae115bc7Smrj * or http://www.opensolaris.org/os/licensing. 10ae115bc7Smrj * See the License for the specific language governing permissions 11ae115bc7Smrj * and limitations under the License. 12ae115bc7Smrj * 13ae115bc7Smrj * When distributing Covered Code, include this CDDL HEADER in each 14ae115bc7Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15ae115bc7Smrj * If applicable, add the following below this CDDL HEADER, with the 16ae115bc7Smrj * fields enclosed by brackets "[]" replaced with your own identifying 17ae115bc7Smrj * information: Portions Copyright [yyyy] [name of copyright owner] 18ae115bc7Smrj * 19ae115bc7Smrj * CDDL HEADER END 20ae115bc7Smrj */ 21ae115bc7Smrj/* 22*db2bae30SDana Myers * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23ae115bc7Smrj * Use is subject to license terms. 24ae115bc7Smrj */ 25ae115bc7Smrj 26ae115bc7Smrj#include <sys/asm_linkage.h> 27ae115bc7Smrj#include <sys/asm_misc.h> 28ae115bc7Smrj 29ae115bc7Smrj#if defined(lint) || defined(__lint) 30ae115bc7Smrj#include <sys/types.h> 31ae115bc7Smrj#include "acpi.h" 32ae115bc7Smrj#endif /* lint */ 33ae115bc7Smrj 34ae115bc7Smrj/* 35ae115bc7Smrj * Implementation as specific by ACPI 3.0 specification 36ae115bc7Smrj * section 5.2.10.1 37ae115bc7Smrj * 38ae115bc7Smrj * Global Lock Structure within the FACS 39ae115bc7Smrj * 40ae115bc7Smrj * |-----------------------------------------------------------------------| 41ae115bc7Smrj * | Field | Bit Length | Bit Offset | Description | 42ae115bc7Smrj * |---------|------------|------------|-----------------------------------| 43ae115bc7Smrj * | Pending | 1 | 0 | Non-zero indicates that a request | 44ae115bc7Smrj * | | | | for ownership of the global lock | 45ae115bc7Smrj * | | | | is pending. | 46ae115bc7Smrj * |---------|------------|------------|-----------------------------------| 47ae115bc7Smrj * | Owned | 1 | 1 | Non-zero indicates that the Global| 48ae115bc7Smrj * | | | | lock is owned. | 49ae115bc7Smrj * |---------|------------|------------|-----------------------------------| 50ae115bc7Smrj * | Reserved| 30 | 2 | Reserved for future use | 51ae115bc7Smrj * |---------|------------|------------|-----------------------------------| 52ae115bc7Smrj */ 53ae115bc7Smrj 54*db2bae30SDana Myers/* Offset of GlobalLock element in FACS structure */ 55*db2bae30SDana Myers#define GlobalLock 0x10 56ae115bc7Smrj 57ae115bc7Smrj#if defined(lint) || defined(__lint) 58ae115bc7Smrj 59ae115bc7Smrj/* ARGSUSED */ 60ae115bc7SmrjUINT32 61*db2bae30SDana Myers__acpi_acquire_global_lock(void *Facs) 62ae115bc7Smrj{ return (0); } 63ae115bc7Smrj 64ae115bc7Smrj#else /* lint */ 65ae115bc7Smrj 66ae115bc7Smrj#if defined(__amd64) 67ae115bc7Smrj ENTRY(__acpi_acquire_global_lock) 68*db2bae30SDana Myers movq $0xff, %rax / error return if FACS is null 69*db2bae30SDana Myers orq %rdi, %rdi / %rdi contains pointer to FACS 70*db2bae30SDana Myers jz 1f 71*db2bae30SDana Myers leaq GlobalLock(%rdi), %rdi / make %rdi point at the lock 72*db2bae30SDana Myers0: 73ae115bc7Smrj movl (%rdi), %eax / get current value of Global Lock 74ae115bc7Smrj movl %eax, %edx 75ae115bc7Smrj andl $0xFFFFFFFE, %edx / Clear pending bit 76ae115bc7Smrj btsl $1, %edx / Check and set owner bit 77ae115bc7Smrj adcl $0, %edx / If owned, set pending bit 78ae115bc7Smrj lock 79ae115bc7Smrj cmpxchgl %edx, (%rdi) / Attempt to set new value 80*db2bae30SDana Myers jnz 0b / If not set, try again 81ae115bc7Smrj cmpb $3, %dl / Was it acquired or marked pending? 82ae115bc7Smrj sbbq %rax, %rax / acquired = -1, pending = 0 83*db2bae30SDana Myers1: 84ae115bc7Smrj ret 85ae115bc7Smrj SET_SIZE(__acpi_acquire_global_lock) 86ae115bc7Smrj 87ae115bc7Smrj#elif defined(__i386) 88ae115bc7Smrj 89ae115bc7Smrj ENTRY(__acpi_acquire_global_lock) 90*db2bae30SDana Myers movl $0xff, %eax / error return if FACS is null 91*db2bae30SDana Myers movl 4(%esp), %ecx / %ecx contains pointer to FACS 92*db2bae30SDana Myers orl %ecx, %ecx 93*db2bae30SDana Myers jz 1f 94*db2bae30SDana Myers leal GlobalLock(%ecx), %ecx / make %ecx point at the lock 95*db2bae30SDana Myers0: 96ae115bc7Smrj movl (%ecx), %eax 97ae115bc7Smrj movl %eax, %edx 98ae115bc7Smrj andl $0xFFFFFFFE, %edx 99ae115bc7Smrj btsl $1, %edx 100ae115bc7Smrj adcl $0, %edx 101ae115bc7Smrj lock 102ae115bc7Smrj cmpxchgl %edx, (%ecx) 103*db2bae30SDana Myers jnz 0b 104ae115bc7Smrj cmpb $3, %dl 105ae115bc7Smrj sbbl %eax, %eax 106*db2bae30SDana Myers1: 107ae115bc7Smrj ret 108ae115bc7Smrj SET_SIZE(__acpi_acquire_global_lock) 109ae115bc7Smrj 110ae115bc7Smrj#endif /* i386 */ 111ae115bc7Smrj 112ae115bc7Smrj#endif /* lint */ 113ae115bc7Smrj 114ae115bc7Smrj 115ae115bc7Smrj#if defined(lint) || defined(__lint) 116ae115bc7Smrj 117ae115bc7Smrj/* ARGSUSED */ 118ae115bc7SmrjUINT32 119*db2bae30SDana Myers__acpi_release_global_lock(void *Facs) 120ae115bc7Smrj{ return (0); } 121ae115bc7Smrj 122ae115bc7Smrj#else /* lint */ 123ae115bc7Smrj 124ae115bc7Smrj#if defined(__amd64) 125ae115bc7Smrj ENTRY(__acpi_release_global_lock) 126*db2bae30SDana Myers xorq %rax, %rax / error return if FACS is null 127*db2bae30SDana Myers orq %rdi, %rdi / %rdi contains pointer to FACS 128*db2bae30SDana Myers jz 1f 129*db2bae30SDana Myers leaq GlobalLock(%rdi), %rdi / make %rdi point at the lock 130*db2bae30SDana Myers0: 131ae115bc7Smrj movl (%rdi), %eax 132ae115bc7Smrj movl %eax, %edx 133ae115bc7Smrj andl $0xFFFFFFFC, %edx 134ae115bc7Smrj lock 135ae115bc7Smrj cmpxchgl %edx, (%rdi) 136*db2bae30SDana Myers jnz 0b 137*db2bae30SDana Myers andq $1, %rax 138*db2bae30SDana Myers1: 139ae115bc7Smrj ret 140ae115bc7Smrj SET_SIZE(__acpi_release_global_lock) 141ae115bc7Smrj 142ae115bc7Smrj#elif defined(__i386) 143ae115bc7Smrj 144ae115bc7Smrj ENTRY(__acpi_release_global_lock) 145*db2bae30SDana Myers xorl %eax, %eax / error return if FACS is null 146*db2bae30SDana Myers movl 4(%esp), %ecx / %ecx contains pointer to FACS 147*db2bae30SDana Myers orl %ecx, %ecx 148*db2bae30SDana Myers jz 1f 149*db2bae30SDana Myers leal GlobalLock(%ecx), %ecx / make %ecx point at the lock 150*db2bae30SDana Myers0: 151ae115bc7Smrj movl (%ecx), %eax 152ae115bc7Smrj movl %eax, %edx 153ae115bc7Smrj andl $0xFFFFFFFC, %edx 154ae115bc7Smrj lock 155ae115bc7Smrj cmpxchgl %edx, (%ecx) 156*db2bae30SDana Myers jnz 0b 157ae115bc7Smrj andl $1, %eax 158*db2bae30SDana Myers1: 159ae115bc7Smrj ret 160ae115bc7Smrj SET_SIZE(__acpi_release_global_lock) 161ae115bc7Smrj 162ae115bc7Smrj#endif /* i386 */ 163ae115bc7Smrj 164ae115bc7Smrj#endif /* lint */ 165ae115bc7Smrj 166ae115bc7Smrj 167ae115bc7Smrj/* 168ae115bc7Smrj * execute WBINVD instruction 169ae115bc7Smrj */ 170ae115bc7Smrj 171ae115bc7Smrj#if defined(lint) || defined(__lint) 172ae115bc7Smrj 173ae115bc7Smrj/* ARGSUSED */ 174ae115bc7Smrjvoid 175ae115bc7Smrj__acpi_wbinvd(void) 176ae115bc7Smrj{ } 177ae115bc7Smrj 178ae115bc7Smrj#else /* lint */ 179ae115bc7Smrj 180ae115bc7Smrj ENTRY(__acpi_wbinvd) 181ae115bc7Smrj wbinvd 182ae115bc7Smrj ret 183ae115bc7Smrj SET_SIZE(__acpi_wbinvd) 184ae115bc7Smrj 185ae115bc7Smrj#endif /* lint */ 186ae115bc7Smrj 187