1 /******************************************************************************
2  *
3  * Module Name: aslnamesp - Namespace output file generation
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "aslcompiler.h"
45 #include "aslcompiler.y.h"
46 #include "acnamesp.h"
47 
48 
49 #define _COMPONENT          ACPI_COMPILER
50         ACPI_MODULE_NAME    ("aslnamesp")
51 
52 /* Local prototypes */
53 
54 static ACPI_STATUS
55 NsDoOneNamespaceObject (
56     ACPI_HANDLE             ObjHandle,
57     UINT32                  Level,
58     void                    *Context,
59     void                    **ReturnValue);
60 
61 static ACPI_STATUS
62 NsDoOnePathname (
63     ACPI_HANDLE             ObjHandle,
64     UINT32                  Level,
65     void                    *Context,
66     void                    **ReturnValue);
67 
68 
69 /*******************************************************************************
70  *
71  * FUNCTION:    NsSetupNamespaceListing
72  *
73  * PARAMETERS:  Handle          - local file handle
74  *
75  * RETURN:      None
76  *
77  * DESCRIPTION: Set the namespace output file to the input handle
78  *
79  ******************************************************************************/
80 
81 void
82 NsSetupNamespaceListing (
83     void                    *Handle)
84 {
85 
86     Gbl_NsOutputFlag = TRUE;
87     Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
88 }
89 
90 
91 /*******************************************************************************
92  *
93  * FUNCTION:    NsDisplayNamespace
94  *
95  * PARAMETERS:  None
96  *
97  * RETURN:      Status
98  *
99  * DESCRIPTION: Walk the namespace an display information about each node
100  *              in the tree. Information is written to the optional
101  *              namespace output file.
102  *
103  ******************************************************************************/
104 
105 ACPI_STATUS
106 NsDisplayNamespace (
107     void)
108 {
109     ACPI_STATUS             Status;
110 
111 
112     if (!Gbl_NsOutputFlag)
113     {
114         return (AE_OK);
115     }
116 
117     Gbl_NumNamespaceObjects = 0;
118 
119     /* File header */
120 
121     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
122     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
123 
124     /* Walk entire namespace from the root */
125 
126     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
127         ACPI_UINT32_MAX, FALSE, NsDoOneNamespaceObject, NULL,
128         NULL, NULL);
129 
130     /* Print the full pathname for each namespace node */
131 
132     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
133 
134     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
135         ACPI_UINT32_MAX, FALSE, NsDoOnePathname, NULL,
136         NULL, NULL);
137 
138     return (Status);
139 }
140 
141 
142 /*******************************************************************************
143  *
144  * FUNCTION:    NsDoOneNamespaceObject
145  *
146  * PARAMETERS:  ACPI_WALK_CALLBACK
147  *
148  * RETURN:      Status
149  *
150  * DESCRIPTION: Dump a namespace object to the namespace output file.
151  *              Called during the walk of the namespace to dump all objects.
152  *
153  ******************************************************************************/
154 
155 static ACPI_STATUS
156 NsDoOneNamespaceObject (
157     ACPI_HANDLE             ObjHandle,
158     UINT32                  Level,
159     void                    *Context,
160     void                    **ReturnValue)
161 {
162     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
163     ACPI_OPERAND_OBJECT     *ObjDesc;
164     ACPI_PARSE_OBJECT       *Op;
165 
166 
167     Gbl_NumNamespaceObjects++;
168 
169     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
170         Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
171         &Node->Name, AcpiUtGetTypeName (Node->Type));
172 
173     Op = Node->Op;
174     ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
175 
176     if (!Op)
177     {
178         FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
179         return (AE_OK);
180     }
181 
182 
183     if ((ObjDesc) &&
184         (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
185     {
186         switch (Node->Type)
187         {
188         case ACPI_TYPE_INTEGER:
189 
190             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
191                 "       [Initial Value   0x%8.8X%8.8X]",
192                 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
193             break;
194 
195         case ACPI_TYPE_STRING:
196 
197             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
198                 "        [Initial Value   \"%s\"]",
199                 ObjDesc->String.Pointer);
200             break;
201 
202         default:
203 
204             /* Nothing to do for other types */
205 
206             break;
207         }
208 
209     }
210     else
211     {
212         switch (Node->Type)
213         {
214         case ACPI_TYPE_INTEGER:
215 
216             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
217             {
218                 Op = Op->Asl.Child;
219             }
220 
221             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
222                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
223             {
224                 Op = Op->Asl.Next;
225             }
226 
227             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
228                 "       [Initial Value   0x%8.8X%8.8X]",
229                 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
230             break;
231 
232         case ACPI_TYPE_STRING:
233 
234             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
235             {
236                 Op = Op->Asl.Child;
237             }
238 
239             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
240                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
241             {
242                 Op = Op->Asl.Next;
243             }
244 
245             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
246                 "        [Initial Value   \"%s\"]",
247                 Op->Asl.Value.String);
248             break;
249 
250         case ACPI_TYPE_LOCAL_REGION_FIELD:
251 
252             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
253                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
254             {
255                 Op = Op->Asl.Child;
256             }
257 
258             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
259                 "   [Offset 0x%04X   Length 0x%04X bits]",
260                 Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
261             break;
262 
263         case ACPI_TYPE_BUFFER_FIELD:
264 
265             switch (Op->Asl.ParseOpcode)
266             {
267             case PARSEOP_CREATEBYTEFIELD:
268 
269                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
270                 break;
271 
272             case PARSEOP_CREATEDWORDFIELD:
273 
274                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
275                 break;
276 
277             case PARSEOP_CREATEQWORDFIELD:
278 
279                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
280                 break;
281 
282             case PARSEOP_CREATEWORDFIELD:
283 
284                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
285                 break;
286 
287             case PARSEOP_CREATEBITFIELD:
288 
289                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
290                 break;
291 
292             case PARSEOP_CREATEFIELD:
293 
294                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
295                 break;
296 
297             default:
298 
299                 break;
300 
301             }
302             break;
303 
304         case ACPI_TYPE_PACKAGE:
305 
306             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
307             {
308                 Op = Op->Asl.Child;
309             }
310 
311             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
312                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
313             {
314                 Op = Op->Asl.Next;
315             }
316 
317             Op = Op->Asl.Child;
318 
319             if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
320                 (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
321             {
322                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
323                     "       [Initial Length  0x%.2X elements]",
324                     Op->Asl.Value.Integer);
325             }
326             break;
327 
328         case ACPI_TYPE_BUFFER:
329 
330             if (Op->Asl.ParseOpcode == PARSEOP_NAME)
331             {
332                 Op = Op->Asl.Child;
333             }
334 
335             if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
336                 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
337             {
338                 Op = Op->Asl.Next;
339             }
340 
341             Op = Op->Asl.Child;
342 
343             if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
344             {
345                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
346                     "        [Initial Length  0x%.2X bytes]",
347                     Op->Asl.Value.Integer);
348             }
349             break;
350 
351         case ACPI_TYPE_METHOD:
352 
353             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
354                 "        [Code Length     0x%.4X bytes]",
355                 Op->Asl.AmlSubtreeLength);
356             break;
357 
358         case ACPI_TYPE_LOCAL_RESOURCE:
359 
360             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
361                 "  [Desc Offset     0x%.4X Bytes]", Node->Value);
362             break;
363 
364         case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
365 
366             FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
367                 "   [Field Offset    0x%.4X Bits 0x%.4X Bytes] ",
368                 Node->Value, Node->Value / 8);
369 
370             if (Node->Flags & ANOBJ_IS_REFERENCED)
371             {
372                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
373                     "Referenced");
374             }
375             else
376             {
377                 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
378                     "Name not referenced");
379             }
380             break;
381 
382         default:
383 
384             /* Nothing to do for other types */
385 
386             break;
387         }
388     }
389 
390     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
391     return (AE_OK);
392 }
393 
394 
395 /*******************************************************************************
396  *
397  * FUNCTION:    NsDoOnePathname
398  *
399  * PARAMETERS:  ACPI_WALK_CALLBACK
400  *
401  * RETURN:      Status
402  *
403  * DESCRIPTION: Print the full pathname for a namespace node.
404  *
405  ******************************************************************************/
406 
407 static ACPI_STATUS
408 NsDoOnePathname (
409     ACPI_HANDLE             ObjHandle,
410     UINT32                  Level,
411     void                    *Context,
412     void                    **ReturnValue)
413 {
414     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
415     ACPI_STATUS             Status;
416     ACPI_BUFFER             TargetPath;
417 
418 
419     TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
420     Status = AcpiNsHandleToPathname (Node, &TargetPath, FALSE);
421     if (ACPI_FAILURE (Status))
422     {
423         return (Status);
424     }
425 
426     FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
427     ACPI_FREE (TargetPath.Pointer);
428     return (AE_OK);
429 }
430