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