at v2.6.12 11 kB view raw
1 2/****************************************************************************** 3 * 4 * Module Name: exutils - interpreter/scanner utilities 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2005, R. Byron Moore 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 46/* 47 * DEFINE_AML_GLOBALS is tested in amlcode.h 48 * to determine whether certain global names should be "defined" or only 49 * "declared" in the current compilation. This enhances maintainability 50 * by enabling a single header file to embody all knowledge of the names 51 * in question. 52 * 53 * Exactly one module of any executable should #define DEFINE_GLOBALS 54 * before #including the header files which use this convention. The 55 * names in question will be defined and initialized in that module, 56 * and declared as extern in all other modules which #include those 57 * header files. 58 */ 59 60#define DEFINE_AML_GLOBALS 61 62#include <acpi/acpi.h> 63#include <acpi/acinterp.h> 64#include <acpi/amlcode.h> 65#include <acpi/acevents.h> 66 67#define _COMPONENT ACPI_EXECUTER 68 ACPI_MODULE_NAME ("exutils") 69 70 71#ifndef ACPI_NO_METHOD_EXECUTION 72 73/******************************************************************************* 74 * 75 * FUNCTION: acpi_ex_enter_interpreter 76 * 77 * PARAMETERS: None 78 * 79 * DESCRIPTION: Enter the interpreter execution region. Failure to enter 80 * the interpreter region is a fatal system error 81 * 82 ******************************************************************************/ 83 84acpi_status 85acpi_ex_enter_interpreter (void) 86{ 87 acpi_status status; 88 89 ACPI_FUNCTION_TRACE ("ex_enter_interpreter"); 90 91 92 status = acpi_ut_acquire_mutex (ACPI_MTX_EXECUTE); 93 if (ACPI_FAILURE (status)) { 94 ACPI_REPORT_ERROR (("Could not acquire interpreter mutex\n")); 95 } 96 97 return_ACPI_STATUS (status); 98} 99 100 101/******************************************************************************* 102 * 103 * FUNCTION: acpi_ex_exit_interpreter 104 * 105 * PARAMETERS: None 106 * 107 * DESCRIPTION: Exit the interpreter execution region 108 * 109 * Cases where the interpreter is unlocked: 110 * 1) Completion of the execution of a control method 111 * 2) Method blocked on a Sleep() AML opcode 112 * 3) Method blocked on an Acquire() AML opcode 113 * 4) Method blocked on a Wait() AML opcode 114 * 5) Method blocked to acquire the global lock 115 * 6) Method blocked to execute a serialized control method that is 116 * already executing 117 * 7) About to invoke a user-installed opregion handler 118 * 119 ******************************************************************************/ 120 121void 122acpi_ex_exit_interpreter (void) 123{ 124 acpi_status status; 125 126 127 ACPI_FUNCTION_TRACE ("ex_exit_interpreter"); 128 129 130 status = acpi_ut_release_mutex (ACPI_MTX_EXECUTE); 131 if (ACPI_FAILURE (status)) { 132 ACPI_REPORT_ERROR (("Could not release interpreter mutex\n")); 133 } 134 135 return_VOID; 136} 137 138 139/******************************************************************************* 140 * 141 * FUNCTION: acpi_ex_truncate_for32bit_table 142 * 143 * PARAMETERS: obj_desc - Object to be truncated 144 * 145 * RETURN: none 146 * 147 * DESCRIPTION: Truncate a number to 32-bits if the currently executing method 148 * belongs to a 32-bit ACPI table. 149 * 150 ******************************************************************************/ 151 152void 153acpi_ex_truncate_for32bit_table ( 154 union acpi_operand_object *obj_desc) 155{ 156 157 ACPI_FUNCTION_ENTRY (); 158 159 160 /* 161 * Object must be a valid number and we must be executing 162 * a control method 163 */ 164 if ((!obj_desc) || 165 (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER)) { 166 return; 167 } 168 169 if (acpi_gbl_integer_byte_width == 4) { 170 /* 171 * We are running a method that exists in a 32-bit ACPI table. 172 * Truncate the value to 32 bits by zeroing out the upper 32-bit field 173 */ 174 obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX; 175 } 176} 177 178 179/******************************************************************************* 180 * 181 * FUNCTION: acpi_ex_acquire_global_lock 182 * 183 * PARAMETERS: field_flags - Flags with Lock rule: 184 * always_lock or never_lock 185 * 186 * RETURN: TRUE/FALSE indicating whether the lock was actually acquired 187 * 188 * DESCRIPTION: Obtain the global lock and keep track of this fact via two 189 * methods. A global variable keeps the state of the lock, and 190 * the state is returned to the caller. 191 * 192 ******************************************************************************/ 193 194u8 195acpi_ex_acquire_global_lock ( 196 u32 field_flags) 197{ 198 u8 locked = FALSE; 199 acpi_status status; 200 201 202 ACPI_FUNCTION_TRACE ("ex_acquire_global_lock"); 203 204 205 /* Only attempt lock if the always_lock bit is set */ 206 207 if (field_flags & AML_FIELD_LOCK_RULE_MASK) { 208 /* We should attempt to get the lock, wait forever */ 209 210 status = acpi_ev_acquire_global_lock (ACPI_WAIT_FOREVER); 211 if (ACPI_SUCCESS (status)) { 212 locked = TRUE; 213 } 214 else { 215 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not acquire Global Lock, %s\n", 216 acpi_format_exception (status))); 217 } 218 } 219 220 return_VALUE (locked); 221} 222 223 224/******************************************************************************* 225 * 226 * FUNCTION: acpi_ex_release_global_lock 227 * 228 * PARAMETERS: locked_by_me - Return value from corresponding call to 229 * acquire_global_lock. 230 * 231 * RETURN: Status 232 * 233 * DESCRIPTION: Release the global lock if it is locked. 234 * 235 ******************************************************************************/ 236 237void 238acpi_ex_release_global_lock ( 239 u8 locked_by_me) 240{ 241 acpi_status status; 242 243 244 ACPI_FUNCTION_TRACE ("ex_release_global_lock"); 245 246 247 /* Only attempt unlock if the caller locked it */ 248 249 if (locked_by_me) { 250 /* OK, now release the lock */ 251 252 status = acpi_ev_release_global_lock (); 253 if (ACPI_FAILURE (status)) { 254 /* Report the error, but there isn't much else we can do */ 255 256 ACPI_REPORT_ERROR (("Could not release ACPI Global Lock, %s\n", 257 acpi_format_exception (status))); 258 } 259 } 260 261 return_VOID; 262} 263 264 265/******************************************************************************* 266 * 267 * FUNCTION: acpi_ex_digits_needed 268 * 269 * PARAMETERS: Value - Value to be represented 270 * Base - Base of representation 271 * 272 * RETURN: the number of digits needed to represent Value in Base 273 * 274 ******************************************************************************/ 275 276u32 277acpi_ex_digits_needed ( 278 acpi_integer value, 279 u32 base) 280{ 281 u32 num_digits; 282 acpi_integer current_value; 283 284 285 ACPI_FUNCTION_TRACE ("ex_digits_needed"); 286 287 288 /* acpi_integer is unsigned, so we don't worry about a '-' prefix */ 289 290 if (value == 0) { 291 return_VALUE (1); 292 } 293 294 current_value = value; 295 num_digits = 0; 296 297 /* Count the digits in the requested base */ 298 299 while (current_value) { 300 (void) acpi_ut_short_divide (current_value, base, &current_value, NULL); 301 num_digits++; 302 } 303 304 return_VALUE (num_digits); 305} 306 307 308/******************************************************************************* 309 * 310 * FUNCTION: acpi_ex_eisa_id_to_string 311 * 312 * PARAMETERS: numeric_id - EISA ID to be converted 313 * out_string - Where to put the converted string (8 bytes) 314 * 315 * DESCRIPTION: Convert a numeric EISA ID to string representation 316 * 317 ******************************************************************************/ 318 319void 320acpi_ex_eisa_id_to_string ( 321 u32 numeric_id, 322 char *out_string) 323{ 324 u32 eisa_id; 325 326 327 ACPI_FUNCTION_ENTRY (); 328 329 330 /* Swap ID to big-endian to get contiguous bits */ 331 332 eisa_id = acpi_ut_dword_byte_swap (numeric_id); 333 334 out_string[0] = (char) ('@' + (((unsigned long) eisa_id >> 26) & 0x1f)); 335 out_string[1] = (char) ('@' + ((eisa_id >> 21) & 0x1f)); 336 out_string[2] = (char) ('@' + ((eisa_id >> 16) & 0x1f)); 337 out_string[3] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 12); 338 out_string[4] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 8); 339 out_string[5] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 4); 340 out_string[6] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 0); 341 out_string[7] = 0; 342} 343 344 345/******************************************************************************* 346 * 347 * FUNCTION: acpi_ex_unsigned_integer_to_string 348 * 349 * PARAMETERS: Value - Value to be converted 350 * out_string - Where to put the converted string (8 bytes) 351 * 352 * RETURN: Convert a number to string representation 353 * 354 ******************************************************************************/ 355 356void 357acpi_ex_unsigned_integer_to_string ( 358 acpi_integer value, 359 char *out_string) 360{ 361 u32 count; 362 u32 digits_needed; 363 u32 remainder; 364 365 366 ACPI_FUNCTION_ENTRY (); 367 368 369 digits_needed = acpi_ex_digits_needed (value, 10); 370 out_string[digits_needed] = 0; 371 372 for (count = digits_needed; count > 0; count--) { 373 (void) acpi_ut_short_divide (value, 10, &value, &remainder); 374 out_string[count-1] = (char) ('0' + remainder);\ 375 } 376} 377 378#endif