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