2 /******************************************************************************
4 * Module Name: amutils - interpreter/scanner utilities
7 *****************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #define _COMPONENT ACPI_EXECUTER
32 MODULE_NAME ("amutils")
35 /*******************************************************************************
37 * FUNCTION: Acpi_aml_enter_interpreter
41 * DESCRIPTION: Enter the interpreter execution region
42 * TBD: should be a macro
44 ******************************************************************************/
47 acpi_aml_enter_interpreter (void)
52 status
= acpi_cm_acquire_mutex (ACPI_MTX_EXECUTE
);
57 /*******************************************************************************
59 * FUNCTION: Acpi_aml_exit_interpreter
63 * DESCRIPTION: Exit the interpreter execution region
65 * Cases where the interpreter is unlocked:
66 * 1) Completion of the execution of a control method
67 * 2) Method blocked on a Sleep() AML opcode
68 * 3) Method blocked on an Acquire() AML opcode
69 * 4) Method blocked on a Wait() AML opcode
70 * 5) Method blocked to acquire the global lock
71 * 6) Method blocked to execute a serialized control method that is
73 * 7) About to invoke a user-installed opregion handler
75 * TBD: should be a macro
77 ******************************************************************************/
80 acpi_aml_exit_interpreter (void)
83 acpi_cm_release_mutex (ACPI_MTX_EXECUTE
);
89 /*******************************************************************************
91 * FUNCTION: Acpi_aml_validate_object_type
93 * PARAMETERS: Type Object type to validate
95 * DESCRIPTION: Determine if a type is a valid ACPI object type
97 ******************************************************************************/
100 acpi_aml_validate_object_type (
101 ACPI_OBJECT_TYPE type
)
104 if ((type
> ACPI_TYPE_MAX
&& type
< INTERNAL_TYPE_BEGIN
) ||
105 (type
> INTERNAL_TYPE_MAX
)) {
113 /*******************************************************************************
115 * FUNCTION: Acpi_aml_truncate_for32bit_table
117 * PARAMETERS: Obj_desc - Object to be truncated
118 * Walk_state - Current walk state
119 * (A method must be executing)
123 * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
124 * belongs to a 32-bit ACPI table.
126 ******************************************************************************/
129 acpi_aml_truncate_for32bit_table (
130 ACPI_OPERAND_OBJECT
*obj_desc
,
131 ACPI_WALK_STATE
*walk_state
)
135 * Object must be a valid number and we must be executing
140 (obj_desc
->common
.type
!= ACPI_TYPE_INTEGER
) ||
141 (!walk_state
->method_node
)) {
145 if (walk_state
->method_node
->flags
& ANOBJ_DATA_WIDTH_32
) {
147 * We are running a method that exists in a 32-bit ACPI table.
148 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
150 obj_desc
->integer
.value
&= (ACPI_INTEGER
) ACPI_UINT32_MAX
;
155 /*******************************************************************************
157 * FUNCTION: Acpi_aml_acquire_global_lock
159 * PARAMETERS: Rule - Lock rule: Always_lock, Never_lock
161 * RETURN: TRUE/FALSE indicating whether the lock was actually acquired
163 * DESCRIPTION: Obtain the global lock and keep track of this fact via two
164 * methods. A global variable keeps the state of the lock, and
165 * the state is returned to the caller.
167 ******************************************************************************/
170 acpi_aml_acquire_global_lock (
177 /* Only attempt lock if the Rule says so */
179 if (rule
== (u32
) GLOCK_ALWAYS_LOCK
) {
180 /* We should attempt to get the lock */
182 status
= acpi_ev_acquire_global_lock ();
183 if (ACPI_SUCCESS (status
)) {
193 /*******************************************************************************
195 * FUNCTION: Acpi_aml_release_global_lock
197 * PARAMETERS: Locked_by_me - Return value from corresponding call to
198 * Acquire_global_lock.
202 * DESCRIPTION: Release the global lock if it is locked.
204 ******************************************************************************/
207 acpi_aml_release_global_lock (
212 /* Only attempt unlock if the caller locked it */
215 /* OK, now release the lock */
217 acpi_ev_release_global_lock ();
225 /*******************************************************************************
227 * FUNCTION: Acpi_aml_digits_needed
229 * PARAMETERS: val - Value to be represented
230 * base - Base of representation
232 * RETURN: the number of digits needed to represent val in base
234 ******************************************************************************/
237 acpi_aml_digits_needed (
245 REPORT_ERROR (("Aml_digits_needed: Internal error - Invalid base\n"));
249 for (num_digits
= 1; (val
= ACPI_DIVIDE (val
,base
)); ++num_digits
) { ; }
256 /*******************************************************************************
260 * PARAMETERS: Value - Value to be converted
262 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
264 ******************************************************************************/
283 out
.bytes
[0] = in
.bytes
[3];
284 out
.bytes
[1] = in
.bytes
[2];
285 out
.bytes
[2] = in
.bytes
[1];
286 out
.bytes
[3] = in
.bytes
[0];
292 /*******************************************************************************
294 * FUNCTION: Acpi_aml_eisa_id_to_string
296 * PARAMETERS: Numeric_id - EISA ID to be converted
297 * Out_string - Where to put the converted string (8 bytes)
299 * DESCRIPTION: Convert a numeric EISA ID to string representation
301 ******************************************************************************/
304 acpi_aml_eisa_id_to_string (
306 NATIVE_CHAR
*out_string
)
310 /* swap to big-endian to get contiguous bits */
312 id
= _ntohl (numeric_id
);
314 out_string
[0] = (char) ('@' + ((id
>> 26) & 0x1f));
315 out_string
[1] = (char) ('@' + ((id
>> 21) & 0x1f));
316 out_string
[2] = (char) ('@' + ((id
>> 16) & 0x1f));
317 out_string
[3] = acpi_gbl_hex_to_ascii
[(id
>> 12) & 0xf];
318 out_string
[4] = acpi_gbl_hex_to_ascii
[(id
>> 8) & 0xf];
319 out_string
[5] = acpi_gbl_hex_to_ascii
[(id
>> 4) & 0xf];
320 out_string
[6] = acpi_gbl_hex_to_ascii
[id
& 0xf];
327 /*******************************************************************************
329 * FUNCTION: Acpi_aml_unsigned_integer_to_string
331 * PARAMETERS: Value - Value to be converted
332 * Out_string - Where to put the converted string (8 bytes)
334 * RETURN: Convert a number to string representation
336 ******************************************************************************/
339 acpi_aml_unsigned_integer_to_string (
341 NATIVE_CHAR
*out_string
)
347 digits_needed
= acpi_aml_digits_needed (value
, 10);
349 out_string
[digits_needed
] = '\0';
351 for (count
= digits_needed
; count
> 0; count
--) {
352 out_string
[count
-1] = (NATIVE_CHAR
) ('0' + (ACPI_MODULO (value
, 10)));
353 value
= ACPI_DIVIDE (value
, 10);