xref: /freebsd/sys/contrib/dev/acpica/compiler/asllookup.c (revision 53289f6a611fdc6a66bd5138b1203ab1e2bfd4fc)
153289f6aSNate Lawson /******************************************************************************
253289f6aSNate Lawson  *
353289f6aSNate Lawson  * Module Name: asllookup- Namespace lookup
453289f6aSNate Lawson  *              $Revision: 82 $
553289f6aSNate Lawson  *
653289f6aSNate Lawson  *****************************************************************************/
753289f6aSNate Lawson 
853289f6aSNate Lawson /******************************************************************************
953289f6aSNate Lawson  *
1053289f6aSNate Lawson  * 1. Copyright Notice
1153289f6aSNate Lawson  *
1253289f6aSNate Lawson  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
1353289f6aSNate Lawson  * All rights reserved.
1453289f6aSNate Lawson  *
1553289f6aSNate Lawson  * 2. License
1653289f6aSNate Lawson  *
1753289f6aSNate Lawson  * 2.1. This is your license from Intel Corp. under its intellectual property
1853289f6aSNate Lawson  * rights.  You may have additional license terms from the party that provided
1953289f6aSNate Lawson  * you this software, covering your right to use that party's intellectual
2053289f6aSNate Lawson  * property rights.
2153289f6aSNate Lawson  *
2253289f6aSNate Lawson  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2353289f6aSNate Lawson  * copy of the source code appearing in this file ("Covered Code") an
2453289f6aSNate Lawson  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2553289f6aSNate Lawson  * base code distributed originally by Intel ("Original Intel Code") to copy,
2653289f6aSNate Lawson  * make derivatives, distribute, use and display any portion of the Covered
2753289f6aSNate Lawson  * Code in any form, with the right to sublicense such rights; and
2853289f6aSNate Lawson  *
2953289f6aSNate Lawson  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3053289f6aSNate Lawson  * license (with the right to sublicense), under only those claims of Intel
3153289f6aSNate Lawson  * patents that are infringed by the Original Intel Code, to make, use, sell,
3253289f6aSNate Lawson  * offer to sell, and import the Covered Code and derivative works thereof
3353289f6aSNate Lawson  * solely to the minimum extent necessary to exercise the above copyright
3453289f6aSNate Lawson  * license, and in no event shall the patent license extend to any additions
3553289f6aSNate Lawson  * to or modifications of the Original Intel Code.  No other license or right
3653289f6aSNate Lawson  * is granted directly or by implication, estoppel or otherwise;
3753289f6aSNate Lawson  *
3853289f6aSNate Lawson  * The above copyright and patent license is granted only if the following
3953289f6aSNate Lawson  * conditions are met:
4053289f6aSNate Lawson  *
4153289f6aSNate Lawson  * 3. Conditions
4253289f6aSNate Lawson  *
4353289f6aSNate Lawson  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4453289f6aSNate Lawson  * Redistribution of source code of any substantial portion of the Covered
4553289f6aSNate Lawson  * Code or modification with rights to further distribute source must include
4653289f6aSNate Lawson  * the above Copyright Notice, the above License, this list of Conditions,
4753289f6aSNate Lawson  * and the following Disclaimer and Export Compliance provision.  In addition,
4853289f6aSNate Lawson  * Licensee must cause all Covered Code to which Licensee contributes to
4953289f6aSNate Lawson  * contain a file documenting the changes Licensee made to create that Covered
5053289f6aSNate Lawson  * Code and the date of any change.  Licensee must include in that file the
5153289f6aSNate Lawson  * documentation of any changes made by any predecessor Licensee.  Licensee
5253289f6aSNate Lawson  * must include a prominent statement that the modification is derived,
5353289f6aSNate Lawson  * directly or indirectly, from Original Intel Code.
5453289f6aSNate Lawson  *
5553289f6aSNate Lawson  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5653289f6aSNate Lawson  * Redistribution of source code of any substantial portion of the Covered
5753289f6aSNate Lawson  * Code or modification without rights to further distribute source must
5853289f6aSNate Lawson  * include the following Disclaimer and Export Compliance provision in the
5953289f6aSNate Lawson  * documentation and/or other materials provided with distribution.  In
6053289f6aSNate Lawson  * addition, Licensee may not authorize further sublicense of source of any
6153289f6aSNate Lawson  * portion of the Covered Code, and must include terms to the effect that the
6253289f6aSNate Lawson  * license from Licensee to its licensee is limited to the intellectual
6353289f6aSNate Lawson  * property embodied in the software Licensee provides to its licensee, and
6453289f6aSNate Lawson  * not to intellectual property embodied in modifications its licensee may
6553289f6aSNate Lawson  * make.
6653289f6aSNate Lawson  *
6753289f6aSNate Lawson  * 3.3. Redistribution of Executable. Redistribution in executable form of any
6853289f6aSNate Lawson  * substantial portion of the Covered Code or modification must reproduce the
6953289f6aSNate Lawson  * above Copyright Notice, and the following Disclaimer and Export Compliance
7053289f6aSNate Lawson  * provision in the documentation and/or other materials provided with the
7153289f6aSNate Lawson  * distribution.
7253289f6aSNate Lawson  *
7353289f6aSNate Lawson  * 3.4. Intel retains all right, title, and interest in and to the Original
7453289f6aSNate Lawson  * Intel Code.
7553289f6aSNate Lawson  *
7653289f6aSNate Lawson  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7753289f6aSNate Lawson  * Intel shall be used in advertising or otherwise to promote the sale, use or
7853289f6aSNate Lawson  * other dealings in products derived from or relating to the Covered Code
7953289f6aSNate Lawson  * without prior written authorization from Intel.
8053289f6aSNate Lawson  *
8153289f6aSNate Lawson  * 4. Disclaimer and Export Compliance
8253289f6aSNate Lawson  *
8353289f6aSNate Lawson  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8453289f6aSNate Lawson  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8553289f6aSNate Lawson  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8653289f6aSNate Lawson  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8753289f6aSNate Lawson  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8853289f6aSNate Lawson  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8953289f6aSNate Lawson  * PARTICULAR PURPOSE.
9053289f6aSNate Lawson  *
9153289f6aSNate Lawson  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9253289f6aSNate Lawson  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9353289f6aSNate Lawson  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9453289f6aSNate Lawson  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9553289f6aSNate Lawson  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9653289f6aSNate Lawson  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9753289f6aSNate Lawson  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9853289f6aSNate Lawson  * LIMITED REMEDY.
9953289f6aSNate Lawson  *
10053289f6aSNate Lawson  * 4.3. Licensee shall not export, either directly or indirectly, any of this
10153289f6aSNate Lawson  * software or system incorporating such software without first obtaining any
10253289f6aSNate Lawson  * required license or other approval from the U. S. Department of Commerce or
10353289f6aSNate Lawson  * any other agency or department of the United States Government.  In the
10453289f6aSNate Lawson  * event Licensee exports any such software from the United States or
10553289f6aSNate Lawson  * re-exports any such software from a foreign destination, Licensee shall
10653289f6aSNate Lawson  * ensure that the distribution and export/re-export of the software is in
10753289f6aSNate Lawson  * compliance with all laws, regulations, orders, or other restrictions of the
10853289f6aSNate Lawson  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10953289f6aSNate Lawson  * any of its subsidiaries will export/re-export any technical data, process,
11053289f6aSNate Lawson  * software, or service, directly or indirectly, to any country for which the
11153289f6aSNate Lawson  * United States government or any agency thereof requires an export license,
11253289f6aSNate Lawson  * other governmental approval, or letter of assurance, without first obtaining
11353289f6aSNate Lawson  * such license, approval or letter.
11453289f6aSNate Lawson  *
11553289f6aSNate Lawson  *****************************************************************************/
11653289f6aSNate Lawson 
11753289f6aSNate Lawson 
11853289f6aSNate Lawson #include "aslcompiler.h"
11953289f6aSNate Lawson #include "aslcompiler.y.h"
12053289f6aSNate Lawson 
12153289f6aSNate Lawson #include "acparser.h"
12253289f6aSNate Lawson #include "amlcode.h"
12353289f6aSNate Lawson #include "acnamesp.h"
12453289f6aSNate Lawson #include "acdispat.h"
12553289f6aSNate Lawson 
12653289f6aSNate Lawson 
12753289f6aSNate Lawson #define _COMPONENT          ACPI_COMPILER
12853289f6aSNate Lawson         ACPI_MODULE_NAME    ("asllookup")
12953289f6aSNate Lawson 
13053289f6aSNate Lawson 
13153289f6aSNate Lawson /*******************************************************************************
13253289f6aSNate Lawson  *
13353289f6aSNate Lawson  * FUNCTION:    LsDoOneNamespaceObject
13453289f6aSNate Lawson  *
13553289f6aSNate Lawson  * PARAMETERS:  ACPI_WALK_CALLBACK
13653289f6aSNate Lawson  *
13753289f6aSNate Lawson  * RETURN:      Status
13853289f6aSNate Lawson  *
13953289f6aSNate Lawson  * DESCRIPTION: Dump a namespace object to the namespace output file.
14053289f6aSNate Lawson  *              Called during the walk of the namespace to dump all objects.
14153289f6aSNate Lawson  *
14253289f6aSNate Lawson  ******************************************************************************/
14353289f6aSNate Lawson 
14453289f6aSNate Lawson ACPI_STATUS
14553289f6aSNate Lawson LsDoOneNamespaceObject (
14653289f6aSNate Lawson     ACPI_HANDLE             ObjHandle,
14753289f6aSNate Lawson     UINT32                  Level,
14853289f6aSNate Lawson     void                    *Context,
14953289f6aSNate Lawson     void                    **ReturnValue)
15053289f6aSNate Lawson {
15153289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
15253289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op;
15353289f6aSNate Lawson 
15453289f6aSNate Lawson 
15553289f6aSNate Lawson     Gbl_NumNamespaceObjects++;
15653289f6aSNate Lawson 
15753289f6aSNate Lawson     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5d  [%d]  %*s %4.4s - %s",
15853289f6aSNate Lawson                         Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
15953289f6aSNate Lawson                         &Node->Name,
16053289f6aSNate Lawson                         AcpiUtGetTypeName (Node->Type));
16153289f6aSNate Lawson 
16253289f6aSNate Lawson     Op = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
16353289f6aSNate Lawson 
16453289f6aSNate Lawson     if (Op)
16553289f6aSNate Lawson     {
16653289f6aSNate Lawson         if (Op->Asl.ParseOpcode == PARSEOP_NAME)
16753289f6aSNate Lawson         {
16853289f6aSNate Lawson             Op = Op->Asl.Child;
16953289f6aSNate Lawson         }
17053289f6aSNate Lawson 
17153289f6aSNate Lawson         switch (Node->Type)
17253289f6aSNate Lawson         {
17353289f6aSNate Lawson         case ACPI_TYPE_INTEGER:
17453289f6aSNate Lawson 
17553289f6aSNate Lawson             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
17653289f6aSNate Lawson                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
17753289f6aSNate Lawson             {
17853289f6aSNate Lawson                 Op = Op->Asl.Next;
17953289f6aSNate Lawson             }
18053289f6aSNate Lawson 
18153289f6aSNate Lawson             if (Op->Asl.Value.Integer > ACPI_UINT32_MAX)
18253289f6aSNate Lawson             {
18353289f6aSNate Lawson                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Initial Value = 0x%X%X]",
18453289f6aSNate Lawson                             ACPI_HIDWORD (Op->Asl.Value.Integer64), (UINT32) Op->Asl.Value.Integer);
18553289f6aSNate Lawson             }
18653289f6aSNate Lawson             else
18753289f6aSNate Lawson             {
18853289f6aSNate Lawson                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Initial Value = 0x%X]",
18953289f6aSNate Lawson                             (UINT32) Op->Asl.Value.Integer);
19053289f6aSNate Lawson             }
19153289f6aSNate Lawson             break;
19253289f6aSNate Lawson 
19353289f6aSNate Lawson 
19453289f6aSNate Lawson         case ACPI_TYPE_STRING:
19553289f6aSNate Lawson 
19653289f6aSNate Lawson             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
19753289f6aSNate Lawson                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
19853289f6aSNate Lawson             {
19953289f6aSNate Lawson                 Op = Op->Asl.Next;
20053289f6aSNate Lawson             }
20153289f6aSNate Lawson 
20253289f6aSNate Lawson             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Initial Value = \"%s\"]",
20353289f6aSNate Lawson                         Op->Asl.Value.String);
20453289f6aSNate Lawson             break;
20553289f6aSNate Lawson 
20653289f6aSNate Lawson 
20753289f6aSNate Lawson         case ACPI_TYPE_LOCAL_REGION_FIELD:
20853289f6aSNate Lawson 
20953289f6aSNate Lawson             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
21053289f6aSNate Lawson                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
21153289f6aSNate Lawson             {
21253289f6aSNate Lawson                 Op = Op->Asl.Child;
21353289f6aSNate Lawson             }
21453289f6aSNate Lawson             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "    [Offset 0x%02X, Length 0x%02X]",
21553289f6aSNate Lawson                         Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
21653289f6aSNate Lawson             break;
21753289f6aSNate Lawson 
21853289f6aSNate Lawson 
21953289f6aSNate Lawson         default:
22053289f6aSNate Lawson             /* Nothing to do for other types */
22153289f6aSNate Lawson             break;
22253289f6aSNate Lawson         }
22353289f6aSNate Lawson     }
22453289f6aSNate Lawson 
22553289f6aSNate Lawson     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
22653289f6aSNate Lawson     return (AE_OK);
22753289f6aSNate Lawson }
22853289f6aSNate Lawson 
22953289f6aSNate Lawson 
23053289f6aSNate Lawson /*******************************************************************************
23153289f6aSNate Lawson  *
23253289f6aSNate Lawson  * FUNCTION:    LsDisplayNamespace
23353289f6aSNate Lawson  *
23453289f6aSNate Lawson  * PARAMETERS:  None
23553289f6aSNate Lawson  *
23653289f6aSNate Lawson  * RETURN:      None
23753289f6aSNate Lawson  *
23853289f6aSNate Lawson  * DESCRIPTION: Walk the namespace an display information about each node
23953289f6aSNate Lawson  *              in the tree.  Information is written to the optional
24053289f6aSNate Lawson  *              namespace output file.
24153289f6aSNate Lawson  *
24253289f6aSNate Lawson  ******************************************************************************/
24353289f6aSNate Lawson 
24453289f6aSNate Lawson ACPI_STATUS
24553289f6aSNate Lawson LsDisplayNamespace (
24653289f6aSNate Lawson     void)
24753289f6aSNate Lawson {
24853289f6aSNate Lawson     ACPI_STATUS             Status;
24953289f6aSNate Lawson 
25053289f6aSNate Lawson 
25153289f6aSNate Lawson     if (!Gbl_NsOutputFlag)
25253289f6aSNate Lawson     {
25353289f6aSNate Lawson         return (AE_OK);
25453289f6aSNate Lawson     }
25553289f6aSNate Lawson 
25653289f6aSNate Lawson     /* File header */
25753289f6aSNate Lawson 
25853289f6aSNate Lawson     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
25953289f6aSNate Lawson     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
26053289f6aSNate Lawson 
26153289f6aSNate Lawson     /* Walk entire namespace from the root */
26253289f6aSNate Lawson 
26353289f6aSNate Lawson     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
26453289f6aSNate Lawson                                 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject,
26553289f6aSNate Lawson                                 NULL, NULL);
26653289f6aSNate Lawson     return (Status);
26753289f6aSNate Lawson }
26853289f6aSNate Lawson 
26953289f6aSNate Lawson 
27053289f6aSNate Lawson /*******************************************************************************
27153289f6aSNate Lawson  *
27253289f6aSNate Lawson  * FUNCTION:    LsCompareOneNamespaceObject
27353289f6aSNate Lawson  *
27453289f6aSNate Lawson  * PARAMETERS:  ACPI_WALK_CALLBACK
27553289f6aSNate Lawson  *
27653289f6aSNate Lawson  * RETURN:      Status
27753289f6aSNate Lawson  *
27853289f6aSNate Lawson  * DESCRIPTION: Compare name of one object.
27953289f6aSNate Lawson  *
28053289f6aSNate Lawson  ******************************************************************************/
28153289f6aSNate Lawson 
28253289f6aSNate Lawson ACPI_STATUS
28353289f6aSNate Lawson LsCompareOneNamespaceObject (
28453289f6aSNate Lawson     ACPI_HANDLE             ObjHandle,
28553289f6aSNate Lawson     UINT32                  Level,
28653289f6aSNate Lawson     void                    *Context,
28753289f6aSNate Lawson     void                    **ReturnValue)
28853289f6aSNate Lawson {
28953289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
29053289f6aSNate Lawson 
29153289f6aSNate Lawson 
29253289f6aSNate Lawson     /* Simply check the name */
29353289f6aSNate Lawson 
29453289f6aSNate Lawson     if (*((UINT32 *) (Context)) == Node->Name.Integer)
29553289f6aSNate Lawson     {
29653289f6aSNate Lawson         /* Abort walk if we found one instance */
29753289f6aSNate Lawson 
29853289f6aSNate Lawson         return (AE_CTRL_TRUE);
29953289f6aSNate Lawson     }
30053289f6aSNate Lawson 
30153289f6aSNate Lawson     return (AE_OK);
30253289f6aSNate Lawson }
30353289f6aSNate Lawson 
30453289f6aSNate Lawson 
30553289f6aSNate Lawson /*******************************************************************************
30653289f6aSNate Lawson  *
30753289f6aSNate Lawson  * FUNCTION:    LkObjectExists
30853289f6aSNate Lawson  *
30953289f6aSNate Lawson  * PARAMETERS:  Name            - 4 char ACPI name
31053289f6aSNate Lawson  *
31153289f6aSNate Lawson  * RETURN:      TRUE if name exists in namespace
31253289f6aSNate Lawson  *
31353289f6aSNate Lawson  * DESCRIPTION: Walk the namespace to find an object
31453289f6aSNate Lawson  *
31553289f6aSNate Lawson  ******************************************************************************/
31653289f6aSNate Lawson 
31753289f6aSNate Lawson BOOLEAN
31853289f6aSNate Lawson LkObjectExists (
31953289f6aSNate Lawson     char                    *Name)
32053289f6aSNate Lawson {
32153289f6aSNate Lawson     ACPI_STATUS             Status;
32253289f6aSNate Lawson 
32353289f6aSNate Lawson 
32453289f6aSNate Lawson     /* Walk entire namespace from the supplied root */
32553289f6aSNate Lawson 
32653289f6aSNate Lawson     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
32753289f6aSNate Lawson                                 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject,
32853289f6aSNate Lawson                                 Name, NULL);
32953289f6aSNate Lawson     if (Status == AE_CTRL_TRUE)
33053289f6aSNate Lawson     {
33153289f6aSNate Lawson         /* At least one instance of the name was found */
33253289f6aSNate Lawson 
33353289f6aSNate Lawson         return (TRUE);
33453289f6aSNate Lawson     }
33553289f6aSNate Lawson 
33653289f6aSNate Lawson     return (FALSE);
33753289f6aSNate Lawson }
33853289f6aSNate Lawson 
33953289f6aSNate Lawson 
34053289f6aSNate Lawson /*******************************************************************************
34153289f6aSNate Lawson  *
34253289f6aSNate Lawson  * FUNCTION:    LkCrossReferenceNamespace
34353289f6aSNate Lawson  *
34453289f6aSNate Lawson  * PARAMETERS:  None
34553289f6aSNate Lawson  *
34653289f6aSNate Lawson  * RETURN:      Status
34753289f6aSNate Lawson  *
34853289f6aSNate Lawson  * DESCRIPTION: Perform a cross reference check of the parse tree against the
34953289f6aSNate Lawson  *              namespace.  Every named referenced within the parse tree
35053289f6aSNate Lawson  *              should be get resolved with a namespace lookup.  If not, the
35153289f6aSNate Lawson  *              original reference in the ASL code is invalid -- i.e., refers
35253289f6aSNate Lawson  *              to a non-existent object.
35353289f6aSNate Lawson  *
35453289f6aSNate Lawson  * NOTE:  The ASL "External" operator causes the name to be inserted into the
35553289f6aSNate Lawson  *        namespace so that references to the external name will be resolved
35653289f6aSNate Lawson  *        correctly here.
35753289f6aSNate Lawson  *
35853289f6aSNate Lawson  ******************************************************************************/
35953289f6aSNate Lawson 
36053289f6aSNate Lawson ACPI_STATUS
36153289f6aSNate Lawson LkCrossReferenceNamespace (
36253289f6aSNate Lawson     void)
36353289f6aSNate Lawson {
36453289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState;
36553289f6aSNate Lawson 
36653289f6aSNate Lawson 
36753289f6aSNate Lawson     DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
36853289f6aSNate Lawson 
36953289f6aSNate Lawson     /*
37053289f6aSNate Lawson      * Create a new walk state for use when looking up names
37153289f6aSNate Lawson      * within the namespace (Passed as context to the callbacks)
37253289f6aSNate Lawson      */
37353289f6aSNate Lawson     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
37453289f6aSNate Lawson     if (!WalkState)
37553289f6aSNate Lawson     {
37653289f6aSNate Lawson         return AE_NO_MEMORY;
37753289f6aSNate Lawson     }
37853289f6aSNate Lawson 
37953289f6aSNate Lawson     /* Walk the entire parse tree */
38053289f6aSNate Lawson 
38153289f6aSNate Lawson     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
38253289f6aSNate Lawson                         LkNamespaceLocateEnd, WalkState);
38353289f6aSNate Lawson     return AE_OK;
38453289f6aSNate Lawson }
38553289f6aSNate Lawson 
38653289f6aSNate Lawson 
38753289f6aSNate Lawson /*******************************************************************************
38853289f6aSNate Lawson  *
38953289f6aSNate Lawson  * FUNCTION:    LkCheckFieldRange
39053289f6aSNate Lawson  *
39153289f6aSNate Lawson  * PARAMETERS:  RegionBitLength     - Length of entire parent region
39253289f6aSNate Lawson  *              FieldBitOffset      - Start of the field unit (within region)
39353289f6aSNate Lawson  *              FieldBitLength      - Entire length of field unit
39453289f6aSNate Lawson  *              AccessBitWidth      - Access width of the field unit
39553289f6aSNate Lawson  *
39653289f6aSNate Lawson  * RETURN:      None
39753289f6aSNate Lawson  *
39853289f6aSNate Lawson  * DESCRIPTION: Check one field unit to make sure it fits in the parent
39953289f6aSNate Lawson  *              op region.
40053289f6aSNate Lawson  *
40153289f6aSNate Lawson  * Note: AccessBitWidth must be either 8,16,32, or 64
40253289f6aSNate Lawson  *
40353289f6aSNate Lawson  ******************************************************************************/
40453289f6aSNate Lawson 
40553289f6aSNate Lawson void
40653289f6aSNate Lawson LkCheckFieldRange (
40753289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
40853289f6aSNate Lawson     UINT32                  RegionBitLength,
40953289f6aSNate Lawson     UINT32                  FieldBitOffset,
41053289f6aSNate Lawson     UINT32                  FieldBitLength,
41153289f6aSNate Lawson     UINT32                  AccessBitWidth)
41253289f6aSNate Lawson {
41353289f6aSNate Lawson     UINT32                  FieldEndBitOffset;
41453289f6aSNate Lawson 
41553289f6aSNate Lawson     /*
41653289f6aSNate Lawson      * Check each field unit against the region size.  The entire
41753289f6aSNate Lawson      * field unit (start offset plus length) must fit within the
41853289f6aSNate Lawson      * region.
41953289f6aSNate Lawson      */
42053289f6aSNate Lawson     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
42153289f6aSNate Lawson 
42253289f6aSNate Lawson     if (FieldEndBitOffset > RegionBitLength)
42353289f6aSNate Lawson     {
42453289f6aSNate Lawson         /* Field definition itself is beyond the end-of-region */
42553289f6aSNate Lawson 
42653289f6aSNate Lawson         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
42753289f6aSNate Lawson         return;
42853289f6aSNate Lawson     }
42953289f6aSNate Lawson 
43053289f6aSNate Lawson     /*
43153289f6aSNate Lawson      * Now check that the field plus AccessWidth doesn't go beyond
43253289f6aSNate Lawson      * the end-of-region.  Assumes AccessBitWidth is a power of 2
43353289f6aSNate Lawson      */
43453289f6aSNate Lawson     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
43553289f6aSNate Lawson 
43653289f6aSNate Lawson     if (FieldEndBitOffset > RegionBitLength)
43753289f6aSNate Lawson     {
43853289f6aSNate Lawson         /* Field definition combined with the access is beyond EOR */
43953289f6aSNate Lawson 
44053289f6aSNate Lawson         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
44153289f6aSNate Lawson     }
44253289f6aSNate Lawson }
44353289f6aSNate Lawson 
44453289f6aSNate Lawson /*******************************************************************************
44553289f6aSNate Lawson  *
44653289f6aSNate Lawson  * FUNCTION:    LkNamespaceLocateBegin
44753289f6aSNate Lawson  *
44853289f6aSNate Lawson  * PARAMETERS:  ASL_WALK_CALLBACK
44953289f6aSNate Lawson  *
45053289f6aSNate Lawson  * RETURN:      Status
45153289f6aSNate Lawson  *
45253289f6aSNate Lawson  * DESCRIPTION: Descending callback used during cross-reference.  For named
45353289f6aSNate Lawson  *              object references, attempt to locate the name in the
45453289f6aSNate Lawson  *              namespace.
45553289f6aSNate Lawson  *
45653289f6aSNate Lawson  * NOTE: ASL references to named fields within resource descriptors are
45753289f6aSNate Lawson  *       resolved to integer values here.  Therefore, this step is an
45853289f6aSNate Lawson  *       important part of the code generation.  We don't know that the
45953289f6aSNate Lawson  *       name refers to a resource descriptor until now.
46053289f6aSNate Lawson  *
46153289f6aSNate Lawson  ******************************************************************************/
46253289f6aSNate Lawson 
46353289f6aSNate Lawson ACPI_STATUS
46453289f6aSNate Lawson LkNamespaceLocateBegin (
46553289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
46653289f6aSNate Lawson     UINT32                  Level,
46753289f6aSNate Lawson     void                    *Context)
46853289f6aSNate Lawson {
46953289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
47053289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node;
47153289f6aSNate Lawson     ACPI_STATUS             Status;
47253289f6aSNate Lawson     ACPI_OBJECT_TYPE        ObjectType;
47353289f6aSNate Lawson     char                    *Path;
47453289f6aSNate Lawson     UINT8                   PassedArgs;
47553289f6aSNate Lawson     ACPI_PARSE_OBJECT       *NextOp;
47653289f6aSNate Lawson     ACPI_PARSE_OBJECT       *OwningOp;
47753289f6aSNate Lawson     ACPI_PARSE_OBJECT       *SpaceIdOp;
47853289f6aSNate Lawson     UINT32                  MinimumLength;
47953289f6aSNate Lawson     UINT32                  Temp;
48053289f6aSNate Lawson     const ACPI_OPCODE_INFO  *OpInfo;
48153289f6aSNate Lawson     UINT32                  Flags;
48253289f6aSNate Lawson 
48353289f6aSNate Lawson 
48453289f6aSNate Lawson     ACPI_FUNCTION_TRACE_PTR ("LkNamespaceLocateBegin", Op);
48553289f6aSNate Lawson 
48653289f6aSNate Lawson     /*
48753289f6aSNate Lawson      * If this node is the actual declaration of a name
48853289f6aSNate Lawson      * [such as the XXXX name in "Method (XXXX)"],
48953289f6aSNate Lawson      * we are not interested in it here.  We only care about names that are
49053289f6aSNate Lawson      * references to other objects within the namespace and the parent objects
49153289f6aSNate Lawson      * of name declarations
49253289f6aSNate Lawson      */
49353289f6aSNate Lawson     if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
49453289f6aSNate Lawson     {
49553289f6aSNate Lawson         return (AE_OK);
49653289f6aSNate Lawson     }
49753289f6aSNate Lawson 
49853289f6aSNate Lawson     /* We are only interested in opcodes that have an associated name */
49953289f6aSNate Lawson 
50053289f6aSNate Lawson     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
50153289f6aSNate Lawson 
50253289f6aSNate Lawson     if ((!(OpInfo->Flags & AML_NAMED)) &&
50353289f6aSNate Lawson         (!(OpInfo->Flags & AML_CREATE)) &&
50453289f6aSNate Lawson         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
50553289f6aSNate Lawson         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
50653289f6aSNate Lawson         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
50753289f6aSNate Lawson     {
50853289f6aSNate Lawson         return (AE_OK);
50953289f6aSNate Lawson     }
51053289f6aSNate Lawson 
51153289f6aSNate Lawson     /*
51253289f6aSNate Lawson      * We must enable the "search-to-root" for single NameSegs, but
51353289f6aSNate Lawson      * we have to be very careful about opening up scopes
51453289f6aSNate Lawson      */
51553289f6aSNate Lawson     Flags = ACPI_NS_SEARCH_PARENT;
51653289f6aSNate Lawson     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
51753289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
51853289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
51953289f6aSNate Lawson     {
52053289f6aSNate Lawson         /*
52153289f6aSNate Lawson          * These are name references, do not push the scope stack
52253289f6aSNate Lawson          * for them.
52353289f6aSNate Lawson          */
52453289f6aSNate Lawson         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
52553289f6aSNate Lawson     }
52653289f6aSNate Lawson 
52753289f6aSNate Lawson     /* Get the NamePath from the appropriate place */
52853289f6aSNate Lawson 
52953289f6aSNate Lawson     if (OpInfo->Flags & AML_NAMED)
53053289f6aSNate Lawson     {
53153289f6aSNate Lawson         /* For all NAMED operators, the name reference is the first child */
53253289f6aSNate Lawson 
53353289f6aSNate Lawson         Path = Op->Asl.Child->Asl.Value.String;
53453289f6aSNate Lawson         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
53553289f6aSNate Lawson         {
53653289f6aSNate Lawson             /*
53753289f6aSNate Lawson              * ALIAS is the only oddball opcode, the name declaration
53853289f6aSNate Lawson              * (alias name) is the second operand
53953289f6aSNate Lawson              */
54053289f6aSNate Lawson             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
54153289f6aSNate Lawson         }
54253289f6aSNate Lawson     }
54353289f6aSNate Lawson     else if (OpInfo->Flags & AML_CREATE)
54453289f6aSNate Lawson     {
54553289f6aSNate Lawson         /* Name must appear as the last parameter */
54653289f6aSNate Lawson 
54753289f6aSNate Lawson         NextOp = Op->Asl.Child;
54853289f6aSNate Lawson         while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
54953289f6aSNate Lawson         {
55053289f6aSNate Lawson             NextOp = NextOp->Asl.Next;
55153289f6aSNate Lawson         }
55253289f6aSNate Lawson         Path = NextOp->Asl.Value.String;
55353289f6aSNate Lawson     }
55453289f6aSNate Lawson     else
55553289f6aSNate Lawson     {
55653289f6aSNate Lawson         Path = Op->Asl.Value.String;
55753289f6aSNate Lawson     }
55853289f6aSNate Lawson 
55953289f6aSNate Lawson     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
56053289f6aSNate Lawson     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
56153289f6aSNate Lawson 
56253289f6aSNate Lawson     /*
56353289f6aSNate Lawson      * Lookup the name in the namespace.  Name must exist at this point, or it
56453289f6aSNate Lawson      * is an invalid reference.
56553289f6aSNate Lawson      *
56653289f6aSNate Lawson      * The namespace is also used as a lookup table for references to resource
56753289f6aSNate Lawson      * descriptors and the fields within them.
56853289f6aSNate Lawson      */
56953289f6aSNate Lawson     Gbl_NsLookupCount++;
57053289f6aSNate Lawson 
57153289f6aSNate Lawson     Status = AcpiNsLookup (WalkState->ScopeInfo,  Path, ObjectType,
57253289f6aSNate Lawson                     ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
57353289f6aSNate Lawson     if (ACPI_FAILURE (Status))
57453289f6aSNate Lawson     {
57553289f6aSNate Lawson         if (Status == AE_NOT_FOUND)
57653289f6aSNate Lawson         {
57753289f6aSNate Lawson             /*
57853289f6aSNate Lawson              * We didn't find the name reference by path -- we can qualify this
57953289f6aSNate Lawson              * a little better before we print an error message
58053289f6aSNate Lawson              */
58153289f6aSNate Lawson             if (strlen (Path) == ACPI_NAME_SIZE)
58253289f6aSNate Lawson             {
58353289f6aSNate Lawson                 /* A simple, one-segment ACPI name */
58453289f6aSNate Lawson 
58553289f6aSNate Lawson                 if (LkObjectExists (Path))
58653289f6aSNate Lawson                 {
58753289f6aSNate Lawson                     /* There exists such a name, but we couldn't get to it from this scope */
58853289f6aSNate Lawson 
58953289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op, Op->Asl.ExternalName);
59053289f6aSNate Lawson                 }
59153289f6aSNate Lawson                 else
59253289f6aSNate Lawson                 {
59353289f6aSNate Lawson                     /* The name doesn't exist, period */
59453289f6aSNate Lawson 
59553289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName);
59653289f6aSNate Lawson                 }
59753289f6aSNate Lawson             }
59853289f6aSNate Lawson             else
59953289f6aSNate Lawson             {
60053289f6aSNate Lawson                 /* Check for a fully qualified path */
60153289f6aSNate Lawson 
60253289f6aSNate Lawson                 if (Path[0] == AML_ROOT_PREFIX)
60353289f6aSNate Lawson                 {
60453289f6aSNate Lawson                     /* Gave full path, the object does not exist */
60553289f6aSNate Lawson 
60653289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName);
60753289f6aSNate Lawson                 }
60853289f6aSNate Lawson                 else
60953289f6aSNate Lawson                 {
61053289f6aSNate Lawson                     /* We can't tell whether it doesn't exist or just can't be reached. */
61153289f6aSNate Lawson 
61253289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName);
61353289f6aSNate Lawson                 }
61453289f6aSNate Lawson             }
61553289f6aSNate Lawson 
61653289f6aSNate Lawson             Status = AE_OK;
61753289f6aSNate Lawson         }
61853289f6aSNate Lawson         return (Status);
61953289f6aSNate Lawson     }
62053289f6aSNate Lawson 
62153289f6aSNate Lawson     /* Attempt to optimize the NamePath */
62253289f6aSNate Lawson 
62353289f6aSNate Lawson     OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
62453289f6aSNate Lawson 
62553289f6aSNate Lawson     /*
62653289f6aSNate Lawson      * Dereference an alias. (A name reference that is an alias.)
62753289f6aSNate Lawson      * Aliases are not nested;  The alias always points to the final object
62853289f6aSNate Lawson      */
62953289f6aSNate Lawson     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) && (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
63053289f6aSNate Lawson     {
63153289f6aSNate Lawson         /* This node points back to the original PARSEOP_ALIAS */
63253289f6aSNate Lawson 
63353289f6aSNate Lawson         NextOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
63453289f6aSNate Lawson 
63553289f6aSNate Lawson         /* The first child is the alias target op */
63653289f6aSNate Lawson 
63753289f6aSNate Lawson         NextOp = NextOp->Asl.Child;
63853289f6aSNate Lawson 
63953289f6aSNate Lawson         /* Who in turn points back to original target alias node */
64053289f6aSNate Lawson 
64153289f6aSNate Lawson         if (NextOp->Asl.Node)
64253289f6aSNate Lawson         {
64353289f6aSNate Lawson             Node = NextOp->Asl.Node;
64453289f6aSNate Lawson         }
64553289f6aSNate Lawson         else
64653289f6aSNate Lawson         {
64753289f6aSNate Lawson             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "Missing alias link");
64853289f6aSNate Lawson         }
64953289f6aSNate Lawson     }
65053289f6aSNate Lawson 
65153289f6aSNate Lawson     /* 1) Check for a reference to a resource descriptor */
65253289f6aSNate Lawson 
65353289f6aSNate Lawson     else if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
65453289f6aSNate Lawson              (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
65553289f6aSNate Lawson     {
65653289f6aSNate Lawson         /*
65753289f6aSNate Lawson          * This was a reference to a field within a resource descriptor.  Extract
65853289f6aSNate Lawson          * the associated field offset (either a bit or byte offset depending on
65953289f6aSNate Lawson          * the field type) and change the named reference into an integer for
66053289f6aSNate Lawson          * AML code generation
66153289f6aSNate Lawson          */
66253289f6aSNate Lawson         Temp = (UINT32) Node->OwnerId;
66353289f6aSNate Lawson         if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
66453289f6aSNate Lawson         {
66553289f6aSNate Lawson             Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
66653289f6aSNate Lawson         }
66753289f6aSNate Lawson 
66853289f6aSNate Lawson         /* Perform BitOffset <--> ByteOffset conversion if necessary */
66953289f6aSNate Lawson 
67053289f6aSNate Lawson         switch (Op->Asl.Parent->Asl.AmlOpcode)
67153289f6aSNate Lawson         {
67253289f6aSNate Lawson         case AML_CREATE_FIELD_OP:
67353289f6aSNate Lawson 
67453289f6aSNate Lawson             /* We allow a Byte offset to Bit Offset conversion for this op */
67553289f6aSNate Lawson 
67653289f6aSNate Lawson             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
67753289f6aSNate Lawson             {
67853289f6aSNate Lawson                 /* Simply multiply byte offset times 8 to get bit offset */
67953289f6aSNate Lawson 
68053289f6aSNate Lawson                 Temp = ACPI_MUL_8 (Temp);
68153289f6aSNate Lawson             }
68253289f6aSNate Lawson             break;
68353289f6aSNate Lawson 
68453289f6aSNate Lawson 
68553289f6aSNate Lawson         case AML_CREATE_BIT_FIELD_OP:
68653289f6aSNate Lawson 
68753289f6aSNate Lawson             /* This op requires a Bit Offset */
68853289f6aSNate Lawson 
68953289f6aSNate Lawson             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
69053289f6aSNate Lawson             {
69153289f6aSNate Lawson                 AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
69253289f6aSNate Lawson             }
69353289f6aSNate Lawson             break;
69453289f6aSNate Lawson 
69553289f6aSNate Lawson 
69653289f6aSNate Lawson         case AML_CREATE_BYTE_FIELD_OP:
69753289f6aSNate Lawson         case AML_CREATE_WORD_FIELD_OP:
69853289f6aSNate Lawson         case AML_CREATE_DWORD_FIELD_OP:
69953289f6aSNate Lawson         case AML_CREATE_QWORD_FIELD_OP:
70053289f6aSNate Lawson         case AML_INDEX_OP:
70153289f6aSNate Lawson 
70253289f6aSNate Lawson             /* These Ops require Byte offsets */
70353289f6aSNate Lawson 
70453289f6aSNate Lawson             if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
70553289f6aSNate Lawson             {
70653289f6aSNate Lawson                 AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
70753289f6aSNate Lawson             }
70853289f6aSNate Lawson             break;
70953289f6aSNate Lawson 
71053289f6aSNate Lawson 
71153289f6aSNate Lawson         default:
71253289f6aSNate Lawson             /* Nothing to do for other opcodes */
71353289f6aSNate Lawson             break;
71453289f6aSNate Lawson         }
71553289f6aSNate Lawson 
71653289f6aSNate Lawson         /* Now convert this node to an integer whose value is the field offset */
71753289f6aSNate Lawson 
71853289f6aSNate Lawson         Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
71953289f6aSNate Lawson         Op->Asl.Value.Integer   = (UINT64) Temp;
72053289f6aSNate Lawson         Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
72153289f6aSNate Lawson 
72253289f6aSNate Lawson         OpcGenerateAmlOpcode (Op);
72353289f6aSNate Lawson         Op->Asl.AmlLength = OpcSetOptimalIntegerSize (Op);
72453289f6aSNate Lawson     }
72553289f6aSNate Lawson 
72653289f6aSNate Lawson     /* 2) Check for a method invocation */
72753289f6aSNate Lawson 
72853289f6aSNate Lawson     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
72953289f6aSNate Lawson                 (Node->Type == ACPI_TYPE_METHOD) &&
73053289f6aSNate Lawson                 (Op->Asl.Parent) &&
73153289f6aSNate Lawson                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
73253289f6aSNate Lawson 
73353289f6aSNate Lawson                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
73453289f6aSNate Lawson     {
73553289f6aSNate Lawson 
73653289f6aSNate Lawson         /*
73753289f6aSNate Lawson          * There are two types of method invocation:
73853289f6aSNate Lawson          * 1) Invocation with arguments -- the parser recognizes this as a METHODCALL
73953289f6aSNate Lawson          * 2) Invocation with no arguments --the parser cannot determine that this is a method
74053289f6aSNate Lawson          *    invocation, therefore we have to figure it out here.
74153289f6aSNate Lawson          */
74253289f6aSNate Lawson         if (Node->Type != ACPI_TYPE_METHOD)
74353289f6aSNate Lawson         {
74453289f6aSNate Lawson             sprintf (MsgBuffer, "%s is a %s", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
74553289f6aSNate Lawson 
74653289f6aSNate Lawson             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
74753289f6aSNate Lawson             return (AE_OK);
74853289f6aSNate Lawson         }
74953289f6aSNate Lawson 
75053289f6aSNate Lawson         /* Save the method node in the caller's op */
75153289f6aSNate Lawson 
75253289f6aSNate Lawson         Op->Asl.Node = Node;
75353289f6aSNate Lawson         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
75453289f6aSNate Lawson         {
75553289f6aSNate Lawson             return (AE_OK);
75653289f6aSNate Lawson         }
75753289f6aSNate Lawson 
75853289f6aSNate Lawson         /*
75953289f6aSNate Lawson          * This is a method invocation, with or without arguments.
76053289f6aSNate Lawson          * Count the number of arguments, each appears as a child
76153289f6aSNate Lawson          * under the parent node
76253289f6aSNate Lawson          */
76353289f6aSNate Lawson         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
76453289f6aSNate Lawson         UtSetParseOpName (Op);
76553289f6aSNate Lawson 
76653289f6aSNate Lawson         PassedArgs = 0;
76753289f6aSNate Lawson         NextOp     = Op->Asl.Child;
76853289f6aSNate Lawson 
76953289f6aSNate Lawson         while (NextOp)
77053289f6aSNate Lawson         {
77153289f6aSNate Lawson             PassedArgs++;
77253289f6aSNate Lawson             NextOp = NextOp->Asl.Next;
77353289f6aSNate Lawson         }
77453289f6aSNate Lawson 
77553289f6aSNate Lawson         if (Node->OwnerId != ASL_EXTERNAL_METHOD)
77653289f6aSNate Lawson         {
77753289f6aSNate Lawson             /*
77853289f6aSNate Lawson              * Check the parsed arguments with the number expected by the
77953289f6aSNate Lawson              * method declaration itself
78053289f6aSNate Lawson              */
78153289f6aSNate Lawson             if (PassedArgs != Node->OwnerId)
78253289f6aSNate Lawson             {
78353289f6aSNate Lawson                 sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName,
78453289f6aSNate Lawson                             Node->OwnerId);
78553289f6aSNate Lawson 
78653289f6aSNate Lawson                 if (PassedArgs < Node->OwnerId)
78753289f6aSNate Lawson                 {
78853289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
78953289f6aSNate Lawson                 }
79053289f6aSNate Lawson                 else
79153289f6aSNate Lawson                 {
79253289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
79353289f6aSNate Lawson                 }
79453289f6aSNate Lawson             }
79553289f6aSNate Lawson         }
79653289f6aSNate Lawson     }
79753289f6aSNate Lawson 
79853289f6aSNate Lawson     /*
79953289f6aSNate Lawson      * 3) Check for an ASL Field definition
80053289f6aSNate Lawson      */
80153289f6aSNate Lawson     else if ((Op->Asl.Parent) &&
80253289f6aSNate Lawson             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
80353289f6aSNate Lawson              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
80453289f6aSNate Lawson     {
80553289f6aSNate Lawson         /*
80653289f6aSNate Lawson          * Offset checking for fields.  If the parent operation region has a
80753289f6aSNate Lawson          * constant length (known at compile time), we can check fields
80853289f6aSNate Lawson          * defined in that region against the region length.  This will catch
80953289f6aSNate Lawson          * fields and field units that cannot possibly fit within the region.
81053289f6aSNate Lawson          *
81153289f6aSNate Lawson          * Note: Index fields do not directly reference an operation region,
81253289f6aSNate Lawson          * thus they are not included in this check.
81353289f6aSNate Lawson          */
81453289f6aSNate Lawson         if (Op == Op->Asl.Parent->Asl.Child)
81553289f6aSNate Lawson         {
81653289f6aSNate Lawson             /*
81753289f6aSNate Lawson              * This is the first child of the field node, which is
81853289f6aSNate Lawson              * the name of the region.  Get the parse node for the
81953289f6aSNate Lawson              * region -- which contains the length of the region.
82053289f6aSNate Lawson              */
82153289f6aSNate Lawson             OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
82253289f6aSNate Lawson             Op->Asl.Parent->Asl.ExtraValue = ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
82353289f6aSNate Lawson 
82453289f6aSNate Lawson             /* Examine the field access width */
82553289f6aSNate Lawson 
82653289f6aSNate Lawson             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
82753289f6aSNate Lawson             {
82853289f6aSNate Lawson             case AML_FIELD_ACCESS_ANY:
82953289f6aSNate Lawson             case AML_FIELD_ACCESS_BYTE:
83053289f6aSNate Lawson             case AML_FIELD_ACCESS_BUFFER:
83153289f6aSNate Lawson             default:
83253289f6aSNate Lawson                 MinimumLength = 1;
83353289f6aSNate Lawson                 break;
83453289f6aSNate Lawson 
83553289f6aSNate Lawson             case AML_FIELD_ACCESS_WORD:
83653289f6aSNate Lawson                 MinimumLength = 2;
83753289f6aSNate Lawson                 break;
83853289f6aSNate Lawson 
83953289f6aSNate Lawson             case AML_FIELD_ACCESS_DWORD:
84053289f6aSNate Lawson                 MinimumLength = 4;
84153289f6aSNate Lawson                 break;
84253289f6aSNate Lawson 
84353289f6aSNate Lawson             case AML_FIELD_ACCESS_QWORD:
84453289f6aSNate Lawson                 MinimumLength = 8;
84553289f6aSNate Lawson                 break;
84653289f6aSNate Lawson             }
84753289f6aSNate Lawson 
84853289f6aSNate Lawson             /*
84953289f6aSNate Lawson              * Is the region at least as big as the access width?
85053289f6aSNate Lawson              * Note: DataTableRegions have 0 length
85153289f6aSNate Lawson              */
85253289f6aSNate Lawson             if (((UINT32) OwningOp->Asl.Value.Integer) &&
85353289f6aSNate Lawson                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
85453289f6aSNate Lawson             {
85553289f6aSNate Lawson                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
85653289f6aSNate Lawson             }
85753289f6aSNate Lawson 
85853289f6aSNate Lawson             /*
85953289f6aSNate Lawson              * Check EC/CMOS/SMBUS fields to make sure that the correct
86053289f6aSNate Lawson              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
86153289f6aSNate Lawson              */
86253289f6aSNate Lawson             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
86353289f6aSNate Lawson             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
86453289f6aSNate Lawson             {
86553289f6aSNate Lawson             case REGION_EC:
86653289f6aSNate Lawson             case REGION_CMOS:
86753289f6aSNate Lawson 
86853289f6aSNate Lawson                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
86953289f6aSNate Lawson                 {
87053289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
87153289f6aSNate Lawson                 }
87253289f6aSNate Lawson                 break;
87353289f6aSNate Lawson 
87453289f6aSNate Lawson             case REGION_SMBUS:
87553289f6aSNate Lawson 
87653289f6aSNate Lawson                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
87753289f6aSNate Lawson                 {
87853289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
87953289f6aSNate Lawson                 }
88053289f6aSNate Lawson                 break;
88153289f6aSNate Lawson 
88253289f6aSNate Lawson             default:
88353289f6aSNate Lawson 
88453289f6aSNate Lawson                 /* Nothing to do for other address spaces */
88553289f6aSNate Lawson                 break;
88653289f6aSNate Lawson             }
88753289f6aSNate Lawson         }
88853289f6aSNate Lawson         else
88953289f6aSNate Lawson         {
89053289f6aSNate Lawson             /*
89153289f6aSNate Lawson              * This is one element of the field list.  Check to make sure
89253289f6aSNate Lawson              * that it does not go beyond the end of the parent operation region.
89353289f6aSNate Lawson              *
89453289f6aSNate Lawson              * In the code below:
89553289f6aSNate Lawson              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
89653289f6aSNate Lawson              *    Op->Asl.ExtraValue                  - Field start offset (bits)
89753289f6aSNate Lawson              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
89853289f6aSNate Lawson              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
89953289f6aSNate Lawson              */
90053289f6aSNate Lawson             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
90153289f6aSNate Lawson             {
90253289f6aSNate Lawson                 LkCheckFieldRange (Op,
90353289f6aSNate Lawson                             Op->Asl.Parent->Asl.ExtraValue,
90453289f6aSNate Lawson                             Op->Asl.ExtraValue,
90553289f6aSNate Lawson                             (UINT32) Op->Asl.Child->Asl.Value.Integer,
90653289f6aSNate Lawson                             Op->Asl.Child->Asl.ExtraValue);
90753289f6aSNate Lawson             }
90853289f6aSNate Lawson         }
90953289f6aSNate Lawson     }
91053289f6aSNate Lawson 
91153289f6aSNate Lawson     Op->Asl.Node = Node;
91253289f6aSNate Lawson     return (Status);
91353289f6aSNate Lawson }
91453289f6aSNate Lawson 
91553289f6aSNate Lawson 
91653289f6aSNate Lawson /*******************************************************************************
91753289f6aSNate Lawson  *
91853289f6aSNate Lawson  * FUNCTION:    LkNamespaceLocateEnd
91953289f6aSNate Lawson  *
92053289f6aSNate Lawson  * PARAMETERS:  ASL_WALK_CALLBACK
92153289f6aSNate Lawson  *
92253289f6aSNate Lawson  * RETURN:      Status
92353289f6aSNate Lawson  *
92453289f6aSNate Lawson  * DESCRIPTION: Ascending callback used during cross reference.  We only
92553289f6aSNate Lawson  *              need to worry about scope management here.
92653289f6aSNate Lawson  *
92753289f6aSNate Lawson  ******************************************************************************/
92853289f6aSNate Lawson 
92953289f6aSNate Lawson ACPI_STATUS
93053289f6aSNate Lawson LkNamespaceLocateEnd (
93153289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
93253289f6aSNate Lawson     UINT32                  Level,
93353289f6aSNate Lawson     void                    *Context)
93453289f6aSNate Lawson {
93553289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
93653289f6aSNate Lawson     const ACPI_OPCODE_INFO  *OpInfo;
93753289f6aSNate Lawson 
93853289f6aSNate Lawson 
93953289f6aSNate Lawson     ACPI_FUNCTION_TRACE ("LkNamespaceLocateEnd");
94053289f6aSNate Lawson 
94153289f6aSNate Lawson 
94253289f6aSNate Lawson     /* We are only interested in opcodes that have an associated name */
94353289f6aSNate Lawson 
94453289f6aSNate Lawson     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
94553289f6aSNate Lawson     if (!(OpInfo->Flags & AML_NAMED))
94653289f6aSNate Lawson     {
94753289f6aSNate Lawson         return (AE_OK);
94853289f6aSNate Lawson     }
94953289f6aSNate Lawson 
95053289f6aSNate Lawson     /* Not interested in name references, we did not open a scope for them */
95153289f6aSNate Lawson 
95253289f6aSNate Lawson     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
95353289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
95453289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
95553289f6aSNate Lawson     {
95653289f6aSNate Lawson         return (AE_OK);
95753289f6aSNate Lawson     }
95853289f6aSNate Lawson 
95953289f6aSNate Lawson     /* Pop the scope stack if necessary */
96053289f6aSNate Lawson 
96153289f6aSNate Lawson     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
96253289f6aSNate Lawson     {
96353289f6aSNate Lawson 
96453289f6aSNate Lawson         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
96553289f6aSNate Lawson             "%s: Popping scope for Op %p\n",
96653289f6aSNate Lawson             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
96753289f6aSNate Lawson 
96853289f6aSNate Lawson         AcpiDsScopeStackPop (WalkState);
96953289f6aSNate Lawson     }
97053289f6aSNate Lawson 
97153289f6aSNate Lawson     return (AE_OK);
97253289f6aSNate Lawson }
97353289f6aSNate Lawson 
97453289f6aSNate Lawson 
975