xref: /freebsd/sys/contrib/dev/acpica/common/dmextern.c (revision 58308fadece25ae4c12bd2f4dce3d73d9c23be43)
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 
70d84335fSJung-uk Kim /******************************************************************************
80d84335fSJung-uk Kim  *
90d84335fSJung-uk Kim  * 1. Copyright Notice
100d84335fSJung-uk Kim  *
11*58308fadSJung-uk Kim  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12f556842eSJung-uk Kim  * All rights reserved.
13f556842eSJung-uk Kim  *
140d84335fSJung-uk Kim  * 2. License
150d84335fSJung-uk Kim  *
160d84335fSJung-uk Kim  * 2.1. This is your license from Intel Corp. under its intellectual property
170d84335fSJung-uk Kim  * rights. You may have additional license terms from the party that provided
180d84335fSJung-uk Kim  * you this software, covering your right to use that party's intellectual
190d84335fSJung-uk Kim  * property rights.
200d84335fSJung-uk Kim  *
210d84335fSJung-uk Kim  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
220d84335fSJung-uk Kim  * copy of the source code appearing in this file ("Covered Code") an
230d84335fSJung-uk Kim  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
240d84335fSJung-uk Kim  * base code distributed originally by Intel ("Original Intel Code") to copy,
250d84335fSJung-uk Kim  * make derivatives, distribute, use and display any portion of the Covered
260d84335fSJung-uk Kim  * Code in any form, with the right to sublicense such rights; and
270d84335fSJung-uk Kim  *
280d84335fSJung-uk Kim  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
290d84335fSJung-uk Kim  * license (with the right to sublicense), under only those claims of Intel
300d84335fSJung-uk Kim  * patents that are infringed by the Original Intel Code, to make, use, sell,
310d84335fSJung-uk Kim  * offer to sell, and import the Covered Code and derivative works thereof
320d84335fSJung-uk Kim  * solely to the minimum extent necessary to exercise the above copyright
330d84335fSJung-uk Kim  * license, and in no event shall the patent license extend to any additions
340d84335fSJung-uk Kim  * to or modifications of the Original Intel Code. No other license or right
350d84335fSJung-uk Kim  * is granted directly or by implication, estoppel or otherwise;
360d84335fSJung-uk Kim  *
370d84335fSJung-uk Kim  * The above copyright and patent license is granted only if the following
380d84335fSJung-uk Kim  * conditions are met:
390d84335fSJung-uk Kim  *
400d84335fSJung-uk Kim  * 3. Conditions
410d84335fSJung-uk Kim  *
420d84335fSJung-uk Kim  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
430d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
440d84335fSJung-uk Kim  * Code or modification with rights to further distribute source must include
450d84335fSJung-uk Kim  * the above Copyright Notice, the above License, this list of Conditions,
460d84335fSJung-uk Kim  * and the following Disclaimer and Export Compliance provision. In addition,
470d84335fSJung-uk Kim  * Licensee must cause all Covered Code to which Licensee contributes to
480d84335fSJung-uk Kim  * contain a file documenting the changes Licensee made to create that Covered
490d84335fSJung-uk Kim  * Code and the date of any change. Licensee must include in that file the
500d84335fSJung-uk Kim  * documentation of any changes made by any predecessor Licensee. Licensee
510d84335fSJung-uk Kim  * must include a prominent statement that the modification is derived,
520d84335fSJung-uk Kim  * directly or indirectly, from Original Intel Code.
530d84335fSJung-uk Kim  *
540d84335fSJung-uk Kim  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
550d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
560d84335fSJung-uk Kim  * Code or modification without rights to further distribute source must
570d84335fSJung-uk Kim  * include the following Disclaimer and Export Compliance provision in the
580d84335fSJung-uk Kim  * documentation and/or other materials provided with distribution. In
590d84335fSJung-uk Kim  * addition, Licensee may not authorize further sublicense of source of any
600d84335fSJung-uk Kim  * portion of the Covered Code, and must include terms to the effect that the
610d84335fSJung-uk Kim  * license from Licensee to its licensee is limited to the intellectual
620d84335fSJung-uk Kim  * property embodied in the software Licensee provides to its licensee, and
630d84335fSJung-uk Kim  * not to intellectual property embodied in modifications its licensee may
640d84335fSJung-uk Kim  * make.
650d84335fSJung-uk Kim  *
660d84335fSJung-uk Kim  * 3.3. Redistribution of Executable. Redistribution in executable form of any
670d84335fSJung-uk Kim  * substantial portion of the Covered Code or modification must reproduce the
680d84335fSJung-uk Kim  * above Copyright Notice, and the following Disclaimer and Export Compliance
690d84335fSJung-uk Kim  * provision in the documentation and/or other materials provided with the
700d84335fSJung-uk Kim  * distribution.
710d84335fSJung-uk Kim  *
720d84335fSJung-uk Kim  * 3.4. Intel retains all right, title, and interest in and to the Original
730d84335fSJung-uk Kim  * Intel Code.
740d84335fSJung-uk Kim  *
750d84335fSJung-uk Kim  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
760d84335fSJung-uk Kim  * Intel shall be used in advertising or otherwise to promote the sale, use or
770d84335fSJung-uk Kim  * other dealings in products derived from or relating to the Covered Code
780d84335fSJung-uk Kim  * without prior written authorization from Intel.
790d84335fSJung-uk Kim  *
800d84335fSJung-uk Kim  * 4. Disclaimer and Export Compliance
810d84335fSJung-uk Kim  *
820d84335fSJung-uk Kim  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
830d84335fSJung-uk Kim  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
840d84335fSJung-uk Kim  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
850d84335fSJung-uk Kim  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
860d84335fSJung-uk Kim  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
870d84335fSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
880d84335fSJung-uk Kim  * PARTICULAR PURPOSE.
890d84335fSJung-uk Kim  *
900d84335fSJung-uk Kim  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
910d84335fSJung-uk Kim  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
920d84335fSJung-uk Kim  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
930d84335fSJung-uk Kim  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
940d84335fSJung-uk Kim  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
950d84335fSJung-uk Kim  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
960d84335fSJung-uk Kim  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
970d84335fSJung-uk Kim  * LIMITED REMEDY.
980d84335fSJung-uk Kim  *
990d84335fSJung-uk Kim  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1000d84335fSJung-uk Kim  * software or system incorporating such software without first obtaining any
1010d84335fSJung-uk Kim  * required license or other approval from the U. S. Department of Commerce or
1020d84335fSJung-uk Kim  * any other agency or department of the United States Government. In the
1030d84335fSJung-uk Kim  * event Licensee exports any such software from the United States or
1040d84335fSJung-uk Kim  * re-exports any such software from a foreign destination, Licensee shall
1050d84335fSJung-uk Kim  * ensure that the distribution and export/re-export of the software is in
1060d84335fSJung-uk Kim  * compliance with all laws, regulations, orders, or other restrictions of the
1070d84335fSJung-uk Kim  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1080d84335fSJung-uk Kim  * any of its subsidiaries will export/re-export any technical data, process,
1090d84335fSJung-uk Kim  * software, or service, directly or indirectly, to any country for which the
1100d84335fSJung-uk Kim  * United States government or any agency thereof requires an export license,
1110d84335fSJung-uk Kim  * other governmental approval, or letter of assurance, without first obtaining
1120d84335fSJung-uk Kim  * such license, approval or letter.
1130d84335fSJung-uk Kim  *
1140d84335fSJung-uk Kim  *****************************************************************************
1150d84335fSJung-uk Kim  *
1160d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
1170d84335fSJung-uk Kim  * following license:
1180d84335fSJung-uk Kim  *
119d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
120d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
121d244b227SJung-uk Kim  * are met:
122d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
123d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
124d244b227SJung-uk Kim  *    without modification.
125d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
127d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
128d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
129d244b227SJung-uk Kim  *    binary redistribution.
130d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
131d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
132d244b227SJung-uk Kim  *    from this software without specific prior written permission.
133f556842eSJung-uk Kim  *
1340d84335fSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1350d84335fSJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1360d84335fSJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1370d84335fSJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1380d84335fSJung-uk Kim  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1390d84335fSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1400d84335fSJung-uk Kim  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1410d84335fSJung-uk Kim  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1420d84335fSJung-uk Kim  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1430d84335fSJung-uk Kim  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1440d84335fSJung-uk Kim  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1450d84335fSJung-uk Kim  *
1460d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
147d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
148d244b227SJung-uk Kim  * Software Foundation.
149f556842eSJung-uk Kim  *
1500d84335fSJung-uk Kim  *****************************************************************************/
151f556842eSJung-uk Kim 
152f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
153f556842eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
154f556842eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
155f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
156f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h>
15779c6d946SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
1589c48c75eSJung-uk Kim #include <stdio.h>
15979c6d946SJung-uk Kim #include <errno.h>
160f556842eSJung-uk Kim 
161f556842eSJung-uk Kim 
162f556842eSJung-uk Kim /*
163f556842eSJung-uk Kim  * This module is used for application-level code (iASL disassembler) only.
164f556842eSJung-uk Kim  *
165f556842eSJung-uk Kim  * It contains the code to create and emit any necessary External() ASL
166f556842eSJung-uk Kim  * statements for the module being disassembled.
167f556842eSJung-uk Kim  */
168f556842eSJung-uk Kim #define _COMPONENT          ACPI_CA_DISASSEMBLER
169f556842eSJung-uk Kim         ACPI_MODULE_NAME    ("dmextern")
170f556842eSJung-uk Kim 
171f556842eSJung-uk Kim 
172f556842eSJung-uk Kim /*
173f556842eSJung-uk Kim  * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
174f556842eSJung-uk Kim  * ObjectTypeKeyword. Used to generate typed external declarations
175f556842eSJung-uk Kim  */
176f556842eSJung-uk Kim static const char           *AcpiGbl_DmTypeNames[] =
177f556842eSJung-uk Kim {
178313a0c13SJung-uk Kim     /* 00 */ ", UnknownObj",        /* Type ANY */
179f556842eSJung-uk Kim     /* 01 */ ", IntObj",
180f556842eSJung-uk Kim     /* 02 */ ", StrObj",
181f556842eSJung-uk Kim     /* 03 */ ", BuffObj",
182f556842eSJung-uk Kim     /* 04 */ ", PkgObj",
183f556842eSJung-uk Kim     /* 05 */ ", FieldUnitObj",
184f556842eSJung-uk Kim     /* 06 */ ", DeviceObj",
185f556842eSJung-uk Kim     /* 07 */ ", EventObj",
186f556842eSJung-uk Kim     /* 08 */ ", MethodObj",
187f556842eSJung-uk Kim     /* 09 */ ", MutexObj",
188f556842eSJung-uk Kim     /* 10 */ ", OpRegionObj",
189f556842eSJung-uk Kim     /* 11 */ ", PowerResObj",
190f556842eSJung-uk Kim     /* 12 */ ", ProcessorObj",
191f556842eSJung-uk Kim     /* 13 */ ", ThermalZoneObj",
192f556842eSJung-uk Kim     /* 14 */ ", BuffFieldObj",
193f556842eSJung-uk Kim     /* 15 */ ", DDBHandleObj",
194f556842eSJung-uk Kim     /* 16 */ "",                    /* Debug object */
195f556842eSJung-uk Kim     /* 17 */ ", FieldUnitObj",
196f556842eSJung-uk Kim     /* 18 */ ", FieldUnitObj",
197f556842eSJung-uk Kim     /* 19 */ ", FieldUnitObj"
198f556842eSJung-uk Kim };
199f556842eSJung-uk Kim 
20079c6d946SJung-uk Kim #define METHOD_SEPARATORS           " \t,()\n"
20179c6d946SJung-uk Kim 
202af051161SJung-uk Kim static const char          *ExternalConflictMessage =
203af051161SJung-uk Kim     "    // Conflicts with a later declaration";
204af051161SJung-uk Kim 
205f556842eSJung-uk Kim 
206f556842eSJung-uk Kim /* Local prototypes */
207f556842eSJung-uk Kim 
208f556842eSJung-uk Kim static const char *
209f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
210f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type);
211f556842eSJung-uk Kim 
212f556842eSJung-uk Kim static char *
213f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
214f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
215f556842eSJung-uk Kim     char                    *Path);
216f556842eSJung-uk Kim 
217af051161SJung-uk Kim static ACPI_STATUS
218af051161SJung-uk Kim AcpiDmGetExternalAndInternalPath (
219af051161SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node,
220af051161SJung-uk Kim     char                    **ExternalPath,
221af051161SJung-uk Kim     char                    **InternalPath);
222af051161SJung-uk Kim 
223af051161SJung-uk Kim static ACPI_STATUS
224af051161SJung-uk Kim AcpiDmRemoveRootPrefix (
225af051161SJung-uk Kim     char                    **Path);
226af051161SJung-uk Kim 
22779c6d946SJung-uk Kim static void
228313a0c13SJung-uk Kim AcpiDmAddPathToExternalList (
22979c6d946SJung-uk Kim     char                    *Path,
23079c6d946SJung-uk Kim     UINT8                   Type,
231313a0c13SJung-uk Kim     UINT32                  Value,
232313a0c13SJung-uk Kim     UINT16                  Flags);
233313a0c13SJung-uk Kim 
234313a0c13SJung-uk Kim static ACPI_STATUS
235313a0c13SJung-uk Kim AcpiDmCreateNewExternal (
236313a0c13SJung-uk Kim     char                    *ExternalPath,
237313a0c13SJung-uk Kim     char                    *InternalPath,
238313a0c13SJung-uk Kim     UINT8                   Type,
239313a0c13SJung-uk Kim     UINT32                  Value,
240313a0c13SJung-uk Kim     UINT16                  Flags);
24179c6d946SJung-uk Kim 
242af051161SJung-uk Kim static void
243af051161SJung-uk Kim AcpiDmCheckForExternalConflict (
244af051161SJung-uk Kim     char                    *Path);
245af051161SJung-uk Kim 
246af051161SJung-uk Kim static ACPI_STATUS
247af051161SJung-uk Kim AcpiDmResolveExternal (
248af051161SJung-uk Kim     char                    *Path,
249af051161SJung-uk Kim     UINT8                   Type,
250af051161SJung-uk Kim     ACPI_NAMESPACE_NODE     **Node);
251af051161SJung-uk Kim 
252af051161SJung-uk Kim 
253af051161SJung-uk Kim static void
254af051161SJung-uk Kim AcpiDmConflictingDeclaration (
255af051161SJung-uk Kim     char                    *Path);
256af051161SJung-uk Kim 
257f556842eSJung-uk Kim 
258f556842eSJung-uk Kim /*******************************************************************************
259f556842eSJung-uk Kim  *
260f556842eSJung-uk Kim  * FUNCTION:    AcpiDmGetObjectTypeName
261f556842eSJung-uk Kim  *
262f556842eSJung-uk Kim  * PARAMETERS:  Type                - An ACPI_OBJECT_TYPE
263f556842eSJung-uk Kim  *
264f556842eSJung-uk Kim  * RETURN:      Pointer to a string
265f556842eSJung-uk Kim  *
266f556842eSJung-uk Kim  * DESCRIPTION: Map an object type to the ASL object type string.
267f556842eSJung-uk Kim  *
268f556842eSJung-uk Kim  ******************************************************************************/
269f556842eSJung-uk Kim 
270f556842eSJung-uk Kim static const char *
AcpiDmGetObjectTypeName(ACPI_OBJECT_TYPE Type)271f556842eSJung-uk Kim AcpiDmGetObjectTypeName (
272f556842eSJung-uk Kim     ACPI_OBJECT_TYPE        Type)
273f556842eSJung-uk Kim {
274f556842eSJung-uk Kim 
275f556842eSJung-uk Kim     if (Type == ACPI_TYPE_LOCAL_SCOPE)
276f556842eSJung-uk Kim     {
277f556842eSJung-uk Kim         Type = ACPI_TYPE_DEVICE;
278f556842eSJung-uk Kim     }
279f556842eSJung-uk Kim     else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
280f556842eSJung-uk Kim     {
281f556842eSJung-uk Kim         return ("");
282f556842eSJung-uk Kim     }
283f556842eSJung-uk Kim 
284f556842eSJung-uk Kim     return (AcpiGbl_DmTypeNames[Type]);
285f556842eSJung-uk Kim }
286f556842eSJung-uk Kim 
287f556842eSJung-uk Kim 
288f556842eSJung-uk Kim /*******************************************************************************
289f556842eSJung-uk Kim  *
290f556842eSJung-uk Kim  * FUNCTION:    AcpiDmNormalizeParentPrefix
291f556842eSJung-uk Kim  *
292f556842eSJung-uk Kim  * PARAMETERS:  Op                  - Parse op
293f556842eSJung-uk Kim  *              Path                - Path with parent prefix
294f556842eSJung-uk Kim  *
295f556842eSJung-uk Kim  * RETURN:      The full pathname to the object (from the namespace root)
296f556842eSJung-uk Kim  *
297f556842eSJung-uk Kim  * DESCRIPTION: Returns the full pathname of a path with parent prefix
298f556842eSJung-uk Kim  *              The caller must free the fullpath returned.
299f556842eSJung-uk Kim  *
300f556842eSJung-uk Kim  ******************************************************************************/
301f556842eSJung-uk Kim 
302f556842eSJung-uk Kim static char *
AcpiDmNormalizeParentPrefix(ACPI_PARSE_OBJECT * Op,char * Path)303f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix (
304f556842eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
305f556842eSJung-uk Kim     char                    *Path)
306f556842eSJung-uk Kim {
307f556842eSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
308f556842eSJung-uk Kim     char                    *Fullpath;
309f556842eSJung-uk Kim     char                    *ParentPath;
310f556842eSJung-uk Kim     ACPI_SIZE               Length;
311ed17e06eSJung-uk Kim     UINT32                  Index = 0;
312f556842eSJung-uk Kim 
313f556842eSJung-uk Kim 
314ed17e06eSJung-uk Kim     if (!Op)
315ed17e06eSJung-uk Kim     {
316ed17e06eSJung-uk Kim         return (NULL);
317ed17e06eSJung-uk Kim     }
318f556842eSJung-uk Kim 
319ed17e06eSJung-uk Kim     /* Search upwards in the parse tree until we reach the next namespace node */
320ed17e06eSJung-uk Kim 
321ed17e06eSJung-uk Kim     Op = Op->Common.Parent;
322f556842eSJung-uk Kim     while (Op)
323f556842eSJung-uk Kim     {
324f556842eSJung-uk Kim         if (Op->Common.Node)
325f556842eSJung-uk Kim         {
326f556842eSJung-uk Kim             break;
327f556842eSJung-uk Kim         }
328f556842eSJung-uk Kim 
329f556842eSJung-uk Kim         Op = Op->Common.Parent;
330f556842eSJung-uk Kim     }
331f556842eSJung-uk Kim 
332f556842eSJung-uk Kim     if (!Op)
333f556842eSJung-uk Kim     {
334f556842eSJung-uk Kim         return (NULL);
335f556842eSJung-uk Kim     }
336f556842eSJung-uk Kim 
337f556842eSJung-uk Kim     /*
338f556842eSJung-uk Kim      * Find the actual parent node for the reference:
339f556842eSJung-uk Kim      * Remove all carat prefixes from the input path.
340f556842eSJung-uk Kim      * There may be multiple parent prefixes (For example, ^^^M000)
341f556842eSJung-uk Kim      */
342f556842eSJung-uk Kim     Node = Op->Common.Node;
343f556842eSJung-uk Kim     while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
344f556842eSJung-uk Kim     {
345a88e22b7SJung-uk Kim         Node = Node->Parent;
346f556842eSJung-uk Kim         Path++;
347f556842eSJung-uk Kim     }
348f556842eSJung-uk Kim 
349f556842eSJung-uk Kim     if (!Node)
350f556842eSJung-uk Kim     {
351f556842eSJung-uk Kim         return (NULL);
352f556842eSJung-uk Kim     }
353f556842eSJung-uk Kim 
354f556842eSJung-uk Kim     /* Get the full pathname for the parent node */
355f556842eSJung-uk Kim 
356f556842eSJung-uk Kim     ParentPath = AcpiNsGetExternalPathname (Node);
357f556842eSJung-uk Kim     if (!ParentPath)
358f556842eSJung-uk Kim     {
359f556842eSJung-uk Kim         return (NULL);
360f556842eSJung-uk Kim     }
361f556842eSJung-uk Kim 
3625ef50723SJung-uk Kim     Length = (strlen (ParentPath) + strlen (Path) + 1);
3638c8be05fSJung-uk Kim     if (ParentPath[1])
3648c8be05fSJung-uk Kim     {
3658c8be05fSJung-uk Kim         /*
3668c8be05fSJung-uk Kim          * If ParentPath is not just a simple '\', increment the length
3678c8be05fSJung-uk Kim          * for the required dot separator (ParentPath.Path)
3688c8be05fSJung-uk Kim          */
3698c8be05fSJung-uk Kim         Length++;
370ed17e06eSJung-uk Kim 
371ed17e06eSJung-uk Kim         /* For External() statements, we do not want a leading '\' */
372ed17e06eSJung-uk Kim 
373ed17e06eSJung-uk Kim         if (*ParentPath == AML_ROOT_PREFIX)
374ed17e06eSJung-uk Kim         {
375ed17e06eSJung-uk Kim             Index = 1;
376ed17e06eSJung-uk Kim         }
3778c8be05fSJung-uk Kim     }
3788c8be05fSJung-uk Kim 
379f556842eSJung-uk Kim     Fullpath = ACPI_ALLOCATE_ZEROED (Length);
380f556842eSJung-uk Kim     if (!Fullpath)
381f556842eSJung-uk Kim     {
382f556842eSJung-uk Kim         goto Cleanup;
383f556842eSJung-uk Kim     }
384f556842eSJung-uk Kim 
385f556842eSJung-uk Kim     /*
386f556842eSJung-uk Kim      * Concatenate parent fullpath and path. For example,
387f556842eSJung-uk Kim      * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
388f556842eSJung-uk Kim      *
389f556842eSJung-uk Kim      * Copy the parent path
390f556842eSJung-uk Kim      */
3915ef50723SJung-uk Kim     strcpy (Fullpath, &ParentPath[Index]);
392f556842eSJung-uk Kim 
393f38b0f21SJung-uk Kim     /*
394f38b0f21SJung-uk Kim      * Add dot separator
395f38b0f21SJung-uk Kim      * (don't need dot if parent fullpath is a single backslash)
396f38b0f21SJung-uk Kim      */
397f556842eSJung-uk Kim     if (ParentPath[1])
398f556842eSJung-uk Kim     {
3995ef50723SJung-uk Kim         strcat (Fullpath, ".");
400f556842eSJung-uk Kim     }
401f556842eSJung-uk Kim 
402f556842eSJung-uk Kim     /* Copy child path (carat parent prefix(es) were skipped above) */
403f556842eSJung-uk Kim 
4045ef50723SJung-uk Kim     strcat (Fullpath, Path);
405f556842eSJung-uk Kim 
406f556842eSJung-uk Kim Cleanup:
407f556842eSJung-uk Kim     ACPI_FREE (ParentPath);
408f556842eSJung-uk Kim     return (Fullpath);
409f556842eSJung-uk Kim }
410f556842eSJung-uk Kim 
411f556842eSJung-uk Kim 
412f556842eSJung-uk Kim /*******************************************************************************
413f556842eSJung-uk Kim  *
414709fac06SJung-uk Kim  * FUNCTION:    AcpiDmAddToExternalFileList
415709fac06SJung-uk Kim  *
416709fac06SJung-uk Kim  * PARAMETERS:  PathList            - Single path or list separated by comma
417709fac06SJung-uk Kim  *
418709fac06SJung-uk Kim  * RETURN:      None
419709fac06SJung-uk Kim  *
420709fac06SJung-uk Kim  * DESCRIPTION: Add external files to global list
421709fac06SJung-uk Kim  *
422709fac06SJung-uk Kim  ******************************************************************************/
423709fac06SJung-uk Kim 
424709fac06SJung-uk Kim ACPI_STATUS
AcpiDmAddToExternalFileList(char * Pathname)425709fac06SJung-uk Kim AcpiDmAddToExternalFileList (
426313a0c13SJung-uk Kim     char                    *Pathname)
427709fac06SJung-uk Kim {
428709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *ExternalFile;
429313a0c13SJung-uk Kim     char                    *LocalPathname;
430709fac06SJung-uk Kim 
431709fac06SJung-uk Kim 
432313a0c13SJung-uk Kim     if (!Pathname)
433709fac06SJung-uk Kim     {
434709fac06SJung-uk Kim         return (AE_OK);
435709fac06SJung-uk Kim     }
436709fac06SJung-uk Kim 
437313a0c13SJung-uk Kim     LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
438313a0c13SJung-uk Kim     if (!LocalPathname)
439709fac06SJung-uk Kim     {
440709fac06SJung-uk Kim         return (AE_NO_MEMORY);
441709fac06SJung-uk Kim     }
442709fac06SJung-uk Kim 
443709fac06SJung-uk Kim     ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
444709fac06SJung-uk Kim     if (!ExternalFile)
445709fac06SJung-uk Kim     {
446313a0c13SJung-uk Kim         ACPI_FREE (LocalPathname);
447709fac06SJung-uk Kim         return (AE_NO_MEMORY);
448709fac06SJung-uk Kim     }
449709fac06SJung-uk Kim 
450313a0c13SJung-uk Kim     /* Take a copy of the file pathname */
451313a0c13SJung-uk Kim 
452313a0c13SJung-uk Kim     strcpy (LocalPathname, Pathname);
453313a0c13SJung-uk Kim     ExternalFile->Path = LocalPathname;
454709fac06SJung-uk Kim 
455709fac06SJung-uk Kim     if (AcpiGbl_ExternalFileList)
456709fac06SJung-uk Kim     {
457709fac06SJung-uk Kim         ExternalFile->Next = AcpiGbl_ExternalFileList;
458709fac06SJung-uk Kim     }
459709fac06SJung-uk Kim 
460709fac06SJung-uk Kim     AcpiGbl_ExternalFileList = ExternalFile;
461709fac06SJung-uk Kim     return (AE_OK);
462709fac06SJung-uk Kim }
463709fac06SJung-uk Kim 
464709fac06SJung-uk Kim 
465709fac06SJung-uk Kim /*******************************************************************************
466709fac06SJung-uk Kim  *
467709fac06SJung-uk Kim  * FUNCTION:    AcpiDmClearExternalFileList
468709fac06SJung-uk Kim  *
469709fac06SJung-uk Kim  * PARAMETERS:  None
470709fac06SJung-uk Kim  *
471709fac06SJung-uk Kim  * RETURN:      None
472709fac06SJung-uk Kim  *
473709fac06SJung-uk Kim  * DESCRIPTION: Clear the external file list
474709fac06SJung-uk Kim  *
475709fac06SJung-uk Kim  ******************************************************************************/
476709fac06SJung-uk Kim 
477709fac06SJung-uk Kim void
AcpiDmClearExternalFileList(void)478709fac06SJung-uk Kim AcpiDmClearExternalFileList (
479709fac06SJung-uk Kim     void)
480709fac06SJung-uk Kim {
481709fac06SJung-uk Kim     ACPI_EXTERNAL_FILE      *NextExternal;
482709fac06SJung-uk Kim 
483709fac06SJung-uk Kim 
484709fac06SJung-uk Kim     while (AcpiGbl_ExternalFileList)
485709fac06SJung-uk Kim     {
486709fac06SJung-uk Kim         NextExternal = AcpiGbl_ExternalFileList->Next;
487709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList->Path);
488709fac06SJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalFileList);
489709fac06SJung-uk Kim         AcpiGbl_ExternalFileList = NextExternal;
490709fac06SJung-uk Kim     }
491709fac06SJung-uk Kim }
492709fac06SJung-uk Kim 
493709fac06SJung-uk Kim 
494709fac06SJung-uk Kim /*******************************************************************************
495709fac06SJung-uk Kim  *
49679c6d946SJung-uk Kim  * FUNCTION:    AcpiDmGetExternalsFromFile
49779c6d946SJung-uk Kim  *
49879c6d946SJung-uk Kim  * PARAMETERS:  None
49979c6d946SJung-uk Kim  *
50079c6d946SJung-uk Kim  * RETURN:      None
50179c6d946SJung-uk Kim  *
50279c6d946SJung-uk Kim  * DESCRIPTION: Process the optional external reference file.
50379c6d946SJung-uk Kim  *
50479c6d946SJung-uk Kim  * Each line in the file should be of the form:
50579c6d946SJung-uk Kim  *      External (<Method namepath>, MethodObj, <ArgCount>)
50679c6d946SJung-uk Kim  *
50779c6d946SJung-uk Kim  * Example:
50879c6d946SJung-uk Kim  *      External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
50979c6d946SJung-uk Kim  *
51079c6d946SJung-uk Kim  ******************************************************************************/
51179c6d946SJung-uk Kim 
51279c6d946SJung-uk Kim void
AcpiDmGetExternalsFromFile(void)51379c6d946SJung-uk Kim AcpiDmGetExternalsFromFile (
51479c6d946SJung-uk Kim     void)
51579c6d946SJung-uk Kim {
51679c6d946SJung-uk Kim     FILE                    *ExternalRefFile;
51779c6d946SJung-uk Kim     char                    *Token;
51879c6d946SJung-uk Kim     char                    *MethodName;
51979c6d946SJung-uk Kim     UINT32                  ArgCount;
52079c6d946SJung-uk Kim     UINT32                  ImportCount = 0;
52179c6d946SJung-uk Kim 
52279c6d946SJung-uk Kim 
5236f1f1a63SJung-uk Kim     if (!AslGbl_ExternalRefFilename)
52479c6d946SJung-uk Kim     {
52579c6d946SJung-uk Kim         return;
52679c6d946SJung-uk Kim     }
52779c6d946SJung-uk Kim 
52879c6d946SJung-uk Kim     /* Open the file */
52979c6d946SJung-uk Kim 
5306f1f1a63SJung-uk Kim     ExternalRefFile = fopen (AslGbl_ExternalRefFilename, "r");
53179c6d946SJung-uk Kim     if (!ExternalRefFile)
53279c6d946SJung-uk Kim     {
53379c6d946SJung-uk Kim         fprintf (stderr, "Could not open external reference file \"%s\"\n",
5346f1f1a63SJung-uk Kim             AslGbl_ExternalRefFilename);
535313a0c13SJung-uk Kim         AslAbort ();
53679c6d946SJung-uk Kim         return;
53779c6d946SJung-uk Kim     }
53879c6d946SJung-uk Kim 
53979c6d946SJung-uk Kim     /* Each line defines a method */
54079c6d946SJung-uk Kim 
5416f1f1a63SJung-uk Kim     while (fgets (AslGbl_StringBuffer, ASL_STRING_BUFFER_SIZE, ExternalRefFile))
54279c6d946SJung-uk Kim     {
5436f1f1a63SJung-uk Kim         Token = strtok (AslGbl_StringBuffer, METHOD_SEPARATORS);   /* "External" */
544313a0c13SJung-uk Kim         if (!Token)
545313a0c13SJung-uk Kim         {
546313a0c13SJung-uk Kim             continue;
547313a0c13SJung-uk Kim         }
548f8146b88SJung-uk Kim 
549313a0c13SJung-uk Kim         if (strcmp (Token, "External"))
550313a0c13SJung-uk Kim         {
551313a0c13SJung-uk Kim             continue;
552313a0c13SJung-uk Kim         }
55379c6d946SJung-uk Kim 
55479c6d946SJung-uk Kim         MethodName = strtok (NULL, METHOD_SEPARATORS);      /* Method namepath */
555313a0c13SJung-uk Kim         if (!MethodName)
556313a0c13SJung-uk Kim         {
557313a0c13SJung-uk Kim             continue;
558313a0c13SJung-uk Kim         }
55979c6d946SJung-uk Kim 
56079c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* "MethodObj" */
561313a0c13SJung-uk Kim         if (!Token)
562313a0c13SJung-uk Kim         {
563313a0c13SJung-uk Kim             continue;
564313a0c13SJung-uk Kim         }
565313a0c13SJung-uk Kim 
566313a0c13SJung-uk Kim         if (strcmp (Token, "MethodObj"))
567313a0c13SJung-uk Kim         {
568313a0c13SJung-uk Kim             continue;
569313a0c13SJung-uk Kim         }
57079c6d946SJung-uk Kim 
57179c6d946SJung-uk Kim         Token = strtok (NULL, METHOD_SEPARATORS);           /* Arg count */
572313a0c13SJung-uk Kim         if (!Token)
573313a0c13SJung-uk Kim         {
574313a0c13SJung-uk Kim             continue;
575313a0c13SJung-uk Kim         }
57679c6d946SJung-uk Kim 
57779c6d946SJung-uk Kim         /* Convert arg count string to an integer */
57879c6d946SJung-uk Kim 
57979c6d946SJung-uk Kim         errno = 0;
58079c6d946SJung-uk Kim         ArgCount = strtoul (Token, NULL, 0);
58179c6d946SJung-uk Kim         if (errno)
58279c6d946SJung-uk Kim         {
58379c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%s)\n", Token);
58479c6d946SJung-uk Kim             continue;
58579c6d946SJung-uk Kim         }
586f8146b88SJung-uk Kim 
58779c6d946SJung-uk Kim         if (ArgCount > 7)
58879c6d946SJung-uk Kim         {
58979c6d946SJung-uk Kim             fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
59079c6d946SJung-uk Kim             continue;
59179c6d946SJung-uk Kim         }
59279c6d946SJung-uk Kim 
59379c6d946SJung-uk Kim         /* Add this external to the global list */
59479c6d946SJung-uk Kim 
59579c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
5966f1f1a63SJung-uk Kim             AslGbl_ExternalRefFilename, ArgCount, MethodName);
59779c6d946SJung-uk Kim 
598313a0c13SJung-uk Kim         AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
599313a0c13SJung-uk Kim             ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
60079c6d946SJung-uk Kim         ImportCount++;
60179c6d946SJung-uk Kim     }
60279c6d946SJung-uk Kim 
60379c6d946SJung-uk Kim     if (!ImportCount)
60479c6d946SJung-uk Kim     {
605f8146b88SJung-uk Kim         fprintf (stderr,
606f8146b88SJung-uk Kim             "Did not find any external methods in reference file \"%s\"\n",
6076f1f1a63SJung-uk Kim             AslGbl_ExternalRefFilename);
60879c6d946SJung-uk Kim     }
60979c6d946SJung-uk Kim     else
61079c6d946SJung-uk Kim     {
61179c6d946SJung-uk Kim         /* Add the external(s) to the namespace */
61279c6d946SJung-uk Kim 
613af051161SJung-uk Kim         AcpiDmAddExternalListToNamespace ();
61479c6d946SJung-uk Kim 
61579c6d946SJung-uk Kim         AcpiOsPrintf ("%s: Imported %u external method definitions\n",
6166f1f1a63SJung-uk Kim             AslGbl_ExternalRefFilename, ImportCount);
61779c6d946SJung-uk Kim     }
61879c6d946SJung-uk Kim 
61979c6d946SJung-uk Kim     fclose (ExternalRefFile);
62079c6d946SJung-uk Kim }
62179c6d946SJung-uk Kim 
62279c6d946SJung-uk Kim 
62379c6d946SJung-uk Kim /*******************************************************************************
62479c6d946SJung-uk Kim  *
625313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddOpToExternalList
62679c6d946SJung-uk Kim  *
627313a0c13SJung-uk Kim  * PARAMETERS:  Op                  - Current parser Op
628313a0c13SJung-uk Kim  *              Path                - Internal (AML) path to the object
62979c6d946SJung-uk Kim  *              Type                - ACPI object type to be added
63079c6d946SJung-uk Kim  *              Value               - Arg count if adding a Method object
631313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
63279c6d946SJung-uk Kim  *
63379c6d946SJung-uk Kim  * RETURN:      None
63479c6d946SJung-uk Kim  *
63579c6d946SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
63679c6d946SJung-uk Kim  *              will in turn be later emitted as an External() declaration
63779c6d946SJung-uk Kim  *              in the disassembled output.
63879c6d946SJung-uk Kim  *
639313a0c13SJung-uk Kim  *              This function handles the most common case where the referenced
640313a0c13SJung-uk Kim  *              name is simply not found in the constructed namespace.
641313a0c13SJung-uk Kim  *
64279c6d946SJung-uk Kim  ******************************************************************************/
64379c6d946SJung-uk Kim 
644313a0c13SJung-uk Kim void
AcpiDmAddOpToExternalList(ACPI_PARSE_OBJECT * Op,char * Path,UINT8 Type,UINT32 Value,UINT16 Flags)645313a0c13SJung-uk Kim AcpiDmAddOpToExternalList (
646313a0c13SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
64779c6d946SJung-uk Kim     char                    *Path,
64879c6d946SJung-uk Kim     UINT8                   Type,
649313a0c13SJung-uk Kim     UINT32                  Value,
650313a0c13SJung-uk Kim     UINT16                  Flags)
65179c6d946SJung-uk Kim {
65279c6d946SJung-uk Kim     char                    *ExternalPath;
653313a0c13SJung-uk Kim     char                    *InternalPath = Path;
654313a0c13SJung-uk Kim     char                    *Temp;
65579c6d946SJung-uk Kim     ACPI_STATUS             Status;
656313a0c13SJung-uk Kim 
657313a0c13SJung-uk Kim 
658313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
65979c6d946SJung-uk Kim 
66079c6d946SJung-uk Kim 
66179c6d946SJung-uk Kim     if (!Path)
66279c6d946SJung-uk Kim     {
663313a0c13SJung-uk Kim         return_VOID;
66479c6d946SJung-uk Kim     }
66579c6d946SJung-uk Kim 
666313a0c13SJung-uk Kim     /* Remove a root backslash if present */
66779c6d946SJung-uk Kim 
668313a0c13SJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
66979c6d946SJung-uk Kim     {
670313a0c13SJung-uk Kim         Path++;
67179c6d946SJung-uk Kim     }
672313a0c13SJung-uk Kim 
673313a0c13SJung-uk Kim     /* Externalize the pathname */
674313a0c13SJung-uk Kim 
675313a0c13SJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
676313a0c13SJung-uk Kim         NULL, &ExternalPath);
677313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
678313a0c13SJung-uk Kim     {
679313a0c13SJung-uk Kim         return_VOID;
68079c6d946SJung-uk Kim     }
68179c6d946SJung-uk Kim 
68279c6d946SJung-uk Kim     /*
683313a0c13SJung-uk Kim      * Get the full pathname from the root if "Path" has one or more
684313a0c13SJung-uk Kim      * parent prefixes (^). Note: path will not contain a leading '\'.
685313a0c13SJung-uk Kim      */
686313a0c13SJung-uk Kim     if (*Path == (UINT8) AML_PARENT_PREFIX)
687313a0c13SJung-uk Kim     {
688313a0c13SJung-uk Kim         Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
689313a0c13SJung-uk Kim 
690313a0c13SJung-uk Kim         /* Set new external path */
691313a0c13SJung-uk Kim 
692313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
693313a0c13SJung-uk Kim         ExternalPath = Temp;
694313a0c13SJung-uk Kim         if (!Temp)
695313a0c13SJung-uk Kim         {
696313a0c13SJung-uk Kim             return_VOID;
697313a0c13SJung-uk Kim         }
698313a0c13SJung-uk Kim 
699313a0c13SJung-uk Kim         /* Create the new internal pathname */
700313a0c13SJung-uk Kim 
701313a0c13SJung-uk Kim         Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
702313a0c13SJung-uk Kim         Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
703313a0c13SJung-uk Kim         if (ACPI_FAILURE (Status))
704313a0c13SJung-uk Kim         {
705313a0c13SJung-uk Kim             ACPI_FREE (ExternalPath);
706313a0c13SJung-uk Kim             return_VOID;
707313a0c13SJung-uk Kim         }
708313a0c13SJung-uk Kim     }
709313a0c13SJung-uk Kim 
710313a0c13SJung-uk Kim     /* Create the new External() declaration node */
711313a0c13SJung-uk Kim 
712313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
713313a0c13SJung-uk Kim         Type, Value, Flags);
714313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
715313a0c13SJung-uk Kim     {
716313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
717313a0c13SJung-uk Kim         if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
718313a0c13SJung-uk Kim         {
719313a0c13SJung-uk Kim             ACPI_FREE (InternalPath);
720313a0c13SJung-uk Kim         }
721313a0c13SJung-uk Kim     }
722313a0c13SJung-uk Kim 
723313a0c13SJung-uk Kim     return_VOID;
724313a0c13SJung-uk Kim }
725313a0c13SJung-uk Kim 
726313a0c13SJung-uk Kim 
727313a0c13SJung-uk Kim /*******************************************************************************
728313a0c13SJung-uk Kim  *
729af051161SJung-uk Kim  * FUNCTION:    AcpiDmGetExternalAndInternalPath
730af051161SJung-uk Kim  *
731af051161SJung-uk Kim  * PARAMETERS:  Node                - Namespace node for object to be added
732af051161SJung-uk Kim  *              ExternalPath        - Will contain the external path of the node
733af051161SJung-uk Kim  *              InternalPath        - Will contain the internal path of the node
734af051161SJung-uk Kim  *
735af051161SJung-uk Kim  * RETURN:      None
736af051161SJung-uk Kim  *
737af051161SJung-uk Kim  * DESCRIPTION: Get the External and Internal path from the given node.
738af051161SJung-uk Kim  *
739af051161SJung-uk Kim  ******************************************************************************/
740af051161SJung-uk Kim 
741af051161SJung-uk Kim static ACPI_STATUS
AcpiDmGetExternalAndInternalPath(ACPI_NAMESPACE_NODE * Node,char ** ExternalPath,char ** InternalPath)742af051161SJung-uk Kim AcpiDmGetExternalAndInternalPath (
743af051161SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node,
744af051161SJung-uk Kim     char                    **ExternalPath,
745af051161SJung-uk Kim     char                    **InternalPath)
746af051161SJung-uk Kim {
747af051161SJung-uk Kim     ACPI_STATUS             Status;
748af051161SJung-uk Kim 
749af051161SJung-uk Kim 
750af051161SJung-uk Kim     if (!Node)
751af051161SJung-uk Kim     {
752af051161SJung-uk Kim         return (AE_BAD_PARAMETER);
753af051161SJung-uk Kim     }
754af051161SJung-uk Kim 
755af051161SJung-uk Kim     /* Get the full external and internal pathnames to the node */
756af051161SJung-uk Kim 
757af051161SJung-uk Kim     *ExternalPath = AcpiNsGetExternalPathname (Node);
758af051161SJung-uk Kim     if (!*ExternalPath)
759af051161SJung-uk Kim     {
760af051161SJung-uk Kim         return (AE_BAD_PATHNAME);
761af051161SJung-uk Kim     }
762af051161SJung-uk Kim 
763af051161SJung-uk Kim     Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);
764af051161SJung-uk Kim     if (ACPI_FAILURE (Status))
765af051161SJung-uk Kim     {
766af051161SJung-uk Kim         ACPI_FREE (*ExternalPath);
767af051161SJung-uk Kim         return (Status);
768af051161SJung-uk Kim     }
769af051161SJung-uk Kim 
770af051161SJung-uk Kim     return (AE_OK);
771af051161SJung-uk Kim }
772af051161SJung-uk Kim 
773af051161SJung-uk Kim 
774af051161SJung-uk Kim /*******************************************************************************
775af051161SJung-uk Kim  *
776af051161SJung-uk Kim  * FUNCTION:    AcpiDmRemoveRootPrefix
777af051161SJung-uk Kim  *
778af051161SJung-uk Kim  * PARAMETERS:  Path                - Remove Root prefix from this Path
779af051161SJung-uk Kim  *
780af051161SJung-uk Kim  * RETURN:      None
781af051161SJung-uk Kim  *
782af051161SJung-uk Kim  * DESCRIPTION: Remove the root prefix character '\' from Path.
783af051161SJung-uk Kim  *
784af051161SJung-uk Kim  ******************************************************************************/
785af051161SJung-uk Kim 
786af051161SJung-uk Kim static ACPI_STATUS
AcpiDmRemoveRootPrefix(char ** Path)787af051161SJung-uk Kim AcpiDmRemoveRootPrefix (
788af051161SJung-uk Kim     char                    **Path)
789af051161SJung-uk Kim {
790af051161SJung-uk Kim     char                    *InputPath = *Path;
791af051161SJung-uk Kim 
792af051161SJung-uk Kim 
793af051161SJung-uk Kim     if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))
794af051161SJung-uk Kim     {
795af051161SJung-uk Kim         if (!memmove(InputPath, InputPath+1, strlen(InputPath)))
796af051161SJung-uk Kim         {
797af051161SJung-uk Kim             return (AE_ERROR);
798af051161SJung-uk Kim         }
799af051161SJung-uk Kim 
800af051161SJung-uk Kim         *Path = InputPath;
801af051161SJung-uk Kim     }
802af051161SJung-uk Kim 
803af051161SJung-uk Kim     return (AE_OK);
804af051161SJung-uk Kim }
805af051161SJung-uk Kim 
806af051161SJung-uk Kim 
807af051161SJung-uk Kim /*******************************************************************************
808af051161SJung-uk Kim  *
809313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddNodeToExternalList
810313a0c13SJung-uk Kim  *
811313a0c13SJung-uk Kim  * PARAMETERS:  Node                - Namespace node for object to be added
812313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
813313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
814313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
815313a0c13SJung-uk Kim  *
816313a0c13SJung-uk Kim  * RETURN:      None
817313a0c13SJung-uk Kim  *
818313a0c13SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
819313a0c13SJung-uk Kim  *              will in turn be later emitted as an External() declaration
820313a0c13SJung-uk Kim  *              in the disassembled output.
821313a0c13SJung-uk Kim  *
822313a0c13SJung-uk Kim  *              This function handles the case where the referenced name has
823313a0c13SJung-uk Kim  *              been found in the namespace, but the name originated in a
824313a0c13SJung-uk Kim  *              table other than the one that is being disassembled (such
825313a0c13SJung-uk Kim  *              as a table that is added via the iASL -e option).
826313a0c13SJung-uk Kim  *
827313a0c13SJung-uk Kim  ******************************************************************************/
828313a0c13SJung-uk Kim 
829313a0c13SJung-uk Kim void
AcpiDmAddNodeToExternalList(ACPI_NAMESPACE_NODE * Node,UINT8 Type,UINT32 Value,UINT16 Flags)830313a0c13SJung-uk Kim AcpiDmAddNodeToExternalList (
831313a0c13SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node,
832313a0c13SJung-uk Kim     UINT8                   Type,
833313a0c13SJung-uk Kim     UINT32                  Value,
834313a0c13SJung-uk Kim     UINT16                  Flags)
835313a0c13SJung-uk Kim {
836313a0c13SJung-uk Kim     char                    *ExternalPath;
837313a0c13SJung-uk Kim     char                    *InternalPath;
838313a0c13SJung-uk Kim     ACPI_STATUS             Status;
839313a0c13SJung-uk Kim 
840313a0c13SJung-uk Kim 
841313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
842313a0c13SJung-uk Kim 
843313a0c13SJung-uk Kim     /* Get the full external and internal pathnames to the node */
844313a0c13SJung-uk Kim 
845af051161SJung-uk Kim     Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);
846313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
847313a0c13SJung-uk Kim     {
848313a0c13SJung-uk Kim         return_VOID;
849313a0c13SJung-uk Kim     }
850313a0c13SJung-uk Kim 
851313a0c13SJung-uk Kim     /* Remove the root backslash */
852313a0c13SJung-uk Kim 
853af051161SJung-uk Kim     Status = AcpiDmRemoveRootPrefix (&ExternalPath);
854af051161SJung-uk Kim     if (ACPI_FAILURE (Status))
855313a0c13SJung-uk Kim     {
856313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
857af051161SJung-uk Kim         ACPI_FREE (InternalPath);
858af051161SJung-uk Kim         return_VOID;
859313a0c13SJung-uk Kim     }
860313a0c13SJung-uk Kim 
861313a0c13SJung-uk Kim     /* Create the new External() declaration node */
862313a0c13SJung-uk Kim 
863313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
864313a0c13SJung-uk Kim         Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
865313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
866313a0c13SJung-uk Kim     {
867313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
868313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
869313a0c13SJung-uk Kim     }
870313a0c13SJung-uk Kim 
871313a0c13SJung-uk Kim     return_VOID;
872313a0c13SJung-uk Kim }
873313a0c13SJung-uk Kim 
874313a0c13SJung-uk Kim 
875313a0c13SJung-uk Kim /*******************************************************************************
876313a0c13SJung-uk Kim  *
877313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmAddPathToExternalList
878313a0c13SJung-uk Kim  *
879313a0c13SJung-uk Kim  * PARAMETERS:  Path                - External name of the object to be added
880313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
881313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
882313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
883313a0c13SJung-uk Kim  *
884313a0c13SJung-uk Kim  * RETURN:      None
885313a0c13SJung-uk Kim  *
886313a0c13SJung-uk Kim  * DESCRIPTION: Insert a new name into the global list of Externals which
887313a0c13SJung-uk Kim  *              will in turn be later emitted as an External() declaration
888313a0c13SJung-uk Kim  *              in the disassembled output.
889313a0c13SJung-uk Kim  *
890313a0c13SJung-uk Kim  *              This function currently is used to add externals via a
891313a0c13SJung-uk Kim  *              reference file (via the -fe iASL option).
892313a0c13SJung-uk Kim  *
893313a0c13SJung-uk Kim  ******************************************************************************/
894313a0c13SJung-uk Kim 
895313a0c13SJung-uk Kim static void
AcpiDmAddPathToExternalList(char * Path,UINT8 Type,UINT32 Value,UINT16 Flags)896313a0c13SJung-uk Kim AcpiDmAddPathToExternalList (
897313a0c13SJung-uk Kim     char                    *Path,
898313a0c13SJung-uk Kim     UINT8                   Type,
899313a0c13SJung-uk Kim     UINT32                  Value,
900313a0c13SJung-uk Kim     UINT16                  Flags)
901313a0c13SJung-uk Kim {
902313a0c13SJung-uk Kim     char                    *InternalPath;
903313a0c13SJung-uk Kim     char                    *ExternalPath;
904313a0c13SJung-uk Kim     ACPI_STATUS             Status;
905313a0c13SJung-uk Kim 
906313a0c13SJung-uk Kim 
907313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
908313a0c13SJung-uk Kim 
909313a0c13SJung-uk Kim 
910313a0c13SJung-uk Kim     if (!Path)
911313a0c13SJung-uk Kim     {
912313a0c13SJung-uk Kim         return_VOID;
913313a0c13SJung-uk Kim     }
914313a0c13SJung-uk Kim 
915313a0c13SJung-uk Kim     /* Remove a root backslash if present */
916313a0c13SJung-uk Kim 
917313a0c13SJung-uk Kim     if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
918313a0c13SJung-uk Kim     {
919313a0c13SJung-uk Kim         Path++;
920313a0c13SJung-uk Kim     }
921313a0c13SJung-uk Kim 
922313a0c13SJung-uk Kim     /* Create the internal and external pathnames */
923313a0c13SJung-uk Kim 
924313a0c13SJung-uk Kim     Status = AcpiNsInternalizeName (Path, &InternalPath);
925313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
926313a0c13SJung-uk Kim     {
927313a0c13SJung-uk Kim         return_VOID;
928313a0c13SJung-uk Kim     }
929313a0c13SJung-uk Kim 
930313a0c13SJung-uk Kim     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
931313a0c13SJung-uk Kim         NULL, &ExternalPath);
932313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
933313a0c13SJung-uk Kim     {
934313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
935313a0c13SJung-uk Kim         return_VOID;
936313a0c13SJung-uk Kim     }
937313a0c13SJung-uk Kim 
938313a0c13SJung-uk Kim     /* Create the new External() declaration node */
939313a0c13SJung-uk Kim 
940313a0c13SJung-uk Kim     Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
941313a0c13SJung-uk Kim         Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
942313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
943313a0c13SJung-uk Kim     {
944313a0c13SJung-uk Kim         ACPI_FREE (ExternalPath);
945313a0c13SJung-uk Kim         ACPI_FREE (InternalPath);
946313a0c13SJung-uk Kim     }
947313a0c13SJung-uk Kim 
948313a0c13SJung-uk Kim     return_VOID;
949313a0c13SJung-uk Kim }
950313a0c13SJung-uk Kim 
951313a0c13SJung-uk Kim 
952313a0c13SJung-uk Kim /*******************************************************************************
953313a0c13SJung-uk Kim  *
954313a0c13SJung-uk Kim  * FUNCTION:    AcpiDmCreateNewExternal
955313a0c13SJung-uk Kim  *
956313a0c13SJung-uk Kim  * PARAMETERS:  ExternalPath        - External path to the object
957313a0c13SJung-uk Kim  *              InternalPath        - Internal (AML) path to the object
958313a0c13SJung-uk Kim  *              Type                - ACPI object type to be added
959313a0c13SJung-uk Kim  *              Value               - Arg count if adding a Method object
960313a0c13SJung-uk Kim  *              Flags               - To be passed to the external object
961313a0c13SJung-uk Kim  *
962313a0c13SJung-uk Kim  * RETURN:      Status
963313a0c13SJung-uk Kim  *
964313a0c13SJung-uk Kim  * DESCRIPTION: Common low-level function to insert a new name into the global
965313a0c13SJung-uk Kim  *              list of Externals which will in turn be later emitted as
966313a0c13SJung-uk Kim  *              External() declarations in the disassembled output.
967313a0c13SJung-uk Kim  *
968313a0c13SJung-uk Kim  *              Note: The external name should not include a root prefix
969313a0c13SJung-uk Kim  *              (backslash). We do not want External() statements to contain
970313a0c13SJung-uk Kim  *              a leading '\', as this prevents duplicate external statements
971313a0c13SJung-uk Kim  *              of the form:
97279c6d946SJung-uk Kim  *
97379c6d946SJung-uk Kim  *                  External (\ABCD)
97479c6d946SJung-uk Kim  *                  External (ABCD)
97579c6d946SJung-uk Kim  *
97679c6d946SJung-uk Kim  *              This would cause a compile time error when the disassembled
97779c6d946SJung-uk Kim  *              output file is recompiled.
978313a0c13SJung-uk Kim  *
979313a0c13SJung-uk Kim  *              There are two cases that are handled here. For both, we emit
980313a0c13SJung-uk Kim  *              an External() statement:
981313a0c13SJung-uk Kim  *              1) The name was simply not found in the namespace.
982313a0c13SJung-uk Kim  *              2) The name was found, but it originated in a table other than
983313a0c13SJung-uk Kim  *              the table that is being disassembled.
984313a0c13SJung-uk Kim  *
985313a0c13SJung-uk Kim  ******************************************************************************/
986313a0c13SJung-uk Kim 
987313a0c13SJung-uk Kim static ACPI_STATUS
AcpiDmCreateNewExternal(char * ExternalPath,char * InternalPath,UINT8 Type,UINT32 Value,UINT16 Flags)988313a0c13SJung-uk Kim AcpiDmCreateNewExternal (
989313a0c13SJung-uk Kim     char                    *ExternalPath,
990313a0c13SJung-uk Kim     char                    *InternalPath,
991313a0c13SJung-uk Kim     UINT8                   Type,
992313a0c13SJung-uk Kim     UINT32                  Value,
993313a0c13SJung-uk Kim     UINT16                  Flags)
99479c6d946SJung-uk Kim {
995313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *NewExternal;
996313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
997313a0c13SJung-uk Kim     ACPI_EXTERNAL_LIST      *PrevExternal = NULL;
998313a0c13SJung-uk Kim 
999313a0c13SJung-uk Kim 
1000313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (DmCreateNewExternal);
1001313a0c13SJung-uk Kim 
100279c6d946SJung-uk Kim 
100379c6d946SJung-uk Kim     /* Check all existing externals to ensure no duplicates */
100479c6d946SJung-uk Kim 
100579c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
100679c6d946SJung-uk Kim     while (NextExternal)
100779c6d946SJung-uk Kim     {
1008f8146b88SJung-uk Kim         /* Check for duplicates */
1009f8146b88SJung-uk Kim 
10105ef50723SJung-uk Kim         if (!strcmp (ExternalPath, NextExternal->Path))
101179c6d946SJung-uk Kim         {
1012f8146b88SJung-uk Kim             /*
1013f8146b88SJung-uk Kim              * If this external came from an External() opcode, we are
1014f8146b88SJung-uk Kim              * finished with this one. (No need to check any further).
1015f8146b88SJung-uk Kim              */
1016f8146b88SJung-uk Kim             if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
101779c6d946SJung-uk Kim             {
1018f8146b88SJung-uk Kim                 return_ACPI_STATUS (AE_ALREADY_EXISTS);
101979c6d946SJung-uk Kim             }
102079c6d946SJung-uk Kim 
102179c6d946SJung-uk Kim             /* Allow upgrade of type from ANY */
102279c6d946SJung-uk Kim 
1023f8146b88SJung-uk Kim             else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
1024f8146b88SJung-uk Kim                 (Type != ACPI_TYPE_ANY))
102579c6d946SJung-uk Kim             {
102679c6d946SJung-uk Kim                 NextExternal->Type = Type;
1027f8146b88SJung-uk Kim             }
1028f8146b88SJung-uk Kim 
1029f8146b88SJung-uk Kim             /* Update the argument count as necessary */
1030f8146b88SJung-uk Kim 
1031f8146b88SJung-uk Kim             if (Value < NextExternal->Value)
1032f8146b88SJung-uk Kim             {
103379c6d946SJung-uk Kim                 NextExternal->Value = Value;
103479c6d946SJung-uk Kim             }
103579c6d946SJung-uk Kim 
1036f8146b88SJung-uk Kim             /* Update flags. */
1037f8146b88SJung-uk Kim 
1038f8146b88SJung-uk Kim             NextExternal->Flags |= Flags;
1039f8146b88SJung-uk Kim             NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
1040f8146b88SJung-uk Kim 
1041313a0c13SJung-uk Kim             return_ACPI_STATUS (AE_ALREADY_EXISTS);
104279c6d946SJung-uk Kim         }
104379c6d946SJung-uk Kim 
104479c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
104579c6d946SJung-uk Kim     }
104679c6d946SJung-uk Kim 
104779c6d946SJung-uk Kim     /* Allocate and init a new External() descriptor */
104879c6d946SJung-uk Kim 
104979c6d946SJung-uk Kim     NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
105079c6d946SJung-uk Kim     if (!NewExternal)
105179c6d946SJung-uk Kim     {
1052313a0c13SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
105379c6d946SJung-uk Kim     }
105479c6d946SJung-uk Kim 
1055313a0c13SJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
1056313a0c13SJung-uk Kim         "Adding external reference node (%s) type [%s]\n",
1057313a0c13SJung-uk Kim         ExternalPath, AcpiUtGetTypeName (Type)));
105879c6d946SJung-uk Kim 
1059313a0c13SJung-uk Kim     NewExternal->Flags = Flags;
1060313a0c13SJung-uk Kim     NewExternal->Value = Value;
106179c6d946SJung-uk Kim     NewExternal->Path = ExternalPath;
106279c6d946SJung-uk Kim     NewExternal->Type = Type;
10635ef50723SJung-uk Kim     NewExternal->Length = (UINT16) strlen (ExternalPath);
106479c6d946SJung-uk Kim     NewExternal->InternalPath = InternalPath;
106579c6d946SJung-uk Kim 
106679c6d946SJung-uk Kim     /* Link the new descriptor into the global list, alphabetically ordered */
106779c6d946SJung-uk Kim 
106879c6d946SJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
106979c6d946SJung-uk Kim     while (NextExternal)
107079c6d946SJung-uk Kim     {
107179c6d946SJung-uk Kim         if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
107279c6d946SJung-uk Kim         {
107379c6d946SJung-uk Kim             if (PrevExternal)
107479c6d946SJung-uk Kim             {
107579c6d946SJung-uk Kim                 PrevExternal->Next = NewExternal;
107679c6d946SJung-uk Kim             }
107779c6d946SJung-uk Kim             else
107879c6d946SJung-uk Kim             {
107979c6d946SJung-uk Kim                 AcpiGbl_ExternalList = NewExternal;
108079c6d946SJung-uk Kim             }
108179c6d946SJung-uk Kim 
108279c6d946SJung-uk Kim             NewExternal->Next = NextExternal;
1083313a0c13SJung-uk Kim             return_ACPI_STATUS (AE_OK);
108479c6d946SJung-uk Kim         }
108579c6d946SJung-uk Kim 
108679c6d946SJung-uk Kim         PrevExternal = NextExternal;
108779c6d946SJung-uk Kim         NextExternal = NextExternal->Next;
108879c6d946SJung-uk Kim     }
108979c6d946SJung-uk Kim 
109079c6d946SJung-uk Kim     if (PrevExternal)
109179c6d946SJung-uk Kim     {
109279c6d946SJung-uk Kim         PrevExternal->Next = NewExternal;
109379c6d946SJung-uk Kim     }
109479c6d946SJung-uk Kim     else
109579c6d946SJung-uk Kim     {
109679c6d946SJung-uk Kim         AcpiGbl_ExternalList = NewExternal;
109779c6d946SJung-uk Kim     }
1098313a0c13SJung-uk Kim 
1099313a0c13SJung-uk Kim     return_ACPI_STATUS (AE_OK);
110079c6d946SJung-uk Kim }
110179c6d946SJung-uk Kim 
110279c6d946SJung-uk Kim 
110379c6d946SJung-uk Kim /*******************************************************************************
110479c6d946SJung-uk Kim  *
1105af051161SJung-uk Kim  * FUNCTION:    AcpiDmResolveExternal
1106f556842eSJung-uk Kim  *
1107af051161SJung-uk Kim  * PARAMETERS:  Path               - Path of the external
1108af051161SJung-uk Kim  *              Type               - Type of the external
1109af051161SJung-uk Kim  *              Node               - Input node for AcpiNsLookup
1110af051161SJung-uk Kim  *
1111af051161SJung-uk Kim  * RETURN:      Status
1112af051161SJung-uk Kim  *
1113af051161SJung-uk Kim  * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.
1114af051161SJung-uk Kim  *              If the returned node is an external and has the same type
1115af051161SJung-uk Kim  *              we assume that it was either an existing external or a
1116af051161SJung-uk Kim  *
1117af051161SJung-uk Kim  ******************************************************************************/
1118af051161SJung-uk Kim 
1119af051161SJung-uk Kim static ACPI_STATUS
AcpiDmResolveExternal(char * Path,UINT8 Type,ACPI_NAMESPACE_NODE ** Node)1120af051161SJung-uk Kim AcpiDmResolveExternal (
1121af051161SJung-uk Kim     char                    *Path,
1122af051161SJung-uk Kim     UINT8                   Type,
1123af051161SJung-uk Kim     ACPI_NAMESPACE_NODE     **Node)
1124af051161SJung-uk Kim {
1125af051161SJung-uk Kim     ACPI_STATUS             Status;
1126af051161SJung-uk Kim 
1127af051161SJung-uk Kim 
1128af051161SJung-uk Kim     Status = AcpiNsLookup (NULL, Path, Type,
1129af051161SJung-uk Kim         ACPI_IMODE_LOAD_PASS1,
1130af051161SJung-uk Kim         ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
1131af051161SJung-uk Kim         NULL, Node);
1132af051161SJung-uk Kim 
1133af051161SJung-uk Kim     if (!Node)
1134af051161SJung-uk Kim     {
1135af051161SJung-uk Kim         ACPI_EXCEPTION ((AE_INFO, Status,
1136af051161SJung-uk Kim             "while adding external to namespace [%s]", Path));
1137af051161SJung-uk Kim     }
1138af051161SJung-uk Kim 
1139af051161SJung-uk Kim     /* Note the asl code "external(a) external(a)" is acceptable ASL */
1140af051161SJung-uk Kim 
1141af051161SJung-uk Kim     else if ((*Node)->Type == Type &&
1142af051161SJung-uk Kim         (*Node)->Flags & ANOBJ_IS_EXTERNAL)
1143af051161SJung-uk Kim     {
1144af051161SJung-uk Kim         return (AE_OK);
1145af051161SJung-uk Kim     }
1146af051161SJung-uk Kim     else
1147af051161SJung-uk Kim     {
1148af051161SJung-uk Kim         ACPI_EXCEPTION ((AE_INFO, AE_ERROR,
1149af051161SJung-uk Kim             "[%s] has conflicting declarations", Path));
1150af051161SJung-uk Kim     }
1151af051161SJung-uk Kim 
1152af051161SJung-uk Kim     return (AE_ERROR);
1153af051161SJung-uk Kim }
1154af051161SJung-uk Kim 
1155af051161SJung-uk Kim 
1156af051161SJung-uk Kim /*******************************************************************************
1157af051161SJung-uk Kim  *
1158af051161SJung-uk Kim  * FUNCTION:    AcpiDmCreateSubobjectForExternal
1159af051161SJung-uk Kim  *
1160af051161SJung-uk Kim  * PARAMETERS:  Type                  - Type of the external
1161af051161SJung-uk Kim  *              Node                  - Namespace node from AcpiNsLookup
1162af051161SJung-uk Kim  *              ParamCount            - Value to be used for Method
1163f556842eSJung-uk Kim  *
1164f556842eSJung-uk Kim  * RETURN:      None
1165f556842eSJung-uk Kim  *
1166af051161SJung-uk Kim  * DESCRIPTION: Add one external to the namespace. Allows external to be
1167f556842eSJung-uk Kim  *              "resolved".
1168f556842eSJung-uk Kim  *
1169f556842eSJung-uk Kim  ******************************************************************************/
1170f556842eSJung-uk Kim 
1171f556842eSJung-uk Kim void
AcpiDmCreateSubobjectForExternal(UINT8 Type,ACPI_NAMESPACE_NODE ** Node,UINT32 ParamCount)1172af051161SJung-uk Kim AcpiDmCreateSubobjectForExternal (
1173af051161SJung-uk Kim     UINT8                   Type,
1174af051161SJung-uk Kim     ACPI_NAMESPACE_NODE     **Node,
1175af051161SJung-uk Kim     UINT32                  ParamCount)
1176f556842eSJung-uk Kim {
1177a7a3b383SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
1178f556842eSJung-uk Kim 
1179f556842eSJung-uk Kim 
1180af051161SJung-uk Kim     switch (Type)
1181f556842eSJung-uk Kim     {
1182a7a3b383SJung-uk Kim     case ACPI_TYPE_METHOD:
1183a7a3b383SJung-uk Kim 
1184f556842eSJung-uk Kim         /* For methods, we need to save the argument count */
1185f556842eSJung-uk Kim 
1186a7a3b383SJung-uk Kim         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
1187af051161SJung-uk Kim         ObjDesc->Method.ParamCount = (UINT8) ParamCount;
1188af051161SJung-uk Kim         (*Node)->Object = ObjDesc;
1189a7a3b383SJung-uk Kim         break;
1190a7a3b383SJung-uk Kim 
1191a7a3b383SJung-uk Kim     case ACPI_TYPE_REGION:
1192a7a3b383SJung-uk Kim 
1193a7a3b383SJung-uk Kim         /* Regions require a region sub-object */
1194a7a3b383SJung-uk Kim 
1195a7a3b383SJung-uk Kim         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
1196af051161SJung-uk Kim         ObjDesc->Region.Node = *Node;
1197af051161SJung-uk Kim         (*Node)->Object = ObjDesc;
1198a7a3b383SJung-uk Kim         break;
1199a7a3b383SJung-uk Kim 
1200a7a3b383SJung-uk Kim     default:
1201a9d8d09cSJung-uk Kim 
1202a7a3b383SJung-uk Kim         break;
1203f556842eSJung-uk Kim     }
1204af051161SJung-uk Kim }
1205f556842eSJung-uk Kim 
1206af051161SJung-uk Kim 
1207af051161SJung-uk Kim /*******************************************************************************
1208af051161SJung-uk Kim  *
1209af051161SJung-uk Kim  * FUNCTION:    AcpiDmAddOneExternalToNamespace
1210af051161SJung-uk Kim  *
1211af051161SJung-uk Kim  * PARAMETERS:  Path                   - External parse object
1212af051161SJung-uk Kim  *              Type                   - Type of parse object
1213af051161SJung-uk Kim  *              ParamCount             - External method parameter count
1214af051161SJung-uk Kim  *
1215af051161SJung-uk Kim  * RETURN:      None
1216af051161SJung-uk Kim  *
1217af051161SJung-uk Kim  * DESCRIPTION: Add one external to the namespace by resolvign the external
1218af051161SJung-uk Kim  *              (by performing a namespace lookup) and annotating the resulting
1219cd6518c7SJung-uk Kim  *              namespace node with the appropriate information if the type
1220af051161SJung-uk Kim  *              is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
1221af051161SJung-uk Kim  *
1222af051161SJung-uk Kim  ******************************************************************************/
1223af051161SJung-uk Kim 
1224af051161SJung-uk Kim void
AcpiDmAddOneExternalToNamespace(char * Path,UINT8 Type,UINT32 ParamCount)1225af051161SJung-uk Kim AcpiDmAddOneExternalToNamespace (
1226af051161SJung-uk Kim     char                    *Path,
1227af051161SJung-uk Kim     UINT8                   Type,
1228af051161SJung-uk Kim     UINT32                  ParamCount)
1229af051161SJung-uk Kim {
1230af051161SJung-uk Kim     ACPI_STATUS             Status;
1231af051161SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
1232af051161SJung-uk Kim 
1233af051161SJung-uk Kim 
1234af051161SJung-uk Kim     Status = AcpiDmResolveExternal (Path, Type, &Node);
1235af051161SJung-uk Kim 
1236af051161SJung-uk Kim     if (ACPI_FAILURE (Status))
1237af051161SJung-uk Kim     {
1238af051161SJung-uk Kim         return;
1239af051161SJung-uk Kim     }
1240af051161SJung-uk Kim 
1241af051161SJung-uk Kim     AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);
1242af051161SJung-uk Kim 
1243af051161SJung-uk Kim }
1244af051161SJung-uk Kim 
1245af051161SJung-uk Kim 
1246af051161SJung-uk Kim /*******************************************************************************
1247af051161SJung-uk Kim  *
1248af051161SJung-uk Kim  * FUNCTION:    AcpiDmAddExternalListToNamespace
1249af051161SJung-uk Kim  *
1250af051161SJung-uk Kim  * PARAMETERS:  None
1251af051161SJung-uk Kim  *
1252af051161SJung-uk Kim  * RETURN:      None
1253af051161SJung-uk Kim  *
1254af051161SJung-uk Kim  * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.
1255af051161SJung-uk Kim  *              Allows externals to be "resolved".
1256af051161SJung-uk Kim  *
1257af051161SJung-uk Kim  ******************************************************************************/
1258af051161SJung-uk Kim 
1259af051161SJung-uk Kim void
AcpiDmAddExternalListToNamespace(void)1260af051161SJung-uk Kim AcpiDmAddExternalListToNamespace (
1261af051161SJung-uk Kim     void)
1262af051161SJung-uk Kim {
1263af051161SJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
1264af051161SJung-uk Kim 
1265af051161SJung-uk Kim 
1266af051161SJung-uk Kim     while (External)
1267af051161SJung-uk Kim     {
1268af051161SJung-uk Kim         AcpiDmAddOneExternalToNamespace (External->InternalPath,
1269af051161SJung-uk Kim             External->Type, External->Value);
1270f556842eSJung-uk Kim         External = External->Next;
1271f556842eSJung-uk Kim     }
1272f556842eSJung-uk Kim }
1273f556842eSJung-uk Kim 
1274f556842eSJung-uk Kim 
1275f556842eSJung-uk Kim /*******************************************************************************
1276f556842eSJung-uk Kim  *
1277af051161SJung-uk Kim  * FUNCTION:    AcpiDmGetUnresolvedExternalMethodCount
1278f556842eSJung-uk Kim  *
1279f556842eSJung-uk Kim  * PARAMETERS:  None
1280f556842eSJung-uk Kim  *
1281af051161SJung-uk Kim  * RETURN:      The number of unresolved control method externals in the
1282af051161SJung-uk Kim  *              external list
1283f556842eSJung-uk Kim  *
1284af051161SJung-uk Kim  * DESCRIPTION: Return the number of unresolved external methods that have been
1285af051161SJung-uk Kim  *              generated. If any unresolved control method externals have been
1286af051161SJung-uk Kim  *              found, we must re-parse the entire definition block with the new
1287af051161SJung-uk Kim  *              information (number of arguments for the methods.)
1288af051161SJung-uk Kim  *              This is limitation of AML, we don't know the number of arguments
1289af051161SJung-uk Kim  *              from the control method invocation itself.
1290af051161SJung-uk Kim  *
1291af051161SJung-uk Kim  *              Note: resolved external control methods are external control
1292af051161SJung-uk Kim  *              methods encoded with the AML_EXTERNAL_OP bytecode within the
1293af051161SJung-uk Kim  *              AML being disassembled.
1294f556842eSJung-uk Kim  *
1295f556842eSJung-uk Kim  ******************************************************************************/
1296f556842eSJung-uk Kim 
1297f556842eSJung-uk Kim UINT32
AcpiDmGetUnresolvedExternalMethodCount(void)1298af051161SJung-uk Kim AcpiDmGetUnresolvedExternalMethodCount (
1299f556842eSJung-uk Kim     void)
1300f556842eSJung-uk Kim {
1301f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *External = AcpiGbl_ExternalList;
1302f556842eSJung-uk Kim     UINT32                  Count = 0;
1303f556842eSJung-uk Kim 
1304f556842eSJung-uk Kim 
1305f556842eSJung-uk Kim     while (External)
1306f556842eSJung-uk Kim     {
1307af051161SJung-uk Kim         if (External->Type == ACPI_TYPE_METHOD &&
1308af051161SJung-uk Kim             !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))
1309f556842eSJung-uk Kim         {
1310f556842eSJung-uk Kim             Count++;
1311f556842eSJung-uk Kim         }
1312f556842eSJung-uk Kim 
1313f556842eSJung-uk Kim         External = External->Next;
1314f556842eSJung-uk Kim     }
1315f556842eSJung-uk Kim 
1316f556842eSJung-uk Kim     return (Count);
1317f556842eSJung-uk Kim }
1318f556842eSJung-uk Kim 
1319f556842eSJung-uk Kim 
1320f556842eSJung-uk Kim /*******************************************************************************
1321f556842eSJung-uk Kim  *
1322f556842eSJung-uk Kim  * FUNCTION:    AcpiDmClearExternalList
1323f556842eSJung-uk Kim  *
1324f556842eSJung-uk Kim  * PARAMETERS:  None
1325f556842eSJung-uk Kim  *
1326f556842eSJung-uk Kim  * RETURN:      None
1327f556842eSJung-uk Kim  *
1328f556842eSJung-uk Kim  * DESCRIPTION: Free the entire External info list
1329f556842eSJung-uk Kim  *
1330f556842eSJung-uk Kim  ******************************************************************************/
1331f556842eSJung-uk Kim 
1332f556842eSJung-uk Kim void
AcpiDmClearExternalList(void)1333f556842eSJung-uk Kim AcpiDmClearExternalList (
1334f556842eSJung-uk Kim     void)
1335f556842eSJung-uk Kim {
1336f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
1337f556842eSJung-uk Kim 
1338f556842eSJung-uk Kim 
1339f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
1340f556842eSJung-uk Kim     {
1341f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
1342f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
1343f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
1344f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
1345f556842eSJung-uk Kim     }
1346f556842eSJung-uk Kim }
1347f556842eSJung-uk Kim 
1348f556842eSJung-uk Kim 
1349f556842eSJung-uk Kim /*******************************************************************************
1350f556842eSJung-uk Kim  *
1351f556842eSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternals
1352f556842eSJung-uk Kim  *
1353f556842eSJung-uk Kim  * PARAMETERS:  None
1354f556842eSJung-uk Kim  *
1355f556842eSJung-uk Kim  * RETURN:      None
1356f556842eSJung-uk Kim  *
1357f556842eSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1358f556842eSJung-uk Kim  *              the global external info list.
1359f556842eSJung-uk Kim  *
1360f556842eSJung-uk Kim  ******************************************************************************/
1361f556842eSJung-uk Kim 
1362f556842eSJung-uk Kim void
AcpiDmEmitExternals(void)1363f556842eSJung-uk Kim AcpiDmEmitExternals (
1364f556842eSJung-uk Kim     void)
1365f556842eSJung-uk Kim {
1366f556842eSJung-uk Kim     ACPI_EXTERNAL_LIST      *NextExternal;
1367f556842eSJung-uk Kim 
1368f556842eSJung-uk Kim 
1369f556842eSJung-uk Kim     if (!AcpiGbl_ExternalList)
1370f556842eSJung-uk Kim     {
1371f556842eSJung-uk Kim         return;
1372f556842eSJung-uk Kim     }
1373f556842eSJung-uk Kim 
1374f556842eSJung-uk Kim     /*
13759c48c75eSJung-uk Kim      * Determine the number of control methods in the external list, and
13769c48c75eSJung-uk Kim      * also how many of those externals were resolved via the namespace.
13779c48c75eSJung-uk Kim      */
13789c48c75eSJung-uk Kim     NextExternal = AcpiGbl_ExternalList;
13799c48c75eSJung-uk Kim     while (NextExternal)
13809c48c75eSJung-uk Kim     {
13819c48c75eSJung-uk Kim         if (NextExternal->Type == ACPI_TYPE_METHOD)
13829c48c75eSJung-uk Kim         {
13839c48c75eSJung-uk Kim             AcpiGbl_NumExternalMethods++;
1384313a0c13SJung-uk Kim             if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
13859c48c75eSJung-uk Kim             {
13869c48c75eSJung-uk Kim                 AcpiGbl_ResolvedExternalMethods++;
13879c48c75eSJung-uk Kim             }
13889c48c75eSJung-uk Kim         }
13899c48c75eSJung-uk Kim 
13909c48c75eSJung-uk Kim         NextExternal = NextExternal->Next;
13919c48c75eSJung-uk Kim     }
13929c48c75eSJung-uk Kim 
13939c48c75eSJung-uk Kim     /* Check if any control methods were unresolved */
13949c48c75eSJung-uk Kim 
13959c48c75eSJung-uk Kim     AcpiDmUnresolvedWarning (1);
13969c48c75eSJung-uk Kim 
13976f1f1a63SJung-uk Kim     if (AslGbl_ExternalRefFilename)
139879c6d946SJung-uk Kim     {
139979c6d946SJung-uk Kim         AcpiOsPrintf (
1400f8146b88SJung-uk Kim             "    /*\n     * External declarations were imported from\n"
1401f8146b88SJung-uk Kim             "     * a reference file -- %s\n     */\n\n",
14026f1f1a63SJung-uk Kim             AslGbl_ExternalRefFilename);
140379c6d946SJung-uk Kim     }
140479c6d946SJung-uk Kim 
14059c48c75eSJung-uk Kim     /*
1406f8146b88SJung-uk Kim      * Walk and emit the list of externals found during the AML parsing
1407f556842eSJung-uk Kim      */
1408f556842eSJung-uk Kim     while (AcpiGbl_ExternalList)
1409f556842eSJung-uk Kim     {
1410313a0c13SJung-uk Kim         if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
1411bf6fac21SJung-uk Kim         {
1412f8146b88SJung-uk Kim             AcpiOsPrintf ("    External (%s%s)",
1413f556842eSJung-uk Kim                 AcpiGbl_ExternalList->Path,
1414f556842eSJung-uk Kim                 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1415f556842eSJung-uk Kim 
1416f8146b88SJung-uk Kim             /* Check for "unresolved" method reference */
1417f8146b88SJung-uk Kim 
1418f8146b88SJung-uk Kim             if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
1419f8146b88SJung-uk Kim                 (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
1420f8146b88SJung-uk Kim             {
1421f8146b88SJung-uk Kim                 AcpiOsPrintf ("    // Warning: Unknown method, "
1422f8146b88SJung-uk Kim                     "guessing %u arguments",
1423f8146b88SJung-uk Kim                     AcpiGbl_ExternalList->Value);
1424f8146b88SJung-uk Kim             }
1425f8146b88SJung-uk Kim 
1426f8146b88SJung-uk Kim             /* Check for external from a external references file */
1427f8146b88SJung-uk Kim 
1428f8146b88SJung-uk Kim             else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
1429f8146b88SJung-uk Kim             {
1430f8146b88SJung-uk Kim                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1431f8146b88SJung-uk Kim                 {
1432f8146b88SJung-uk Kim                     AcpiOsPrintf ("    // %u Arguments",
1433f8146b88SJung-uk Kim                         AcpiGbl_ExternalList->Value);
1434f8146b88SJung-uk Kim                 }
1435f8146b88SJung-uk Kim 
1436f8146b88SJung-uk Kim                 AcpiOsPrintf ("    // From external reference file");
1437f8146b88SJung-uk Kim             }
1438f8146b88SJung-uk Kim 
1439f8146b88SJung-uk Kim             /* This is the normal external case */
1440f8146b88SJung-uk Kim 
1441f8146b88SJung-uk Kim             else
1442f8146b88SJung-uk Kim             {
1443bf6fac21SJung-uk Kim                 /* For methods, add a comment with the number of arguments */
1444bf6fac21SJung-uk Kim 
1445f556842eSJung-uk Kim                 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1446f556842eSJung-uk Kim                 {
1447f8146b88SJung-uk Kim                     AcpiOsPrintf ("    // %u Arguments",
1448f556842eSJung-uk Kim                         AcpiGbl_ExternalList->Value);
1449f556842eSJung-uk Kim                 }
1450f556842eSJung-uk Kim             }
1451f8146b88SJung-uk Kim 
1452af051161SJung-uk Kim             if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)
1453af051161SJung-uk Kim             {
1454af051161SJung-uk Kim                 AcpiOsPrintf ("%s", ExternalConflictMessage);
1455af051161SJung-uk Kim                 AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);
1456af051161SJung-uk Kim             }
1457f8146b88SJung-uk Kim             AcpiOsPrintf ("\n");
1458bf6fac21SJung-uk Kim         }
1459f556842eSJung-uk Kim 
1460f556842eSJung-uk Kim         /* Free this external info block and move on to next external */
1461f556842eSJung-uk Kim 
1462f556842eSJung-uk Kim         NextExternal = AcpiGbl_ExternalList->Next;
1463313a0c13SJung-uk Kim         if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
1464f556842eSJung-uk Kim         {
1465f556842eSJung-uk Kim             ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1466f556842eSJung-uk Kim         }
1467f556842eSJung-uk Kim 
1468f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList->Path);
1469f556842eSJung-uk Kim         ACPI_FREE (AcpiGbl_ExternalList);
1470f556842eSJung-uk Kim         AcpiGbl_ExternalList = NextExternal;
1471f556842eSJung-uk Kim     }
1472f556842eSJung-uk Kim 
1473f556842eSJung-uk Kim     AcpiOsPrintf ("\n");
1474f556842eSJung-uk Kim }
14759c48c75eSJung-uk Kim 
14769c48c75eSJung-uk Kim 
14779c48c75eSJung-uk Kim /*******************************************************************************
14789c48c75eSJung-uk Kim  *
1479af051161SJung-uk Kim  * FUNCTION:    AcpiDmMarkExternalConflict
1480af051161SJung-uk Kim  *
1481af051161SJung-uk Kim  * PARAMETERS:  Path          - Namepath to search
1482af051161SJung-uk Kim  *
1483af051161SJung-uk Kim  * RETURN:      ExternalList
1484af051161SJung-uk Kim  *
1485af051161SJung-uk Kim  * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path
1486af051161SJung-uk Kim  *
1487af051161SJung-uk Kim  ******************************************************************************/
1488af051161SJung-uk Kim 
1489af051161SJung-uk Kim void
AcpiDmMarkExternalConflict(ACPI_NAMESPACE_NODE * Node)1490af051161SJung-uk Kim AcpiDmMarkExternalConflict (
1491af051161SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node)
1492af051161SJung-uk Kim {
1493af051161SJung-uk Kim     ACPI_EXTERNAL_LIST      *ExternalList = AcpiGbl_ExternalList;
1494af051161SJung-uk Kim     char                    *ExternalPath;
1495af051161SJung-uk Kim     char                    *InternalPath;
1496af051161SJung-uk Kim     ACPI_STATUS             Status;
1497af051161SJung-uk Kim 
1498af051161SJung-uk Kim 
1499af051161SJung-uk Kim     ACPI_FUNCTION_TRACE (DmMarkExternalConflict);
1500af051161SJung-uk Kim 
1501af051161SJung-uk Kim 
1502af051161SJung-uk Kim     if (Node->Flags & ANOBJ_IS_EXTERNAL)
1503af051161SJung-uk Kim     {
1504af051161SJung-uk Kim         return_VOID;
1505af051161SJung-uk Kim     }
1506af051161SJung-uk Kim 
1507af051161SJung-uk Kim     /* Get the full external and internal pathnames to the node */
1508af051161SJung-uk Kim 
1509af051161SJung-uk Kim     Status = AcpiDmGetExternalAndInternalPath (Node,
1510af051161SJung-uk Kim         &ExternalPath, &InternalPath);
1511af051161SJung-uk Kim     if (ACPI_FAILURE (Status))
1512af051161SJung-uk Kim     {
1513af051161SJung-uk Kim         return_VOID;
1514af051161SJung-uk Kim     }
1515af051161SJung-uk Kim 
1516af051161SJung-uk Kim     /* Remove the root backslash */
1517af051161SJung-uk Kim 
1518af051161SJung-uk Kim     Status = AcpiDmRemoveRootPrefix (&InternalPath);
1519af051161SJung-uk Kim     if (ACPI_FAILURE (Status))
1520af051161SJung-uk Kim     {
1521af051161SJung-uk Kim         ACPI_FREE (InternalPath);
1522af051161SJung-uk Kim         ACPI_FREE (ExternalPath);
1523af051161SJung-uk Kim         return_VOID;
1524af051161SJung-uk Kim     }
1525af051161SJung-uk Kim 
1526af051161SJung-uk Kim     while (ExternalList)
1527af051161SJung-uk Kim     {
1528af051161SJung-uk Kim         if (!strcmp (ExternalList->InternalPath, InternalPath))
1529af051161SJung-uk Kim         {
1530af051161SJung-uk Kim             ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;
1531af051161SJung-uk Kim         }
1532af051161SJung-uk Kim         ExternalList = ExternalList->Next;
1533af051161SJung-uk Kim     }
1534af051161SJung-uk Kim 
1535af051161SJung-uk Kim     ACPI_FREE (InternalPath);
1536af051161SJung-uk Kim     ACPI_FREE (ExternalPath);
1537af051161SJung-uk Kim 
1538af051161SJung-uk Kim     return_VOID;
1539af051161SJung-uk Kim }
1540af051161SJung-uk Kim 
1541af051161SJung-uk Kim 
1542af051161SJung-uk Kim /*******************************************************************************
1543af051161SJung-uk Kim  *
1544af051161SJung-uk Kim  * FUNCTION:    AcpiDmConflictingDeclaration
1545af051161SJung-uk Kim  *
1546af051161SJung-uk Kim  * PARAMETERS:  Path                - Path with conflicting declaration
1547af051161SJung-uk Kim  *
1548af051161SJung-uk Kim  * RETURN:      None
1549af051161SJung-uk Kim  *
1550af051161SJung-uk Kim  * DESCRIPTION: Emit a warning when printing conflicting ASL external
1551af051161SJung-uk Kim  *              declarations.
1552af051161SJung-uk Kim  *
1553af051161SJung-uk Kim  ******************************************************************************/
1554af051161SJung-uk Kim 
1555af051161SJung-uk Kim static void
AcpiDmConflictingDeclaration(char * Path)1556af051161SJung-uk Kim AcpiDmConflictingDeclaration (
1557af051161SJung-uk Kim     char                    *Path)
1558af051161SJung-uk Kim {
1559af051161SJung-uk Kim     fprintf (stderr,
1560af051161SJung-uk Kim         " Warning - Emitting ASL code \"External (%s)\"\n"
1561af051161SJung-uk Kim         "           This is a conflicting declaration with some "
1562af051161SJung-uk Kim         "other declaration within the ASL code.\n"
1563af051161SJung-uk Kim         "           This external declaration may need to be "
1564af051161SJung-uk Kim         "deleted in order to recompile the dsl file.\n\n",
1565af051161SJung-uk Kim         Path);
1566af051161SJung-uk Kim }
1567af051161SJung-uk Kim 
1568af051161SJung-uk Kim 
1569af051161SJung-uk Kim /*******************************************************************************
1570af051161SJung-uk Kim  *
15710d84335fSJung-uk Kim  * FUNCTION:    AcpiDmEmitExternal
15720d84335fSJung-uk Kim  *
15730d84335fSJung-uk Kim  * PARAMETERS:  Op                  External Parse Object
15740d84335fSJung-uk Kim  *
15750d84335fSJung-uk Kim  * RETURN:      None
15760d84335fSJung-uk Kim  *
15770d84335fSJung-uk Kim  * DESCRIPTION: Emit an External() ASL statement for the current External
1578af051161SJung-uk Kim  *              parse object. Note: External Ops are named types so the
1579af051161SJung-uk Kim  *              namepath is contained within NameOp->Name.Path.
15800d84335fSJung-uk Kim  *
15810d84335fSJung-uk Kim  ******************************************************************************/
15820d84335fSJung-uk Kim 
15830d84335fSJung-uk Kim void
AcpiDmEmitExternal(ACPI_PARSE_OBJECT * NameOp,ACPI_PARSE_OBJECT * TypeOp)15840d84335fSJung-uk Kim AcpiDmEmitExternal (
15850d84335fSJung-uk Kim     ACPI_PARSE_OBJECT       *NameOp,
15860d84335fSJung-uk Kim     ACPI_PARSE_OBJECT       *TypeOp)
15870d84335fSJung-uk Kim {
15880d84335fSJung-uk Kim     AcpiOsPrintf ("External (");
1589af051161SJung-uk Kim     AcpiDmNamestring (NameOp->Named.Path);
1590af051161SJung-uk Kim     AcpiOsPrintf ("%s)",
15910d84335fSJung-uk Kim         AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
1592af051161SJung-uk Kim     AcpiDmCheckForExternalConflict (NameOp->Named.Path);
1593af051161SJung-uk Kim     AcpiOsPrintf ("\n");
15940d84335fSJung-uk Kim }
15950d84335fSJung-uk Kim 
15960d84335fSJung-uk Kim 
15970d84335fSJung-uk Kim /*******************************************************************************
15980d84335fSJung-uk Kim  *
1599af051161SJung-uk Kim  * FUNCTION:    AcpiDmCheckForExternalConflict
1600af051161SJung-uk Kim  *
1601af051161SJung-uk Kim  * PARAMETERS:  Path                - Path to check
1602af051161SJung-uk Kim  *
1603af051161SJung-uk Kim  * RETURN:      None
1604af051161SJung-uk Kim  *
1605af051161SJung-uk Kim  * DESCRIPTION: Search the External List to see if the input Path has a
1606af051161SJung-uk Kim  *              conflicting declaration.
1607af051161SJung-uk Kim  *
1608af051161SJung-uk Kim  ******************************************************************************/
1609af051161SJung-uk Kim 
1610af051161SJung-uk Kim static void
AcpiDmCheckForExternalConflict(char * Path)1611af051161SJung-uk Kim AcpiDmCheckForExternalConflict (
1612af051161SJung-uk Kim     char                    *Path)
1613af051161SJung-uk Kim {
1614af051161SJung-uk Kim     ACPI_EXTERNAL_LIST      *ExternalList = AcpiGbl_ExternalList;
1615af051161SJung-uk Kim     char                    *ListItemPath;
1616af051161SJung-uk Kim     char                    *InputPath;
1617af051161SJung-uk Kim 
1618af051161SJung-uk Kim 
1619af051161SJung-uk Kim     if (!Path)
1620af051161SJung-uk Kim     {
1621af051161SJung-uk Kim         return;
1622af051161SJung-uk Kim     }
1623af051161SJung-uk Kim 
1624af051161SJung-uk Kim     /* Move past the root prefix '\' */
1625af051161SJung-uk Kim 
1626af051161SJung-uk Kim     InputPath = Path;
1627af051161SJung-uk Kim     if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])
1628af051161SJung-uk Kim     {
1629af051161SJung-uk Kim         InputPath++;
1630af051161SJung-uk Kim     }
1631af051161SJung-uk Kim 
1632af051161SJung-uk Kim     while (ExternalList)
1633af051161SJung-uk Kim     {
1634af051161SJung-uk Kim         ListItemPath = ExternalList->Path;
1635af051161SJung-uk Kim         if (ListItemPath)
1636af051161SJung-uk Kim         {
1637af051161SJung-uk Kim             /* Move past the root prefix '\' */
1638af051161SJung-uk Kim 
1639af051161SJung-uk Kim             if ((*ListItemPath == AML_ROOT_PREFIX) &&
1640af051161SJung-uk Kim                 ListItemPath[1])
1641af051161SJung-uk Kim             {
1642af051161SJung-uk Kim                 ListItemPath++;
1643af051161SJung-uk Kim             }
1644af051161SJung-uk Kim 
1645af051161SJung-uk Kim             if (!strcmp (ListItemPath, InputPath) &&
1646af051161SJung-uk Kim                 (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))
1647af051161SJung-uk Kim             {
1648af051161SJung-uk Kim                 AcpiOsPrintf ("%s", ExternalConflictMessage);
1649af051161SJung-uk Kim                 AcpiDmConflictingDeclaration (Path);
1650af051161SJung-uk Kim 
1651af051161SJung-uk Kim                 return;
1652af051161SJung-uk Kim             }
1653af051161SJung-uk Kim         }
1654af051161SJung-uk Kim         ExternalList = ExternalList->Next;
1655af051161SJung-uk Kim     }
1656af051161SJung-uk Kim }
1657af051161SJung-uk Kim /*******************************************************************************
1658af051161SJung-uk Kim  *
16599c48c75eSJung-uk Kim  * FUNCTION:    AcpiDmUnresolvedWarning
16609c48c75eSJung-uk Kim  *
16619c48c75eSJung-uk Kim  * PARAMETERS:  Type                - Where to output the warning.
16629c48c75eSJung-uk Kim  *                                    0 means write to stderr
16639c48c75eSJung-uk Kim  *                                    1 means write to AcpiOsPrintf
16649c48c75eSJung-uk Kim  *
16659c48c75eSJung-uk Kim  * RETURN:      None
16669c48c75eSJung-uk Kim  *
16679c48c75eSJung-uk Kim  * DESCRIPTION: Issue warning message if there are unresolved external control
16689c48c75eSJung-uk Kim  *              methods within the disassembly.
16699c48c75eSJung-uk Kim  *
16709c48c75eSJung-uk Kim  ******************************************************************************/
16719c48c75eSJung-uk Kim 
1672af051161SJung-uk Kim /*
16739c48c75eSJung-uk Kim Summary of the external control method problem:
16749c48c75eSJung-uk Kim 
16759c48c75eSJung-uk Kim When the -e option is used with disassembly, the various SSDTs are simply
16769c48c75eSJung-uk Kim loaded into a global namespace for the disassembler to use in order to
16779c48c75eSJung-uk Kim resolve control method references (invocations).
16789c48c75eSJung-uk Kim 
16799c48c75eSJung-uk Kim The disassembler tracks any such references, and will emit an External()
16809c48c75eSJung-uk Kim statement for these types of methods, with the proper number of arguments .
16819c48c75eSJung-uk Kim 
16829c48c75eSJung-uk Kim Without the SSDTs, the AML does not contain enough information to properly
16839c48c75eSJung-uk Kim disassemble the control method invocation -- because the disassembler does
16849c48c75eSJung-uk Kim not know how many arguments to parse.
16859c48c75eSJung-uk Kim 
16869c48c75eSJung-uk Kim An example: Assume we have two control methods. ABCD has one argument, and
16879c48c75eSJung-uk Kim EFGH has zero arguments. Further, we have two additional control methods
16889c48c75eSJung-uk Kim that invoke ABCD and EFGH, named T1 and T2:
16899c48c75eSJung-uk Kim 
16909c48c75eSJung-uk Kim     Method (ABCD, 1)
16919c48c75eSJung-uk Kim     {
16929c48c75eSJung-uk Kim     }
16939c48c75eSJung-uk Kim     Method (EFGH, 0)
16949c48c75eSJung-uk Kim     {
16959c48c75eSJung-uk Kim     }
16969c48c75eSJung-uk Kim     Method (T1)
16979c48c75eSJung-uk Kim     {
16989c48c75eSJung-uk Kim         ABCD (Add (2, 7, Local0))
16999c48c75eSJung-uk Kim     }
17009c48c75eSJung-uk Kim     Method (T2)
17019c48c75eSJung-uk Kim     {
17029c48c75eSJung-uk Kim         EFGH ()
17039c48c75eSJung-uk Kim         Add (2, 7, Local0)
17049c48c75eSJung-uk Kim     }
17059c48c75eSJung-uk Kim 
17069c48c75eSJung-uk Kim Here is the AML code that is generated for T1 and T2:
17079c48c75eSJung-uk Kim 
17089c48c75eSJung-uk Kim      185:      Method (T1)
17099c48c75eSJung-uk Kim 
17109c48c75eSJung-uk Kim 0000034C:  14 10 54 31 5F 5F 00 ...    "..T1__."
17119c48c75eSJung-uk Kim 
17129c48c75eSJung-uk Kim      186:      {
17139c48c75eSJung-uk Kim      187:          ABCD (Add (2, 7, Local0))
17149c48c75eSJung-uk Kim 
17159c48c75eSJung-uk Kim 00000353:  41 42 43 44 ............    "ABCD"
17169c48c75eSJung-uk Kim 00000357:  72 0A 02 0A 07 60 ......    "r....`"
17179c48c75eSJung-uk Kim 
17189c48c75eSJung-uk Kim      188:      }
17199c48c75eSJung-uk Kim 
17209c48c75eSJung-uk Kim      190:      Method (T2)
17219c48c75eSJung-uk Kim 
17229c48c75eSJung-uk Kim 0000035D:  14 10 54 32 5F 5F 00 ...    "..T2__."
17239c48c75eSJung-uk Kim 
17249c48c75eSJung-uk Kim      191:      {
17259c48c75eSJung-uk Kim      192:          EFGH ()
17269c48c75eSJung-uk Kim 
17279c48c75eSJung-uk Kim 00000364:  45 46 47 48 ............    "EFGH"
17289c48c75eSJung-uk Kim 
17299c48c75eSJung-uk Kim      193:          Add (2, 7, Local0)
17309c48c75eSJung-uk Kim 
17319c48c75eSJung-uk Kim 00000368:  72 0A 02 0A 07 60 ......    "r....`"
17329c48c75eSJung-uk Kim      194:      }
17339c48c75eSJung-uk Kim 
17349c48c75eSJung-uk Kim Note that the AML code for T1 and T2 is essentially identical. When
17359c48c75eSJung-uk Kim disassembling this code, the methods ABCD and EFGH must be known to the
17369c48c75eSJung-uk Kim disassembler, otherwise it does not know how to handle the method invocations.
17379c48c75eSJung-uk Kim 
17389c48c75eSJung-uk Kim In other words, if ABCD and EFGH are actually external control methods
17399c48c75eSJung-uk Kim appearing in an SSDT, the disassembler does not know what to do unless
17409c48c75eSJung-uk Kim the owning SSDT has been loaded via the -e option.
1741af051161SJung-uk Kim */
17429c48c75eSJung-uk Kim 
1743f8146b88SJung-uk Kim static char             ExternalWarningPart1[600];
1744f8146b88SJung-uk Kim static char             ExternalWarningPart2[400];
1745f8146b88SJung-uk Kim static char             ExternalWarningPart3[400];
1746f8146b88SJung-uk Kim static char             ExternalWarningPart4[200];
1747f8146b88SJung-uk Kim 
17489c48c75eSJung-uk Kim void
AcpiDmUnresolvedWarning(UINT8 Type)17499c48c75eSJung-uk Kim AcpiDmUnresolvedWarning (
17509c48c75eSJung-uk Kim     UINT8                   Type)
17519c48c75eSJung-uk Kim {
1752f8146b88SJung-uk Kim     char                    *Format;
1753f8146b88SJung-uk Kim     char                    Pad[] = "     *";
1754f8146b88SJung-uk Kim     char                    NoPad[] = "";
1755f8146b88SJung-uk Kim 
17569c48c75eSJung-uk Kim 
17579c48c75eSJung-uk Kim     if (!AcpiGbl_NumExternalMethods)
17589c48c75eSJung-uk Kim     {
17599c48c75eSJung-uk Kim         return;
17609c48c75eSJung-uk Kim     }
17619c48c75eSJung-uk Kim 
1762f8146b88SJung-uk Kim     if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
1763f8146b88SJung-uk Kim     {
1764f8146b88SJung-uk Kim         return;
1765f8146b88SJung-uk Kim     }
1766f8146b88SJung-uk Kim 
1767f8146b88SJung-uk Kim     Format = Type ? Pad : NoPad;
1768f8146b88SJung-uk Kim 
1769f8146b88SJung-uk Kim     sprintf (ExternalWarningPart1,
1770f8146b88SJung-uk Kim         "%s iASL Warning: There %s %u external control method%s found during\n"
1771f8146b88SJung-uk Kim         "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1772f8146b88SJung-uk Kim         "%s ACPI tables may be required to properly disassemble the code. This\n"
1773f8146b88SJung-uk Kim         "%s resulting disassembler output file may not compile because the\n"
1774f8146b88SJung-uk Kim         "%s disassembler did not know how many arguments to assign to the\n"
1775f8146b88SJung-uk Kim         "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
1776f8146b88SJung-uk Kim         "%s runtime and may or may not be available via the host OS.\n",
1777f8146b88SJung-uk Kim         Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
1778f8146b88SJung-uk Kim         AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
1779f8146b88SJung-uk Kim         Format, AcpiGbl_ResolvedExternalMethods,
1780f8146b88SJung-uk Kim         (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
1781f8146b88SJung-uk Kim         (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
1782f8146b88SJung-uk Kim         Format, Format, Format, Format, Format);
1783f8146b88SJung-uk Kim 
1784f8146b88SJung-uk Kim     sprintf (ExternalWarningPart2,
1785f8146b88SJung-uk Kim         "%s To specify the tables needed to resolve external control method\n"
1786f8146b88SJung-uk Kim         "%s references, the -e option can be used to specify the filenames.\n"
1787f8146b88SJung-uk Kim         "%s Example iASL invocations:\n"
1788f8146b88SJung-uk Kim         "%s     iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1789f8146b88SJung-uk Kim         "%s     iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1790f8146b88SJung-uk Kim         "%s     iasl -e ssdt*.aml -d dsdt.aml\n",
1791f8146b88SJung-uk Kim         Format, Format, Format, Format, Format, Format);
1792f8146b88SJung-uk Kim 
1793f8146b88SJung-uk Kim     sprintf (ExternalWarningPart3,
1794f8146b88SJung-uk Kim         "%s In addition, the -fe option can be used to specify a file containing\n"
1795f8146b88SJung-uk Kim         "%s control method external declarations with the associated method\n"
1796f8146b88SJung-uk Kim         "%s argument counts. Each line of the file must be of the form:\n"
1797f8146b88SJung-uk Kim         "%s     External (<method pathname>, MethodObj, <argument count>)\n"
1798f8146b88SJung-uk Kim         "%s Invocation:\n"
1799f8146b88SJung-uk Kim         "%s     iasl -fe refs.txt -d dsdt.aml\n",
1800f8146b88SJung-uk Kim         Format, Format, Format, Format, Format, Format);
1801f8146b88SJung-uk Kim 
1802f8146b88SJung-uk Kim     sprintf (ExternalWarningPart4,
1803f8146b88SJung-uk Kim         "%s The following methods were unresolved and many not compile properly\n"
1804f8146b88SJung-uk Kim         "%s because the disassembler had to guess at the number of arguments\n"
1805f8146b88SJung-uk Kim         "%s required for each:\n",
1806f8146b88SJung-uk Kim         Format, Format, Format);
1807f8146b88SJung-uk Kim 
18089c48c75eSJung-uk Kim     if (Type)
18099c48c75eSJung-uk Kim     {
18109c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
18119c48c75eSJung-uk Kim         {
18129c48c75eSJung-uk Kim             /* The -e option was not specified */
18139c48c75eSJung-uk Kim 
1814f8146b88SJung-uk Kim            AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     *\n%s     */\n",
1815f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
1816f8146b88SJung-uk Kim                ExternalWarningPart4);
18179c48c75eSJung-uk Kim         }
1818f8146b88SJung-uk Kim         else
18199c48c75eSJung-uk Kim         {
18209c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
18219c48c75eSJung-uk Kim 
1822f8146b88SJung-uk Kim             AcpiOsPrintf ("    /*\n%s     *\n%s     *\n%s     */\n",
1823f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
18249c48c75eSJung-uk Kim         }
18259c48c75eSJung-uk Kim     }
18269c48c75eSJung-uk Kim     else
18279c48c75eSJung-uk Kim     {
18289c48c75eSJung-uk Kim         if (!AcpiGbl_ExternalFileList)
18299c48c75eSJung-uk Kim         {
18309c48c75eSJung-uk Kim             /* The -e option was not specified */
18319c48c75eSJung-uk Kim 
1832f8146b88SJung-uk Kim             fprintf (stderr, "\n%s\n%s\n%s\n",
1833f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
18349c48c75eSJung-uk Kim         }
1835f8146b88SJung-uk Kim         else
18369c48c75eSJung-uk Kim         {
18379c48c75eSJung-uk Kim             /* The -e option was specified, but there are still some unresolved externals */
18389c48c75eSJung-uk Kim 
1839f8146b88SJung-uk Kim             fprintf (stderr, "\n%s\n%s\n",
1840f8146b88SJung-uk Kim                ExternalWarningPart1, ExternalWarningPart3);
18419c48c75eSJung-uk Kim         }
18429c48c75eSJung-uk Kim     }
18439c48c75eSJung-uk Kim }
1844