xref: /illumos-gate/usr/src/uts/intel/io/acpica/osl_ml.S (revision 012e6ce759c490003aed29439cc47d3d73a99ad3)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26/*
27 * Copyright 2019 Joyent, Inc.
28 */
29
30#include <sys/asm_linkage.h>
31#include <sys/asm_misc.h>
32
33/*
34 * Implementation as specific by ACPI 3.0 specification
35 * section 5.2.10.1
36 *
37 * Global Lock Structure within the FACS
38 *
39 * |-----------------------------------------------------------------------|
40 * |  Field  | Bit Length | Bit Offset |           Description             |
41 * |---------|------------|------------|-----------------------------------|
42 * | Pending |     1      |     0      | Non-zero indicates that a request |
43 * |         |            |            | for ownership of the global lock  |
44 * |         |            |            | is pending.                       |
45 * |---------|------------|------------|-----------------------------------|
46 * | Owned   |     1      |     1      | Non-zero indicates that the Global|
47 * |         |            |            | lock is owned.                    |
48 * |---------|------------|------------|-----------------------------------|
49 * | Reserved|     30     |     2      | Reserved for future use           |
50 * |---------|------------|------------|-----------------------------------|
51 */
52
53/* Offset of GlobalLock element in FACS structure */
54#define	GlobalLock	0x10
55
56	ENTRY(__acpi_acquire_global_lock)
57	movq	$0xff, %rax		/ error return if FACS is null
58	orq	%rdi, %rdi		/ %rdi contains pointer to FACS
59	jz	1f
60	leaq	GlobalLock(%rdi), %rdi	/ make %rdi point at the lock
610:
62	movl	(%rdi), %eax		/ get current value of Global Lock
63	movl	%eax, %edx
64	andl	$0xFFFFFFFE, %edx	/ Clear pending bit
65	btsl	$1, %edx		/ Check and set owner bit
66	adcl	$0, %edx		/ If owned, set pending bit
67	lock
68	cmpxchgl %edx, (%rdi)		/ Attempt to set new value
69	jnz	0b			/ If not set, try again
70	cmpb	$3, %dl			/ Was it acquired or marked pending?
71	sbbq	%rax, %rax		/ acquired = -1, pending = 0
721:
73	ret
74	SET_SIZE(__acpi_acquire_global_lock)
75
76
77	ENTRY(__acpi_release_global_lock)
78	xorq	%rax, %rax	/ error return if FACS is null
79	orq	%rdi, %rdi	/ %rdi contains pointer to FACS
80	jz	1f
81	leaq	GlobalLock(%rdi), %rdi	/ make %rdi point at the lock
820:
83	movl	(%rdi), %eax
84	movl	%eax, %edx
85	andl	$0xFFFFFFFC, %edx
86	lock
87	cmpxchgl %edx, (%rdi)
88	jnz	0b
89	andq	$1, %rax
901:
91	ret
92	SET_SIZE(__acpi_release_global_lock)
93
94
95/*
96 * execute WBINVD instruction
97 */
98
99	ENTRY(__acpi_wbinvd)
100	wbinvd
101	ret
102	SET_SIZE(__acpi_wbinvd)
103
104