xref: /titanic_50/usr/src/uts/intel/io/acpica/osl_ml.s (revision db2bae3047e71d795bde12e3baa621f4b6cc8930)
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