1 /****************************************************************************** 2 * 3 * Module Name: asllookup- Namespace lookup 4 * $Revision: 1.95 $ 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2005, 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 <contrib/dev/acpica/compiler/aslcompiler.h> 119 #include "aslcompiler.y.h" 120 121 #include <contrib/dev/acpica/acparser.h> 122 #include <contrib/dev/acpica/amlcode.h> 123 #include <contrib/dev/acpica/acnamesp.h> 124 #include <contrib/dev/acpica/acdispat.h> 125 126 127 #define _COMPONENT ACPI_COMPILER 128 ACPI_MODULE_NAME ("asllookup") 129 130 /* Local prototypes */ 131 132 static ACPI_STATUS 133 LsCompareOneNamespaceObject ( 134 ACPI_HANDLE ObjHandle, 135 UINT32 Level, 136 void *Context, 137 void **ReturnValue); 138 139 static ACPI_STATUS 140 LsDoOneNamespaceObject ( 141 ACPI_HANDLE ObjHandle, 142 UINT32 Level, 143 void *Context, 144 void **ReturnValue); 145 146 static BOOLEAN 147 LkObjectExists ( 148 char *Name); 149 150 static void 151 LkCheckFieldRange ( 152 ACPI_PARSE_OBJECT *Op, 153 UINT32 RegionBitLength, 154 UINT32 FieldBitOffset, 155 UINT32 FieldBitLength, 156 UINT32 AccessBitWidth); 157 158 static ACPI_STATUS 159 LkNamespaceLocateBegin ( 160 ACPI_PARSE_OBJECT *Op, 161 UINT32 Level, 162 void *Context); 163 164 static ACPI_STATUS 165 LkNamespaceLocateEnd ( 166 ACPI_PARSE_OBJECT *Op, 167 UINT32 Level, 168 void *Context); 169 170 171 /******************************************************************************* 172 * 173 * FUNCTION: LsDoOneNamespaceObject 174 * 175 * PARAMETERS: ACPI_WALK_CALLBACK 176 * 177 * RETURN: Status 178 * 179 * DESCRIPTION: Dump a namespace object to the namespace output file. 180 * Called during the walk of the namespace to dump all objects. 181 * 182 ******************************************************************************/ 183 184 static ACPI_STATUS 185 LsDoOneNamespaceObject ( 186 ACPI_HANDLE ObjHandle, 187 UINT32 Level, 188 void *Context, 189 void **ReturnValue) 190 { 191 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 192 ACPI_OPERAND_OBJECT *ObjDesc; 193 ACPI_PARSE_OBJECT *Op; 194 195 196 Gbl_NumNamespaceObjects++; 197 198 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5d [%d] %*s %4.4s - %s", 199 Gbl_NumNamespaceObjects, Level, (Level * 3), " ", 200 &Node->Name, 201 AcpiUtGetTypeName (Node->Type)); 202 203 Op = Node->Op; 204 ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object); 205 206 if (!Op) 207 { 208 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n"); 209 return (AE_OK); 210 } 211 212 213 if ((ObjDesc) && 214 (ObjDesc->Common.Descriptor == ACPI_DESC_TYPE_OPERAND)) 215 { 216 switch (Node->Type) 217 { 218 case ACPI_TYPE_INTEGER: 219 220 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 221 " [Initial Value 0x%8.8X%8.8X]", 222 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 223 break; 224 225 226 case ACPI_TYPE_STRING: 227 228 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 229 " [Initial Value \"%s\"]", 230 ObjDesc->String.Pointer); 231 break; 232 233 default: 234 /* Nothing to do for other types */ 235 break; 236 } 237 238 } 239 else 240 { 241 switch (Node->Type) 242 { 243 case ACPI_TYPE_INTEGER: 244 245 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 246 { 247 Op = Op->Asl.Child; 248 } 249 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 250 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 251 { 252 Op = Op->Asl.Next; 253 } 254 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 255 " [Initial Value 0x%8.8X%8.8X]", 256 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer)); 257 break; 258 259 260 case ACPI_TYPE_STRING: 261 262 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 263 { 264 Op = Op->Asl.Child; 265 } 266 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 267 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 268 { 269 Op = Op->Asl.Next; 270 } 271 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 272 " [Initial Value \"%s\"]", 273 Op->Asl.Value.String); 274 break; 275 276 277 case ACPI_TYPE_LOCAL_REGION_FIELD: 278 279 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 280 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 281 { 282 Op = Op->Asl.Child; 283 } 284 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 285 " [Offset 0x%04X Length 0x%04X bits]", 286 Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer); 287 break; 288 289 290 case ACPI_TYPE_BUFFER_FIELD: 291 292 switch (Op->Asl.ParseOpcode) 293 { 294 case PARSEOP_CREATEBYTEFIELD: 295 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BYTE ( 8 bit)]"); 296 break; 297 298 case PARSEOP_CREATEDWORDFIELD: 299 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [DWORD (32 bit)]"); 300 break; 301 302 case PARSEOP_CREATEQWORDFIELD: 303 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [QWORD (64 bit)]"); 304 break; 305 306 case PARSEOP_CREATEWORDFIELD: 307 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [WORD (16 bit)]"); 308 break; 309 310 case PARSEOP_CREATEBITFIELD: 311 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BIT ( 1 bit)]"); 312 break; 313 314 case PARSEOP_CREATEFIELD: 315 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Arbitrary Bit Field]"); 316 break; 317 318 default: 319 break; 320 321 } 322 break; 323 324 325 case ACPI_TYPE_PACKAGE: 326 327 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 328 { 329 Op = Op->Asl.Child; 330 } 331 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 332 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 333 { 334 Op = Op->Asl.Next; 335 } 336 Op = Op->Asl.Child; 337 338 if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) || 339 (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA)) 340 { 341 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 342 " [Initial Length 0x%.2X elements]", 343 Op->Asl.Value.Integer); 344 } 345 break; 346 347 348 case ACPI_TYPE_BUFFER: 349 350 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 351 { 352 Op = Op->Asl.Child; 353 } 354 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 355 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 356 { 357 Op = Op->Asl.Next; 358 } 359 Op = Op->Asl.Child; 360 361 if (Op->Asl.ParseOpcode == PARSEOP_INTEGER) 362 { 363 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 364 " [Initial Length 0x%.2X bytes]", 365 Op->Asl.Value.Integer); 366 } 367 break; 368 369 370 case ACPI_TYPE_METHOD: 371 372 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 373 " [Code Length 0x%.4X bytes]", 374 Op->Asl.AmlSubtreeLength); 375 break; 376 377 378 default: 379 /* Nothing to do for other types */ 380 break; 381 } 382 } 383 384 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n"); 385 return (AE_OK); 386 } 387 388 389 /******************************************************************************* 390 * 391 * FUNCTION: LsDisplayNamespace 392 * 393 * PARAMETERS: None 394 * 395 * RETURN: Status 396 * 397 * DESCRIPTION: Walk the namespace an display information about each node 398 * in the tree. Information is written to the optional 399 * namespace output file. 400 * 401 ******************************************************************************/ 402 403 ACPI_STATUS 404 LsDisplayNamespace ( 405 void) 406 { 407 ACPI_STATUS Status; 408 409 410 if (!Gbl_NsOutputFlag) 411 { 412 return (AE_OK); 413 } 414 415 /* File header */ 416 417 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n"); 418 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count Depth Name - Type\n\n"); 419 420 /* Walk entire namespace from the root */ 421 422 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 423 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, 424 NULL, NULL); 425 return (Status); 426 } 427 428 429 /******************************************************************************* 430 * 431 * FUNCTION: LsCompareOneNamespaceObject 432 * 433 * PARAMETERS: ACPI_WALK_CALLBACK 434 * 435 * RETURN: Status 436 * 437 * DESCRIPTION: Compare name of one object. 438 * 439 ******************************************************************************/ 440 441 static ACPI_STATUS 442 LsCompareOneNamespaceObject ( 443 ACPI_HANDLE ObjHandle, 444 UINT32 Level, 445 void *Context, 446 void **ReturnValue) 447 { 448 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 449 450 451 /* Simply check the name */ 452 453 if (*((UINT32 *) (Context)) == Node->Name.Integer) 454 { 455 /* Abort walk if we found one instance */ 456 457 return (AE_CTRL_TRUE); 458 } 459 460 return (AE_OK); 461 } 462 463 464 /******************************************************************************* 465 * 466 * FUNCTION: LkObjectExists 467 * 468 * PARAMETERS: Name - 4 char ACPI name 469 * 470 * RETURN: TRUE if name exists in namespace 471 * 472 * DESCRIPTION: Walk the namespace to find an object 473 * 474 ******************************************************************************/ 475 476 static BOOLEAN 477 LkObjectExists ( 478 char *Name) 479 { 480 ACPI_STATUS Status; 481 482 483 /* Walk entire namespace from the supplied root */ 484 485 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 486 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, 487 Name, NULL); 488 if (Status == AE_CTRL_TRUE) 489 { 490 /* At least one instance of the name was found */ 491 492 return (TRUE); 493 } 494 495 return (FALSE); 496 } 497 498 499 /******************************************************************************* 500 * 501 * FUNCTION: LkCrossReferenceNamespace 502 * 503 * PARAMETERS: None 504 * 505 * RETURN: Status 506 * 507 * DESCRIPTION: Perform a cross reference check of the parse tree against the 508 * namespace. Every named referenced within the parse tree 509 * should be get resolved with a namespace lookup. If not, the 510 * original reference in the ASL code is invalid -- i.e., refers 511 * to a non-existent object. 512 * 513 * NOTE: The ASL "External" operator causes the name to be inserted into the 514 * namespace so that references to the external name will be resolved 515 * correctly here. 516 * 517 ******************************************************************************/ 518 519 ACPI_STATUS 520 LkCrossReferenceNamespace ( 521 void) 522 { 523 ACPI_WALK_STATE *WalkState; 524 525 526 DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n"); 527 528 /* 529 * Create a new walk state for use when looking up names 530 * within the namespace (Passed as context to the callbacks) 531 */ 532 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 533 if (!WalkState) 534 { 535 return AE_NO_MEMORY; 536 } 537 538 /* Walk the entire parse tree */ 539 540 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin, 541 LkNamespaceLocateEnd, WalkState); 542 return AE_OK; 543 } 544 545 546 /******************************************************************************* 547 * 548 * FUNCTION: LkCheckFieldRange 549 * 550 * PARAMETERS: RegionBitLength - Length of entire parent region 551 * FieldBitOffset - Start of the field unit (within region) 552 * FieldBitLength - Entire length of field unit 553 * AccessBitWidth - Access width of the field unit 554 * 555 * RETURN: None 556 * 557 * DESCRIPTION: Check one field unit to make sure it fits in the parent 558 * op region. 559 * 560 * Note: AccessBitWidth must be either 8,16,32, or 64 561 * 562 ******************************************************************************/ 563 564 static void 565 LkCheckFieldRange ( 566 ACPI_PARSE_OBJECT *Op, 567 UINT32 RegionBitLength, 568 UINT32 FieldBitOffset, 569 UINT32 FieldBitLength, 570 UINT32 AccessBitWidth) 571 { 572 UINT32 FieldEndBitOffset; 573 574 575 /* 576 * Check each field unit against the region size. The entire 577 * field unit (start offset plus length) must fit within the 578 * region. 579 */ 580 FieldEndBitOffset = FieldBitOffset + FieldBitLength; 581 582 if (FieldEndBitOffset > RegionBitLength) 583 { 584 /* Field definition itself is beyond the end-of-region */ 585 586 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL); 587 return; 588 } 589 590 /* 591 * Now check that the field plus AccessWidth doesn't go beyond 592 * the end-of-region. Assumes AccessBitWidth is a power of 2 593 */ 594 FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth); 595 596 if (FieldEndBitOffset > RegionBitLength) 597 { 598 /* Field definition combined with the access is beyond EOR */ 599 600 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL); 601 } 602 } 603 604 /******************************************************************************* 605 * 606 * FUNCTION: LkNamespaceLocateBegin 607 * 608 * PARAMETERS: ASL_WALK_CALLBACK 609 * 610 * RETURN: Status 611 * 612 * DESCRIPTION: Descending callback used during cross-reference. For named 613 * object references, attempt to locate the name in the 614 * namespace. 615 * 616 * NOTE: ASL references to named fields within resource descriptors are 617 * resolved to integer values here. Therefore, this step is an 618 * important part of the code generation. We don't know that the 619 * name refers to a resource descriptor until now. 620 * 621 ******************************************************************************/ 622 623 static ACPI_STATUS 624 LkNamespaceLocateBegin ( 625 ACPI_PARSE_OBJECT *Op, 626 UINT32 Level, 627 void *Context) 628 { 629 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 630 ACPI_NAMESPACE_NODE *Node; 631 ACPI_STATUS Status; 632 ACPI_OBJECT_TYPE ObjectType; 633 char *Path; 634 UINT8 PassedArgs; 635 ACPI_PARSE_OBJECT *NextOp; 636 ACPI_PARSE_OBJECT *OwningOp; 637 ACPI_PARSE_OBJECT *SpaceIdOp; 638 UINT32 MinimumLength; 639 UINT32 Temp; 640 const ACPI_OPCODE_INFO *OpInfo; 641 UINT32 Flags; 642 643 644 ACPI_FUNCTION_TRACE_PTR ("LkNamespaceLocateBegin", Op); 645 646 /* 647 * If this node is the actual declaration of a name 648 * [such as the XXXX name in "Method (XXXX)"], 649 * we are not interested in it here. We only care about names that are 650 * references to other objects within the namespace and the parent objects 651 * of name declarations 652 */ 653 if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) 654 { 655 return (AE_OK); 656 } 657 658 /* We are only interested in opcodes that have an associated name */ 659 660 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 661 662 if ((!(OpInfo->Flags & AML_NAMED)) && 663 (!(OpInfo->Flags & AML_CREATE)) && 664 (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) && 665 (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) && 666 (Op->Asl.ParseOpcode != PARSEOP_METHODCALL)) 667 { 668 return (AE_OK); 669 } 670 671 /* 672 * We must enable the "search-to-root" for single NameSegs, but 673 * we have to be very careful about opening up scopes 674 */ 675 Flags = ACPI_NS_SEARCH_PARENT; 676 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 677 (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 678 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 679 { 680 /* 681 * These are name references, do not push the scope stack 682 * for them. 683 */ 684 Flags |= ACPI_NS_DONT_OPEN_SCOPE; 685 } 686 687 /* Get the NamePath from the appropriate place */ 688 689 if (OpInfo->Flags & AML_NAMED) 690 { 691 /* For all NAMED operators, the name reference is the first child */ 692 693 Path = Op->Asl.Child->Asl.Value.String; 694 if (Op->Asl.AmlOpcode == AML_ALIAS_OP) 695 { 696 /* 697 * ALIAS is the only oddball opcode, the name declaration 698 * (alias name) is the second operand 699 */ 700 Path = Op->Asl.Child->Asl.Next->Asl.Value.String; 701 } 702 } 703 else if (OpInfo->Flags & AML_CREATE) 704 { 705 /* Name must appear as the last parameter */ 706 707 NextOp = Op->Asl.Child; 708 while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)) 709 { 710 NextOp = NextOp->Asl.Next; 711 } 712 Path = NextOp->Asl.Value.String; 713 } 714 else 715 { 716 Path = Op->Asl.Value.String; 717 } 718 719 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 720 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 721 "Type=%s\n", AcpiUtGetTypeName (ObjectType))); 722 723 /* 724 * Lookup the name in the namespace. Name must exist at this point, or it 725 * is an invalid reference. 726 * 727 * The namespace is also used as a lookup table for references to resource 728 * descriptors and the fields within them. 729 */ 730 Gbl_NsLookupCount++; 731 732 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 733 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node)); 734 if (ACPI_FAILURE (Status)) 735 { 736 if (Status == AE_NOT_FOUND) 737 { 738 /* 739 * We didn't find the name reference by path -- we can qualify this 740 * a little better before we print an error message 741 */ 742 if (strlen (Path) == ACPI_NAME_SIZE) 743 { 744 /* A simple, one-segment ACPI name */ 745 746 if (LkObjectExists (Path)) 747 { 748 /* 749 * There exists such a name, but we couldn't get to it 750 * from this scope 751 */ 752 AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op, 753 Op->Asl.ExternalName); 754 } 755 else 756 { 757 /* The name doesn't exist, period */ 758 759 if ((Op->Asl.Parent) && 760 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)) 761 { 762 /* Ignore not found if parent is CondRefOf */ 763 764 return (AE_OK); 765 } 766 767 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, 768 Op, Op->Asl.ExternalName); 769 } 770 } 771 else 772 { 773 /* Check for a fully qualified path */ 774 775 if (Path[0] == AML_ROOT_PREFIX) 776 { 777 /* Gave full path, the object does not exist */ 778 779 if ((Op->Asl.Parent) && 780 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)) 781 { 782 /* Ignore not found if parent is CondRefOf */ 783 784 return (AE_OK); 785 } 786 787 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, 788 Op->Asl.ExternalName); 789 } 790 else 791 { 792 /* 793 * We can't tell whether it doesn't exist or just 794 * can't be reached. 795 */ 796 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 797 Op->Asl.ExternalName); 798 } 799 } 800 801 Status = AE_OK; 802 } 803 return (Status); 804 } 805 806 /* Attempt to optimize the NamePath */ 807 808 OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node); 809 810 /* 811 * Dereference an alias. (A name reference that is an alias.) 812 * Aliases are not nested; The alias always points to the final object 813 */ 814 if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) && 815 (Node->Type == ACPI_TYPE_LOCAL_ALIAS)) 816 { 817 /* This node points back to the original PARSEOP_ALIAS */ 818 819 NextOp = Node->Op; 820 821 /* The first child is the alias target op */ 822 823 NextOp = NextOp->Asl.Child; 824 825 /* Who in turn points back to original target alias node */ 826 827 if (NextOp->Asl.Node) 828 { 829 Node = NextOp->Asl.Node; 830 } 831 else 832 { 833 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 834 "Missing alias link"); 835 } 836 } 837 838 /* 1) Check for a reference to a resource descriptor */ 839 840 else if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 841 (Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 842 { 843 /* 844 * This was a reference to a field within a resource descriptor. Extract 845 * the associated field offset (either a bit or byte offset depending on 846 * the field type) and change the named reference into an integer for 847 * AML code generation 848 */ 849 Temp = Node->Value; 850 if (Node->Flags & ANOBJ_IS_BIT_OFFSET) 851 { 852 Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET; 853 } 854 855 /* Perform BitOffset <--> ByteOffset conversion if necessary */ 856 857 switch (Op->Asl.Parent->Asl.AmlOpcode) 858 { 859 case AML_CREATE_FIELD_OP: 860 861 /* We allow a Byte offset to Bit Offset conversion for this op */ 862 863 if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)) 864 { 865 /* Simply multiply byte offset times 8 to get bit offset */ 866 867 Temp = ACPI_MUL_8 (Temp); 868 } 869 break; 870 871 872 case AML_CREATE_BIT_FIELD_OP: 873 874 /* This op requires a Bit Offset */ 875 876 if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)) 877 { 878 AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL); 879 } 880 break; 881 882 883 case AML_CREATE_BYTE_FIELD_OP: 884 case AML_CREATE_WORD_FIELD_OP: 885 case AML_CREATE_DWORD_FIELD_OP: 886 case AML_CREATE_QWORD_FIELD_OP: 887 case AML_INDEX_OP: 888 889 /* These Ops require Byte offsets */ 890 891 if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET) 892 { 893 AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL); 894 } 895 break; 896 897 898 default: 899 /* Nothing to do for other opcodes */ 900 break; 901 } 902 903 /* Now convert this node to an integer whose value is the field offset */ 904 905 Op->Asl.AmlLength = 0; 906 Op->Asl.ParseOpcode = PARSEOP_INTEGER; 907 Op->Asl.Value.Integer = (UINT64) Temp; 908 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 909 910 OpcGenerateAmlOpcode (Op); 911 } 912 913 /* 2) Check for a method invocation */ 914 915 else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) && 916 (Node->Type == ACPI_TYPE_METHOD) && 917 (Op->Asl.Parent) && 918 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) || 919 920 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 921 { 922 923 /* 924 * A reference to a method within one of these opcodes is not an 925 * invocation of the method, it is simply a reference to the method. 926 */ 927 if ((Op->Asl.Parent) && 928 ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF) || 929 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF) || 930 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE))) 931 { 932 return (AE_OK); 933 } 934 /* 935 * There are two types of method invocation: 936 * 1) Invocation with arguments -- the parser recognizes this 937 * as a METHODCALL. 938 * 2) Invocation with no arguments --the parser cannot determine that 939 * this is a method invocation, therefore we have to figure it out 940 * here. 941 */ 942 if (Node->Type != ACPI_TYPE_METHOD) 943 { 944 sprintf (MsgBuffer, "%s is a %s", 945 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 946 947 AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer); 948 return (AE_OK); 949 } 950 951 /* Save the method node in the caller's op */ 952 953 Op->Asl.Node = Node; 954 if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF) 955 { 956 return (AE_OK); 957 } 958 959 /* 960 * This is a method invocation, with or without arguments. 961 * Count the number of arguments, each appears as a child 962 * under the parent node 963 */ 964 Op->Asl.ParseOpcode = PARSEOP_METHODCALL; 965 UtSetParseOpName (Op); 966 967 PassedArgs = 0; 968 NextOp = Op->Asl.Child; 969 970 while (NextOp) 971 { 972 PassedArgs++; 973 NextOp = NextOp->Asl.Next; 974 } 975 976 if (Node->Value != ASL_EXTERNAL_METHOD) 977 { 978 /* 979 * Check the parsed arguments with the number expected by the 980 * method declaration itself 981 */ 982 if (PassedArgs != Node->Value) 983 { 984 sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName, 985 Node->Value); 986 987 if (PassedArgs < Node->Value) 988 { 989 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer); 990 } 991 else 992 { 993 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer); 994 } 995 } 996 } 997 } 998 999 /* 3) Check for an ASL Field definition */ 1000 1001 else if ((Op->Asl.Parent) && 1002 ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) || 1003 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD))) 1004 { 1005 /* 1006 * Offset checking for fields. If the parent operation region has a 1007 * constant length (known at compile time), we can check fields 1008 * defined in that region against the region length. This will catch 1009 * fields and field units that cannot possibly fit within the region. 1010 * 1011 * Note: Index fields do not directly reference an operation region, 1012 * thus they are not included in this check. 1013 */ 1014 if (Op == Op->Asl.Parent->Asl.Child) 1015 { 1016 /* 1017 * This is the first child of the field node, which is 1018 * the name of the region. Get the parse node for the 1019 * region -- which contains the length of the region. 1020 */ 1021 OwningOp = Node->Op; 1022 Op->Asl.Parent->Asl.ExtraValue = 1023 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer); 1024 1025 /* Examine the field access width */ 1026 1027 switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer) 1028 { 1029 case AML_FIELD_ACCESS_ANY: 1030 case AML_FIELD_ACCESS_BYTE: 1031 case AML_FIELD_ACCESS_BUFFER: 1032 default: 1033 MinimumLength = 1; 1034 break; 1035 1036 case AML_FIELD_ACCESS_WORD: 1037 MinimumLength = 2; 1038 break; 1039 1040 case AML_FIELD_ACCESS_DWORD: 1041 MinimumLength = 4; 1042 break; 1043 1044 case AML_FIELD_ACCESS_QWORD: 1045 MinimumLength = 8; 1046 break; 1047 } 1048 1049 /* 1050 * Is the region at least as big as the access width? 1051 * Note: DataTableRegions have 0 length 1052 */ 1053 if (((UINT32) OwningOp->Asl.Value.Integer) && 1054 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength)) 1055 { 1056 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL); 1057 } 1058 1059 /* 1060 * Check EC/CMOS/SMBUS fields to make sure that the correct 1061 * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS) 1062 */ 1063 SpaceIdOp = OwningOp->Asl.Child->Asl.Next; 1064 switch ((UINT32) SpaceIdOp->Asl.Value.Integer) 1065 { 1066 case REGION_EC: 1067 case REGION_CMOS: 1068 1069 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE) 1070 { 1071 AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL); 1072 } 1073 break; 1074 1075 case REGION_SMBUS: 1076 1077 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER) 1078 { 1079 AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL); 1080 } 1081 break; 1082 1083 default: 1084 1085 /* Nothing to do for other address spaces */ 1086 break; 1087 } 1088 } 1089 else 1090 { 1091 /* 1092 * This is one element of the field list. Check to make sure 1093 * that it does not go beyond the end of the parent operation region. 1094 * 1095 * In the code below: 1096 * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits) 1097 * Op->Asl.ExtraValue - Field start offset (bits) 1098 * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits) 1099 * Op->Asl.Child->Asl.ExtraValue - Field access width (bits) 1100 */ 1101 if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child) 1102 { 1103 LkCheckFieldRange (Op, 1104 Op->Asl.Parent->Asl.ExtraValue, 1105 Op->Asl.ExtraValue, 1106 (UINT32) Op->Asl.Child->Asl.Value.Integer, 1107 Op->Asl.Child->Asl.ExtraValue); 1108 } 1109 } 1110 } 1111 1112 Op->Asl.Node = Node; 1113 return (Status); 1114 } 1115 1116 1117 /******************************************************************************* 1118 * 1119 * FUNCTION: LkNamespaceLocateEnd 1120 * 1121 * PARAMETERS: ASL_WALK_CALLBACK 1122 * 1123 * RETURN: Status 1124 * 1125 * DESCRIPTION: Ascending callback used during cross reference. We only 1126 * need to worry about scope management here. 1127 * 1128 ******************************************************************************/ 1129 1130 static ACPI_STATUS 1131 LkNamespaceLocateEnd ( 1132 ACPI_PARSE_OBJECT *Op, 1133 UINT32 Level, 1134 void *Context) 1135 { 1136 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 1137 const ACPI_OPCODE_INFO *OpInfo; 1138 1139 1140 ACPI_FUNCTION_TRACE ("LkNamespaceLocateEnd"); 1141 1142 1143 /* We are only interested in opcodes that have an associated name */ 1144 1145 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1146 if (!(OpInfo->Flags & AML_NAMED)) 1147 { 1148 return (AE_OK); 1149 } 1150 1151 /* Not interested in name references, we did not open a scope for them */ 1152 1153 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 1154 (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 1155 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 1156 { 1157 return (AE_OK); 1158 } 1159 1160 /* Pop the scope stack if necessary */ 1161 1162 if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode))) 1163 { 1164 1165 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1166 "%s: Popping scope for Op %p\n", 1167 AcpiUtGetTypeName (OpInfo->ObjectType), Op)); 1168 1169 (void) AcpiDsScopeStackPop (WalkState); 1170 } 1171 1172 return (AE_OK); 1173 } 1174 1175 1176