Home | History | Annotate | Line # | Download | only in compiler
asllookup.c revision 1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: asllookup- Namespace lookup
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights.  You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code.  No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision.  In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change.  Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee.  Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution.  In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government.  In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************/
    115 
    116 
    117 #include "aslcompiler.h"
    118 #include "aslcompiler.y.h"
    119 
    120 #include "acparser.h"
    121 #include "amlcode.h"
    122 #include "acnamesp.h"
    123 #include "acdispat.h"
    124 
    125 
    126 #define _COMPONENT          ACPI_COMPILER
    127         ACPI_MODULE_NAME    ("asllookup")
    128 
    129 /* Local prototypes */
    130 
    131 static ACPI_STATUS
    132 LsCompareOneNamespaceObject (
    133     ACPI_HANDLE             ObjHandle,
    134     UINT32                  Level,
    135     void                    *Context,
    136     void                    **ReturnValue);
    137 
    138 static ACPI_STATUS
    139 LsDoOneNamespaceObject (
    140     ACPI_HANDLE             ObjHandle,
    141     UINT32                  Level,
    142     void                    *Context,
    143     void                    **ReturnValue);
    144 
    145 static BOOLEAN
    146 LkObjectExists (
    147     char                    *Name);
    148 
    149 static void
    150 LkCheckFieldRange (
    151     ACPI_PARSE_OBJECT       *Op,
    152     UINT32                  RegionBitLength,
    153     UINT32                  FieldBitOffset,
    154     UINT32                  FieldBitLength,
    155     UINT32                  AccessBitWidth);
    156 
    157 static ACPI_STATUS
    158 LkNamespaceLocateBegin (
    159     ACPI_PARSE_OBJECT       *Op,
    160     UINT32                  Level,
    161     void                    *Context);
    162 
    163 static ACPI_STATUS
    164 LkNamespaceLocateEnd (
    165     ACPI_PARSE_OBJECT       *Op,
    166     UINT32                  Level,
    167     void                    *Context);
    168 
    169 static ACPI_STATUS
    170 LkIsObjectUsed (
    171     ACPI_HANDLE             ObjHandle,
    172     UINT32                  Level,
    173     void                    *Context,
    174     void                    **ReturnValue);
    175 
    176 static ACPI_STATUS
    177 LsDoOnePathname (
    178     ACPI_HANDLE             ObjHandle,
    179     UINT32                  Level,
    180     void                    *Context,
    181     void                    **ReturnValue);
    182 
    183 void
    184 LsSetupNsList (
    185     void                    *Handle);
    186 
    187 ACPI_PARSE_OBJECT *
    188 LkGetNameOp (
    189     ACPI_PARSE_OBJECT       *Op);
    190 
    191 
    192 /*******************************************************************************
    193  *
    194  * FUNCTION:    LsDoOneNamespaceObject
    195  *
    196  * PARAMETERS:  ACPI_WALK_CALLBACK
    197  *
    198  * RETURN:      Status
    199  *
    200  * DESCRIPTION: Dump a namespace object to the namespace output file.
    201  *              Called during the walk of the namespace to dump all objects.
    202  *
    203  ******************************************************************************/
    204 
    205 static ACPI_STATUS
    206 LsDoOneNamespaceObject (
    207     ACPI_HANDLE             ObjHandle,
    208     UINT32                  Level,
    209     void                    *Context,
    210     void                    **ReturnValue)
    211 {
    212     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    213     ACPI_OPERAND_OBJECT     *ObjDesc;
    214     ACPI_PARSE_OBJECT       *Op;
    215 
    216 
    217     Gbl_NumNamespaceObjects++;
    218 
    219     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
    220         Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
    221         &Node->Name,
    222         AcpiUtGetTypeName (Node->Type));
    223 
    224     Op = Node->Op;
    225     ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
    226 
    227     if (!Op)
    228     {
    229         FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
    230         return (AE_OK);
    231     }
    232 
    233 
    234     if ((ObjDesc) &&
    235         (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
    236     {
    237         switch (Node->Type)
    238         {
    239         case ACPI_TYPE_INTEGER:
    240 
    241             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    242                 "       [Initial Value   0x%8.8X%8.8X]",
    243                 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
    244             break;
    245 
    246 
    247         case ACPI_TYPE_STRING:
    248 
    249             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    250                 "        [Initial Value   \"%s\"]",
    251                 ObjDesc->String.Pointer);
    252             break;
    253 
    254         default:
    255             /* Nothing to do for other types */
    256             break;
    257         }
    258 
    259     }
    260     else
    261     {
    262         switch (Node->Type)
    263         {
    264         case ACPI_TYPE_INTEGER:
    265 
    266             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
    267             {
    268                 Op = Op->Asl.Child;
    269             }
    270             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
    271                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
    272             {
    273                 Op = Op->Asl.Next;
    274             }
    275             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    276                 "       [Initial Value   0x%8.8X%8.8X]",
    277                 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
    278             break;
    279 
    280 
    281         case ACPI_TYPE_STRING:
    282 
    283             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
    284             {
    285                 Op = Op->Asl.Child;
    286             }
    287             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
    288                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
    289             {
    290                 Op = Op->Asl.Next;
    291             }
    292             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    293                 "        [Initial Value   \"%s\"]",
    294                 Op->Asl.Value.String);
    295             break;
    296 
    297 
    298         case ACPI_TYPE_LOCAL_REGION_FIELD:
    299 
    300             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
    301                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
    302             {
    303                 Op = Op->Asl.Child;
    304             }
    305             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    306                 "   [Offset 0x%04X   Length 0x%04X bits]",
    307                 Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
    308             break;
    309 
    310 
    311         case ACPI_TYPE_BUFFER_FIELD:
    312 
    313             switch (Op->Asl.ParseOpcode)
    314             {
    315             case PARSEOP_CREATEBYTEFIELD:
    316                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
    317                 break;
    318 
    319             case PARSEOP_CREATEDWORDFIELD:
    320                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
    321                 break;
    322 
    323             case PARSEOP_CREATEQWORDFIELD:
    324                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
    325                 break;
    326 
    327             case PARSEOP_CREATEWORDFIELD:
    328                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
    329                 break;
    330 
    331             case PARSEOP_CREATEBITFIELD:
    332                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
    333                 break;
    334 
    335             case PARSEOP_CREATEFIELD:
    336                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
    337                 break;
    338 
    339             default:
    340                 break;
    341 
    342             }
    343             break;
    344 
    345 
    346         case ACPI_TYPE_PACKAGE:
    347 
    348             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
    349             {
    350                 Op = Op->Asl.Child;
    351             }
    352             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
    353                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
    354             {
    355                 Op = Op->Asl.Next;
    356             }
    357             Op = Op->Asl.Child;
    358 
    359             if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
    360                 (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
    361             {
    362                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    363                     "       [Initial Length  0x%.2X elements]",
    364                     Op->Asl.Value.Integer);
    365             }
    366             break;
    367 
    368 
    369         case ACPI_TYPE_BUFFER:
    370 
    371             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
    372             {
    373                 Op = Op->Asl.Child;
    374             }
    375             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
    376                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
    377             {
    378                 Op = Op->Asl.Next;
    379             }
    380             Op = Op->Asl.Child;
    381 
    382             if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
    383             {
    384                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    385                     "        [Initial Length  0x%.2X bytes]",
    386                     Op->Asl.Value.Integer);
    387             }
    388             break;
    389 
    390 
    391         case ACPI_TYPE_METHOD:
    392 
    393             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    394                 "        [Code Length     0x%.4X bytes]",
    395                 Op->Asl.AmlSubtreeLength);
    396             break;
    397 
    398 
    399         case ACPI_TYPE_LOCAL_RESOURCE:
    400 
    401             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    402                 "  [Desc Offset     0x%.4X Bytes]", Node->Value);
    403             break;
    404 
    405 
    406         case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
    407 
    408             if (Node->Flags & 0x80)
    409             {
    410                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    411                     "   [Field Offset    0x%.4X Bits 0x%.4X Bytes]",
    412                     Node->Value, Node->Value / 8);
    413             }
    414             else
    415             {
    416                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
    417                     "   [Field Offset    0x%.4X Bytes]", Node->Value);
    418             }
    419             break;
    420 
    421 
    422         default:
    423             /* Nothing to do for other types */
    424             break;
    425         }
    426     }
    427 
    428     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
    429     return (AE_OK);
    430 }
    431 
    432 
    433 /*******************************************************************************
    434  *
    435  * FUNCTION:    LsSetupNsList
    436  *
    437  * PARAMETERS:  Handle          - local file handle
    438  *
    439  * RETURN:      None
    440  *
    441  * DESCRIPTION: Set the namespace output file to the input handle
    442  *
    443  ******************************************************************************/
    444 
    445 void
    446 LsSetupNsList (
    447     void                    *Handle)
    448 {
    449 
    450     Gbl_NsOutputFlag = TRUE;
    451     Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
    452 }
    453 
    454 
    455 /*******************************************************************************
    456  *
    457  * FUNCTION:    LsDoOnePathname
    458  *
    459  * PARAMETERS:  ACPI_WALK_CALLBACK
    460  *
    461  * RETURN:      Status
    462  *
    463  * DESCRIPTION: Print the full pathname for a namespace node.
    464  *
    465  ******************************************************************************/
    466 
    467 static ACPI_STATUS
    468 LsDoOnePathname (
    469     ACPI_HANDLE             ObjHandle,
    470     UINT32                  Level,
    471     void                    *Context,
    472     void                    **ReturnValue)
    473 {
    474     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    475     ACPI_STATUS             Status;
    476     ACPI_BUFFER             TargetPath;
    477 
    478 
    479     TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    480     Status = AcpiNsHandleToPathname (Node, &TargetPath);
    481     if (ACPI_FAILURE (Status))
    482     {
    483         return (Status);
    484     }
    485 
    486     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
    487     ACPI_FREE (TargetPath.Pointer);
    488 
    489     return (AE_OK);
    490 }
    491 
    492 
    493 /*******************************************************************************
    494  *
    495  * FUNCTION:    LsDisplayNamespace
    496  *
    497  * PARAMETERS:  None
    498  *
    499  * RETURN:      Status
    500  *
    501  * DESCRIPTION: Walk the namespace an display information about each node
    502  *              in the tree.  Information is written to the optional
    503  *              namespace output file.
    504  *
    505  ******************************************************************************/
    506 
    507 ACPI_STATUS
    508 LsDisplayNamespace (
    509     void)
    510 {
    511     ACPI_STATUS             Status;
    512 
    513 
    514     if (!Gbl_NsOutputFlag)
    515     {
    516         return (AE_OK);
    517     }
    518 
    519     Gbl_NumNamespaceObjects = 0;
    520 
    521     /* File header */
    522 
    523     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
    524     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
    525 
    526     /* Walk entire namespace from the root */
    527 
    528     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    529                 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
    530                 NULL, NULL);
    531 
    532     /* Print the full pathname for each namespace node */
    533 
    534     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
    535 
    536     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    537                 ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
    538                 NULL, NULL);
    539 
    540     return (Status);
    541 }
    542 
    543 
    544 /*******************************************************************************
    545  *
    546  * FUNCTION:    LsCompareOneNamespaceObject
    547  *
    548  * PARAMETERS:  ACPI_WALK_CALLBACK
    549  *
    550  * RETURN:      Status
    551  *
    552  * DESCRIPTION: Compare name of one object.
    553  *
    554  ******************************************************************************/
    555 
    556 static ACPI_STATUS
    557 LsCompareOneNamespaceObject (
    558     ACPI_HANDLE             ObjHandle,
    559     UINT32                  Level,
    560     void                    *Context,
    561     void                    **ReturnValue)
    562 {
    563     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    564 
    565 
    566     /* Simply check the name */
    567 
    568     if (*((UINT32 *) (Context)) == Node->Name.Integer)
    569     {
    570         /* Abort walk if we found one instance */
    571 
    572         return (AE_CTRL_TRUE);
    573     }
    574 
    575     return (AE_OK);
    576 }
    577 
    578 
    579 /*******************************************************************************
    580  *
    581  * FUNCTION:    LkObjectExists
    582  *
    583  * PARAMETERS:  Name            - 4 char ACPI name
    584  *
    585  * RETURN:      TRUE if name exists in namespace
    586  *
    587  * DESCRIPTION: Walk the namespace to find an object
    588  *
    589  ******************************************************************************/
    590 
    591 static BOOLEAN
    592 LkObjectExists (
    593     char                    *Name)
    594 {
    595     ACPI_STATUS             Status;
    596 
    597 
    598     /* Walk entire namespace from the supplied root */
    599 
    600     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    601                 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
    602                 Name, NULL);
    603     if (Status == AE_CTRL_TRUE)
    604     {
    605         /* At least one instance of the name was found */
    606 
    607         return (TRUE);
    608     }
    609 
    610     return (FALSE);
    611 }
    612 
    613 
    614 /*******************************************************************************
    615  *
    616  * FUNCTION:    LkGetNameOp
    617  *
    618  * PARAMETERS:  Op              - Current Op
    619  *
    620  * RETURN:      NameOp associated with the input op
    621  *
    622  * DESCRIPTION: Find the name declaration op associated with the operator
    623  *
    624  ******************************************************************************/
    625 
    626 ACPI_PARSE_OBJECT *
    627 LkGetNameOp (
    628     ACPI_PARSE_OBJECT       *Op)
    629 {
    630     const ACPI_OPCODE_INFO  *OpInfo;
    631     ACPI_PARSE_OBJECT       *NameOp = Op;
    632 
    633 
    634     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    635 
    636 
    637     /* Get the NamePath from the appropriate place */
    638 
    639     if (OpInfo->Flags & AML_NAMED)
    640     {
    641         /* For nearly all NAMED operators, the name reference is the first child */
    642 
    643         NameOp = Op->Asl.Child;
    644         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
    645         {
    646             /*
    647              * ALIAS is the only oddball opcode, the name declaration
    648              * (alias name) is the second operand
    649              */
    650             NameOp = Op->Asl.Child->Asl.Next;
    651         }
    652     }
    653     else if (OpInfo->Flags & AML_CREATE)
    654     {
    655         /* Name must appear as the last parameter */
    656 
    657         NameOp = Op->Asl.Child;
    658         while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
    659         {
    660             NameOp = NameOp->Asl.Next;
    661         }
    662     }
    663 
    664     return (NameOp);
    665 }
    666 
    667 
    668 /*******************************************************************************
    669  *
    670  * FUNCTION:    LkIsObjectUsed
    671  *
    672  * PARAMETERS:  ACPI_WALK_CALLBACK
    673  *
    674  * RETURN:      Status
    675  *
    676  * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
    677  *              We have to be careful, because some types and names are
    678  *              typically or always unreferenced, we don't want to issue
    679  *              excessive warnings.
    680  *
    681  ******************************************************************************/
    682 
    683 static ACPI_STATUS
    684 LkIsObjectUsed (
    685     ACPI_HANDLE             ObjHandle,
    686     UINT32                  Level,
    687     void                    *Context,
    688     void                    **ReturnValue)
    689 {
    690     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
    691 
    692 
    693     /* Referenced flag is set during the namespace xref */
    694 
    695     if (Node->Flags & ANOBJ_IS_REFERENCED)
    696     {
    697         return (AE_OK);
    698     }
    699 
    700     /*
    701      * Ignore names that start with an underscore,
    702      * these are the reserved ACPI names and are typically not referenced,
    703      * they are called by the host OS.
    704      */
    705     if (Node->Name.Ascii[0] == '_')
    706     {
    707         return (AE_OK);
    708     }
    709 
    710     /* There are some types that are typically not referenced, ignore them */
    711 
    712     switch (Node->Type)
    713     {
    714     case ACPI_TYPE_DEVICE:
    715     case ACPI_TYPE_PROCESSOR:
    716     case ACPI_TYPE_POWER:
    717     case ACPI_TYPE_LOCAL_RESOURCE:
    718         return (AE_OK);
    719 
    720     default:
    721         break;
    722     }
    723 
    724     /* All others are valid unreferenced namespace objects */
    725 
    726     if (Node->Op)
    727     {
    728         AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
    729     }
    730     return (AE_OK);
    731 }
    732 
    733 
    734 /*******************************************************************************
    735  *
    736  * FUNCTION:    LkFindUnreferencedObjects
    737  *
    738  * PARAMETERS:  None
    739  *
    740  * RETURN:      None
    741  *
    742  * DESCRIPTION: Namespace walk to find objects that are not referenced in any
    743  *              way. Must be called after the namespace has been cross
    744  *              referenced.
    745  *
    746  ******************************************************************************/
    747 
    748 void
    749 LkFindUnreferencedObjects (
    750     void)
    751 {
    752 
    753     /* Walk entire namespace from the supplied root */
    754 
    755     (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    756                 ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
    757                 NULL, NULL);
    758 }
    759 
    760 
    761 /*******************************************************************************
    762  *
    763  * FUNCTION:    LkCrossReferenceNamespace
    764  *
    765  * PARAMETERS:  None
    766  *
    767  * RETURN:      Status
    768  *
    769  * DESCRIPTION: Perform a cross reference check of the parse tree against the
    770  *              namespace.  Every named referenced within the parse tree
    771  *              should be get resolved with a namespace lookup.  If not, the
    772  *              original reference in the ASL code is invalid -- i.e., refers
    773  *              to a non-existent object.
    774  *
    775  * NOTE:  The ASL "External" operator causes the name to be inserted into the
    776  *        namespace so that references to the external name will be resolved
    777  *        correctly here.
    778  *
    779  ******************************************************************************/
    780 
    781 ACPI_STATUS
    782 LkCrossReferenceNamespace (
    783     void)
    784 {
    785     ACPI_WALK_STATE         *WalkState;
    786 
    787 
    788     DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
    789 
    790     /*
    791      * Create a new walk state for use when looking up names
    792      * within the namespace (Passed as context to the callbacks)
    793      */
    794     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    795     if (!WalkState)
    796     {
    797         return AE_NO_MEMORY;
    798     }
    799 
    800     /* Walk the entire parse tree */
    801 
    802     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
    803                         LkNamespaceLocateEnd, WalkState);
    804     return AE_OK;
    805 }
    806 
    807 
    808 /*******************************************************************************
    809  *
    810  * FUNCTION:    LkCheckFieldRange
    811  *
    812  * PARAMETERS:  RegionBitLength     - Length of entire parent region
    813  *              FieldBitOffset      - Start of the field unit (within region)
    814  *              FieldBitLength      - Entire length of field unit
    815  *              AccessBitWidth      - Access width of the field unit
    816  *
    817  * RETURN:      None
    818  *
    819  * DESCRIPTION: Check one field unit to make sure it fits in the parent
    820  *              op region.
    821  *
    822  * Note: AccessBitWidth must be either 8,16,32, or 64
    823  *
    824  ******************************************************************************/
    825 
    826 static void
    827 LkCheckFieldRange (
    828     ACPI_PARSE_OBJECT       *Op,
    829     UINT32                  RegionBitLength,
    830     UINT32                  FieldBitOffset,
    831     UINT32                  FieldBitLength,
    832     UINT32                  AccessBitWidth)
    833 {
    834     UINT32                  FieldEndBitOffset;
    835 
    836 
    837     /*
    838      * Check each field unit against the region size.  The entire
    839      * field unit (start offset plus length) must fit within the
    840      * region.
    841      */
    842     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
    843 
    844     if (FieldEndBitOffset > RegionBitLength)
    845     {
    846         /* Field definition itself is beyond the end-of-region */
    847 
    848         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
    849         return;
    850     }
    851 
    852     /*
    853      * Now check that the field plus AccessWidth doesn't go beyond
    854      * the end-of-region.  Assumes AccessBitWidth is a power of 2
    855      */
    856     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
    857 
    858     if (FieldEndBitOffset > RegionBitLength)
    859     {
    860         /* Field definition combined with the access is beyond EOR */
    861 
    862         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
    863     }
    864 }
    865 
    866 /*******************************************************************************
    867  *
    868  * FUNCTION:    LkNamespaceLocateBegin
    869  *
    870  * PARAMETERS:  ASL_WALK_CALLBACK
    871  *
    872  * RETURN:      Status
    873  *
    874  * DESCRIPTION: Descending callback used during cross-reference.  For named
    875  *              object references, attempt to locate the name in the
    876  *              namespace.
    877  *
    878  * NOTE: ASL references to named fields within resource descriptors are
    879  *       resolved to integer values here.  Therefore, this step is an
    880  *       important part of the code generation.  We don't know that the
    881  *       name refers to a resource descriptor until now.
    882  *
    883  ******************************************************************************/
    884 
    885 static ACPI_STATUS
    886 LkNamespaceLocateBegin (
    887     ACPI_PARSE_OBJECT       *Op,
    888     UINT32                  Level,
    889     void                    *Context)
    890 {
    891     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
    892     ACPI_NAMESPACE_NODE     *Node;
    893     ACPI_STATUS             Status;
    894     ACPI_OBJECT_TYPE        ObjectType;
    895     char                    *Path;
    896     UINT8                   PassedArgs;
    897     ACPI_PARSE_OBJECT       *NextOp;
    898     ACPI_PARSE_OBJECT       *OwningOp;
    899     ACPI_PARSE_OBJECT       *SpaceIdOp;
    900     UINT32                  MinimumLength;
    901     UINT32                  Temp;
    902     const ACPI_OPCODE_INFO  *OpInfo;
    903     UINT32                  Flags;
    904 
    905 
    906     ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
    907 
    908     /*
    909      * If this node is the actual declaration of a name
    910      * [such as the XXXX name in "Method (XXXX)"],
    911      * we are not interested in it here.  We only care about names that are
    912      * references to other objects within the namespace and the parent objects
    913      * of name declarations
    914      */
    915     if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
    916     {
    917         return (AE_OK);
    918     }
    919 
    920     /* We are only interested in opcodes that have an associated name */
    921 
    922     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    923 
    924     if ((!(OpInfo->Flags & AML_NAMED)) &&
    925         (!(OpInfo->Flags & AML_CREATE)) &&
    926         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
    927         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
    928         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
    929     {
    930         return (AE_OK);
    931     }
    932 
    933     /*
    934      * One special case: CondRefOf operator - we don't care if the name exists
    935      * or not at this point, just ignore it, the point of the operator is to
    936      * determine if the name exists at runtime.
    937      */
    938     if ((Op->Asl.Parent) &&
    939         (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
    940     {
    941         return (AE_OK);
    942     }
    943 
    944     /*
    945      * We must enable the "search-to-root" for single NameSegs, but
    946      * we have to be very careful about opening up scopes
    947      */
    948     Flags = ACPI_NS_SEARCH_PARENT;
    949     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
    950         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
    951         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
    952     {
    953         /*
    954          * These are name references, do not push the scope stack
    955          * for them.
    956          */
    957         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
    958     }
    959 
    960     /* Get the NamePath from the appropriate place */
    961 
    962     if (OpInfo->Flags & AML_NAMED)
    963     {
    964         /* For nearly all NAMED operators, the name reference is the first child */
    965 
    966         Path = Op->Asl.Child->Asl.Value.String;
    967         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
    968         {
    969             /*
    970              * ALIAS is the only oddball opcode, the name declaration
    971              * (alias name) is the second operand
    972              */
    973             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
    974         }
    975     }
    976     else if (OpInfo->Flags & AML_CREATE)
    977     {
    978         /* Name must appear as the last parameter */
    979 
    980         NextOp = Op->Asl.Child;
    981         while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
    982         {
    983             NextOp = NextOp->Asl.Next;
    984         }
    985         Path = NextOp->Asl.Value.String;
    986     }
    987     else
    988     {
    989         Path = Op->Asl.Value.String;
    990     }
    991 
    992     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    993     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    994         "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
    995 
    996     /*
    997      * Lookup the name in the namespace.  Name must exist at this point, or it
    998      * is an invalid reference.
    999      *
   1000      * The namespace is also used as a lookup table for references to resource
   1001      * descriptors and the fields within them.
   1002      */
   1003     Gbl_NsLookupCount++;
   1004 
   1005     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
   1006                 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
   1007     if (ACPI_FAILURE (Status))
   1008     {
   1009         if (Status == AE_NOT_FOUND)
   1010         {
   1011             /*
   1012              * We didn't find the name reference by path -- we can qualify this
   1013              * a little better before we print an error message
   1014              */
   1015             if (strlen (Path) == ACPI_NAME_SIZE)
   1016             {
   1017                 /* A simple, one-segment ACPI name */
   1018 
   1019                 if (LkObjectExists (Path))
   1020                 {
   1021                     /*
   1022                      * There exists such a name, but we couldn't get to it
   1023                      * from this scope
   1024                      */
   1025                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
   1026                         Op->Asl.ExternalName);
   1027                 }
   1028                 else
   1029                 {
   1030                     /* The name doesn't exist, period */
   1031 
   1032                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
   1033                         Op, Op->Asl.ExternalName);
   1034                 }
   1035             }
   1036             else
   1037             {
   1038                 /* Check for a fully qualified path */
   1039 
   1040                 if (Path[0] == AML_ROOT_PREFIX)
   1041                 {
   1042                     /* Gave full path, the object does not exist */
   1043 
   1044                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
   1045                         Op->Asl.ExternalName);
   1046                 }
   1047                 else
   1048                 {
   1049                     /*
   1050                      * We can't tell whether it doesn't exist or just
   1051                      * can't be reached.
   1052                      */
   1053                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
   1054                         Op->Asl.ExternalName);
   1055                 }
   1056             }
   1057 
   1058             Status = AE_OK;
   1059         }
   1060         return (Status);
   1061     }
   1062 
   1063     /* Check for a reference vs. name declaration */
   1064 
   1065     if (!(OpInfo->Flags & AML_NAMED) &&
   1066         !(OpInfo->Flags & AML_CREATE))
   1067     {
   1068         /* This node has been referenced, mark it for reference check */
   1069 
   1070         Node->Flags |= ANOBJ_IS_REFERENCED;
   1071     }
   1072 
   1073     /* Attempt to optimize the NamePath */
   1074 
   1075     OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
   1076 
   1077     /*
   1078      * 1) Dereference an alias (A name reference that is an alias)
   1079      *    Aliases are not nested, the alias always points to the final object
   1080      */
   1081     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
   1082         (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
   1083     {
   1084         /* This node points back to the original PARSEOP_ALIAS */
   1085 
   1086         NextOp = Node->Op;
   1087 
   1088         /* The first child is the alias target op */
   1089 
   1090         NextOp = NextOp->Asl.Child;
   1091 
   1092         /* That in turn points back to original target alias node */
   1093 
   1094         if (NextOp->Asl.Node)
   1095         {
   1096             Node = NextOp->Asl.Node;
   1097         }
   1098 
   1099         /* Else - forward reference to alias, will be resolved later */
   1100     }
   1101 
   1102     /* 2) Check for a reference to a resource descriptor */
   1103 
   1104     if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
   1105              (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
   1106     {
   1107         /*
   1108          * This was a reference to a field within a resource descriptor.  Extract
   1109          * the associated field offset (either a bit or byte offset depending on
   1110          * the field type) and change the named reference into an integer for
   1111          * AML code generation
   1112          */
   1113         Temp = Node->Value;
   1114         if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
   1115         {
   1116             Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
   1117         }
   1118 
   1119         /* Perform BitOffset <--> ByteOffset conversion if necessary */
   1120 
   1121         switch (Op->Asl.Parent->Asl.AmlOpcode)
   1122         {
   1123         case AML_CREATE_FIELD_OP:
   1124 
   1125             /* We allow a Byte offset to Bit Offset conversion for this op */
   1126 
   1127             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
   1128             {
   1129                 /* Simply multiply byte offset times 8 to get bit offset */
   1130 
   1131                 Temp = ACPI_MUL_8 (Temp);
   1132             }
   1133             break;
   1134 
   1135 
   1136         case AML_CREATE_BIT_FIELD_OP:
   1137 
   1138             /* This op requires a Bit Offset */
   1139 
   1140             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
   1141             {
   1142                 AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
   1143             }
   1144             break;
   1145 
   1146 
   1147         case AML_CREATE_BYTE_FIELD_OP:
   1148         case AML_CREATE_WORD_FIELD_OP:
   1149         case AML_CREATE_DWORD_FIELD_OP:
   1150         case AML_CREATE_QWORD_FIELD_OP:
   1151         case AML_INDEX_OP:
   1152 
   1153             /* These Ops require Byte offsets */
   1154 
   1155             if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
   1156             {
   1157                 AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
   1158             }
   1159             break;
   1160 
   1161 
   1162         default:
   1163             /* Nothing to do for other opcodes */
   1164             break;
   1165         }
   1166 
   1167         /* Now convert this node to an integer whose value is the field offset */
   1168 
   1169         Op->Asl.AmlLength       = 0;
   1170         Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
   1171         Op->Asl.Value.Integer   = (UINT64) Temp;
   1172         Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
   1173 
   1174         OpcGenerateAmlOpcode (Op);
   1175     }
   1176 
   1177     /* 3) Check for a method invocation */
   1178 
   1179     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
   1180                 (Node->Type == ACPI_TYPE_METHOD) &&
   1181                 (Op->Asl.Parent) &&
   1182                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
   1183 
   1184                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
   1185     {
   1186 
   1187         /*
   1188          * A reference to a method within one of these opcodes is not an
   1189          * invocation of the method, it is simply a reference to the method.
   1190          */
   1191         if ((Op->Asl.Parent) &&
   1192            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||
   1193             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||
   1194             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
   1195         {
   1196             return (AE_OK);
   1197         }
   1198         /*
   1199          * There are two types of method invocation:
   1200          * 1) Invocation with arguments -- the parser recognizes this
   1201          *    as a METHODCALL.
   1202          * 2) Invocation with no arguments --the parser cannot determine that
   1203          *    this is a method invocation, therefore we have to figure it out
   1204          *    here.
   1205          */
   1206         if (Node->Type != ACPI_TYPE_METHOD)
   1207         {
   1208             sprintf (MsgBuffer, "%s is a %s",
   1209                     Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
   1210 
   1211             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
   1212             return (AE_OK);
   1213         }
   1214 
   1215         /* Save the method node in the caller's op */
   1216 
   1217         Op->Asl.Node = Node;
   1218         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
   1219         {
   1220             return (AE_OK);
   1221         }
   1222 
   1223         /*
   1224          * This is a method invocation, with or without arguments.
   1225          * Count the number of arguments, each appears as a child
   1226          * under the parent node
   1227          */
   1228         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
   1229         UtSetParseOpName (Op);
   1230 
   1231         PassedArgs = 0;
   1232         NextOp     = Op->Asl.Child;
   1233 
   1234         while (NextOp)
   1235         {
   1236             PassedArgs++;
   1237             NextOp = NextOp->Asl.Next;
   1238         }
   1239 
   1240         if (Node->Value != ASL_EXTERNAL_METHOD)
   1241         {
   1242             /*
   1243              * Check the parsed arguments with the number expected by the
   1244              * method declaration itself
   1245              */
   1246             if (PassedArgs != Node->Value)
   1247             {
   1248                 sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
   1249                             Node->Value);
   1250 
   1251                 if (PassedArgs < Node->Value)
   1252                 {
   1253                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
   1254                 }
   1255                 else
   1256                 {
   1257                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
   1258                 }
   1259             }
   1260         }
   1261     }
   1262 
   1263     /* 4) Check for an ASL Field definition */
   1264 
   1265     else if ((Op->Asl.Parent) &&
   1266             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
   1267              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
   1268     {
   1269         /*
   1270          * Offset checking for fields.  If the parent operation region has a
   1271          * constant length (known at compile time), we can check fields
   1272          * defined in that region against the region length.  This will catch
   1273          * fields and field units that cannot possibly fit within the region.
   1274          *
   1275          * Note: Index fields do not directly reference an operation region,
   1276          * thus they are not included in this check.
   1277          */
   1278         if (Op == Op->Asl.Parent->Asl.Child)
   1279         {
   1280             /*
   1281              * This is the first child of the field node, which is
   1282              * the name of the region.  Get the parse node for the
   1283              * region -- which contains the length of the region.
   1284              */
   1285             OwningOp = Node->Op;
   1286             Op->Asl.Parent->Asl.ExtraValue =
   1287                 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
   1288 
   1289             /* Examine the field access width */
   1290 
   1291             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
   1292             {
   1293             case AML_FIELD_ACCESS_ANY:
   1294             case AML_FIELD_ACCESS_BYTE:
   1295             case AML_FIELD_ACCESS_BUFFER:
   1296             default:
   1297                 MinimumLength = 1;
   1298                 break;
   1299 
   1300             case AML_FIELD_ACCESS_WORD:
   1301                 MinimumLength = 2;
   1302                 break;
   1303 
   1304             case AML_FIELD_ACCESS_DWORD:
   1305                 MinimumLength = 4;
   1306                 break;
   1307 
   1308             case AML_FIELD_ACCESS_QWORD:
   1309                 MinimumLength = 8;
   1310                 break;
   1311             }
   1312 
   1313             /*
   1314              * Is the region at least as big as the access width?
   1315              * Note: DataTableRegions have 0 length
   1316              */
   1317             if (((UINT32) OwningOp->Asl.Value.Integer) &&
   1318                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
   1319             {
   1320                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
   1321             }
   1322 
   1323             /*
   1324              * Check EC/CMOS/SMBUS fields to make sure that the correct
   1325              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
   1326              */
   1327             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
   1328             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
   1329             {
   1330             case REGION_EC:
   1331             case REGION_CMOS:
   1332 
   1333                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
   1334                 {
   1335                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
   1336                 }
   1337                 break;
   1338 
   1339             case REGION_SMBUS:
   1340             case REGION_IPMI:
   1341 
   1342                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
   1343                 {
   1344                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
   1345                 }
   1346                 break;
   1347 
   1348             default:
   1349 
   1350                 /* Nothing to do for other address spaces */
   1351                 break;
   1352             }
   1353         }
   1354         else
   1355         {
   1356             /*
   1357              * This is one element of the field list.  Check to make sure
   1358              * that it does not go beyond the end of the parent operation region.
   1359              *
   1360              * In the code below:
   1361              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
   1362              *    Op->Asl.ExtraValue                  - Field start offset (bits)
   1363              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
   1364              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
   1365              */
   1366             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
   1367             {
   1368                 LkCheckFieldRange (Op,
   1369                             Op->Asl.Parent->Asl.ExtraValue,
   1370                             Op->Asl.ExtraValue,
   1371                             (UINT32) Op->Asl.Child->Asl.Value.Integer,
   1372                             Op->Asl.Child->Asl.ExtraValue);
   1373             }
   1374         }
   1375     }
   1376 
   1377     Op->Asl.Node = Node;
   1378     return (Status);
   1379 }
   1380 
   1381 
   1382 /*******************************************************************************
   1383  *
   1384  * FUNCTION:    LkNamespaceLocateEnd
   1385  *
   1386  * PARAMETERS:  ASL_WALK_CALLBACK
   1387  *
   1388  * RETURN:      Status
   1389  *
   1390  * DESCRIPTION: Ascending callback used during cross reference.  We only
   1391  *              need to worry about scope management here.
   1392  *
   1393  ******************************************************************************/
   1394 
   1395 static ACPI_STATUS
   1396 LkNamespaceLocateEnd (
   1397     ACPI_PARSE_OBJECT       *Op,
   1398     UINT32                  Level,
   1399     void                    *Context)
   1400 {
   1401     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
   1402     const ACPI_OPCODE_INFO  *OpInfo;
   1403 
   1404 
   1405     ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
   1406 
   1407 
   1408     /* We are only interested in opcodes that have an associated name */
   1409 
   1410     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
   1411     if (!(OpInfo->Flags & AML_NAMED))
   1412     {
   1413         return (AE_OK);
   1414     }
   1415 
   1416     /* Not interested in name references, we did not open a scope for them */
   1417 
   1418     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
   1419         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
   1420         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
   1421     {
   1422         return (AE_OK);
   1423     }
   1424 
   1425     /* Pop the scope stack if necessary */
   1426 
   1427     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
   1428     {
   1429 
   1430         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
   1431             "%s: Popping scope for Op %p\n",
   1432             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
   1433 
   1434         (void) AcpiDsScopeStackPop (WalkState);
   1435     }
   1436 
   1437     return (AE_OK);
   1438 }
   1439 
   1440 
   1441