xref: /freebsd/sys/contrib/dev/acpica/compiler/asllookup.c (revision d244b2279c2f63fc930fa1c11a6033b7119d426a)
153289f6aSNate Lawson /******************************************************************************
253289f6aSNate Lawson  *
353289f6aSNate Lawson  * Module Name: asllookup- Namespace lookup
453289f6aSNate Lawson  *
553289f6aSNate Lawson  *****************************************************************************/
653289f6aSNate Lawson 
7*d244b227SJung-uk Kim /*
8*d244b227SJung-uk Kim  * Copyright (C) 2000 - 2011, Intel Corp.
953289f6aSNate Lawson  * All rights reserved.
1053289f6aSNate Lawson  *
11*d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
13*d244b227SJung-uk Kim  * are met:
14*d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*d244b227SJung-uk Kim  *    without modification.
17*d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*d244b227SJung-uk Kim  *    binary redistribution.
22*d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*d244b227SJung-uk Kim  *    from this software without specific prior written permission.
2553289f6aSNate Lawson  *
26*d244b227SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*d244b227SJung-uk Kim  * Software Foundation.
2953289f6aSNate Lawson  *
30*d244b227SJung-uk Kim  * NO WARRANTY
31*d244b227SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*d244b227SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*d244b227SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*d244b227SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*d244b227SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*d244b227SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*d244b227SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*d244b227SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*d244b227SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*d244b227SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*d244b227SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*d244b227SJung-uk Kim  */
4353289f6aSNate Lawson 
4453289f6aSNate Lawson 
45ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
4653289f6aSNate Lawson #include "aslcompiler.y.h"
4753289f6aSNate Lawson 
48ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
49ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
50ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
51ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h>
5253289f6aSNate Lawson 
5353289f6aSNate Lawson 
5453289f6aSNate Lawson #define _COMPONENT          ACPI_COMPILER
5553289f6aSNate Lawson         ACPI_MODULE_NAME    ("asllookup")
5653289f6aSNate Lawson 
57fba7fc7eSJung-uk Kim /* Local prototypes */
58fba7fc7eSJung-uk Kim 
59fba7fc7eSJung-uk Kim static ACPI_STATUS
60fba7fc7eSJung-uk Kim LsCompareOneNamespaceObject (
61fba7fc7eSJung-uk Kim     ACPI_HANDLE             ObjHandle,
62fba7fc7eSJung-uk Kim     UINT32                  Level,
63fba7fc7eSJung-uk Kim     void                    *Context,
64fba7fc7eSJung-uk Kim     void                    **ReturnValue);
65fba7fc7eSJung-uk Kim 
66fba7fc7eSJung-uk Kim static ACPI_STATUS
67fba7fc7eSJung-uk Kim LsDoOneNamespaceObject (
68fba7fc7eSJung-uk Kim     ACPI_HANDLE             ObjHandle,
69fba7fc7eSJung-uk Kim     UINT32                  Level,
70fba7fc7eSJung-uk Kim     void                    *Context,
71fba7fc7eSJung-uk Kim     void                    **ReturnValue);
72fba7fc7eSJung-uk Kim 
73fba7fc7eSJung-uk Kim static BOOLEAN
74fba7fc7eSJung-uk Kim LkObjectExists (
75fba7fc7eSJung-uk Kim     char                    *Name);
76fba7fc7eSJung-uk Kim 
77fba7fc7eSJung-uk Kim static void
78fba7fc7eSJung-uk Kim LkCheckFieldRange (
79fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
80fba7fc7eSJung-uk Kim     UINT32                  RegionBitLength,
81fba7fc7eSJung-uk Kim     UINT32                  FieldBitOffset,
82fba7fc7eSJung-uk Kim     UINT32                  FieldBitLength,
83fba7fc7eSJung-uk Kim     UINT32                  AccessBitWidth);
84fba7fc7eSJung-uk Kim 
85fba7fc7eSJung-uk Kim static ACPI_STATUS
86fba7fc7eSJung-uk Kim LkNamespaceLocateBegin (
87fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
88fba7fc7eSJung-uk Kim     UINT32                  Level,
89fba7fc7eSJung-uk Kim     void                    *Context);
90fba7fc7eSJung-uk Kim 
91fba7fc7eSJung-uk Kim static ACPI_STATUS
92fba7fc7eSJung-uk Kim LkNamespaceLocateEnd (
93fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
94fba7fc7eSJung-uk Kim     UINT32                  Level,
95fba7fc7eSJung-uk Kim     void                    *Context);
96fba7fc7eSJung-uk Kim 
971a39cfb0SJung-uk Kim static ACPI_STATUS
981a39cfb0SJung-uk Kim LkIsObjectUsed (
991a39cfb0SJung-uk Kim     ACPI_HANDLE             ObjHandle,
1001a39cfb0SJung-uk Kim     UINT32                  Level,
1011a39cfb0SJung-uk Kim     void                    *Context,
1021a39cfb0SJung-uk Kim     void                    **ReturnValue);
1031a39cfb0SJung-uk Kim 
104a9f12690SJung-uk Kim static ACPI_STATUS
105a9f12690SJung-uk Kim LsDoOnePathname (
106a9f12690SJung-uk Kim     ACPI_HANDLE             ObjHandle,
107a9f12690SJung-uk Kim     UINT32                  Level,
108a9f12690SJung-uk Kim     void                    *Context,
109a9f12690SJung-uk Kim     void                    **ReturnValue);
110a9f12690SJung-uk Kim 
11142fecd12SJung-uk Kim static ACPI_PARSE_OBJECT *
112a9f12690SJung-uk Kim LkGetNameOp (
113a9f12690SJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
114a9f12690SJung-uk Kim 
11553289f6aSNate Lawson 
11653289f6aSNate Lawson /*******************************************************************************
11753289f6aSNate Lawson  *
11853289f6aSNate Lawson  * FUNCTION:    LsDoOneNamespaceObject
11953289f6aSNate Lawson  *
12053289f6aSNate Lawson  * PARAMETERS:  ACPI_WALK_CALLBACK
12153289f6aSNate Lawson  *
12253289f6aSNate Lawson  * RETURN:      Status
12353289f6aSNate Lawson  *
12453289f6aSNate Lawson  * DESCRIPTION: Dump a namespace object to the namespace output file.
12553289f6aSNate Lawson  *              Called during the walk of the namespace to dump all objects.
12653289f6aSNate Lawson  *
12753289f6aSNate Lawson  ******************************************************************************/
12853289f6aSNate Lawson 
129fba7fc7eSJung-uk Kim static ACPI_STATUS
13053289f6aSNate Lawson LsDoOneNamespaceObject (
13153289f6aSNate Lawson     ACPI_HANDLE             ObjHandle,
13253289f6aSNate Lawson     UINT32                  Level,
13353289f6aSNate Lawson     void                    *Context,
13453289f6aSNate Lawson     void                    **ReturnValue)
13553289f6aSNate Lawson {
13653289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
137fba7fc7eSJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
13853289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op;
13953289f6aSNate Lawson 
14053289f6aSNate Lawson 
14153289f6aSNate Lawson     Gbl_NumNamespaceObjects++;
14253289f6aSNate Lawson 
143a88e22b7SJung-uk Kim     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
14453289f6aSNate Lawson         Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
14553289f6aSNate Lawson         &Node->Name,
14653289f6aSNate Lawson         AcpiUtGetTypeName (Node->Type));
14753289f6aSNate Lawson 
148fba7fc7eSJung-uk Kim     Op = Node->Op;
149fba7fc7eSJung-uk Kim     ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
15053289f6aSNate Lawson 
151fba7fc7eSJung-uk Kim     if (!Op)
15253289f6aSNate Lawson     {
153fba7fc7eSJung-uk Kim         FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
154fba7fc7eSJung-uk Kim         return (AE_OK);
15553289f6aSNate Lawson     }
15653289f6aSNate Lawson 
157fba7fc7eSJung-uk Kim 
158fba7fc7eSJung-uk Kim     if ((ObjDesc) &&
1591a39cfb0SJung-uk Kim         (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
160fba7fc7eSJung-uk Kim     {
16153289f6aSNate Lawson         switch (Node->Type)
16253289f6aSNate Lawson         {
16353289f6aSNate Lawson         case ACPI_TYPE_INTEGER:
16453289f6aSNate Lawson 
165fba7fc7eSJung-uk Kim             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
166fba7fc7eSJung-uk Kim                 "       [Initial Value   0x%8.8X%8.8X]",
167fba7fc7eSJung-uk Kim                 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
16853289f6aSNate Lawson             break;
16953289f6aSNate Lawson 
17053289f6aSNate Lawson 
17153289f6aSNate Lawson         case ACPI_TYPE_STRING:
17253289f6aSNate Lawson 
173fba7fc7eSJung-uk Kim             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
174fba7fc7eSJung-uk Kim                 "        [Initial Value   \"%s\"]",
175fba7fc7eSJung-uk Kim                 ObjDesc->String.Pointer);
176fba7fc7eSJung-uk Kim             break;
177fba7fc7eSJung-uk Kim 
178fba7fc7eSJung-uk Kim         default:
179fba7fc7eSJung-uk Kim             /* Nothing to do for other types */
180fba7fc7eSJung-uk Kim             break;
181fba7fc7eSJung-uk Kim         }
182fba7fc7eSJung-uk Kim 
183fba7fc7eSJung-uk Kim     }
184fba7fc7eSJung-uk Kim     else
185fba7fc7eSJung-uk Kim     {
186fba7fc7eSJung-uk Kim         switch (Node->Type)
187fba7fc7eSJung-uk Kim         {
188fba7fc7eSJung-uk Kim         case ACPI_TYPE_INTEGER:
189fba7fc7eSJung-uk Kim 
190fba7fc7eSJung-uk Kim             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
191fba7fc7eSJung-uk Kim             {
192fba7fc7eSJung-uk Kim                 Op = Op->Asl.Child;
193fba7fc7eSJung-uk Kim             }
19453289f6aSNate Lawson             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
19553289f6aSNate Lawson                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
19653289f6aSNate Lawson             {
19753289f6aSNate Lawson                 Op = Op->Asl.Next;
19853289f6aSNate Lawson             }
199fba7fc7eSJung-uk Kim             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
200fba7fc7eSJung-uk Kim                 "       [Initial Value   0x%8.8X%8.8X]",
201fba7fc7eSJung-uk Kim                 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
202fba7fc7eSJung-uk Kim             break;
20353289f6aSNate Lawson 
204fba7fc7eSJung-uk Kim 
205fba7fc7eSJung-uk Kim         case ACPI_TYPE_STRING:
206fba7fc7eSJung-uk Kim 
207fba7fc7eSJung-uk Kim             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
208fba7fc7eSJung-uk Kim             {
209fba7fc7eSJung-uk Kim                 Op = Op->Asl.Child;
210fba7fc7eSJung-uk Kim             }
211fba7fc7eSJung-uk Kim             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
212fba7fc7eSJung-uk Kim                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
213fba7fc7eSJung-uk Kim             {
214fba7fc7eSJung-uk Kim                 Op = Op->Asl.Next;
215fba7fc7eSJung-uk Kim             }
216fba7fc7eSJung-uk Kim             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
217fba7fc7eSJung-uk Kim                 "        [Initial Value   \"%s\"]",
21853289f6aSNate Lawson                 Op->Asl.Value.String);
21953289f6aSNate Lawson             break;
22053289f6aSNate Lawson 
22153289f6aSNate Lawson 
22253289f6aSNate Lawson         case ACPI_TYPE_LOCAL_REGION_FIELD:
22353289f6aSNate Lawson 
22453289f6aSNate Lawson             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
22553289f6aSNate Lawson                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
22653289f6aSNate Lawson             {
22753289f6aSNate Lawson                 Op = Op->Asl.Child;
22853289f6aSNate Lawson             }
229fba7fc7eSJung-uk Kim             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
230fba7fc7eSJung-uk Kim                 "   [Offset 0x%04X   Length 0x%04X bits]",
23153289f6aSNate Lawson                 Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
23253289f6aSNate Lawson             break;
23353289f6aSNate Lawson 
23453289f6aSNate Lawson 
235fba7fc7eSJung-uk Kim         case ACPI_TYPE_BUFFER_FIELD:
236fba7fc7eSJung-uk Kim 
237fba7fc7eSJung-uk Kim             switch (Op->Asl.ParseOpcode)
238fba7fc7eSJung-uk Kim             {
239fba7fc7eSJung-uk Kim             case PARSEOP_CREATEBYTEFIELD:
240fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
241fba7fc7eSJung-uk Kim                 break;
242fba7fc7eSJung-uk Kim 
243fba7fc7eSJung-uk Kim             case PARSEOP_CREATEDWORDFIELD:
244fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
245fba7fc7eSJung-uk Kim                 break;
246fba7fc7eSJung-uk Kim 
247fba7fc7eSJung-uk Kim             case PARSEOP_CREATEQWORDFIELD:
248fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
249fba7fc7eSJung-uk Kim                 break;
250fba7fc7eSJung-uk Kim 
251fba7fc7eSJung-uk Kim             case PARSEOP_CREATEWORDFIELD:
252fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
253fba7fc7eSJung-uk Kim                 break;
254fba7fc7eSJung-uk Kim 
255fba7fc7eSJung-uk Kim             case PARSEOP_CREATEBITFIELD:
256fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
257fba7fc7eSJung-uk Kim                 break;
258fba7fc7eSJung-uk Kim 
259fba7fc7eSJung-uk Kim             case PARSEOP_CREATEFIELD:
260fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
261fba7fc7eSJung-uk Kim                 break;
262fba7fc7eSJung-uk Kim 
263fba7fc7eSJung-uk Kim             default:
264fba7fc7eSJung-uk Kim                 break;
265fba7fc7eSJung-uk Kim 
266fba7fc7eSJung-uk Kim             }
267fba7fc7eSJung-uk Kim             break;
268fba7fc7eSJung-uk Kim 
269fba7fc7eSJung-uk Kim 
270fba7fc7eSJung-uk Kim         case ACPI_TYPE_PACKAGE:
271fba7fc7eSJung-uk Kim 
272fba7fc7eSJung-uk Kim             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
273fba7fc7eSJung-uk Kim             {
274fba7fc7eSJung-uk Kim                 Op = Op->Asl.Child;
275fba7fc7eSJung-uk Kim             }
276fba7fc7eSJung-uk Kim             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
277fba7fc7eSJung-uk Kim                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
278fba7fc7eSJung-uk Kim             {
279fba7fc7eSJung-uk Kim                 Op = Op->Asl.Next;
280fba7fc7eSJung-uk Kim             }
281fba7fc7eSJung-uk Kim             Op = Op->Asl.Child;
282fba7fc7eSJung-uk Kim 
283fba7fc7eSJung-uk Kim             if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
284fba7fc7eSJung-uk Kim                 (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
285fba7fc7eSJung-uk Kim             {
286fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
287fba7fc7eSJung-uk Kim                     "       [Initial Length  0x%.2X elements]",
288fba7fc7eSJung-uk Kim                     Op->Asl.Value.Integer);
289fba7fc7eSJung-uk Kim             }
290fba7fc7eSJung-uk Kim             break;
291fba7fc7eSJung-uk Kim 
292fba7fc7eSJung-uk Kim 
293fba7fc7eSJung-uk Kim         case ACPI_TYPE_BUFFER:
294fba7fc7eSJung-uk Kim 
295fba7fc7eSJung-uk Kim             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
296fba7fc7eSJung-uk Kim             {
297fba7fc7eSJung-uk Kim                 Op = Op->Asl.Child;
298fba7fc7eSJung-uk Kim             }
299fba7fc7eSJung-uk Kim             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
300fba7fc7eSJung-uk Kim                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
301fba7fc7eSJung-uk Kim             {
302fba7fc7eSJung-uk Kim                 Op = Op->Asl.Next;
303fba7fc7eSJung-uk Kim             }
304fba7fc7eSJung-uk Kim             Op = Op->Asl.Child;
305fba7fc7eSJung-uk Kim 
3061a39cfb0SJung-uk Kim             if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
307fba7fc7eSJung-uk Kim             {
308fba7fc7eSJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
309fba7fc7eSJung-uk Kim                     "        [Initial Length  0x%.2X bytes]",
310fba7fc7eSJung-uk Kim                     Op->Asl.Value.Integer);
311fba7fc7eSJung-uk Kim             }
312fba7fc7eSJung-uk Kim             break;
313fba7fc7eSJung-uk Kim 
314fba7fc7eSJung-uk Kim 
315fba7fc7eSJung-uk Kim         case ACPI_TYPE_METHOD:
316fba7fc7eSJung-uk Kim 
317fba7fc7eSJung-uk Kim             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
318fba7fc7eSJung-uk Kim                 "        [Code Length     0x%.4X bytes]",
319fba7fc7eSJung-uk Kim                 Op->Asl.AmlSubtreeLength);
320fba7fc7eSJung-uk Kim             break;
321fba7fc7eSJung-uk Kim 
322fba7fc7eSJung-uk Kim 
3231a39cfb0SJung-uk Kim         case ACPI_TYPE_LOCAL_RESOURCE:
3241a39cfb0SJung-uk Kim 
3251a39cfb0SJung-uk Kim             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
3261a39cfb0SJung-uk Kim                 "  [Desc Offset     0x%.4X Bytes]", Node->Value);
3271a39cfb0SJung-uk Kim             break;
3281a39cfb0SJung-uk Kim 
3291a39cfb0SJung-uk Kim 
3301a39cfb0SJung-uk Kim         case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
3311a39cfb0SJung-uk Kim 
3321a39cfb0SJung-uk Kim             if (Node->Flags & 0x80)
3331a39cfb0SJung-uk Kim             {
3341a39cfb0SJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
3351a39cfb0SJung-uk Kim                     "   [Field Offset    0x%.4X Bits 0x%.4X Bytes]",
3361a39cfb0SJung-uk Kim                     Node->Value, Node->Value / 8);
3371a39cfb0SJung-uk Kim             }
3381a39cfb0SJung-uk Kim             else
3391a39cfb0SJung-uk Kim             {
3401a39cfb0SJung-uk Kim                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
3411a39cfb0SJung-uk Kim                     "   [Field Offset    0x%.4X Bytes]", Node->Value);
3421a39cfb0SJung-uk Kim             }
3431a39cfb0SJung-uk Kim             break;
3441a39cfb0SJung-uk Kim 
3451a39cfb0SJung-uk Kim 
34653289f6aSNate Lawson         default:
34753289f6aSNate Lawson             /* Nothing to do for other types */
34853289f6aSNate Lawson             break;
34953289f6aSNate Lawson         }
35053289f6aSNate Lawson     }
35153289f6aSNate Lawson 
35253289f6aSNate Lawson     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
35353289f6aSNate Lawson     return (AE_OK);
35453289f6aSNate Lawson }
35553289f6aSNate Lawson 
35653289f6aSNate Lawson 
357a9f12690SJung-uk Kim /*******************************************************************************
358a9f12690SJung-uk Kim  *
359a9f12690SJung-uk Kim  * FUNCTION:    LsSetupNsList
360a9f12690SJung-uk Kim  *
361a9f12690SJung-uk Kim  * PARAMETERS:  Handle          - local file handle
362a9f12690SJung-uk Kim  *
363a9f12690SJung-uk Kim  * RETURN:      None
364a9f12690SJung-uk Kim  *
365a9f12690SJung-uk Kim  * DESCRIPTION: Set the namespace output file to the input handle
366a9f12690SJung-uk Kim  *
367a9f12690SJung-uk Kim  ******************************************************************************/
368a9f12690SJung-uk Kim 
3691a39cfb0SJung-uk Kim void
370a9f12690SJung-uk Kim LsSetupNsList (
371a9f12690SJung-uk Kim     void                    *Handle)
3721a39cfb0SJung-uk Kim {
3731a39cfb0SJung-uk Kim 
3741a39cfb0SJung-uk Kim     Gbl_NsOutputFlag = TRUE;
3751a39cfb0SJung-uk Kim     Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
3761a39cfb0SJung-uk Kim }
3771a39cfb0SJung-uk Kim 
3781a39cfb0SJung-uk Kim 
37953289f6aSNate Lawson /*******************************************************************************
38053289f6aSNate Lawson  *
381a9f12690SJung-uk Kim  * FUNCTION:    LsDoOnePathname
382a9f12690SJung-uk Kim  *
383a9f12690SJung-uk Kim  * PARAMETERS:  ACPI_WALK_CALLBACK
384a9f12690SJung-uk Kim  *
385a9f12690SJung-uk Kim  * RETURN:      Status
386a9f12690SJung-uk Kim  *
387a9f12690SJung-uk Kim  * DESCRIPTION: Print the full pathname for a namespace node.
388a9f12690SJung-uk Kim  *
389a9f12690SJung-uk Kim  ******************************************************************************/
390a9f12690SJung-uk Kim 
391a9f12690SJung-uk Kim static ACPI_STATUS
392a9f12690SJung-uk Kim LsDoOnePathname (
393a9f12690SJung-uk Kim     ACPI_HANDLE             ObjHandle,
394a9f12690SJung-uk Kim     UINT32                  Level,
395a9f12690SJung-uk Kim     void                    *Context,
396a9f12690SJung-uk Kim     void                    **ReturnValue)
397a9f12690SJung-uk Kim {
398a9f12690SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
399a9f12690SJung-uk Kim     ACPI_STATUS             Status;
400a9f12690SJung-uk Kim     ACPI_BUFFER             TargetPath;
401a9f12690SJung-uk Kim 
402a9f12690SJung-uk Kim 
403a9f12690SJung-uk Kim     TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
404a9f12690SJung-uk Kim     Status = AcpiNsHandleToPathname (Node, &TargetPath);
405a9f12690SJung-uk Kim     if (ACPI_FAILURE (Status))
406a9f12690SJung-uk Kim     {
407a9f12690SJung-uk Kim         return (Status);
408a9f12690SJung-uk Kim     }
409a9f12690SJung-uk Kim 
410a9f12690SJung-uk Kim     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
411a9f12690SJung-uk Kim     ACPI_FREE (TargetPath.Pointer);
412a9f12690SJung-uk Kim 
413a9f12690SJung-uk Kim     return (AE_OK);
414a9f12690SJung-uk Kim }
415a9f12690SJung-uk Kim 
416a9f12690SJung-uk Kim 
417a9f12690SJung-uk Kim /*******************************************************************************
418a9f12690SJung-uk Kim  *
41953289f6aSNate Lawson  * FUNCTION:    LsDisplayNamespace
42053289f6aSNate Lawson  *
42153289f6aSNate Lawson  * PARAMETERS:  None
42253289f6aSNate Lawson  *
423fba7fc7eSJung-uk Kim  * RETURN:      Status
42453289f6aSNate Lawson  *
42553289f6aSNate Lawson  * DESCRIPTION: Walk the namespace an display information about each node
42653289f6aSNate Lawson  *              in the tree.  Information is written to the optional
42753289f6aSNate Lawson  *              namespace output file.
42853289f6aSNate Lawson  *
42953289f6aSNate Lawson  ******************************************************************************/
43053289f6aSNate Lawson 
43153289f6aSNate Lawson ACPI_STATUS
43253289f6aSNate Lawson LsDisplayNamespace (
43353289f6aSNate Lawson     void)
43453289f6aSNate Lawson {
43553289f6aSNate Lawson     ACPI_STATUS             Status;
43653289f6aSNate Lawson 
43753289f6aSNate Lawson 
43853289f6aSNate Lawson     if (!Gbl_NsOutputFlag)
43953289f6aSNate Lawson     {
44053289f6aSNate Lawson         return (AE_OK);
44153289f6aSNate Lawson     }
44253289f6aSNate Lawson 
4431a39cfb0SJung-uk Kim     Gbl_NumNamespaceObjects = 0;
4441a39cfb0SJung-uk Kim 
44553289f6aSNate Lawson     /* File header */
44653289f6aSNate Lawson 
44753289f6aSNate Lawson     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
44853289f6aSNate Lawson     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
44953289f6aSNate Lawson 
45053289f6aSNate Lawson     /* Walk entire namespace from the root */
45153289f6aSNate Lawson 
45253289f6aSNate Lawson     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
4532272d050SJung-uk Kim                 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
45453289f6aSNate Lawson                 NULL, NULL);
455a9f12690SJung-uk Kim 
456a9f12690SJung-uk Kim     /* Print the full pathname for each namespace node */
457a9f12690SJung-uk Kim 
458a9f12690SJung-uk Kim     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
459a9f12690SJung-uk Kim 
460a9f12690SJung-uk Kim     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
4612272d050SJung-uk Kim                 ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
462a9f12690SJung-uk Kim                 NULL, NULL);
463a9f12690SJung-uk Kim 
46453289f6aSNate Lawson     return (Status);
46553289f6aSNate Lawson }
46653289f6aSNate Lawson 
46753289f6aSNate Lawson 
46853289f6aSNate Lawson /*******************************************************************************
46953289f6aSNate Lawson  *
47053289f6aSNate Lawson  * FUNCTION:    LsCompareOneNamespaceObject
47153289f6aSNate Lawson  *
47253289f6aSNate Lawson  * PARAMETERS:  ACPI_WALK_CALLBACK
47353289f6aSNate Lawson  *
47453289f6aSNate Lawson  * RETURN:      Status
47553289f6aSNate Lawson  *
47653289f6aSNate Lawson  * DESCRIPTION: Compare name of one object.
47753289f6aSNate Lawson  *
47853289f6aSNate Lawson  ******************************************************************************/
47953289f6aSNate Lawson 
480fba7fc7eSJung-uk Kim static ACPI_STATUS
48153289f6aSNate Lawson LsCompareOneNamespaceObject (
48253289f6aSNate Lawson     ACPI_HANDLE             ObjHandle,
48353289f6aSNate Lawson     UINT32                  Level,
48453289f6aSNate Lawson     void                    *Context,
48553289f6aSNate Lawson     void                    **ReturnValue)
48653289f6aSNate Lawson {
48753289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
48853289f6aSNate Lawson 
48953289f6aSNate Lawson 
49053289f6aSNate Lawson     /* Simply check the name */
49153289f6aSNate Lawson 
49253289f6aSNate Lawson     if (*((UINT32 *) (Context)) == Node->Name.Integer)
49353289f6aSNate Lawson     {
49453289f6aSNate Lawson         /* Abort walk if we found one instance */
49553289f6aSNate Lawson 
49653289f6aSNate Lawson         return (AE_CTRL_TRUE);
49753289f6aSNate Lawson     }
49853289f6aSNate Lawson 
49953289f6aSNate Lawson     return (AE_OK);
50053289f6aSNate Lawson }
50153289f6aSNate Lawson 
50253289f6aSNate Lawson 
50353289f6aSNate Lawson /*******************************************************************************
50453289f6aSNate Lawson  *
50553289f6aSNate Lawson  * FUNCTION:    LkObjectExists
50653289f6aSNate Lawson  *
50753289f6aSNate Lawson  * PARAMETERS:  Name            - 4 char ACPI name
50853289f6aSNate Lawson  *
50953289f6aSNate Lawson  * RETURN:      TRUE if name exists in namespace
51053289f6aSNate Lawson  *
51153289f6aSNate Lawson  * DESCRIPTION: Walk the namespace to find an object
51253289f6aSNate Lawson  *
51353289f6aSNate Lawson  ******************************************************************************/
51453289f6aSNate Lawson 
515fba7fc7eSJung-uk Kim static BOOLEAN
51653289f6aSNate Lawson LkObjectExists (
51753289f6aSNate Lawson     char                    *Name)
51853289f6aSNate Lawson {
51953289f6aSNate Lawson     ACPI_STATUS             Status;
52053289f6aSNate Lawson 
52153289f6aSNate Lawson 
52253289f6aSNate Lawson     /* Walk entire namespace from the supplied root */
52353289f6aSNate Lawson 
52453289f6aSNate Lawson     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
5252272d050SJung-uk Kim                 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
52653289f6aSNate Lawson                 Name, NULL);
52753289f6aSNate Lawson     if (Status == AE_CTRL_TRUE)
52853289f6aSNate Lawson     {
52953289f6aSNate Lawson         /* At least one instance of the name was found */
53053289f6aSNate Lawson 
53153289f6aSNate Lawson         return (TRUE);
53253289f6aSNate Lawson     }
53353289f6aSNate Lawson 
53453289f6aSNate Lawson     return (FALSE);
53553289f6aSNate Lawson }
53653289f6aSNate Lawson 
53753289f6aSNate Lawson 
53853289f6aSNate Lawson /*******************************************************************************
53953289f6aSNate Lawson  *
5401a39cfb0SJung-uk Kim  * FUNCTION:    LkGetNameOp
5411a39cfb0SJung-uk Kim  *
5421a39cfb0SJung-uk Kim  * PARAMETERS:  Op              - Current Op
5431a39cfb0SJung-uk Kim  *
5441a39cfb0SJung-uk Kim  * RETURN:      NameOp associated with the input op
5451a39cfb0SJung-uk Kim  *
5461a39cfb0SJung-uk Kim  * DESCRIPTION: Find the name declaration op associated with the operator
5471a39cfb0SJung-uk Kim  *
5481a39cfb0SJung-uk Kim  ******************************************************************************/
5491a39cfb0SJung-uk Kim 
55042fecd12SJung-uk Kim static ACPI_PARSE_OBJECT *
5511a39cfb0SJung-uk Kim LkGetNameOp (
5521a39cfb0SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
5531a39cfb0SJung-uk Kim {
5541a39cfb0SJung-uk Kim     const ACPI_OPCODE_INFO  *OpInfo;
5551a39cfb0SJung-uk Kim     ACPI_PARSE_OBJECT       *NameOp = Op;
5561a39cfb0SJung-uk Kim 
5571a39cfb0SJung-uk Kim 
5581a39cfb0SJung-uk Kim     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
5591a39cfb0SJung-uk Kim 
5601a39cfb0SJung-uk Kim 
5611a39cfb0SJung-uk Kim     /* Get the NamePath from the appropriate place */
5621a39cfb0SJung-uk Kim 
5631a39cfb0SJung-uk Kim     if (OpInfo->Flags & AML_NAMED)
5641a39cfb0SJung-uk Kim     {
5651a39cfb0SJung-uk Kim         /* For nearly all NAMED operators, the name reference is the first child */
5661a39cfb0SJung-uk Kim 
5671a39cfb0SJung-uk Kim         NameOp = Op->Asl.Child;
5681a39cfb0SJung-uk Kim         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
5691a39cfb0SJung-uk Kim         {
5701a39cfb0SJung-uk Kim             /*
5711a39cfb0SJung-uk Kim              * ALIAS is the only oddball opcode, the name declaration
5721a39cfb0SJung-uk Kim              * (alias name) is the second operand
5731a39cfb0SJung-uk Kim              */
5741a39cfb0SJung-uk Kim             NameOp = Op->Asl.Child->Asl.Next;
5751a39cfb0SJung-uk Kim         }
5761a39cfb0SJung-uk Kim     }
5771a39cfb0SJung-uk Kim     else if (OpInfo->Flags & AML_CREATE)
5781a39cfb0SJung-uk Kim     {
5791a39cfb0SJung-uk Kim         /* Name must appear as the last parameter */
5801a39cfb0SJung-uk Kim 
5811a39cfb0SJung-uk Kim         NameOp = Op->Asl.Child;
5821a39cfb0SJung-uk Kim         while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
5831a39cfb0SJung-uk Kim         {
5841a39cfb0SJung-uk Kim             NameOp = NameOp->Asl.Next;
5851a39cfb0SJung-uk Kim         }
5861a39cfb0SJung-uk Kim     }
5871a39cfb0SJung-uk Kim 
5881a39cfb0SJung-uk Kim     return (NameOp);
5891a39cfb0SJung-uk Kim }
5901a39cfb0SJung-uk Kim 
5911a39cfb0SJung-uk Kim 
5921a39cfb0SJung-uk Kim /*******************************************************************************
5931a39cfb0SJung-uk Kim  *
5941a39cfb0SJung-uk Kim  * FUNCTION:    LkIsObjectUsed
5951a39cfb0SJung-uk Kim  *
5961a39cfb0SJung-uk Kim  * PARAMETERS:  ACPI_WALK_CALLBACK
5971a39cfb0SJung-uk Kim  *
5981a39cfb0SJung-uk Kim  * RETURN:      Status
5991a39cfb0SJung-uk Kim  *
6001a39cfb0SJung-uk Kim  * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
6011a39cfb0SJung-uk Kim  *              We have to be careful, because some types and names are
6021a39cfb0SJung-uk Kim  *              typically or always unreferenced, we don't want to issue
6031a39cfb0SJung-uk Kim  *              excessive warnings.
6041a39cfb0SJung-uk Kim  *
6051a39cfb0SJung-uk Kim  ******************************************************************************/
6061a39cfb0SJung-uk Kim 
6071a39cfb0SJung-uk Kim static ACPI_STATUS
6081a39cfb0SJung-uk Kim LkIsObjectUsed (
6091a39cfb0SJung-uk Kim     ACPI_HANDLE             ObjHandle,
6101a39cfb0SJung-uk Kim     UINT32                  Level,
6111a39cfb0SJung-uk Kim     void                    *Context,
6121a39cfb0SJung-uk Kim     void                    **ReturnValue)
6131a39cfb0SJung-uk Kim {
6141a39cfb0SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
6151a39cfb0SJung-uk Kim 
6161a39cfb0SJung-uk Kim 
6171a39cfb0SJung-uk Kim     /* Referenced flag is set during the namespace xref */
6181a39cfb0SJung-uk Kim 
6191a39cfb0SJung-uk Kim     if (Node->Flags & ANOBJ_IS_REFERENCED)
6201a39cfb0SJung-uk Kim     {
6211a39cfb0SJung-uk Kim         return (AE_OK);
6221a39cfb0SJung-uk Kim     }
6231a39cfb0SJung-uk Kim 
6241a39cfb0SJung-uk Kim     /*
6251a39cfb0SJung-uk Kim      * Ignore names that start with an underscore,
6261a39cfb0SJung-uk Kim      * these are the reserved ACPI names and are typically not referenced,
6271a39cfb0SJung-uk Kim      * they are called by the host OS.
6281a39cfb0SJung-uk Kim      */
6291a39cfb0SJung-uk Kim     if (Node->Name.Ascii[0] == '_')
6301a39cfb0SJung-uk Kim     {
6311a39cfb0SJung-uk Kim         return (AE_OK);
6321a39cfb0SJung-uk Kim     }
6331a39cfb0SJung-uk Kim 
6341a39cfb0SJung-uk Kim     /* There are some types that are typically not referenced, ignore them */
6351a39cfb0SJung-uk Kim 
6361a39cfb0SJung-uk Kim     switch (Node->Type)
6371a39cfb0SJung-uk Kim     {
6381a39cfb0SJung-uk Kim     case ACPI_TYPE_DEVICE:
6391a39cfb0SJung-uk Kim     case ACPI_TYPE_PROCESSOR:
6401a39cfb0SJung-uk Kim     case ACPI_TYPE_POWER:
6411a39cfb0SJung-uk Kim     case ACPI_TYPE_LOCAL_RESOURCE:
6421a39cfb0SJung-uk Kim         return (AE_OK);
6431a39cfb0SJung-uk Kim 
6441a39cfb0SJung-uk Kim     default:
6451a39cfb0SJung-uk Kim         break;
6461a39cfb0SJung-uk Kim     }
6471a39cfb0SJung-uk Kim 
6481a39cfb0SJung-uk Kim     /* All others are valid unreferenced namespace objects */
6491a39cfb0SJung-uk Kim 
6501a39cfb0SJung-uk Kim     if (Node->Op)
6511a39cfb0SJung-uk Kim     {
6521a39cfb0SJung-uk Kim         AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
6531a39cfb0SJung-uk Kim     }
6541a39cfb0SJung-uk Kim     return (AE_OK);
6551a39cfb0SJung-uk Kim }
6561a39cfb0SJung-uk Kim 
6571a39cfb0SJung-uk Kim 
6581a39cfb0SJung-uk Kim /*******************************************************************************
6591a39cfb0SJung-uk Kim  *
6601a39cfb0SJung-uk Kim  * FUNCTION:    LkFindUnreferencedObjects
6611a39cfb0SJung-uk Kim  *
6621a39cfb0SJung-uk Kim  * PARAMETERS:  None
6631a39cfb0SJung-uk Kim  *
6641a39cfb0SJung-uk Kim  * RETURN:      None
6651a39cfb0SJung-uk Kim  *
6661a39cfb0SJung-uk Kim  * DESCRIPTION: Namespace walk to find objects that are not referenced in any
6671a39cfb0SJung-uk Kim  *              way. Must be called after the namespace has been cross
6681a39cfb0SJung-uk Kim  *              referenced.
6691a39cfb0SJung-uk Kim  *
6701a39cfb0SJung-uk Kim  ******************************************************************************/
6711a39cfb0SJung-uk Kim 
6721a39cfb0SJung-uk Kim void
6731a39cfb0SJung-uk Kim LkFindUnreferencedObjects (
6741a39cfb0SJung-uk Kim     void)
6751a39cfb0SJung-uk Kim {
6761a39cfb0SJung-uk Kim 
6771a39cfb0SJung-uk Kim     /* Walk entire namespace from the supplied root */
6781a39cfb0SJung-uk Kim 
6791a39cfb0SJung-uk Kim     (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
6802272d050SJung-uk Kim                 ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
6811a39cfb0SJung-uk Kim                 NULL, NULL);
6821a39cfb0SJung-uk Kim }
6831a39cfb0SJung-uk Kim 
6841a39cfb0SJung-uk Kim 
6851a39cfb0SJung-uk Kim /*******************************************************************************
6861a39cfb0SJung-uk Kim  *
68753289f6aSNate Lawson  * FUNCTION:    LkCrossReferenceNamespace
68853289f6aSNate Lawson  *
68953289f6aSNate Lawson  * PARAMETERS:  None
69053289f6aSNate Lawson  *
69153289f6aSNate Lawson  * RETURN:      Status
69253289f6aSNate Lawson  *
69353289f6aSNate Lawson  * DESCRIPTION: Perform a cross reference check of the parse tree against the
69453289f6aSNate Lawson  *              namespace.  Every named referenced within the parse tree
69553289f6aSNate Lawson  *              should be get resolved with a namespace lookup.  If not, the
69653289f6aSNate Lawson  *              original reference in the ASL code is invalid -- i.e., refers
69753289f6aSNate Lawson  *              to a non-existent object.
69853289f6aSNate Lawson  *
69953289f6aSNate Lawson  * NOTE:  The ASL "External" operator causes the name to be inserted into the
70053289f6aSNate Lawson  *        namespace so that references to the external name will be resolved
70153289f6aSNate Lawson  *        correctly here.
70253289f6aSNate Lawson  *
70353289f6aSNate Lawson  ******************************************************************************/
70453289f6aSNate Lawson 
70553289f6aSNate Lawson ACPI_STATUS
70653289f6aSNate Lawson LkCrossReferenceNamespace (
70753289f6aSNate Lawson     void)
70853289f6aSNate Lawson {
70953289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState;
71053289f6aSNate Lawson 
71153289f6aSNate Lawson 
71253289f6aSNate Lawson     DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
71353289f6aSNate Lawson 
71453289f6aSNate Lawson     /*
71553289f6aSNate Lawson      * Create a new walk state for use when looking up names
71653289f6aSNate Lawson      * within the namespace (Passed as context to the callbacks)
71753289f6aSNate Lawson      */
71853289f6aSNate Lawson     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
71953289f6aSNate Lawson     if (!WalkState)
72053289f6aSNate Lawson     {
72153289f6aSNate Lawson         return AE_NO_MEMORY;
72253289f6aSNate Lawson     }
72353289f6aSNate Lawson 
72453289f6aSNate Lawson     /* Walk the entire parse tree */
72553289f6aSNate Lawson 
72653289f6aSNate Lawson     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
72753289f6aSNate Lawson                         LkNamespaceLocateEnd, WalkState);
72853289f6aSNate Lawson     return AE_OK;
72953289f6aSNate Lawson }
73053289f6aSNate Lawson 
73153289f6aSNate Lawson 
73253289f6aSNate Lawson /*******************************************************************************
73353289f6aSNate Lawson  *
73453289f6aSNate Lawson  * FUNCTION:    LkCheckFieldRange
73553289f6aSNate Lawson  *
73653289f6aSNate Lawson  * PARAMETERS:  RegionBitLength     - Length of entire parent region
73753289f6aSNate Lawson  *              FieldBitOffset      - Start of the field unit (within region)
73853289f6aSNate Lawson  *              FieldBitLength      - Entire length of field unit
73953289f6aSNate Lawson  *              AccessBitWidth      - Access width of the field unit
74053289f6aSNate Lawson  *
74153289f6aSNate Lawson  * RETURN:      None
74253289f6aSNate Lawson  *
74353289f6aSNate Lawson  * DESCRIPTION: Check one field unit to make sure it fits in the parent
74453289f6aSNate Lawson  *              op region.
74553289f6aSNate Lawson  *
74653289f6aSNate Lawson  * Note: AccessBitWidth must be either 8,16,32, or 64
74753289f6aSNate Lawson  *
74853289f6aSNate Lawson  ******************************************************************************/
74953289f6aSNate Lawson 
750fba7fc7eSJung-uk Kim static void
75153289f6aSNate Lawson LkCheckFieldRange (
75253289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
75353289f6aSNate Lawson     UINT32                  RegionBitLength,
75453289f6aSNate Lawson     UINT32                  FieldBitOffset,
75553289f6aSNate Lawson     UINT32                  FieldBitLength,
75653289f6aSNate Lawson     UINT32                  AccessBitWidth)
75753289f6aSNate Lawson {
75853289f6aSNate Lawson     UINT32                  FieldEndBitOffset;
75953289f6aSNate Lawson 
760fba7fc7eSJung-uk Kim 
76153289f6aSNate Lawson     /*
76253289f6aSNate Lawson      * Check each field unit against the region size.  The entire
76353289f6aSNate Lawson      * field unit (start offset plus length) must fit within the
76453289f6aSNate Lawson      * region.
76553289f6aSNate Lawson      */
76653289f6aSNate Lawson     FieldEndBitOffset = FieldBitOffset + FieldBitLength;
76753289f6aSNate Lawson 
76853289f6aSNate Lawson     if (FieldEndBitOffset > RegionBitLength)
76953289f6aSNate Lawson     {
77053289f6aSNate Lawson         /* Field definition itself is beyond the end-of-region */
77153289f6aSNate Lawson 
77253289f6aSNate Lawson         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
77353289f6aSNate Lawson         return;
77453289f6aSNate Lawson     }
77553289f6aSNate Lawson 
77653289f6aSNate Lawson     /*
77753289f6aSNate Lawson      * Now check that the field plus AccessWidth doesn't go beyond
77853289f6aSNate Lawson      * the end-of-region.  Assumes AccessBitWidth is a power of 2
77953289f6aSNate Lawson      */
78053289f6aSNate Lawson     FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
78153289f6aSNate Lawson 
78253289f6aSNate Lawson     if (FieldEndBitOffset > RegionBitLength)
78353289f6aSNate Lawson     {
78453289f6aSNate Lawson         /* Field definition combined with the access is beyond EOR */
78553289f6aSNate Lawson 
78653289f6aSNate Lawson         AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
78753289f6aSNate Lawson     }
78853289f6aSNate Lawson }
78953289f6aSNate Lawson 
79053289f6aSNate Lawson /*******************************************************************************
79153289f6aSNate Lawson  *
79253289f6aSNate Lawson  * FUNCTION:    LkNamespaceLocateBegin
79353289f6aSNate Lawson  *
79453289f6aSNate Lawson  * PARAMETERS:  ASL_WALK_CALLBACK
79553289f6aSNate Lawson  *
79653289f6aSNate Lawson  * RETURN:      Status
79753289f6aSNate Lawson  *
79853289f6aSNate Lawson  * DESCRIPTION: Descending callback used during cross-reference.  For named
79953289f6aSNate Lawson  *              object references, attempt to locate the name in the
80053289f6aSNate Lawson  *              namespace.
80153289f6aSNate Lawson  *
80253289f6aSNate Lawson  * NOTE: ASL references to named fields within resource descriptors are
80353289f6aSNate Lawson  *       resolved to integer values here.  Therefore, this step is an
80453289f6aSNate Lawson  *       important part of the code generation.  We don't know that the
80553289f6aSNate Lawson  *       name refers to a resource descriptor until now.
80653289f6aSNate Lawson  *
80753289f6aSNate Lawson  ******************************************************************************/
80853289f6aSNate Lawson 
809fba7fc7eSJung-uk Kim static ACPI_STATUS
81053289f6aSNate Lawson LkNamespaceLocateBegin (
81153289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
81253289f6aSNate Lawson     UINT32                  Level,
81353289f6aSNate Lawson     void                    *Context)
81453289f6aSNate Lawson {
81553289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
81653289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node;
81753289f6aSNate Lawson     ACPI_STATUS             Status;
81853289f6aSNate Lawson     ACPI_OBJECT_TYPE        ObjectType;
81953289f6aSNate Lawson     char                    *Path;
82053289f6aSNate Lawson     UINT8                   PassedArgs;
82153289f6aSNate Lawson     ACPI_PARSE_OBJECT       *NextOp;
82253289f6aSNate Lawson     ACPI_PARSE_OBJECT       *OwningOp;
82353289f6aSNate Lawson     ACPI_PARSE_OBJECT       *SpaceIdOp;
82453289f6aSNate Lawson     UINT32                  MinimumLength;
82553289f6aSNate Lawson     UINT32                  Temp;
82653289f6aSNate Lawson     const ACPI_OPCODE_INFO  *OpInfo;
82753289f6aSNate Lawson     UINT32                  Flags;
82853289f6aSNate Lawson 
82953289f6aSNate Lawson 
8301a39cfb0SJung-uk Kim     ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
83153289f6aSNate Lawson 
83253289f6aSNate Lawson     /*
83353289f6aSNate Lawson      * If this node is the actual declaration of a name
83453289f6aSNate Lawson      * [such as the XXXX name in "Method (XXXX)"],
83553289f6aSNate Lawson      * we are not interested in it here.  We only care about names that are
83653289f6aSNate Lawson      * references to other objects within the namespace and the parent objects
83753289f6aSNate Lawson      * of name declarations
83853289f6aSNate Lawson      */
83953289f6aSNate Lawson     if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
84053289f6aSNate Lawson     {
84153289f6aSNate Lawson         return (AE_OK);
84253289f6aSNate Lawson     }
84353289f6aSNate Lawson 
84453289f6aSNate Lawson     /* We are only interested in opcodes that have an associated name */
84553289f6aSNate Lawson 
84653289f6aSNate Lawson     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
84753289f6aSNate Lawson 
84853289f6aSNate Lawson     if ((!(OpInfo->Flags & AML_NAMED)) &&
84953289f6aSNate Lawson         (!(OpInfo->Flags & AML_CREATE)) &&
85053289f6aSNate Lawson         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
85153289f6aSNate Lawson         (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
85253289f6aSNate Lawson         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
85353289f6aSNate Lawson     {
85453289f6aSNate Lawson         return (AE_OK);
85553289f6aSNate Lawson     }
85653289f6aSNate Lawson 
85753289f6aSNate Lawson     /*
858a9f12690SJung-uk Kim      * One special case: CondRefOf operator - we don't care if the name exists
859a9f12690SJung-uk Kim      * or not at this point, just ignore it, the point of the operator is to
860a9f12690SJung-uk Kim      * determine if the name exists at runtime.
861a9f12690SJung-uk Kim      */
862a9f12690SJung-uk Kim     if ((Op->Asl.Parent) &&
863a9f12690SJung-uk Kim         (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
864a9f12690SJung-uk Kim     {
865a9f12690SJung-uk Kim         return (AE_OK);
866a9f12690SJung-uk Kim     }
867a9f12690SJung-uk Kim 
868a9f12690SJung-uk Kim     /*
86953289f6aSNate Lawson      * We must enable the "search-to-root" for single NameSegs, but
87053289f6aSNate Lawson      * we have to be very careful about opening up scopes
87153289f6aSNate Lawson      */
87253289f6aSNate Lawson     Flags = ACPI_NS_SEARCH_PARENT;
87353289f6aSNate Lawson     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
87453289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
87553289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
87653289f6aSNate Lawson     {
87753289f6aSNate Lawson         /*
87853289f6aSNate Lawson          * These are name references, do not push the scope stack
87953289f6aSNate Lawson          * for them.
88053289f6aSNate Lawson          */
88153289f6aSNate Lawson         Flags |= ACPI_NS_DONT_OPEN_SCOPE;
88253289f6aSNate Lawson     }
88353289f6aSNate Lawson 
88453289f6aSNate Lawson     /* Get the NamePath from the appropriate place */
88553289f6aSNate Lawson 
88653289f6aSNate Lawson     if (OpInfo->Flags & AML_NAMED)
88753289f6aSNate Lawson     {
8881a39cfb0SJung-uk Kim         /* For nearly all NAMED operators, the name reference is the first child */
88953289f6aSNate Lawson 
89053289f6aSNate Lawson         Path = Op->Asl.Child->Asl.Value.String;
89153289f6aSNate Lawson         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
89253289f6aSNate Lawson         {
89353289f6aSNate Lawson             /*
89453289f6aSNate Lawson              * ALIAS is the only oddball opcode, the name declaration
89553289f6aSNate Lawson              * (alias name) is the second operand
89653289f6aSNate Lawson              */
89753289f6aSNate Lawson             Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
89853289f6aSNate Lawson         }
89953289f6aSNate Lawson     }
90053289f6aSNate Lawson     else if (OpInfo->Flags & AML_CREATE)
90153289f6aSNate Lawson     {
90253289f6aSNate Lawson         /* Name must appear as the last parameter */
90353289f6aSNate Lawson 
90453289f6aSNate Lawson         NextOp = Op->Asl.Child;
90553289f6aSNate Lawson         while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
90653289f6aSNate Lawson         {
90753289f6aSNate Lawson             NextOp = NextOp->Asl.Next;
90853289f6aSNate Lawson         }
90953289f6aSNate Lawson         Path = NextOp->Asl.Value.String;
91053289f6aSNate Lawson     }
91153289f6aSNate Lawson     else
91253289f6aSNate Lawson     {
91353289f6aSNate Lawson         Path = Op->Asl.Value.String;
91453289f6aSNate Lawson     }
91553289f6aSNate Lawson 
91653289f6aSNate Lawson     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
917fba7fc7eSJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
918fba7fc7eSJung-uk Kim         "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
91953289f6aSNate Lawson 
92053289f6aSNate Lawson     /*
92153289f6aSNate Lawson      * Lookup the name in the namespace.  Name must exist at this point, or it
92253289f6aSNate Lawson      * is an invalid reference.
92353289f6aSNate Lawson      *
92453289f6aSNate Lawson      * The namespace is also used as a lookup table for references to resource
92553289f6aSNate Lawson      * descriptors and the fields within them.
92653289f6aSNate Lawson      */
92753289f6aSNate Lawson     Gbl_NsLookupCount++;
92853289f6aSNate Lawson 
92953289f6aSNate Lawson     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
93053289f6aSNate Lawson                 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
93153289f6aSNate Lawson     if (ACPI_FAILURE (Status))
93253289f6aSNate Lawson     {
93353289f6aSNate Lawson         if (Status == AE_NOT_FOUND)
93453289f6aSNate Lawson         {
93553289f6aSNate Lawson             /*
93653289f6aSNate Lawson              * We didn't find the name reference by path -- we can qualify this
93753289f6aSNate Lawson              * a little better before we print an error message
93853289f6aSNate Lawson              */
93953289f6aSNate Lawson             if (strlen (Path) == ACPI_NAME_SIZE)
94053289f6aSNate Lawson             {
94153289f6aSNate Lawson                 /* A simple, one-segment ACPI name */
94253289f6aSNate Lawson 
94353289f6aSNate Lawson                 if (LkObjectExists (Path))
94453289f6aSNate Lawson                 {
945fba7fc7eSJung-uk Kim                     /*
946fba7fc7eSJung-uk Kim                      * There exists such a name, but we couldn't get to it
947fba7fc7eSJung-uk Kim                      * from this scope
948fba7fc7eSJung-uk Kim                      */
949fba7fc7eSJung-uk Kim                     AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
950fba7fc7eSJung-uk Kim                         Op->Asl.ExternalName);
95153289f6aSNate Lawson                 }
95253289f6aSNate Lawson                 else
95353289f6aSNate Lawson                 {
95453289f6aSNate Lawson                     /* The name doesn't exist, period */
95553289f6aSNate Lawson 
956fba7fc7eSJung-uk Kim                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
957fba7fc7eSJung-uk Kim                         Op, Op->Asl.ExternalName);
95853289f6aSNate Lawson                 }
95953289f6aSNate Lawson             }
96053289f6aSNate Lawson             else
96153289f6aSNate Lawson             {
96253289f6aSNate Lawson                 /* Check for a fully qualified path */
96353289f6aSNate Lawson 
96453289f6aSNate Lawson                 if (Path[0] == AML_ROOT_PREFIX)
96553289f6aSNate Lawson                 {
96653289f6aSNate Lawson                     /* Gave full path, the object does not exist */
96753289f6aSNate Lawson 
968fba7fc7eSJung-uk Kim                     AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
969fba7fc7eSJung-uk Kim                         Op->Asl.ExternalName);
97053289f6aSNate Lawson                 }
97153289f6aSNate Lawson                 else
97253289f6aSNate Lawson                 {
973fba7fc7eSJung-uk Kim                     /*
974fba7fc7eSJung-uk Kim                      * We can't tell whether it doesn't exist or just
975fba7fc7eSJung-uk Kim                      * can't be reached.
976fba7fc7eSJung-uk Kim                      */
977fba7fc7eSJung-uk Kim                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
978fba7fc7eSJung-uk Kim                         Op->Asl.ExternalName);
97953289f6aSNate Lawson                 }
98053289f6aSNate Lawson             }
98153289f6aSNate Lawson 
98253289f6aSNate Lawson             Status = AE_OK;
98353289f6aSNate Lawson         }
98453289f6aSNate Lawson         return (Status);
98553289f6aSNate Lawson     }
98653289f6aSNate Lawson 
9871a39cfb0SJung-uk Kim     /* Check for a reference vs. name declaration */
9881a39cfb0SJung-uk Kim 
9891a39cfb0SJung-uk Kim     if (!(OpInfo->Flags & AML_NAMED) &&
9901a39cfb0SJung-uk Kim         !(OpInfo->Flags & AML_CREATE))
9911a39cfb0SJung-uk Kim     {
9921a39cfb0SJung-uk Kim         /* This node has been referenced, mark it for reference check */
9931a39cfb0SJung-uk Kim 
9941a39cfb0SJung-uk Kim         Node->Flags |= ANOBJ_IS_REFERENCED;
9951a39cfb0SJung-uk Kim     }
9961a39cfb0SJung-uk Kim 
99753289f6aSNate Lawson     /* Attempt to optimize the NamePath */
99853289f6aSNate Lawson 
99953289f6aSNate Lawson     OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
100053289f6aSNate Lawson 
100153289f6aSNate Lawson     /*
10021a39cfb0SJung-uk Kim      * 1) Dereference an alias (A name reference that is an alias)
10031a39cfb0SJung-uk Kim      *    Aliases are not nested, the alias always points to the final object
100453289f6aSNate Lawson      */
1005fba7fc7eSJung-uk Kim     if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
1006fba7fc7eSJung-uk Kim         (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
100753289f6aSNate Lawson     {
100853289f6aSNate Lawson         /* This node points back to the original PARSEOP_ALIAS */
100953289f6aSNate Lawson 
1010fba7fc7eSJung-uk Kim         NextOp = Node->Op;
101153289f6aSNate Lawson 
101253289f6aSNate Lawson         /* The first child is the alias target op */
101353289f6aSNate Lawson 
101453289f6aSNate Lawson         NextOp = NextOp->Asl.Child;
101553289f6aSNate Lawson 
10161a39cfb0SJung-uk Kim         /* That in turn points back to original target alias node */
101753289f6aSNate Lawson 
101853289f6aSNate Lawson         if (NextOp->Asl.Node)
101953289f6aSNate Lawson         {
102053289f6aSNate Lawson             Node = NextOp->Asl.Node;
102153289f6aSNate Lawson         }
10221a39cfb0SJung-uk Kim 
10231a39cfb0SJung-uk Kim         /* Else - forward reference to alias, will be resolved later */
102453289f6aSNate Lawson     }
102553289f6aSNate Lawson 
10261a39cfb0SJung-uk Kim     /* 2) Check for a reference to a resource descriptor */
102753289f6aSNate Lawson 
10281a39cfb0SJung-uk Kim     if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
102953289f6aSNate Lawson              (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
103053289f6aSNate Lawson     {
103153289f6aSNate Lawson         /*
103253289f6aSNate Lawson          * This was a reference to a field within a resource descriptor.  Extract
103353289f6aSNate Lawson          * the associated field offset (either a bit or byte offset depending on
103453289f6aSNate Lawson          * the field type) and change the named reference into an integer for
103553289f6aSNate Lawson          * AML code generation
103653289f6aSNate Lawson          */
1037fba7fc7eSJung-uk Kim         Temp = Node->Value;
103853289f6aSNate Lawson         if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
103953289f6aSNate Lawson         {
104053289f6aSNate Lawson             Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
104153289f6aSNate Lawson         }
104253289f6aSNate Lawson 
104353289f6aSNate Lawson         /* Perform BitOffset <--> ByteOffset conversion if necessary */
104453289f6aSNate Lawson 
104553289f6aSNate Lawson         switch (Op->Asl.Parent->Asl.AmlOpcode)
104653289f6aSNate Lawson         {
104753289f6aSNate Lawson         case AML_CREATE_FIELD_OP:
104853289f6aSNate Lawson 
104953289f6aSNate Lawson             /* We allow a Byte offset to Bit Offset conversion for this op */
105053289f6aSNate Lawson 
105153289f6aSNate Lawson             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
105253289f6aSNate Lawson             {
105353289f6aSNate Lawson                 /* Simply multiply byte offset times 8 to get bit offset */
105453289f6aSNate Lawson 
105553289f6aSNate Lawson                 Temp = ACPI_MUL_8 (Temp);
105653289f6aSNate Lawson             }
105753289f6aSNate Lawson             break;
105853289f6aSNate Lawson 
105953289f6aSNate Lawson 
106053289f6aSNate Lawson         case AML_CREATE_BIT_FIELD_OP:
106153289f6aSNate Lawson 
106253289f6aSNate Lawson             /* This op requires a Bit Offset */
106353289f6aSNate Lawson 
106453289f6aSNate Lawson             if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
106553289f6aSNate Lawson             {
106653289f6aSNate Lawson                 AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
106753289f6aSNate Lawson             }
106853289f6aSNate Lawson             break;
106953289f6aSNate Lawson 
107053289f6aSNate Lawson 
107153289f6aSNate Lawson         case AML_CREATE_BYTE_FIELD_OP:
107253289f6aSNate Lawson         case AML_CREATE_WORD_FIELD_OP:
107353289f6aSNate Lawson         case AML_CREATE_DWORD_FIELD_OP:
107453289f6aSNate Lawson         case AML_CREATE_QWORD_FIELD_OP:
107553289f6aSNate Lawson         case AML_INDEX_OP:
107653289f6aSNate Lawson 
107753289f6aSNate Lawson             /* These Ops require Byte offsets */
107853289f6aSNate Lawson 
107953289f6aSNate Lawson             if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
108053289f6aSNate Lawson             {
108153289f6aSNate Lawson                 AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
108253289f6aSNate Lawson             }
108353289f6aSNate Lawson             break;
108453289f6aSNate Lawson 
108553289f6aSNate Lawson 
108653289f6aSNate Lawson         default:
108753289f6aSNate Lawson             /* Nothing to do for other opcodes */
108853289f6aSNate Lawson             break;
108953289f6aSNate Lawson         }
109053289f6aSNate Lawson 
109153289f6aSNate Lawson         /* Now convert this node to an integer whose value is the field offset */
109253289f6aSNate Lawson 
1093fba7fc7eSJung-uk Kim         Op->Asl.AmlLength       = 0;
109453289f6aSNate Lawson         Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
109553289f6aSNate Lawson         Op->Asl.Value.Integer   = (UINT64) Temp;
109653289f6aSNate Lawson         Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
109753289f6aSNate Lawson 
109853289f6aSNate Lawson         OpcGenerateAmlOpcode (Op);
109953289f6aSNate Lawson     }
110053289f6aSNate Lawson 
11011a39cfb0SJung-uk Kim     /* 3) Check for a method invocation */
110253289f6aSNate Lawson 
110353289f6aSNate Lawson     else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
110453289f6aSNate Lawson                 (Node->Type == ACPI_TYPE_METHOD) &&
110553289f6aSNate Lawson                 (Op->Asl.Parent) &&
110653289f6aSNate Lawson                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
110753289f6aSNate Lawson 
110853289f6aSNate Lawson                 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
110953289f6aSNate Lawson     {
111053289f6aSNate Lawson 
111153289f6aSNate Lawson         /*
1112fba7fc7eSJung-uk Kim          * A reference to a method within one of these opcodes is not an
1113fba7fc7eSJung-uk Kim          * invocation of the method, it is simply a reference to the method.
1114fba7fc7eSJung-uk Kim          */
1115fba7fc7eSJung-uk Kim         if ((Op->Asl.Parent) &&
1116fba7fc7eSJung-uk Kim            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||
1117fba7fc7eSJung-uk Kim             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||
1118fba7fc7eSJung-uk Kim             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
1119fba7fc7eSJung-uk Kim         {
1120fba7fc7eSJung-uk Kim             return (AE_OK);
1121fba7fc7eSJung-uk Kim         }
1122fba7fc7eSJung-uk Kim         /*
112353289f6aSNate Lawson          * There are two types of method invocation:
1124fba7fc7eSJung-uk Kim          * 1) Invocation with arguments -- the parser recognizes this
1125fba7fc7eSJung-uk Kim          *    as a METHODCALL.
1126fba7fc7eSJung-uk Kim          * 2) Invocation with no arguments --the parser cannot determine that
1127fba7fc7eSJung-uk Kim          *    this is a method invocation, therefore we have to figure it out
1128fba7fc7eSJung-uk Kim          *    here.
112953289f6aSNate Lawson          */
113053289f6aSNate Lawson         if (Node->Type != ACPI_TYPE_METHOD)
113153289f6aSNate Lawson         {
1132fba7fc7eSJung-uk Kim             sprintf (MsgBuffer, "%s is a %s",
1133fba7fc7eSJung-uk Kim                     Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
113453289f6aSNate Lawson 
113553289f6aSNate Lawson             AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
113653289f6aSNate Lawson             return (AE_OK);
113753289f6aSNate Lawson         }
113853289f6aSNate Lawson 
113953289f6aSNate Lawson         /* Save the method node in the caller's op */
114053289f6aSNate Lawson 
114153289f6aSNate Lawson         Op->Asl.Node = Node;
114253289f6aSNate Lawson         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
114353289f6aSNate Lawson         {
114453289f6aSNate Lawson             return (AE_OK);
114553289f6aSNate Lawson         }
114653289f6aSNate Lawson 
114753289f6aSNate Lawson         /*
114853289f6aSNate Lawson          * This is a method invocation, with or without arguments.
114953289f6aSNate Lawson          * Count the number of arguments, each appears as a child
115053289f6aSNate Lawson          * under the parent node
115153289f6aSNate Lawson          */
115253289f6aSNate Lawson         Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
115353289f6aSNate Lawson         UtSetParseOpName (Op);
115453289f6aSNate Lawson 
115553289f6aSNate Lawson         PassedArgs = 0;
115653289f6aSNate Lawson         NextOp     = Op->Asl.Child;
115753289f6aSNate Lawson 
115853289f6aSNate Lawson         while (NextOp)
115953289f6aSNate Lawson         {
116053289f6aSNate Lawson             PassedArgs++;
116153289f6aSNate Lawson             NextOp = NextOp->Asl.Next;
116253289f6aSNate Lawson         }
116353289f6aSNate Lawson 
1164fba7fc7eSJung-uk Kim         if (Node->Value != ASL_EXTERNAL_METHOD)
116553289f6aSNate Lawson         {
116653289f6aSNate Lawson             /*
116753289f6aSNate Lawson              * Check the parsed arguments with the number expected by the
116853289f6aSNate Lawson              * method declaration itself
116953289f6aSNate Lawson              */
1170fba7fc7eSJung-uk Kim             if (PassedArgs != Node->Value)
117153289f6aSNate Lawson             {
1172a88e22b7SJung-uk Kim                 sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
1173fba7fc7eSJung-uk Kim                             Node->Value);
117453289f6aSNate Lawson 
1175fba7fc7eSJung-uk Kim                 if (PassedArgs < Node->Value)
117653289f6aSNate Lawson                 {
117753289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
117853289f6aSNate Lawson                 }
117953289f6aSNate Lawson                 else
118053289f6aSNate Lawson                 {
118153289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
118253289f6aSNate Lawson                 }
118353289f6aSNate Lawson             }
118453289f6aSNate Lawson         }
118553289f6aSNate Lawson     }
118653289f6aSNate Lawson 
11871a39cfb0SJung-uk Kim     /* 4) Check for an ASL Field definition */
1188fba7fc7eSJung-uk Kim 
118953289f6aSNate Lawson     else if ((Op->Asl.Parent) &&
119053289f6aSNate Lawson             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
119153289f6aSNate Lawson              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
119253289f6aSNate Lawson     {
119353289f6aSNate Lawson         /*
119453289f6aSNate Lawson          * Offset checking for fields.  If the parent operation region has a
119553289f6aSNate Lawson          * constant length (known at compile time), we can check fields
119653289f6aSNate Lawson          * defined in that region against the region length.  This will catch
119753289f6aSNate Lawson          * fields and field units that cannot possibly fit within the region.
119853289f6aSNate Lawson          *
119953289f6aSNate Lawson          * Note: Index fields do not directly reference an operation region,
120053289f6aSNate Lawson          * thus they are not included in this check.
120153289f6aSNate Lawson          */
120253289f6aSNate Lawson         if (Op == Op->Asl.Parent->Asl.Child)
120353289f6aSNate Lawson         {
120453289f6aSNate Lawson             /*
120553289f6aSNate Lawson              * This is the first child of the field node, which is
120653289f6aSNate Lawson              * the name of the region.  Get the parse node for the
120753289f6aSNate Lawson              * region -- which contains the length of the region.
120853289f6aSNate Lawson              */
1209fba7fc7eSJung-uk Kim             OwningOp = Node->Op;
1210fba7fc7eSJung-uk Kim             Op->Asl.Parent->Asl.ExtraValue =
1211fba7fc7eSJung-uk Kim                 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
121253289f6aSNate Lawson 
121353289f6aSNate Lawson             /* Examine the field access width */
121453289f6aSNate Lawson 
121553289f6aSNate Lawson             switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
121653289f6aSNate Lawson             {
121753289f6aSNate Lawson             case AML_FIELD_ACCESS_ANY:
121853289f6aSNate Lawson             case AML_FIELD_ACCESS_BYTE:
121953289f6aSNate Lawson             case AML_FIELD_ACCESS_BUFFER:
122053289f6aSNate Lawson             default:
122153289f6aSNate Lawson                 MinimumLength = 1;
122253289f6aSNate Lawson                 break;
122353289f6aSNate Lawson 
122453289f6aSNate Lawson             case AML_FIELD_ACCESS_WORD:
122553289f6aSNate Lawson                 MinimumLength = 2;
122653289f6aSNate Lawson                 break;
122753289f6aSNate Lawson 
122853289f6aSNate Lawson             case AML_FIELD_ACCESS_DWORD:
122953289f6aSNate Lawson                 MinimumLength = 4;
123053289f6aSNate Lawson                 break;
123153289f6aSNate Lawson 
123253289f6aSNate Lawson             case AML_FIELD_ACCESS_QWORD:
123353289f6aSNate Lawson                 MinimumLength = 8;
123453289f6aSNate Lawson                 break;
123553289f6aSNate Lawson             }
123653289f6aSNate Lawson 
123753289f6aSNate Lawson             /*
123853289f6aSNate Lawson              * Is the region at least as big as the access width?
123953289f6aSNate Lawson              * Note: DataTableRegions have 0 length
124053289f6aSNate Lawson              */
124153289f6aSNate Lawson             if (((UINT32) OwningOp->Asl.Value.Integer) &&
124253289f6aSNate Lawson                 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
124353289f6aSNate Lawson             {
124453289f6aSNate Lawson                 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
124553289f6aSNate Lawson             }
124653289f6aSNate Lawson 
124753289f6aSNate Lawson             /*
124853289f6aSNate Lawson              * Check EC/CMOS/SMBUS fields to make sure that the correct
124953289f6aSNate Lawson              * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
125053289f6aSNate Lawson              */
125153289f6aSNate Lawson             SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
125253289f6aSNate Lawson             switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
125353289f6aSNate Lawson             {
125453289f6aSNate Lawson             case REGION_EC:
125553289f6aSNate Lawson             case REGION_CMOS:
125653289f6aSNate Lawson 
125753289f6aSNate Lawson                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
125853289f6aSNate Lawson                 {
125953289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
126053289f6aSNate Lawson                 }
126153289f6aSNate Lawson                 break;
126253289f6aSNate Lawson 
126353289f6aSNate Lawson             case REGION_SMBUS:
1264d6dd1baeSJung-uk Kim             case REGION_IPMI:
126553289f6aSNate Lawson 
126653289f6aSNate Lawson                 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
126753289f6aSNate Lawson                 {
126853289f6aSNate Lawson                     AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
126953289f6aSNate Lawson                 }
127053289f6aSNate Lawson                 break;
127153289f6aSNate Lawson 
127253289f6aSNate Lawson             default:
127353289f6aSNate Lawson 
127453289f6aSNate Lawson                 /* Nothing to do for other address spaces */
127553289f6aSNate Lawson                 break;
127653289f6aSNate Lawson             }
127753289f6aSNate Lawson         }
127853289f6aSNate Lawson         else
127953289f6aSNate Lawson         {
128053289f6aSNate Lawson             /*
128153289f6aSNate Lawson              * This is one element of the field list.  Check to make sure
128253289f6aSNate Lawson              * that it does not go beyond the end of the parent operation region.
128353289f6aSNate Lawson              *
128453289f6aSNate Lawson              * In the code below:
128553289f6aSNate Lawson              *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
128653289f6aSNate Lawson              *    Op->Asl.ExtraValue                  - Field start offset (bits)
128753289f6aSNate Lawson              *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
128853289f6aSNate Lawson              *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
128953289f6aSNate Lawson              */
129053289f6aSNate Lawson             if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
129153289f6aSNate Lawson             {
129253289f6aSNate Lawson                 LkCheckFieldRange (Op,
129353289f6aSNate Lawson                             Op->Asl.Parent->Asl.ExtraValue,
129453289f6aSNate Lawson                             Op->Asl.ExtraValue,
129553289f6aSNate Lawson                             (UINT32) Op->Asl.Child->Asl.Value.Integer,
129653289f6aSNate Lawson                             Op->Asl.Child->Asl.ExtraValue);
129753289f6aSNate Lawson             }
129853289f6aSNate Lawson         }
129953289f6aSNate Lawson     }
130053289f6aSNate Lawson 
130153289f6aSNate Lawson     Op->Asl.Node = Node;
130253289f6aSNate Lawson     return (Status);
130353289f6aSNate Lawson }
130453289f6aSNate Lawson 
130553289f6aSNate Lawson 
130653289f6aSNate Lawson /*******************************************************************************
130753289f6aSNate Lawson  *
130853289f6aSNate Lawson  * FUNCTION:    LkNamespaceLocateEnd
130953289f6aSNate Lawson  *
131053289f6aSNate Lawson  * PARAMETERS:  ASL_WALK_CALLBACK
131153289f6aSNate Lawson  *
131253289f6aSNate Lawson  * RETURN:      Status
131353289f6aSNate Lawson  *
131453289f6aSNate Lawson  * DESCRIPTION: Ascending callback used during cross reference.  We only
131553289f6aSNate Lawson  *              need to worry about scope management here.
131653289f6aSNate Lawson  *
131753289f6aSNate Lawson  ******************************************************************************/
131853289f6aSNate Lawson 
1319fba7fc7eSJung-uk Kim static ACPI_STATUS
132053289f6aSNate Lawson LkNamespaceLocateEnd (
132153289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
132253289f6aSNate Lawson     UINT32                  Level,
132353289f6aSNate Lawson     void                    *Context)
132453289f6aSNate Lawson {
132553289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
132653289f6aSNate Lawson     const ACPI_OPCODE_INFO  *OpInfo;
132753289f6aSNate Lawson 
132853289f6aSNate Lawson 
13291a39cfb0SJung-uk Kim     ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
133053289f6aSNate Lawson 
133153289f6aSNate Lawson 
133253289f6aSNate Lawson     /* We are only interested in opcodes that have an associated name */
133353289f6aSNate Lawson 
133453289f6aSNate Lawson     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
133553289f6aSNate Lawson     if (!(OpInfo->Flags & AML_NAMED))
133653289f6aSNate Lawson     {
133753289f6aSNate Lawson         return (AE_OK);
133853289f6aSNate Lawson     }
133953289f6aSNate Lawson 
134053289f6aSNate Lawson     /* Not interested in name references, we did not open a scope for them */
134153289f6aSNate Lawson 
134253289f6aSNate Lawson     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
134353289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
134453289f6aSNate Lawson         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
134553289f6aSNate Lawson     {
134653289f6aSNate Lawson         return (AE_OK);
134753289f6aSNate Lawson     }
134853289f6aSNate Lawson 
134953289f6aSNate Lawson     /* Pop the scope stack if necessary */
135053289f6aSNate Lawson 
135153289f6aSNate Lawson     if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
135253289f6aSNate Lawson     {
135353289f6aSNate Lawson 
135453289f6aSNate Lawson         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
135553289f6aSNate Lawson             "%s: Popping scope for Op %p\n",
135653289f6aSNate Lawson             AcpiUtGetTypeName (OpInfo->ObjectType), Op));
135753289f6aSNate Lawson 
1358fba7fc7eSJung-uk Kim         (void) AcpiDsScopeStackPop (WalkState);
135953289f6aSNate Lawson     }
136053289f6aSNate Lawson 
136153289f6aSNate Lawson     return (AE_OK);
136253289f6aSNate Lawson }
136353289f6aSNate Lawson 
136453289f6aSNate Lawson 
1365