xref: /freebsd/sys/contrib/dev/acpica/common/dmextern.c (revision 79c6d946797dd4db2f2a943f664a4e976f6c942b)
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>
49*79c6d946SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
509c48c75eSJung-uk Kim #include <stdio.h>
51*79c6d946SJung-uk Kim #include <errno.h>
52f556842eSJung-uk Kim 
53f556842eSJung-uk Kim 
54f556842eSJung-uk Kim /*
55f556842eSJung-uk Kim  * This module is used for application-level code (iASL disassembler) only.
56f556842eSJung-uk Kim  *
57f556842eSJung-uk Kim  * It contains the code to create and emit any necessary External() ASL
58f556842eSJung-uk Kim  * statements for the module being disassembled.
59f556842eSJung-uk Kim  */
60f556842eSJung-uk Kim #define _COMPONENT          ACPI_CA_DISASSEMBLER
61f556842eSJung-uk Kim         ACPI_MODULE_NAME    ("dmextern")
62f556842eSJung-uk Kim 
63f556842eSJung-uk Kim 
64f556842eSJung-uk Kim /*
65f556842eSJung-uk Kim  * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
66f556842eSJung-uk Kim  * ObjectTypeKeyword. Used to generate typed external declarations
67f556842eSJung-uk Kim  */
68f556842eSJung-uk Kim static const char           *AcpiGbl_DmTypeNames[] =
69f556842eSJung-uk Kim {
70f556842eSJung-uk Kim     /* 00 */ "",                    /* Type ANY */
71f556842eSJung-uk Kim     /* 01 */ ", IntObj",
72f556842eSJung-uk Kim     /* 02 */ ", StrObj",
73f556842eSJung-uk Kim     /* 03 */ ", BuffObj",
74f556842eSJung-uk Kim     /* 04 */ ", PkgObj",
75f556842eSJung-uk Kim     /* 05 */ ", FieldUnitObj",
76f556842eSJung-uk Kim     /* 06 */ ", DeviceObj",
77f556842eSJung-uk Kim     /* 07 */ ", EventObj",
78f556842eSJung-uk Kim     /* 08 */ ", MethodObj",
79f556842eSJung-uk Kim     /* 09 */ ", MutexObj",
80f556842eSJung-uk Kim     /* 10 */ ", OpRegionObj",
81f556842eSJung-uk Kim     /* 11 */ ", PowerResObj",
82f556842eSJung-uk Kim     /* 12 */ ", ProcessorObj",
83f556842eSJung-uk Kim     /* 13 */ ", ThermalZoneObj",
84f556842eSJung-uk Kim     /* 14 */ ", BuffFieldObj",
85f556842eSJung-uk Kim     /* 15 */ ", DDBHandleObj",
86f556842eSJung-uk Kim     /* 16 */ "",                    /* Debug object */
87f556842eSJung-uk Kim     /* 17 */ ", FieldUnitObj",
88f556842eSJung-uk Kim     /* 18 */ ", FieldUnitObj",
89f556842eSJung-uk Kim     /* 19 */ ", FieldUnitObj"
90f556842eSJung-uk Kim };
91f556842eSJung-uk Kim 
92*79c6d946SJung-uk Kim #define METHOD_SEPARATORS           " \t,()\n"
93*79c6d946SJung-uk Kim 
94f556842eSJung-uk Kim 
95f556842eSJung-uk Kim /* Local prototypes */
96f556842eSJung-uk Kim 
97f556842eSJung-uk Kim static const char *
98f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
99f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type);
100f556842eSJung-uk Kim 
101f556842eSJung-uk Kim static char *
102f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
103f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
104f556842eSJung-uk Kim     char                    *Path);
105f556842eSJung-uk Kim 
106*79c6d946SJung-uk Kim static void
107*79c6d946SJung-uk Kim AcpiDmAddToExternalListFromFile (
108*79c6d946SJung-uk Kim     char                    *Path,
109*79c6d946SJung-uk Kim     UINT8                   Type,
110*79c6d946SJung-uk Kim     UINT32                  Value);
111*79c6d946SJung-uk Kim 
112f556842eSJung-uk Kim 
113f556842eSJung-uk Kim /*******************************************************************************
114f556842eSJung-uk Kim  *
115f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetObjectTypeName
116f556842eSJung-uk Kim  *
117f556842eSJung-uk Kim  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
118f556842eSJung-uk Kim  *
119f556842eSJung-uk Kim  * RETURN:      Pointer to a string
120f556842eSJung-uk Kim  *
121f556842eSJung-uk Kim  * DESCRIPTION: Map an object type to the ASL object type string.
122f556842eSJung-uk Kim  *
123f556842eSJung-uk Kim  ******************************************************************************/
124f556842eSJung-uk Kim 
125f556842eSJung-uk Kim static const char *
126f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
127f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type)
128f556842eSJung-uk Kim {
129f556842eSJung-uk Kim 
130f556842eSJung-uk Kim     if (Type == ACPI_TYPE_LOCAL_SCOPE)
131f556842eSJung-uk Kim     {
132f556842eSJung-uk Kim         Type = ACPI_TYPE_DEVICE;
133f556842eSJung-uk Kim     }
134f556842eSJung-uk Kim 
135f556842eSJung-uk Kim     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
136f556842eSJung-uk Kim     {
137f556842eSJung-uk Kim         return ("");
138f556842eSJung-uk Kim     }
139f556842eSJung-uk Kim 
140f556842eSJung-uk Kim     return (AcpiGbl_DmTypeNames[Type]);
141f556842eSJung-uk Kim }
142f556842eSJung-uk Kim 
143f556842eSJung-uk Kim 
144f556842eSJung-uk Kim /*******************************************************************************
145f556842eSJung-uk Kim  *
146f556842eSJung-uk Kim  * FUNCTION:    AcpiDmNormalizeParentPrefix
147f556842eSJung-uk Kim  *
148f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Parse op
149f556842eSJung-uk Kim  *              Path                - Path with parent prefix
150f556842eSJung-uk Kim  *
151f556842eSJung-uk Kim  * RETURN:      The full pathname to the object (from the namespace root)
152f556842eSJung-uk Kim  *
153f556842eSJung-uk Kim  * DESCRIPTION: Returns the full pathname of a path with parent prefix
154f556842eSJung-uk Kim  *              The caller must free the fullpath returned.
155f556842eSJung-uk Kim  *
156f556842eSJung-uk Kim  ******************************************************************************/
157f556842eSJung-uk Kim 
158f556842eSJung-uk Kim static char *
159f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
160f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
161f556842eSJung-uk Kim     char                    *Path)
162f556842eSJung-uk Kim {
163f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
164f556842eSJung-uk Kim     char                    *Fullpath;
165f556842eSJung-uk Kim     char                    *ParentPath;
166f556842eSJung-uk Kim     ACPI_SIZE               Length;
167ed17e06eSJung-uk Kim     UINT32                  Index = 0;
168f556842eSJung-uk Kim 
169f556842eSJung-uk Kim 
170ed17e06eSJung-uk Kim     if (!Op)
171ed17e06eSJung-uk Kim     {
172ed17e06eSJung-uk Kim         return (NULL);
173ed17e06eSJung-uk Kim     }
174f556842eSJung-uk Kim 
175ed17e06eSJung-uk Kim     /* Search upwards in the parse tree until we reach the next namespace node */
176ed17e06eSJung-uk Kim 
177ed17e06eSJung-uk Kim     Op = Op->Common.Parent;
178f556842eSJung-uk Kim     while (Op)
179f556842eSJung-uk Kim     {
180f556842eSJung-uk Kim         if (Op->Common.Node)
181f556842eSJung-uk Kim         {
182f556842eSJung-uk Kim             break;
183f556842eSJung-uk Kim         }
184f556842eSJung-uk Kim 
185f556842eSJung-uk Kim         Op = Op->Common.Parent;
186f556842eSJung-uk Kim     }
187f556842eSJung-uk Kim 
188f556842eSJung-uk Kim     if (!Op)
189f556842eSJung-uk Kim     {
190f556842eSJung-uk Kim         return (NULL);
191f556842eSJung-uk Kim     }
192f556842eSJung-uk Kim 
193f556842eSJung-uk Kim     /*
194f556842eSJung-uk Kim      * Find the actual parent node for the reference:
195f556842eSJung-uk Kim      * Remove all carat prefixes from the input path.
196f556842eSJung-uk Kim      * There may be multiple parent prefixes (For example, ^^^M000)
197f556842eSJung-uk Kim      */
198f556842eSJung-uk Kim     Node = Op->Common.Node;
199f556842eSJung-uk Kim     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
200f556842eSJung-uk Kim     {
201a88e22b7SJung-uk Kim         Node = Node->Parent;
202f556842eSJung-uk Kim         Path++;
203f556842eSJung-uk Kim     }
204f556842eSJung-uk Kim 
205f556842eSJung-uk Kim     if (!Node)
206f556842eSJung-uk Kim     {
207f556842eSJung-uk Kim         return (NULL);
208f556842eSJung-uk Kim     }
209f556842eSJung-uk Kim 
210f556842eSJung-uk Kim     /* Get the full pathname for the parent node */
211f556842eSJung-uk Kim 
212f556842eSJung-uk Kim     ParentPath = AcpiNsGetExternalPathname (Node);
213f556842eSJung-uk Kim     if (!ParentPath)
214f556842eSJung-uk Kim     {
215f556842eSJung-uk Kim         return (NULL);
216f556842eSJung-uk Kim     }
217f556842eSJung-uk Kim 
218f556842eSJung-uk Kim     Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
2198c8be05fSJung-uk Kim     if (ParentPath[1])
2208c8be05fSJung-uk Kim     {
2218c8be05fSJung-uk Kim         /*
2228c8be05fSJung-uk Kim          * If ParentPath is not just a simple '\', increment the length
2238c8be05fSJung-uk Kim          * for the required dot separator (ParentPath.Path)
2248c8be05fSJung-uk Kim          */
2258c8be05fSJung-uk Kim         Length++;
226ed17e06eSJung-uk Kim 
227ed17e06eSJung-uk Kim         /* For External() statements, we do not want a leading '\' */
228ed17e06eSJung-uk Kim 
229ed17e06eSJung-uk Kim         if (*ParentPath == AML_ROOT_PREFIX)
230ed17e06eSJung-uk Kim         {
231ed17e06eSJung-uk Kim             Index = 1;
232ed17e06eSJung-uk Kim         }
2338c8be05fSJung-uk Kim     }
2348c8be05fSJung-uk Kim 
235f556842eSJung-uk Kim     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
236f556842eSJung-uk Kim     if (!Fullpath)
237f556842eSJung-uk Kim     {
238f556842eSJung-uk Kim         goto Cleanup;
239f556842eSJung-uk Kim     }
240f556842eSJung-uk Kim 
241f556842eSJung-uk Kim     /*
242f556842eSJung-uk Kim      * Concatenate parent fullpath and path. For example,
243f556842eSJung-uk Kim      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
244f556842eSJung-uk Kim      *
245f556842eSJung-uk Kim      * Copy the parent path
246f556842eSJung-uk Kim      */
247ed17e06eSJung-uk Kim     ACPI_STRCPY (Fullpath, &ParentPath[Index]);
248f556842eSJung-uk Kim 
249f38b0f21SJung-uk Kim     /*
250f38b0f21SJung-uk Kim      * Add dot separator
251f38b0f21SJung-uk Kim      * (don't need dot if parent fullpath is a single backslash)
252f38b0f21SJung-uk Kim      */
253f556842eSJung-uk Kim     if (ParentPath[1])
254f556842eSJung-uk Kim     {
255f556842eSJung-uk Kim         ACPI_STRCAT (Fullpath, ".");
256f556842eSJung-uk Kim     }
257f556842eSJung-uk Kim 
258f556842eSJung-uk Kim     /* Copy child path (carat parent prefix(es) were skipped above) */
259f556842eSJung-uk Kim 
260f556842eSJung-uk Kim     ACPI_STRCAT (Fullpath, Path);
261f556842eSJung-uk Kim 
262f556842eSJung-uk Kim Cleanup:
263f556842eSJung-uk Kim     ACPI_FREE (ParentPath);
264f556842eSJung-uk Kim     return (Fullpath);
265f556842eSJung-uk Kim }
266f556842eSJung-uk Kim 
267f556842eSJung-uk Kim 
268f556842eSJung-uk Kim /*******************************************************************************
269f556842eSJung-uk Kim  *
270709fac06SJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalFileList
271709fac06SJung-uk Kim  *
272709fac06SJung-uk Kim  * PARAMETERS:  PathList            - Single path or list separated by comma
273709fac06SJung-uk Kim  *
274709fac06SJung-uk Kim  * RETURN:      None
275709fac06SJung-uk Kim  *
276709fac06SJung-uk Kim  * DESCRIPTION: Add external files to global list
277709fac06SJung-uk Kim  *
278709fac06SJung-uk Kim  ******************************************************************************/
279709fac06SJung-uk Kim 
280709fac06SJung-uk Kim ACPI_STATUS
281709fac06SJung-uk Kim AcpiDmAddToExternalFileList (
282709fac06SJung-uk Kim     char                    *PathList)
283709fac06SJung-uk Kim {
284709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *ExternalFile;
285709fac06SJung-uk Kim     char                    *Path;
286709fac06SJung-uk Kim     char                    *TmpPath;
287709fac06SJung-uk Kim 
288709fac06SJung-uk Kim 
289709fac06SJung-uk Kim     if (!PathList)
290709fac06SJung-uk Kim     {
291709fac06SJung-uk Kim         return (AE_OK);
292709fac06SJung-uk Kim     }
293709fac06SJung-uk Kim 
294709fac06SJung-uk Kim     Path = strtok (PathList, ",");
295709fac06SJung-uk Kim 
296709fac06SJung-uk Kim     while (Path)
297709fac06SJung-uk Kim     {
298709fac06SJung-uk Kim         TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1);
299709fac06SJung-uk Kim         if (!TmpPath)
300709fac06SJung-uk Kim         {
301709fac06SJung-uk Kim             return (AE_NO_MEMORY);
302709fac06SJung-uk Kim         }
303709fac06SJung-uk Kim 
304709fac06SJung-uk Kim         ACPI_STRCPY (TmpPath, Path);
305709fac06SJung-uk Kim 
306709fac06SJung-uk Kim         ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
307709fac06SJung-uk Kim         if (!ExternalFile)
308709fac06SJung-uk Kim         {
309709fac06SJung-uk Kim             ACPI_FREE (TmpPath);
310709fac06SJung-uk Kim             return (AE_NO_MEMORY);
311709fac06SJung-uk Kim         }
312709fac06SJung-uk Kim 
313709fac06SJung-uk Kim         ExternalFile->Path = TmpPath;
314709fac06SJung-uk Kim 
315709fac06SJung-uk Kim         if (AcpiGbl_ExternalFileList)
316709fac06SJung-uk Kim         {
317709fac06SJung-uk Kim             ExternalFile->Next = AcpiGbl_ExternalFileList;
318709fac06SJung-uk Kim         }
319709fac06SJung-uk Kim 
320709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = ExternalFile;
321709fac06SJung-uk Kim         Path = strtok (NULL, ",");
322709fac06SJung-uk Kim     }
323709fac06SJung-uk Kim 
324709fac06SJung-uk Kim     return (AE_OK);
325709fac06SJung-uk Kim }
326709fac06SJung-uk Kim 
327709fac06SJung-uk Kim 
328709fac06SJung-uk Kim /*******************************************************************************
329709fac06SJung-uk Kim  *
330709fac06SJung-uk Kim  * FUNCTION:    AcpiDmClearExternalFileList
331709fac06SJung-uk Kim  *
332709fac06SJung-uk Kim  * PARAMETERS:  None
333709fac06SJung-uk Kim  *
334709fac06SJung-uk Kim  * RETURN:      None
335709fac06SJung-uk Kim  *
336709fac06SJung-uk Kim  * DESCRIPTION: Clear the external file list
337709fac06SJung-uk Kim  *
338709fac06SJung-uk Kim  ******************************************************************************/
339709fac06SJung-uk Kim 
340709fac06SJung-uk Kim void
341709fac06SJung-uk Kim AcpiDmClearExternalFileList (
342709fac06SJung-uk Kim     void)
343709fac06SJung-uk Kim {
344709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *NextExternal;
345709fac06SJung-uk Kim 
346709fac06SJung-uk Kim 
347709fac06SJung-uk Kim     while (AcpiGbl_ExternalFileList)
348709fac06SJung-uk Kim     {
349709fac06SJung-uk Kim         NextExternal = AcpiGbl_ExternalFileList->Next;
350709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
351709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList);
352709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = NextExternal;
353709fac06SJung-uk Kim     }
354709fac06SJung-uk Kim }
355709fac06SJung-uk Kim 
356709fac06SJung-uk Kim 
357709fac06SJung-uk Kim /*******************************************************************************
358709fac06SJung-uk Kim  *
359f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalList
360f556842eSJung-uk Kim  *
361f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Current parser Op
362f556842eSJung-uk Kim  *              Path                - Internal (AML) path to the object
363f556842eSJung-uk Kim  *              Type                - ACPI object type to be added
364f556842eSJung-uk Kim  *              Value               - Arg count if adding a Method object
365f556842eSJung-uk Kim  *
366f556842eSJung-uk Kim  * RETURN:      None
367f556842eSJung-uk Kim  *
368f556842eSJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
369f556842eSJung-uk Kim  *              will in turn be later emitted as an External() declaration
370f556842eSJung-uk Kim  *              in the disassembled output.
371f556842eSJung-uk Kim  *
372f556842eSJung-uk Kim  ******************************************************************************/
373f556842eSJung-uk Kim 
374f556842eSJung-uk Kim void
375f556842eSJung-uk Kim AcpiDmAddToExternalList (
376f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
377f556842eSJung-uk Kim     char                    *Path,
378f556842eSJung-uk Kim     UINT8                   Type,
379f556842eSJung-uk Kim     UINT32                  Value)
380f556842eSJung-uk Kim {
381f556842eSJung-uk Kim     char                    *ExternalPath;
382f556842eSJung-uk Kim     char                    *Fullpath = NULL;
383f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NewExternal;
384f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
385f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
386f556842eSJung-uk Kim     ACPI_STATUS             Status;
3879c48c75eSJung-uk Kim     BOOLEAN                 Resolved = FALSE;
388f556842eSJung-uk Kim 
389f556842eSJung-uk Kim 
390f556842eSJung-uk Kim     if (!Path)
391f556842eSJung-uk Kim     {
392f556842eSJung-uk Kim         return;
393f556842eSJung-uk Kim     }
394f556842eSJung-uk Kim 
3959c48c75eSJung-uk Kim     if (Type == ACPI_TYPE_METHOD)
3969c48c75eSJung-uk Kim     {
3979c48c75eSJung-uk Kim         if (Value & 0x80)
3989c48c75eSJung-uk Kim         {
3999c48c75eSJung-uk Kim             Resolved = TRUE;
4009c48c75eSJung-uk Kim         }
4019c48c75eSJung-uk Kim         Value &= 0x07;
4029c48c75eSJung-uk Kim     }
4039c48c75eSJung-uk Kim 
404ed17e06eSJung-uk Kim     /*
405ed17e06eSJung-uk Kim      * We don't want External() statements to contain a leading '\'.
406ed17e06eSJung-uk Kim      * This prevents duplicate external statements of the form:
407ed17e06eSJung-uk Kim      *
408ed17e06eSJung-uk Kim      *    External (\ABCD)
409ed17e06eSJung-uk Kim      *    External (ABCD)
410ed17e06eSJung-uk Kim      *
411ed17e06eSJung-uk Kim      * This would cause a compile time error when the disassembled
412ed17e06eSJung-uk Kim      * output file is recompiled.
413ed17e06eSJung-uk Kim      */
414ed17e06eSJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
415ed17e06eSJung-uk Kim     {
416ed17e06eSJung-uk Kim         Path++;
417ed17e06eSJung-uk Kim     }
418ed17e06eSJung-uk Kim 
419ed17e06eSJung-uk Kim     /* Externalize the ACPI pathname */
420f556842eSJung-uk Kim 
421f556842eSJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
422f556842eSJung-uk Kim                 NULL, &ExternalPath);
423f556842eSJung-uk Kim     if (ACPI_FAILURE (Status))
424f556842eSJung-uk Kim     {
425f556842eSJung-uk Kim         return;
426f556842eSJung-uk Kim     }
427f556842eSJung-uk Kim 
428ed17e06eSJung-uk Kim     /*
429ed17e06eSJung-uk Kim      * Get the full pathname from the root if "Path" has one or more
430ed17e06eSJung-uk Kim      * parent prefixes (^). Note: path will not contain a leading '\'.
431ed17e06eSJung-uk Kim      */
432f556842eSJung-uk Kim     if (*Path == (UINT8) AML_PARENT_PREFIX)
433f556842eSJung-uk Kim     {
434f556842eSJung-uk Kim         Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
435f556842eSJung-uk Kim         if (Fullpath)
436f556842eSJung-uk Kim         {
437f556842eSJung-uk Kim             /* Set new external path */
438f556842eSJung-uk Kim 
439f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
440f556842eSJung-uk Kim             ExternalPath = Fullpath;
441f556842eSJung-uk Kim         }
442f556842eSJung-uk Kim     }
443f556842eSJung-uk Kim 
444f556842eSJung-uk Kim     /* Check all existing externals to ensure no duplicates */
445f556842eSJung-uk Kim 
446f556842eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
447f556842eSJung-uk Kim     while (NextExternal)
448f556842eSJung-uk Kim     {
449f556842eSJung-uk Kim         if (!ACPI_STRCMP (ExternalPath, NextExternal->Path))
450f556842eSJung-uk Kim         {
451f556842eSJung-uk Kim             /* Duplicate method, check that the Value (ArgCount) is the same */
452f556842eSJung-uk Kim 
453f556842eSJung-uk Kim             if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
454f556842eSJung-uk Kim                 (NextExternal->Value != Value))
455f556842eSJung-uk Kim             {
456f556842eSJung-uk Kim                 ACPI_ERROR ((AE_INFO,
457*79c6d946SJung-uk Kim                     "External method arg count mismatch %s: Current %u, attempted %u",
458f556842eSJung-uk Kim                     NextExternal->Path, NextExternal->Value, Value));
459f556842eSJung-uk Kim             }
460f556842eSJung-uk Kim 
461f556842eSJung-uk Kim             /* Allow upgrade of type from ANY */
462f556842eSJung-uk Kim 
463f556842eSJung-uk Kim             else if (NextExternal->Type == ACPI_TYPE_ANY)
464f556842eSJung-uk Kim             {
465f556842eSJung-uk Kim                 NextExternal->Type = Type;
466f556842eSJung-uk Kim                 NextExternal->Value = Value;
467f556842eSJung-uk Kim             }
468f556842eSJung-uk Kim 
469f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
470f556842eSJung-uk Kim             return;
471f556842eSJung-uk Kim         }
472f556842eSJung-uk Kim 
473f556842eSJung-uk Kim         NextExternal = NextExternal->Next;
474f556842eSJung-uk Kim     }
475f556842eSJung-uk Kim 
476f556842eSJung-uk Kim     /* Allocate and init a new External() descriptor */
477f556842eSJung-uk Kim 
478f556842eSJung-uk Kim     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
479f556842eSJung-uk Kim     if (!NewExternal)
480f556842eSJung-uk Kim     {
481f556842eSJung-uk Kim         ACPI_FREE (ExternalPath);
482f556842eSJung-uk Kim         return;
483f556842eSJung-uk Kim     }
484f556842eSJung-uk Kim 
485f556842eSJung-uk Kim     NewExternal->Path = ExternalPath;
486f556842eSJung-uk Kim     NewExternal->Type = Type;
487f556842eSJung-uk Kim     NewExternal->Value = Value;
4889c48c75eSJung-uk Kim     NewExternal->Resolved = Resolved;
489f556842eSJung-uk Kim     NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath);
490f556842eSJung-uk Kim 
491f556842eSJung-uk Kim     /* Was the external path with parent prefix normalized to a fullpath? */
492f556842eSJung-uk Kim 
493f556842eSJung-uk Kim     if (Fullpath == ExternalPath)
494f556842eSJung-uk Kim     {
495f556842eSJung-uk Kim         /* Get new internal path */
496f556842eSJung-uk Kim 
497f556842eSJung-uk Kim         Status = AcpiNsInternalizeName (ExternalPath, &Path);
498f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
499f556842eSJung-uk Kim         {
500f556842eSJung-uk Kim             ACPI_FREE (ExternalPath);
501f556842eSJung-uk Kim             ACPI_FREE (NewExternal);
502f556842eSJung-uk Kim             return;
503f556842eSJung-uk Kim         }
504f556842eSJung-uk Kim 
505f556842eSJung-uk Kim         /* Set flag to indicate External->InternalPath need to be freed */
506f556842eSJung-uk Kim 
507f556842eSJung-uk Kim         NewExternal->Flags |= ACPI_IPATH_ALLOCATED;
508f556842eSJung-uk Kim     }
509f556842eSJung-uk Kim 
510f556842eSJung-uk Kim     NewExternal->InternalPath = Path;
511f556842eSJung-uk Kim 
512a7a3b383SJung-uk Kim     /* Link the new descriptor into the global list, alphabetically ordered */
513f556842eSJung-uk Kim 
514f556842eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
515f556842eSJung-uk Kim     while (NextExternal)
516f556842eSJung-uk Kim     {
517a7a3b383SJung-uk Kim         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
518f556842eSJung-uk Kim         {
519f556842eSJung-uk Kim             if (PrevExternal)
520f556842eSJung-uk Kim             {
521f556842eSJung-uk Kim                 PrevExternal->Next = NewExternal;
522f556842eSJung-uk Kim             }
523f556842eSJung-uk Kim             else
524f556842eSJung-uk Kim             {
525f556842eSJung-uk Kim                 AcpiGbl_ExternalList = NewExternal;
526f556842eSJung-uk Kim             }
527f556842eSJung-uk Kim 
528f556842eSJung-uk Kim             NewExternal->Next = NextExternal;
529f556842eSJung-uk Kim             return;
530f556842eSJung-uk Kim         }
531f556842eSJung-uk Kim 
532f556842eSJung-uk Kim         PrevExternal = NextExternal;
533f556842eSJung-uk Kim         NextExternal = NextExternal->Next;
534f556842eSJung-uk Kim     }
535f556842eSJung-uk Kim 
536f556842eSJung-uk Kim     if (PrevExternal)
537f556842eSJung-uk Kim     {
538f556842eSJung-uk Kim         PrevExternal->Next = NewExternal;
539f556842eSJung-uk Kim     }
540f556842eSJung-uk Kim     else
541f556842eSJung-uk Kim     {
542f556842eSJung-uk Kim         AcpiGbl_ExternalList = NewExternal;
543f556842eSJung-uk Kim     }
544f556842eSJung-uk Kim }
545f556842eSJung-uk Kim 
546f556842eSJung-uk Kim 
547f556842eSJung-uk Kim /*******************************************************************************
548f556842eSJung-uk Kim  *
549*79c6d946SJung-uk Kim  * FUNCTION:    AcpiDmGetExternalsFromFile
550*79c6d946SJung-uk Kim  *
551*79c6d946SJung-uk Kim  * PARAMETERS:  None
552*79c6d946SJung-uk Kim  *
553*79c6d946SJung-uk Kim  * RETURN:      None
554*79c6d946SJung-uk Kim  *
555*79c6d946SJung-uk Kim  * DESCRIPTION: Process the optional external reference file.
556*79c6d946SJung-uk Kim  *
557*79c6d946SJung-uk Kim  * Each line in the file should be of the form:
558*79c6d946SJung-uk Kim  *      External (<Method namepath>, MethodObj, <ArgCount>)
559*79c6d946SJung-uk Kim  *
560*79c6d946SJung-uk Kim  * Example:
561*79c6d946SJung-uk Kim  *      External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
562*79c6d946SJung-uk Kim  *
563*79c6d946SJung-uk Kim  ******************************************************************************/
564*79c6d946SJung-uk Kim 
565*79c6d946SJung-uk Kim void
566*79c6d946SJung-uk Kim AcpiDmGetExternalsFromFile (
567*79c6d946SJung-uk Kim     void)
568*79c6d946SJung-uk Kim {
569*79c6d946SJung-uk Kim     FILE                    *ExternalRefFile;
570*79c6d946SJung-uk Kim     char                    *Token;
571*79c6d946SJung-uk Kim     char                    *MethodName;
572*79c6d946SJung-uk Kim     UINT32                  ArgCount;
573*79c6d946SJung-uk Kim     UINT32                  ImportCount = 0;
574*79c6d946SJung-uk Kim 
575*79c6d946SJung-uk Kim 
576*79c6d946SJung-uk Kim     if (!Gbl_ExternalRefFilename)
577*79c6d946SJung-uk Kim     {
578*79c6d946SJung-uk Kim         return;
579*79c6d946SJung-uk Kim     }
580*79c6d946SJung-uk Kim 
581*79c6d946SJung-uk Kim     /* Open the file */
582*79c6d946SJung-uk Kim 
583*79c6d946SJung-uk Kim     ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
584*79c6d946SJung-uk Kim     if (!ExternalRefFile)
585*79c6d946SJung-uk Kim     {
586*79c6d946SJung-uk Kim         fprintf (stderr, "Could not open external reference file \"%s\"\n",
587*79c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
588*79c6d946SJung-uk Kim         return;
589*79c6d946SJung-uk Kim     }
590*79c6d946SJung-uk Kim 
591*79c6d946SJung-uk Kim     /* Each line defines a method */
592*79c6d946SJung-uk Kim 
593*79c6d946SJung-uk Kim     while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
594*79c6d946SJung-uk Kim     {
595*79c6d946SJung-uk Kim         Token = strtok (StringBuffer, METHOD_SEPARATORS);   /* "External" */
596*79c6d946SJung-uk Kim         if (!Token) continue;
597*79c6d946SJung-uk Kim         if (strcmp (Token, "External")) continue;
598*79c6d946SJung-uk Kim 
599*79c6d946SJung-uk Kim         MethodName = strtok (NULL, METHOD_SEPARATORS);      /* Method namepath */
600*79c6d946SJung-uk Kim         if (!MethodName) continue;
601*79c6d946SJung-uk Kim 
602*79c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* "MethodObj" */
603*79c6d946SJung-uk Kim         if (!Token) continue;
604*79c6d946SJung-uk Kim         if (strcmp (Token, "MethodObj")) continue;
605*79c6d946SJung-uk Kim 
606*79c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* Arg count */
607*79c6d946SJung-uk Kim         if (!Token) continue;
608*79c6d946SJung-uk Kim 
609*79c6d946SJung-uk Kim         /* Convert arg count string to an integer */
610*79c6d946SJung-uk Kim 
611*79c6d946SJung-uk Kim         errno = 0;
612*79c6d946SJung-uk Kim         ArgCount = strtoul (Token, NULL, 0);
613*79c6d946SJung-uk Kim         if (errno)
614*79c6d946SJung-uk Kim         {
615*79c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%s)\n", Token);
616*79c6d946SJung-uk Kim             continue;
617*79c6d946SJung-uk Kim         }
618*79c6d946SJung-uk Kim         if (ArgCount > 7)
619*79c6d946SJung-uk Kim         {
620*79c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
621*79c6d946SJung-uk Kim             continue;
622*79c6d946SJung-uk Kim         }
623*79c6d946SJung-uk Kim 
624*79c6d946SJung-uk Kim         /* Add this external to the global list */
625*79c6d946SJung-uk Kim 
626*79c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
627*79c6d946SJung-uk Kim             Gbl_ExternalRefFilename, ArgCount, MethodName);
628*79c6d946SJung-uk Kim 
629*79c6d946SJung-uk Kim         AcpiDmAddToExternalListFromFile (MethodName, ACPI_TYPE_METHOD, ArgCount | 0x80);
630*79c6d946SJung-uk Kim         ImportCount++;
631*79c6d946SJung-uk Kim     }
632*79c6d946SJung-uk Kim 
633*79c6d946SJung-uk Kim     if (!ImportCount)
634*79c6d946SJung-uk Kim     {
635*79c6d946SJung-uk Kim         fprintf (stderr, "Did not find any external methods in reference file \"%s\"\n",
636*79c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
637*79c6d946SJung-uk Kim     }
638*79c6d946SJung-uk Kim     else
639*79c6d946SJung-uk Kim     {
640*79c6d946SJung-uk Kim         /* Add the external(s) to the namespace */
641*79c6d946SJung-uk Kim 
642*79c6d946SJung-uk Kim         AcpiDmAddExternalsToNamespace ();
643*79c6d946SJung-uk Kim 
644*79c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Imported %u external method definitions\n",
645*79c6d946SJung-uk Kim             Gbl_ExternalRefFilename, ImportCount);
646*79c6d946SJung-uk Kim     }
647*79c6d946SJung-uk Kim 
648*79c6d946SJung-uk Kim     fclose (ExternalRefFile);
649*79c6d946SJung-uk Kim }
650*79c6d946SJung-uk Kim 
651*79c6d946SJung-uk Kim 
652*79c6d946SJung-uk Kim /*******************************************************************************
653*79c6d946SJung-uk Kim  *
654*79c6d946SJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalListFromFile
655*79c6d946SJung-uk Kim  *
656*79c6d946SJung-uk Kim  * PARAMETERS:  Path                - Internal (AML) path to the object
657*79c6d946SJung-uk Kim  *              Type                - ACPI object type to be added
658*79c6d946SJung-uk Kim  *              Value               - Arg count if adding a Method object
659*79c6d946SJung-uk Kim  *
660*79c6d946SJung-uk Kim  * RETURN:      None
661*79c6d946SJung-uk Kim  *
662*79c6d946SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
663*79c6d946SJung-uk Kim  *              will in turn be later emitted as an External() declaration
664*79c6d946SJung-uk Kim  *              in the disassembled output.
665*79c6d946SJung-uk Kim  *
666*79c6d946SJung-uk Kim  ******************************************************************************/
667*79c6d946SJung-uk Kim 
668*79c6d946SJung-uk Kim static void
669*79c6d946SJung-uk Kim AcpiDmAddToExternalListFromFile (
670*79c6d946SJung-uk Kim     char                    *Path,
671*79c6d946SJung-uk Kim     UINT8                   Type,
672*79c6d946SJung-uk Kim     UINT32                  Value)
673*79c6d946SJung-uk Kim {
674*79c6d946SJung-uk Kim     char                    *InternalPath;
675*79c6d946SJung-uk Kim     char                    *ExternalPath;
676*79c6d946SJung-uk Kim     ACPI_EXTERNAL_LIST      *NewExternal;
677*79c6d946SJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
678*79c6d946SJung-uk Kim     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
679*79c6d946SJung-uk Kim     ACPI_STATUS             Status;
680*79c6d946SJung-uk Kim     BOOLEAN                 Resolved = FALSE;
681*79c6d946SJung-uk Kim 
682*79c6d946SJung-uk Kim 
683*79c6d946SJung-uk Kim     if (!Path)
684*79c6d946SJung-uk Kim     {
685*79c6d946SJung-uk Kim         return;
686*79c6d946SJung-uk Kim     }
687*79c6d946SJung-uk Kim 
688*79c6d946SJung-uk Kim     /* TBD: Add a flags parameter */
689*79c6d946SJung-uk Kim 
690*79c6d946SJung-uk Kim     if (Type == ACPI_TYPE_METHOD)
691*79c6d946SJung-uk Kim     {
692*79c6d946SJung-uk Kim         if (Value & 0x80)
693*79c6d946SJung-uk Kim         {
694*79c6d946SJung-uk Kim             Resolved = TRUE;
695*79c6d946SJung-uk Kim         }
696*79c6d946SJung-uk Kim         Value &= 0x07;
697*79c6d946SJung-uk Kim     }
698*79c6d946SJung-uk Kim 
699*79c6d946SJung-uk Kim     /*
700*79c6d946SJung-uk Kim      * We don't want External() statements to contain a leading '\'.
701*79c6d946SJung-uk Kim      * This prevents duplicate external statements of the form:
702*79c6d946SJung-uk Kim      *
703*79c6d946SJung-uk Kim      *    External (\ABCD)
704*79c6d946SJung-uk Kim      *    External (ABCD)
705*79c6d946SJung-uk Kim      *
706*79c6d946SJung-uk Kim      * This would cause a compile time error when the disassembled
707*79c6d946SJung-uk Kim      * output file is recompiled.
708*79c6d946SJung-uk Kim      */
709*79c6d946SJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
710*79c6d946SJung-uk Kim     {
711*79c6d946SJung-uk Kim         Path++;
712*79c6d946SJung-uk Kim     }
713*79c6d946SJung-uk Kim 
714*79c6d946SJung-uk Kim     /* Check all existing externals to ensure no duplicates */
715*79c6d946SJung-uk Kim 
716*79c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
717*79c6d946SJung-uk Kim     while (NextExternal)
718*79c6d946SJung-uk Kim     {
719*79c6d946SJung-uk Kim         if (!ACPI_STRCMP (Path, NextExternal->Path))
720*79c6d946SJung-uk Kim         {
721*79c6d946SJung-uk Kim             /* Duplicate method, check that the Value (ArgCount) is the same */
722*79c6d946SJung-uk Kim 
723*79c6d946SJung-uk Kim             if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
724*79c6d946SJung-uk Kim                 (NextExternal->Value != Value))
725*79c6d946SJung-uk Kim             {
726*79c6d946SJung-uk Kim                 ACPI_ERROR ((AE_INFO,
727*79c6d946SJung-uk Kim                     "(File) External method arg count mismatch %s: Current %u, override to %u",
728*79c6d946SJung-uk Kim                     NextExternal->Path, NextExternal->Value, Value));
729*79c6d946SJung-uk Kim 
730*79c6d946SJung-uk Kim                 /* Override, since new value came from external reference file */
731*79c6d946SJung-uk Kim 
732*79c6d946SJung-uk Kim                 NextExternal->Value = Value;
733*79c6d946SJung-uk Kim             }
734*79c6d946SJung-uk Kim 
735*79c6d946SJung-uk Kim             /* Allow upgrade of type from ANY */
736*79c6d946SJung-uk Kim 
737*79c6d946SJung-uk Kim             else if (NextExternal->Type == ACPI_TYPE_ANY)
738*79c6d946SJung-uk Kim             {
739*79c6d946SJung-uk Kim                 NextExternal->Type = Type;
740*79c6d946SJung-uk Kim                 NextExternal->Value = Value;
741*79c6d946SJung-uk Kim             }
742*79c6d946SJung-uk Kim 
743*79c6d946SJung-uk Kim             return;
744*79c6d946SJung-uk Kim         }
745*79c6d946SJung-uk Kim 
746*79c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
747*79c6d946SJung-uk Kim     }
748*79c6d946SJung-uk Kim 
749*79c6d946SJung-uk Kim     /* Get the internal pathname (AML format) */
750*79c6d946SJung-uk Kim 
751*79c6d946SJung-uk Kim     Status = AcpiNsInternalizeName (Path, &InternalPath);
752*79c6d946SJung-uk Kim     if (ACPI_FAILURE (Status))
753*79c6d946SJung-uk Kim     {
754*79c6d946SJung-uk Kim         return;
755*79c6d946SJung-uk Kim     }
756*79c6d946SJung-uk Kim 
757*79c6d946SJung-uk Kim     /* Allocate and init a new External() descriptor */
758*79c6d946SJung-uk Kim 
759*79c6d946SJung-uk Kim     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
760*79c6d946SJung-uk Kim     if (!NewExternal)
761*79c6d946SJung-uk Kim     {
762*79c6d946SJung-uk Kim         ACPI_FREE (InternalPath);
763*79c6d946SJung-uk Kim         return;
764*79c6d946SJung-uk Kim     }
765*79c6d946SJung-uk Kim 
766*79c6d946SJung-uk Kim     /* Must copy and normalize the input path */
767*79c6d946SJung-uk Kim 
768*79c6d946SJung-uk Kim     AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath, NULL, &ExternalPath);
769*79c6d946SJung-uk Kim 
770*79c6d946SJung-uk Kim     NewExternal->Path = ExternalPath;
771*79c6d946SJung-uk Kim     NewExternal->Type = Type;
772*79c6d946SJung-uk Kim     NewExternal->Value = Value;
773*79c6d946SJung-uk Kim     NewExternal->Resolved = Resolved;
774*79c6d946SJung-uk Kim     NewExternal->Length = (UINT16) ACPI_STRLEN (Path);
775*79c6d946SJung-uk Kim     NewExternal->InternalPath = InternalPath;
776*79c6d946SJung-uk Kim 
777*79c6d946SJung-uk Kim     /* Set flag to indicate External->InternalPath needs to be freed */
778*79c6d946SJung-uk Kim 
779*79c6d946SJung-uk Kim     NewExternal->Flags |= ACPI_IPATH_ALLOCATED | ACPI_FROM_REFERENCE_FILE;
780*79c6d946SJung-uk Kim 
781*79c6d946SJung-uk Kim     /* Link the new descriptor into the global list, alphabetically ordered */
782*79c6d946SJung-uk Kim 
783*79c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
784*79c6d946SJung-uk Kim     while (NextExternal)
785*79c6d946SJung-uk Kim     {
786*79c6d946SJung-uk Kim         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
787*79c6d946SJung-uk Kim         {
788*79c6d946SJung-uk Kim             if (PrevExternal)
789*79c6d946SJung-uk Kim             {
790*79c6d946SJung-uk Kim                 PrevExternal->Next = NewExternal;
791*79c6d946SJung-uk Kim             }
792*79c6d946SJung-uk Kim             else
793*79c6d946SJung-uk Kim             {
794*79c6d946SJung-uk Kim                 AcpiGbl_ExternalList = NewExternal;
795*79c6d946SJung-uk Kim             }
796*79c6d946SJung-uk Kim 
797*79c6d946SJung-uk Kim             NewExternal->Next = NextExternal;
798*79c6d946SJung-uk Kim             return;
799*79c6d946SJung-uk Kim         }
800*79c6d946SJung-uk Kim 
801*79c6d946SJung-uk Kim         PrevExternal = NextExternal;
802*79c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
803*79c6d946SJung-uk Kim     }
804*79c6d946SJung-uk Kim 
805*79c6d946SJung-uk Kim     if (PrevExternal)
806*79c6d946SJung-uk Kim     {
807*79c6d946SJung-uk Kim         PrevExternal->Next = NewExternal;
808*79c6d946SJung-uk Kim     }
809*79c6d946SJung-uk Kim     else
810*79c6d946SJung-uk Kim     {
811*79c6d946SJung-uk Kim         AcpiGbl_ExternalList = NewExternal;
812*79c6d946SJung-uk Kim     }
813*79c6d946SJung-uk Kim }
814*79c6d946SJung-uk Kim 
815*79c6d946SJung-uk Kim 
816*79c6d946SJung-uk Kim /*******************************************************************************
817*79c6d946SJung-uk Kim  *
818f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddExternalsToNamespace
819f556842eSJung-uk Kim  *
820f556842eSJung-uk Kim  * PARAMETERS:  None
821f556842eSJung-uk Kim  *
822f556842eSJung-uk Kim  * RETURN:      None
823f556842eSJung-uk Kim  *
824f556842eSJung-uk Kim  * DESCRIPTION: Add all externals to the namespace. Allows externals to be
825f556842eSJung-uk Kim  *              "resolved".
826f556842eSJung-uk Kim  *
827f556842eSJung-uk Kim  ******************************************************************************/
828f556842eSJung-uk Kim 
829f556842eSJung-uk Kim void
830f556842eSJung-uk Kim AcpiDmAddExternalsToNamespace (
831f556842eSJung-uk Kim     void)
832f556842eSJung-uk Kim {
833f556842eSJung-uk Kim     ACPI_STATUS             Status;
834f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
835a7a3b383SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
836f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
837f556842eSJung-uk Kim 
838f556842eSJung-uk Kim 
839f556842eSJung-uk Kim     while (External)
840f556842eSJung-uk Kim     {
841f556842eSJung-uk Kim         /* Add the external name (object) into the namespace */
842f556842eSJung-uk Kim 
843f556842eSJung-uk Kim         Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
844f556842eSJung-uk Kim                    ACPI_IMODE_LOAD_PASS1,
845*79c6d946SJung-uk Kim                    ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
846f556842eSJung-uk Kim                    NULL, &Node);
847f556842eSJung-uk Kim 
848f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
849f556842eSJung-uk Kim         {
850f556842eSJung-uk Kim             ACPI_EXCEPTION ((AE_INFO, Status,
851f556842eSJung-uk Kim                 "while adding external to namespace [%s]",
852f556842eSJung-uk Kim                 External->Path));
853f556842eSJung-uk Kim         }
854a7a3b383SJung-uk Kim 
855a7a3b383SJung-uk Kim         else switch (External->Type)
856f556842eSJung-uk Kim         {
857a7a3b383SJung-uk Kim         case ACPI_TYPE_METHOD:
858a7a3b383SJung-uk Kim 
859f556842eSJung-uk Kim             /* For methods, we need to save the argument count */
860f556842eSJung-uk Kim 
861a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
862a7a3b383SJung-uk Kim             ObjDesc->Method.ParamCount = (UINT8) External->Value;
863a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
864a7a3b383SJung-uk Kim             break;
865a7a3b383SJung-uk Kim 
866a7a3b383SJung-uk Kim         case ACPI_TYPE_REGION:
867a7a3b383SJung-uk Kim 
868a7a3b383SJung-uk Kim             /* Regions require a region sub-object */
869a7a3b383SJung-uk Kim 
870a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
871a7a3b383SJung-uk Kim             ObjDesc->Region.Node = Node;
872a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
873a7a3b383SJung-uk Kim             break;
874a7a3b383SJung-uk Kim 
875a7a3b383SJung-uk Kim         default:
876a9d8d09cSJung-uk Kim 
877a7a3b383SJung-uk Kim             break;
878f556842eSJung-uk Kim         }
879f556842eSJung-uk Kim 
880f556842eSJung-uk Kim         External = External->Next;
881f556842eSJung-uk Kim     }
882f556842eSJung-uk Kim }
883f556842eSJung-uk Kim 
884f556842eSJung-uk Kim 
885f556842eSJung-uk Kim /*******************************************************************************
886f556842eSJung-uk Kim  *
887f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetExternalMethodCount
888f556842eSJung-uk Kim  *
889f556842eSJung-uk Kim  * PARAMETERS:  None
890f556842eSJung-uk Kim  *
891f556842eSJung-uk Kim  * RETURN:      The number of control method externals in the external list
892f556842eSJung-uk Kim  *
893f556842eSJung-uk Kim  * DESCRIPTION: Return the number of method externals that have been generated.
894f556842eSJung-uk Kim  *              If any control method externals have been found, we must
895f556842eSJung-uk Kim  *              re-parse the entire definition block with the new information
896f556842eSJung-uk Kim  *              (number of arguments for the methods.) This is limitation of
897f556842eSJung-uk Kim  *              AML, we don't know the number of arguments from the control
898f556842eSJung-uk Kim  *              method invocation itself.
899f556842eSJung-uk Kim  *
900f556842eSJung-uk Kim  ******************************************************************************/
901f556842eSJung-uk Kim 
902f556842eSJung-uk Kim UINT32
903f556842eSJung-uk Kim AcpiDmGetExternalMethodCount (
904f556842eSJung-uk Kim     void)
905f556842eSJung-uk Kim {
906f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
907f556842eSJung-uk Kim     UINT32                  Count = 0;
908f556842eSJung-uk Kim 
909f556842eSJung-uk Kim 
910f556842eSJung-uk Kim     while (External)
911f556842eSJung-uk Kim     {
912f556842eSJung-uk Kim         if (External->Type == ACPI_TYPE_METHOD)
913f556842eSJung-uk Kim         {
914f556842eSJung-uk Kim             Count++;
915f556842eSJung-uk Kim         }
916f556842eSJung-uk Kim 
917f556842eSJung-uk Kim         External = External->Next;
918f556842eSJung-uk Kim     }
919f556842eSJung-uk Kim 
920f556842eSJung-uk Kim     return (Count);
921f556842eSJung-uk Kim }
922f556842eSJung-uk Kim 
923f556842eSJung-uk Kim 
924f556842eSJung-uk Kim /*******************************************************************************
925f556842eSJung-uk Kim  *
926f556842eSJung-uk Kim  * FUNCTION:    AcpiDmClearExternalList
927f556842eSJung-uk Kim  *
928f556842eSJung-uk Kim  * PARAMETERS:  None
929f556842eSJung-uk Kim  *
930f556842eSJung-uk Kim  * RETURN:      None
931f556842eSJung-uk Kim  *
932f556842eSJung-uk Kim  * DESCRIPTION: Free the entire External info list
933f556842eSJung-uk Kim  *
934f556842eSJung-uk Kim  ******************************************************************************/
935f556842eSJung-uk Kim 
936f556842eSJung-uk Kim void
937f556842eSJung-uk Kim AcpiDmClearExternalList (
938f556842eSJung-uk Kim     void)
939f556842eSJung-uk Kim {
940f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
941f556842eSJung-uk Kim 
942f556842eSJung-uk Kim 
943f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
944f556842eSJung-uk Kim     {
945f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
946f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
947f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
948f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
949f556842eSJung-uk Kim     }
950f556842eSJung-uk Kim }
951f556842eSJung-uk Kim 
952f556842eSJung-uk Kim 
953f556842eSJung-uk Kim /*******************************************************************************
954f556842eSJung-uk Kim  *
955f556842eSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternals
956f556842eSJung-uk Kim  *
957f556842eSJung-uk Kim  * PARAMETERS:  None
958f556842eSJung-uk Kim  *
959f556842eSJung-uk Kim  * RETURN:      None
960f556842eSJung-uk Kim  *
961f556842eSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
962f556842eSJung-uk Kim  *              the global external info list.
963f556842eSJung-uk Kim  *
964f556842eSJung-uk Kim  ******************************************************************************/
965f556842eSJung-uk Kim 
966f556842eSJung-uk Kim void
967f556842eSJung-uk Kim AcpiDmEmitExternals (
968f556842eSJung-uk Kim     void)
969f556842eSJung-uk Kim {
970f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
971f556842eSJung-uk Kim 
972f556842eSJung-uk Kim 
973f556842eSJung-uk Kim     if (!AcpiGbl_ExternalList)
974f556842eSJung-uk Kim     {
975f556842eSJung-uk Kim         return;
976f556842eSJung-uk Kim     }
977f556842eSJung-uk Kim 
978f556842eSJung-uk Kim     /*
9799c48c75eSJung-uk Kim      * Determine the number of control methods in the external list, and
9809c48c75eSJung-uk Kim      * also how many of those externals were resolved via the namespace.
9819c48c75eSJung-uk Kim      */
9829c48c75eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
9839c48c75eSJung-uk Kim     while (NextExternal)
9849c48c75eSJung-uk Kim     {
9859c48c75eSJung-uk Kim         if (NextExternal->Type == ACPI_TYPE_METHOD)
9869c48c75eSJung-uk Kim         {
9879c48c75eSJung-uk Kim             AcpiGbl_NumExternalMethods++;
9889c48c75eSJung-uk Kim             if (NextExternal->Resolved)
9899c48c75eSJung-uk Kim             {
9909c48c75eSJung-uk Kim                 AcpiGbl_ResolvedExternalMethods++;
9919c48c75eSJung-uk Kim             }
9929c48c75eSJung-uk Kim         }
9939c48c75eSJung-uk Kim 
9949c48c75eSJung-uk Kim         NextExternal = NextExternal->Next;
9959c48c75eSJung-uk Kim     }
9969c48c75eSJung-uk Kim 
9979c48c75eSJung-uk Kim     /* Check if any control methods were unresolved */
9989c48c75eSJung-uk Kim 
9999c48c75eSJung-uk Kim     AcpiDmUnresolvedWarning (1);
10009c48c75eSJung-uk Kim 
1001bf6fac21SJung-uk Kim     /* Emit any unresolved method externals in a single text block */
1002bf6fac21SJung-uk Kim 
1003bf6fac21SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
1004bf6fac21SJung-uk Kim     while (NextExternal)
1005bf6fac21SJung-uk Kim     {
1006bf6fac21SJung-uk Kim         if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
1007bf6fac21SJung-uk Kim             (!NextExternal->Resolved))
1008bf6fac21SJung-uk Kim         {
1009bf6fac21SJung-uk Kim             AcpiOsPrintf ("    External (%s%s",
1010bf6fac21SJung-uk Kim                 NextExternal->Path,
1011bf6fac21SJung-uk Kim                 AcpiDmGetObjectTypeName (NextExternal->Type));
1012bf6fac21SJung-uk Kim 
1013*79c6d946SJung-uk Kim             AcpiOsPrintf (
1014*79c6d946SJung-uk Kim                 ")    // Warning: Unresolved Method, "
1015bf6fac21SJung-uk Kim                 "guessing %u arguments (may be incorrect, see warning above)\n",
1016bf6fac21SJung-uk Kim                 NextExternal->Value);
1017bf6fac21SJung-uk Kim 
1018bf6fac21SJung-uk Kim             NextExternal->Emitted = TRUE;
1019bf6fac21SJung-uk Kim         }
1020bf6fac21SJung-uk Kim 
1021bf6fac21SJung-uk Kim         NextExternal = NextExternal->Next;
1022bf6fac21SJung-uk Kim     }
1023bf6fac21SJung-uk Kim 
1024bf6fac21SJung-uk Kim     AcpiOsPrintf ("\n");
1025bf6fac21SJung-uk Kim 
1026*79c6d946SJung-uk Kim 
1027*79c6d946SJung-uk Kim     /* Emit externals that were imported from a file */
1028*79c6d946SJung-uk Kim 
1029*79c6d946SJung-uk Kim     if (Gbl_ExternalRefFilename)
1030*79c6d946SJung-uk Kim     {
1031*79c6d946SJung-uk Kim         AcpiOsPrintf (
1032*79c6d946SJung-uk Kim             "    /*\n     * External declarations that were imported from\n"
1033*79c6d946SJung-uk Kim             "     * the reference file [%s]\n     */\n",
1034*79c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
1035*79c6d946SJung-uk Kim 
1036*79c6d946SJung-uk Kim         NextExternal = AcpiGbl_ExternalList;
1037*79c6d946SJung-uk Kim         while (NextExternal)
1038*79c6d946SJung-uk Kim         {
1039*79c6d946SJung-uk Kim             if (!NextExternal->Emitted && (NextExternal->Flags & ACPI_FROM_REFERENCE_FILE))
1040*79c6d946SJung-uk Kim             {
1041*79c6d946SJung-uk Kim                 AcpiOsPrintf ("    External (%s%s",
1042*79c6d946SJung-uk Kim                     NextExternal->Path,
1043*79c6d946SJung-uk Kim                     AcpiDmGetObjectTypeName (NextExternal->Type));
1044*79c6d946SJung-uk Kim 
1045*79c6d946SJung-uk Kim                 if (NextExternal->Type == ACPI_TYPE_METHOD)
1046*79c6d946SJung-uk Kim                 {
1047*79c6d946SJung-uk Kim                     AcpiOsPrintf (")    // %u Arguments\n",
1048*79c6d946SJung-uk Kim                         NextExternal->Value);
1049*79c6d946SJung-uk Kim                 }
1050*79c6d946SJung-uk Kim                 else
1051*79c6d946SJung-uk Kim                 {
1052*79c6d946SJung-uk Kim                     AcpiOsPrintf (")\n");
1053*79c6d946SJung-uk Kim                 }
1054*79c6d946SJung-uk Kim                 NextExternal->Emitted = TRUE;
1055*79c6d946SJung-uk Kim             }
1056*79c6d946SJung-uk Kim 
1057*79c6d946SJung-uk Kim             NextExternal = NextExternal->Next;
1058*79c6d946SJung-uk Kim         }
1059*79c6d946SJung-uk Kim 
1060*79c6d946SJung-uk Kim         AcpiOsPrintf ("\n");
1061*79c6d946SJung-uk Kim     }
1062*79c6d946SJung-uk Kim 
10639c48c75eSJung-uk Kim     /*
1064*79c6d946SJung-uk Kim      * Walk the list of externals found during the AML parsing
1065f556842eSJung-uk Kim      */
1066f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
1067f556842eSJung-uk Kim     {
1068bf6fac21SJung-uk Kim         if (!AcpiGbl_ExternalList->Emitted)
1069bf6fac21SJung-uk Kim         {
1070f556842eSJung-uk Kim             AcpiOsPrintf ("    External (%s%s",
1071f556842eSJung-uk Kim                 AcpiGbl_ExternalList->Path,
1072f556842eSJung-uk Kim                 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1073f556842eSJung-uk Kim 
1074bf6fac21SJung-uk Kim             /* For methods, add a comment with the number of arguments */
1075bf6fac21SJung-uk Kim 
1076f556842eSJung-uk Kim             if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1077f556842eSJung-uk Kim             {
1078a88e22b7SJung-uk Kim                 AcpiOsPrintf (")    // %u Arguments\n",
1079f556842eSJung-uk Kim                     AcpiGbl_ExternalList->Value);
1080f556842eSJung-uk Kim             }
1081f556842eSJung-uk Kim             else
1082f556842eSJung-uk Kim             {
1083f556842eSJung-uk Kim                 AcpiOsPrintf (")\n");
1084f556842eSJung-uk Kim             }
1085bf6fac21SJung-uk Kim         }
1086f556842eSJung-uk Kim 
1087f556842eSJung-uk Kim         /* Free this external info block and move on to next external */
1088f556842eSJung-uk Kim 
1089f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
1090f556842eSJung-uk Kim         if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED)
1091f556842eSJung-uk Kim         {
1092f556842eSJung-uk Kim             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1093f556842eSJung-uk Kim         }
1094f556842eSJung-uk Kim 
1095f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
1096f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
1097f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
1098f556842eSJung-uk Kim     }
1099f556842eSJung-uk Kim 
1100f556842eSJung-uk Kim     AcpiOsPrintf ("\n");
1101f556842eSJung-uk Kim }
11029c48c75eSJung-uk Kim 
11039c48c75eSJung-uk Kim 
11049c48c75eSJung-uk Kim /*******************************************************************************
11059c48c75eSJung-uk Kim  *
11069c48c75eSJung-uk Kim  * FUNCTION:    AcpiDmUnresolvedWarning
11079c48c75eSJung-uk Kim  *
11089c48c75eSJung-uk Kim  * PARAMETERS:  Type                - Where to output the warning.
11099c48c75eSJung-uk Kim  *                                    0 means write to stderr
11109c48c75eSJung-uk Kim  *                                    1 means write to AcpiOsPrintf
11119c48c75eSJung-uk Kim  *
11129c48c75eSJung-uk Kim  * RETURN:      None
11139c48c75eSJung-uk Kim  *
11149c48c75eSJung-uk Kim  * DESCRIPTION: Issue warning message if there are unresolved external control
11159c48c75eSJung-uk Kim  *              methods within the disassembly.
11169c48c75eSJung-uk Kim  *
11179c48c75eSJung-uk Kim  ******************************************************************************/
11189c48c75eSJung-uk Kim 
11199c48c75eSJung-uk Kim #if 0
11209c48c75eSJung-uk Kim Summary of the external control method problem:
11219c48c75eSJung-uk Kim 
11229c48c75eSJung-uk Kim When the -e option is used with disassembly, the various SSDTs are simply
11239c48c75eSJung-uk Kim loaded into a global namespace for the disassembler to use in order to
11249c48c75eSJung-uk Kim resolve control method references (invocations).
11259c48c75eSJung-uk Kim 
11269c48c75eSJung-uk Kim The disassembler tracks any such references, and will emit an External()
11279c48c75eSJung-uk Kim statement for these types of methods, with the proper number of arguments .
11289c48c75eSJung-uk Kim 
11299c48c75eSJung-uk Kim Without the SSDTs, the AML does not contain enough information to properly
11309c48c75eSJung-uk Kim disassemble the control method invocation -- because the disassembler does
11319c48c75eSJung-uk Kim not know how many arguments to parse.
11329c48c75eSJung-uk Kim 
11339c48c75eSJung-uk Kim An example: Assume we have two control methods. ABCD has one argument, and
11349c48c75eSJung-uk Kim EFGH has zero arguments. Further, we have two additional control methods
11359c48c75eSJung-uk Kim that invoke ABCD and EFGH, named T1 and T2:
11369c48c75eSJung-uk Kim 
11379c48c75eSJung-uk Kim     Method (ABCD, 1)
11389c48c75eSJung-uk Kim     {
11399c48c75eSJung-uk Kim     }
11409c48c75eSJung-uk Kim     Method (EFGH, 0)
11419c48c75eSJung-uk Kim     {
11429c48c75eSJung-uk Kim     }
11439c48c75eSJung-uk Kim     Method (T1)
11449c48c75eSJung-uk Kim     {
11459c48c75eSJung-uk Kim         ABCD (Add (2, 7, Local0))
11469c48c75eSJung-uk Kim     }
11479c48c75eSJung-uk Kim     Method (T2)
11489c48c75eSJung-uk Kim     {
11499c48c75eSJung-uk Kim         EFGH ()
11509c48c75eSJung-uk Kim         Add (2, 7, Local0)
11519c48c75eSJung-uk Kim     }
11529c48c75eSJung-uk Kim 
11539c48c75eSJung-uk Kim Here is the AML code that is generated for T1 and T2:
11549c48c75eSJung-uk Kim 
11559c48c75eSJung-uk Kim      185:      Method (T1)
11569c48c75eSJung-uk Kim 
11579c48c75eSJung-uk Kim 0000034C:  14 10 54 31 5F 5F 00 ...    "..T1__."
11589c48c75eSJung-uk Kim 
11599c48c75eSJung-uk Kim      186:      {
11609c48c75eSJung-uk Kim      187:          ABCD (Add (2, 7, Local0))
11619c48c75eSJung-uk Kim 
11629c48c75eSJung-uk Kim 00000353:  41 42 43 44 ............    "ABCD"
11639c48c75eSJung-uk Kim 00000357:  72 0A 02 0A 07 60 ......    "r....`"
11649c48c75eSJung-uk Kim 
11659c48c75eSJung-uk Kim      188:      }
11669c48c75eSJung-uk Kim 
11679c48c75eSJung-uk Kim      190:      Method (T2)
11689c48c75eSJung-uk Kim 
11699c48c75eSJung-uk Kim 0000035D:  14 10 54 32 5F 5F 00 ...    "..T2__."
11709c48c75eSJung-uk Kim 
11719c48c75eSJung-uk Kim      191:      {
11729c48c75eSJung-uk Kim      192:          EFGH ()
11739c48c75eSJung-uk Kim 
11749c48c75eSJung-uk Kim 00000364:  45 46 47 48 ............    "EFGH"
11759c48c75eSJung-uk Kim 
11769c48c75eSJung-uk Kim      193:          Add (2, 7, Local0)
11779c48c75eSJung-uk Kim 
11789c48c75eSJung-uk Kim 00000368:  72 0A 02 0A 07 60 ......    "r....`"
11799c48c75eSJung-uk Kim      194:      }
11809c48c75eSJung-uk Kim 
11819c48c75eSJung-uk Kim Note that the AML code for T1 and T2 is essentially identical. When
11829c48c75eSJung-uk Kim disassembling this code, the methods ABCD and EFGH must be known to the
11839c48c75eSJung-uk Kim disassembler, otherwise it does not know how to handle the method invocations.
11849c48c75eSJung-uk Kim 
11859c48c75eSJung-uk Kim In other words, if ABCD and EFGH are actually external control methods
11869c48c75eSJung-uk Kim appearing in an SSDT, the disassembler does not know what to do unless
11879c48c75eSJung-uk Kim the owning SSDT has been loaded via the -e option.
11889c48c75eSJung-uk Kim #endif
11899c48c75eSJung-uk Kim 
11909c48c75eSJung-uk Kim void
11919c48c75eSJung-uk Kim AcpiDmUnresolvedWarning (
11929c48c75eSJung-uk Kim     UINT8                   Type)
11939c48c75eSJung-uk Kim {
11949c48c75eSJung-uk Kim 
11959c48c75eSJung-uk Kim     if (!AcpiGbl_NumExternalMethods)
11969c48c75eSJung-uk Kim     {
11979c48c75eSJung-uk Kim         return;
11989c48c75eSJung-uk Kim     }
11999c48c75eSJung-uk Kim 
12009c48c75eSJung-uk Kim     if (Type)
12019c48c75eSJung-uk Kim     {
12029c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
12039c48c75eSJung-uk Kim         {
12049c48c75eSJung-uk Kim             /* The -e option was not specified */
12059c48c75eSJung-uk Kim 
12069c48c75eSJung-uk Kim            AcpiOsPrintf ("    /*\n"
12079c48c75eSJung-uk Kim                 "     * iASL Warning: There were %u external control methods found during\n"
12089c48c75eSJung-uk Kim                 "     * disassembly, but additional ACPI tables to resolve these externals\n"
12099c48c75eSJung-uk Kim                 "     * were not specified. This resulting disassembler output file may not\n"
12109c48c75eSJung-uk Kim                 "     * compile because the disassembler did not know how many arguments\n"
12119c48c75eSJung-uk Kim                 "     * to assign to these methods. To specify the tables needed to resolve\n"
12129c48c75eSJung-uk Kim                 "     * external control method references, use the one of the following\n"
12139c48c75eSJung-uk Kim                 "     * example iASL invocations:\n"
12149c48c75eSJung-uk Kim                 "     *     iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n"
12159c48c75eSJung-uk Kim                 "     *     iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n"
12169c48c75eSJung-uk Kim                 "     */\n",
12179c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods);
12189c48c75eSJung-uk Kim         }
12199c48c75eSJung-uk Kim         else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods)
12209c48c75eSJung-uk Kim         {
12219c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
12229c48c75eSJung-uk Kim 
12239c48c75eSJung-uk Kim             AcpiOsPrintf ("    /*\n"
12249c48c75eSJung-uk Kim                 "     * iASL Warning: There were %u external control methods found during\n"
12259c48c75eSJung-uk Kim                 "     * disassembly, but only %u %s resolved (%u unresolved). Additional\n"
12269c48c75eSJung-uk Kim                 "     * ACPI tables are required to properly disassemble the code. This\n"
12279c48c75eSJung-uk Kim                 "     * resulting disassembler output file may not compile because the\n"
12289c48c75eSJung-uk Kim                 "     * disassembler did not know how many arguments to assign to the\n"
12299c48c75eSJung-uk Kim                 "     * unresolved methods.\n"
12309c48c75eSJung-uk Kim                 "     */\n",
12319c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods,
12329c48c75eSJung-uk Kim                 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"),
12339c48c75eSJung-uk Kim                 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods));
12349c48c75eSJung-uk Kim         }
12359c48c75eSJung-uk Kim     }
12369c48c75eSJung-uk Kim     else
12379c48c75eSJung-uk Kim     {
12389c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
12399c48c75eSJung-uk Kim         {
12409c48c75eSJung-uk Kim             /* The -e option was not specified */
12419c48c75eSJung-uk Kim 
12429c48c75eSJung-uk Kim             fprintf (stderr, "\n"
12439c48c75eSJung-uk Kim                 "iASL Warning: There were %u external control methods found during\n"
12449c48c75eSJung-uk Kim                 "disassembly, but additional ACPI tables to resolve these externals\n"
12459c48c75eSJung-uk Kim                 "were not specified. The resulting disassembler output file may not\n"
12469c48c75eSJung-uk Kim                 "compile because the disassembler did not know how many arguments\n"
12479c48c75eSJung-uk Kim                 "to assign to these methods. To specify the tables needed to resolve\n"
12489c48c75eSJung-uk Kim                 "external control method references, use the one of the following\n"
12499c48c75eSJung-uk Kim                 "example iASL invocations:\n"
12509c48c75eSJung-uk Kim                 "    iasl -e <ssdt1.aml,ssdt2.aml...> -d <dsdt.aml>\n"
12519c48c75eSJung-uk Kim                 "    iasl -e <dsdt.aml,ssdt2.aml...> -d <ssdt1.aml>\n",
12529c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods);
12539c48c75eSJung-uk Kim         }
12549c48c75eSJung-uk Kim         else if (AcpiGbl_NumExternalMethods != AcpiGbl_ResolvedExternalMethods)
12559c48c75eSJung-uk Kim         {
12569c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
12579c48c75eSJung-uk Kim 
12589c48c75eSJung-uk Kim             fprintf (stderr, "\n"
12599c48c75eSJung-uk Kim                 "iASL Warning: There were %u external control methods found during\n"
12609c48c75eSJung-uk Kim                 "disassembly, but only %u %s resolved (%u unresolved). Additional\n"
12619c48c75eSJung-uk Kim                 "ACPI tables are required to properly disassemble the code. The\n"
12629c48c75eSJung-uk Kim                 "resulting disassembler output file may not compile because the\n"
12639c48c75eSJung-uk Kim                 "disassembler did not know how many arguments to assign to the\n"
12649c48c75eSJung-uk Kim                 "unresolved methods.\n",
12659c48c75eSJung-uk Kim                 AcpiGbl_NumExternalMethods, AcpiGbl_ResolvedExternalMethods,
12669c48c75eSJung-uk Kim                 (AcpiGbl_ResolvedExternalMethods > 1 ? "were" : "was"),
12679c48c75eSJung-uk Kim                 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods));
12689c48c75eSJung-uk Kim         }
12699c48c75eSJung-uk Kim     }
12709c48c75eSJung-uk Kim }
1271