10d02842fSSascha Wildner /******************************************************************************
20d02842fSSascha Wildner *
30d02842fSSascha Wildner * Module Name: dmextern - Support for External() ASL statements
40d02842fSSascha Wildner *
50d02842fSSascha Wildner *****************************************************************************/
60d02842fSSascha Wildner
7b4315fc7SSascha Wildner /******************************************************************************
8b4315fc7SSascha Wildner *
9b4315fc7SSascha Wildner * 1. Copyright Notice
10b4315fc7SSascha Wildner *
11*383048acSSascha Wildner * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
120d02842fSSascha Wildner * All rights reserved.
130d02842fSSascha Wildner *
14b4315fc7SSascha Wildner * 2. License
15b4315fc7SSascha Wildner *
16b4315fc7SSascha Wildner * 2.1. This is your license from Intel Corp. under its intellectual property
17b4315fc7SSascha Wildner * rights. You may have additional license terms from the party that provided
18b4315fc7SSascha Wildner * you this software, covering your right to use that party's intellectual
19b4315fc7SSascha Wildner * property rights.
20b4315fc7SSascha Wildner *
21b4315fc7SSascha Wildner * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22b4315fc7SSascha Wildner * copy of the source code appearing in this file ("Covered Code") an
23b4315fc7SSascha Wildner * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24b4315fc7SSascha Wildner * base code distributed originally by Intel ("Original Intel Code") to copy,
25b4315fc7SSascha Wildner * make derivatives, distribute, use and display any portion of the Covered
26b4315fc7SSascha Wildner * Code in any form, with the right to sublicense such rights; and
27b4315fc7SSascha Wildner *
28b4315fc7SSascha Wildner * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29b4315fc7SSascha Wildner * license (with the right to sublicense), under only those claims of Intel
30b4315fc7SSascha Wildner * patents that are infringed by the Original Intel Code, to make, use, sell,
31b4315fc7SSascha Wildner * offer to sell, and import the Covered Code and derivative works thereof
32b4315fc7SSascha Wildner * solely to the minimum extent necessary to exercise the above copyright
33b4315fc7SSascha Wildner * license, and in no event shall the patent license extend to any additions
34b4315fc7SSascha Wildner * to or modifications of the Original Intel Code. No other license or right
35b4315fc7SSascha Wildner * is granted directly or by implication, estoppel or otherwise;
36b4315fc7SSascha Wildner *
37b4315fc7SSascha Wildner * The above copyright and patent license is granted only if the following
38b4315fc7SSascha Wildner * conditions are met:
39b4315fc7SSascha Wildner *
40b4315fc7SSascha Wildner * 3. Conditions
41b4315fc7SSascha Wildner *
42b4315fc7SSascha Wildner * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43b4315fc7SSascha Wildner * Redistribution of source code of any substantial portion of the Covered
44b4315fc7SSascha Wildner * Code or modification with rights to further distribute source must include
45b4315fc7SSascha Wildner * the above Copyright Notice, the above License, this list of Conditions,
46b4315fc7SSascha Wildner * and the following Disclaimer and Export Compliance provision. In addition,
47b4315fc7SSascha Wildner * Licensee must cause all Covered Code to which Licensee contributes to
48b4315fc7SSascha Wildner * contain a file documenting the changes Licensee made to create that Covered
49b4315fc7SSascha Wildner * Code and the date of any change. Licensee must include in that file the
50b4315fc7SSascha Wildner * documentation of any changes made by any predecessor Licensee. Licensee
51b4315fc7SSascha Wildner * must include a prominent statement that the modification is derived,
52b4315fc7SSascha Wildner * directly or indirectly, from Original Intel Code.
53b4315fc7SSascha Wildner *
54b4315fc7SSascha Wildner * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55b4315fc7SSascha Wildner * Redistribution of source code of any substantial portion of the Covered
56b4315fc7SSascha Wildner * Code or modification without rights to further distribute source must
57b4315fc7SSascha Wildner * include the following Disclaimer and Export Compliance provision in the
58b4315fc7SSascha Wildner * documentation and/or other materials provided with distribution. In
59b4315fc7SSascha Wildner * addition, Licensee may not authorize further sublicense of source of any
60b4315fc7SSascha Wildner * portion of the Covered Code, and must include terms to the effect that the
61b4315fc7SSascha Wildner * license from Licensee to its licensee is limited to the intellectual
62b4315fc7SSascha Wildner * property embodied in the software Licensee provides to its licensee, and
63b4315fc7SSascha Wildner * not to intellectual property embodied in modifications its licensee may
64b4315fc7SSascha Wildner * make.
65b4315fc7SSascha Wildner *
66b4315fc7SSascha Wildner * 3.3. Redistribution of Executable. Redistribution in executable form of any
67b4315fc7SSascha Wildner * substantial portion of the Covered Code or modification must reproduce the
68b4315fc7SSascha Wildner * above Copyright Notice, and the following Disclaimer and Export Compliance
69b4315fc7SSascha Wildner * provision in the documentation and/or other materials provided with the
70b4315fc7SSascha Wildner * distribution.
71b4315fc7SSascha Wildner *
72b4315fc7SSascha Wildner * 3.4. Intel retains all right, title, and interest in and to the Original
73b4315fc7SSascha Wildner * Intel Code.
74b4315fc7SSascha Wildner *
75b4315fc7SSascha Wildner * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76b4315fc7SSascha Wildner * Intel shall be used in advertising or otherwise to promote the sale, use or
77b4315fc7SSascha Wildner * other dealings in products derived from or relating to the Covered Code
78b4315fc7SSascha Wildner * without prior written authorization from Intel.
79b4315fc7SSascha Wildner *
80b4315fc7SSascha Wildner * 4. Disclaimer and Export Compliance
81b4315fc7SSascha Wildner *
82b4315fc7SSascha Wildner * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83b4315fc7SSascha Wildner * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84b4315fc7SSascha Wildner * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85b4315fc7SSascha Wildner * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86b4315fc7SSascha Wildner * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87b4315fc7SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88b4315fc7SSascha Wildner * PARTICULAR PURPOSE.
89b4315fc7SSascha Wildner *
90b4315fc7SSascha Wildner * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91b4315fc7SSascha Wildner * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92b4315fc7SSascha Wildner * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93b4315fc7SSascha Wildner * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94b4315fc7SSascha Wildner * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95b4315fc7SSascha Wildner * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96b4315fc7SSascha Wildner * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97b4315fc7SSascha Wildner * LIMITED REMEDY.
98b4315fc7SSascha Wildner *
99b4315fc7SSascha Wildner * 4.3. Licensee shall not export, either directly or indirectly, any of this
100b4315fc7SSascha Wildner * software or system incorporating such software without first obtaining any
101b4315fc7SSascha Wildner * required license or other approval from the U. S. Department of Commerce or
102b4315fc7SSascha Wildner * any other agency or department of the United States Government. In the
103b4315fc7SSascha Wildner * event Licensee exports any such software from the United States or
104b4315fc7SSascha Wildner * re-exports any such software from a foreign destination, Licensee shall
105b4315fc7SSascha Wildner * ensure that the distribution and export/re-export of the software is in
106b4315fc7SSascha Wildner * compliance with all laws, regulations, orders, or other restrictions of the
107b4315fc7SSascha Wildner * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108b4315fc7SSascha Wildner * any of its subsidiaries will export/re-export any technical data, process,
109b4315fc7SSascha Wildner * software, or service, directly or indirectly, to any country for which the
110b4315fc7SSascha Wildner * United States government or any agency thereof requires an export license,
111b4315fc7SSascha Wildner * other governmental approval, or letter of assurance, without first obtaining
112b4315fc7SSascha Wildner * such license, approval or letter.
113b4315fc7SSascha Wildner *
114b4315fc7SSascha Wildner *****************************************************************************
115b4315fc7SSascha Wildner *
116b4315fc7SSascha Wildner * Alternatively, you may choose to be licensed under the terms of the
117b4315fc7SSascha Wildner * following license:
118b4315fc7SSascha Wildner *
1190d02842fSSascha Wildner * Redistribution and use in source and binary forms, with or without
1200d02842fSSascha Wildner * modification, are permitted provided that the following conditions
1210d02842fSSascha Wildner * are met:
1220d02842fSSascha Wildner * 1. Redistributions of source code must retain the above copyright
1230d02842fSSascha Wildner * notice, this list of conditions, and the following disclaimer,
1240d02842fSSascha Wildner * without modification.
1250d02842fSSascha Wildner * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1260d02842fSSascha Wildner * substantially similar to the "NO WARRANTY" disclaimer below
1270d02842fSSascha Wildner * ("Disclaimer") and any redistribution must be conditioned upon
1280d02842fSSascha Wildner * including a substantially similar Disclaimer requirement for further
1290d02842fSSascha Wildner * binary redistribution.
1300d02842fSSascha Wildner * 3. Neither the names of the above-listed copyright holders nor the names
1310d02842fSSascha Wildner * of any contributors may be used to endorse or promote products derived
1320d02842fSSascha Wildner * from this software without specific prior written permission.
1330d02842fSSascha Wildner *
134b4315fc7SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135b4315fc7SSascha Wildner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136b4315fc7SSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137b4315fc7SSascha Wildner * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138b4315fc7SSascha Wildner * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139b4315fc7SSascha Wildner * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140b4315fc7SSascha Wildner * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141b4315fc7SSascha Wildner * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142b4315fc7SSascha Wildner * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143b4315fc7SSascha Wildner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144b4315fc7SSascha Wildner * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145b4315fc7SSascha Wildner *
146b4315fc7SSascha Wildner * Alternatively, you may choose to be licensed under the terms of the
1470d02842fSSascha Wildner * GNU General Public License ("GPL") version 2 as published by the Free
1480d02842fSSascha Wildner * Software Foundation.
1490d02842fSSascha Wildner *
150b4315fc7SSascha Wildner *****************************************************************************/
1510d02842fSSascha Wildner
1520d02842fSSascha Wildner #include "acpi.h"
1530d02842fSSascha Wildner #include "accommon.h"
1540d02842fSSascha Wildner #include "amlcode.h"
1550d02842fSSascha Wildner #include "acnamesp.h"
1560d02842fSSascha Wildner #include "acdisasm.h"
1570d02842fSSascha Wildner #include "aslcompiler.h"
1580d02842fSSascha Wildner #include <stdio.h>
1590d02842fSSascha Wildner #include <errno.h>
1600d02842fSSascha Wildner
1610d02842fSSascha Wildner
1620d02842fSSascha Wildner /*
1630d02842fSSascha Wildner * This module is used for application-level code (iASL disassembler) only.
1640d02842fSSascha Wildner *
1650d02842fSSascha Wildner * It contains the code to create and emit any necessary External() ASL
1660d02842fSSascha Wildner * statements for the module being disassembled.
1670d02842fSSascha Wildner */
1680d02842fSSascha Wildner #define _COMPONENT ACPI_CA_DISASSEMBLER
1690d02842fSSascha Wildner ACPI_MODULE_NAME ("dmextern")
1700d02842fSSascha Wildner
1710d02842fSSascha Wildner
1720d02842fSSascha Wildner /*
1730d02842fSSascha Wildner * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
1740d02842fSSascha Wildner * ObjectTypeKeyword. Used to generate typed external declarations
1750d02842fSSascha Wildner */
1760d02842fSSascha Wildner static const char *AcpiGbl_DmTypeNames[] =
1770d02842fSSascha Wildner {
178d4972a9cSSascha Wildner /* 00 */ ", UnknownObj", /* Type ANY */
1790d02842fSSascha Wildner /* 01 */ ", IntObj",
1800d02842fSSascha Wildner /* 02 */ ", StrObj",
1810d02842fSSascha Wildner /* 03 */ ", BuffObj",
1820d02842fSSascha Wildner /* 04 */ ", PkgObj",
1830d02842fSSascha Wildner /* 05 */ ", FieldUnitObj",
1840d02842fSSascha Wildner /* 06 */ ", DeviceObj",
1850d02842fSSascha Wildner /* 07 */ ", EventObj",
1860d02842fSSascha Wildner /* 08 */ ", MethodObj",
1870d02842fSSascha Wildner /* 09 */ ", MutexObj",
1880d02842fSSascha Wildner /* 10 */ ", OpRegionObj",
1890d02842fSSascha Wildner /* 11 */ ", PowerResObj",
1900d02842fSSascha Wildner /* 12 */ ", ProcessorObj",
1910d02842fSSascha Wildner /* 13 */ ", ThermalZoneObj",
1920d02842fSSascha Wildner /* 14 */ ", BuffFieldObj",
1930d02842fSSascha Wildner /* 15 */ ", DDBHandleObj",
1940d02842fSSascha Wildner /* 16 */ "", /* Debug object */
1950d02842fSSascha Wildner /* 17 */ ", FieldUnitObj",
1960d02842fSSascha Wildner /* 18 */ ", FieldUnitObj",
1970d02842fSSascha Wildner /* 19 */ ", FieldUnitObj"
1980d02842fSSascha Wildner };
1990d02842fSSascha Wildner
2000d02842fSSascha Wildner #define METHOD_SEPARATORS " \t,()\n"
2010d02842fSSascha Wildner
2021093ca81SSascha Wildner static const char *ExternalConflictMessage =
2031093ca81SSascha Wildner " // Conflicts with a later declaration";
2041093ca81SSascha Wildner
2050d02842fSSascha Wildner
2060d02842fSSascha Wildner /* Local prototypes */
2070d02842fSSascha Wildner
2080d02842fSSascha Wildner static const char *
2090d02842fSSascha Wildner AcpiDmGetObjectTypeName (
2100d02842fSSascha Wildner ACPI_OBJECT_TYPE Type);
2110d02842fSSascha Wildner
2120d02842fSSascha Wildner static char *
2130d02842fSSascha Wildner AcpiDmNormalizeParentPrefix (
2140d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op,
2150d02842fSSascha Wildner char *Path);
2160d02842fSSascha Wildner
2171093ca81SSascha Wildner static ACPI_STATUS
2181093ca81SSascha Wildner AcpiDmGetExternalAndInternalPath (
2191093ca81SSascha Wildner ACPI_NAMESPACE_NODE *Node,
2201093ca81SSascha Wildner char **ExternalPath,
2211093ca81SSascha Wildner char **InternalPath);
2221093ca81SSascha Wildner
2231093ca81SSascha Wildner static ACPI_STATUS
2241093ca81SSascha Wildner AcpiDmRemoveRootPrefix (
2251093ca81SSascha Wildner char **Path);
2261093ca81SSascha Wildner
2270d02842fSSascha Wildner static void
2280d02842fSSascha Wildner AcpiDmAddPathToExternalList (
2290d02842fSSascha Wildner char *Path,
2300d02842fSSascha Wildner UINT8 Type,
2310d02842fSSascha Wildner UINT32 Value,
2320d02842fSSascha Wildner UINT16 Flags);
2330d02842fSSascha Wildner
2340d02842fSSascha Wildner static ACPI_STATUS
2350d02842fSSascha Wildner AcpiDmCreateNewExternal (
2360d02842fSSascha Wildner char *ExternalPath,
2370d02842fSSascha Wildner char *InternalPath,
2380d02842fSSascha Wildner UINT8 Type,
2390d02842fSSascha Wildner UINT32 Value,
2400d02842fSSascha Wildner UINT16 Flags);
2410d02842fSSascha Wildner
2421093ca81SSascha Wildner static void
2431093ca81SSascha Wildner AcpiDmCheckForExternalConflict (
2441093ca81SSascha Wildner char *Path);
2451093ca81SSascha Wildner
2461093ca81SSascha Wildner static ACPI_STATUS
2471093ca81SSascha Wildner AcpiDmResolveExternal (
2481093ca81SSascha Wildner char *Path,
2491093ca81SSascha Wildner UINT8 Type,
2501093ca81SSascha Wildner ACPI_NAMESPACE_NODE **Node);
2511093ca81SSascha Wildner
2521093ca81SSascha Wildner
2531093ca81SSascha Wildner static void
2541093ca81SSascha Wildner AcpiDmConflictingDeclaration (
2551093ca81SSascha Wildner char *Path);
2561093ca81SSascha Wildner
2570d02842fSSascha Wildner
2580d02842fSSascha Wildner /*******************************************************************************
2590d02842fSSascha Wildner *
2600d02842fSSascha Wildner * FUNCTION: AcpiDmGetObjectTypeName
2610d02842fSSascha Wildner *
2620d02842fSSascha Wildner * PARAMETERS: Type - An ACPI_OBJECT_TYPE
2630d02842fSSascha Wildner *
2640d02842fSSascha Wildner * RETURN: Pointer to a string
2650d02842fSSascha Wildner *
2660d02842fSSascha Wildner * DESCRIPTION: Map an object type to the ASL object type string.
2670d02842fSSascha Wildner *
2680d02842fSSascha Wildner ******************************************************************************/
2690d02842fSSascha Wildner
2700d02842fSSascha Wildner static const char *
AcpiDmGetObjectTypeName(ACPI_OBJECT_TYPE Type)2710d02842fSSascha Wildner AcpiDmGetObjectTypeName (
2720d02842fSSascha Wildner ACPI_OBJECT_TYPE Type)
2730d02842fSSascha Wildner {
2740d02842fSSascha Wildner
2750d02842fSSascha Wildner if (Type == ACPI_TYPE_LOCAL_SCOPE)
2760d02842fSSascha Wildner {
2770d02842fSSascha Wildner Type = ACPI_TYPE_DEVICE;
2780d02842fSSascha Wildner }
2790d02842fSSascha Wildner else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
2800d02842fSSascha Wildner {
2810d02842fSSascha Wildner return ("");
2820d02842fSSascha Wildner }
2830d02842fSSascha Wildner
2840d02842fSSascha Wildner return (AcpiGbl_DmTypeNames[Type]);
2850d02842fSSascha Wildner }
2860d02842fSSascha Wildner
2870d02842fSSascha Wildner
2880d02842fSSascha Wildner /*******************************************************************************
2890d02842fSSascha Wildner *
2900d02842fSSascha Wildner * FUNCTION: AcpiDmNormalizeParentPrefix
2910d02842fSSascha Wildner *
2920d02842fSSascha Wildner * PARAMETERS: Op - Parse op
2930d02842fSSascha Wildner * Path - Path with parent prefix
2940d02842fSSascha Wildner *
2950d02842fSSascha Wildner * RETURN: The full pathname to the object (from the namespace root)
2960d02842fSSascha Wildner *
2970d02842fSSascha Wildner * DESCRIPTION: Returns the full pathname of a path with parent prefix
2980d02842fSSascha Wildner * The caller must free the fullpath returned.
2990d02842fSSascha Wildner *
3000d02842fSSascha Wildner ******************************************************************************/
3010d02842fSSascha Wildner
3020d02842fSSascha Wildner static char *
AcpiDmNormalizeParentPrefix(ACPI_PARSE_OBJECT * Op,char * Path)3030d02842fSSascha Wildner AcpiDmNormalizeParentPrefix (
3040d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op,
3050d02842fSSascha Wildner char *Path)
3060d02842fSSascha Wildner {
3070d02842fSSascha Wildner ACPI_NAMESPACE_NODE *Node;
3080d02842fSSascha Wildner char *Fullpath;
3090d02842fSSascha Wildner char *ParentPath;
3100d02842fSSascha Wildner ACPI_SIZE Length;
3110d02842fSSascha Wildner UINT32 Index = 0;
3120d02842fSSascha Wildner
3130d02842fSSascha Wildner
3140d02842fSSascha Wildner if (!Op)
3150d02842fSSascha Wildner {
3160d02842fSSascha Wildner return (NULL);
3170d02842fSSascha Wildner }
3180d02842fSSascha Wildner
3190d02842fSSascha Wildner /* Search upwards in the parse tree until we reach the next namespace node */
3200d02842fSSascha Wildner
3210d02842fSSascha Wildner Op = Op->Common.Parent;
3220d02842fSSascha Wildner while (Op)
3230d02842fSSascha Wildner {
3240d02842fSSascha Wildner if (Op->Common.Node)
3250d02842fSSascha Wildner {
3260d02842fSSascha Wildner break;
3270d02842fSSascha Wildner }
3280d02842fSSascha Wildner
3290d02842fSSascha Wildner Op = Op->Common.Parent;
3300d02842fSSascha Wildner }
3310d02842fSSascha Wildner
3320d02842fSSascha Wildner if (!Op)
3330d02842fSSascha Wildner {
3340d02842fSSascha Wildner return (NULL);
3350d02842fSSascha Wildner }
3360d02842fSSascha Wildner
3370d02842fSSascha Wildner /*
3380d02842fSSascha Wildner * Find the actual parent node for the reference:
3390d02842fSSascha Wildner * Remove all carat prefixes from the input path.
3400d02842fSSascha Wildner * There may be multiple parent prefixes (For example, ^^^M000)
3410d02842fSSascha Wildner */
3420d02842fSSascha Wildner Node = Op->Common.Node;
3430d02842fSSascha Wildner while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
3440d02842fSSascha Wildner {
3450d02842fSSascha Wildner Node = Node->Parent;
3460d02842fSSascha Wildner Path++;
3470d02842fSSascha Wildner }
3480d02842fSSascha Wildner
3490d02842fSSascha Wildner if (!Node)
3500d02842fSSascha Wildner {
3510d02842fSSascha Wildner return (NULL);
3520d02842fSSascha Wildner }
3530d02842fSSascha Wildner
3540d02842fSSascha Wildner /* Get the full pathname for the parent node */
3550d02842fSSascha Wildner
3560d02842fSSascha Wildner ParentPath = AcpiNsGetExternalPathname (Node);
3570d02842fSSascha Wildner if (!ParentPath)
3580d02842fSSascha Wildner {
3590d02842fSSascha Wildner return (NULL);
3600d02842fSSascha Wildner }
3610d02842fSSascha Wildner
36225ca8c79SSascha Wildner Length = (strlen (ParentPath) + strlen (Path) + 1);
3630d02842fSSascha Wildner if (ParentPath[1])
3640d02842fSSascha Wildner {
3650d02842fSSascha Wildner /*
3660d02842fSSascha Wildner * If ParentPath is not just a simple '\', increment the length
3670d02842fSSascha Wildner * for the required dot separator (ParentPath.Path)
3680d02842fSSascha Wildner */
3690d02842fSSascha Wildner Length++;
3700d02842fSSascha Wildner
3710d02842fSSascha Wildner /* For External() statements, we do not want a leading '\' */
3720d02842fSSascha Wildner
3730d02842fSSascha Wildner if (*ParentPath == AML_ROOT_PREFIX)
3740d02842fSSascha Wildner {
3750d02842fSSascha Wildner Index = 1;
3760d02842fSSascha Wildner }
3770d02842fSSascha Wildner }
3780d02842fSSascha Wildner
3790d02842fSSascha Wildner Fullpath = ACPI_ALLOCATE_ZEROED (Length);
3800d02842fSSascha Wildner if (!Fullpath)
3810d02842fSSascha Wildner {
3820d02842fSSascha Wildner goto Cleanup;
3830d02842fSSascha Wildner }
3840d02842fSSascha Wildner
3850d02842fSSascha Wildner /*
3860d02842fSSascha Wildner * Concatenate parent fullpath and path. For example,
3870d02842fSSascha Wildner * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
3880d02842fSSascha Wildner *
3890d02842fSSascha Wildner * Copy the parent path
3900d02842fSSascha Wildner */
39125ca8c79SSascha Wildner strcpy (Fullpath, &ParentPath[Index]);
3920d02842fSSascha Wildner
3930d02842fSSascha Wildner /*
3940d02842fSSascha Wildner * Add dot separator
3950d02842fSSascha Wildner * (don't need dot if parent fullpath is a single backslash)
3960d02842fSSascha Wildner */
3970d02842fSSascha Wildner if (ParentPath[1])
3980d02842fSSascha Wildner {
39925ca8c79SSascha Wildner strcat (Fullpath, ".");
4000d02842fSSascha Wildner }
4010d02842fSSascha Wildner
4020d02842fSSascha Wildner /* Copy child path (carat parent prefix(es) were skipped above) */
4030d02842fSSascha Wildner
40425ca8c79SSascha Wildner strcat (Fullpath, Path);
4050d02842fSSascha Wildner
4060d02842fSSascha Wildner Cleanup:
4070d02842fSSascha Wildner ACPI_FREE (ParentPath);
4080d02842fSSascha Wildner return (Fullpath);
4090d02842fSSascha Wildner }
4100d02842fSSascha Wildner
4110d02842fSSascha Wildner
4120d02842fSSascha Wildner /*******************************************************************************
4130d02842fSSascha Wildner *
4140d02842fSSascha Wildner * FUNCTION: AcpiDmAddToExternalFileList
4150d02842fSSascha Wildner *
4160d02842fSSascha Wildner * PARAMETERS: PathList - Single path or list separated by comma
4170d02842fSSascha Wildner *
4180d02842fSSascha Wildner * RETURN: None
4190d02842fSSascha Wildner *
4200d02842fSSascha Wildner * DESCRIPTION: Add external files to global list
4210d02842fSSascha Wildner *
4220d02842fSSascha Wildner ******************************************************************************/
4230d02842fSSascha Wildner
4240d02842fSSascha Wildner ACPI_STATUS
AcpiDmAddToExternalFileList(char * Pathname)4250d02842fSSascha Wildner AcpiDmAddToExternalFileList (
4260d02842fSSascha Wildner char *Pathname)
4270d02842fSSascha Wildner {
4280d02842fSSascha Wildner ACPI_EXTERNAL_FILE *ExternalFile;
4290d02842fSSascha Wildner char *LocalPathname;
4300d02842fSSascha Wildner
4310d02842fSSascha Wildner
4320d02842fSSascha Wildner if (!Pathname)
4330d02842fSSascha Wildner {
4340d02842fSSascha Wildner return (AE_OK);
4350d02842fSSascha Wildner }
4360d02842fSSascha Wildner
4370d02842fSSascha Wildner LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
4380d02842fSSascha Wildner if (!LocalPathname)
4390d02842fSSascha Wildner {
4400d02842fSSascha Wildner return (AE_NO_MEMORY);
4410d02842fSSascha Wildner }
4420d02842fSSascha Wildner
4430d02842fSSascha Wildner ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
4440d02842fSSascha Wildner if (!ExternalFile)
4450d02842fSSascha Wildner {
4460d02842fSSascha Wildner ACPI_FREE (LocalPathname);
4470d02842fSSascha Wildner return (AE_NO_MEMORY);
4480d02842fSSascha Wildner }
4490d02842fSSascha Wildner
4500d02842fSSascha Wildner /* Take a copy of the file pathname */
4510d02842fSSascha Wildner
4520d02842fSSascha Wildner strcpy (LocalPathname, Pathname);
4530d02842fSSascha Wildner ExternalFile->Path = LocalPathname;
4540d02842fSSascha Wildner
4550d02842fSSascha Wildner if (AcpiGbl_ExternalFileList)
4560d02842fSSascha Wildner {
4570d02842fSSascha Wildner ExternalFile->Next = AcpiGbl_ExternalFileList;
4580d02842fSSascha Wildner }
4590d02842fSSascha Wildner
4600d02842fSSascha Wildner AcpiGbl_ExternalFileList = ExternalFile;
4610d02842fSSascha Wildner return (AE_OK);
4620d02842fSSascha Wildner }
4630d02842fSSascha Wildner
4640d02842fSSascha Wildner
4650d02842fSSascha Wildner /*******************************************************************************
4660d02842fSSascha Wildner *
4670d02842fSSascha Wildner * FUNCTION: AcpiDmClearExternalFileList
4680d02842fSSascha Wildner *
4690d02842fSSascha Wildner * PARAMETERS: None
4700d02842fSSascha Wildner *
4710d02842fSSascha Wildner * RETURN: None
4720d02842fSSascha Wildner *
4730d02842fSSascha Wildner * DESCRIPTION: Clear the external file list
4740d02842fSSascha Wildner *
4750d02842fSSascha Wildner ******************************************************************************/
4760d02842fSSascha Wildner
4770d02842fSSascha Wildner void
AcpiDmClearExternalFileList(void)4780d02842fSSascha Wildner AcpiDmClearExternalFileList (
4790d02842fSSascha Wildner void)
4800d02842fSSascha Wildner {
4810d02842fSSascha Wildner ACPI_EXTERNAL_FILE *NextExternal;
4820d02842fSSascha Wildner
4830d02842fSSascha Wildner
4840d02842fSSascha Wildner while (AcpiGbl_ExternalFileList)
4850d02842fSSascha Wildner {
4860d02842fSSascha Wildner NextExternal = AcpiGbl_ExternalFileList->Next;
4870d02842fSSascha Wildner ACPI_FREE (AcpiGbl_ExternalFileList->Path);
4880d02842fSSascha Wildner ACPI_FREE (AcpiGbl_ExternalFileList);
4890d02842fSSascha Wildner AcpiGbl_ExternalFileList = NextExternal;
4900d02842fSSascha Wildner }
4910d02842fSSascha Wildner }
4920d02842fSSascha Wildner
4930d02842fSSascha Wildner
4940d02842fSSascha Wildner /*******************************************************************************
4950d02842fSSascha Wildner *
4960d02842fSSascha Wildner * FUNCTION: AcpiDmGetExternalsFromFile
4970d02842fSSascha Wildner *
4980d02842fSSascha Wildner * PARAMETERS: None
4990d02842fSSascha Wildner *
5000d02842fSSascha Wildner * RETURN: None
5010d02842fSSascha Wildner *
5020d02842fSSascha Wildner * DESCRIPTION: Process the optional external reference file.
5030d02842fSSascha Wildner *
5040d02842fSSascha Wildner * Each line in the file should be of the form:
5050d02842fSSascha Wildner * External (<Method namepath>, MethodObj, <ArgCount>)
5060d02842fSSascha Wildner *
5070d02842fSSascha Wildner * Example:
5080d02842fSSascha Wildner * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
5090d02842fSSascha Wildner *
5100d02842fSSascha Wildner ******************************************************************************/
5110d02842fSSascha Wildner
5120d02842fSSascha Wildner void
AcpiDmGetExternalsFromFile(void)5130d02842fSSascha Wildner AcpiDmGetExternalsFromFile (
5140d02842fSSascha Wildner void)
5150d02842fSSascha Wildner {
5160d02842fSSascha Wildner FILE *ExternalRefFile;
5170d02842fSSascha Wildner char *Token;
5180d02842fSSascha Wildner char *MethodName;
5190d02842fSSascha Wildner UINT32 ArgCount;
5200d02842fSSascha Wildner UINT32 ImportCount = 0;
5210d02842fSSascha Wildner
5220d02842fSSascha Wildner
523806343b9SSascha Wildner if (!AslGbl_ExternalRefFilename)
5240d02842fSSascha Wildner {
5250d02842fSSascha Wildner return;
5260d02842fSSascha Wildner }
5270d02842fSSascha Wildner
5280d02842fSSascha Wildner /* Open the file */
5290d02842fSSascha Wildner
530806343b9SSascha Wildner ExternalRefFile = fopen (AslGbl_ExternalRefFilename, "r");
5310d02842fSSascha Wildner if (!ExternalRefFile)
5320d02842fSSascha Wildner {
5330d02842fSSascha Wildner fprintf (stderr, "Could not open external reference file \"%s\"\n",
534806343b9SSascha Wildner AslGbl_ExternalRefFilename);
535d4972a9cSSascha Wildner AslAbort ();
5360d02842fSSascha Wildner return;
5370d02842fSSascha Wildner }
5380d02842fSSascha Wildner
5390d02842fSSascha Wildner /* Each line defines a method */
5400d02842fSSascha Wildner
541806343b9SSascha Wildner while (fgets (AslGbl_StringBuffer, ASL_STRING_BUFFER_SIZE, ExternalRefFile))
5420d02842fSSascha Wildner {
543806343b9SSascha Wildner Token = strtok (AslGbl_StringBuffer, METHOD_SEPARATORS); /* "External" */
544066b6da2SSascha Wildner if (!Token)
545066b6da2SSascha Wildner {
546066b6da2SSascha Wildner continue;
547066b6da2SSascha Wildner }
548820c5b08SSascha Wildner
549066b6da2SSascha Wildner if (strcmp (Token, "External"))
550066b6da2SSascha Wildner {
551066b6da2SSascha Wildner continue;
552066b6da2SSascha Wildner }
5530d02842fSSascha Wildner
5540d02842fSSascha Wildner MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
555066b6da2SSascha Wildner if (!MethodName)
556066b6da2SSascha Wildner {
557066b6da2SSascha Wildner continue;
558066b6da2SSascha Wildner }
5590d02842fSSascha Wildner
5600d02842fSSascha Wildner Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
561066b6da2SSascha Wildner if (!Token)
562066b6da2SSascha Wildner {
563066b6da2SSascha Wildner continue;
564066b6da2SSascha Wildner }
565066b6da2SSascha Wildner
566066b6da2SSascha Wildner if (strcmp (Token, "MethodObj"))
567066b6da2SSascha Wildner {
568066b6da2SSascha Wildner continue;
569066b6da2SSascha Wildner }
5700d02842fSSascha Wildner
5710d02842fSSascha Wildner Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
572066b6da2SSascha Wildner if (!Token)
573066b6da2SSascha Wildner {
574066b6da2SSascha Wildner continue;
575066b6da2SSascha Wildner }
5760d02842fSSascha Wildner
5770d02842fSSascha Wildner /* Convert arg count string to an integer */
5780d02842fSSascha Wildner
5790d02842fSSascha Wildner errno = 0;
5800d02842fSSascha Wildner ArgCount = strtoul (Token, NULL, 0);
5810d02842fSSascha Wildner if (errno)
5820d02842fSSascha Wildner {
5830d02842fSSascha Wildner fprintf (stderr, "Invalid argument count (%s)\n", Token);
5840d02842fSSascha Wildner continue;
5850d02842fSSascha Wildner }
586820c5b08SSascha Wildner
5870d02842fSSascha Wildner if (ArgCount > 7)
5880d02842fSSascha Wildner {
5890d02842fSSascha Wildner fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
5900d02842fSSascha Wildner continue;
5910d02842fSSascha Wildner }
5920d02842fSSascha Wildner
5930d02842fSSascha Wildner /* Add this external to the global list */
5940d02842fSSascha Wildner
5950d02842fSSascha Wildner AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
596806343b9SSascha Wildner AslGbl_ExternalRefFilename, ArgCount, MethodName);
5970d02842fSSascha Wildner
5980d02842fSSascha Wildner AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
5990d02842fSSascha Wildner ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
6000d02842fSSascha Wildner ImportCount++;
6010d02842fSSascha Wildner }
6020d02842fSSascha Wildner
6030d02842fSSascha Wildner if (!ImportCount)
6040d02842fSSascha Wildner {
605820c5b08SSascha Wildner fprintf (stderr,
606820c5b08SSascha Wildner "Did not find any external methods in reference file \"%s\"\n",
607806343b9SSascha Wildner AslGbl_ExternalRefFilename);
6080d02842fSSascha Wildner }
6090d02842fSSascha Wildner else
6100d02842fSSascha Wildner {
6110d02842fSSascha Wildner /* Add the external(s) to the namespace */
6120d02842fSSascha Wildner
6131093ca81SSascha Wildner AcpiDmAddExternalListToNamespace ();
6140d02842fSSascha Wildner
6150d02842fSSascha Wildner AcpiOsPrintf ("%s: Imported %u external method definitions\n",
616806343b9SSascha Wildner AslGbl_ExternalRefFilename, ImportCount);
6170d02842fSSascha Wildner }
6180d02842fSSascha Wildner
6190d02842fSSascha Wildner fclose (ExternalRefFile);
6200d02842fSSascha Wildner }
6210d02842fSSascha Wildner
6220d02842fSSascha Wildner
6230d02842fSSascha Wildner /*******************************************************************************
6240d02842fSSascha Wildner *
6250d02842fSSascha Wildner * FUNCTION: AcpiDmAddOpToExternalList
6260d02842fSSascha Wildner *
6270d02842fSSascha Wildner * PARAMETERS: Op - Current parser Op
6280d02842fSSascha Wildner * Path - Internal (AML) path to the object
6290d02842fSSascha Wildner * Type - ACPI object type to be added
6300d02842fSSascha Wildner * Value - Arg count if adding a Method object
6310d02842fSSascha Wildner * Flags - To be passed to the external object
6320d02842fSSascha Wildner *
6330d02842fSSascha Wildner * RETURN: None
6340d02842fSSascha Wildner *
6350d02842fSSascha Wildner * DESCRIPTION: Insert a new name into the global list of Externals which
6360d02842fSSascha Wildner * will in turn be later emitted as an External() declaration
6370d02842fSSascha Wildner * in the disassembled output.
6380d02842fSSascha Wildner *
6390d02842fSSascha Wildner * This function handles the most common case where the referenced
6400d02842fSSascha Wildner * name is simply not found in the constructed namespace.
6410d02842fSSascha Wildner *
6420d02842fSSascha Wildner ******************************************************************************/
6430d02842fSSascha Wildner
6440d02842fSSascha Wildner void
AcpiDmAddOpToExternalList(ACPI_PARSE_OBJECT * Op,char * Path,UINT8 Type,UINT32 Value,UINT16 Flags)6450d02842fSSascha Wildner AcpiDmAddOpToExternalList (
6460d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op,
6470d02842fSSascha Wildner char *Path,
6480d02842fSSascha Wildner UINT8 Type,
6490d02842fSSascha Wildner UINT32 Value,
6500d02842fSSascha Wildner UINT16 Flags)
6510d02842fSSascha Wildner {
6520d02842fSSascha Wildner char *ExternalPath;
6530d02842fSSascha Wildner char *InternalPath = Path;
6540d02842fSSascha Wildner char *Temp;
6550d02842fSSascha Wildner ACPI_STATUS Status;
6560d02842fSSascha Wildner
6570d02842fSSascha Wildner
6580d02842fSSascha Wildner ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
6590d02842fSSascha Wildner
6600d02842fSSascha Wildner
6610d02842fSSascha Wildner if (!Path)
6620d02842fSSascha Wildner {
6630d02842fSSascha Wildner return_VOID;
6640d02842fSSascha Wildner }
6650d02842fSSascha Wildner
6660d02842fSSascha Wildner /* Remove a root backslash if present */
6670d02842fSSascha Wildner
6680d02842fSSascha Wildner if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
6690d02842fSSascha Wildner {
6700d02842fSSascha Wildner Path++;
6710d02842fSSascha Wildner }
6720d02842fSSascha Wildner
6730d02842fSSascha Wildner /* Externalize the pathname */
6740d02842fSSascha Wildner
6750d02842fSSascha Wildner Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
6760d02842fSSascha Wildner NULL, &ExternalPath);
6770d02842fSSascha Wildner if (ACPI_FAILURE (Status))
6780d02842fSSascha Wildner {
6790d02842fSSascha Wildner return_VOID;
6800d02842fSSascha Wildner }
6810d02842fSSascha Wildner
6820d02842fSSascha Wildner /*
6830d02842fSSascha Wildner * Get the full pathname from the root if "Path" has one or more
6840d02842fSSascha Wildner * parent prefixes (^). Note: path will not contain a leading '\'.
6850d02842fSSascha Wildner */
6860d02842fSSascha Wildner if (*Path == (UINT8) AML_PARENT_PREFIX)
6870d02842fSSascha Wildner {
6880d02842fSSascha Wildner Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
6890d02842fSSascha Wildner
6900d02842fSSascha Wildner /* Set new external path */
6910d02842fSSascha Wildner
6920d02842fSSascha Wildner ACPI_FREE (ExternalPath);
6930d02842fSSascha Wildner ExternalPath = Temp;
6940d02842fSSascha Wildner if (!Temp)
6950d02842fSSascha Wildner {
6960d02842fSSascha Wildner return_VOID;
6970d02842fSSascha Wildner }
6980d02842fSSascha Wildner
6990d02842fSSascha Wildner /* Create the new internal pathname */
7000d02842fSSascha Wildner
7010d02842fSSascha Wildner Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
7020d02842fSSascha Wildner Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
7030d02842fSSascha Wildner if (ACPI_FAILURE (Status))
7040d02842fSSascha Wildner {
7050d02842fSSascha Wildner ACPI_FREE (ExternalPath);
7060d02842fSSascha Wildner return_VOID;
7070d02842fSSascha Wildner }
7080d02842fSSascha Wildner }
7090d02842fSSascha Wildner
7100d02842fSSascha Wildner /* Create the new External() declaration node */
7110d02842fSSascha Wildner
7120d02842fSSascha Wildner Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
7130d02842fSSascha Wildner Type, Value, Flags);
7140d02842fSSascha Wildner if (ACPI_FAILURE (Status))
7150d02842fSSascha Wildner {
7160d02842fSSascha Wildner ACPI_FREE (ExternalPath);
7170d02842fSSascha Wildner if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
7180d02842fSSascha Wildner {
7190d02842fSSascha Wildner ACPI_FREE (InternalPath);
7200d02842fSSascha Wildner }
7210d02842fSSascha Wildner }
7220d02842fSSascha Wildner
7230d02842fSSascha Wildner return_VOID;
7240d02842fSSascha Wildner }
7250d02842fSSascha Wildner
7260d02842fSSascha Wildner
7270d02842fSSascha Wildner /*******************************************************************************
7280d02842fSSascha Wildner *
7291093ca81SSascha Wildner * FUNCTION: AcpiDmGetExternalAndInternalPath
7301093ca81SSascha Wildner *
7311093ca81SSascha Wildner * PARAMETERS: Node - Namespace node for object to be added
7321093ca81SSascha Wildner * ExternalPath - Will contain the external path of the node
7331093ca81SSascha Wildner * InternalPath - Will contain the internal path of the node
7341093ca81SSascha Wildner *
7351093ca81SSascha Wildner * RETURN: None
7361093ca81SSascha Wildner *
7371093ca81SSascha Wildner * DESCRIPTION: Get the External and Internal path from the given node.
7381093ca81SSascha Wildner *
7391093ca81SSascha Wildner ******************************************************************************/
7401093ca81SSascha Wildner
7411093ca81SSascha Wildner static ACPI_STATUS
AcpiDmGetExternalAndInternalPath(ACPI_NAMESPACE_NODE * Node,char ** ExternalPath,char ** InternalPath)7421093ca81SSascha Wildner AcpiDmGetExternalAndInternalPath (
7431093ca81SSascha Wildner ACPI_NAMESPACE_NODE *Node,
7441093ca81SSascha Wildner char **ExternalPath,
7451093ca81SSascha Wildner char **InternalPath)
7461093ca81SSascha Wildner {
7471093ca81SSascha Wildner ACPI_STATUS Status;
7481093ca81SSascha Wildner
7491093ca81SSascha Wildner
7501093ca81SSascha Wildner if (!Node)
7511093ca81SSascha Wildner {
7521093ca81SSascha Wildner return (AE_BAD_PARAMETER);
7531093ca81SSascha Wildner }
7541093ca81SSascha Wildner
7551093ca81SSascha Wildner /* Get the full external and internal pathnames to the node */
7561093ca81SSascha Wildner
7571093ca81SSascha Wildner *ExternalPath = AcpiNsGetExternalPathname (Node);
7581093ca81SSascha Wildner if (!*ExternalPath)
7591093ca81SSascha Wildner {
7601093ca81SSascha Wildner return (AE_BAD_PATHNAME);
7611093ca81SSascha Wildner }
7621093ca81SSascha Wildner
7631093ca81SSascha Wildner Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);
7641093ca81SSascha Wildner if (ACPI_FAILURE (Status))
7651093ca81SSascha Wildner {
7661093ca81SSascha Wildner ACPI_FREE (*ExternalPath);
7671093ca81SSascha Wildner return (Status);
7681093ca81SSascha Wildner }
7691093ca81SSascha Wildner
7701093ca81SSascha Wildner return (AE_OK);
7711093ca81SSascha Wildner }
7721093ca81SSascha Wildner
7731093ca81SSascha Wildner
7741093ca81SSascha Wildner /*******************************************************************************
7751093ca81SSascha Wildner *
7761093ca81SSascha Wildner * FUNCTION: AcpiDmRemoveRootPrefix
7771093ca81SSascha Wildner *
7781093ca81SSascha Wildner * PARAMETERS: Path - Remove Root prefix from this Path
7791093ca81SSascha Wildner *
7801093ca81SSascha Wildner * RETURN: None
7811093ca81SSascha Wildner *
7821093ca81SSascha Wildner * DESCRIPTION: Remove the root prefix character '\' from Path.
7831093ca81SSascha Wildner *
7841093ca81SSascha Wildner ******************************************************************************/
7851093ca81SSascha Wildner
7861093ca81SSascha Wildner static ACPI_STATUS
AcpiDmRemoveRootPrefix(char ** Path)7871093ca81SSascha Wildner AcpiDmRemoveRootPrefix (
7881093ca81SSascha Wildner char **Path)
7891093ca81SSascha Wildner {
7901093ca81SSascha Wildner char *InputPath = *Path;
7911093ca81SSascha Wildner
7921093ca81SSascha Wildner
7931093ca81SSascha Wildner if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))
7941093ca81SSascha Wildner {
7951093ca81SSascha Wildner if (!memmove(InputPath, InputPath+1, strlen(InputPath)))
7961093ca81SSascha Wildner {
7971093ca81SSascha Wildner return (AE_ERROR);
7981093ca81SSascha Wildner }
7991093ca81SSascha Wildner
8001093ca81SSascha Wildner *Path = InputPath;
8011093ca81SSascha Wildner }
8021093ca81SSascha Wildner
8031093ca81SSascha Wildner return (AE_OK);
8041093ca81SSascha Wildner }
8051093ca81SSascha Wildner
8061093ca81SSascha Wildner
8071093ca81SSascha Wildner /*******************************************************************************
8081093ca81SSascha Wildner *
8090d02842fSSascha Wildner * FUNCTION: AcpiDmAddNodeToExternalList
8100d02842fSSascha Wildner *
8110d02842fSSascha Wildner * PARAMETERS: Node - Namespace node for object to be added
8120d02842fSSascha Wildner * Type - ACPI object type to be added
8130d02842fSSascha Wildner * Value - Arg count if adding a Method object
8140d02842fSSascha Wildner * Flags - To be passed to the external object
8150d02842fSSascha Wildner *
8160d02842fSSascha Wildner * RETURN: None
8170d02842fSSascha Wildner *
8180d02842fSSascha Wildner * DESCRIPTION: Insert a new name into the global list of Externals which
8190d02842fSSascha Wildner * will in turn be later emitted as an External() declaration
8200d02842fSSascha Wildner * in the disassembled output.
8210d02842fSSascha Wildner *
8220d02842fSSascha Wildner * This function handles the case where the referenced name has
8230d02842fSSascha Wildner * been found in the namespace, but the name originated in a
8240d02842fSSascha Wildner * table other than the one that is being disassembled (such
8250d02842fSSascha Wildner * as a table that is added via the iASL -e option).
8260d02842fSSascha Wildner *
8270d02842fSSascha Wildner ******************************************************************************/
8280d02842fSSascha Wildner
8290d02842fSSascha Wildner void
AcpiDmAddNodeToExternalList(ACPI_NAMESPACE_NODE * Node,UINT8 Type,UINT32 Value,UINT16 Flags)8300d02842fSSascha Wildner AcpiDmAddNodeToExternalList (
8310d02842fSSascha Wildner ACPI_NAMESPACE_NODE *Node,
8320d02842fSSascha Wildner UINT8 Type,
8330d02842fSSascha Wildner UINT32 Value,
8340d02842fSSascha Wildner UINT16 Flags)
8350d02842fSSascha Wildner {
8360d02842fSSascha Wildner char *ExternalPath;
8370d02842fSSascha Wildner char *InternalPath;
8380d02842fSSascha Wildner ACPI_STATUS Status;
8390d02842fSSascha Wildner
8400d02842fSSascha Wildner
8410d02842fSSascha Wildner ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
8420d02842fSSascha Wildner
8430d02842fSSascha Wildner /* Get the full external and internal pathnames to the node */
8440d02842fSSascha Wildner
8451093ca81SSascha Wildner Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);
8460d02842fSSascha Wildner if (ACPI_FAILURE (Status))
8470d02842fSSascha Wildner {
8480d02842fSSascha Wildner return_VOID;
8490d02842fSSascha Wildner }
8500d02842fSSascha Wildner
8510d02842fSSascha Wildner /* Remove the root backslash */
8520d02842fSSascha Wildner
8531093ca81SSascha Wildner Status = AcpiDmRemoveRootPrefix (&ExternalPath);
8541093ca81SSascha Wildner if (ACPI_FAILURE (Status))
8550d02842fSSascha Wildner {
8560d02842fSSascha Wildner ACPI_FREE (ExternalPath);
8571093ca81SSascha Wildner ACPI_FREE (InternalPath);
8581093ca81SSascha Wildner return_VOID;
8590d02842fSSascha Wildner }
8600d02842fSSascha Wildner
8610d02842fSSascha Wildner /* Create the new External() declaration node */
8620d02842fSSascha Wildner
8630d02842fSSascha Wildner Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
8640d02842fSSascha Wildner Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
8650d02842fSSascha Wildner if (ACPI_FAILURE (Status))
8660d02842fSSascha Wildner {
8670d02842fSSascha Wildner ACPI_FREE (ExternalPath);
8680d02842fSSascha Wildner ACPI_FREE (InternalPath);
8690d02842fSSascha Wildner }
8700d02842fSSascha Wildner
8710d02842fSSascha Wildner return_VOID;
8720d02842fSSascha Wildner }
8730d02842fSSascha Wildner
8740d02842fSSascha Wildner
8750d02842fSSascha Wildner /*******************************************************************************
8760d02842fSSascha Wildner *
8770d02842fSSascha Wildner * FUNCTION: AcpiDmAddPathToExternalList
8780d02842fSSascha Wildner *
8790d02842fSSascha Wildner * PARAMETERS: Path - External name of the object to be added
8800d02842fSSascha Wildner * Type - ACPI object type to be added
8810d02842fSSascha Wildner * Value - Arg count if adding a Method object
8820d02842fSSascha Wildner * Flags - To be passed to the external object
8830d02842fSSascha Wildner *
8840d02842fSSascha Wildner * RETURN: None
8850d02842fSSascha Wildner *
8860d02842fSSascha Wildner * DESCRIPTION: Insert a new name into the global list of Externals which
8870d02842fSSascha Wildner * will in turn be later emitted as an External() declaration
8880d02842fSSascha Wildner * in the disassembled output.
8890d02842fSSascha Wildner *
8900d02842fSSascha Wildner * This function currently is used to add externals via a
8910d02842fSSascha Wildner * reference file (via the -fe iASL option).
8920d02842fSSascha Wildner *
8930d02842fSSascha Wildner ******************************************************************************/
8940d02842fSSascha Wildner
8950d02842fSSascha Wildner static void
AcpiDmAddPathToExternalList(char * Path,UINT8 Type,UINT32 Value,UINT16 Flags)8960d02842fSSascha Wildner AcpiDmAddPathToExternalList (
8970d02842fSSascha Wildner char *Path,
8980d02842fSSascha Wildner UINT8 Type,
8990d02842fSSascha Wildner UINT32 Value,
9000d02842fSSascha Wildner UINT16 Flags)
9010d02842fSSascha Wildner {
9020d02842fSSascha Wildner char *InternalPath;
9030d02842fSSascha Wildner char *ExternalPath;
9040d02842fSSascha Wildner ACPI_STATUS Status;
9050d02842fSSascha Wildner
9060d02842fSSascha Wildner
9070d02842fSSascha Wildner ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
9080d02842fSSascha Wildner
9090d02842fSSascha Wildner
9100d02842fSSascha Wildner if (!Path)
9110d02842fSSascha Wildner {
9120d02842fSSascha Wildner return_VOID;
9130d02842fSSascha Wildner }
9140d02842fSSascha Wildner
9150d02842fSSascha Wildner /* Remove a root backslash if present */
9160d02842fSSascha Wildner
9170d02842fSSascha Wildner if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
9180d02842fSSascha Wildner {
9190d02842fSSascha Wildner Path++;
9200d02842fSSascha Wildner }
9210d02842fSSascha Wildner
9220d02842fSSascha Wildner /* Create the internal and external pathnames */
9230d02842fSSascha Wildner
9240d02842fSSascha Wildner Status = AcpiNsInternalizeName (Path, &InternalPath);
9250d02842fSSascha Wildner if (ACPI_FAILURE (Status))
9260d02842fSSascha Wildner {
9270d02842fSSascha Wildner return_VOID;
9280d02842fSSascha Wildner }
9290d02842fSSascha Wildner
9300d02842fSSascha Wildner Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
9310d02842fSSascha Wildner NULL, &ExternalPath);
9320d02842fSSascha Wildner if (ACPI_FAILURE (Status))
9330d02842fSSascha Wildner {
9340d02842fSSascha Wildner ACPI_FREE (InternalPath);
9350d02842fSSascha Wildner return_VOID;
9360d02842fSSascha Wildner }
9370d02842fSSascha Wildner
9380d02842fSSascha Wildner /* Create the new External() declaration node */
9390d02842fSSascha Wildner
9400d02842fSSascha Wildner Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
9410d02842fSSascha Wildner Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
9420d02842fSSascha Wildner if (ACPI_FAILURE (Status))
9430d02842fSSascha Wildner {
9440d02842fSSascha Wildner ACPI_FREE (ExternalPath);
9450d02842fSSascha Wildner ACPI_FREE (InternalPath);
9460d02842fSSascha Wildner }
9470d02842fSSascha Wildner
9480d02842fSSascha Wildner return_VOID;
9490d02842fSSascha Wildner }
9500d02842fSSascha Wildner
9510d02842fSSascha Wildner
9520d02842fSSascha Wildner /*******************************************************************************
9530d02842fSSascha Wildner *
9540d02842fSSascha Wildner * FUNCTION: AcpiDmCreateNewExternal
9550d02842fSSascha Wildner *
9560d02842fSSascha Wildner * PARAMETERS: ExternalPath - External path to the object
9570d02842fSSascha Wildner * InternalPath - Internal (AML) path to the object
9580d02842fSSascha Wildner * Type - ACPI object type to be added
9590d02842fSSascha Wildner * Value - Arg count if adding a Method object
9600d02842fSSascha Wildner * Flags - To be passed to the external object
9610d02842fSSascha Wildner *
9620d02842fSSascha Wildner * RETURN: Status
9630d02842fSSascha Wildner *
9640d02842fSSascha Wildner * DESCRIPTION: Common low-level function to insert a new name into the global
9650d02842fSSascha Wildner * list of Externals which will in turn be later emitted as
9660d02842fSSascha Wildner * External() declarations in the disassembled output.
9670d02842fSSascha Wildner *
9680d02842fSSascha Wildner * Note: The external name should not include a root prefix
9690d02842fSSascha Wildner * (backslash). We do not want External() statements to contain
9700d02842fSSascha Wildner * a leading '\', as this prevents duplicate external statements
9710d02842fSSascha Wildner * of the form:
9720d02842fSSascha Wildner *
9730d02842fSSascha Wildner * External (\ABCD)
9740d02842fSSascha Wildner * External (ABCD)
9750d02842fSSascha Wildner *
9760d02842fSSascha Wildner * This would cause a compile time error when the disassembled
9770d02842fSSascha Wildner * output file is recompiled.
9780d02842fSSascha Wildner *
9790d02842fSSascha Wildner * There are two cases that are handled here. For both, we emit
9800d02842fSSascha Wildner * an External() statement:
9810d02842fSSascha Wildner * 1) The name was simply not found in the namespace.
9820d02842fSSascha Wildner * 2) The name was found, but it originated in a table other than
9830d02842fSSascha Wildner * the table that is being disassembled.
9840d02842fSSascha Wildner *
9850d02842fSSascha Wildner ******************************************************************************/
9860d02842fSSascha Wildner
9870d02842fSSascha Wildner static ACPI_STATUS
AcpiDmCreateNewExternal(char * ExternalPath,char * InternalPath,UINT8 Type,UINT32 Value,UINT16 Flags)9880d02842fSSascha Wildner AcpiDmCreateNewExternal (
9890d02842fSSascha Wildner char *ExternalPath,
9900d02842fSSascha Wildner char *InternalPath,
9910d02842fSSascha Wildner UINT8 Type,
9920d02842fSSascha Wildner UINT32 Value,
9930d02842fSSascha Wildner UINT16 Flags)
9940d02842fSSascha Wildner {
9950d02842fSSascha Wildner ACPI_EXTERNAL_LIST *NewExternal;
9960d02842fSSascha Wildner ACPI_EXTERNAL_LIST *NextExternal;
9970d02842fSSascha Wildner ACPI_EXTERNAL_LIST *PrevExternal = NULL;
9980d02842fSSascha Wildner
9990d02842fSSascha Wildner
10000d02842fSSascha Wildner ACPI_FUNCTION_TRACE (DmCreateNewExternal);
10010d02842fSSascha Wildner
10020d02842fSSascha Wildner
10030d02842fSSascha Wildner /* Check all existing externals to ensure no duplicates */
10040d02842fSSascha Wildner
10050d02842fSSascha Wildner NextExternal = AcpiGbl_ExternalList;
10060d02842fSSascha Wildner while (NextExternal)
10070d02842fSSascha Wildner {
10087c9678bcSSascha Wildner /* Check for duplicates */
10097c9678bcSSascha Wildner
10102ffe9f16SSascha Wildner if (!strcmp (ExternalPath, NextExternal->Path))
10110d02842fSSascha Wildner {
10122ffe9f16SSascha Wildner /*
10132ffe9f16SSascha Wildner * If this external came from an External() opcode, we are
10142ffe9f16SSascha Wildner * finished with this one. (No need to check any further).
10152ffe9f16SSascha Wildner */
10162ffe9f16SSascha Wildner if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
10170d02842fSSascha Wildner {
10182ffe9f16SSascha Wildner return_ACPI_STATUS (AE_ALREADY_EXISTS);
10190d02842fSSascha Wildner }
10200d02842fSSascha Wildner
10210d02842fSSascha Wildner /* Allow upgrade of type from ANY */
10220d02842fSSascha Wildner
10232ffe9f16SSascha Wildner else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
10242ffe9f16SSascha Wildner (Type != ACPI_TYPE_ANY))
10250d02842fSSascha Wildner {
10260d02842fSSascha Wildner NextExternal->Type = Type;
10272ffe9f16SSascha Wildner }
10282ffe9f16SSascha Wildner
10292ffe9f16SSascha Wildner /* Update the argument count as necessary */
10302ffe9f16SSascha Wildner
10312ffe9f16SSascha Wildner if (Value < NextExternal->Value)
10322ffe9f16SSascha Wildner {
10330d02842fSSascha Wildner NextExternal->Value = Value;
10340d02842fSSascha Wildner }
10350d02842fSSascha Wildner
10367c9678bcSSascha Wildner /* Update flags. */
10377c9678bcSSascha Wildner
10387c9678bcSSascha Wildner NextExternal->Flags |= Flags;
10397c9678bcSSascha Wildner NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
10407c9678bcSSascha Wildner
10410d02842fSSascha Wildner return_ACPI_STATUS (AE_ALREADY_EXISTS);
10420d02842fSSascha Wildner }
10430d02842fSSascha Wildner
10440d02842fSSascha Wildner NextExternal = NextExternal->Next;
10450d02842fSSascha Wildner }
10460d02842fSSascha Wildner
10470d02842fSSascha Wildner /* Allocate and init a new External() descriptor */
10480d02842fSSascha Wildner
10490d02842fSSascha Wildner NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
10500d02842fSSascha Wildner if (!NewExternal)
10510d02842fSSascha Wildner {
10520d02842fSSascha Wildner return_ACPI_STATUS (AE_NO_MEMORY);
10530d02842fSSascha Wildner }
10540d02842fSSascha Wildner
10550d02842fSSascha Wildner ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
10560d02842fSSascha Wildner "Adding external reference node (%s) type [%s]\n",
10570d02842fSSascha Wildner ExternalPath, AcpiUtGetTypeName (Type)));
10580d02842fSSascha Wildner
10590d02842fSSascha Wildner NewExternal->Flags = Flags;
10600d02842fSSascha Wildner NewExternal->Value = Value;
10610d02842fSSascha Wildner NewExternal->Path = ExternalPath;
10620d02842fSSascha Wildner NewExternal->Type = Type;
106325ca8c79SSascha Wildner NewExternal->Length = (UINT16) strlen (ExternalPath);
10640d02842fSSascha Wildner NewExternal->InternalPath = InternalPath;
10650d02842fSSascha Wildner
10660d02842fSSascha Wildner /* Link the new descriptor into the global list, alphabetically ordered */
10670d02842fSSascha Wildner
10680d02842fSSascha Wildner NextExternal = AcpiGbl_ExternalList;
10690d02842fSSascha Wildner while (NextExternal)
10700d02842fSSascha Wildner {
10710d02842fSSascha Wildner if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
10720d02842fSSascha Wildner {
10730d02842fSSascha Wildner if (PrevExternal)
10740d02842fSSascha Wildner {
10750d02842fSSascha Wildner PrevExternal->Next = NewExternal;
10760d02842fSSascha Wildner }
10770d02842fSSascha Wildner else
10780d02842fSSascha Wildner {
10790d02842fSSascha Wildner AcpiGbl_ExternalList = NewExternal;
10800d02842fSSascha Wildner }
10810d02842fSSascha Wildner
10820d02842fSSascha Wildner NewExternal->Next = NextExternal;
10830d02842fSSascha Wildner return_ACPI_STATUS (AE_OK);
10840d02842fSSascha Wildner }
10850d02842fSSascha Wildner
10860d02842fSSascha Wildner PrevExternal = NextExternal;
10870d02842fSSascha Wildner NextExternal = NextExternal->Next;
10880d02842fSSascha Wildner }
10890d02842fSSascha Wildner
10900d02842fSSascha Wildner if (PrevExternal)
10910d02842fSSascha Wildner {
10920d02842fSSascha Wildner PrevExternal->Next = NewExternal;
10930d02842fSSascha Wildner }
10940d02842fSSascha Wildner else
10950d02842fSSascha Wildner {
10960d02842fSSascha Wildner AcpiGbl_ExternalList = NewExternal;
10970d02842fSSascha Wildner }
10980d02842fSSascha Wildner
10990d02842fSSascha Wildner return_ACPI_STATUS (AE_OK);
11000d02842fSSascha Wildner }
11010d02842fSSascha Wildner
11020d02842fSSascha Wildner
11030d02842fSSascha Wildner /*******************************************************************************
11040d02842fSSascha Wildner *
11051093ca81SSascha Wildner * FUNCTION: AcpiDmResolveExternal
11060d02842fSSascha Wildner *
11071093ca81SSascha Wildner * PARAMETERS: Path - Path of the external
11081093ca81SSascha Wildner * Type - Type of the external
11091093ca81SSascha Wildner * Node - Input node for AcpiNsLookup
11101093ca81SSascha Wildner *
11111093ca81SSascha Wildner * RETURN: Status
11121093ca81SSascha Wildner *
11131093ca81SSascha Wildner * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.
11141093ca81SSascha Wildner * If the returned node is an external and has the same type
11151093ca81SSascha Wildner * we assume that it was either an existing external or a
11161093ca81SSascha Wildner *
11171093ca81SSascha Wildner ******************************************************************************/
11181093ca81SSascha Wildner
11191093ca81SSascha Wildner static ACPI_STATUS
AcpiDmResolveExternal(char * Path,UINT8 Type,ACPI_NAMESPACE_NODE ** Node)11201093ca81SSascha Wildner AcpiDmResolveExternal (
11211093ca81SSascha Wildner char *Path,
11221093ca81SSascha Wildner UINT8 Type,
11231093ca81SSascha Wildner ACPI_NAMESPACE_NODE **Node)
11241093ca81SSascha Wildner {
11251093ca81SSascha Wildner ACPI_STATUS Status;
11261093ca81SSascha Wildner
11271093ca81SSascha Wildner
11281093ca81SSascha Wildner Status = AcpiNsLookup (NULL, Path, Type,
11291093ca81SSascha Wildner ACPI_IMODE_LOAD_PASS1,
11301093ca81SSascha Wildner ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
11311093ca81SSascha Wildner NULL, Node);
11321093ca81SSascha Wildner
11331093ca81SSascha Wildner if (!Node)
11341093ca81SSascha Wildner {
11351093ca81SSascha Wildner ACPI_EXCEPTION ((AE_INFO, Status,
11361093ca81SSascha Wildner "while adding external to namespace [%s]", Path));
11371093ca81SSascha Wildner }
11381093ca81SSascha Wildner
11391093ca81SSascha Wildner /* Note the asl code "external(a) external(a)" is acceptable ASL */
11401093ca81SSascha Wildner
11411093ca81SSascha Wildner else if ((*Node)->Type == Type &&
11421093ca81SSascha Wildner (*Node)->Flags & ANOBJ_IS_EXTERNAL)
11431093ca81SSascha Wildner {
11441093ca81SSascha Wildner return (AE_OK);
11451093ca81SSascha Wildner }
11461093ca81SSascha Wildner else
11471093ca81SSascha Wildner {
11481093ca81SSascha Wildner ACPI_EXCEPTION ((AE_INFO, AE_ERROR,
11491093ca81SSascha Wildner "[%s] has conflicting declarations", Path));
11501093ca81SSascha Wildner }
11511093ca81SSascha Wildner
11521093ca81SSascha Wildner return (AE_ERROR);
11531093ca81SSascha Wildner }
11541093ca81SSascha Wildner
11551093ca81SSascha Wildner
11561093ca81SSascha Wildner /*******************************************************************************
11571093ca81SSascha Wildner *
11581093ca81SSascha Wildner * FUNCTION: AcpiDmCreateSubobjectForExternal
11591093ca81SSascha Wildner *
11601093ca81SSascha Wildner * PARAMETERS: Type - Type of the external
11611093ca81SSascha Wildner * Node - Namespace node from AcpiNsLookup
11621093ca81SSascha Wildner * ParamCount - Value to be used for Method
11630d02842fSSascha Wildner *
11640d02842fSSascha Wildner * RETURN: None
11650d02842fSSascha Wildner *
11661093ca81SSascha Wildner * DESCRIPTION: Add one external to the namespace. Allows external to be
11670d02842fSSascha Wildner * "resolved".
11680d02842fSSascha Wildner *
11690d02842fSSascha Wildner ******************************************************************************/
11700d02842fSSascha Wildner
11710d02842fSSascha Wildner void
AcpiDmCreateSubobjectForExternal(UINT8 Type,ACPI_NAMESPACE_NODE ** Node,UINT32 ParamCount)11721093ca81SSascha Wildner AcpiDmCreateSubobjectForExternal (
11731093ca81SSascha Wildner UINT8 Type,
11741093ca81SSascha Wildner ACPI_NAMESPACE_NODE **Node,
11751093ca81SSascha Wildner UINT32 ParamCount)
11760d02842fSSascha Wildner {
11770d02842fSSascha Wildner ACPI_OPERAND_OBJECT *ObjDesc;
11780d02842fSSascha Wildner
11790d02842fSSascha Wildner
11801093ca81SSascha Wildner switch (Type)
11810d02842fSSascha Wildner {
11820d02842fSSascha Wildner case ACPI_TYPE_METHOD:
11830d02842fSSascha Wildner
11840d02842fSSascha Wildner /* For methods, we need to save the argument count */
11850d02842fSSascha Wildner
11860d02842fSSascha Wildner ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
11871093ca81SSascha Wildner ObjDesc->Method.ParamCount = (UINT8) ParamCount;
11881093ca81SSascha Wildner (*Node)->Object = ObjDesc;
11890d02842fSSascha Wildner break;
11900d02842fSSascha Wildner
11910d02842fSSascha Wildner case ACPI_TYPE_REGION:
11920d02842fSSascha Wildner
11930d02842fSSascha Wildner /* Regions require a region sub-object */
11940d02842fSSascha Wildner
11950d02842fSSascha Wildner ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
11961093ca81SSascha Wildner ObjDesc->Region.Node = *Node;
11971093ca81SSascha Wildner (*Node)->Object = ObjDesc;
11980d02842fSSascha Wildner break;
11990d02842fSSascha Wildner
12000d02842fSSascha Wildner default:
12010d02842fSSascha Wildner
12020d02842fSSascha Wildner break;
12030d02842fSSascha Wildner }
12041093ca81SSascha Wildner }
12050d02842fSSascha Wildner
12061093ca81SSascha Wildner
12071093ca81SSascha Wildner /*******************************************************************************
12081093ca81SSascha Wildner *
12091093ca81SSascha Wildner * FUNCTION: AcpiDmAddOneExternalToNamespace
12101093ca81SSascha Wildner *
12111093ca81SSascha Wildner * PARAMETERS: Path - External parse object
12121093ca81SSascha Wildner * Type - Type of parse object
12131093ca81SSascha Wildner * ParamCount - External method parameter count
12141093ca81SSascha Wildner *
12151093ca81SSascha Wildner * RETURN: None
12161093ca81SSascha Wildner *
12171093ca81SSascha Wildner * DESCRIPTION: Add one external to the namespace by resolvign the external
12181093ca81SSascha Wildner * (by performing a namespace lookup) and annotating the resulting
121900ffa116SSascha Wildner * namespace node with the appropriate information if the type
12201093ca81SSascha Wildner * is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
12211093ca81SSascha Wildner *
12221093ca81SSascha Wildner ******************************************************************************/
12231093ca81SSascha Wildner
12241093ca81SSascha Wildner void
AcpiDmAddOneExternalToNamespace(char * Path,UINT8 Type,UINT32 ParamCount)12251093ca81SSascha Wildner AcpiDmAddOneExternalToNamespace (
12261093ca81SSascha Wildner char *Path,
12271093ca81SSascha Wildner UINT8 Type,
12281093ca81SSascha Wildner UINT32 ParamCount)
12291093ca81SSascha Wildner {
12301093ca81SSascha Wildner ACPI_STATUS Status;
12311093ca81SSascha Wildner ACPI_NAMESPACE_NODE *Node;
12321093ca81SSascha Wildner
12331093ca81SSascha Wildner
12341093ca81SSascha Wildner Status = AcpiDmResolveExternal (Path, Type, &Node);
12351093ca81SSascha Wildner
12361093ca81SSascha Wildner if (ACPI_FAILURE (Status))
12371093ca81SSascha Wildner {
12381093ca81SSascha Wildner return;
12391093ca81SSascha Wildner }
12401093ca81SSascha Wildner
12411093ca81SSascha Wildner AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);
12421093ca81SSascha Wildner
12431093ca81SSascha Wildner }
12441093ca81SSascha Wildner
12451093ca81SSascha Wildner
12461093ca81SSascha Wildner /*******************************************************************************
12471093ca81SSascha Wildner *
12481093ca81SSascha Wildner * FUNCTION: AcpiDmAddExternalListToNamespace
12491093ca81SSascha Wildner *
12501093ca81SSascha Wildner * PARAMETERS: None
12511093ca81SSascha Wildner *
12521093ca81SSascha Wildner * RETURN: None
12531093ca81SSascha Wildner *
12541093ca81SSascha Wildner * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.
12551093ca81SSascha Wildner * Allows externals to be "resolved".
12561093ca81SSascha Wildner *
12571093ca81SSascha Wildner ******************************************************************************/
12581093ca81SSascha Wildner
12591093ca81SSascha Wildner void
AcpiDmAddExternalListToNamespace(void)12601093ca81SSascha Wildner AcpiDmAddExternalListToNamespace (
12611093ca81SSascha Wildner void)
12621093ca81SSascha Wildner {
12631093ca81SSascha Wildner ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
12641093ca81SSascha Wildner
12651093ca81SSascha Wildner
12661093ca81SSascha Wildner while (External)
12671093ca81SSascha Wildner {
12681093ca81SSascha Wildner AcpiDmAddOneExternalToNamespace (External->InternalPath,
12691093ca81SSascha Wildner External->Type, External->Value);
12700d02842fSSascha Wildner External = External->Next;
12710d02842fSSascha Wildner }
12720d02842fSSascha Wildner }
12730d02842fSSascha Wildner
12740d02842fSSascha Wildner
12750d02842fSSascha Wildner /*******************************************************************************
12760d02842fSSascha Wildner *
12771093ca81SSascha Wildner * FUNCTION: AcpiDmGetUnresolvedExternalMethodCount
12780d02842fSSascha Wildner *
12790d02842fSSascha Wildner * PARAMETERS: None
12800d02842fSSascha Wildner *
12811093ca81SSascha Wildner * RETURN: The number of unresolved control method externals in the
12821093ca81SSascha Wildner * external list
12830d02842fSSascha Wildner *
12841093ca81SSascha Wildner * DESCRIPTION: Return the number of unresolved external methods that have been
12851093ca81SSascha Wildner * generated. If any unresolved control method externals have been
12861093ca81SSascha Wildner * found, we must re-parse the entire definition block with the new
12871093ca81SSascha Wildner * information (number of arguments for the methods.)
12881093ca81SSascha Wildner * This is limitation of AML, we don't know the number of arguments
12891093ca81SSascha Wildner * from the control method invocation itself.
12901093ca81SSascha Wildner *
12911093ca81SSascha Wildner * Note: resolved external control methods are external control
12921093ca81SSascha Wildner * methods encoded with the AML_EXTERNAL_OP bytecode within the
12931093ca81SSascha Wildner * AML being disassembled.
12940d02842fSSascha Wildner *
12950d02842fSSascha Wildner ******************************************************************************/
12960d02842fSSascha Wildner
12970d02842fSSascha Wildner UINT32
AcpiDmGetUnresolvedExternalMethodCount(void)12981093ca81SSascha Wildner AcpiDmGetUnresolvedExternalMethodCount (
12990d02842fSSascha Wildner void)
13000d02842fSSascha Wildner {
13010d02842fSSascha Wildner ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
13020d02842fSSascha Wildner UINT32 Count = 0;
13030d02842fSSascha Wildner
13040d02842fSSascha Wildner
13050d02842fSSascha Wildner while (External)
13060d02842fSSascha Wildner {
13071093ca81SSascha Wildner if (External->Type == ACPI_TYPE_METHOD &&
13081093ca81SSascha Wildner !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))
13090d02842fSSascha Wildner {
13100d02842fSSascha Wildner Count++;
13110d02842fSSascha Wildner }
13120d02842fSSascha Wildner
13130d02842fSSascha Wildner External = External->Next;
13140d02842fSSascha Wildner }
13150d02842fSSascha Wildner
13160d02842fSSascha Wildner return (Count);
13170d02842fSSascha Wildner }
13180d02842fSSascha Wildner
13190d02842fSSascha Wildner
13200d02842fSSascha Wildner /*******************************************************************************
13210d02842fSSascha Wildner *
13220d02842fSSascha Wildner * FUNCTION: AcpiDmClearExternalList
13230d02842fSSascha Wildner *
13240d02842fSSascha Wildner * PARAMETERS: None
13250d02842fSSascha Wildner *
13260d02842fSSascha Wildner * RETURN: None
13270d02842fSSascha Wildner *
13280d02842fSSascha Wildner * DESCRIPTION: Free the entire External info list
13290d02842fSSascha Wildner *
13300d02842fSSascha Wildner ******************************************************************************/
13310d02842fSSascha Wildner
13320d02842fSSascha Wildner void
AcpiDmClearExternalList(void)13330d02842fSSascha Wildner AcpiDmClearExternalList (
13340d02842fSSascha Wildner void)
13350d02842fSSascha Wildner {
13360d02842fSSascha Wildner ACPI_EXTERNAL_LIST *NextExternal;
13370d02842fSSascha Wildner
13380d02842fSSascha Wildner
13390d02842fSSascha Wildner while (AcpiGbl_ExternalList)
13400d02842fSSascha Wildner {
13410d02842fSSascha Wildner NextExternal = AcpiGbl_ExternalList->Next;
13420d02842fSSascha Wildner ACPI_FREE (AcpiGbl_ExternalList->Path);
13430d02842fSSascha Wildner ACPI_FREE (AcpiGbl_ExternalList);
13440d02842fSSascha Wildner AcpiGbl_ExternalList = NextExternal;
13450d02842fSSascha Wildner }
13460d02842fSSascha Wildner }
13470d02842fSSascha Wildner
13480d02842fSSascha Wildner
13490d02842fSSascha Wildner /*******************************************************************************
13500d02842fSSascha Wildner *
13510d02842fSSascha Wildner * FUNCTION: AcpiDmEmitExternals
13520d02842fSSascha Wildner *
13530d02842fSSascha Wildner * PARAMETERS: None
13540d02842fSSascha Wildner *
13550d02842fSSascha Wildner * RETURN: None
13560d02842fSSascha Wildner *
13570d02842fSSascha Wildner * DESCRIPTION: Emit an External() ASL statement for each of the externals in
13580d02842fSSascha Wildner * the global external info list.
13590d02842fSSascha Wildner *
13600d02842fSSascha Wildner ******************************************************************************/
13610d02842fSSascha Wildner
13620d02842fSSascha Wildner void
AcpiDmEmitExternals(void)13630d02842fSSascha Wildner AcpiDmEmitExternals (
13640d02842fSSascha Wildner void)
13650d02842fSSascha Wildner {
13660d02842fSSascha Wildner ACPI_EXTERNAL_LIST *NextExternal;
13670d02842fSSascha Wildner
13680d02842fSSascha Wildner
13690d02842fSSascha Wildner if (!AcpiGbl_ExternalList)
13700d02842fSSascha Wildner {
13710d02842fSSascha Wildner return;
13720d02842fSSascha Wildner }
13730d02842fSSascha Wildner
13740d02842fSSascha Wildner /*
13750d02842fSSascha Wildner * Determine the number of control methods in the external list, and
13760d02842fSSascha Wildner * also how many of those externals were resolved via the namespace.
13770d02842fSSascha Wildner */
13780d02842fSSascha Wildner NextExternal = AcpiGbl_ExternalList;
13790d02842fSSascha Wildner while (NextExternal)
13800d02842fSSascha Wildner {
13810d02842fSSascha Wildner if (NextExternal->Type == ACPI_TYPE_METHOD)
13820d02842fSSascha Wildner {
13830d02842fSSascha Wildner AcpiGbl_NumExternalMethods++;
13840d02842fSSascha Wildner if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
13850d02842fSSascha Wildner {
13860d02842fSSascha Wildner AcpiGbl_ResolvedExternalMethods++;
13870d02842fSSascha Wildner }
13880d02842fSSascha Wildner }
13890d02842fSSascha Wildner
13900d02842fSSascha Wildner NextExternal = NextExternal->Next;
13910d02842fSSascha Wildner }
13920d02842fSSascha Wildner
13930d02842fSSascha Wildner /* Check if any control methods were unresolved */
13940d02842fSSascha Wildner
13950d02842fSSascha Wildner AcpiDmUnresolvedWarning (1);
13960d02842fSSascha Wildner
1397806343b9SSascha Wildner if (AslGbl_ExternalRefFilename)
13980d02842fSSascha Wildner {
13990d02842fSSascha Wildner AcpiOsPrintf (
14002ffe9f16SSascha Wildner " /*\n * External declarations were imported from\n"
14012ffe9f16SSascha Wildner " * a reference file -- %s\n */\n\n",
1402806343b9SSascha Wildner AslGbl_ExternalRefFilename);
14030d02842fSSascha Wildner }
14040d02842fSSascha Wildner
14050d02842fSSascha Wildner /*
14062ffe9f16SSascha Wildner * Walk and emit the list of externals found during the AML parsing
14070d02842fSSascha Wildner */
14080d02842fSSascha Wildner while (AcpiGbl_ExternalList)
14090d02842fSSascha Wildner {
14100d02842fSSascha Wildner if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
14110d02842fSSascha Wildner {
14122ffe9f16SSascha Wildner AcpiOsPrintf (" External (%s%s)",
14130d02842fSSascha Wildner AcpiGbl_ExternalList->Path,
14140d02842fSSascha Wildner AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
14150d02842fSSascha Wildner
14162ffe9f16SSascha Wildner /* Check for "unresolved" method reference */
14172ffe9f16SSascha Wildner
14182ffe9f16SSascha Wildner if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
14192ffe9f16SSascha Wildner (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
14202ffe9f16SSascha Wildner {
14212ffe9f16SSascha Wildner AcpiOsPrintf (" // Warning: Unknown method, "
14222ffe9f16SSascha Wildner "guessing %u arguments",
14232ffe9f16SSascha Wildner AcpiGbl_ExternalList->Value);
14242ffe9f16SSascha Wildner }
14252ffe9f16SSascha Wildner
14262ffe9f16SSascha Wildner /* Check for external from a external references file */
14272ffe9f16SSascha Wildner
14282ffe9f16SSascha Wildner else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
14292ffe9f16SSascha Wildner {
14302ffe9f16SSascha Wildner if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
14312ffe9f16SSascha Wildner {
14322ffe9f16SSascha Wildner AcpiOsPrintf (" // %u Arguments",
14332ffe9f16SSascha Wildner AcpiGbl_ExternalList->Value);
14342ffe9f16SSascha Wildner }
14352ffe9f16SSascha Wildner
14362ffe9f16SSascha Wildner AcpiOsPrintf (" // From external reference file");
14372ffe9f16SSascha Wildner }
14382ffe9f16SSascha Wildner
14392ffe9f16SSascha Wildner /* This is the normal external case */
14402ffe9f16SSascha Wildner
14412ffe9f16SSascha Wildner else
14422ffe9f16SSascha Wildner {
14430d02842fSSascha Wildner /* For methods, add a comment with the number of arguments */
14440d02842fSSascha Wildner
14450d02842fSSascha Wildner if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
14460d02842fSSascha Wildner {
14472ffe9f16SSascha Wildner AcpiOsPrintf (" // %u Arguments",
14480d02842fSSascha Wildner AcpiGbl_ExternalList->Value);
14490d02842fSSascha Wildner }
14500d02842fSSascha Wildner }
14512ffe9f16SSascha Wildner
14521093ca81SSascha Wildner if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)
14531093ca81SSascha Wildner {
14541093ca81SSascha Wildner AcpiOsPrintf ("%s", ExternalConflictMessage);
14551093ca81SSascha Wildner AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);
14561093ca81SSascha Wildner }
14572ffe9f16SSascha Wildner AcpiOsPrintf ("\n");
14580d02842fSSascha Wildner }
14590d02842fSSascha Wildner
14600d02842fSSascha Wildner /* Free this external info block and move on to next external */
14610d02842fSSascha Wildner
14620d02842fSSascha Wildner NextExternal = AcpiGbl_ExternalList->Next;
14630d02842fSSascha Wildner if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
14640d02842fSSascha Wildner {
14650d02842fSSascha Wildner ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
14660d02842fSSascha Wildner }
14670d02842fSSascha Wildner
14680d02842fSSascha Wildner ACPI_FREE (AcpiGbl_ExternalList->Path);
14690d02842fSSascha Wildner ACPI_FREE (AcpiGbl_ExternalList);
14700d02842fSSascha Wildner AcpiGbl_ExternalList = NextExternal;
14710d02842fSSascha Wildner }
14720d02842fSSascha Wildner
14730d02842fSSascha Wildner AcpiOsPrintf ("\n");
14740d02842fSSascha Wildner }
14750d02842fSSascha Wildner
14760d02842fSSascha Wildner
14770d02842fSSascha Wildner /*******************************************************************************
14780d02842fSSascha Wildner *
14791093ca81SSascha Wildner * FUNCTION: AcpiDmMarkExternalConflict
14801093ca81SSascha Wildner *
14811093ca81SSascha Wildner * PARAMETERS: Path - Namepath to search
14821093ca81SSascha Wildner *
14831093ca81SSascha Wildner * RETURN: ExternalList
14841093ca81SSascha Wildner *
14851093ca81SSascha Wildner * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path
14861093ca81SSascha Wildner *
14871093ca81SSascha Wildner ******************************************************************************/
14881093ca81SSascha Wildner
14891093ca81SSascha Wildner void
AcpiDmMarkExternalConflict(ACPI_NAMESPACE_NODE * Node)14901093ca81SSascha Wildner AcpiDmMarkExternalConflict (
14911093ca81SSascha Wildner ACPI_NAMESPACE_NODE *Node)
14921093ca81SSascha Wildner {
14931093ca81SSascha Wildner ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
14941093ca81SSascha Wildner char *ExternalPath;
14951093ca81SSascha Wildner char *InternalPath;
14961093ca81SSascha Wildner char *Temp;
14971093ca81SSascha Wildner ACPI_STATUS Status;
14981093ca81SSascha Wildner
14991093ca81SSascha Wildner
15001093ca81SSascha Wildner ACPI_FUNCTION_TRACE (DmMarkExternalConflict);
15011093ca81SSascha Wildner
15021093ca81SSascha Wildner
15031093ca81SSascha Wildner if (Node->Flags & ANOBJ_IS_EXTERNAL)
15041093ca81SSascha Wildner {
15051093ca81SSascha Wildner return_VOID;
15061093ca81SSascha Wildner }
15071093ca81SSascha Wildner
15081093ca81SSascha Wildner /* Get the full external and internal pathnames to the node */
15091093ca81SSascha Wildner
15101093ca81SSascha Wildner Status = AcpiDmGetExternalAndInternalPath (Node,
15111093ca81SSascha Wildner &ExternalPath, &InternalPath);
15121093ca81SSascha Wildner if (ACPI_FAILURE (Status))
15131093ca81SSascha Wildner {
15141093ca81SSascha Wildner return_VOID;
15151093ca81SSascha Wildner }
15161093ca81SSascha Wildner
15171093ca81SSascha Wildner /* Remove the root backslash */
15181093ca81SSascha Wildner
15191093ca81SSascha Wildner Status = AcpiDmRemoveRootPrefix (&InternalPath);
15201093ca81SSascha Wildner if (ACPI_FAILURE (Status))
15211093ca81SSascha Wildner {
15221093ca81SSascha Wildner ACPI_FREE (InternalPath);
15231093ca81SSascha Wildner ACPI_FREE (ExternalPath);
15241093ca81SSascha Wildner return_VOID;
15251093ca81SSascha Wildner }
15261093ca81SSascha Wildner
15271093ca81SSascha Wildner while (ExternalList)
15281093ca81SSascha Wildner {
15291093ca81SSascha Wildner Temp = ExternalList->InternalPath;
15301093ca81SSascha Wildner if ((*ExternalList->InternalPath == AML_ROOT_PREFIX) &&
15311093ca81SSascha Wildner (ExternalList->InternalPath[1]))
15321093ca81SSascha Wildner {
15331093ca81SSascha Wildner Temp++;
15341093ca81SSascha Wildner }
15351093ca81SSascha Wildner
15361093ca81SSascha Wildner if (!strcmp (ExternalList->InternalPath, InternalPath))
15371093ca81SSascha Wildner {
15381093ca81SSascha Wildner ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;
15391093ca81SSascha Wildner }
15401093ca81SSascha Wildner ExternalList = ExternalList->Next;
15411093ca81SSascha Wildner }
15421093ca81SSascha Wildner
15431093ca81SSascha Wildner ACPI_FREE (InternalPath);
15441093ca81SSascha Wildner ACPI_FREE (ExternalPath);
15451093ca81SSascha Wildner
15461093ca81SSascha Wildner return_VOID;
15471093ca81SSascha Wildner }
15481093ca81SSascha Wildner
15491093ca81SSascha Wildner
15501093ca81SSascha Wildner /*******************************************************************************
15511093ca81SSascha Wildner *
15521093ca81SSascha Wildner * FUNCTION: AcpiDmConflictingDeclaration
15531093ca81SSascha Wildner *
15541093ca81SSascha Wildner * PARAMETERS: Path - Path with conflicting declaration
15551093ca81SSascha Wildner *
15561093ca81SSascha Wildner * RETURN: None
15571093ca81SSascha Wildner *
15581093ca81SSascha Wildner * DESCRIPTION: Emit a warning when printing conflicting ASL external
15591093ca81SSascha Wildner * declarations.
15601093ca81SSascha Wildner *
15611093ca81SSascha Wildner ******************************************************************************/
15621093ca81SSascha Wildner
15631093ca81SSascha Wildner static void
AcpiDmConflictingDeclaration(char * Path)15641093ca81SSascha Wildner AcpiDmConflictingDeclaration (
15651093ca81SSascha Wildner char *Path)
15661093ca81SSascha Wildner {
15671093ca81SSascha Wildner fprintf (stderr,
15681093ca81SSascha Wildner " Warning - Emitting ASL code \"External (%s)\"\n"
15691093ca81SSascha Wildner " This is a conflicting declaration with some "
15701093ca81SSascha Wildner "other declaration within the ASL code.\n"
15711093ca81SSascha Wildner " This external declaration may need to be "
15721093ca81SSascha Wildner "deleted in order to recompile the dsl file.\n\n",
15731093ca81SSascha Wildner Path);
15741093ca81SSascha Wildner }
15751093ca81SSascha Wildner
15761093ca81SSascha Wildner
15771093ca81SSascha Wildner /*******************************************************************************
15781093ca81SSascha Wildner *
1579d638c6eeSSascha Wildner * FUNCTION: AcpiDmEmitExternal
1580d638c6eeSSascha Wildner *
1581d638c6eeSSascha Wildner * PARAMETERS: Op External Parse Object
1582d638c6eeSSascha Wildner *
1583d638c6eeSSascha Wildner * RETURN: None
1584d638c6eeSSascha Wildner *
1585d638c6eeSSascha Wildner * DESCRIPTION: Emit an External() ASL statement for the current External
15861093ca81SSascha Wildner * parse object. Note: External Ops are named types so the
15871093ca81SSascha Wildner * namepath is contained within NameOp->Name.Path.
1588d638c6eeSSascha Wildner *
1589d638c6eeSSascha Wildner ******************************************************************************/
1590d638c6eeSSascha Wildner
1591d638c6eeSSascha Wildner void
AcpiDmEmitExternal(ACPI_PARSE_OBJECT * NameOp,ACPI_PARSE_OBJECT * TypeOp)1592d638c6eeSSascha Wildner AcpiDmEmitExternal (
1593d638c6eeSSascha Wildner ACPI_PARSE_OBJECT *NameOp,
1594d638c6eeSSascha Wildner ACPI_PARSE_OBJECT *TypeOp)
1595d638c6eeSSascha Wildner {
1596d638c6eeSSascha Wildner AcpiOsPrintf ("External (");
15971093ca81SSascha Wildner AcpiDmNamestring (NameOp->Named.Path);
15981093ca81SSascha Wildner AcpiOsPrintf ("%s)",
1599d638c6eeSSascha Wildner AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
16001093ca81SSascha Wildner AcpiDmCheckForExternalConflict (NameOp->Named.Path);
16011093ca81SSascha Wildner AcpiOsPrintf ("\n");
1602d638c6eeSSascha Wildner }
1603d638c6eeSSascha Wildner
1604d638c6eeSSascha Wildner
1605d638c6eeSSascha Wildner /*******************************************************************************
1606d638c6eeSSascha Wildner *
16071093ca81SSascha Wildner * FUNCTION: AcpiDmCheckForExternalConflict
16081093ca81SSascha Wildner *
16091093ca81SSascha Wildner * PARAMETERS: Path - Path to check
16101093ca81SSascha Wildner *
16111093ca81SSascha Wildner * RETURN: None
16121093ca81SSascha Wildner *
16131093ca81SSascha Wildner * DESCRIPTION: Search the External List to see if the input Path has a
16141093ca81SSascha Wildner * conflicting declaration.
16151093ca81SSascha Wildner *
16161093ca81SSascha Wildner ******************************************************************************/
16171093ca81SSascha Wildner
16181093ca81SSascha Wildner static void
AcpiDmCheckForExternalConflict(char * Path)16191093ca81SSascha Wildner AcpiDmCheckForExternalConflict (
16201093ca81SSascha Wildner char *Path)
16211093ca81SSascha Wildner {
16221093ca81SSascha Wildner ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
16231093ca81SSascha Wildner char *ListItemPath;
16241093ca81SSascha Wildner char *InputPath;
16251093ca81SSascha Wildner
16261093ca81SSascha Wildner
16271093ca81SSascha Wildner if (!Path)
16281093ca81SSascha Wildner {
16291093ca81SSascha Wildner return;
16301093ca81SSascha Wildner }
16311093ca81SSascha Wildner
16321093ca81SSascha Wildner /* Move past the root prefix '\' */
16331093ca81SSascha Wildner
16341093ca81SSascha Wildner InputPath = Path;
16351093ca81SSascha Wildner if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])
16361093ca81SSascha Wildner {
16371093ca81SSascha Wildner InputPath++;
16381093ca81SSascha Wildner }
16391093ca81SSascha Wildner
16401093ca81SSascha Wildner while (ExternalList)
16411093ca81SSascha Wildner {
16421093ca81SSascha Wildner ListItemPath = ExternalList->Path;
16431093ca81SSascha Wildner if (ListItemPath)
16441093ca81SSascha Wildner {
16451093ca81SSascha Wildner /* Move past the root prefix '\' */
16461093ca81SSascha Wildner
16471093ca81SSascha Wildner if ((*ListItemPath == AML_ROOT_PREFIX) &&
16481093ca81SSascha Wildner ListItemPath[1])
16491093ca81SSascha Wildner {
16501093ca81SSascha Wildner ListItemPath++;
16511093ca81SSascha Wildner }
16521093ca81SSascha Wildner
16531093ca81SSascha Wildner if (!strcmp (ListItemPath, InputPath) &&
16541093ca81SSascha Wildner (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))
16551093ca81SSascha Wildner {
16561093ca81SSascha Wildner AcpiOsPrintf ("%s", ExternalConflictMessage);
16571093ca81SSascha Wildner AcpiDmConflictingDeclaration (Path);
16581093ca81SSascha Wildner
16591093ca81SSascha Wildner return;
16601093ca81SSascha Wildner }
16611093ca81SSascha Wildner }
16621093ca81SSascha Wildner ExternalList = ExternalList->Next;
16631093ca81SSascha Wildner }
16641093ca81SSascha Wildner }
16651093ca81SSascha Wildner /*******************************************************************************
16661093ca81SSascha Wildner *
16670d02842fSSascha Wildner * FUNCTION: AcpiDmUnresolvedWarning
16680d02842fSSascha Wildner *
16690d02842fSSascha Wildner * PARAMETERS: Type - Where to output the warning.
16700d02842fSSascha Wildner * 0 means write to stderr
16710d02842fSSascha Wildner * 1 means write to AcpiOsPrintf
16720d02842fSSascha Wildner *
16730d02842fSSascha Wildner * RETURN: None
16740d02842fSSascha Wildner *
16750d02842fSSascha Wildner * DESCRIPTION: Issue warning message if there are unresolved external control
16760d02842fSSascha Wildner * methods within the disassembly.
16770d02842fSSascha Wildner *
16780d02842fSSascha Wildner ******************************************************************************/
16790d02842fSSascha Wildner
16801093ca81SSascha Wildner /*
16810d02842fSSascha Wildner Summary of the external control method problem:
16820d02842fSSascha Wildner
16830d02842fSSascha Wildner When the -e option is used with disassembly, the various SSDTs are simply
16840d02842fSSascha Wildner loaded into a global namespace for the disassembler to use in order to
16850d02842fSSascha Wildner resolve control method references (invocations).
16860d02842fSSascha Wildner
16870d02842fSSascha Wildner The disassembler tracks any such references, and will emit an External()
16880d02842fSSascha Wildner statement for these types of methods, with the proper number of arguments .
16890d02842fSSascha Wildner
16900d02842fSSascha Wildner Without the SSDTs, the AML does not contain enough information to properly
16910d02842fSSascha Wildner disassemble the control method invocation -- because the disassembler does
16920d02842fSSascha Wildner not know how many arguments to parse.
16930d02842fSSascha Wildner
16940d02842fSSascha Wildner An example: Assume we have two control methods. ABCD has one argument, and
16950d02842fSSascha Wildner EFGH has zero arguments. Further, we have two additional control methods
16960d02842fSSascha Wildner that invoke ABCD and EFGH, named T1 and T2:
16970d02842fSSascha Wildner
16980d02842fSSascha Wildner Method (ABCD, 1)
16990d02842fSSascha Wildner {
17000d02842fSSascha Wildner }
17010d02842fSSascha Wildner Method (EFGH, 0)
17020d02842fSSascha Wildner {
17030d02842fSSascha Wildner }
17040d02842fSSascha Wildner Method (T1)
17050d02842fSSascha Wildner {
17060d02842fSSascha Wildner ABCD (Add (2, 7, Local0))
17070d02842fSSascha Wildner }
17080d02842fSSascha Wildner Method (T2)
17090d02842fSSascha Wildner {
17100d02842fSSascha Wildner EFGH ()
17110d02842fSSascha Wildner Add (2, 7, Local0)
17120d02842fSSascha Wildner }
17130d02842fSSascha Wildner
17140d02842fSSascha Wildner Here is the AML code that is generated for T1 and T2:
17150d02842fSSascha Wildner
17160d02842fSSascha Wildner 185: Method (T1)
17170d02842fSSascha Wildner
17180d02842fSSascha Wildner 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__."
17190d02842fSSascha Wildner
17200d02842fSSascha Wildner 186: {
17210d02842fSSascha Wildner 187: ABCD (Add (2, 7, Local0))
17220d02842fSSascha Wildner
17230d02842fSSascha Wildner 00000353: 41 42 43 44 ............ "ABCD"
17240d02842fSSascha Wildner 00000357: 72 0A 02 0A 07 60 ...... "r....`"
17250d02842fSSascha Wildner
17260d02842fSSascha Wildner 188: }
17270d02842fSSascha Wildner
17280d02842fSSascha Wildner 190: Method (T2)
17290d02842fSSascha Wildner
17300d02842fSSascha Wildner 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__."
17310d02842fSSascha Wildner
17320d02842fSSascha Wildner 191: {
17330d02842fSSascha Wildner 192: EFGH ()
17340d02842fSSascha Wildner
17350d02842fSSascha Wildner 00000364: 45 46 47 48 ............ "EFGH"
17360d02842fSSascha Wildner
17370d02842fSSascha Wildner 193: Add (2, 7, Local0)
17380d02842fSSascha Wildner
17390d02842fSSascha Wildner 00000368: 72 0A 02 0A 07 60 ...... "r....`"
17400d02842fSSascha Wildner 194: }
17410d02842fSSascha Wildner
17420d02842fSSascha Wildner Note that the AML code for T1 and T2 is essentially identical. When
17430d02842fSSascha Wildner disassembling this code, the methods ABCD and EFGH must be known to the
17440d02842fSSascha Wildner disassembler, otherwise it does not know how to handle the method invocations.
17450d02842fSSascha Wildner
17460d02842fSSascha Wildner In other words, if ABCD and EFGH are actually external control methods
17470d02842fSSascha Wildner appearing in an SSDT, the disassembler does not know what to do unless
17480d02842fSSascha Wildner the owning SSDT has been loaded via the -e option.
17491093ca81SSascha Wildner */
17500d02842fSSascha Wildner
17517c9678bcSSascha Wildner static char ExternalWarningPart1[600];
17527c9678bcSSascha Wildner static char ExternalWarningPart2[400];
17537c9678bcSSascha Wildner static char ExternalWarningPart3[400];
17547c9678bcSSascha Wildner static char ExternalWarningPart4[200];
17557c9678bcSSascha Wildner
17560d02842fSSascha Wildner void
AcpiDmUnresolvedWarning(UINT8 Type)17570d02842fSSascha Wildner AcpiDmUnresolvedWarning (
17580d02842fSSascha Wildner UINT8 Type)
17590d02842fSSascha Wildner {
17607c9678bcSSascha Wildner char *Format;
17617c9678bcSSascha Wildner char Pad[] = " *";
17627c9678bcSSascha Wildner char NoPad[] = "";
17637c9678bcSSascha Wildner
17640d02842fSSascha Wildner
17650d02842fSSascha Wildner if (!AcpiGbl_NumExternalMethods)
17660d02842fSSascha Wildner {
17670d02842fSSascha Wildner return;
17680d02842fSSascha Wildner }
17690d02842fSSascha Wildner
17707c9678bcSSascha Wildner if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
17717c9678bcSSascha Wildner {
17727c9678bcSSascha Wildner return;
17737c9678bcSSascha Wildner }
17747c9678bcSSascha Wildner
17757c9678bcSSascha Wildner Format = Type ? Pad : NoPad;
17767c9678bcSSascha Wildner
17777c9678bcSSascha Wildner sprintf (ExternalWarningPart1,
17782ffe9f16SSascha Wildner "%s iASL Warning: There %s %u external control method%s found during\n"
17797c9678bcSSascha Wildner "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
17807c9678bcSSascha Wildner "%s ACPI tables may be required to properly disassemble the code. This\n"
17817c9678bcSSascha Wildner "%s resulting disassembler output file may not compile because the\n"
17827c9678bcSSascha Wildner "%s disassembler did not know how many arguments to assign to the\n"
17837c9678bcSSascha Wildner "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
17847c9678bcSSascha Wildner "%s runtime and may or may not be available via the host OS.\n",
17852ffe9f16SSascha Wildner Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
17862ffe9f16SSascha Wildner AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
17872ffe9f16SSascha Wildner Format, AcpiGbl_ResolvedExternalMethods,
17882ffe9f16SSascha Wildner (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
17897c9678bcSSascha Wildner (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
17907c9678bcSSascha Wildner Format, Format, Format, Format, Format);
17917c9678bcSSascha Wildner
17927c9678bcSSascha Wildner sprintf (ExternalWarningPart2,
17937c9678bcSSascha Wildner "%s To specify the tables needed to resolve external control method\n"
17947c9678bcSSascha Wildner "%s references, the -e option can be used to specify the filenames.\n"
17957c9678bcSSascha Wildner "%s Example iASL invocations:\n"
17967c9678bcSSascha Wildner "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
17977c9678bcSSascha Wildner "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
17987c9678bcSSascha Wildner "%s iasl -e ssdt*.aml -d dsdt.aml\n",
17997c9678bcSSascha Wildner Format, Format, Format, Format, Format, Format);
18007c9678bcSSascha Wildner
18017c9678bcSSascha Wildner sprintf (ExternalWarningPart3,
18027c9678bcSSascha Wildner "%s In addition, the -fe option can be used to specify a file containing\n"
18037c9678bcSSascha Wildner "%s control method external declarations with the associated method\n"
18047c9678bcSSascha Wildner "%s argument counts. Each line of the file must be of the form:\n"
18057c9678bcSSascha Wildner "%s External (<method pathname>, MethodObj, <argument count>)\n"
18067c9678bcSSascha Wildner "%s Invocation:\n"
18077c9678bcSSascha Wildner "%s iasl -fe refs.txt -d dsdt.aml\n",
18087c9678bcSSascha Wildner Format, Format, Format, Format, Format, Format);
18097c9678bcSSascha Wildner
18107c9678bcSSascha Wildner sprintf (ExternalWarningPart4,
18117c9678bcSSascha Wildner "%s The following methods were unresolved and many not compile properly\n"
18127c9678bcSSascha Wildner "%s because the disassembler had to guess at the number of arguments\n"
18137c9678bcSSascha Wildner "%s required for each:\n",
18147c9678bcSSascha Wildner Format, Format, Format);
18157c9678bcSSascha Wildner
18160d02842fSSascha Wildner if (Type)
18170d02842fSSascha Wildner {
18180d02842fSSascha Wildner if (!AcpiGbl_ExternalFileList)
18190d02842fSSascha Wildner {
18200d02842fSSascha Wildner /* The -e option was not specified */
18210d02842fSSascha Wildner
18227c9678bcSSascha Wildner AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n",
18237c9678bcSSascha Wildner ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
18247c9678bcSSascha Wildner ExternalWarningPart4);
18250d02842fSSascha Wildner }
18267c9678bcSSascha Wildner else
18270d02842fSSascha Wildner {
18280d02842fSSascha Wildner /* The -e option was specified, but there are still some unresolved externals */
18290d02842fSSascha Wildner
18302ffe9f16SSascha Wildner AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n",
18317c9678bcSSascha Wildner ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
18320d02842fSSascha Wildner }
18330d02842fSSascha Wildner }
18340d02842fSSascha Wildner else
18350d02842fSSascha Wildner {
18360d02842fSSascha Wildner if (!AcpiGbl_ExternalFileList)
18370d02842fSSascha Wildner {
18380d02842fSSascha Wildner /* The -e option was not specified */
18390d02842fSSascha Wildner
18407c9678bcSSascha Wildner fprintf (stderr, "\n%s\n%s\n%s\n",
18417c9678bcSSascha Wildner ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
18420d02842fSSascha Wildner }
18437c9678bcSSascha Wildner else
18440d02842fSSascha Wildner {
18450d02842fSSascha Wildner /* The -e option was specified, but there are still some unresolved externals */
18460d02842fSSascha Wildner
18477c9678bcSSascha Wildner fprintf (stderr, "\n%s\n%s\n",
18487c9678bcSSascha Wildner ExternalWarningPart1, ExternalWarningPart3);
18490d02842fSSascha Wildner }
18500d02842fSSascha Wildner }
18510d02842fSSascha Wildner }
1852