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