xref: /freebsd/sys/contrib/dev/acpica/common/dmextern.c (revision f8146b882bc156c1d8ddf14bbea67253ebc064bb)
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 /*
8*f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, 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>
4979c6d946SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
509c48c75eSJung-uk Kim #include <stdio.h>
5179c6d946SJung-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 {
70313a0c13SJung-uk Kim     /* 00 */ ", UnknownObj",        /* 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 
9279c6d946SJung-uk Kim #define METHOD_SEPARATORS           " \t,()\n"
9379c6d946SJung-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 
10679c6d946SJung-uk Kim static void
107313a0c13SJung-uk Kim AcpiDmAddPathToExternalList (
10879c6d946SJung-uk Kim     char                    *Path,
10979c6d946SJung-uk Kim     UINT8                   Type,
110313a0c13SJung-uk Kim     UINT32                  Value,
111313a0c13SJung-uk Kim     UINT16                  Flags);
112313a0c13SJung-uk Kim 
113313a0c13SJung-uk Kim static ACPI_STATUS
114313a0c13SJung-uk Kim AcpiDmCreateNewExternal (
115313a0c13SJung-uk Kim     char                    *ExternalPath,
116313a0c13SJung-uk Kim     char                    *InternalPath,
117313a0c13SJung-uk Kim     UINT8                   Type,
118313a0c13SJung-uk Kim     UINT32                  Value,
119313a0c13SJung-uk Kim     UINT16                  Flags);
12079c6d946SJung-uk Kim 
121f556842eSJung-uk Kim 
122f556842eSJung-uk Kim /*******************************************************************************
123f556842eSJung-uk Kim  *
124f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetObjectTypeName
125f556842eSJung-uk Kim  *
126f556842eSJung-uk Kim  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
127f556842eSJung-uk Kim  *
128f556842eSJung-uk Kim  * RETURN:      Pointer to a string
129f556842eSJung-uk Kim  *
130f556842eSJung-uk Kim  * DESCRIPTION: Map an object type to the ASL object type string.
131f556842eSJung-uk Kim  *
132f556842eSJung-uk Kim  ******************************************************************************/
133f556842eSJung-uk Kim 
134f556842eSJung-uk Kim static const char *
135f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
136f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type)
137f556842eSJung-uk Kim {
138f556842eSJung-uk Kim 
139f556842eSJung-uk Kim     if (Type == ACPI_TYPE_LOCAL_SCOPE)
140f556842eSJung-uk Kim     {
141f556842eSJung-uk Kim         Type = ACPI_TYPE_DEVICE;
142f556842eSJung-uk Kim     }
143f556842eSJung-uk Kim     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
144f556842eSJung-uk Kim     {
145f556842eSJung-uk Kim         return ("");
146f556842eSJung-uk Kim     }
147f556842eSJung-uk Kim 
148f556842eSJung-uk Kim     return (AcpiGbl_DmTypeNames[Type]);
149f556842eSJung-uk Kim }
150f556842eSJung-uk Kim 
151f556842eSJung-uk Kim 
152f556842eSJung-uk Kim /*******************************************************************************
153f556842eSJung-uk Kim  *
154f556842eSJung-uk Kim  * FUNCTION:    AcpiDmNormalizeParentPrefix
155f556842eSJung-uk Kim  *
156f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Parse op
157f556842eSJung-uk Kim  *              Path                - Path with parent prefix
158f556842eSJung-uk Kim  *
159f556842eSJung-uk Kim  * RETURN:      The full pathname to the object (from the namespace root)
160f556842eSJung-uk Kim  *
161f556842eSJung-uk Kim  * DESCRIPTION: Returns the full pathname of a path with parent prefix
162f556842eSJung-uk Kim  *              The caller must free the fullpath returned.
163f556842eSJung-uk Kim  *
164f556842eSJung-uk Kim  ******************************************************************************/
165f556842eSJung-uk Kim 
166f556842eSJung-uk Kim static char *
167f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
168f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
169f556842eSJung-uk Kim     char                    *Path)
170f556842eSJung-uk Kim {
171f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
172f556842eSJung-uk Kim     char                    *Fullpath;
173f556842eSJung-uk Kim     char                    *ParentPath;
174f556842eSJung-uk Kim     ACPI_SIZE               Length;
175ed17e06eSJung-uk Kim     UINT32                  Index = 0;
176f556842eSJung-uk Kim 
177f556842eSJung-uk Kim 
178ed17e06eSJung-uk Kim     if (!Op)
179ed17e06eSJung-uk Kim     {
180ed17e06eSJung-uk Kim         return (NULL);
181ed17e06eSJung-uk Kim     }
182f556842eSJung-uk Kim 
183ed17e06eSJung-uk Kim     /* Search upwards in the parse tree until we reach the next namespace node */
184ed17e06eSJung-uk Kim 
185ed17e06eSJung-uk Kim     Op = Op->Common.Parent;
186f556842eSJung-uk Kim     while (Op)
187f556842eSJung-uk Kim     {
188f556842eSJung-uk Kim         if (Op->Common.Node)
189f556842eSJung-uk Kim         {
190f556842eSJung-uk Kim             break;
191f556842eSJung-uk Kim         }
192f556842eSJung-uk Kim 
193f556842eSJung-uk Kim         Op = Op->Common.Parent;
194f556842eSJung-uk Kim     }
195f556842eSJung-uk Kim 
196f556842eSJung-uk Kim     if (!Op)
197f556842eSJung-uk Kim     {
198f556842eSJung-uk Kim         return (NULL);
199f556842eSJung-uk Kim     }
200f556842eSJung-uk Kim 
201f556842eSJung-uk Kim     /*
202f556842eSJung-uk Kim      * Find the actual parent node for the reference:
203f556842eSJung-uk Kim      * Remove all carat prefixes from the input path.
204f556842eSJung-uk Kim      * There may be multiple parent prefixes (For example, ^^^M000)
205f556842eSJung-uk Kim      */
206f556842eSJung-uk Kim     Node = Op->Common.Node;
207f556842eSJung-uk Kim     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
208f556842eSJung-uk Kim     {
209a88e22b7SJung-uk Kim         Node = Node->Parent;
210f556842eSJung-uk Kim         Path++;
211f556842eSJung-uk Kim     }
212f556842eSJung-uk Kim 
213f556842eSJung-uk Kim     if (!Node)
214f556842eSJung-uk Kim     {
215f556842eSJung-uk Kim         return (NULL);
216f556842eSJung-uk Kim     }
217f556842eSJung-uk Kim 
218f556842eSJung-uk Kim     /* Get the full pathname for the parent node */
219f556842eSJung-uk Kim 
220f556842eSJung-uk Kim     ParentPath = AcpiNsGetExternalPathname (Node);
221f556842eSJung-uk Kim     if (!ParentPath)
222f556842eSJung-uk Kim     {
223f556842eSJung-uk Kim         return (NULL);
224f556842eSJung-uk Kim     }
225f556842eSJung-uk Kim 
2265ef50723SJung-uk Kim     Length = (strlen (ParentPath) + strlen (Path) + 1);
2278c8be05fSJung-uk Kim     if (ParentPath[1])
2288c8be05fSJung-uk Kim     {
2298c8be05fSJung-uk Kim         /*
2308c8be05fSJung-uk Kim          * If ParentPath is not just a simple '\', increment the length
2318c8be05fSJung-uk Kim          * for the required dot separator (ParentPath.Path)
2328c8be05fSJung-uk Kim          */
2338c8be05fSJung-uk Kim         Length++;
234ed17e06eSJung-uk Kim 
235ed17e06eSJung-uk Kim         /* For External() statements, we do not want a leading '\' */
236ed17e06eSJung-uk Kim 
237ed17e06eSJung-uk Kim         if (*ParentPath == AML_ROOT_PREFIX)
238ed17e06eSJung-uk Kim         {
239ed17e06eSJung-uk Kim             Index = 1;
240ed17e06eSJung-uk Kim         }
2418c8be05fSJung-uk Kim     }
2428c8be05fSJung-uk Kim 
243f556842eSJung-uk Kim     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
244f556842eSJung-uk Kim     if (!Fullpath)
245f556842eSJung-uk Kim     {
246f556842eSJung-uk Kim         goto Cleanup;
247f556842eSJung-uk Kim     }
248f556842eSJung-uk Kim 
249f556842eSJung-uk Kim     /*
250f556842eSJung-uk Kim      * Concatenate parent fullpath and path. For example,
251f556842eSJung-uk Kim      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
252f556842eSJung-uk Kim      *
253f556842eSJung-uk Kim      * Copy the parent path
254f556842eSJung-uk Kim      */
2555ef50723SJung-uk Kim     strcpy (Fullpath, &ParentPath[Index]);
256f556842eSJung-uk Kim 
257f38b0f21SJung-uk Kim     /*
258f38b0f21SJung-uk Kim      * Add dot separator
259f38b0f21SJung-uk Kim      * (don't need dot if parent fullpath is a single backslash)
260f38b0f21SJung-uk Kim      */
261f556842eSJung-uk Kim     if (ParentPath[1])
262f556842eSJung-uk Kim     {
2635ef50723SJung-uk Kim         strcat (Fullpath, ".");
264f556842eSJung-uk Kim     }
265f556842eSJung-uk Kim 
266f556842eSJung-uk Kim     /* Copy child path (carat parent prefix(es) were skipped above) */
267f556842eSJung-uk Kim 
2685ef50723SJung-uk Kim     strcat (Fullpath, Path);
269f556842eSJung-uk Kim 
270f556842eSJung-uk Kim Cleanup:
271f556842eSJung-uk Kim     ACPI_FREE (ParentPath);
272f556842eSJung-uk Kim     return (Fullpath);
273f556842eSJung-uk Kim }
274f556842eSJung-uk Kim 
275f556842eSJung-uk Kim 
276f556842eSJung-uk Kim /*******************************************************************************
277f556842eSJung-uk Kim  *
278709fac06SJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalFileList
279709fac06SJung-uk Kim  *
280709fac06SJung-uk Kim  * PARAMETERS:  PathList            - Single path or list separated by comma
281709fac06SJung-uk Kim  *
282709fac06SJung-uk Kim  * RETURN:      None
283709fac06SJung-uk Kim  *
284709fac06SJung-uk Kim  * DESCRIPTION: Add external files to global list
285709fac06SJung-uk Kim  *
286709fac06SJung-uk Kim  ******************************************************************************/
287709fac06SJung-uk Kim 
288709fac06SJung-uk Kim ACPI_STATUS
289709fac06SJung-uk Kim AcpiDmAddToExternalFileList (
290313a0c13SJung-uk Kim     char                    *Pathname)
291709fac06SJung-uk Kim {
292709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *ExternalFile;
293313a0c13SJung-uk Kim     char                    *LocalPathname;
294709fac06SJung-uk Kim 
295709fac06SJung-uk Kim 
296313a0c13SJung-uk Kim     if (!Pathname)
297709fac06SJung-uk Kim     {
298709fac06SJung-uk Kim         return (AE_OK);
299709fac06SJung-uk Kim     }
300709fac06SJung-uk Kim 
301313a0c13SJung-uk Kim     LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
302313a0c13SJung-uk Kim     if (!LocalPathname)
303709fac06SJung-uk Kim     {
304709fac06SJung-uk Kim         return (AE_NO_MEMORY);
305709fac06SJung-uk Kim     }
306709fac06SJung-uk Kim 
307709fac06SJung-uk Kim     ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
308709fac06SJung-uk Kim     if (!ExternalFile)
309709fac06SJung-uk Kim     {
310313a0c13SJung-uk Kim         ACPI_FREE (LocalPathname);
311709fac06SJung-uk Kim         return (AE_NO_MEMORY);
312709fac06SJung-uk Kim     }
313709fac06SJung-uk Kim 
314313a0c13SJung-uk Kim     /* Take a copy of the file pathname */
315313a0c13SJung-uk Kim 
316313a0c13SJung-uk Kim     strcpy (LocalPathname, Pathname);
317313a0c13SJung-uk Kim     ExternalFile->Path = LocalPathname;
318709fac06SJung-uk Kim 
319709fac06SJung-uk Kim     if (AcpiGbl_ExternalFileList)
320709fac06SJung-uk Kim     {
321709fac06SJung-uk Kim         ExternalFile->Next = AcpiGbl_ExternalFileList;
322709fac06SJung-uk Kim     }
323709fac06SJung-uk Kim 
324709fac06SJung-uk Kim     AcpiGbl_ExternalFileList = ExternalFile;
325709fac06SJung-uk Kim     return (AE_OK);
326709fac06SJung-uk Kim }
327709fac06SJung-uk Kim 
328709fac06SJung-uk Kim 
329709fac06SJung-uk Kim /*******************************************************************************
330709fac06SJung-uk Kim  *
331709fac06SJung-uk Kim  * FUNCTION:    AcpiDmClearExternalFileList
332709fac06SJung-uk Kim  *
333709fac06SJung-uk Kim  * PARAMETERS:  None
334709fac06SJung-uk Kim  *
335709fac06SJung-uk Kim  * RETURN:      None
336709fac06SJung-uk Kim  *
337709fac06SJung-uk Kim  * DESCRIPTION: Clear the external file list
338709fac06SJung-uk Kim  *
339709fac06SJung-uk Kim  ******************************************************************************/
340709fac06SJung-uk Kim 
341709fac06SJung-uk Kim void
342709fac06SJung-uk Kim AcpiDmClearExternalFileList (
343709fac06SJung-uk Kim     void)
344709fac06SJung-uk Kim {
345709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *NextExternal;
346709fac06SJung-uk Kim 
347709fac06SJung-uk Kim 
348709fac06SJung-uk Kim     while (AcpiGbl_ExternalFileList)
349709fac06SJung-uk Kim     {
350709fac06SJung-uk Kim         NextExternal = AcpiGbl_ExternalFileList->Next;
351709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
352709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList);
353709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = NextExternal;
354709fac06SJung-uk Kim     }
355709fac06SJung-uk Kim }
356709fac06SJung-uk Kim 
357709fac06SJung-uk Kim 
358709fac06SJung-uk Kim /*******************************************************************************
359709fac06SJung-uk Kim  *
36079c6d946SJung-uk Kim  * FUNCTION:    AcpiDmGetExternalsFromFile
36179c6d946SJung-uk Kim  *
36279c6d946SJung-uk Kim  * PARAMETERS:  None
36379c6d946SJung-uk Kim  *
36479c6d946SJung-uk Kim  * RETURN:      None
36579c6d946SJung-uk Kim  *
36679c6d946SJung-uk Kim  * DESCRIPTION: Process the optional external reference file.
36779c6d946SJung-uk Kim  *
36879c6d946SJung-uk Kim  * Each line in the file should be of the form:
36979c6d946SJung-uk Kim  *      External (<Method namepath>, MethodObj, <ArgCount>)
37079c6d946SJung-uk Kim  *
37179c6d946SJung-uk Kim  * Example:
37279c6d946SJung-uk Kim  *      External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
37379c6d946SJung-uk Kim  *
37479c6d946SJung-uk Kim  ******************************************************************************/
37579c6d946SJung-uk Kim 
37679c6d946SJung-uk Kim void
37779c6d946SJung-uk Kim AcpiDmGetExternalsFromFile (
37879c6d946SJung-uk Kim     void)
37979c6d946SJung-uk Kim {
38079c6d946SJung-uk Kim     FILE                    *ExternalRefFile;
38179c6d946SJung-uk Kim     char                    *Token;
38279c6d946SJung-uk Kim     char                    *MethodName;
38379c6d946SJung-uk Kim     UINT32                  ArgCount;
38479c6d946SJung-uk Kim     UINT32                  ImportCount = 0;
38579c6d946SJung-uk Kim 
38679c6d946SJung-uk Kim 
38779c6d946SJung-uk Kim     if (!Gbl_ExternalRefFilename)
38879c6d946SJung-uk Kim     {
38979c6d946SJung-uk Kim         return;
39079c6d946SJung-uk Kim     }
39179c6d946SJung-uk Kim 
39279c6d946SJung-uk Kim     /* Open the file */
39379c6d946SJung-uk Kim 
39479c6d946SJung-uk Kim     ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
39579c6d946SJung-uk Kim     if (!ExternalRefFile)
39679c6d946SJung-uk Kim     {
39779c6d946SJung-uk Kim         fprintf (stderr, "Could not open external reference file \"%s\"\n",
39879c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
399313a0c13SJung-uk Kim         AslAbort ();
40079c6d946SJung-uk Kim         return;
40179c6d946SJung-uk Kim     }
40279c6d946SJung-uk Kim 
40379c6d946SJung-uk Kim     /* Each line defines a method */
40479c6d946SJung-uk Kim 
40579c6d946SJung-uk Kim     while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
40679c6d946SJung-uk Kim     {
40779c6d946SJung-uk Kim         Token = strtok (StringBuffer, METHOD_SEPARATORS);   /* "External" */
408313a0c13SJung-uk Kim         if (!Token)
409313a0c13SJung-uk Kim         {
410313a0c13SJung-uk Kim             continue;
411313a0c13SJung-uk Kim         }
412*f8146b88SJung-uk Kim 
413313a0c13SJung-uk Kim         if (strcmp (Token, "External"))
414313a0c13SJung-uk Kim         {
415313a0c13SJung-uk Kim             continue;
416313a0c13SJung-uk Kim         }
41779c6d946SJung-uk Kim 
41879c6d946SJung-uk Kim         MethodName = strtok (NULL, METHOD_SEPARATORS);      /* Method namepath */
419313a0c13SJung-uk Kim         if (!MethodName)
420313a0c13SJung-uk Kim         {
421313a0c13SJung-uk Kim             continue;
422313a0c13SJung-uk Kim         }
42379c6d946SJung-uk Kim 
42479c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* "MethodObj" */
425313a0c13SJung-uk Kim         if (!Token)
426313a0c13SJung-uk Kim         {
427313a0c13SJung-uk Kim             continue;
428313a0c13SJung-uk Kim         }
429313a0c13SJung-uk Kim 
430313a0c13SJung-uk Kim         if (strcmp (Token, "MethodObj"))
431313a0c13SJung-uk Kim         {
432313a0c13SJung-uk Kim             continue;
433313a0c13SJung-uk Kim         }
43479c6d946SJung-uk Kim 
43579c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* Arg count */
436313a0c13SJung-uk Kim         if (!Token)
437313a0c13SJung-uk Kim         {
438313a0c13SJung-uk Kim             continue;
439313a0c13SJung-uk Kim         }
44079c6d946SJung-uk Kim 
44179c6d946SJung-uk Kim         /* Convert arg count string to an integer */
44279c6d946SJung-uk Kim 
44379c6d946SJung-uk Kim         errno = 0;
44479c6d946SJung-uk Kim         ArgCount = strtoul (Token, NULL, 0);
44579c6d946SJung-uk Kim         if (errno)
44679c6d946SJung-uk Kim         {
44779c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%s)\n", Token);
44879c6d946SJung-uk Kim             continue;
44979c6d946SJung-uk Kim         }
450*f8146b88SJung-uk Kim 
45179c6d946SJung-uk Kim         if (ArgCount > 7)
45279c6d946SJung-uk Kim         {
45379c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
45479c6d946SJung-uk Kim             continue;
45579c6d946SJung-uk Kim         }
45679c6d946SJung-uk Kim 
45779c6d946SJung-uk Kim         /* Add this external to the global list */
45879c6d946SJung-uk Kim 
45979c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
46079c6d946SJung-uk Kim             Gbl_ExternalRefFilename, ArgCount, MethodName);
46179c6d946SJung-uk Kim 
462313a0c13SJung-uk Kim         AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
463313a0c13SJung-uk Kim             ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
46479c6d946SJung-uk Kim         ImportCount++;
46579c6d946SJung-uk Kim     }
46679c6d946SJung-uk Kim 
46779c6d946SJung-uk Kim     if (!ImportCount)
46879c6d946SJung-uk Kim     {
469*f8146b88SJung-uk Kim         fprintf (stderr,
470*f8146b88SJung-uk Kim             "Did not find any external methods in reference file \"%s\"\n",
47179c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
47279c6d946SJung-uk Kim     }
47379c6d946SJung-uk Kim     else
47479c6d946SJung-uk Kim     {
47579c6d946SJung-uk Kim         /* Add the external(s) to the namespace */
47679c6d946SJung-uk Kim 
47779c6d946SJung-uk Kim         AcpiDmAddExternalsToNamespace ();
47879c6d946SJung-uk Kim 
47979c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Imported %u external method definitions\n",
48079c6d946SJung-uk Kim             Gbl_ExternalRefFilename, ImportCount);
48179c6d946SJung-uk Kim     }
48279c6d946SJung-uk Kim 
48379c6d946SJung-uk Kim     fclose (ExternalRefFile);
48479c6d946SJung-uk Kim }
48579c6d946SJung-uk Kim 
48679c6d946SJung-uk Kim 
48779c6d946SJung-uk Kim /*******************************************************************************
48879c6d946SJung-uk Kim  *
489313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddOpToExternalList
49079c6d946SJung-uk Kim  *
491313a0c13SJung-uk Kim  * PARAMETERS:  Op                  - Current parser Op
492313a0c13SJung-uk Kim  *              Path                - Internal (AML) path to the object
49379c6d946SJung-uk Kim  *              Type                - ACPI object type to be added
49479c6d946SJung-uk Kim  *              Value               - Arg count if adding a Method object
495313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
49679c6d946SJung-uk Kim  *
49779c6d946SJung-uk Kim  * RETURN:      None
49879c6d946SJung-uk Kim  *
49979c6d946SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
50079c6d946SJung-uk Kim  *              will in turn be later emitted as an External() declaration
50179c6d946SJung-uk Kim  *              in the disassembled output.
50279c6d946SJung-uk Kim  *
503313a0c13SJung-uk Kim  *              This function handles the most common case where the referenced
504313a0c13SJung-uk Kim  *              name is simply not found in the constructed namespace.
505313a0c13SJung-uk Kim  *
50679c6d946SJung-uk Kim  ******************************************************************************/
50779c6d946SJung-uk Kim 
508313a0c13SJung-uk Kim void
509313a0c13SJung-uk Kim AcpiDmAddOpToExternalList (
510313a0c13SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
51179c6d946SJung-uk Kim     char                    *Path,
51279c6d946SJung-uk Kim     UINT8                   Type,
513313a0c13SJung-uk Kim     UINT32                  Value,
514313a0c13SJung-uk Kim     UINT16                  Flags)
51579c6d946SJung-uk Kim {
51679c6d946SJung-uk Kim     char                    *ExternalPath;
517313a0c13SJung-uk Kim     char                    *InternalPath = Path;
518313a0c13SJung-uk Kim     char                    *Temp;
51979c6d946SJung-uk Kim     ACPI_STATUS             Status;
520313a0c13SJung-uk Kim 
521313a0c13SJung-uk Kim 
522313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
52379c6d946SJung-uk Kim 
52479c6d946SJung-uk Kim 
52579c6d946SJung-uk Kim     if (!Path)
52679c6d946SJung-uk Kim     {
527313a0c13SJung-uk Kim         return_VOID;
52879c6d946SJung-uk Kim     }
52979c6d946SJung-uk Kim 
530313a0c13SJung-uk Kim     /* Remove a root backslash if present */
53179c6d946SJung-uk Kim 
532313a0c13SJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
53379c6d946SJung-uk Kim     {
534313a0c13SJung-uk Kim         Path++;
53579c6d946SJung-uk Kim     }
536313a0c13SJung-uk Kim 
537313a0c13SJung-uk Kim     /* Externalize the pathname */
538313a0c13SJung-uk Kim 
539313a0c13SJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
540313a0c13SJung-uk Kim         NULL, &ExternalPath);
541313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
542313a0c13SJung-uk Kim     {
543313a0c13SJung-uk Kim         return_VOID;
54479c6d946SJung-uk Kim     }
54579c6d946SJung-uk Kim 
54679c6d946SJung-uk Kim     /*
547313a0c13SJung-uk Kim      * Get the full pathname from the root if "Path" has one or more
548313a0c13SJung-uk Kim      * parent prefixes (^). Note: path will not contain a leading '\'.
549313a0c13SJung-uk Kim      */
550313a0c13SJung-uk Kim     if (*Path == (UINT8) AML_PARENT_PREFIX)
551313a0c13SJung-uk Kim     {
552313a0c13SJung-uk Kim         Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
553313a0c13SJung-uk Kim 
554313a0c13SJung-uk Kim         /* Set new external path */
555313a0c13SJung-uk Kim 
556313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
557313a0c13SJung-uk Kim         ExternalPath = Temp;
558313a0c13SJung-uk Kim         if (!Temp)
559313a0c13SJung-uk Kim         {
560313a0c13SJung-uk Kim             return_VOID;
561313a0c13SJung-uk Kim         }
562313a0c13SJung-uk Kim 
563313a0c13SJung-uk Kim         /* Create the new internal pathname */
564313a0c13SJung-uk Kim 
565313a0c13SJung-uk Kim         Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
566313a0c13SJung-uk Kim         Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
567313a0c13SJung-uk Kim         if (ACPI_FAILURE (Status))
568313a0c13SJung-uk Kim         {
569313a0c13SJung-uk Kim             ACPI_FREE (ExternalPath);
570313a0c13SJung-uk Kim             return_VOID;
571313a0c13SJung-uk Kim         }
572313a0c13SJung-uk Kim     }
573313a0c13SJung-uk Kim 
574313a0c13SJung-uk Kim     /* Create the new External() declaration node */
575313a0c13SJung-uk Kim 
576313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
577313a0c13SJung-uk Kim         Type, Value, Flags);
578313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
579313a0c13SJung-uk Kim     {
580313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
581313a0c13SJung-uk Kim         if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
582313a0c13SJung-uk Kim         {
583313a0c13SJung-uk Kim             ACPI_FREE (InternalPath);
584313a0c13SJung-uk Kim         }
585313a0c13SJung-uk Kim     }
586313a0c13SJung-uk Kim 
587313a0c13SJung-uk Kim     return_VOID;
588313a0c13SJung-uk Kim }
589313a0c13SJung-uk Kim 
590313a0c13SJung-uk Kim 
591313a0c13SJung-uk Kim /*******************************************************************************
592313a0c13SJung-uk Kim  *
593313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddNodeToExternalList
594313a0c13SJung-uk Kim  *
595313a0c13SJung-uk Kim  * PARAMETERS:  Node                - Namespace node for object to be added
596313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
597313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
598313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
599313a0c13SJung-uk Kim  *
600313a0c13SJung-uk Kim  * RETURN:      None
601313a0c13SJung-uk Kim  *
602313a0c13SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
603313a0c13SJung-uk Kim  *              will in turn be later emitted as an External() declaration
604313a0c13SJung-uk Kim  *              in the disassembled output.
605313a0c13SJung-uk Kim  *
606313a0c13SJung-uk Kim  *              This function handles the case where the referenced name has
607313a0c13SJung-uk Kim  *              been found in the namespace, but the name originated in a
608313a0c13SJung-uk Kim  *              table other than the one that is being disassembled (such
609313a0c13SJung-uk Kim  *              as a table that is added via the iASL -e option).
610313a0c13SJung-uk Kim  *
611313a0c13SJung-uk Kim  ******************************************************************************/
612313a0c13SJung-uk Kim 
613313a0c13SJung-uk Kim void
614313a0c13SJung-uk Kim AcpiDmAddNodeToExternalList (
615313a0c13SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node,
616313a0c13SJung-uk Kim     UINT8                   Type,
617313a0c13SJung-uk Kim     UINT32                  Value,
618313a0c13SJung-uk Kim     UINT16                  Flags)
619313a0c13SJung-uk Kim {
620313a0c13SJung-uk Kim     char                    *ExternalPath;
621313a0c13SJung-uk Kim     char                    *InternalPath;
622313a0c13SJung-uk Kim     char                    *Temp;
623313a0c13SJung-uk Kim     ACPI_STATUS             Status;
624313a0c13SJung-uk Kim 
625313a0c13SJung-uk Kim 
626313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
627313a0c13SJung-uk Kim 
628313a0c13SJung-uk Kim 
629313a0c13SJung-uk Kim     if (!Node)
630313a0c13SJung-uk Kim     {
631313a0c13SJung-uk Kim         return_VOID;
632313a0c13SJung-uk Kim     }
633313a0c13SJung-uk Kim 
634313a0c13SJung-uk Kim     /* Get the full external and internal pathnames to the node */
635313a0c13SJung-uk Kim 
636313a0c13SJung-uk Kim     ExternalPath = AcpiNsGetExternalPathname (Node);
637313a0c13SJung-uk Kim     if (!ExternalPath)
638313a0c13SJung-uk Kim     {
639313a0c13SJung-uk Kim         return_VOID;
640313a0c13SJung-uk Kim     }
641313a0c13SJung-uk Kim 
642313a0c13SJung-uk Kim     Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
643313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
644313a0c13SJung-uk Kim     {
645313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
646313a0c13SJung-uk Kim         return_VOID;
647313a0c13SJung-uk Kim     }
648313a0c13SJung-uk Kim 
649313a0c13SJung-uk Kim     /* Remove the root backslash */
650313a0c13SJung-uk Kim 
651313a0c13SJung-uk Kim     if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
652313a0c13SJung-uk Kim     {
6535ef50723SJung-uk Kim         Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
654313a0c13SJung-uk Kim         if (!Temp)
655313a0c13SJung-uk Kim         {
656313a0c13SJung-uk Kim             return_VOID;
657313a0c13SJung-uk Kim         }
658313a0c13SJung-uk Kim 
6595ef50723SJung-uk Kim         strcpy (Temp, &ExternalPath[1]);
660313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
661313a0c13SJung-uk Kim         ExternalPath = Temp;
662313a0c13SJung-uk Kim     }
663313a0c13SJung-uk Kim 
664313a0c13SJung-uk Kim     /* Create the new External() declaration node */
665313a0c13SJung-uk Kim 
666313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
667313a0c13SJung-uk Kim         Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
668313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
669313a0c13SJung-uk Kim     {
670313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
671313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
672313a0c13SJung-uk Kim     }
673313a0c13SJung-uk Kim 
674313a0c13SJung-uk Kim     return_VOID;
675313a0c13SJung-uk Kim }
676313a0c13SJung-uk Kim 
677313a0c13SJung-uk Kim 
678313a0c13SJung-uk Kim /*******************************************************************************
679313a0c13SJung-uk Kim  *
680313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddPathToExternalList
681313a0c13SJung-uk Kim  *
682313a0c13SJung-uk Kim  * PARAMETERS:  Path                - External name of the object to be added
683313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
684313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
685313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
686313a0c13SJung-uk Kim  *
687313a0c13SJung-uk Kim  * RETURN:      None
688313a0c13SJung-uk Kim  *
689313a0c13SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
690313a0c13SJung-uk Kim  *              will in turn be later emitted as an External() declaration
691313a0c13SJung-uk Kim  *              in the disassembled output.
692313a0c13SJung-uk Kim  *
693313a0c13SJung-uk Kim  *              This function currently is used to add externals via a
694313a0c13SJung-uk Kim  *              reference file (via the -fe iASL option).
695313a0c13SJung-uk Kim  *
696313a0c13SJung-uk Kim  ******************************************************************************/
697313a0c13SJung-uk Kim 
698313a0c13SJung-uk Kim static void
699313a0c13SJung-uk Kim AcpiDmAddPathToExternalList (
700313a0c13SJung-uk Kim     char                    *Path,
701313a0c13SJung-uk Kim     UINT8                   Type,
702313a0c13SJung-uk Kim     UINT32                  Value,
703313a0c13SJung-uk Kim     UINT16                  Flags)
704313a0c13SJung-uk Kim {
705313a0c13SJung-uk Kim     char                    *InternalPath;
706313a0c13SJung-uk Kim     char                    *ExternalPath;
707313a0c13SJung-uk Kim     ACPI_STATUS             Status;
708313a0c13SJung-uk Kim 
709313a0c13SJung-uk Kim 
710313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
711313a0c13SJung-uk Kim 
712313a0c13SJung-uk Kim 
713313a0c13SJung-uk Kim     if (!Path)
714313a0c13SJung-uk Kim     {
715313a0c13SJung-uk Kim         return_VOID;
716313a0c13SJung-uk Kim     }
717313a0c13SJung-uk Kim 
718313a0c13SJung-uk Kim     /* Remove a root backslash if present */
719313a0c13SJung-uk Kim 
720313a0c13SJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
721313a0c13SJung-uk Kim     {
722313a0c13SJung-uk Kim         Path++;
723313a0c13SJung-uk Kim     }
724313a0c13SJung-uk Kim 
725313a0c13SJung-uk Kim     /* Create the internal and external pathnames */
726313a0c13SJung-uk Kim 
727313a0c13SJung-uk Kim     Status = AcpiNsInternalizeName (Path, &InternalPath);
728313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
729313a0c13SJung-uk Kim     {
730313a0c13SJung-uk Kim         return_VOID;
731313a0c13SJung-uk Kim     }
732313a0c13SJung-uk Kim 
733313a0c13SJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
734313a0c13SJung-uk Kim         NULL, &ExternalPath);
735313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
736313a0c13SJung-uk Kim     {
737313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
738313a0c13SJung-uk Kim         return_VOID;
739313a0c13SJung-uk Kim     }
740313a0c13SJung-uk Kim 
741313a0c13SJung-uk Kim     /* Create the new External() declaration node */
742313a0c13SJung-uk Kim 
743313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
744313a0c13SJung-uk Kim         Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
745313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
746313a0c13SJung-uk Kim     {
747313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
748313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
749313a0c13SJung-uk Kim     }
750313a0c13SJung-uk Kim 
751313a0c13SJung-uk Kim     return_VOID;
752313a0c13SJung-uk Kim }
753313a0c13SJung-uk Kim 
754313a0c13SJung-uk Kim 
755313a0c13SJung-uk Kim /*******************************************************************************
756313a0c13SJung-uk Kim  *
757313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmCreateNewExternal
758313a0c13SJung-uk Kim  *
759313a0c13SJung-uk Kim  * PARAMETERS:  ExternalPath        - External path to the object
760313a0c13SJung-uk Kim  *              InternalPath        - Internal (AML) path to the object
761313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
762313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
763313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
764313a0c13SJung-uk Kim  *
765313a0c13SJung-uk Kim  * RETURN:      Status
766313a0c13SJung-uk Kim  *
767313a0c13SJung-uk Kim  * DESCRIPTION: Common low-level function to insert a new name into the global
768313a0c13SJung-uk Kim  *              list of Externals which will in turn be later emitted as
769313a0c13SJung-uk Kim  *              External() declarations in the disassembled output.
770313a0c13SJung-uk Kim  *
771313a0c13SJung-uk Kim  *              Note: The external name should not include a root prefix
772313a0c13SJung-uk Kim  *              (backslash). We do not want External() statements to contain
773313a0c13SJung-uk Kim  *              a leading '\', as this prevents duplicate external statements
774313a0c13SJung-uk Kim  *              of the form:
77579c6d946SJung-uk Kim  *
77679c6d946SJung-uk Kim  *                  External (\ABCD)
77779c6d946SJung-uk Kim  *                  External (ABCD)
77879c6d946SJung-uk Kim  *
77979c6d946SJung-uk Kim  *              This would cause a compile time error when the disassembled
78079c6d946SJung-uk Kim  *              output file is recompiled.
781313a0c13SJung-uk Kim  *
782313a0c13SJung-uk Kim  *              There are two cases that are handled here. For both, we emit
783313a0c13SJung-uk Kim  *              an External() statement:
784313a0c13SJung-uk Kim  *              1) The name was simply not found in the namespace.
785313a0c13SJung-uk Kim  *              2) The name was found, but it originated in a table other than
786313a0c13SJung-uk Kim  *              the table that is being disassembled.
787313a0c13SJung-uk Kim  *
788313a0c13SJung-uk Kim  ******************************************************************************/
789313a0c13SJung-uk Kim 
790313a0c13SJung-uk Kim static ACPI_STATUS
791313a0c13SJung-uk Kim AcpiDmCreateNewExternal (
792313a0c13SJung-uk Kim     char                    *ExternalPath,
793313a0c13SJung-uk Kim     char                    *InternalPath,
794313a0c13SJung-uk Kim     UINT8                   Type,
795313a0c13SJung-uk Kim     UINT32                  Value,
796313a0c13SJung-uk Kim     UINT16                  Flags)
79779c6d946SJung-uk Kim {
798313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *NewExternal;
799313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
800313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
801313a0c13SJung-uk Kim 
802313a0c13SJung-uk Kim 
803313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmCreateNewExternal);
804313a0c13SJung-uk Kim 
80579c6d946SJung-uk Kim 
80679c6d946SJung-uk Kim     /* Check all existing externals to ensure no duplicates */
80779c6d946SJung-uk Kim 
80879c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
80979c6d946SJung-uk Kim     while (NextExternal)
81079c6d946SJung-uk Kim     {
811*f8146b88SJung-uk Kim         /* Check for duplicates */
812*f8146b88SJung-uk Kim 
8135ef50723SJung-uk Kim         if (!strcmp (ExternalPath, NextExternal->Path))
81479c6d946SJung-uk Kim         {
815*f8146b88SJung-uk Kim             /*
816*f8146b88SJung-uk Kim              * If this external came from an External() opcode, we are
817*f8146b88SJung-uk Kim              * finished with this one. (No need to check any further).
818*f8146b88SJung-uk Kim              */
819*f8146b88SJung-uk Kim             if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
82079c6d946SJung-uk Kim             {
821*f8146b88SJung-uk Kim                 return_ACPI_STATUS (AE_ALREADY_EXISTS);
82279c6d946SJung-uk Kim             }
82379c6d946SJung-uk Kim 
82479c6d946SJung-uk Kim             /* Allow upgrade of type from ANY */
82579c6d946SJung-uk Kim 
826*f8146b88SJung-uk Kim             else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
827*f8146b88SJung-uk Kim                 (Type != ACPI_TYPE_ANY))
82879c6d946SJung-uk Kim             {
82979c6d946SJung-uk Kim                 NextExternal->Type = Type;
830*f8146b88SJung-uk Kim             }
831*f8146b88SJung-uk Kim 
832*f8146b88SJung-uk Kim             /* Update the argument count as necessary */
833*f8146b88SJung-uk Kim 
834*f8146b88SJung-uk Kim             if (Value < NextExternal->Value)
835*f8146b88SJung-uk Kim             {
83679c6d946SJung-uk Kim                 NextExternal->Value = Value;
83779c6d946SJung-uk Kim             }
83879c6d946SJung-uk Kim 
839*f8146b88SJung-uk Kim             /* Update flags. */
840*f8146b88SJung-uk Kim 
841*f8146b88SJung-uk Kim             NextExternal->Flags |= Flags;
842*f8146b88SJung-uk Kim             NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
843*f8146b88SJung-uk Kim 
844313a0c13SJung-uk Kim             return_ACPI_STATUS (AE_ALREADY_EXISTS);
84579c6d946SJung-uk Kim         }
84679c6d946SJung-uk Kim 
84779c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
84879c6d946SJung-uk Kim     }
84979c6d946SJung-uk Kim 
85079c6d946SJung-uk Kim     /* Allocate and init a new External() descriptor */
85179c6d946SJung-uk Kim 
85279c6d946SJung-uk Kim     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
85379c6d946SJung-uk Kim     if (!NewExternal)
85479c6d946SJung-uk Kim     {
855313a0c13SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
85679c6d946SJung-uk Kim     }
85779c6d946SJung-uk Kim 
858313a0c13SJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
859313a0c13SJung-uk Kim         "Adding external reference node (%s) type [%s]\n",
860313a0c13SJung-uk Kim         ExternalPath, AcpiUtGetTypeName (Type)));
86179c6d946SJung-uk Kim 
862313a0c13SJung-uk Kim     NewExternal->Flags = Flags;
863313a0c13SJung-uk Kim     NewExternal->Value = Value;
86479c6d946SJung-uk Kim     NewExternal->Path = ExternalPath;
86579c6d946SJung-uk Kim     NewExternal->Type = Type;
8665ef50723SJung-uk Kim     NewExternal->Length = (UINT16) strlen (ExternalPath);
86779c6d946SJung-uk Kim     NewExternal->InternalPath = InternalPath;
86879c6d946SJung-uk Kim 
86979c6d946SJung-uk Kim     /* Link the new descriptor into the global list, alphabetically ordered */
87079c6d946SJung-uk Kim 
87179c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
87279c6d946SJung-uk Kim     while (NextExternal)
87379c6d946SJung-uk Kim     {
87479c6d946SJung-uk Kim         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
87579c6d946SJung-uk Kim         {
87679c6d946SJung-uk Kim             if (PrevExternal)
87779c6d946SJung-uk Kim             {
87879c6d946SJung-uk Kim                 PrevExternal->Next = NewExternal;
87979c6d946SJung-uk Kim             }
88079c6d946SJung-uk Kim             else
88179c6d946SJung-uk Kim             {
88279c6d946SJung-uk Kim                 AcpiGbl_ExternalList = NewExternal;
88379c6d946SJung-uk Kim             }
88479c6d946SJung-uk Kim 
88579c6d946SJung-uk Kim             NewExternal->Next = NextExternal;
886313a0c13SJung-uk Kim             return_ACPI_STATUS (AE_OK);
88779c6d946SJung-uk Kim         }
88879c6d946SJung-uk Kim 
88979c6d946SJung-uk Kim         PrevExternal = NextExternal;
89079c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
89179c6d946SJung-uk Kim     }
89279c6d946SJung-uk Kim 
89379c6d946SJung-uk Kim     if (PrevExternal)
89479c6d946SJung-uk Kim     {
89579c6d946SJung-uk Kim         PrevExternal->Next = NewExternal;
89679c6d946SJung-uk Kim     }
89779c6d946SJung-uk Kim     else
89879c6d946SJung-uk Kim     {
89979c6d946SJung-uk Kim         AcpiGbl_ExternalList = NewExternal;
90079c6d946SJung-uk Kim     }
901313a0c13SJung-uk Kim 
902313a0c13SJung-uk Kim     return_ACPI_STATUS (AE_OK);
90379c6d946SJung-uk Kim }
90479c6d946SJung-uk Kim 
90579c6d946SJung-uk Kim 
90679c6d946SJung-uk Kim /*******************************************************************************
90779c6d946SJung-uk Kim  *
908f556842eSJung-uk Kim  * FUNCTION:    AcpiDmAddExternalsToNamespace
909f556842eSJung-uk Kim  *
910f556842eSJung-uk Kim  * PARAMETERS:  None
911f556842eSJung-uk Kim  *
912f556842eSJung-uk Kim  * RETURN:      None
913f556842eSJung-uk Kim  *
914f556842eSJung-uk Kim  * DESCRIPTION: Add all externals to the namespace. Allows externals to be
915f556842eSJung-uk Kim  *              "resolved".
916f556842eSJung-uk Kim  *
917f556842eSJung-uk Kim  ******************************************************************************/
918f556842eSJung-uk Kim 
919f556842eSJung-uk Kim void
920f556842eSJung-uk Kim AcpiDmAddExternalsToNamespace (
921f556842eSJung-uk Kim     void)
922f556842eSJung-uk Kim {
923f556842eSJung-uk Kim     ACPI_STATUS             Status;
924f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
925a7a3b383SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
926f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
927f556842eSJung-uk Kim 
928f556842eSJung-uk Kim 
929f556842eSJung-uk Kim     while (External)
930f556842eSJung-uk Kim     {
931f556842eSJung-uk Kim         /* Add the external name (object) into the namespace */
932f556842eSJung-uk Kim 
933f556842eSJung-uk Kim         Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
934f556842eSJung-uk Kim             ACPI_IMODE_LOAD_PASS1,
93579c6d946SJung-uk Kim             ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
936f556842eSJung-uk Kim             NULL, &Node);
937f556842eSJung-uk Kim 
938f556842eSJung-uk Kim         if (ACPI_FAILURE (Status))
939f556842eSJung-uk Kim         {
940f556842eSJung-uk Kim             ACPI_EXCEPTION ((AE_INFO, Status,
941f556842eSJung-uk Kim                 "while adding external to namespace [%s]",
942f556842eSJung-uk Kim                 External->Path));
943f556842eSJung-uk Kim         }
944a7a3b383SJung-uk Kim 
945a7a3b383SJung-uk Kim         else switch (External->Type)
946f556842eSJung-uk Kim         {
947a7a3b383SJung-uk Kim         case ACPI_TYPE_METHOD:
948a7a3b383SJung-uk Kim 
949f556842eSJung-uk Kim             /* For methods, we need to save the argument count */
950f556842eSJung-uk Kim 
951a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
952a7a3b383SJung-uk Kim             ObjDesc->Method.ParamCount = (UINT8) External->Value;
953a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
954a7a3b383SJung-uk Kim             break;
955a7a3b383SJung-uk Kim 
956a7a3b383SJung-uk Kim         case ACPI_TYPE_REGION:
957a7a3b383SJung-uk Kim 
958a7a3b383SJung-uk Kim             /* Regions require a region sub-object */
959a7a3b383SJung-uk Kim 
960a7a3b383SJung-uk Kim             ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
961a7a3b383SJung-uk Kim             ObjDesc->Region.Node = Node;
962a7a3b383SJung-uk Kim             Node->Object = ObjDesc;
963a7a3b383SJung-uk Kim             break;
964a7a3b383SJung-uk Kim 
965a7a3b383SJung-uk Kim         default:
966a9d8d09cSJung-uk Kim 
967a7a3b383SJung-uk Kim             break;
968f556842eSJung-uk Kim         }
969f556842eSJung-uk Kim 
970f556842eSJung-uk Kim         External = External->Next;
971f556842eSJung-uk Kim     }
972f556842eSJung-uk Kim }
973f556842eSJung-uk Kim 
974f556842eSJung-uk Kim 
975f556842eSJung-uk Kim /*******************************************************************************
976f556842eSJung-uk Kim  *
977f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetExternalMethodCount
978f556842eSJung-uk Kim  *
979f556842eSJung-uk Kim  * PARAMETERS:  None
980f556842eSJung-uk Kim  *
981f556842eSJung-uk Kim  * RETURN:      The number of control method externals in the external list
982f556842eSJung-uk Kim  *
983f556842eSJung-uk Kim  * DESCRIPTION: Return the number of method externals that have been generated.
984f556842eSJung-uk Kim  *              If any control method externals have been found, we must
985f556842eSJung-uk Kim  *              re-parse the entire definition block with the new information
986f556842eSJung-uk Kim  *              (number of arguments for the methods.) This is limitation of
987f556842eSJung-uk Kim  *              AML, we don't know the number of arguments from the control
988f556842eSJung-uk Kim  *              method invocation itself.
989f556842eSJung-uk Kim  *
990f556842eSJung-uk Kim  ******************************************************************************/
991f556842eSJung-uk Kim 
992f556842eSJung-uk Kim UINT32
993f556842eSJung-uk Kim AcpiDmGetExternalMethodCount (
994f556842eSJung-uk Kim     void)
995f556842eSJung-uk Kim {
996f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
997f556842eSJung-uk Kim     UINT32                  Count = 0;
998f556842eSJung-uk Kim 
999f556842eSJung-uk Kim 
1000f556842eSJung-uk Kim     while (External)
1001f556842eSJung-uk Kim     {
1002f556842eSJung-uk Kim         if (External->Type == ACPI_TYPE_METHOD)
1003f556842eSJung-uk Kim         {
1004f556842eSJung-uk Kim             Count++;
1005f556842eSJung-uk Kim         }
1006f556842eSJung-uk Kim 
1007f556842eSJung-uk Kim         External = External->Next;
1008f556842eSJung-uk Kim     }
1009f556842eSJung-uk Kim 
1010f556842eSJung-uk Kim     return (Count);
1011f556842eSJung-uk Kim }
1012f556842eSJung-uk Kim 
1013f556842eSJung-uk Kim 
1014f556842eSJung-uk Kim /*******************************************************************************
1015f556842eSJung-uk Kim  *
1016f556842eSJung-uk Kim  * FUNCTION:    AcpiDmClearExternalList
1017f556842eSJung-uk Kim  *
1018f556842eSJung-uk Kim  * PARAMETERS:  None
1019f556842eSJung-uk Kim  *
1020f556842eSJung-uk Kim  * RETURN:      None
1021f556842eSJung-uk Kim  *
1022f556842eSJung-uk Kim  * DESCRIPTION: Free the entire External info list
1023f556842eSJung-uk Kim  *
1024f556842eSJung-uk Kim  ******************************************************************************/
1025f556842eSJung-uk Kim 
1026f556842eSJung-uk Kim void
1027f556842eSJung-uk Kim AcpiDmClearExternalList (
1028f556842eSJung-uk Kim     void)
1029f556842eSJung-uk Kim {
1030f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
1031f556842eSJung-uk Kim 
1032f556842eSJung-uk Kim 
1033f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
1034f556842eSJung-uk Kim     {
1035f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
1036f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
1037f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
1038f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
1039f556842eSJung-uk Kim     }
1040f556842eSJung-uk Kim }
1041f556842eSJung-uk Kim 
1042f556842eSJung-uk Kim 
1043f556842eSJung-uk Kim /*******************************************************************************
1044f556842eSJung-uk Kim  *
1045f556842eSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternals
1046f556842eSJung-uk Kim  *
1047f556842eSJung-uk Kim  * PARAMETERS:  None
1048f556842eSJung-uk Kim  *
1049f556842eSJung-uk Kim  * RETURN:      None
1050f556842eSJung-uk Kim  *
1051f556842eSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1052f556842eSJung-uk Kim  *              the global external info list.
1053f556842eSJung-uk Kim  *
1054f556842eSJung-uk Kim  ******************************************************************************/
1055f556842eSJung-uk Kim 
1056f556842eSJung-uk Kim void
1057f556842eSJung-uk Kim AcpiDmEmitExternals (
1058f556842eSJung-uk Kim     void)
1059f556842eSJung-uk Kim {
1060f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
1061f556842eSJung-uk Kim 
1062f556842eSJung-uk Kim 
1063f556842eSJung-uk Kim     if (!AcpiGbl_ExternalList)
1064f556842eSJung-uk Kim     {
1065f556842eSJung-uk Kim         return;
1066f556842eSJung-uk Kim     }
1067f556842eSJung-uk Kim 
1068f556842eSJung-uk Kim     /*
10699c48c75eSJung-uk Kim      * Determine the number of control methods in the external list, and
10709c48c75eSJung-uk Kim      * also how many of those externals were resolved via the namespace.
10719c48c75eSJung-uk Kim      */
10729c48c75eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
10739c48c75eSJung-uk Kim     while (NextExternal)
10749c48c75eSJung-uk Kim     {
10759c48c75eSJung-uk Kim         if (NextExternal->Type == ACPI_TYPE_METHOD)
10769c48c75eSJung-uk Kim         {
10779c48c75eSJung-uk Kim             AcpiGbl_NumExternalMethods++;
1078313a0c13SJung-uk Kim             if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
10799c48c75eSJung-uk Kim             {
10809c48c75eSJung-uk Kim                 AcpiGbl_ResolvedExternalMethods++;
10819c48c75eSJung-uk Kim             }
10829c48c75eSJung-uk Kim         }
10839c48c75eSJung-uk Kim 
10849c48c75eSJung-uk Kim         NextExternal = NextExternal->Next;
10859c48c75eSJung-uk Kim     }
10869c48c75eSJung-uk Kim 
10879c48c75eSJung-uk Kim     /* Check if any control methods were unresolved */
10889c48c75eSJung-uk Kim 
10899c48c75eSJung-uk Kim     AcpiDmUnresolvedWarning (1);
10909c48c75eSJung-uk Kim 
109179c6d946SJung-uk Kim     if (Gbl_ExternalRefFilename)
109279c6d946SJung-uk Kim     {
109379c6d946SJung-uk Kim         AcpiOsPrintf (
1094*f8146b88SJung-uk Kim             "    /*\n     * External declarations were imported from\n"
1095*f8146b88SJung-uk Kim             "     * a reference file -- %s\n     */\n\n",
109679c6d946SJung-uk Kim             Gbl_ExternalRefFilename);
109779c6d946SJung-uk Kim     }
109879c6d946SJung-uk Kim 
10999c48c75eSJung-uk Kim     /*
1100*f8146b88SJung-uk Kim      * Walk and emit the list of externals found during the AML parsing
1101f556842eSJung-uk Kim      */
1102f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
1103f556842eSJung-uk Kim     {
1104313a0c13SJung-uk Kim         if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
1105bf6fac21SJung-uk Kim         {
1106*f8146b88SJung-uk Kim             AcpiOsPrintf ("    External (%s%s)",
1107f556842eSJung-uk Kim                 AcpiGbl_ExternalList->Path,
1108f556842eSJung-uk Kim                 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1109f556842eSJung-uk Kim 
1110*f8146b88SJung-uk Kim             /* Check for "unresolved" method reference */
1111*f8146b88SJung-uk Kim 
1112*f8146b88SJung-uk Kim             if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
1113*f8146b88SJung-uk Kim                 (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
1114*f8146b88SJung-uk Kim             {
1115*f8146b88SJung-uk Kim                 AcpiOsPrintf ("    // Warning: Unknown method, "
1116*f8146b88SJung-uk Kim                     "guessing %u arguments",
1117*f8146b88SJung-uk Kim                     AcpiGbl_ExternalList->Value);
1118*f8146b88SJung-uk Kim             }
1119*f8146b88SJung-uk Kim 
1120*f8146b88SJung-uk Kim             /* Check for external from a external references file */
1121*f8146b88SJung-uk Kim 
1122*f8146b88SJung-uk Kim             else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
1123*f8146b88SJung-uk Kim             {
1124*f8146b88SJung-uk Kim                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1125*f8146b88SJung-uk Kim                 {
1126*f8146b88SJung-uk Kim                     AcpiOsPrintf ("    // %u Arguments",
1127*f8146b88SJung-uk Kim                         AcpiGbl_ExternalList->Value);
1128*f8146b88SJung-uk Kim                 }
1129*f8146b88SJung-uk Kim 
1130*f8146b88SJung-uk Kim                 AcpiOsPrintf ("    // From external reference file");
1131*f8146b88SJung-uk Kim             }
1132*f8146b88SJung-uk Kim 
1133*f8146b88SJung-uk Kim             /* This is the normal external case */
1134*f8146b88SJung-uk Kim 
1135*f8146b88SJung-uk Kim             else
1136*f8146b88SJung-uk Kim             {
1137bf6fac21SJung-uk Kim                 /* For methods, add a comment with the number of arguments */
1138bf6fac21SJung-uk Kim 
1139f556842eSJung-uk Kim                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1140f556842eSJung-uk Kim                 {
1141*f8146b88SJung-uk Kim                     AcpiOsPrintf ("    // %u Arguments",
1142f556842eSJung-uk Kim                         AcpiGbl_ExternalList->Value);
1143f556842eSJung-uk Kim                 }
1144f556842eSJung-uk Kim             }
1145*f8146b88SJung-uk Kim 
1146*f8146b88SJung-uk Kim             AcpiOsPrintf ("\n");
1147bf6fac21SJung-uk Kim         }
1148f556842eSJung-uk Kim 
1149f556842eSJung-uk Kim         /* Free this external info block and move on to next external */
1150f556842eSJung-uk Kim 
1151f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
1152313a0c13SJung-uk Kim         if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
1153f556842eSJung-uk Kim         {
1154f556842eSJung-uk Kim             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1155f556842eSJung-uk Kim         }
1156f556842eSJung-uk Kim 
1157f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
1158f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
1159f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
1160f556842eSJung-uk Kim     }
1161f556842eSJung-uk Kim 
1162f556842eSJung-uk Kim     AcpiOsPrintf ("\n");
1163f556842eSJung-uk Kim }
11649c48c75eSJung-uk Kim 
11659c48c75eSJung-uk Kim 
11669c48c75eSJung-uk Kim /*******************************************************************************
11679c48c75eSJung-uk Kim  *
11689c48c75eSJung-uk Kim  * FUNCTION:    AcpiDmUnresolvedWarning
11699c48c75eSJung-uk Kim  *
11709c48c75eSJung-uk Kim  * PARAMETERS:  Type                - Where to output the warning.
11719c48c75eSJung-uk Kim  *                                    0 means write to stderr
11729c48c75eSJung-uk Kim  *                                    1 means write to AcpiOsPrintf
11739c48c75eSJung-uk Kim  *
11749c48c75eSJung-uk Kim  * RETURN:      None
11759c48c75eSJung-uk Kim  *
11769c48c75eSJung-uk Kim  * DESCRIPTION: Issue warning message if there are unresolved external control
11779c48c75eSJung-uk Kim  *              methods within the disassembly.
11789c48c75eSJung-uk Kim  *
11799c48c75eSJung-uk Kim  ******************************************************************************/
11809c48c75eSJung-uk Kim 
11819c48c75eSJung-uk Kim #if 0
11829c48c75eSJung-uk Kim Summary of the external control method problem:
11839c48c75eSJung-uk Kim 
11849c48c75eSJung-uk Kim When the -e option is used with disassembly, the various SSDTs are simply
11859c48c75eSJung-uk Kim loaded into a global namespace for the disassembler to use in order to
11869c48c75eSJung-uk Kim resolve control method references (invocations).
11879c48c75eSJung-uk Kim 
11889c48c75eSJung-uk Kim The disassembler tracks any such references, and will emit an External()
11899c48c75eSJung-uk Kim statement for these types of methods, with the proper number of arguments .
11909c48c75eSJung-uk Kim 
11919c48c75eSJung-uk Kim Without the SSDTs, the AML does not contain enough information to properly
11929c48c75eSJung-uk Kim disassemble the control method invocation -- because the disassembler does
11939c48c75eSJung-uk Kim not know how many arguments to parse.
11949c48c75eSJung-uk Kim 
11959c48c75eSJung-uk Kim An example: Assume we have two control methods. ABCD has one argument, and
11969c48c75eSJung-uk Kim EFGH has zero arguments. Further, we have two additional control methods
11979c48c75eSJung-uk Kim that invoke ABCD and EFGH, named T1 and T2:
11989c48c75eSJung-uk Kim 
11999c48c75eSJung-uk Kim     Method (ABCD, 1)
12009c48c75eSJung-uk Kim     {
12019c48c75eSJung-uk Kim     }
12029c48c75eSJung-uk Kim     Method (EFGH, 0)
12039c48c75eSJung-uk Kim     {
12049c48c75eSJung-uk Kim     }
12059c48c75eSJung-uk Kim     Method (T1)
12069c48c75eSJung-uk Kim     {
12079c48c75eSJung-uk Kim         ABCD (Add (2, 7, Local0))
12089c48c75eSJung-uk Kim     }
12099c48c75eSJung-uk Kim     Method (T2)
12109c48c75eSJung-uk Kim     {
12119c48c75eSJung-uk Kim         EFGH ()
12129c48c75eSJung-uk Kim         Add (2, 7, Local0)
12139c48c75eSJung-uk Kim     }
12149c48c75eSJung-uk Kim 
12159c48c75eSJung-uk Kim Here is the AML code that is generated for T1 and T2:
12169c48c75eSJung-uk Kim 
12179c48c75eSJung-uk Kim      185:      Method (T1)
12189c48c75eSJung-uk Kim 
12199c48c75eSJung-uk Kim 0000034C:  14 10 54 31 5F 5F 00 ...    "..T1__."
12209c48c75eSJung-uk Kim 
12219c48c75eSJung-uk Kim      186:      {
12229c48c75eSJung-uk Kim      187:          ABCD (Add (2, 7, Local0))
12239c48c75eSJung-uk Kim 
12249c48c75eSJung-uk Kim 00000353:  41 42 43 44 ............    "ABCD"
12259c48c75eSJung-uk Kim 00000357:  72 0A 02 0A 07 60 ......    "r....`"
12269c48c75eSJung-uk Kim 
12279c48c75eSJung-uk Kim      188:      }
12289c48c75eSJung-uk Kim 
12299c48c75eSJung-uk Kim      190:      Method (T2)
12309c48c75eSJung-uk Kim 
12319c48c75eSJung-uk Kim 0000035D:  14 10 54 32 5F 5F 00 ...    "..T2__."
12329c48c75eSJung-uk Kim 
12339c48c75eSJung-uk Kim      191:      {
12349c48c75eSJung-uk Kim      192:          EFGH ()
12359c48c75eSJung-uk Kim 
12369c48c75eSJung-uk Kim 00000364:  45 46 47 48 ............    "EFGH"
12379c48c75eSJung-uk Kim 
12389c48c75eSJung-uk Kim      193:          Add (2, 7, Local0)
12399c48c75eSJung-uk Kim 
12409c48c75eSJung-uk Kim 00000368:  72 0A 02 0A 07 60 ......    "r....`"
12419c48c75eSJung-uk Kim      194:      }
12429c48c75eSJung-uk Kim 
12439c48c75eSJung-uk Kim Note that the AML code for T1 and T2 is essentially identical. When
12449c48c75eSJung-uk Kim disassembling this code, the methods ABCD and EFGH must be known to the
12459c48c75eSJung-uk Kim disassembler, otherwise it does not know how to handle the method invocations.
12469c48c75eSJung-uk Kim 
12479c48c75eSJung-uk Kim In other words, if ABCD and EFGH are actually external control methods
12489c48c75eSJung-uk Kim appearing in an SSDT, the disassembler does not know what to do unless
12499c48c75eSJung-uk Kim the owning SSDT has been loaded via the -e option.
12509c48c75eSJung-uk Kim #endif
12519c48c75eSJung-uk Kim 
1252*f8146b88SJung-uk Kim static char             ExternalWarningPart1[600];
1253*f8146b88SJung-uk Kim static char             ExternalWarningPart2[400];
1254*f8146b88SJung-uk Kim static char             ExternalWarningPart3[400];
1255*f8146b88SJung-uk Kim static char             ExternalWarningPart4[200];
1256*f8146b88SJung-uk Kim 
12579c48c75eSJung-uk Kim void
12589c48c75eSJung-uk Kim AcpiDmUnresolvedWarning (
12599c48c75eSJung-uk Kim     UINT8                   Type)
12609c48c75eSJung-uk Kim {
1261*f8146b88SJung-uk Kim     char                    *Format;
1262*f8146b88SJung-uk Kim     char                    Pad[] = "     *";
1263*f8146b88SJung-uk Kim     char                    NoPad[] = "";
1264*f8146b88SJung-uk Kim 
12659c48c75eSJung-uk Kim 
12669c48c75eSJung-uk Kim     if (!AcpiGbl_NumExternalMethods)
12679c48c75eSJung-uk Kim     {
12689c48c75eSJung-uk Kim         return;
12699c48c75eSJung-uk Kim     }
12709c48c75eSJung-uk Kim 
1271*f8146b88SJung-uk Kim     if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
1272*f8146b88SJung-uk Kim     {
1273*f8146b88SJung-uk Kim         return;
1274*f8146b88SJung-uk Kim     }
1275*f8146b88SJung-uk Kim 
1276*f8146b88SJung-uk Kim     Format = Type ? Pad : NoPad;
1277*f8146b88SJung-uk Kim 
1278*f8146b88SJung-uk Kim     sprintf (ExternalWarningPart1,
1279*f8146b88SJung-uk Kim         "%s iASL Warning: There %s %u external control method%s found during\n"
1280*f8146b88SJung-uk Kim         "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1281*f8146b88SJung-uk Kim         "%s ACPI tables may be required to properly disassemble the code. This\n"
1282*f8146b88SJung-uk Kim         "%s resulting disassembler output file may not compile because the\n"
1283*f8146b88SJung-uk Kim         "%s disassembler did not know how many arguments to assign to the\n"
1284*f8146b88SJung-uk Kim         "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
1285*f8146b88SJung-uk Kim         "%s runtime and may or may not be available via the host OS.\n",
1286*f8146b88SJung-uk Kim         Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
1287*f8146b88SJung-uk Kim         AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
1288*f8146b88SJung-uk Kim         Format, AcpiGbl_ResolvedExternalMethods,
1289*f8146b88SJung-uk Kim         (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
1290*f8146b88SJung-uk Kim         (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
1291*f8146b88SJung-uk Kim         Format, Format, Format, Format, Format);
1292*f8146b88SJung-uk Kim 
1293*f8146b88SJung-uk Kim     sprintf (ExternalWarningPart2,
1294*f8146b88SJung-uk Kim         "%s To specify the tables needed to resolve external control method\n"
1295*f8146b88SJung-uk Kim         "%s references, the -e option can be used to specify the filenames.\n"
1296*f8146b88SJung-uk Kim         "%s Example iASL invocations:\n"
1297*f8146b88SJung-uk Kim         "%s     iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1298*f8146b88SJung-uk Kim         "%s     iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1299*f8146b88SJung-uk Kim         "%s     iasl -e ssdt*.aml -d dsdt.aml\n",
1300*f8146b88SJung-uk Kim         Format, Format, Format, Format, Format, Format);
1301*f8146b88SJung-uk Kim 
1302*f8146b88SJung-uk Kim     sprintf (ExternalWarningPart3,
1303*f8146b88SJung-uk Kim         "%s In addition, the -fe option can be used to specify a file containing\n"
1304*f8146b88SJung-uk Kim         "%s control method external declarations with the associated method\n"
1305*f8146b88SJung-uk Kim         "%s argument counts. Each line of the file must be of the form:\n"
1306*f8146b88SJung-uk Kim         "%s     External (<method pathname>, MethodObj, <argument count>)\n"
1307*f8146b88SJung-uk Kim         "%s Invocation:\n"
1308*f8146b88SJung-uk Kim         "%s     iasl -fe refs.txt -d dsdt.aml\n",
1309*f8146b88SJung-uk Kim         Format, Format, Format, Format, Format, Format);
1310*f8146b88SJung-uk Kim 
1311*f8146b88SJung-uk Kim     sprintf (ExternalWarningPart4,
1312*f8146b88SJung-uk Kim         "%s The following methods were unresolved and many not compile properly\n"
1313*f8146b88SJung-uk Kim         "%s because the disassembler had to guess at the number of arguments\n"
1314*f8146b88SJung-uk Kim         "%s required for each:\n",
1315*f8146b88SJung-uk Kim         Format, Format, Format);
1316*f8146b88SJung-uk Kim 
13179c48c75eSJung-uk Kim     if (Type)
13189c48c75eSJung-uk Kim     {
13199c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
13209c48c75eSJung-uk Kim         {
13219c48c75eSJung-uk Kim             /* The -e option was not specified */
13229c48c75eSJung-uk Kim 
1323*f8146b88SJung-uk Kim            AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     *\n%s     */\n",
1324*f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
1325*f8146b88SJung-uk Kim                ExternalWarningPart4);
13269c48c75eSJung-uk Kim         }
1327*f8146b88SJung-uk Kim         else
13289c48c75eSJung-uk Kim         {
13299c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
13309c48c75eSJung-uk Kim 
1331*f8146b88SJung-uk Kim             AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     */\n",
1332*f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
13339c48c75eSJung-uk Kim         }
13349c48c75eSJung-uk Kim     }
13359c48c75eSJung-uk Kim     else
13369c48c75eSJung-uk Kim     {
13379c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
13389c48c75eSJung-uk Kim         {
13399c48c75eSJung-uk Kim             /* The -e option was not specified */
13409c48c75eSJung-uk Kim 
1341*f8146b88SJung-uk Kim             fprintf (stderr, "\n%s\n%s\n%s\n",
1342*f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
13439c48c75eSJung-uk Kim         }
1344*f8146b88SJung-uk Kim         else
13459c48c75eSJung-uk Kim         {
13469c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
13479c48c75eSJung-uk Kim 
1348*f8146b88SJung-uk Kim             fprintf (stderr, "\n%s\n%s\n",
1349*f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart3);
13509c48c75eSJung-uk Kim         }
13519c48c75eSJung-uk Kim     }
13529c48c75eSJung-uk Kim }
1353