1 /******************************************************************************
   2  *
   3  * Module Name: aslxref - Namespace cross-reference
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 
  45 #include "aslcompiler.h"
  46 #include "aslcompiler.y.h"
  47 #include "acparser.h"
  48 #include "amlcode.h"
  49 #include "acnamesp.h"
  50 #include "acdispat.h"
  51 
  52 
  53 #define _COMPONENT          ACPI_COMPILER
  54         ACPI_MODULE_NAME    ("aslxref")
  55 
  56 /* Local prototypes */
  57 
  58 static ACPI_STATUS
  59 XfNamespaceLocateBegin (
  60     ACPI_PARSE_OBJECT       *Op,
  61     UINT32                  Level,
  62     void                    *Context);
  63 
  64 static ACPI_STATUS
  65 XfNamespaceLocateEnd (
  66     ACPI_PARSE_OBJECT       *Op,
  67     UINT32                  Level,
  68     void                    *Context);
  69 
  70 static BOOLEAN
  71 XfObjectExists (
  72     char                    *Name);
  73 
  74 static ACPI_STATUS
  75 XfCompareOneNamespaceObject (
  76     ACPI_HANDLE             ObjHandle,
  77     UINT32                  Level,
  78     void                    *Context,
  79     void                    **ReturnValue);
  80 
  81 static void
  82 XfCheckFieldRange (
  83     ACPI_PARSE_OBJECT       *Op,
  84     UINT32                  RegionBitLength,
  85     UINT32                  FieldBitOffset,
  86     UINT32                  FieldBitLength,
  87     UINT32                  AccessBitWidth);
  88 
  89 
  90 /*******************************************************************************
  91  *
  92  * FUNCTION:    XfCrossReferenceNamespace
  93  *
  94  * PARAMETERS:  None
  95  *
  96  * RETURN:      Status
  97  *
  98  * DESCRIPTION: Perform a cross reference check of the parse tree against the
  99  *              namespace. Every named referenced within the parse tree
 100  *              should be get resolved with a namespace lookup. If not, the
 101  *              original reference in the ASL code is invalid -- i.e., refers
 102  *              to a non-existent object.
 103  *
 104  * NOTE:  The ASL "External" operator causes the name to be inserted into the
 105  *        namespace so that references to the external name will be resolved
 106  *        correctly here.
 107  *
 108  ******************************************************************************/
 109 
 110 ACPI_STATUS
 111 XfCrossReferenceNamespace (
 112     void)
 113 {
 114     ACPI_WALK_STATE         *WalkState;
 115 
 116 
 117     DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
 118 
 119     /*
 120      * Create a new walk state for use when looking up names
 121      * within the namespace (Passed as context to the callbacks)
 122      */
 123     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
 124     if (!WalkState)
 125     {
 126         return (AE_NO_MEMORY);
 127     }
 128 
 129     /* Walk the entire parse tree */
 130 
 131     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, XfNamespaceLocateBegin,
 132                         XfNamespaceLocateEnd, WalkState);
 133     return (AE_OK);
 134 }
 135 
 136 
 137 /*******************************************************************************
 138  *
 139  * FUNCTION:    XfObjectExists
 140  *
 141  * PARAMETERS:  Name            - 4 char ACPI name
 142  *
 143  * RETURN:      TRUE if name exists in namespace
 144  *
 145  * DESCRIPTION: Walk the namespace to find an object
 146  *
 147  ******************************************************************************/
 148 
 149 static BOOLEAN
 150 XfObjectExists (
 151     char                    *Name)
 152 {
 153     ACPI_STATUS             Status;
 154 
 155 
 156     /* Walk entire namespace from the supplied root */
 157 
 158     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 159                 ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
 160                 Name, NULL);
 161     if (Status == AE_CTRL_TRUE)
 162     {
 163         /* At least one instance of the name was found */
 164 
 165         return (TRUE);
 166     }
 167 
 168     return (FALSE);
 169 }
 170 
 171 
 172 /*******************************************************************************
 173  *
 174  * FUNCTION:    XfCompareOneNamespaceObject
 175  *
 176  * PARAMETERS:  ACPI_WALK_CALLBACK
 177  *
 178  * RETURN:      Status
 179  *
 180  * DESCRIPTION: Compare name of one object.
 181  *
 182  ******************************************************************************/
 183 
 184 static ACPI_STATUS
 185 XfCompareOneNamespaceObject (
 186     ACPI_HANDLE             ObjHandle,
 187     UINT32                  Level,
 188     void                    *Context,
 189     void                    **ReturnValue)
 190 {
 191     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
 192 
 193 
 194     /* Simply check the name */
 195 
 196     if (*((UINT32 *) (Context)) == Node->Name.Integer)
 197     {
 198         /* Abort walk if we found one instance */
 199 
 200         return (AE_CTRL_TRUE);
 201     }
 202 
 203     return (AE_OK);
 204 }
 205 
 206 
 207 /*******************************************************************************
 208  *
 209  * FUNCTION:    XfCheckFieldRange
 210  *
 211  * PARAMETERS:  RegionBitLength     - Length of entire parent region
 212  *              FieldBitOffset      - Start of the field unit (within region)
 213  *              FieldBitLength      - Entire length of field unit
 214  *              AccessBitWidth      - Access width of the field unit
 215  *
 216  * RETURN:      None
 217  *
 218  * DESCRIPTION: Check one field unit to make sure it fits in the parent
 219  *              op region.
 220  *
 221  * Note: AccessBitWidth must be either 8,16,32, or 64
 222  *
 223  ******************************************************************************/
 224 
 225 static void
 226 XfCheckFieldRange (
 227     ACPI_PARSE_OBJECT       *Op,
 228     UINT32                  RegionBitLength,
 229     UINT32                  FieldBitOffset,
 230     UINT32                  FieldBitLength,
 231     UINT32                  AccessBitWidth)
 232 {
 233     UINT32                  FieldEndBitOffset;
 234 
 235 
 236     /*
 237      * Check each field unit against the region size. The entire
 238      * field unit (start offset plus length) must fit within the
 239      * region.
 240      */
 241     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
 242 
 243     if (FieldEndBitOffset > RegionBitLength)
 244     {
 245         /* Field definition itself is beyond the end-of-region */
 246 
 247         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
 248         return;
 249     }
 250 
 251     /*
 252      * Now check that the field plus AccessWidth doesn't go beyond
 253      * the end-of-region. Assumes AccessBitWidth is a power of 2
 254      */
 255     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
 256 
 257     if (FieldEndBitOffset > RegionBitLength)
 258     {
 259         /* Field definition combined with the access is beyond EOR */
 260 
 261         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
 262     }
 263 }
 264 
 265 /*******************************************************************************
 266  *
 267  * FUNCTION:    XfNamespaceLocateBegin
 268  *
 269  * PARAMETERS:  ASL_WALK_CALLBACK
 270  *
 271  * RETURN:      Status
 272  *
 273  * DESCRIPTION: Descending callback used during cross-reference. For named
 274  *              object references, attempt to locate the name in the
 275  *              namespace.
 276  *
 277  * NOTE: ASL references to named fields within resource descriptors are
 278  *       resolved to integer values here. Therefore, this step is an
 279  *       important part of the code generation. We don't know that the
 280  *       name refers to a resource descriptor until now.
 281  *
 282  ******************************************************************************/
 283 
 284 static ACPI_STATUS
 285 XfNamespaceLocateBegin (
 286     ACPI_PARSE_OBJECT       *Op,
 287     UINT32                  Level,
 288     void                    *Context)
 289 {
 290     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
 291     ACPI_NAMESPACE_NODE     *Node;
 292     ACPI_STATUS             Status;
 293     ACPI_OBJECT_TYPE        ObjectType;
 294     char                    *Path;
 295     UINT8                   PassedArgs;
 296     ACPI_PARSE_OBJECT       *NextOp;
 297     ACPI_PARSE_OBJECT       *OwningOp;
 298     ACPI_PARSE_OBJECT       *SpaceIdOp;
 299     UINT32                  MinimumLength;
 300     UINT32                  Offset;
 301     UINT32                  FieldBitLength;
 302     UINT32                  TagBitLength;
 303     UINT8                   Message = 0;
 304     const ACPI_OPCODE_INFO  *OpInfo;
 305     UINT32                  Flags;
 306 
 307 
 308     ACPI_FUNCTION_TRACE_PTR (XfNamespaceLocateBegin, Op);
 309 
 310     /*
 311      * If this node is the actual declaration of a name
 312      * [such as the XXXX name in "Method (XXXX)"],
 313      * we are not interested in it here. We only care about names that are
 314      * references to other objects within the namespace and the parent objects
 315      * of name declarations
 316      */
 317     if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
 318     {
 319         return_ACPI_STATUS (AE_OK);
 320     }
 321 
 322     /* We are only interested in opcodes that have an associated name */
 323 
 324     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
 325 
 326     if ((!(OpInfo->Flags & AML_NAMED)) &&
 327         (!(OpInfo->Flags & AML_CREATE)) &&
 328         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
 329         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
 330         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
 331     {
 332         return_ACPI_STATUS (AE_OK);
 333     }
 334 
 335     /*
 336      * One special case: CondRefOf operator - we don't care if the name exists
 337      * or not at this point, just ignore it, the point of the operator is to
 338      * determine if the name exists at runtime.
 339      */
 340     if ((Op->Asl.Parent) &&
 341         (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
 342     {
 343         return_ACPI_STATUS (AE_OK);
 344     }
 345 
 346     /*
 347      * We must enable the "search-to-root" for single NameSegs, but
 348      * we have to be very careful about opening up scopes
 349      */
 350     Flags = ACPI_NS_SEARCH_PARENT;
 351     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
 352         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
 353         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
 354     {
 355         /*
 356          * These are name references, do not push the scope stack
 357          * for them.
 358          */
 359         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
 360     }
 361 
 362     /* Get the NamePath from the appropriate place */
 363 
 364     if (OpInfo->Flags & AML_NAMED)
 365     {
 366         /* For nearly all NAMED operators, the name reference is the first child */
 367 
 368         Path = Op->Asl.Child->Asl.Value.String;
 369         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
 370         {
 371             /*
 372              * ALIAS is the only oddball opcode, the name declaration
 373              * (alias name) is the second operand
 374              */
 375             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
 376         }
 377     }
 378     else if (OpInfo->Flags & AML_CREATE)
 379     {
 380         /* Name must appear as the last parameter */
 381 
 382         NextOp = Op->Asl.Child;
 383         while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
 384         {
 385             NextOp = NextOp->Asl.Next;
 386         }
 387         Path = NextOp->Asl.Value.String;
 388     }
 389     else
 390     {
 391         Path = Op->Asl.Value.String;
 392     }
 393 
 394     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
 395     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 396         "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
 397 
 398     /*
 399      * Lookup the name in the namespace. Name must exist at this point, or it
 400      * is an invalid reference.
 401      *
 402      * The namespace is also used as a lookup table for references to resource
 403      * descriptors and the fields within them.
 404      */
 405     Gbl_NsLookupCount++;
 406 
 407     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
 408                 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
 409     if (ACPI_FAILURE (Status))
 410     {
 411         if (Status == AE_NOT_FOUND)
 412         {
 413             /*
 414              * We didn't find the name reference by path -- we can qualify this
 415              * a little better before we print an error message
 416              */
 417             if (strlen (Path) == ACPI_NAME_SIZE)
 418             {
 419                 /* A simple, one-segment ACPI name */
 420 
 421                 if (XfObjectExists (Path))
 422                 {
 423                     /*
 424                      * There exists such a name, but we couldn't get to it
 425                      * from this scope
 426                      */
 427                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
 428                         Op->Asl.ExternalName);
 429                 }
 430                 else
 431                 {
 432                     /* The name doesn't exist, period */
 433 
 434                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
 435                         Op, Op->Asl.ExternalName);
 436                 }
 437             }
 438             else
 439             {
 440                 /* Check for a fully qualified path */
 441 
 442                 if (Path[0] == AML_ROOT_PREFIX)
 443                 {
 444                     /* Gave full path, the object does not exist */
 445 
 446                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
 447                         Op->Asl.ExternalName);
 448                 }
 449                 else
 450                 {
 451                     /*
 452                      * We can't tell whether it doesn't exist or just
 453                      * can't be reached.
 454                      */
 455                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
 456                         Op->Asl.ExternalName);
 457                 }
 458             }
 459 
 460             Status = AE_OK;
 461         }
 462 
 463         return_ACPI_STATUS (Status);
 464     }
 465 
 466     /* Check for a reference vs. name declaration */
 467 
 468     if (!(OpInfo->Flags & AML_NAMED) &&
 469         !(OpInfo->Flags & AML_CREATE))
 470     {
 471         /* This node has been referenced, mark it for reference check */
 472 
 473         Node->Flags |= ANOBJ_IS_REFERENCED;
 474     }
 475 
 476     /* Attempt to optimize the NamePath */
 477 
 478     OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
 479 
 480     /*
 481      * 1) Dereference an alias (A name reference that is an alias)
 482      *    Aliases are not nested, the alias always points to the final object
 483      */
 484     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
 485         (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
 486     {
 487         /* This node points back to the original PARSEOP_ALIAS */
 488 
 489         NextOp = Node->Op;
 490 
 491         /* The first child is the alias target op */
 492 
 493         NextOp = NextOp->Asl.Child;
 494 
 495         /* That in turn points back to original target alias node */
 496 
 497         if (NextOp->Asl.Node)
 498         {
 499             Node = NextOp->Asl.Node;
 500         }
 501 
 502         /* Else - forward reference to alias, will be resolved later */
 503     }
 504 
 505     /* 2) Check for a reference to a resource descriptor */
 506 
 507     if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
 508         (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
 509     {
 510         /*
 511          * This was a reference to a field within a resource descriptor.
 512          * Extract the associated field offset (either a bit or byte
 513          * offset depending on the field type) and change the named
 514          * reference into an integer for AML code generation
 515          */
 516         Offset = Node->Value;
 517         TagBitLength = Node->Length;
 518 
 519         /*
 520          * If a field is being created, generate the length (in bits) of
 521          * the field. Note: Opcodes other than CreateXxxField and Index
 522          * can come through here. For other opcodes, we just need to
 523          * convert the resource tag reference to an integer offset.
 524          */
 525         switch (Op->Asl.Parent->Asl.AmlOpcode)
 526         {
 527         case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
 528             /*
 529              * We know the length operand is an integer constant because
 530              * we know that it contains a reference to a resource
 531              * descriptor tag.
 532              */
 533             FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
 534             break;
 535 
 536         case AML_CREATE_BIT_FIELD_OP:
 537 
 538             FieldBitLength = 1;
 539             break;
 540 
 541         case AML_CREATE_BYTE_FIELD_OP:
 542         case AML_INDEX_OP:
 543 
 544             FieldBitLength = 8;
 545             break;
 546 
 547         case AML_CREATE_WORD_FIELD_OP:
 548 
 549             FieldBitLength = 16;
 550             break;
 551 
 552         case AML_CREATE_DWORD_FIELD_OP:
 553 
 554             FieldBitLength = 32;
 555             break;
 556 
 557         case AML_CREATE_QWORD_FIELD_OP:
 558 
 559             FieldBitLength = 64;
 560             break;
 561 
 562         default:
 563 
 564             FieldBitLength = 0;
 565             break;
 566         }
 567 
 568         /* Check the field length against the length of the resource tag */
 569 
 570         if (FieldBitLength)
 571         {
 572             if (TagBitLength < FieldBitLength)
 573             {
 574                 Message = ASL_MSG_TAG_SMALLER;
 575             }
 576             else if (TagBitLength > FieldBitLength)
 577             {
 578                 Message = ASL_MSG_TAG_LARGER;
 579             }
 580 
 581             if (Message)
 582             {
 583                 sprintf (MsgBuffer, "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
 584                     TagBitLength, (TagBitLength > 1) ? "s" : "",
 585                     FieldBitLength, (FieldBitLength > 1) ? "s" : "");
 586 
 587                 AslError (ASL_WARNING, Message, Op, MsgBuffer);
 588             }
 589         }
 590 
 591         /* Convert the BitOffset to a ByteOffset for certain opcodes */
 592 
 593         switch (Op->Asl.Parent->Asl.AmlOpcode)
 594         {
 595         case AML_CREATE_BYTE_FIELD_OP:
 596         case AML_CREATE_WORD_FIELD_OP:
 597         case AML_CREATE_DWORD_FIELD_OP:
 598         case AML_CREATE_QWORD_FIELD_OP:
 599         case AML_INDEX_OP:
 600 
 601             Offset = ACPI_DIV_8 (Offset);
 602             break;
 603 
 604         default:
 605 
 606             break;
 607         }
 608 
 609         /* Now convert this node to an integer whose value is the field offset */
 610 
 611         Op->Asl.AmlLength = 0;
 612         Op->Asl.ParseOpcode = PARSEOP_INTEGER;
 613         Op->Asl.Value.Integer = (UINT64) Offset;
 614         Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
 615 
 616         OpcGenerateAmlOpcode (Op);
 617     }
 618 
 619     /* 3) Check for a method invocation */
 620 
 621     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
 622                 (Node->Type == ACPI_TYPE_METHOD) &&
 623                 (Op->Asl.Parent) &&
 624                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
 625 
 626                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
 627     {
 628         /*
 629          * A reference to a method within one of these opcodes is not an
 630          * invocation of the method, it is simply a reference to the method.
 631          */
 632         if ((Op->Asl.Parent) &&
 633            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||
 634             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||
 635             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
 636         {
 637             return_ACPI_STATUS (AE_OK);
 638         }
 639         /*
 640          * There are two types of method invocation:
 641          * 1) Invocation with arguments -- the parser recognizes this
 642          *    as a METHODCALL.
 643          * 2) Invocation with no arguments --the parser cannot determine that
 644          *    this is a method invocation, therefore we have to figure it out
 645          *    here.
 646          */
 647         if (Node->Type != ACPI_TYPE_METHOD)
 648         {
 649             sprintf (MsgBuffer, "%s is a %s",
 650                     Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
 651 
 652             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
 653             return_ACPI_STATUS (AE_OK);
 654         }
 655 
 656         /* Save the method node in the caller's op */
 657 
 658         Op->Asl.Node = Node;
 659         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
 660         {
 661             return_ACPI_STATUS (AE_OK);
 662         }
 663 
 664         /*
 665          * This is a method invocation, with or without arguments.
 666          * Count the number of arguments, each appears as a child
 667          * under the parent node
 668          */
 669         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
 670         UtSetParseOpName (Op);
 671 
 672         PassedArgs = 0;
 673         NextOp     = Op->Asl.Child;
 674 
 675         while (NextOp)
 676         {
 677             PassedArgs++;
 678             NextOp = NextOp->Asl.Next;
 679         }
 680 
 681         if (Node->Value != ASL_EXTERNAL_METHOD)
 682         {
 683             /*
 684              * Check the parsed arguments with the number expected by the
 685              * method declaration itself
 686              */
 687             if (PassedArgs != Node->Value)
 688             {
 689                 sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
 690                             Node->Value);
 691 
 692                 if (PassedArgs < Node->Value)
 693                 {
 694                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
 695                 }
 696                 else
 697                 {
 698                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
 699                 }
 700             }
 701         }
 702     }
 703 
 704     /* 4) Check for an ASL Field definition */
 705 
 706     else if ((Op->Asl.Parent) &&
 707             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
 708              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
 709     {
 710         /*
 711          * Offset checking for fields. If the parent operation region has a
 712          * constant length (known at compile time), we can check fields
 713          * defined in that region against the region length. This will catch
 714          * fields and field units that cannot possibly fit within the region.
 715          *
 716          * Note: Index fields do not directly reference an operation region,
 717          * thus they are not included in this check.
 718          */
 719         if (Op == Op->Asl.Parent->Asl.Child)
 720         {
 721             /*
 722              * This is the first child of the field node, which is
 723              * the name of the region. Get the parse node for the
 724              * region -- which contains the length of the region.
 725              */
 726             OwningOp = Node->Op;
 727             Op->Asl.Parent->Asl.ExtraValue =
 728                 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
 729 
 730             /* Examine the field access width */
 731 
 732             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
 733             {
 734             case AML_FIELD_ACCESS_ANY:
 735             case AML_FIELD_ACCESS_BYTE:
 736             case AML_FIELD_ACCESS_BUFFER:
 737             default:
 738 
 739                 MinimumLength = 1;
 740                 break;
 741 
 742             case AML_FIELD_ACCESS_WORD:
 743 
 744                 MinimumLength = 2;
 745                 break;
 746 
 747             case AML_FIELD_ACCESS_DWORD:
 748 
 749                 MinimumLength = 4;
 750                 break;
 751 
 752             case AML_FIELD_ACCESS_QWORD:
 753 
 754                 MinimumLength = 8;
 755                 break;
 756             }
 757 
 758             /*
 759              * Is the region at least as big as the access width?
 760              * Note: DataTableRegions have 0 length
 761              */
 762             if (((UINT32) OwningOp->Asl.Value.Integer) &&
 763                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
 764             {
 765                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
 766             }
 767 
 768             /*
 769              * Check EC/CMOS/SMBUS fields to make sure that the correct
 770              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
 771              */
 772             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
 773             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
 774             {
 775             case ACPI_ADR_SPACE_EC:
 776             case ACPI_ADR_SPACE_CMOS:
 777             case ACPI_ADR_SPACE_GPIO:
 778 
 779                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
 780                 {
 781                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
 782                 }
 783                 break;
 784 
 785             case ACPI_ADR_SPACE_SMBUS:
 786             case ACPI_ADR_SPACE_IPMI:
 787             case ACPI_ADR_SPACE_GSBUS:
 788 
 789                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
 790                 {
 791                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
 792                 }
 793                 break;
 794 
 795             default:
 796 
 797                 /* Nothing to do for other address spaces */
 798 
 799                 break;
 800             }
 801         }
 802         else
 803         {
 804             /*
 805              * This is one element of the field list. Check to make sure
 806              * that it does not go beyond the end of the parent operation region.
 807              *
 808              * In the code below:
 809              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
 810              *    Op->Asl.ExtraValue                  - Field start offset (bits)
 811              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
 812              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
 813              */
 814             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
 815             {
 816                 XfCheckFieldRange (Op,
 817                             Op->Asl.Parent->Asl.ExtraValue,
 818                             Op->Asl.ExtraValue,
 819                             (UINT32) Op->Asl.Child->Asl.Value.Integer,
 820                             Op->Asl.Child->Asl.ExtraValue);
 821             }
 822         }
 823     }
 824 
 825     Op->Asl.Node = Node;
 826     return_ACPI_STATUS (Status);
 827 }
 828 
 829 
 830 /*******************************************************************************
 831  *
 832  * FUNCTION:    XfNamespaceLocateEnd
 833  *
 834  * PARAMETERS:  ASL_WALK_CALLBACK
 835  *
 836  * RETURN:      Status
 837  *
 838  * DESCRIPTION: Ascending callback used during cross reference. We only
 839  *              need to worry about scope management here.
 840  *
 841  ******************************************************************************/
 842 
 843 static ACPI_STATUS
 844 XfNamespaceLocateEnd (
 845     ACPI_PARSE_OBJECT       *Op,
 846     UINT32                  Level,
 847     void                    *Context)
 848 {
 849     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
 850     const ACPI_OPCODE_INFO  *OpInfo;
 851 
 852 
 853     ACPI_FUNCTION_TRACE (XfNamespaceLocateEnd);
 854 
 855 
 856     /* We are only interested in opcodes that have an associated name */
 857 
 858     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
 859     if (!(OpInfo->Flags & AML_NAMED))
 860     {
 861         return_ACPI_STATUS (AE_OK);
 862     }
 863 
 864     /* Not interested in name references, we did not open a scope for them */
 865 
 866     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
 867         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
 868         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
 869     {
 870         return_ACPI_STATUS (AE_OK);
 871     }
 872 
 873     /* Pop the scope stack if necessary */
 874 
 875     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
 876     {
 877 
 878         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 879             "%s: Popping scope for Op %p\n",
 880             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
 881 
 882         (void) AcpiDsScopeStackPop (WalkState);
 883     }
 884 
 885     return_ACPI_STATUS (AE_OK);
 886 }