psutils.c revision 70243
1/****************************************************************************** 2 * 3 * Module Name: psutils - Parser miscellaneous utilities (Parser only) 4 * $Revision: 31 $ 5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999, 2000, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 118#include "acpi.h" 119#include "acparser.h" 120#include "amlcode.h" 121 122#define _COMPONENT PARSER 123 MODULE_NAME ("psutils") 124 125 126#define PARSEOP_GENERIC 0x01 127#define PARSEOP_NAMED 0x02 128#define PARSEOP_DEFERRED 0x03 129#define PARSEOP_BYTELIST 0x04 130#define PARSEOP_IN_CACHE 0x80 131 132 133/******************************************************************************* 134 * 135 * FUNCTION: AcpiPsInitOp 136 * 137 * PARAMETERS: Op - A newly allocated Op object 138 * Opcode - Opcode to store in the Op 139 * 140 * RETURN: Status 141 * 142 * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on 143 * opcode 144 * 145 ******************************************************************************/ 146 147void 148AcpiPsInitOp ( 149 ACPI_PARSE_OBJECT *Op, 150 UINT16 Opcode) 151{ 152 ACPI_OPCODE_INFO *AmlOp; 153 154 155 Op->DataType = ACPI_DESC_TYPE_PARSER; 156 Op->Opcode = Opcode; 157 158 AmlOp = AcpiPsGetOpcodeInfo (Opcode); 159 160 DEBUG_ONLY_MEMBERS (STRNCPY (Op->OpName, AmlOp->Name, 161 sizeof (Op->OpName))); 162} 163 164 165/******************************************************************************* 166 * 167 * FUNCTION: AcpiPsAllocOp 168 * 169 * PARAMETERS: Opcode - Opcode that will be stored in the new Op 170 * 171 * RETURN: Pointer to the new Op. 172 * 173 * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on 174 * opcode. A cache of opcodes is available for the pure 175 * GENERIC_OP, since this is by far the most commonly used. 176 * 177 ******************************************************************************/ 178 179ACPI_PARSE_OBJECT* 180AcpiPsAllocOp ( 181 UINT16 Opcode) 182{ 183 ACPI_PARSE_OBJECT *Op = NULL; 184 UINT32 Size; 185 UINT8 Flags; 186 187 188 /* Allocate the minimum required size object */ 189 190 if (AcpiPsIsDeferredOp (Opcode)) 191 { 192 Size = sizeof (ACPI_PARSE2_OBJECT); 193 Flags = PARSEOP_DEFERRED; 194 } 195 196 else if (AcpiPsIsNamedOp (Opcode)) 197 { 198 Size = sizeof (ACPI_PARSE2_OBJECT); 199 Flags = PARSEOP_NAMED; 200 } 201 202 else if (AcpiPsIsBytelistOp (Opcode)) 203 { 204 Size = sizeof (ACPI_PARSE2_OBJECT); 205 Flags = PARSEOP_BYTELIST; 206 } 207 208 else 209 { 210 Size = sizeof (ACPI_PARSE_OBJECT); 211 Flags = PARSEOP_GENERIC; 212 } 213 214 215 if (Size == sizeof (ACPI_PARSE_OBJECT)) 216 { 217 /* 218 * The generic op is by far the most common (16 to 1), and therefore 219 * the op cache is implemented with this type. 220 * 221 * Check if there is an Op already available in the cache 222 */ 223 224 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 225 AcpiGbl_ParseCacheRequests++; 226 if (AcpiGbl_ParseCache) 227 { 228 /* Extract an op from the front of the cache list */ 229 230 AcpiGbl_ParseCacheDepth--; 231 AcpiGbl_ParseCacheHits++; 232 233 Op = AcpiGbl_ParseCache; 234 AcpiGbl_ParseCache = Op->Next; 235 236 if (Op->DataType == 0xFF) 237 { 238 DEBUG_PRINT (ACPI_ERROR, ("Op %p deleted while in cache!\n", Op)); 239 } 240 241 /* Clear the previously used Op */ 242 243 MEMSET (Op, 0, sizeof (ACPI_PARSE_OBJECT)); 244 245 DEBUG_PRINT (TRACE_PARSE, 246 ("PsAllocOp: Op %p from Parse Cache\n", Op)); 247 } 248 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 249 } 250 251 else 252 { 253 /* 254 * The generic op is by far the most common (16 to 1), and therefore 255 * the op cache is implemented with this type. 256 * 257 * Check if there is an Op already available in the cache 258 */ 259 260 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 261 AcpiGbl_ExtParseCacheRequests++; 262 if (AcpiGbl_ExtParseCache) 263 { 264 /* Extract an op from the front of the cache list */ 265 266 AcpiGbl_ExtParseCacheDepth--; 267 AcpiGbl_ExtParseCacheHits++; 268 269 Op = (ACPI_PARSE_OBJECT *) AcpiGbl_ExtParseCache; 270 AcpiGbl_ExtParseCache = (ACPI_PARSE2_OBJECT *) Op->Next; 271 272 if (Op->DataType == 0xFF) 273 { 274 DEBUG_PRINT (ACPI_ERROR, ("Op %p deleted while in cache!\n", Op)); 275 } 276 277 /* Clear the previously used Op */ 278 279 MEMSET (Op, 0, sizeof (ACPI_PARSE2_OBJECT)); 280 281 DEBUG_PRINT (TRACE_PARSE, 282 ("PsAllocOp: Op %p from ExtParse Cache\n", Op)); 283 } 284 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 285 } 286 287 288 /* Allocate a new Op if necessary */ 289 290 if (!Op) 291 { 292 Op = AcpiCmCallocate (Size); 293 } 294 295 /* Initialize the Op */ 296 if (Op) 297 { 298 AcpiPsInitOp (Op, Opcode); 299 Op->Flags = Flags; 300 } 301 302 return (Op); 303} 304 305 306/******************************************************************************* 307 * 308 * FUNCTION: AcpiPsFreeOp 309 * 310 * PARAMETERS: Op - Op to be freed 311 * 312 * RETURN: None. 313 * 314 * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list 315 * or actually free it. 316 * 317 ******************************************************************************/ 318 319void 320AcpiPsFreeOp ( 321 ACPI_PARSE_OBJECT *Op) 322{ 323 324 325 if (Op->Opcode == AML_RETURN_VALUE_OP) 326 { 327 DEBUG_PRINT (ACPI_INFO, ("Free retval op: %p\n", Op)); 328 } 329 330 if (Op->Flags == PARSEOP_GENERIC) 331 { 332 /* Is the cache full? */ 333 334 if (AcpiGbl_ParseCacheDepth < MAX_PARSE_CACHE_DEPTH) 335 { 336 /* Put a GENERIC_OP back into the cache */ 337 338 /* Clear the previously used Op */ 339 340 MEMSET (Op, 0, sizeof (ACPI_PARSE_OBJECT)); 341 Op->Flags = PARSEOP_IN_CACHE; 342 343 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 344 AcpiGbl_ParseCacheDepth++; 345 346 Op->Next = AcpiGbl_ParseCache; 347 AcpiGbl_ParseCache = Op; 348 349 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 350 return; 351 } 352 } 353 354 else 355 { 356 /* Is the cache full? */ 357 358 if (AcpiGbl_ExtParseCacheDepth < MAX_EXTPARSE_CACHE_DEPTH) 359 { 360 /* Put a GENERIC_OP back into the cache */ 361 362 /* Clear the previously used Op */ 363 364 MEMSET (Op, 0, sizeof (ACPI_PARSE2_OBJECT)); 365 Op->Flags = PARSEOP_IN_CACHE; 366 367 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 368 AcpiGbl_ExtParseCacheDepth++; 369 370 Op->Next = (ACPI_PARSE_OBJECT *) AcpiGbl_ExtParseCache; 371 AcpiGbl_ExtParseCache = (ACPI_PARSE2_OBJECT *) Op; 372 373 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 374 return; 375 } 376 } 377 378 379 /* 380 * Not a GENERIC OP, or the cache is full, just free the Op 381 */ 382 383 AcpiCmFree (Op); 384} 385 386 387/******************************************************************************* 388 * 389 * FUNCTION: AcpiPsDeleteParseCache 390 * 391 * PARAMETERS: None 392 * 393 * RETURN: None 394 * 395 * DESCRIPTION: Free all objects that are on the parse cache list. 396 * 397 ******************************************************************************/ 398 399void 400AcpiPsDeleteParseCache ( 401 void) 402{ 403 ACPI_PARSE_OBJECT *Next; 404 405 406 FUNCTION_TRACE ("PsDeleteParseCache"); 407 408 409 /* Traverse the global cache list */ 410 411 while (AcpiGbl_ParseCache) 412 { 413 /* Delete one cached state object */ 414 415 Next = AcpiGbl_ParseCache->Next; 416 AcpiCmFree (AcpiGbl_ParseCache); 417 AcpiGbl_ParseCache = Next; 418 AcpiGbl_ParseCacheDepth--; 419 } 420 421 /* Traverse the global cache list */ 422 423 while (AcpiGbl_ExtParseCache) 424 { 425 /* Delete one cached state object */ 426 427 Next = AcpiGbl_ExtParseCache->Next; 428 AcpiCmFree (AcpiGbl_ExtParseCache); 429 AcpiGbl_ExtParseCache = (ACPI_PARSE2_OBJECT *) Next; 430 AcpiGbl_ExtParseCacheDepth--; 431 } 432 433 return_VOID; 434} 435 436 437/******************************************************************************* 438 * 439 * FUNCTION: Utility functions 440 * 441 * DESCRIPTION: Low level functions 442 * 443 * TBD: [Restructure] 444 * 1) Some of these functions should be macros 445 * 2) Some can be simplified 446 * 447 ******************************************************************************/ 448 449 450/* 451 * Is "c" a namestring lead character? 452 */ 453 454 455BOOLEAN 456AcpiPsIsLeadingChar ( 457 UINT32 c) 458{ 459 return ((BOOLEAN) (c == '_' || (c >= 'A' && c <= 'Z'))); 460} 461 462 463/* 464 * Is "c" a namestring prefix character? 465 */ 466BOOLEAN 467AcpiPsIsPrefixChar ( 468 UINT32 c) 469{ 470 return ((BOOLEAN) (c == '\\' || c == '^')); 471} 472 473 474BOOLEAN 475AcpiPsIsNamespaceObjectOp ( 476 UINT16 Opcode) 477{ 478 return ((BOOLEAN) 479 (Opcode == AML_SCOPE_OP || 480 Opcode == AML_DEVICE_OP || 481 Opcode == AML_THERMAL_ZONE_OP || 482 Opcode == AML_METHOD_OP || 483 Opcode == AML_POWER_RES_OP || 484 Opcode == AML_PROCESSOR_OP || 485 Opcode == AML_DEF_FIELD_OP || 486 Opcode == AML_INDEX_FIELD_OP || 487 Opcode == AML_BANK_FIELD_OP || 488 Opcode == AML_NAMEDFIELD_OP || 489 Opcode == AML_NAME_OP || 490 Opcode == AML_ALIAS_OP || 491 Opcode == AML_MUTEX_OP || 492 Opcode == AML_EVENT_OP || 493 Opcode == AML_REGION_OP || 494 Opcode == AML_CREATE_FIELD_OP || 495 Opcode == AML_BIT_FIELD_OP || 496 Opcode == AML_BYTE_FIELD_OP || 497 Opcode == AML_WORD_FIELD_OP || 498 Opcode == AML_DWORD_FIELD_OP || 499 Opcode == AML_METHODCALL_OP || 500 Opcode == AML_NAMEPATH_OP)); 501} 502 503BOOLEAN 504AcpiPsIsNamespaceOp ( 505 UINT16 Opcode) 506{ 507 return ((BOOLEAN) 508 (Opcode == AML_SCOPE_OP || 509 Opcode == AML_DEVICE_OP || 510 Opcode == AML_THERMAL_ZONE_OP || 511 Opcode == AML_METHOD_OP || 512 Opcode == AML_POWER_RES_OP || 513 Opcode == AML_PROCESSOR_OP || 514 Opcode == AML_DEF_FIELD_OP || 515 Opcode == AML_INDEX_FIELD_OP || 516 Opcode == AML_BANK_FIELD_OP || 517 Opcode == AML_NAME_OP || 518 Opcode == AML_ALIAS_OP || 519 Opcode == AML_MUTEX_OP || 520 Opcode == AML_EVENT_OP || 521 Opcode == AML_REGION_OP || 522 Opcode == AML_NAMEDFIELD_OP)); 523} 524 525 526/* 527 * Is opcode for a named object Op? 528 * (Includes all named object opcodes) 529 * 530 * TBD: [Restructure] Need a better way than this brute force approach! 531 */ 532BOOLEAN 533AcpiPsIsNodeOp ( 534 UINT16 Opcode) 535{ 536 return ((BOOLEAN) 537 (Opcode == AML_SCOPE_OP || 538 Opcode == AML_DEVICE_OP || 539 Opcode == AML_THERMAL_ZONE_OP || 540 Opcode == AML_METHOD_OP || 541 Opcode == AML_POWER_RES_OP || 542 Opcode == AML_PROCESSOR_OP || 543 Opcode == AML_NAMEDFIELD_OP || 544 Opcode == AML_NAME_OP || 545 Opcode == AML_ALIAS_OP || 546 Opcode == AML_MUTEX_OP || 547 Opcode == AML_EVENT_OP || 548 Opcode == AML_REGION_OP || 549 550 551 Opcode == AML_CREATE_FIELD_OP || 552 Opcode == AML_BIT_FIELD_OP || 553 Opcode == AML_BYTE_FIELD_OP || 554 Opcode == AML_WORD_FIELD_OP || 555 Opcode == AML_DWORD_FIELD_OP || 556 Opcode == AML_METHODCALL_OP || 557 Opcode == AML_NAMEPATH_OP)); 558} 559 560 561/* 562 * Is opcode for a named Op? 563 */ 564BOOLEAN 565AcpiPsIsNamedOp ( 566 UINT16 Opcode) 567{ 568 return ((BOOLEAN) 569 (Opcode == AML_SCOPE_OP || 570 Opcode == AML_DEVICE_OP || 571 Opcode == AML_THERMAL_ZONE_OP || 572 Opcode == AML_METHOD_OP || 573 Opcode == AML_POWER_RES_OP || 574 Opcode == AML_PROCESSOR_OP || 575 Opcode == AML_NAME_OP || 576 Opcode == AML_ALIAS_OP || 577 Opcode == AML_MUTEX_OP || 578 Opcode == AML_EVENT_OP || 579 Opcode == AML_REGION_OP || 580 Opcode == AML_NAMEDFIELD_OP)); 581} 582 583 584BOOLEAN 585AcpiPsIsDeferredOp ( 586 UINT16 Opcode) 587{ 588 return ((BOOLEAN) 589 (Opcode == AML_METHOD_OP || 590 Opcode == AML_CREATE_FIELD_OP || 591 Opcode == AML_BIT_FIELD_OP || 592 Opcode == AML_BYTE_FIELD_OP || 593 Opcode == AML_WORD_FIELD_OP || 594 Opcode == AML_DWORD_FIELD_OP || 595 Opcode == AML_REGION_OP)); 596} 597 598 599/* 600 * Is opcode for a bytelist? 601 */ 602BOOLEAN 603AcpiPsIsBytelistOp ( 604 UINT16 Opcode) 605{ 606 return ((BOOLEAN) (Opcode == AML_BYTELIST_OP)); 607} 608 609 610/* 611 * Is opcode for a Field, IndexField, or BankField 612 */ 613BOOLEAN 614AcpiPsIsFieldOp ( 615 UINT16 Opcode) 616{ 617 return ((BOOLEAN) 618 (Opcode == AML_CREATE_FIELD_OP 619 || Opcode == AML_DEF_FIELD_OP 620 || Opcode == AML_INDEX_FIELD_OP 621 || Opcode == AML_BANK_FIELD_OP)); 622} 623 624 625/* 626 * Is field creation op 627 */ 628BOOLEAN 629AcpiPsIsCreateFieldOp ( 630 UINT16 Opcode) 631{ 632 return ((BOOLEAN) 633 (Opcode == AML_CREATE_FIELD_OP || 634 Opcode == AML_BIT_FIELD_OP || 635 Opcode == AML_BYTE_FIELD_OP || 636 Opcode == AML_WORD_FIELD_OP || 637 Opcode == AML_DWORD_FIELD_OP)); 638} 639 640 641/* 642 * Cast an acpi_op to an acpi_extended_op if possible 643 */ 644 645/* TBD: This is very inefficient, fix */ 646ACPI_PARSE2_OBJECT * 647AcpiPsToExtendedOp ( 648 ACPI_PARSE_OBJECT *Op) 649{ 650 return ((AcpiPsIsDeferredOp (Op->Opcode) || AcpiPsIsNamedOp (Op->Opcode) || AcpiPsIsBytelistOp (Op->Opcode)) 651 ? ( (ACPI_PARSE2_OBJECT *) Op) : NULL); 652} 653 654 655/* 656 * Get op's name (4-byte name segment) or 0 if unnamed 657 */ 658UINT32 659AcpiPsGetName ( 660 ACPI_PARSE_OBJECT *Op) 661{ 662 ACPI_PARSE2_OBJECT *Named = AcpiPsToExtendedOp (Op); 663 664 return (Named ? Named->Name : 0); 665} 666 667 668/* 669 * Set op's name 670 */ 671void 672AcpiPsSetName ( 673 ACPI_PARSE_OBJECT *Op, 674 UINT32 name) 675{ 676 ACPI_PARSE2_OBJECT *Named = AcpiPsToExtendedOp (Op); 677 678 if (Named) 679 { 680 Named->Name = name; 681 } 682} 683 684