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 #include <sys/asm_linkage.h>
27 #include <sys/asm_misc.h>
28
29 #if defined(lint) || defined(__lint)
30 #include <sys/types.h>
31 #include "acpi.h"
32 #endif /* lint */
33
34 /*
35 * Implementation as specific by ACPI 3.0 specification
36 * section 5.2.10.1
37 *
38 * Global Lock Structure within the FACS
39 *
40 * |-----------------------------------------------------------------------|
41 * | Field | Bit Length | Bit Offset | Description |
42 * |---------|------------|------------|-----------------------------------|
43 * | Pending | 1 | 0 | Non-zero indicates that a request |
44 * | | | | for ownership of the global lock |
45 * | | | | is pending. |
46 * |---------|------------|------------|-----------------------------------|
47 * | Owned | 1 | 1 | Non-zero indicates that the Global|
48 * | | | | lock is owned. |
49 * |---------|------------|------------|-----------------------------------|
50 * | Reserved| 30 | 2 | Reserved for future use |
51 * |---------|------------|------------|-----------------------------------|
52 */
53
54 /* Offset of GlobalLock element in FACS structure */
55 #define GlobalLock 0x10
56
57 #if defined(lint) || defined(__lint)
58
59 /* ARGSUSED */
60 UINT32
61 __acpi_acquire_global_lock(void *Facs)
62 { return (0); }
63
64 #else /* lint */
65
66 #if defined(__amd64)
67 ENTRY(__acpi_acquire_global_lock)
68 movq $0xff, %rax / error return if FACS is null
69 orq %rdi, %rdi / %rdi contains pointer to FACS
70 jz 1f
71 leaq GlobalLock(%rdi), %rdi / make %rdi point at the lock
72 0:
73 movl (%rdi), %eax / get current value of Global Lock
74 movl %eax, %edx
75 andl $0xFFFFFFFE, %edx / Clear pending bit
76 btsl $1, %edx / Check and set owner bit
77 adcl $0, %edx / If owned, set pending bit
78 lock
79 cmpxchgl %edx, (%rdi) / Attempt to set new value
80 jnz 0b / If not set, try again
81 cmpb $3, %dl / Was it acquired or marked pending?
82 sbbq %rax, %rax / acquired = -1, pending = 0
83 1:
84 ret
85 SET_SIZE(__acpi_acquire_global_lock)
86
87 #elif defined(__i386)
88
89 ENTRY(__acpi_acquire_global_lock)
90 movl $0xff, %eax / error return if FACS is null
91 movl 4(%esp), %ecx / %ecx contains pointer to FACS
92 orl %ecx, %ecx
93 jz 1f
94 leal GlobalLock(%ecx), %ecx / make %ecx point at the lock
95 0:
96 movl (%ecx), %eax
97 movl %eax, %edx
98 andl $0xFFFFFFFE, %edx
99 btsl $1, %edx
100 adcl $0, %edx
101 lock
102 cmpxchgl %edx, (%ecx)
103 jnz 0b
104 cmpb $3, %dl
105 sbbl %eax, %eax
106 1:
107 ret
108 SET_SIZE(__acpi_acquire_global_lock)
109
110 #endif /* i386 */
111
112 #endif /* lint */
113
114
115 #if defined(lint) || defined(__lint)
116
117 /* ARGSUSED */
118 UINT32
119 __acpi_release_global_lock(void *Facs)
120 { return (0); }
121
122 #else /* lint */
123
124 #if defined(__amd64)
125 ENTRY(__acpi_release_global_lock)
126 xorq %rax, %rax / error return if FACS is null
127 orq %rdi, %rdi / %rdi contains pointer to FACS
128 jz 1f
129 leaq GlobalLock(%rdi), %rdi / make %rdi point at the lock
130 0:
131 movl (%rdi), %eax
132 movl %eax, %edx
133 andl $0xFFFFFFFC, %edx
134 lock
135 cmpxchgl %edx, (%rdi)
136 jnz 0b
137 andq $1, %rax
138 1:
139 ret
140 SET_SIZE(__acpi_release_global_lock)
141
142 #elif defined(__i386)
143
144 ENTRY(__acpi_release_global_lock)
145 xorl %eax, %eax / error return if FACS is null
146 movl 4(%esp), %ecx / %ecx contains pointer to FACS
147 orl %ecx, %ecx
148 jz 1f
149 leal GlobalLock(%ecx), %ecx / make %ecx point at the lock
150 0:
151 movl (%ecx), %eax
152 movl %eax, %edx
153 andl $0xFFFFFFFC, %edx
154 lock
155 cmpxchgl %edx, (%ecx)
156 jnz 0b
157 andl $1, %eax
158 1:
159 ret
160 SET_SIZE(__acpi_release_global_lock)
161
162 #endif /* i386 */
163
164 #endif /* lint */
165
166
167 /*
168 * execute WBINVD instruction
169 */
170
171 #if defined(lint) || defined(__lint)
172
173 /* ARGSUSED */
174 void
175 __acpi_wbinvd(void)
176 { }
177
178 #else /* lint */
179
180 ENTRY(__acpi_wbinvd)
181 wbinvd
182 ret
183 SET_SIZE(__acpi_wbinvd)
184
185 #endif /* lint */
186
|
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
61 0:
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
72 1:
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
82 0:
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
90 1:
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
|