1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: asllookup- Namespace lookup
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118611Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118611Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118611Snjl
44118611Snjl
45151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
46118611Snjl#include "aslcompiler.y.h"
47118611Snjl
48193529Sjkim#include <contrib/dev/acpica/include/acparser.h>
49193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
50193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
51193529Sjkim#include <contrib/dev/acpica/include/acdispat.h>
52118611Snjl
53118611Snjl
54118611Snjl#define _COMPONENT          ACPI_COMPILER
55118611Snjl        ACPI_MODULE_NAME    ("asllookup")
56118611Snjl
57151937Sjkim/* Local prototypes */
58118611Snjl
59151937Sjkimstatic ACPI_STATUS
60151937SjkimLsCompareOneNamespaceObject (
61151937Sjkim    ACPI_HANDLE             ObjHandle,
62151937Sjkim    UINT32                  Level,
63151937Sjkim    void                    *Context,
64151937Sjkim    void                    **ReturnValue);
65151937Sjkim
66151937Sjkimstatic ACPI_STATUS
67151937SjkimLsDoOneNamespaceObject (
68151937Sjkim    ACPI_HANDLE             ObjHandle,
69151937Sjkim    UINT32                  Level,
70151937Sjkim    void                    *Context,
71151937Sjkim    void                    **ReturnValue);
72151937Sjkim
73151937Sjkimstatic BOOLEAN
74151937SjkimLkObjectExists (
75151937Sjkim    char                    *Name);
76151937Sjkim
77151937Sjkimstatic void
78151937SjkimLkCheckFieldRange (
79151937Sjkim    ACPI_PARSE_OBJECT       *Op,
80151937Sjkim    UINT32                  RegionBitLength,
81151937Sjkim    UINT32                  FieldBitOffset,
82151937Sjkim    UINT32                  FieldBitLength,
83151937Sjkim    UINT32                  AccessBitWidth);
84151937Sjkim
85151937Sjkimstatic ACPI_STATUS
86151937SjkimLkNamespaceLocateBegin (
87151937Sjkim    ACPI_PARSE_OBJECT       *Op,
88151937Sjkim    UINT32                  Level,
89151937Sjkim    void                    *Context);
90151937Sjkim
91151937Sjkimstatic ACPI_STATUS
92151937SjkimLkNamespaceLocateEnd (
93151937Sjkim    ACPI_PARSE_OBJECT       *Op,
94151937Sjkim    UINT32                  Level,
95151937Sjkim    void                    *Context);
96151937Sjkim
97167802Sjkimstatic ACPI_STATUS
98167802SjkimLkIsObjectUsed (
99167802Sjkim    ACPI_HANDLE             ObjHandle,
100167802Sjkim    UINT32                  Level,
101167802Sjkim    void                    *Context,
102167802Sjkim    void                    **ReturnValue);
103151937Sjkim
104193529Sjkimstatic ACPI_STATUS
105193529SjkimLsDoOnePathname (
106193529Sjkim    ACPI_HANDLE             ObjHandle,
107193529Sjkim    UINT32                  Level,
108193529Sjkim    void                    *Context,
109193529Sjkim    void                    **ReturnValue);
110167802Sjkim
111212761Sjkimstatic ACPI_PARSE_OBJECT *
112193529SjkimLkGetNameOp (
113193529Sjkim    ACPI_PARSE_OBJECT       *Op);
114193529Sjkim
115193529Sjkim
116118611Snjl/*******************************************************************************
117118611Snjl *
118118611Snjl * FUNCTION:    LsDoOneNamespaceObject
119118611Snjl *
120118611Snjl * PARAMETERS:  ACPI_WALK_CALLBACK
121118611Snjl *
122118611Snjl * RETURN:      Status
123118611Snjl *
124118611Snjl * DESCRIPTION: Dump a namespace object to the namespace output file.
125118611Snjl *              Called during the walk of the namespace to dump all objects.
126118611Snjl *
127118611Snjl ******************************************************************************/
128118611Snjl
129151937Sjkimstatic ACPI_STATUS
130118611SnjlLsDoOneNamespaceObject (
131118611Snjl    ACPI_HANDLE             ObjHandle,
132118611Snjl    UINT32                  Level,
133118611Snjl    void                    *Context,
134118611Snjl    void                    **ReturnValue)
135118611Snjl{
136118611Snjl    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
137151937Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
138118611Snjl    ACPI_PARSE_OBJECT       *Op;
139118611Snjl
140118611Snjl
141118611Snjl    Gbl_NumNamespaceObjects++;
142118611Snjl
143209746Sjkim    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
144167802Sjkim        Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
145167802Sjkim        &Node->Name,
146167802Sjkim        AcpiUtGetTypeName (Node->Type));
147118611Snjl
148151937Sjkim    Op = Node->Op;
149151937Sjkim    ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
150118611Snjl
151151937Sjkim    if (!Op)
152118611Snjl    {
153151937Sjkim        FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
154151937Sjkim        return (AE_OK);
155151937Sjkim    }
156151937Sjkim
157151937Sjkim
158151937Sjkim    if ((ObjDesc) &&
159167802Sjkim        (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
160151937Sjkim    {
161151937Sjkim        switch (Node->Type)
162118611Snjl        {
163151937Sjkim        case ACPI_TYPE_INTEGER:
164151937Sjkim
165151937Sjkim            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
166151937Sjkim                "       [Initial Value   0x%8.8X%8.8X]",
167151937Sjkim                ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
168151937Sjkim            break;
169151937Sjkim
170151937Sjkim
171151937Sjkim        case ACPI_TYPE_STRING:
172151937Sjkim
173151937Sjkim            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
174151937Sjkim                "        [Initial Value   \"%s\"]",
175151937Sjkim                ObjDesc->String.Pointer);
176151937Sjkim            break;
177151937Sjkim
178151937Sjkim        default:
179151937Sjkim            /* Nothing to do for other types */
180151937Sjkim            break;
181118611Snjl        }
182118611Snjl
183151937Sjkim    }
184151937Sjkim    else
185151937Sjkim    {
186118611Snjl        switch (Node->Type)
187118611Snjl        {
188118611Snjl        case ACPI_TYPE_INTEGER:
189118611Snjl
190151937Sjkim            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
191151937Sjkim            {
192151937Sjkim                Op = Op->Asl.Child;
193151937Sjkim            }
194118611Snjl            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
195118611Snjl                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
196118611Snjl            {
197118611Snjl                Op = Op->Asl.Next;
198118611Snjl            }
199151937Sjkim            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
200151937Sjkim                "       [Initial Value   0x%8.8X%8.8X]",
201151937Sjkim                ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
202151937Sjkim            break;
203118611Snjl
204151937Sjkim
205151937Sjkim        case ACPI_TYPE_STRING:
206151937Sjkim
207151937Sjkim            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
208118611Snjl            {
209151937Sjkim                Op = Op->Asl.Child;
210118611Snjl            }
211151937Sjkim            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
212151937Sjkim                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
213118611Snjl            {
214151937Sjkim                Op = Op->Asl.Next;
215118611Snjl            }
216151937Sjkim            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
217151937Sjkim                "        [Initial Value   \"%s\"]",
218151937Sjkim                Op->Asl.Value.String);
219118611Snjl            break;
220118611Snjl
221118611Snjl
222151937Sjkim        case ACPI_TYPE_LOCAL_REGION_FIELD:
223118611Snjl
224118611Snjl            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
225118611Snjl                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
226118611Snjl            {
227151937Sjkim                Op = Op->Asl.Child;
228118611Snjl            }
229151937Sjkim            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
230151937Sjkim                "   [Offset 0x%04X   Length 0x%04X bits]",
231151937Sjkim                Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
232151937Sjkim            break;
233118611Snjl
234151937Sjkim
235151937Sjkim        case ACPI_TYPE_BUFFER_FIELD:
236151937Sjkim
237151937Sjkim            switch (Op->Asl.ParseOpcode)
238151937Sjkim            {
239151937Sjkim            case PARSEOP_CREATEBYTEFIELD:
240151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
241151937Sjkim                break;
242151937Sjkim
243151937Sjkim            case PARSEOP_CREATEDWORDFIELD:
244151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
245151937Sjkim                break;
246151937Sjkim
247151937Sjkim            case PARSEOP_CREATEQWORDFIELD:
248151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
249151937Sjkim                break;
250151937Sjkim
251151937Sjkim            case PARSEOP_CREATEWORDFIELD:
252151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
253151937Sjkim                break;
254151937Sjkim
255151937Sjkim            case PARSEOP_CREATEBITFIELD:
256151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
257151937Sjkim                break;
258151937Sjkim
259151937Sjkim            case PARSEOP_CREATEFIELD:
260151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
261151937Sjkim                break;
262151937Sjkim
263151937Sjkim            default:
264151937Sjkim                break;
265151937Sjkim
266151937Sjkim            }
267118611Snjl            break;
268118611Snjl
269118611Snjl
270151937Sjkim        case ACPI_TYPE_PACKAGE:
271118611Snjl
272151937Sjkim            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
273151937Sjkim            {
274151937Sjkim                Op = Op->Asl.Child;
275151937Sjkim            }
276118611Snjl            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
277118611Snjl                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
278118611Snjl            {
279151937Sjkim                Op = Op->Asl.Next;
280151937Sjkim            }
281151937Sjkim            Op = Op->Asl.Child;
282151937Sjkim
283151937Sjkim            if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
284151937Sjkim                (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
285151937Sjkim            {
286151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
287151937Sjkim                    "       [Initial Length  0x%.2X elements]",
288151937Sjkim                    Op->Asl.Value.Integer);
289151937Sjkim            }
290151937Sjkim            break;
291151937Sjkim
292151937Sjkim
293151937Sjkim        case ACPI_TYPE_BUFFER:
294151937Sjkim
295151937Sjkim            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
296151937Sjkim            {
297118611Snjl                Op = Op->Asl.Child;
298118611Snjl            }
299151937Sjkim            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
300151937Sjkim                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
301151937Sjkim            {
302151937Sjkim                Op = Op->Asl.Next;
303151937Sjkim            }
304151937Sjkim            Op = Op->Asl.Child;
305151937Sjkim
306167802Sjkim            if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
307151937Sjkim            {
308151937Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
309151937Sjkim                    "        [Initial Length  0x%.2X bytes]",
310151937Sjkim                    Op->Asl.Value.Integer);
311151937Sjkim            }
312118611Snjl            break;
313118611Snjl
314118611Snjl
315151937Sjkim        case ACPI_TYPE_METHOD:
316151937Sjkim
317151937Sjkim            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
318151937Sjkim                "        [Code Length     0x%.4X bytes]",
319151937Sjkim                Op->Asl.AmlSubtreeLength);
320151937Sjkim            break;
321151937Sjkim
322151937Sjkim
323167802Sjkim        case ACPI_TYPE_LOCAL_RESOURCE:
324167802Sjkim
325167802Sjkim            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
326167802Sjkim                "  [Desc Offset     0x%.4X Bytes]", Node->Value);
327167802Sjkim            break;
328167802Sjkim
329167802Sjkim
330167802Sjkim        case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
331167802Sjkim
332167802Sjkim            if (Node->Flags & 0x80)
333167802Sjkim            {
334167802Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
335167802Sjkim                    "   [Field Offset    0x%.4X Bits 0x%.4X Bytes]",
336167802Sjkim                    Node->Value, Node->Value / 8);
337167802Sjkim            }
338167802Sjkim            else
339167802Sjkim            {
340167802Sjkim                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
341167802Sjkim                    "   [Field Offset    0x%.4X Bytes]", Node->Value);
342167802Sjkim            }
343167802Sjkim            break;
344167802Sjkim
345167802Sjkim
346118611Snjl        default:
347118611Snjl            /* Nothing to do for other types */
348118611Snjl            break;
349118611Snjl        }
350118611Snjl    }
351118611Snjl
352118611Snjl    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
353118611Snjl    return (AE_OK);
354118611Snjl}
355118611Snjl
356118611Snjl
357193529Sjkim/*******************************************************************************
358193529Sjkim *
359193529Sjkim * FUNCTION:    LsSetupNsList
360193529Sjkim *
361193529Sjkim * PARAMETERS:  Handle          - local file handle
362193529Sjkim *
363193529Sjkim * RETURN:      None
364193529Sjkim *
365193529Sjkim * DESCRIPTION: Set the namespace output file to the input handle
366193529Sjkim *
367193529Sjkim ******************************************************************************/
368193529Sjkim
369167802Sjkimvoid
370193529SjkimLsSetupNsList (
371193529Sjkim    void                    *Handle)
372167802Sjkim{
373167802Sjkim
374167802Sjkim    Gbl_NsOutputFlag = TRUE;
375167802Sjkim    Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
376167802Sjkim}
377167802Sjkim
378167802Sjkim
379118611Snjl/*******************************************************************************
380118611Snjl *
381193529Sjkim * FUNCTION:    LsDoOnePathname
382193529Sjkim *
383193529Sjkim * PARAMETERS:  ACPI_WALK_CALLBACK
384193529Sjkim *
385193529Sjkim * RETURN:      Status
386193529Sjkim *
387193529Sjkim * DESCRIPTION: Print the full pathname for a namespace node.
388193529Sjkim *
389193529Sjkim ******************************************************************************/
390193529Sjkim
391193529Sjkimstatic ACPI_STATUS
392193529SjkimLsDoOnePathname (
393193529Sjkim    ACPI_HANDLE             ObjHandle,
394193529Sjkim    UINT32                  Level,
395193529Sjkim    void                    *Context,
396193529Sjkim    void                    **ReturnValue)
397193529Sjkim{
398193529Sjkim    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
399193529Sjkim    ACPI_STATUS             Status;
400193529Sjkim    ACPI_BUFFER             TargetPath;
401193529Sjkim
402193529Sjkim
403193529Sjkim    TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
404193529Sjkim    Status = AcpiNsHandleToPathname (Node, &TargetPath);
405193529Sjkim    if (ACPI_FAILURE (Status))
406193529Sjkim    {
407193529Sjkim        return (Status);
408193529Sjkim    }
409193529Sjkim
410193529Sjkim    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
411193529Sjkim    ACPI_FREE (TargetPath.Pointer);
412193529Sjkim
413193529Sjkim    return (AE_OK);
414193529Sjkim}
415193529Sjkim
416193529Sjkim
417193529Sjkim/*******************************************************************************
418193529Sjkim *
419118611Snjl * FUNCTION:    LsDisplayNamespace
420118611Snjl *
421118611Snjl * PARAMETERS:  None
422118611Snjl *
423151937Sjkim * RETURN:      Status
424118611Snjl *
425118611Snjl * DESCRIPTION: Walk the namespace an display information about each node
426118611Snjl *              in the tree.  Information is written to the optional
427118611Snjl *              namespace output file.
428118611Snjl *
429118611Snjl ******************************************************************************/
430118611Snjl
431118611SnjlACPI_STATUS
432118611SnjlLsDisplayNamespace (
433118611Snjl    void)
434118611Snjl{
435118611Snjl    ACPI_STATUS             Status;
436118611Snjl
437118611Snjl
438118611Snjl    if (!Gbl_NsOutputFlag)
439118611Snjl    {
440118611Snjl        return (AE_OK);
441118611Snjl    }
442118611Snjl
443167802Sjkim    Gbl_NumNamespaceObjects = 0;
444167802Sjkim
445118611Snjl    /* File header */
446118611Snjl
447118611Snjl    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
448118611Snjl    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
449118611Snjl
450118611Snjl    /* Walk entire namespace from the root */
451118611Snjl
452118611Snjl    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
453199337Sjkim                ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
454151937Sjkim                NULL, NULL);
455193529Sjkim
456193529Sjkim    /* Print the full pathname for each namespace node */
457193529Sjkim
458193529Sjkim    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
459193529Sjkim
460193529Sjkim    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
461199337Sjkim                ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
462193529Sjkim                NULL, NULL);
463193529Sjkim
464118611Snjl    return (Status);
465118611Snjl}
466118611Snjl
467118611Snjl
468118611Snjl/*******************************************************************************
469118611Snjl *
470118611Snjl * FUNCTION:    LsCompareOneNamespaceObject
471118611Snjl *
472118611Snjl * PARAMETERS:  ACPI_WALK_CALLBACK
473118611Snjl *
474118611Snjl * RETURN:      Status
475118611Snjl *
476118611Snjl * DESCRIPTION: Compare name of one object.
477118611Snjl *
478118611Snjl ******************************************************************************/
479118611Snjl
480151937Sjkimstatic ACPI_STATUS
481118611SnjlLsCompareOneNamespaceObject (
482118611Snjl    ACPI_HANDLE             ObjHandle,
483118611Snjl    UINT32                  Level,
484118611Snjl    void                    *Context,
485118611Snjl    void                    **ReturnValue)
486118611Snjl{
487118611Snjl    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
488118611Snjl
489118611Snjl
490118611Snjl    /* Simply check the name */
491118611Snjl
492118611Snjl    if (*((UINT32 *) (Context)) == Node->Name.Integer)
493118611Snjl    {
494118611Snjl        /* Abort walk if we found one instance */
495118611Snjl
496118611Snjl        return (AE_CTRL_TRUE);
497118611Snjl    }
498118611Snjl
499118611Snjl    return (AE_OK);
500118611Snjl}
501118611Snjl
502118611Snjl
503118611Snjl/*******************************************************************************
504118611Snjl *
505118611Snjl * FUNCTION:    LkObjectExists
506118611Snjl *
507118611Snjl * PARAMETERS:  Name            - 4 char ACPI name
508118611Snjl *
509118611Snjl * RETURN:      TRUE if name exists in namespace
510118611Snjl *
511118611Snjl * DESCRIPTION: Walk the namespace to find an object
512118611Snjl *
513118611Snjl ******************************************************************************/
514118611Snjl
515151937Sjkimstatic BOOLEAN
516118611SnjlLkObjectExists (
517118611Snjl    char                    *Name)
518118611Snjl{
519118611Snjl    ACPI_STATUS             Status;
520118611Snjl
521118611Snjl
522118611Snjl    /* Walk entire namespace from the supplied root */
523118611Snjl
524118611Snjl    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
525199337Sjkim                ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
526151937Sjkim                Name, NULL);
527118611Snjl    if (Status == AE_CTRL_TRUE)
528118611Snjl    {
529118611Snjl        /* At least one instance of the name was found */
530118611Snjl
531118611Snjl        return (TRUE);
532118611Snjl    }
533118611Snjl
534118611Snjl    return (FALSE);
535118611Snjl}
536118611Snjl
537118611Snjl
538118611Snjl/*******************************************************************************
539118611Snjl *
540167802Sjkim * FUNCTION:    LkGetNameOp
541167802Sjkim *
542167802Sjkim * PARAMETERS:  Op              - Current Op
543167802Sjkim *
544167802Sjkim * RETURN:      NameOp associated with the input op
545167802Sjkim *
546167802Sjkim * DESCRIPTION: Find the name declaration op associated with the operator
547167802Sjkim *
548167802Sjkim ******************************************************************************/
549167802Sjkim
550212761Sjkimstatic ACPI_PARSE_OBJECT *
551167802SjkimLkGetNameOp (
552167802Sjkim    ACPI_PARSE_OBJECT       *Op)
553167802Sjkim{
554167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
555167802Sjkim    ACPI_PARSE_OBJECT       *NameOp = Op;
556167802Sjkim
557167802Sjkim
558167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
559167802Sjkim
560167802Sjkim
561167802Sjkim    /* Get the NamePath from the appropriate place */
562167802Sjkim
563167802Sjkim    if (OpInfo->Flags & AML_NAMED)
564167802Sjkim    {
565167802Sjkim        /* For nearly all NAMED operators, the name reference is the first child */
566167802Sjkim
567167802Sjkim        NameOp = Op->Asl.Child;
568167802Sjkim        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
569167802Sjkim        {
570167802Sjkim            /*
571167802Sjkim             * ALIAS is the only oddball opcode, the name declaration
572167802Sjkim             * (alias name) is the second operand
573167802Sjkim             */
574167802Sjkim            NameOp = Op->Asl.Child->Asl.Next;
575167802Sjkim        }
576167802Sjkim    }
577167802Sjkim    else if (OpInfo->Flags & AML_CREATE)
578167802Sjkim    {
579167802Sjkim        /* Name must appear as the last parameter */
580167802Sjkim
581167802Sjkim        NameOp = Op->Asl.Child;
582167802Sjkim        while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
583167802Sjkim        {
584167802Sjkim            NameOp = NameOp->Asl.Next;
585167802Sjkim        }
586167802Sjkim    }
587167802Sjkim
588167802Sjkim    return (NameOp);
589167802Sjkim}
590167802Sjkim
591167802Sjkim
592167802Sjkim/*******************************************************************************
593167802Sjkim *
594167802Sjkim * FUNCTION:    LkIsObjectUsed
595167802Sjkim *
596167802Sjkim * PARAMETERS:  ACPI_WALK_CALLBACK
597167802Sjkim *
598167802Sjkim * RETURN:      Status
599167802Sjkim *
600167802Sjkim * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
601167802Sjkim *              We have to be careful, because some types and names are
602167802Sjkim *              typically or always unreferenced, we don't want to issue
603167802Sjkim *              excessive warnings.
604167802Sjkim *
605167802Sjkim ******************************************************************************/
606167802Sjkim
607167802Sjkimstatic ACPI_STATUS
608167802SjkimLkIsObjectUsed (
609167802Sjkim    ACPI_HANDLE             ObjHandle,
610167802Sjkim    UINT32                  Level,
611167802Sjkim    void                    *Context,
612167802Sjkim    void                    **ReturnValue)
613167802Sjkim{
614167802Sjkim    ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
615167802Sjkim
616167802Sjkim
617167802Sjkim    /* Referenced flag is set during the namespace xref */
618167802Sjkim
619167802Sjkim    if (Node->Flags & ANOBJ_IS_REFERENCED)
620167802Sjkim    {
621167802Sjkim        return (AE_OK);
622167802Sjkim    }
623167802Sjkim
624167802Sjkim    /*
625167802Sjkim     * Ignore names that start with an underscore,
626167802Sjkim     * these are the reserved ACPI names and are typically not referenced,
627167802Sjkim     * they are called by the host OS.
628167802Sjkim     */
629167802Sjkim    if (Node->Name.Ascii[0] == '_')
630167802Sjkim    {
631167802Sjkim        return (AE_OK);
632167802Sjkim    }
633167802Sjkim
634167802Sjkim    /* There are some types that are typically not referenced, ignore them */
635167802Sjkim
636167802Sjkim    switch (Node->Type)
637167802Sjkim    {
638167802Sjkim    case ACPI_TYPE_DEVICE:
639167802Sjkim    case ACPI_TYPE_PROCESSOR:
640167802Sjkim    case ACPI_TYPE_POWER:
641167802Sjkim    case ACPI_TYPE_LOCAL_RESOURCE:
642167802Sjkim        return (AE_OK);
643167802Sjkim
644167802Sjkim    default:
645167802Sjkim        break;
646167802Sjkim    }
647167802Sjkim
648167802Sjkim    /* All others are valid unreferenced namespace objects */
649167802Sjkim
650167802Sjkim    if (Node->Op)
651167802Sjkim    {
652167802Sjkim        AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
653167802Sjkim    }
654167802Sjkim    return (AE_OK);
655167802Sjkim}
656167802Sjkim
657167802Sjkim
658167802Sjkim/*******************************************************************************
659167802Sjkim *
660167802Sjkim * FUNCTION:    LkFindUnreferencedObjects
661167802Sjkim *
662167802Sjkim * PARAMETERS:  None
663167802Sjkim *
664167802Sjkim * RETURN:      None
665167802Sjkim *
666167802Sjkim * DESCRIPTION: Namespace walk to find objects that are not referenced in any
667167802Sjkim *              way. Must be called after the namespace has been cross
668167802Sjkim *              referenced.
669167802Sjkim *
670167802Sjkim ******************************************************************************/
671167802Sjkim
672167802Sjkimvoid
673167802SjkimLkFindUnreferencedObjects (
674167802Sjkim    void)
675167802Sjkim{
676167802Sjkim
677167802Sjkim    /* Walk entire namespace from the supplied root */
678167802Sjkim
679167802Sjkim    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
680199337Sjkim                ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
681167802Sjkim                NULL, NULL);
682167802Sjkim}
683167802Sjkim
684167802Sjkim
685167802Sjkim/*******************************************************************************
686167802Sjkim *
687118611Snjl * FUNCTION:    LkCrossReferenceNamespace
688118611Snjl *
689118611Snjl * PARAMETERS:  None
690118611Snjl *
691118611Snjl * RETURN:      Status
692118611Snjl *
693118611Snjl * DESCRIPTION: Perform a cross reference check of the parse tree against the
694118611Snjl *              namespace.  Every named referenced within the parse tree
695118611Snjl *              should be get resolved with a namespace lookup.  If not, the
696118611Snjl *              original reference in the ASL code is invalid -- i.e., refers
697118611Snjl *              to a non-existent object.
698118611Snjl *
699118611Snjl * NOTE:  The ASL "External" operator causes the name to be inserted into the
700118611Snjl *        namespace so that references to the external name will be resolved
701118611Snjl *        correctly here.
702118611Snjl *
703118611Snjl ******************************************************************************/
704118611Snjl
705118611SnjlACPI_STATUS
706118611SnjlLkCrossReferenceNamespace (
707118611Snjl    void)
708118611Snjl{
709118611Snjl    ACPI_WALK_STATE         *WalkState;
710118611Snjl
711118611Snjl
712118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
713118611Snjl
714118611Snjl    /*
715118611Snjl     * Create a new walk state for use when looking up names
716118611Snjl     * within the namespace (Passed as context to the callbacks)
717118611Snjl     */
718118611Snjl    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
719118611Snjl    if (!WalkState)
720118611Snjl    {
721118611Snjl        return AE_NO_MEMORY;
722118611Snjl    }
723118611Snjl
724118611Snjl    /* Walk the entire parse tree */
725118611Snjl
726118611Snjl    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
727118611Snjl                        LkNamespaceLocateEnd, WalkState);
728118611Snjl    return AE_OK;
729118611Snjl}
730118611Snjl
731118611Snjl
732118611Snjl/*******************************************************************************
733118611Snjl *
734118611Snjl * FUNCTION:    LkCheckFieldRange
735118611Snjl *
736118611Snjl * PARAMETERS:  RegionBitLength     - Length of entire parent region
737118611Snjl *              FieldBitOffset      - Start of the field unit (within region)
738118611Snjl *              FieldBitLength      - Entire length of field unit
739118611Snjl *              AccessBitWidth      - Access width of the field unit
740118611Snjl *
741118611Snjl * RETURN:      None
742118611Snjl *
743118611Snjl * DESCRIPTION: Check one field unit to make sure it fits in the parent
744118611Snjl *              op region.
745118611Snjl *
746118611Snjl * Note: AccessBitWidth must be either 8,16,32, or 64
747118611Snjl *
748118611Snjl ******************************************************************************/
749118611Snjl
750151937Sjkimstatic void
751118611SnjlLkCheckFieldRange (
752118611Snjl    ACPI_PARSE_OBJECT       *Op,
753118611Snjl    UINT32                  RegionBitLength,
754118611Snjl    UINT32                  FieldBitOffset,
755118611Snjl    UINT32                  FieldBitLength,
756118611Snjl    UINT32                  AccessBitWidth)
757118611Snjl{
758118611Snjl    UINT32                  FieldEndBitOffset;
759118611Snjl
760151937Sjkim
761118611Snjl    /*
762118611Snjl     * Check each field unit against the region size.  The entire
763118611Snjl     * field unit (start offset plus length) must fit within the
764118611Snjl     * region.
765118611Snjl     */
766118611Snjl    FieldEndBitOffset = FieldBitOffset + FieldBitLength;
767118611Snjl
768118611Snjl    if (FieldEndBitOffset > RegionBitLength)
769118611Snjl    {
770118611Snjl        /* Field definition itself is beyond the end-of-region */
771118611Snjl
772118611Snjl        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
773118611Snjl        return;
774118611Snjl    }
775118611Snjl
776118611Snjl    /*
777118611Snjl     * Now check that the field plus AccessWidth doesn't go beyond
778118611Snjl     * the end-of-region.  Assumes AccessBitWidth is a power of 2
779118611Snjl     */
780118611Snjl    FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
781118611Snjl
782118611Snjl    if (FieldEndBitOffset > RegionBitLength)
783118611Snjl    {
784118611Snjl        /* Field definition combined with the access is beyond EOR */
785118611Snjl
786118611Snjl        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
787118611Snjl    }
788118611Snjl}
789118611Snjl
790118611Snjl/*******************************************************************************
791118611Snjl *
792118611Snjl * FUNCTION:    LkNamespaceLocateBegin
793118611Snjl *
794118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
795118611Snjl *
796118611Snjl * RETURN:      Status
797118611Snjl *
798118611Snjl * DESCRIPTION: Descending callback used during cross-reference.  For named
799118611Snjl *              object references, attempt to locate the name in the
800118611Snjl *              namespace.
801118611Snjl *
802118611Snjl * NOTE: ASL references to named fields within resource descriptors are
803118611Snjl *       resolved to integer values here.  Therefore, this step is an
804118611Snjl *       important part of the code generation.  We don't know that the
805118611Snjl *       name refers to a resource descriptor until now.
806118611Snjl *
807118611Snjl ******************************************************************************/
808118611Snjl
809151937Sjkimstatic ACPI_STATUS
810118611SnjlLkNamespaceLocateBegin (
811118611Snjl    ACPI_PARSE_OBJECT       *Op,
812118611Snjl    UINT32                  Level,
813118611Snjl    void                    *Context)
814118611Snjl{
815118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
816118611Snjl    ACPI_NAMESPACE_NODE     *Node;
817118611Snjl    ACPI_STATUS             Status;
818118611Snjl    ACPI_OBJECT_TYPE        ObjectType;
819118611Snjl    char                    *Path;
820118611Snjl    UINT8                   PassedArgs;
821118611Snjl    ACPI_PARSE_OBJECT       *NextOp;
822118611Snjl    ACPI_PARSE_OBJECT       *OwningOp;
823118611Snjl    ACPI_PARSE_OBJECT       *SpaceIdOp;
824118611Snjl    UINT32                  MinimumLength;
825118611Snjl    UINT32                  Temp;
826118611Snjl    const ACPI_OPCODE_INFO  *OpInfo;
827118611Snjl    UINT32                  Flags;
828118611Snjl
829118611Snjl
830167802Sjkim    ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
831118611Snjl
832118611Snjl    /*
833118611Snjl     * If this node is the actual declaration of a name
834118611Snjl     * [such as the XXXX name in "Method (XXXX)"],
835118611Snjl     * we are not interested in it here.  We only care about names that are
836118611Snjl     * references to other objects within the namespace and the parent objects
837118611Snjl     * of name declarations
838118611Snjl     */
839118611Snjl    if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
840118611Snjl    {
841118611Snjl        return (AE_OK);
842118611Snjl    }
843118611Snjl
844118611Snjl    /* We are only interested in opcodes that have an associated name */
845118611Snjl
846118611Snjl    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
847118611Snjl
848118611Snjl    if ((!(OpInfo->Flags & AML_NAMED)) &&
849118611Snjl        (!(OpInfo->Flags & AML_CREATE)) &&
850118611Snjl        (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
851118611Snjl        (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
852118611Snjl        (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
853118611Snjl    {
854118611Snjl        return (AE_OK);
855118611Snjl    }
856118611Snjl
857118611Snjl    /*
858193529Sjkim     * One special case: CondRefOf operator - we don't care if the name exists
859193529Sjkim     * or not at this point, just ignore it, the point of the operator is to
860193529Sjkim     * determine if the name exists at runtime.
861193529Sjkim     */
862193529Sjkim    if ((Op->Asl.Parent) &&
863193529Sjkim        (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
864193529Sjkim    {
865193529Sjkim        return (AE_OK);
866193529Sjkim    }
867193529Sjkim
868193529Sjkim    /*
869118611Snjl     * We must enable the "search-to-root" for single NameSegs, but
870118611Snjl     * we have to be very careful about opening up scopes
871118611Snjl     */
872118611Snjl    Flags = ACPI_NS_SEARCH_PARENT;
873118611Snjl    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
874118611Snjl        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
875118611Snjl        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
876118611Snjl    {
877118611Snjl        /*
878118611Snjl         * These are name references, do not push the scope stack
879118611Snjl         * for them.
880118611Snjl         */
881118611Snjl        Flags |= ACPI_NS_DONT_OPEN_SCOPE;
882118611Snjl    }
883118611Snjl
884118611Snjl    /* Get the NamePath from the appropriate place */
885118611Snjl
886118611Snjl    if (OpInfo->Flags & AML_NAMED)
887118611Snjl    {
888167802Sjkim        /* For nearly all NAMED operators, the name reference is the first child */
889118611Snjl
890118611Snjl        Path = Op->Asl.Child->Asl.Value.String;
891118611Snjl        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
892118611Snjl        {
893118611Snjl            /*
894118611Snjl             * ALIAS is the only oddball opcode, the name declaration
895118611Snjl             * (alias name) is the second operand
896118611Snjl             */
897118611Snjl            Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
898118611Snjl        }
899118611Snjl    }
900118611Snjl    else if (OpInfo->Flags & AML_CREATE)
901118611Snjl    {
902118611Snjl        /* Name must appear as the last parameter */
903118611Snjl
904118611Snjl        NextOp = Op->Asl.Child;
905118611Snjl        while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
906118611Snjl        {
907118611Snjl            NextOp = NextOp->Asl.Next;
908118611Snjl        }
909118611Snjl        Path = NextOp->Asl.Value.String;
910118611Snjl    }
911118611Snjl    else
912118611Snjl    {
913118611Snjl        Path = Op->Asl.Value.String;
914118611Snjl    }
915118611Snjl
916118611Snjl    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
917151937Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
918151937Sjkim        "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
919118611Snjl
920118611Snjl    /*
921118611Snjl     * Lookup the name in the namespace.  Name must exist at this point, or it
922118611Snjl     * is an invalid reference.
923118611Snjl     *
924118611Snjl     * The namespace is also used as a lookup table for references to resource
925118611Snjl     * descriptors and the fields within them.
926118611Snjl     */
927118611Snjl    Gbl_NsLookupCount++;
928118611Snjl
929167802Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
930151937Sjkim                ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
931118611Snjl    if (ACPI_FAILURE (Status))
932118611Snjl    {
933118611Snjl        if (Status == AE_NOT_FOUND)
934118611Snjl        {
935118611Snjl            /*
936118611Snjl             * We didn't find the name reference by path -- we can qualify this
937118611Snjl             * a little better before we print an error message
938118611Snjl             */
939118611Snjl            if (strlen (Path) == ACPI_NAME_SIZE)
940118611Snjl            {
941118611Snjl                /* A simple, one-segment ACPI name */
942118611Snjl
943118611Snjl                if (LkObjectExists (Path))
944118611Snjl                {
945151937Sjkim                    /*
946151937Sjkim                     * There exists such a name, but we couldn't get to it
947151937Sjkim                     * from this scope
948151937Sjkim                     */
949151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
950151937Sjkim                        Op->Asl.ExternalName);
951118611Snjl                }
952118611Snjl                else
953118611Snjl                {
954118611Snjl                    /* The name doesn't exist, period */
955118611Snjl
956151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
957151937Sjkim                        Op, Op->Asl.ExternalName);
958118611Snjl                }
959118611Snjl            }
960118611Snjl            else
961118611Snjl            {
962118611Snjl                /* Check for a fully qualified path */
963118611Snjl
964118611Snjl                if (Path[0] == AML_ROOT_PREFIX)
965118611Snjl                {
966118611Snjl                    /* Gave full path, the object does not exist */
967118611Snjl
968151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
969151937Sjkim                        Op->Asl.ExternalName);
970118611Snjl                }
971118611Snjl                else
972118611Snjl                {
973151937Sjkim                    /*
974151937Sjkim                     * We can't tell whether it doesn't exist or just
975151937Sjkim                     * can't be reached.
976151937Sjkim                     */
977151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
978151937Sjkim                        Op->Asl.ExternalName);
979118611Snjl                }
980118611Snjl            }
981118611Snjl
982118611Snjl            Status = AE_OK;
983118611Snjl        }
984118611Snjl        return (Status);
985118611Snjl    }
986118611Snjl
987167802Sjkim    /* Check for a reference vs. name declaration */
988167802Sjkim
989167802Sjkim    if (!(OpInfo->Flags & AML_NAMED) &&
990167802Sjkim        !(OpInfo->Flags & AML_CREATE))
991167802Sjkim    {
992167802Sjkim        /* This node has been referenced, mark it for reference check */
993167802Sjkim
994167802Sjkim        Node->Flags |= ANOBJ_IS_REFERENCED;
995167802Sjkim    }
996167802Sjkim
997118611Snjl    /* Attempt to optimize the NamePath */
998118611Snjl
999118611Snjl    OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
1000118611Snjl
1001118611Snjl    /*
1002167802Sjkim     * 1) Dereference an alias (A name reference that is an alias)
1003167802Sjkim     *    Aliases are not nested, the alias always points to the final object
1004118611Snjl     */
1005151937Sjkim    if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
1006151937Sjkim        (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
1007118611Snjl    {
1008118611Snjl        /* This node points back to the original PARSEOP_ALIAS */
1009118611Snjl
1010151937Sjkim        NextOp = Node->Op;
1011118611Snjl
1012118611Snjl        /* The first child is the alias target op */
1013118611Snjl
1014118611Snjl        NextOp = NextOp->Asl.Child;
1015118611Snjl
1016167802Sjkim        /* That in turn points back to original target alias node */
1017118611Snjl
1018118611Snjl        if (NextOp->Asl.Node)
1019118611Snjl        {
1020118611Snjl            Node = NextOp->Asl.Node;
1021118611Snjl        }
1022167802Sjkim
1023167802Sjkim        /* Else - forward reference to alias, will be resolved later */
1024118611Snjl    }
1025118611Snjl
1026167802Sjkim    /* 2) Check for a reference to a resource descriptor */
1027118611Snjl
1028167802Sjkim    if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1029118611Snjl             (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1030118611Snjl    {
1031118611Snjl        /*
1032118611Snjl         * This was a reference to a field within a resource descriptor.  Extract
1033118611Snjl         * the associated field offset (either a bit or byte offset depending on
1034118611Snjl         * the field type) and change the named reference into an integer for
1035118611Snjl         * AML code generation
1036118611Snjl         */
1037151937Sjkim        Temp = Node->Value;
1038118611Snjl        if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
1039118611Snjl        {
1040118611Snjl            Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
1041118611Snjl        }
1042118611Snjl
1043118611Snjl        /* Perform BitOffset <--> ByteOffset conversion if necessary */
1044118611Snjl
1045118611Snjl        switch (Op->Asl.Parent->Asl.AmlOpcode)
1046118611Snjl        {
1047118611Snjl        case AML_CREATE_FIELD_OP:
1048118611Snjl
1049118611Snjl            /* We allow a Byte offset to Bit Offset conversion for this op */
1050118611Snjl
1051118611Snjl            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
1052118611Snjl            {
1053118611Snjl                /* Simply multiply byte offset times 8 to get bit offset */
1054118611Snjl
1055118611Snjl                Temp = ACPI_MUL_8 (Temp);
1056118611Snjl            }
1057118611Snjl            break;
1058118611Snjl
1059118611Snjl
1060118611Snjl        case AML_CREATE_BIT_FIELD_OP:
1061118611Snjl
1062118611Snjl            /* This op requires a Bit Offset */
1063118611Snjl
1064118611Snjl            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
1065118611Snjl            {
1066118611Snjl                AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
1067118611Snjl            }
1068118611Snjl            break;
1069118611Snjl
1070118611Snjl
1071118611Snjl        case AML_CREATE_BYTE_FIELD_OP:
1072118611Snjl        case AML_CREATE_WORD_FIELD_OP:
1073118611Snjl        case AML_CREATE_DWORD_FIELD_OP:
1074118611Snjl        case AML_CREATE_QWORD_FIELD_OP:
1075118611Snjl        case AML_INDEX_OP:
1076118611Snjl
1077118611Snjl            /* These Ops require Byte offsets */
1078118611Snjl
1079118611Snjl            if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
1080118611Snjl            {
1081118611Snjl                AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
1082118611Snjl            }
1083118611Snjl            break;
1084118611Snjl
1085118611Snjl
1086118611Snjl        default:
1087118611Snjl            /* Nothing to do for other opcodes */
1088118611Snjl            break;
1089118611Snjl        }
1090118611Snjl
1091118611Snjl        /* Now convert this node to an integer whose value is the field offset */
1092118611Snjl
1093151937Sjkim        Op->Asl.AmlLength       = 0;
1094118611Snjl        Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
1095118611Snjl        Op->Asl.Value.Integer   = (UINT64) Temp;
1096118611Snjl        Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
1097118611Snjl
1098118611Snjl        OpcGenerateAmlOpcode (Op);
1099118611Snjl    }
1100118611Snjl
1101167802Sjkim    /* 3) Check for a method invocation */
1102118611Snjl
1103118611Snjl    else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
1104118611Snjl                (Node->Type == ACPI_TYPE_METHOD) &&
1105118611Snjl                (Op->Asl.Parent) &&
1106118611Snjl                (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
1107118611Snjl
1108118611Snjl                (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1109118611Snjl    {
1110118611Snjl
1111118611Snjl        /*
1112151937Sjkim         * A reference to a method within one of these opcodes is not an
1113151937Sjkim         * invocation of the method, it is simply a reference to the method.
1114151937Sjkim         */
1115151937Sjkim        if ((Op->Asl.Parent) &&
1116151937Sjkim           ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||
1117151937Sjkim            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||
1118151937Sjkim            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
1119151937Sjkim        {
1120151937Sjkim            return (AE_OK);
1121151937Sjkim        }
1122151937Sjkim        /*
1123118611Snjl         * There are two types of method invocation:
1124151937Sjkim         * 1) Invocation with arguments -- the parser recognizes this
1125151937Sjkim         *    as a METHODCALL.
1126151937Sjkim         * 2) Invocation with no arguments --the parser cannot determine that
1127151937Sjkim         *    this is a method invocation, therefore we have to figure it out
1128151937Sjkim         *    here.
1129118611Snjl         */
1130118611Snjl        if (Node->Type != ACPI_TYPE_METHOD)
1131118611Snjl        {
1132151937Sjkim            sprintf (MsgBuffer, "%s is a %s",
1133151937Sjkim                    Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
1134118611Snjl
1135118611Snjl            AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
1136118611Snjl            return (AE_OK);
1137118611Snjl        }
1138118611Snjl
1139118611Snjl        /* Save the method node in the caller's op */
1140118611Snjl
1141118611Snjl        Op->Asl.Node = Node;
1142118611Snjl        if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
1143118611Snjl        {
1144118611Snjl            return (AE_OK);
1145118611Snjl        }
1146118611Snjl
1147118611Snjl        /*
1148118611Snjl         * This is a method invocation, with or without arguments.
1149118611Snjl         * Count the number of arguments, each appears as a child
1150118611Snjl         * under the parent node
1151118611Snjl         */
1152118611Snjl        Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
1153118611Snjl        UtSetParseOpName (Op);
1154118611Snjl
1155118611Snjl        PassedArgs = 0;
1156118611Snjl        NextOp     = Op->Asl.Child;
1157118611Snjl
1158118611Snjl        while (NextOp)
1159118611Snjl        {
1160118611Snjl            PassedArgs++;
1161118611Snjl            NextOp = NextOp->Asl.Next;
1162118611Snjl        }
1163118611Snjl
1164151937Sjkim        if (Node->Value != ASL_EXTERNAL_METHOD)
1165118611Snjl        {
1166118611Snjl            /*
1167118611Snjl             * Check the parsed arguments with the number expected by the
1168118611Snjl             * method declaration itself
1169118611Snjl             */
1170151937Sjkim            if (PassedArgs != Node->Value)
1171118611Snjl            {
1172209746Sjkim                sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
1173151937Sjkim                            Node->Value);
1174118611Snjl
1175151937Sjkim                if (PassedArgs < Node->Value)
1176118611Snjl                {
1177118611Snjl                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
1178118611Snjl                }
1179118611Snjl                else
1180118611Snjl                {
1181118611Snjl                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
1182118611Snjl                }
1183118611Snjl            }
1184118611Snjl        }
1185118611Snjl    }
1186118611Snjl
1187167802Sjkim    /* 4) Check for an ASL Field definition */
1188151937Sjkim
1189118611Snjl    else if ((Op->Asl.Parent) &&
1190118611Snjl            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
1191118611Snjl             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
1192118611Snjl    {
1193118611Snjl        /*
1194118611Snjl         * Offset checking for fields.  If the parent operation region has a
1195118611Snjl         * constant length (known at compile time), we can check fields
1196118611Snjl         * defined in that region against the region length.  This will catch
1197118611Snjl         * fields and field units that cannot possibly fit within the region.
1198118611Snjl         *
1199118611Snjl         * Note: Index fields do not directly reference an operation region,
1200118611Snjl         * thus they are not included in this check.
1201118611Snjl         */
1202118611Snjl        if (Op == Op->Asl.Parent->Asl.Child)
1203118611Snjl        {
1204118611Snjl            /*
1205118611Snjl             * This is the first child of the field node, which is
1206118611Snjl             * the name of the region.  Get the parse node for the
1207118611Snjl             * region -- which contains the length of the region.
1208118611Snjl             */
1209151937Sjkim            OwningOp = Node->Op;
1210151937Sjkim            Op->Asl.Parent->Asl.ExtraValue =
1211151937Sjkim                ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
1212118611Snjl
1213118611Snjl            /* Examine the field access width */
1214118611Snjl
1215118611Snjl            switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
1216118611Snjl            {
1217118611Snjl            case AML_FIELD_ACCESS_ANY:
1218118611Snjl            case AML_FIELD_ACCESS_BYTE:
1219118611Snjl            case AML_FIELD_ACCESS_BUFFER:
1220118611Snjl            default:
1221118611Snjl                MinimumLength = 1;
1222118611Snjl                break;
1223118611Snjl
1224118611Snjl            case AML_FIELD_ACCESS_WORD:
1225118611Snjl                MinimumLength = 2;
1226118611Snjl                break;
1227118611Snjl
1228118611Snjl            case AML_FIELD_ACCESS_DWORD:
1229118611Snjl                MinimumLength = 4;
1230118611Snjl                break;
1231118611Snjl
1232118611Snjl            case AML_FIELD_ACCESS_QWORD:
1233118611Snjl                MinimumLength = 8;
1234118611Snjl                break;
1235118611Snjl            }
1236118611Snjl
1237118611Snjl            /*
1238118611Snjl             * Is the region at least as big as the access width?
1239118611Snjl             * Note: DataTableRegions have 0 length
1240118611Snjl             */
1241118611Snjl            if (((UINT32) OwningOp->Asl.Value.Integer) &&
1242118611Snjl                ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
1243118611Snjl            {
1244118611Snjl                AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
1245118611Snjl            }
1246118611Snjl
1247118611Snjl            /*
1248118611Snjl             * Check EC/CMOS/SMBUS fields to make sure that the correct
1249118611Snjl             * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
1250118611Snjl             */
1251118611Snjl            SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
1252118611Snjl            switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
1253118611Snjl            {
1254220663Sjkim            case ACPI_ADR_SPACE_EC:
1255220663Sjkim            case ACPI_ADR_SPACE_CMOS:
1256118611Snjl
1257118611Snjl                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
1258118611Snjl                {
1259118611Snjl                    AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
1260118611Snjl                }
1261118611Snjl                break;
1262118611Snjl
1263220663Sjkim            case ACPI_ADR_SPACE_SMBUS:
1264220663Sjkim            case ACPI_ADR_SPACE_IPMI:
1265118611Snjl
1266118611Snjl                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
1267118611Snjl                {
1268118611Snjl                    AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
1269118611Snjl                }
1270118611Snjl                break;
1271118611Snjl
1272118611Snjl            default:
1273118611Snjl
1274118611Snjl                /* Nothing to do for other address spaces */
1275118611Snjl                break;
1276118611Snjl            }
1277118611Snjl        }
1278118611Snjl        else
1279118611Snjl        {
1280118611Snjl            /*
1281118611Snjl             * This is one element of the field list.  Check to make sure
1282118611Snjl             * that it does not go beyond the end of the parent operation region.
1283118611Snjl             *
1284118611Snjl             * In the code below:
1285118611Snjl             *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
1286118611Snjl             *    Op->Asl.ExtraValue                  - Field start offset (bits)
1287118611Snjl             *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
1288118611Snjl             *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
1289118611Snjl             */
1290118611Snjl            if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
1291118611Snjl            {
1292118611Snjl                LkCheckFieldRange (Op,
1293118611Snjl                            Op->Asl.Parent->Asl.ExtraValue,
1294118611Snjl                            Op->Asl.ExtraValue,
1295118611Snjl                            (UINT32) Op->Asl.Child->Asl.Value.Integer,
1296118611Snjl                            Op->Asl.Child->Asl.ExtraValue);
1297118611Snjl            }
1298118611Snjl        }
1299118611Snjl    }
1300118611Snjl
1301118611Snjl    Op->Asl.Node = Node;
1302118611Snjl    return (Status);
1303118611Snjl}
1304118611Snjl
1305118611Snjl
1306118611Snjl/*******************************************************************************
1307118611Snjl *
1308118611Snjl * FUNCTION:    LkNamespaceLocateEnd
1309118611Snjl *
1310118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
1311118611Snjl *
1312118611Snjl * RETURN:      Status
1313118611Snjl *
1314118611Snjl * DESCRIPTION: Ascending callback used during cross reference.  We only
1315118611Snjl *              need to worry about scope management here.
1316118611Snjl *
1317118611Snjl ******************************************************************************/
1318118611Snjl
1319151937Sjkimstatic ACPI_STATUS
1320118611SnjlLkNamespaceLocateEnd (
1321118611Snjl    ACPI_PARSE_OBJECT       *Op,
1322118611Snjl    UINT32                  Level,
1323118611Snjl    void                    *Context)
1324118611Snjl{
1325118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1326118611Snjl    const ACPI_OPCODE_INFO  *OpInfo;
1327118611Snjl
1328118611Snjl
1329167802Sjkim    ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
1330118611Snjl
1331118611Snjl
1332118611Snjl    /* We are only interested in opcodes that have an associated name */
1333118611Snjl
1334118611Snjl    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1335118611Snjl    if (!(OpInfo->Flags & AML_NAMED))
1336118611Snjl    {
1337118611Snjl        return (AE_OK);
1338118611Snjl    }
1339118611Snjl
1340118611Snjl    /* Not interested in name references, we did not open a scope for them */
1341118611Snjl
1342118611Snjl    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
1343118611Snjl        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
1344118611Snjl        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1345118611Snjl    {
1346118611Snjl        return (AE_OK);
1347118611Snjl    }
1348118611Snjl
1349118611Snjl    /* Pop the scope stack if necessary */
1350118611Snjl
1351118611Snjl    if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
1352118611Snjl    {
1353118611Snjl
1354118611Snjl        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1355118611Snjl            "%s: Popping scope for Op %p\n",
1356118611Snjl            AcpiUtGetTypeName (OpInfo->ObjectType), Op));
1357118611Snjl
1358151937Sjkim        (void) AcpiDsScopeStackPop (WalkState);
1359118611Snjl    }
1360118611Snjl
1361118611Snjl    return (AE_OK);
1362118611Snjl}
1363118611Snjl
1364118611Snjl
1365