1 2/****************************************************************************** 3 * 4 * Module Name: exutils - interpreter/scanner utilities 5 * $Revision: 1.1.1.1 $ 6 * 7 *****************************************************************************/ 8 9/* 10 * Copyright (C) 2000, 2001 R. Byron Moore 11 * 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. 16 * 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. 21 * 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 25 */ 26 27 28/* 29 * DEFINE_AML_GLOBALS is tested in amlcode.h 30 * to determine whether certain global names should be "defined" or only 31 * "declared" in the current compilation. This enhances maintainability 32 * by enabling a single header file to embody all knowledge of the names 33 * in question. 34 * 35 * Exactly one module of any executable should #define DEFINE_GLOBALS 36 * before #including the header files which use this convention. The 37 * names in question will be defined and initialized in that module, 38 * and declared as extern in all other modules which #include those 39 * header files. 40 */ 41 42#define DEFINE_AML_GLOBALS 43 44#include "acpi.h" 45#include "acparser.h" 46#include "acinterp.h" 47#include "amlcode.h" 48#include "acnamesp.h" 49#include "acevents.h" 50#include "acparser.h" 51 52#define _COMPONENT ACPI_EXECUTER 53 MODULE_NAME ("exutils") 54 55 56/******************************************************************************* 57 * 58 * FUNCTION: Acpi_ex_enter_interpreter 59 * 60 * PARAMETERS: None 61 * 62 * DESCRIPTION: Enter the interpreter execution region 63 * TBD: should be a macro 64 * 65 ******************************************************************************/ 66 67acpi_status 68acpi_ex_enter_interpreter (void) 69{ 70 acpi_status status; 71 72 FUNCTION_TRACE ("Ex_enter_interpreter"); 73 74 75 status = acpi_ut_acquire_mutex (ACPI_MTX_EXECUTE); 76 return_ACPI_STATUS (status); 77} 78 79 80/******************************************************************************* 81 * 82 * FUNCTION: Acpi_ex_exit_interpreter 83 * 84 * PARAMETERS: None 85 * 86 * DESCRIPTION: Exit the interpreter execution region 87 * 88 * Cases where the interpreter is unlocked: 89 * 1) Completion of the execution of a control method 90 * 2) Method blocked on a Sleep() AML opcode 91 * 3) Method blocked on an Acquire() AML opcode 92 * 4) Method blocked on a Wait() AML opcode 93 * 5) Method blocked to acquire the global lock 94 * 6) Method blocked to execute a serialized control method that is 95 * already executing 96 * 7) About to invoke a user-installed opregion handler 97 * 98 * TBD: should be a macro 99 * 100 ******************************************************************************/ 101 102void 103acpi_ex_exit_interpreter (void) 104{ 105 FUNCTION_TRACE ("Ex_exit_interpreter"); 106 107 108 acpi_ut_release_mutex (ACPI_MTX_EXECUTE); 109 110 return_VOID; 111} 112 113 114/******************************************************************************* 115 * 116 * FUNCTION: Acpi_ex_validate_object_type 117 * 118 * PARAMETERS: Type Object type to validate 119 * 120 * DESCRIPTION: Determine if a type is a valid ACPI object type 121 * 122 ******************************************************************************/ 123 124u8 125acpi_ex_validate_object_type ( 126 acpi_object_type type) 127{ 128 129 FUNCTION_ENTRY (); 130 131 132 if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) || 133 (type > INTERNAL_TYPE_MAX)) { 134 return (FALSE); 135 } 136 137 return (TRUE); 138} 139 140 141/******************************************************************************* 142 * 143 * FUNCTION: Acpi_ex_truncate_for32bit_table 144 * 145 * PARAMETERS: Obj_desc - Object to be truncated 146 * Walk_state - Current walk state 147 * (A method must be executing) 148 * 149 * RETURN: none 150 * 151 * DESCRIPTION: Truncate a number to 32-bits if the currently executing method 152 * belongs to a 32-bit ACPI table. 153 * 154 ******************************************************************************/ 155 156void 157acpi_ex_truncate_for32bit_table ( 158 acpi_operand_object *obj_desc, 159 acpi_walk_state *walk_state) 160{ 161 162 FUNCTION_ENTRY (); 163 164 165 /* 166 * Object must be a valid number and we must be executing 167 * a control method 168 */ 169 if ((!obj_desc) || 170 (obj_desc->common.type != ACPI_TYPE_INTEGER) || 171 (!walk_state->method_node)) { 172 return; 173 } 174 175 if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { 176 /* 177 * We are running a method that exists in a 32-bit ACPI table. 178 * Truncate the value to 32 bits by zeroing out the upper 32-bit field 179 */ 180 obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX; 181 } 182} 183 184 185/******************************************************************************* 186 * 187 * FUNCTION: Acpi_ex_acquire_global_lock 188 * 189 * PARAMETERS: Rule - Lock rule: Always_lock, Never_lock 190 * 191 * RETURN: TRUE/FALSE indicating whether the lock was actually acquired 192 * 193 * DESCRIPTION: Obtain the global lock and keep track of this fact via two 194 * methods. A global variable keeps the state of the lock, and 195 * the state is returned to the caller. 196 * 197 ******************************************************************************/ 198 199u8 200acpi_ex_acquire_global_lock ( 201 u32 rule) 202{ 203 u8 locked = FALSE; 204 acpi_status status; 205 206 207 FUNCTION_TRACE ("Ex_acquire_global_lock"); 208 209 210 /* Only attempt lock if the Rule says so */ 211 212 if (rule == (u32) GLOCK_ALWAYS_LOCK) { 213 /* We should attempt to get the lock */ 214 215 status = acpi_ev_acquire_global_lock (); 216 if (ACPI_SUCCESS (status)) { 217 locked = TRUE; 218 } 219 220 else { 221 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not acquire Global Lock, %s\n", 222 acpi_format_exception (status))); 223 } 224 } 225 226 return_VALUE (locked); 227} 228 229 230/******************************************************************************* 231 * 232 * FUNCTION: Acpi_ex_release_global_lock 233 * 234 * PARAMETERS: Locked_by_me - Return value from corresponding call to 235 * Acquire_global_lock. 236 * 237 * RETURN: Status 238 * 239 * DESCRIPTION: Release the global lock if it is locked. 240 * 241 ******************************************************************************/ 242 243acpi_status 244acpi_ex_release_global_lock ( 245 u8 locked_by_me) 246{ 247 248 FUNCTION_TRACE ("Ex_release_global_lock"); 249 250 251 /* Only attempt unlock if the caller locked it */ 252 253 if (locked_by_me) { 254 /* OK, now release the lock */ 255 256 acpi_ev_release_global_lock (); 257 } 258 259 260 return_ACPI_STATUS (AE_OK); 261} 262 263 264/******************************************************************************* 265 * 266 * FUNCTION: Acpi_ex_digits_needed 267 * 268 * PARAMETERS: Value - Value to be represented 269 * Base - Base of representation 270 * 271 * RETURN: the number of digits needed to represent Value in Base 272 * 273 ******************************************************************************/ 274 275u32 276acpi_ex_digits_needed ( 277 acpi_integer value, 278 u32 base) 279{ 280 u32 num_digits = 0; 281 282 283 FUNCTION_TRACE ("Ex_digits_needed"); 284 285 286 if (base < 1) { 287 REPORT_ERROR (("Ex_digits_needed: Internal error - Invalid base\n")); 288 } 289 290 else { 291 /* 292 * acpi_integer is unsigned, which is why we don't worry about a '-' 293 */ 294 for (num_digits = 1; 295 (acpi_ut_short_divide (&value, base, &value, NULL)); 296 ++num_digits) { ; } 297 } 298 299 return_VALUE (num_digits); 300} 301 302 303/******************************************************************************* 304 * 305 * FUNCTION: ntohl 306 * 307 * PARAMETERS: Value - Value to be converted 308 * 309 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 310 * 311 ******************************************************************************/ 312 313static u32 314_ntohl ( 315 u32 value) 316{ 317 union { 318 u32 value; 319 u8 bytes[4]; 320 } out; 321 322 union { 323 u32 value; 324 u8 bytes[4]; 325 } in; 326 327 328 FUNCTION_ENTRY (); 329 330 331 in.value = value; 332 333 out.bytes[0] = in.bytes[3]; 334 out.bytes[1] = in.bytes[2]; 335 out.bytes[2] = in.bytes[1]; 336 out.bytes[3] = in.bytes[0]; 337 338 return (out.value); 339} 340 341 342/******************************************************************************* 343 * 344 * FUNCTION: Acpi_ex_eisa_id_to_string 345 * 346 * PARAMETERS: Numeric_id - EISA ID to be converted 347 * Out_string - Where to put the converted string (8 bytes) 348 * 349 * DESCRIPTION: Convert a numeric EISA ID to string representation 350 * 351 ******************************************************************************/ 352 353acpi_status 354acpi_ex_eisa_id_to_string ( 355 u32 numeric_id, 356 NATIVE_CHAR *out_string) 357{ 358 u32 id; 359 360 361 FUNCTION_ENTRY (); 362 363 364 /* swap to big-endian to get contiguous bits */ 365 366 id = _ntohl (numeric_id); 367 368 out_string[0] = (char) ('@' + ((id >> 26) & 0x1f)); 369 out_string[1] = (char) ('@' + ((id >> 21) & 0x1f)); 370 out_string[2] = (char) ('@' + ((id >> 16) & 0x1f)); 371 out_string[3] = acpi_ut_hex_to_ascii_char (id, 12); 372 out_string[4] = acpi_ut_hex_to_ascii_char (id, 8); 373 out_string[5] = acpi_ut_hex_to_ascii_char (id, 4); 374 out_string[6] = acpi_ut_hex_to_ascii_char (id, 0); 375 out_string[7] = 0; 376 377 return (AE_OK); 378} 379 380 381/******************************************************************************* 382 * 383 * FUNCTION: Acpi_ex_unsigned_integer_to_string 384 * 385 * PARAMETERS: Value - Value to be converted 386 * Out_string - Where to put the converted string (8 bytes) 387 * 388 * RETURN: Convert a number to string representation 389 * 390 ******************************************************************************/ 391 392acpi_status 393acpi_ex_unsigned_integer_to_string ( 394 acpi_integer value, 395 NATIVE_CHAR *out_string) 396{ 397 u32 count; 398 u32 digits_needed; 399 u32 remainder; 400 401 402 FUNCTION_ENTRY (); 403 404 405 digits_needed = acpi_ex_digits_needed (value, 10); 406 out_string[digits_needed] = 0; 407 408 for (count = digits_needed; count > 0; count--) { 409 acpi_ut_short_divide (&value, 10, &value, &remainder); 410 out_string[count-1] = (NATIVE_CHAR) ('0' + remainder); 411 } 412 413 return (AE_OK); 414} 415 416 417