xref: /freebsd/sys/contrib/dev/acpica/common/dmextern.c (revision a9d8d09c46ec699e45f3fd46ca9abcf02e5baca9)
1f556842eSJung-uk Kim /******************************************************************************
2f556842eSJung-uk Kim  *
3f556842eSJung-uk Kim  * Module Name: dmextern - Support for External() ASL statements
4f556842eSJung-uk Kim  *
5f556842eSJung-uk Kim  *****************************************************************************/
6f556842eSJung-uk Kim 
7d244b227SJung-uk Kim /*
8efcc2a30SJung-uk Kim  * Copyright (C) 2000 - 2013, Intel Corp.
9f556842eSJung-uk Kim  * All rights reserved.
10f556842eSJung-uk Kim  *
11d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
13d244b227SJung-uk Kim  * are met:
14d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16d244b227SJung-uk Kim  *    without modification.
17d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21d244b227SJung-uk Kim  *    binary redistribution.
22d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24d244b227SJung-uk Kim  *    from this software without specific prior written permission.
25f556842eSJung-uk Kim  *
26d244b227SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28d244b227SJung-uk Kim  * Software Foundation.
29f556842eSJung-uk Kim  *
30d244b227SJung-uk Kim  * NO WARRANTY
31d244b227SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32d244b227SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33d244b227SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34d244b227SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35d244b227SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36d244b227SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37d244b227SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38d244b227SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39d244b227SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40d244b227SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41d244b227SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42d244b227SJung-uk Kim  */
43f556842eSJung-uk Kim 
44f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
45f556842eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
46f556842eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
47f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
48f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h>
499c48c75eSJung-uk Kim #include <stdio.h>
50f556842eSJung-uk Kim 
51f556842eSJung-uk Kim 
52f556842eSJung-uk Kim /*
53f556842eSJung-uk Kim  * This module is used for application-level code (iASL disassembler) only.
54f556842eSJung-uk Kim  *
55f556842eSJung-uk Kim  * It contains the code to create and emit any necessary External() ASL
56f556842eSJung-uk Kim  * statements for the module being disassembled.
57f556842eSJung-uk Kim  */
58f556842eSJung-uk Kim #define _COMPONENT          ACPI_CA_DISASSEMBLER
59f556842eSJung-uk Kim         ACPI_MODULE_NAME    ("dmextern")
60f556842eSJung-uk Kim 
61f556842eSJung-uk Kim 
62f556842eSJung-uk Kim /*
63f556842eSJung-uk Kim  * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
64f556842eSJung-uk Kim  * ObjectTypeKeyword. Used to generate typed external declarations
65f556842eSJung-uk Kim  */
66f556842eSJung-uk Kim static const char           *AcpiGbl_DmTypeNames[] =
67f556842eSJung-uk Kim {
68f556842eSJung-uk Kim     /* 00 */ "",                    /* Type ANY */
69f556842eSJung-uk Kim     /* 01 */ ", IntObj",
70f556842eSJung-uk Kim     /* 02 */ ", StrObj",
71f556842eSJung-uk Kim     /* 03 */ ", BuffObj",
72f556842eSJung-uk Kim     /* 04 */ ", PkgObj",
73f556842eSJung-uk Kim     /* 05 */ ", FieldUnitObj",
74f556842eSJung-uk Kim     /* 06 */ ", DeviceObj",
75f556842eSJung-uk Kim     /* 07 */ ", EventObj",
76f556842eSJung-uk Kim     /* 08 */ ", MethodObj",
77f556842eSJung-uk Kim     /* 09 */ ", MutexObj",
78f556842eSJung-uk Kim     /* 10 */ ", OpRegionObj",
79f556842eSJung-uk Kim     /* 11 */ ", PowerResObj",
80f556842eSJung-uk Kim     /* 12 */ ", ProcessorObj",
81f556842eSJung-uk Kim     /* 13 */ ", ThermalZoneObj",
82f556842eSJung-uk Kim     /* 14 */ ", BuffFieldObj",
83f556842eSJung-uk Kim     /* 15 */ ", DDBHandleObj",
84f556842eSJung-uk Kim     /* 16 */ "",                    /* Debug object */
85f556842eSJung-uk Kim     /* 17 */ ", FieldUnitObj",
86f556842eSJung-uk Kim     /* 18 */ ", FieldUnitObj",
87f556842eSJung-uk Kim     /* 19 */ ", FieldUnitObj"
88f556842eSJung-uk Kim };
89f556842eSJung-uk Kim 
90f556842eSJung-uk Kim 
91f556842eSJung-uk Kim /* Local prototypes */
92f556842eSJung-uk Kim 
93f556842eSJung-uk Kim static const char *
94f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
95f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type);
96f556842eSJung-uk Kim 
97f556842eSJung-uk Kim static char *
98f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
99f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
100f556842eSJung-uk Kim     char                    *Path);
101f556842eSJung-uk Kim 
102f556842eSJung-uk Kim 
103f556842eSJung-uk Kim /*******************************************************************************
104f556842eSJung-uk Kim  *
105f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetObjectTypeName
106f556842eSJung-uk Kim  *
107f556842eSJung-uk Kim  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
108f556842eSJung-uk Kim  *
109f556842eSJung-uk Kim  * RETURN:      Pointer to a string
110f556842eSJung-uk Kim  *
111f556842eSJung-uk Kim  * DESCRIPTION: Map an object type to the ASL object type string.
112f556842eSJung-uk Kim  *
113f556842eSJung-uk Kim  ******************************************************************************/
114f556842eSJung-uk Kim 
115f556842eSJung-uk Kim static const char *
116f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
117f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type)
118f556842eSJung-uk Kim {
119f556842eSJung-uk Kim 
120f556842eSJung-uk Kim     if (Type == ACPI_TYPE_LOCAL_SCOPE)
121f556842eSJung-uk Kim     {
122f556842eSJung-uk Kim         Type = ACPI_TYPE_DEVICE;
123f556842eSJung-uk Kim     }
124f556842eSJung-uk Kim 
125f556842eSJung-uk Kim     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
126f556842eSJung-uk Kim     {
127f556842eSJung-uk Kim         return ("");
128f556842eSJung-uk Kim     }
129f556842eSJung-uk Kim 
130f556842eSJung-uk Kim     return (AcpiGbl_DmTypeNames[Type]);
131f556842eSJung-uk Kim }
132f556842eSJung-uk Kim 
133f556842eSJung-uk Kim 
134f556842eSJung-uk Kim /*******************************************************************************
135f556842eSJung-uk Kim  *
136f556842eSJung-uk Kim  * FUNCTION:    AcpiDmNormalizeParentPrefix
137f556842eSJung-uk Kim  *
138f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Parse op
139f556842eSJung-uk Kim  *              Path                - Path with parent prefix
140f556842eSJung-uk Kim  *
141f556842eSJung-uk Kim  * RETURN:      The full pathname to the object (from the namespace root)
142f556842eSJung-uk Kim  *
143f556842eSJung-uk Kim  * DESCRIPTION: Returns the full pathname of a path with parent prefix
144f556842eSJung-uk Kim  *              The caller must free the fullpath returned.
145f556842eSJung-uk Kim  *
146f556842eSJung-uk Kim  ******************************************************************************/
147f556842eSJung-uk Kim 
148f556842eSJung-uk Kim static char *
149f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
150f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
151f556842eSJung-uk Kim     char                    *Path)
152f556842eSJung-uk Kim {
153f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
154f556842eSJung-uk Kim     char                    *Fullpath;
155f556842eSJung-uk Kim     char                    *ParentPath;
156f556842eSJung-uk Kim     ACPI_SIZE               Length;
157ed17e06eSJung-uk Kim     UINT32                  Index = 0;
158f556842eSJung-uk Kim 
159f556842eSJung-uk Kim 
160ed17e06eSJung-uk Kim     if (!Op)
161ed17e06eSJung-uk Kim     {
162ed17e06eSJung-uk Kim         return (NULL);
163ed17e06eSJung-uk Kim     }
164f556842eSJung-uk Kim 
165ed17e06eSJung-uk Kim     /* Search upwards in the parse tree until we reach the next namespace node */
166ed17e06eSJung-uk Kim 
167ed17e06eSJung-uk Kim     Op = Op->Common.Parent;
168f556842eSJung-uk Kim     while (Op)
169f556842eSJung-uk Kim     {
170f556842eSJung-uk Kim         if (Op->Common.Node)
171f556842eSJung-uk Kim         {
172f556842eSJung-uk Kim             break;
173f556842eSJung-uk Kim         }
174f556842eSJung-uk Kim 
175f556842eSJung-uk Kim         Op = Op->Common.Parent;
176f556842eSJung-uk Kim     }
177f556842eSJung-uk Kim 
178f556842eSJung-uk Kim     if (!Op)
179f556842eSJung-uk Kim     {
180f556842eSJung-uk Kim         return (NULL);
181f556842eSJung-uk Kim     }
182f556842eSJung-uk Kim 
183f556842eSJung-uk Kim     /*
184f556842eSJung-uk Kim      * Find the actual parent node for the reference:
185f556842eSJung-uk Kim      * Remove all carat prefixes from the input path.
186f556842eSJung-uk Kim      * There may be multiple parent prefixes (For example, ^^^M000)
187f556842eSJung-uk Kim      */
188f556842eSJung-uk Kim     Node = Op->Common.Node;
189f556842eSJung-uk Kim     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
190f556842eSJung-uk Kim     {
191a88e22b7SJung-uk Kim         Node = Node->Parent;
192f556842eSJung-uk Kim         Path++;
193f556842eSJung-uk Kim     }
194f556842eSJung-uk Kim 
195f556842eSJung-uk Kim     if (!Node)
196f556842eSJung-uk Kim     {
197f556842eSJung-uk Kim         return (NULL);
198f556842eSJung-uk Kim     }
199f556842eSJung-uk Kim 
200f556842eSJung-uk Kim     /* Get the full pathname for the parent node */
201f556842eSJung-uk Kim 
202f556842eSJung-uk Kim     ParentPath = AcpiNsGetExternalPathname (Node);
203f556842eSJung-uk Kim     if (!ParentPath)
204f556842eSJung-uk Kim     {
205f556842eSJung-uk Kim         return (NULL);
206f556842eSJung-uk Kim     }
207f556842eSJung-uk Kim 
208f556842eSJung-uk Kim     Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
2098c8be05fSJung-uk Kim     if (ParentPath[1])
2108c8be05fSJung-uk Kim     {
2118c8be05fSJung-uk Kim         /*
2128c8be05fSJung-uk Kim          * If ParentPath is not just a simple '\', increment the length
2138c8be05fSJung-uk Kim          * for the required dot separator (ParentPath.Path)
2148c8be05fSJung-uk Kim          */
2158c8be05fSJung-uk Kim         Length++;
216ed17e06eSJung-uk Kim 
217ed17e06eSJung-uk Kim         /* For External() statements, we do not want a leading '\' */
218ed17e06eSJung-uk Kim 
219ed17e06eSJung-uk Kim         if (*ParentPath == AML_ROOT_PREFIX)
220ed17e06eSJung-uk Kim         {
221ed17e06eSJung-uk Kim             Index = 1;
222ed17e06eSJung-uk Kim         }
2238c8be05fSJung-uk Kim     }
2248c8be05fSJung-uk Kim 
225f556842eSJung-uk Kim     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
226f556842eSJung-uk Kim     if (!Fullpath)
227f556842eSJung-uk Kim     {
228f556842eSJung-uk Kim         goto Cleanup;
229f556842eSJung-uk Kim     }
230f556842eSJung-uk Kim 
231f556842eSJung-uk Kim     /*
232f556842eSJung-uk Kim      * Concatenate parent fullpath and path. For example,
233f556842eSJung-uk Kim      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
234f556842eSJung-uk Kim      *
235f556842eSJung-uk Kim      * Copy the parent path
236f556842eSJung-uk Kim      */
237ed17e06eSJung-uk Kim     ACPI_STRCPY (Fullpath, &ParentPath[Index]);
238f556842eSJung-uk Kim 
239f38b0f21SJung-uk Kim     /*
240f38b0f21SJung-uk Kim      * Add dot separator
241f38b0f21SJung-uk Kim      * (don't need dot if parent fullpath is a single backslash)
242f38b0f21SJung-uk Kim      */
243f556842eSJung-uk Kim     if (ParentPath[1])
244f556842eSJung-uk Kim     {
245f556842eSJung-uk Kim         ACPI_STRCAT (Fullpath, ".");
246f556842eSJung-uk Kim     }
247f556842eSJung-uk Kim 
248f556842eSJung-uk Kim     /* Copy child path (carat parent prefix(es) were skipped above) */
249f556842eSJung-uk Kim 
250f556842eSJung-uk Kim     ACPI_STRCAT (Fullpath, Path);
251f556842eSJung-uk Kim 
252f556842eSJung-uk Kim Cleanup:
253f556842eSJung-uk Kim     ACPI_FREE (ParentPath);
254f556842eSJung-uk Kim     return (Fullpath);
255f556842eSJung-uk Kim }
256f556842eSJung-uk Kim 
257f556842eSJung-uk Kim 
258f556842eSJung-uk Kim /*******************************************************************************
259f556842eSJung-uk Kim  *
260709fac06SJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalFileList
261709fac06SJung-uk Kim  *
262709fac06SJung-uk Kim  * PARAMETERS:  PathList            - Single path or list separated by comma
263709fac06SJung-uk Kim  *
264709fac06SJung-uk Kim  * RETURN:      None
265709fac06SJung-uk Kim  *
266709fac06SJung-uk Kim  * DESCRIPTION: Add external files to global list
267709fac06SJung-uk Kim  *
268709fac06SJung-uk Kim  ******************************************************************************/
269709fac06SJung-uk Kim 
270709fac06SJung-uk Kim ACPI_STATUS
271709fac06SJung-uk Kim AcpiDmAddToExternalFileList (
272709fac06SJung-uk Kim     char                    *PathList)
273709fac06SJung-uk Kim {
274709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *ExternalFile;
275709fac06SJung-uk Kim     char                    *Path;
276709fac06SJung-uk Kim     char                    *TmpPath;
277709fac06SJung-uk Kim 
278709fac06SJung-uk Kim 
279709fac06SJung-uk Kim     if (!PathList)
280709fac06SJung-uk Kim     {
281709fac06SJung-uk Kim         return (AE_OK);
282709fac06SJung-uk Kim     }
283709fac06SJung-uk Kim 
284709fac06SJung-uk Kim     Path = strtok (PathList, ",");
285709fac06SJung-uk Kim 
286709fac06SJung-uk Kim     while (Path)
287709fac06SJung-uk Kim     {
288709fac06SJung-uk Kim         TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1);
289709fac06SJung-uk Kim         if (!TmpPath)
290709fac06SJung-uk Kim         {
291709fac06SJung-uk Kim             return (AE_NO_MEMORY);
292709fac06SJung-uk Kim         }
293709fac06SJung-uk Kim 
294709fac06SJung-uk Kim         ACPI_STRCPY (TmpPath, Path);
295709fac06SJung-uk Kim 
296709fac06SJung-uk Kim         ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
297709fac06SJung-uk Kim         if (!ExternalFile)
298709fac06SJung-uk Kim         {
299709fac06SJung-uk Kim             ACPI_FREE (TmpPath);
300709fac06SJung-uk Kim             return (AE_NO_MEMORY);
301709fac06SJung-uk Kim         }
302709fac06SJung-uk Kim 
303709fac06SJung-uk Kim         ExternalFile->Path = TmpPath;
304709fac06SJung-uk Kim 
305709fac06SJung-uk Kim         if (AcpiGbl_ExternalFileList)
306709fac06SJung-uk Kim         {
307709fac06SJung-uk Kim             ExternalFile->Next = AcpiGbl_ExternalFileList;
308709fac06SJung-uk Kim         }
309709fac06SJung-uk Kim 
310709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = ExternalFile;
311709fac06SJung-uk Kim         Path = strtok (NULL, ",");
312709fac06SJung-uk Kim     }
313709fac06SJung-uk Kim 
314709fac06SJung-uk Kim     return (AE_OK);
315709fac06SJung-uk Kim }
316709fac06SJung-uk Kim 
317709fac06SJung-uk Kim 
318709fac06SJung-uk Kim /*******************************************************************************
319709fac06SJung-uk Kim  *
320709fac06SJung-uk Kim  * FUNCTION:    AcpiDmClearExternalFileList
321709fac06SJung-uk Kim  *
322709fac06SJung-uk Kim  * PARAMETERS:  None
323709fac06SJung-uk Kim  *
324709fac06SJung-uk Kim  * RETURN:      None
325709fac06SJung-uk Kim  *
326709fac06SJung-uk Kim  * DESCRIPTION: Clear the external file list
327709fac06SJung-uk Kim  *
328709fac06SJung-uk Kim  ******************************************************************************/
329709fac06SJung-uk Kim 
330709fac06SJung-uk Kim void
331709fac06SJung-uk Kim AcpiDmClearExternalFileList (
332709fac06SJung-uk Kim     void)
333709fac06SJung-uk Kim {
334709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *NextExternal;
335709fac06SJung-uk Kim 
336709fac06SJung-uk Kim 
337709fac06SJung-uk Kim     while (AcpiGbl_ExternalFileList)
338709fac06SJung-uk Kim     {
339709fac06SJung-uk Kim         NextExternal = AcpiGbl_ExternalFileList->Next;
340709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
341709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList);
342709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = NextExternal;
343709fac06SJung-uk Kim     }
344709fac06SJung-uk Kim }
345709fac06SJung-uk Kim 
346709fac06SJung-uk Kim 
347709fac06SJung-uk Kim /*******************************************************************************
348709fac06SJung-uk Kim  *
349f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalList
350f556842eSJung-uk Kim  *
351f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Current parser Op
352f556842eSJung-uk Kim  *              Path                - Internal (AML) path to the object
353f556842eSJung-uk Kim  *              Type                - ACPI object type to be added
354f556842eSJung-uk Kim  *              Value               - Arg count if adding a Method object
355f556842eSJung-uk Kim  *
356f556842eSJung-uk Kim  * RETURN:      None
357f556842eSJung-uk Kim  *
358f556842eSJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
359f556842eSJung-uk Kim  *              will in turn be later emitted as an External() declaration
360f556842eSJung-uk Kim  *              in the disassembled output.
361f556842eSJung-uk Kim  *
362f556842eSJung-uk Kim  ******************************************************************************/
363f556842eSJung-uk Kim 
364f556842eSJung-uk Kim void
365f556842eSJung-uk Kim AcpiDmAddToExternalList (
366f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
367f556842eSJung-uk Kim     char                    *Path,
368f556842eSJung-uk Kim     UINT8                   Type,
369f556842eSJung-uk Kim     UINT32                  Value)
370f556842eSJung-uk Kim {
371f556842eSJung-uk Kim     char                    *ExternalPath;
372f556842eSJung-uk Kim     char                    *Fullpath = NULL;
373f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NewExternal;
374f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
375f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
376f556842eSJung-uk Kim     ACPI_STATUS             Status;
3779c48c75eSJung-uk Kim     BOOLEAN                 Resolved = FALSE;
378f556842eSJung-uk Kim 
379f556842eSJung-uk Kim 
380f556842eSJung-uk Kim     if (!Path)
381f556842eSJung-uk Kim     {
382f556842eSJung-uk Kim         return;
383f556842eSJung-uk Kim     }
384f556842eSJung-uk Kim 
3859c48c75eSJung-uk Kim     if (Type == ACPI_TYPE_METHOD)
3869c48c75eSJung-uk Kim     {
3879c48c75eSJung-uk Kim         if (Value & 0x80)
3889c48c75eSJung-uk Kim         {
3899c48c75eSJung-uk Kim             Resolved = TRUE;
3909c48c75eSJung-uk Kim         }
3919c48c75eSJung-uk Kim         Value &= 0x07;
3929c48c75eSJung-uk Kim     }
3939c48c75eSJung-uk Kim 
394ed17e06eSJung-uk Kim     /*
395ed17e06eSJung-uk Kim      * We don't want External() statements to contain a leading '\'.
396ed17e06eSJung-uk Kim      * This prevents duplicate external statements of the form:
397ed17e06eSJung-uk Kim      *
398ed17e06eSJung-uk Kim      *    External (\ABCD)
399ed17e06eSJung-uk Kim      *    External (ABCD)
400ed17e06eSJung-uk Kim      *
401ed17e06eSJung-uk Kim      * This would cause a compile time error when the disassembled
402ed17e06eSJung-uk Kim      * output file is recompiled.
403ed17e06eSJung-uk Kim      */
404ed17e06eSJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
405ed17e06eSJung-uk Kim     {
406ed17e06eSJung-uk Kim         Path++;
407ed17e06eSJung-uk Kim     }
408ed17e06eSJung-uk Kim 
409ed17e06eSJung-uk Kim     /* Externalize the ACPI pathname */
410f556842eSJung-uk Kim 
411f556842eSJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
412f556842eSJung-uk Kim                 NULL, &ExternalPath);
413f556842eSJung-uk Kim     if (ACPI_FAILURE (Status))
414f556842eSJung-uk Kim     {
415f556842eSJung-uk Kim         return;
416f556842eSJung-uk Kim     }
417f556842eSJung-uk Kim 
418ed17e06eSJung-uk Kim     /*
419ed17e06eSJung-uk Kim      * Get the full pathname from the root if "Path" has one or more
420ed17e06eSJung-uk Kim      * parent prefixes (^). Note: path will not contain a leading '\'.
421ed17e06eSJung-uk Kim      */
422f556842eSJung-uk Kim     if (*Path == (UINT8) AML_PARENT_PREFIX)
423f556842eSJung-uk Kim     {
424f556842eSJung-uk Kim         Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
425f556842eSJung-uk Kim         if (Fullpath)
426f556842eSJung-uk Kim         {
427f556842eSJung-uk Kim             /* Set new external path */
428f556842eSJung-uk Kim 
429f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
430f556842eSJung-uk Kim             ExternalPath = Fullpath;
431f556842eSJung-uk Kim         }
432f556842eSJung-uk Kim     }
433f556842eSJung-uk Kim 
434f556842eSJung-uk Kim     /* Check all existing externals to ensure no duplicates */
435f556842eSJung-uk Kim 
436f556842eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
437f556842eSJung-uk Kim     while (NextExternal)
438f556842eSJung-uk Kim     {
439f556842eSJung-uk Kim         if (!ACPI_STRCMP (ExternalPath, NextExternal->Path))
440f556842eSJung-uk Kim         {
441f556842eSJung-uk Kim             /* Duplicate method, check that the Value (ArgCount) is the same */
442f556842eSJung-uk Kim 
443f556842eSJung-uk Kim             if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
444f556842eSJung-uk Kim                 (NextExternal->Value != Value))
445f556842eSJung-uk Kim             {
446f556842eSJung-uk Kim                 ACPI_ERROR ((AE_INFO,
447ca3cf4faSJung-uk Kim                     "Argument count mismatch for method %s %u %u",
448f556842eSJung-uk Kim                     NextExternal->Path, NextExternal->Value, Value));
449f556842eSJung-uk Kim             }
450f556842eSJung-uk Kim 
451f556842eSJung-uk Kim             /* Allow upgrade of type from ANY */
452f556842eSJung-uk Kim 
453f556842eSJung-uk Kim             else if (NextExternal->Type == ACPI_TYPE_ANY)
454f556842eSJung-uk Kim             {
455f556842eSJung-uk Kim                 NextExternal->Type = Type;
456f556842eSJung-uk Kim                 NextExternal->Value = Value;
457f556842eSJung-uk Kim             }
458f556842eSJung-uk Kim 
459f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
460f556842eSJung-uk Kim             return;
461f556842eSJung-uk Kim         }
462f556842eSJung-uk Kim 
463f556842eSJung-uk Kim         NextExternal = NextExternal->Next;
464f556842eSJung-uk Kim     }
465f556842eSJung-uk Kim 
466f556842eSJung-uk Kim     /* Allocate and init a new External() descriptor */
467f556842eSJung-uk Kim 
468f556842eSJung-uk Kim     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
469f556842eSJung-uk Kim     if (!NewExternal)
470f556842eSJung-uk Kim     {
471f556842eSJung-uk Kim         ACPI_FREE (ExternalPath);
472f556842eSJung-uk Kim         return;
473f556842eSJung-uk Kim     }
474f556842eSJung-uk Kim 
475f556842eSJung-uk Kim     NewExternal->Path = ExternalPath;
476f556842eSJung-uk Kim     NewExternal->Type = Type;
477f556842eSJung-uk Kim     NewExternal->Value = Value;
4789c48c75eSJung-uk Kim     NewExternal->Resolved = Resolved;
479f556842eSJung-uk Kim     NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath);
480f556842eSJung-uk Kim 
481f556842eSJung-uk Kim     /* Was the external path with parent prefix normalized to a fullpath? */
482f556842eSJung-uk Kim 
483f556842eSJung-uk Kim     if (Fullpath == ExternalPath)
484f556842eSJung-uk Kim     {
485f556842eSJung-uk Kim         /* Get new internal path */
486f556842eSJung-uk Kim 
487f556842eSJung-uk Kim         Status = AcpiNsInternalizeName (ExternalPath, &Path);
488f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
489f556842eSJung-uk Kim         {
490f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
491f556842eSJung-uk Kim             ACPI_FREE (NewExternal);
492f556842eSJung-uk Kim             return;
493f556842eSJung-uk Kim         }
494f556842eSJung-uk Kim 
495f556842eSJung-uk Kim         /* Set flag to indicate External->InternalPath need to be freed */
496f556842eSJung-uk Kim 
497f556842eSJung-uk Kim         NewExternal->Flags |= ACPI_IPATH_ALLOCATED;
498f556842eSJung-uk Kim     }
499f556842eSJung-uk Kim 
500f556842eSJung-uk Kim     NewExternal->InternalPath = Path;
501f556842eSJung-uk Kim 
502a7a3b383SJung-uk Kim     /* Link the new descriptor into the global list, alphabetically ordered */
503f556842eSJung-uk Kim 
504f556842eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
505f556842eSJung-uk Kim     while (NextExternal)
506f556842eSJung-uk Kim     {
507a7a3b383SJung-uk Kim         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
508f556842eSJung-uk Kim         {
509f556842eSJung-uk Kim             if (PrevExternal)
510f556842eSJung-uk Kim             {
511f556842eSJung-uk Kim                 PrevExternal->Next = NewExternal;
512f556842eSJung-uk Kim             }
513f556842eSJung-uk Kim             else
514f556842eSJung-uk Kim             {
515f556842eSJung-uk Kim                 AcpiGbl_ExternalList = NewExternal;
516f556842eSJung-uk Kim             }
517f556842eSJung-uk Kim 
518f556842eSJung-uk Kim             NewExternal->Next = NextExternal;
519f556842eSJung-uk Kim             return;
520f556842eSJung-uk Kim         }
521f556842eSJung-uk Kim 
522f556842eSJung-uk Kim         PrevExternal = NextExternal;
523f556842eSJung-uk Kim         NextExternal = NextExternal->Next;
524f556842eSJung-uk Kim     }
525f556842eSJung-uk Kim 
526f556842eSJung-uk Kim     if (PrevExternal)
527f556842eSJung-uk Kim     {
528f556842eSJung-uk Kim         PrevExternal->Next = NewExternal;
529f556842eSJung-uk Kim     }
530f556842eSJung-uk Kim     else
531f556842eSJung-uk Kim     {
532f556842eSJung-uk Kim         AcpiGbl_ExternalList = NewExternal;
533f556842eSJung-uk Kim     }
534f556842eSJung-uk Kim }
535f556842eSJung-uk Kim 
536f556842eSJung-uk Kim 
537f556842eSJung-uk Kim /*******************************************************************************
538f556842eSJung-uk Kim  *
539f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddExternalsToNamespace
540f556842eSJung-uk Kim  *
541f556842eSJung-uk Kim  * PARAMETERS:  None
542f556842eSJung-uk Kim  *
543f556842eSJung-uk Kim  * RETURN:      None
544f556842eSJung-uk Kim  *
545f556842eSJung-uk Kim  * DESCRIPTION: Add all externals to the namespace. Allows externals to be
546f556842eSJung-uk Kim  *              "resolved".
547f556842eSJung-uk Kim  *
548f556842eSJung-uk Kim  ******************************************************************************/
549f556842eSJung-uk Kim 
550f556842eSJung-uk Kim void
551f556842eSJung-uk Kim AcpiDmAddExternalsToNamespace (
552f556842eSJung-uk Kim     void)
553f556842eSJung-uk Kim {
554f556842eSJung-uk Kim     ACPI_STATUS             Status;
555f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
556a7a3b383SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
557f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
558f556842eSJung-uk Kim 
559f556842eSJung-uk Kim 
560f556842eSJung-uk Kim     while (External)
561f556842eSJung-uk Kim     {
562f556842eSJung-uk Kim         /* Add the external name (object) into the namespace */
563f556842eSJung-uk Kim 
564f556842eSJung-uk Kim         Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
565f556842eSJung-uk Kim                    ACPI_IMODE_LOAD_PASS1,
566f556842eSJung-uk Kim                    ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
567f556842eSJung-uk Kim                    NULL, &Node);
568f556842eSJung-uk Kim 
569f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
570f556842eSJung-uk Kim         {
571f556842eSJung-uk Kim             ACPI_EXCEPTION ((AE_INFO, Status,
572f556842eSJung-uk Kim                 "while adding external to namespace [%s]",
573f556842eSJung-uk Kim                 External->Path));
574f556842eSJung-uk Kim         }
575a7a3b383SJung-uk Kim 
576a7a3b383SJung-uk Kim         else switch (External->Type)
577f556842eSJung-uk Kim         {
578a7a3b383SJung-uk Kim         case ACPI_TYPE_METHOD:
579a7a3b383SJung-uk Kim 
580f556842eSJung-uk Kim             /* For methods, we need to save the argument count */
581f556842eSJung-uk Kim 
582a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
583a7a3b383SJung-uk Kim             ObjDesc->Method.ParamCount = (UINT8) External->Value;
584a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
585a7a3b383SJung-uk Kim             break;
586a7a3b383SJung-uk Kim 
587a7a3b383SJung-uk Kim         case ACPI_TYPE_REGION:
588a7a3b383SJung-uk Kim 
589a7a3b383SJung-uk Kim             /* Regions require a region sub-object */
590a7a3b383SJung-uk Kim 
591a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
592a7a3b383SJung-uk Kim             ObjDesc->Region.Node = Node;
593a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
594a7a3b383SJung-uk Kim             break;
595a7a3b383SJung-uk Kim 
596a7a3b383SJung-uk Kim         default:
597*a9d8d09cSJung-uk Kim 
598a7a3b383SJung-uk Kim             break;
599f556842eSJung-uk Kim         }
600f556842eSJung-uk Kim 
601f556842eSJung-uk Kim         External = External->Next;
602f556842eSJung-uk Kim     }
603f556842eSJung-uk Kim }
604f556842eSJung-uk Kim 
605f556842eSJung-uk Kim 
606f556842eSJung-uk Kim /*******************************************************************************
607f556842eSJung-uk Kim  *
608f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetExternalMethodCount
609f556842eSJung-uk Kim  *
610f556842eSJung-uk Kim  * PARAMETERS:  None
611f556842eSJung-uk Kim  *
612f556842eSJung-uk Kim  * RETURN:      The number of control method externals in the external list
613f556842eSJung-uk Kim  *
614f556842eSJung-uk Kim  * DESCRIPTION: Return the number of method externals that have been generated.
615f556842eSJung-uk Kim  *              If any control method externals have been found, we must
616f556842eSJung-uk Kim  *              re-parse the entire definition block with the new information
617f556842eSJung-uk Kim  *              (number of arguments for the methods.) This is limitation of
618f556842eSJung-uk Kim  *              AML, we don't know the number of arguments from the control
619f556842eSJung-uk Kim  *              method invocation itself.
620f556842eSJung-uk Kim  *
621f556842eSJung-uk Kim  ******************************************************************************/
622f556842eSJung-uk Kim 
623f556842eSJung-uk Kim UINT32
624f556842eSJung-uk Kim AcpiDmGetExternalMethodCount (
625f556842eSJung-uk Kim     void)
626f556842eSJung-uk Kim {
627f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
628f556842eSJung-uk Kim     UINT32                  Count = 0;
629f556842eSJung-uk Kim 
630f556842eSJung-uk Kim 
631f556842eSJung-uk Kim     while (External)
632f556842eSJung-uk Kim     {
633f556842eSJung-uk Kim         if (External->Type == ACPI_TYPE_METHOD)
634f556842eSJung-uk Kim         {
635f556842eSJung-uk Kim             Count++;
636f556842eSJung-uk Kim         }
637f556842eSJung-uk Kim 
638f556842eSJung-uk Kim         External = External->Next;
639f556842eSJung-uk Kim     }
640f556842eSJung-uk Kim 
641f556842eSJung-uk Kim     return (Count);
642f556842eSJung-uk Kim }
643f556842eSJung-uk Kim 
644f556842eSJung-uk Kim 
645f556842eSJung-uk Kim /*******************************************************************************
646f556842eSJung-uk Kim  *
647f556842eSJung-uk Kim  * FUNCTION:    AcpiDmClearExternalList
648f556842eSJung-uk Kim  *
649f556842eSJung-uk Kim  * PARAMETERS:  None
650f556842eSJung-uk Kim  *
651f556842eSJung-uk Kim  * RETURN:      None
652f556842eSJung-uk Kim  *
653f556842eSJung-uk Kim  * DESCRIPTION: Free the entire External info list
654f556842eSJung-uk Kim  *
655f556842eSJung-uk Kim  ******************************************************************************/
656f556842eSJung-uk Kim 
657f556842eSJung-uk Kim void
658f556842eSJung-uk Kim AcpiDmClearExternalList (
659f556842eSJung-uk Kim     void)
660f556842eSJung-uk Kim {
661f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
662f556842eSJung-uk Kim 
663f556842eSJung-uk Kim 
664f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
665f556842eSJung-uk Kim     {
666f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
667f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
668f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
669f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
670f556842eSJung-uk Kim     }
671f556842eSJung-uk Kim }
672f556842eSJung-uk Kim 
673f556842eSJung-uk Kim 
674f556842eSJung-uk Kim /*******************************************************************************
675f556842eSJung-uk Kim  *
676f556842eSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternals
677f556842eSJung-uk Kim  *
678f556842eSJung-uk Kim  * PARAMETERS:  None
679f556842eSJung-uk Kim  *
680f556842eSJung-uk Kim  * RETURN:      None
681f556842eSJung-uk Kim  *
682f556842eSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
683f556842eSJung-uk Kim  *              the global external info list.
684f556842eSJung-uk Kim  *
685f556842eSJung-uk Kim  ******************************************************************************/
686f556842eSJung-uk Kim 
687f556842eSJung-uk Kim void
688f556842eSJung-uk Kim AcpiDmEmitExternals (
689f556842eSJung-uk Kim     void)
690f556842eSJung-uk Kim {
691f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
692f556842eSJung-uk Kim 
693f556842eSJung-uk Kim 
694f556842eSJung-uk Kim     if (!AcpiGbl_ExternalList)
695f556842eSJung-uk Kim     {
696f556842eSJung-uk Kim         return;
697f556842eSJung-uk Kim     }
698f556842eSJung-uk Kim 
699f556842eSJung-uk Kim     /*
7009c48c75eSJung-uk Kim      * Determine the number of control methods in the external list, and
7019c48c75eSJung-uk Kim      * also how many of those externals were resolved via the namespace.
7029c48c75eSJung-uk Kim      */
7039c48c75eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
7049c48c75eSJung-uk Kim     while (NextExternal)
7059c48c75eSJung-uk Kim     {
7069c48c75eSJung-uk Kim         if (NextExternal->Type == ACPI_TYPE_METHOD)
7079c48c75eSJung-uk Kim         {
7089c48c75eSJung-uk Kim             AcpiGbl_NumExternalMethods++;
7099c48c75eSJung-uk Kim             if (NextExternal->Resolved)
7109c48c75eSJung-uk Kim             {
7119c48c75eSJung-uk Kim                 AcpiGbl_ResolvedExternalMethods++;
7129c48c75eSJung-uk Kim             }
7139c48c75eSJung-uk Kim         }
7149c48c75eSJung-uk Kim 
7159c48c75eSJung-uk Kim         NextExternal = NextExternal->Next;
7169c48c75eSJung-uk Kim     }
7179c48c75eSJung-uk Kim 
7189c48c75eSJung-uk Kim     /* Check if any control methods were unresolved */
7199c48c75eSJung-uk Kim 
7209c48c75eSJung-uk Kim     AcpiDmUnresolvedWarning (1);
7219c48c75eSJung-uk Kim 
7229c48c75eSJung-uk Kim     /*
723f556842eSJung-uk Kim      * Walk the list of externals (unresolved references)
724f556842eSJung-uk Kim      * found during the AML parsing
725f556842eSJung-uk Kim      */
726f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
727f556842eSJung-uk Kim     {
728f556842eSJung-uk Kim         AcpiOsPrintf ("    External (%s%s",
729f556842eSJung-uk Kim             AcpiGbl_ExternalList->Path,
730f556842eSJung-uk Kim             AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
731f556842eSJung-uk Kim 
732f556842eSJung-uk Kim         if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
733f556842eSJung-uk Kim         {
7349c48c75eSJung-uk Kim             if (AcpiGbl_ExternalList->Resolved)
7359c48c75eSJung-uk Kim             {
736a88e22b7SJung-uk Kim                 AcpiOsPrintf (")    // %u Arguments\n",
737f556842eSJung-uk Kim                     AcpiGbl_ExternalList->Value);
738f556842eSJung-uk Kim             }
739f556842eSJung-uk Kim             else
740f556842eSJung-uk Kim             {
7419c48c75eSJung-uk Kim                 AcpiOsPrintf (")    // Warning: unresolved Method, "
7429c48c75eSJung-uk Kim                     "assuming %u arguments (may be incorrect, see warning above)\n",
7439c48c75eSJung-uk Kim                     AcpiGbl_ExternalList->Value);
7449c48c75eSJung-uk Kim             }
7459c48c75eSJung-uk Kim         }
7469c48c75eSJung-uk Kim         else
7479c48c75eSJung-uk Kim         {
748f556842eSJung-uk Kim             AcpiOsPrintf (")\n");
749f556842eSJung-uk Kim         }
750f556842eSJung-uk Kim 
751f556842eSJung-uk Kim         /* Free this external info block and move on to next external */
752f556842eSJung-uk Kim 
753f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
754f556842eSJung-uk Kim         if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED)
755f556842eSJung-uk Kim         {
756f556842eSJung-uk Kim             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
757f556842eSJung-uk Kim         }
758f556842eSJung-uk Kim 
759f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
760f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
761f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
762f556842eSJung-uk Kim     }
763f556842eSJung-uk Kim 
764f556842eSJung-uk Kim     AcpiOsPrintf ("\n");
765f556842eSJung-uk Kim }
7669c48c75eSJung-uk Kim 
7679c48c75eSJung-uk Kim 
7689c48c75eSJung-uk Kim /*******************************************************************************
7699c48c75eSJung-uk Kim  *
7709c48c75eSJung-uk Kim  * FUNCTION:    AcpiDmUnresolvedWarning
7719c48c75eSJung-uk Kim  *
7729c48c75eSJung-uk Kim  * PARAMETERS:  Type                - Where to output the warning.
7739c48c75eSJung-uk Kim  *                                    0 means write to stderr
7749c48c75eSJung-uk Kim  *                                    1 means write to AcpiOsPrintf
7759c48c75eSJung-uk Kim  *
7769c48c75eSJung-uk Kim  * RETURN:      None
7779c48c75eSJung-uk Kim  *
7789c48c75eSJung-uk Kim  * DESCRIPTION: Issue warning message if there are unresolved external control
7799c48c75eSJung-uk Kim  *              methods within the disassembly.
7809c48c75eSJung-uk Kim  *
7819c48c75eSJung-uk Kim  ******************************************************************************/
7829c48c75eSJung-uk Kim 
7839c48c75eSJung-uk Kim #if 0
7849c48c75eSJung-uk Kim Summary of the external control method problem:
7859c48c75eSJung-uk Kim 
7869c48c75eSJung-uk Kim When the -e option is used with disassembly, the various SSDTs are simply
7879c48c75eSJung-uk Kim loaded into a global namespace for the disassembler to use in order to
7889c48c75eSJung-uk Kim resolve control method references (invocations).
7899c48c75eSJung-uk Kim 
7909c48c75eSJung-uk Kim The disassembler tracks any such references, and will emit an External()
7919c48c75eSJung-uk Kim statement for these types of methods, with the proper number of arguments .
7929c48c75eSJung-uk Kim 
7939c48c75eSJung-uk Kim Without the SSDTs, the AML does not contain enough information to properly
7949c48c75eSJung-uk Kim disassemble the control method invocation -- because the disassembler does
7959c48c75eSJung-uk Kim not know how many arguments to parse.
7969c48c75eSJung-uk Kim 
7979c48c75eSJung-uk Kim An example: Assume we have two control methods. ABCD has one argument, and
7989c48c75eSJung-uk Kim EFGH has zero arguments. Further, we have two additional control methods
7999c48c75eSJung-uk Kim that invoke ABCD and EFGH, named T1 and T2:
8009c48c75eSJung-uk Kim 
8019c48c75eSJung-uk Kim     Method (ABCD, 1)
8029c48c75eSJung-uk Kim     {
8039c48c75eSJung-uk Kim     }
8049c48c75eSJung-uk Kim     Method (EFGH, 0)
8059c48c75eSJung-uk Kim     {
8069c48c75eSJung-uk Kim     }
8079c48c75eSJung-uk Kim     Method (T1)
8089c48c75eSJung-uk Kim     {
8099c48c75eSJung-uk Kim         ABCD (Add (2, 7, Local0))
8109c48c75eSJung-uk Kim     }
8119c48c75eSJung-uk Kim     Method (T2)
8129c48c75eSJung-uk Kim     {
8139c48c75eSJung-uk Kim         EFGH ()
8149c48c75eSJung-uk Kim         Add (2, 7, Local0)
8159c48c75eSJung-uk Kim     }
8169c48c75eSJung-uk Kim 
8179c48c75eSJung-uk Kim Here is the AML code that is generated for T1 and T2:
8189c48c75eSJung-uk Kim 
8199c48c75eSJung-uk Kim      185:      Method (T1)
8209c48c75eSJung-uk Kim 
8219c48c75eSJung-uk Kim 0000034C:  14 10 54 31 5F 5F 00 ...    "..T1__."
8229c48c75eSJung-uk Kim 
8239c48c75eSJung-uk Kim      186:      {
8249c48c75eSJung-uk Kim      187:          ABCD (Add (2, 7, Local0))
8259c48c75eSJung-uk Kim 
8269c48c75eSJung-uk Kim 00000353:  41 42 43 44 ............    "ABCD"
8279c48c75eSJung-uk Kim 00000357:  72 0A 02 0A 07 60 ......    "r....`"
8289c48c75eSJung-uk Kim 
8299c48c75eSJung-uk Kim      188:      }
8309c48c75eSJung-uk Kim 
8319c48c75eSJung-uk Kim      190:      Method (T2)
8329c48c75eSJung-uk Kim 
8339c48c75eSJung-uk Kim 0000035D:  14 10 54 32 5F 5F 00 ...    "..T2__."
8349c48c75eSJung-uk Kim 
8359c48c75eSJung-uk Kim      191:      {
8369c48c75eSJung-uk Kim      192:          EFGH ()
8379c48c75eSJung-uk Kim 
8389c48c75eSJung-uk Kim 00000364:  45 46 47 48 ............    "EFGH"
8399c48c75eSJung-uk Kim 
8409c48c75eSJung-uk Kim      193:          Add (2, 7, Local0)
8419c48c75eSJung-uk Kim 
8429c48c75eSJung-uk Kim 00000368:  72 0A 02 0A 07 60 ......    "r....`"
8439c48c75eSJung-uk Kim      194:      }
8449c48c75eSJung-uk Kim 
8459c48c75eSJung-uk Kim Note that the AML code for T1 and T2 is essentially identical. When
8469c48c75eSJung-uk Kim disassembling this code, the methods ABCD and EFGH must be known to the
8479c48c75eSJung-uk Kim disassembler, otherwise it does not know how to handle the method invocations.
8489c48c75eSJung-uk Kim 
8499c48c75eSJung-uk Kim In other words, if ABCD and EFGH are actually external control methods
8509c48c75eSJung-uk Kim appearing in an SSDT, the disassembler does not know what to do unless
8519c48c75eSJung-uk Kim the owning SSDT has been loaded via the -e option.
8529c48c75eSJung-uk Kim #endif
8539c48c75eSJung-uk Kim 
8549c48c75eSJung-uk Kim void
8559c48c75eSJung-uk Kim AcpiDmUnresolvedWarning (
8569c48c75eSJung-uk Kim     UINT8                   Type)
8579c48c75eSJung-uk Kim {
8589c48c75eSJung-uk Kim 
8599c48c75eSJung-uk Kim     if (!AcpiGbl_NumExternalMethods)
8609c48c75eSJung-uk Kim     {
8619c48c75eSJung-uk Kim         return;
8629c48c75eSJung-uk Kim     }
8639c48c75eSJung-uk Kim 
8649c48c75eSJung-uk Kim     if (Type)
8659c48c75eSJung-uk Kim     {
8669c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
8679c48c75eSJung-uk Kim         {
8689c48c75eSJung-uk Kim             /* The -e option was not specified */
8699c48c75eSJung-uk Kim 
8709c48c75eSJung-uk Kim            AcpiOsPrintf ("    /*\n"
8719c48c75eSJung-uk Kim                 "     * iASL Warning: There were %u external control methods found during\n"
8729c48c75eSJung-uk Kim                 "     * disassembly, but additional ACPI tables to resolve these externals\n"
8739c48c75eSJung-uk Kim                 "     * were not specified. This resulting disassembler output file may not\n"
8749c48c75eSJung-uk Kim                 "     * compile because the disassembler did not know how many arguments\n"
8759c48c75eSJung-uk Kim                 "     * to assign to these methods. To specify the tables needed to resolve\n"
8769c48c75eSJung-uk Kim                 "     * external control method references, use the one of the following\n"
8779c48c75eSJung-uk Kim                 "     * example iASL invocations:\n"
8789c48c75eSJung-uk Kim                 "     *     iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n"
8799c48c75eSJung-uk Kim                 "     *     iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n"
8809c48c75eSJung-uk Kim                 "     */\n",
8819c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods);
8829c48c75eSJung-uk Kim         }
8839c48c75eSJung-uk Kim         else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods)
8849c48c75eSJung-uk Kim         {
8859c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
8869c48c75eSJung-uk Kim 
8879c48c75eSJung-uk Kim             AcpiOsPrintf ("    /*\n"
8889c48c75eSJung-uk Kim                 "     * iASL Warning: There were %u external control methods found during\n"
8899c48c75eSJung-uk Kim                 "     * disassembly, but only %u %s resolved (%u unresolved). Additional\n"
8909c48c75eSJung-uk Kim                 "     * ACPI tables are required to properly disassemble the code. This\n"
8919c48c75eSJung-uk Kim                 "     * resulting disassembler output file may not compile because the\n"
8929c48c75eSJung-uk Kim                 "     * disassembler did not know how many arguments to assign to the\n"
8939c48c75eSJung-uk Kim                 "     * unresolved methods.\n"
8949c48c75eSJung-uk Kim                 "     */\n",
8959c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods,
8969c48c75eSJung-uk Kim                 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"),
8979c48c75eSJung-uk Kim                 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods));
8989c48c75eSJung-uk Kim         }
8999c48c75eSJung-uk Kim     }
9009c48c75eSJung-uk Kim     else
9019c48c75eSJung-uk Kim     {
9029c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
9039c48c75eSJung-uk Kim         {
9049c48c75eSJung-uk Kim             /* The -e option was not specified */
9059c48c75eSJung-uk Kim 
9069c48c75eSJung-uk Kim             fprintf (stderr, "\n"
9079c48c75eSJung-uk Kim                 "iASL Warning: There were %u external control methods found during\n"
9089c48c75eSJung-uk Kim                 "disassembly, but additional ACPI tables to resolve these externals\n"
9099c48c75eSJung-uk Kim                 "were not specified. The resulting disassembler output file may not\n"
9109c48c75eSJung-uk Kim                 "compile because the disassembler did not know how many arguments\n"
9119c48c75eSJung-uk Kim                 "to assign to these methods. To specify the tables needed to resolve\n"
9129c48c75eSJung-uk Kim                 "external control method references, use the one of the following\n"
9139c48c75eSJung-uk Kim                 "example iASL invocations:\n"
9149c48c75eSJung-uk Kim                 "    iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n"
9159c48c75eSJung-uk Kim                 "    iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n",
9169c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods);
9179c48c75eSJung-uk Kim         }
9189c48c75eSJung-uk Kim         else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods)
9199c48c75eSJung-uk Kim         {
9209c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
9219c48c75eSJung-uk Kim 
9229c48c75eSJung-uk Kim             fprintf (stderr, "\n"
9239c48c75eSJung-uk Kim                 "iASL Warning: There were %u external control methods found during\n"
9249c48c75eSJung-uk Kim                 "disassembly, but only %u %s resolved (%u unresolved). Additional\n"
9259c48c75eSJung-uk Kim                 "ACPI tables are required to properly disassemble the code. The\n"
9269c48c75eSJung-uk Kim                 "resulting disassembler output file may not compile because the\n"
9279c48c75eSJung-uk Kim                 "disassembler did not know how many arguments to assign to the\n"
9289c48c75eSJung-uk Kim                 "unresolved methods.\n",
9299c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods,
9309c48c75eSJung-uk Kim                 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"),
9319c48c75eSJung-uk Kim                 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods));
9329c48c75eSJung-uk Kim         }
9339c48c75eSJung-uk Kim     }
9349c48c75eSJung-uk Kim 
9359c48c75eSJung-uk Kim }
936