inet6: require RTF_ANNOUNCE to proxy NS
[dragonfly.git] / sys / contrib / dev / acpica / source / common / dmextern.c
blob36d586008cb662158a2371010e5be8f6cd44b6bb
1 /******************************************************************************
3 * Module Name: dmextern - Support for External() ASL statements
5 *****************************************************************************/
7 /******************************************************************************
9 * 1. Copyright Notice
11 * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
12 * All rights reserved.
14 * 2. License
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
40 * 3. Conditions
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
80 * 4. Disclaimer and Export Compliance
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
114 *****************************************************************************
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
150 *****************************************************************************/
152 #include "acpi.h"
153 #include "accommon.h"
154 #include "amlcode.h"
155 #include "acnamesp.h"
156 #include "acdisasm.h"
157 #include "aslcompiler.h"
158 #include <stdio.h>
159 #include <errno.h>
163 * This module is used for application-level code (iASL disassembler) only.
165 * It contains the code to create and emit any necessary External() ASL
166 * statements for the module being disassembled.
168 #define _COMPONENT ACPI_CA_DISASSEMBLER
169 ACPI_MODULE_NAME ("dmextern")
173 * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
174 * ObjectTypeKeyword. Used to generate typed external declarations
176 static const char *AcpiGbl_DmTypeNames[] =
178 /* 00 */ ", UnknownObj", /* Type ANY */
179 /* 01 */ ", IntObj",
180 /* 02 */ ", StrObj",
181 /* 03 */ ", BuffObj",
182 /* 04 */ ", PkgObj",
183 /* 05 */ ", FieldUnitObj",
184 /* 06 */ ", DeviceObj",
185 /* 07 */ ", EventObj",
186 /* 08 */ ", MethodObj",
187 /* 09 */ ", MutexObj",
188 /* 10 */ ", OpRegionObj",
189 /* 11 */ ", PowerResObj",
190 /* 12 */ ", ProcessorObj",
191 /* 13 */ ", ThermalZoneObj",
192 /* 14 */ ", BuffFieldObj",
193 /* 15 */ ", DDBHandleObj",
194 /* 16 */ "", /* Debug object */
195 /* 17 */ ", FieldUnitObj",
196 /* 18 */ ", FieldUnitObj",
197 /* 19 */ ", FieldUnitObj"
200 #define METHOD_SEPARATORS " \t,()\n"
202 static const char *ExternalConflictMessage =
203 " // Conflicts with a later declaration";
206 /* Local prototypes */
208 static const char *
209 AcpiDmGetObjectTypeName (
210 ACPI_OBJECT_TYPE Type);
212 static char *
213 AcpiDmNormalizeParentPrefix (
214 ACPI_PARSE_OBJECT *Op,
215 char *Path);
217 static ACPI_STATUS
218 AcpiDmGetExternalAndInternalPath (
219 ACPI_NAMESPACE_NODE *Node,
220 char **ExternalPath,
221 char **InternalPath);
223 static ACPI_STATUS
224 AcpiDmRemoveRootPrefix (
225 char **Path);
227 static void
228 AcpiDmAddPathToExternalList (
229 char *Path,
230 UINT8 Type,
231 UINT32 Value,
232 UINT16 Flags);
234 static ACPI_STATUS
235 AcpiDmCreateNewExternal (
236 char *ExternalPath,
237 char *InternalPath,
238 UINT8 Type,
239 UINT32 Value,
240 UINT16 Flags);
242 static void
243 AcpiDmCheckForExternalConflict (
244 char *Path);
246 static ACPI_STATUS
247 AcpiDmResolveExternal (
248 char *Path,
249 UINT8 Type,
250 ACPI_NAMESPACE_NODE **Node);
253 static void
254 AcpiDmConflictingDeclaration (
255 char *Path);
258 /*******************************************************************************
260 * FUNCTION: AcpiDmGetObjectTypeName
262 * PARAMETERS: Type - An ACPI_OBJECT_TYPE
264 * RETURN: Pointer to a string
266 * DESCRIPTION: Map an object type to the ASL object type string.
268 ******************************************************************************/
270 static const char *
271 AcpiDmGetObjectTypeName (
272 ACPI_OBJECT_TYPE Type)
275 if (Type == ACPI_TYPE_LOCAL_SCOPE)
277 Type = ACPI_TYPE_DEVICE;
279 else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
281 return ("");
284 return (AcpiGbl_DmTypeNames[Type]);
288 /*******************************************************************************
290 * FUNCTION: AcpiDmNormalizeParentPrefix
292 * PARAMETERS: Op - Parse op
293 * Path - Path with parent prefix
295 * RETURN: The full pathname to the object (from the namespace root)
297 * DESCRIPTION: Returns the full pathname of a path with parent prefix
298 * The caller must free the fullpath returned.
300 ******************************************************************************/
302 static char *
303 AcpiDmNormalizeParentPrefix (
304 ACPI_PARSE_OBJECT *Op,
305 char *Path)
307 ACPI_NAMESPACE_NODE *Node;
308 char *Fullpath;
309 char *ParentPath;
310 ACPI_SIZE Length;
311 UINT32 Index = 0;
314 if (!Op)
316 return (NULL);
319 /* Search upwards in the parse tree until we reach the next namespace node */
321 Op = Op->Common.Parent;
322 while (Op)
324 if (Op->Common.Node)
326 break;
329 Op = Op->Common.Parent;
332 if (!Op)
334 return (NULL);
338 * Find the actual parent node for the reference:
339 * Remove all carat prefixes from the input path.
340 * There may be multiple parent prefixes (For example, ^^^M000)
342 Node = Op->Common.Node;
343 while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
345 Node = Node->Parent;
346 Path++;
349 if (!Node)
351 return (NULL);
354 /* Get the full pathname for the parent node */
356 ParentPath = AcpiNsGetExternalPathname (Node);
357 if (!ParentPath)
359 return (NULL);
362 Length = (strlen (ParentPath) + strlen (Path) + 1);
363 if (ParentPath[1])
366 * If ParentPath is not just a simple '\', increment the length
367 * for the required dot separator (ParentPath.Path)
369 Length++;
371 /* For External() statements, we do not want a leading '\' */
373 if (*ParentPath == AML_ROOT_PREFIX)
375 Index = 1;
379 Fullpath = ACPI_ALLOCATE_ZEROED (Length);
380 if (!Fullpath)
382 goto Cleanup;
386 * Concatenate parent fullpath and path. For example,
387 * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
389 * Copy the parent path
391 strcpy (Fullpath, &ParentPath[Index]);
394 * Add dot separator
395 * (don't need dot if parent fullpath is a single backslash)
397 if (ParentPath[1])
399 strcat (Fullpath, ".");
402 /* Copy child path (carat parent prefix(es) were skipped above) */
404 strcat (Fullpath, Path);
406 Cleanup:
407 ACPI_FREE (ParentPath);
408 return (Fullpath);
412 /*******************************************************************************
414 * FUNCTION: AcpiDmAddToExternalFileList
416 * PARAMETERS: PathList - Single path or list separated by comma
418 * RETURN: None
420 * DESCRIPTION: Add external files to global list
422 ******************************************************************************/
424 ACPI_STATUS
425 AcpiDmAddToExternalFileList (
426 char *Pathname)
428 ACPI_EXTERNAL_FILE *ExternalFile;
429 char *LocalPathname;
432 if (!Pathname)
434 return (AE_OK);
437 LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
438 if (!LocalPathname)
440 return (AE_NO_MEMORY);
443 ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
444 if (!ExternalFile)
446 ACPI_FREE (LocalPathname);
447 return (AE_NO_MEMORY);
450 /* Take a copy of the file pathname */
452 strcpy (LocalPathname, Pathname);
453 ExternalFile->Path = LocalPathname;
455 if (AcpiGbl_ExternalFileList)
457 ExternalFile->Next = AcpiGbl_ExternalFileList;
460 AcpiGbl_ExternalFileList = ExternalFile;
461 return (AE_OK);
465 /*******************************************************************************
467 * FUNCTION: AcpiDmClearExternalFileList
469 * PARAMETERS: None
471 * RETURN: None
473 * DESCRIPTION: Clear the external file list
475 ******************************************************************************/
477 void
478 AcpiDmClearExternalFileList (
479 void)
481 ACPI_EXTERNAL_FILE *NextExternal;
484 while (AcpiGbl_ExternalFileList)
486 NextExternal = AcpiGbl_ExternalFileList->Next;
487 ACPI_FREE (AcpiGbl_ExternalFileList->Path);
488 ACPI_FREE (AcpiGbl_ExternalFileList);
489 AcpiGbl_ExternalFileList = NextExternal;
494 /*******************************************************************************
496 * FUNCTION: AcpiDmGetExternalsFromFile
498 * PARAMETERS: None
500 * RETURN: None
502 * DESCRIPTION: Process the optional external reference file.
504 * Each line in the file should be of the form:
505 * External (<Method namepath>, MethodObj, <ArgCount>)
507 * Example:
508 * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
510 ******************************************************************************/
512 void
513 AcpiDmGetExternalsFromFile (
514 void)
516 FILE *ExternalRefFile;
517 char *Token;
518 char *MethodName;
519 UINT32 ArgCount;
520 UINT32 ImportCount = 0;
523 if (!AslGbl_ExternalRefFilename)
525 return;
528 /* Open the file */
530 ExternalRefFile = fopen (AslGbl_ExternalRefFilename, "r");
531 if (!ExternalRefFile)
533 fprintf (stderr, "Could not open external reference file \"%s\"\n",
534 AslGbl_ExternalRefFilename);
535 AslAbort ();
536 return;
539 /* Each line defines a method */
541 while (fgets (AslGbl_StringBuffer, ASL_STRING_BUFFER_SIZE, ExternalRefFile))
543 Token = strtok (AslGbl_StringBuffer, METHOD_SEPARATORS); /* "External" */
544 if (!Token)
546 continue;
549 if (strcmp (Token, "External"))
551 continue;
554 MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
555 if (!MethodName)
557 continue;
560 Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
561 if (!Token)
563 continue;
566 if (strcmp (Token, "MethodObj"))
568 continue;
571 Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
572 if (!Token)
574 continue;
577 /* Convert arg count string to an integer */
579 errno = 0;
580 ArgCount = strtoul (Token, NULL, 0);
581 if (errno)
583 fprintf (stderr, "Invalid argument count (%s)\n", Token);
584 continue;
587 if (ArgCount > 7)
589 fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
590 continue;
593 /* Add this external to the global list */
595 AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
596 AslGbl_ExternalRefFilename, ArgCount, MethodName);
598 AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
599 ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
600 ImportCount++;
603 if (!ImportCount)
605 fprintf (stderr,
606 "Did not find any external methods in reference file \"%s\"\n",
607 AslGbl_ExternalRefFilename);
609 else
611 /* Add the external(s) to the namespace */
613 AcpiDmAddExternalListToNamespace ();
615 AcpiOsPrintf ("%s: Imported %u external method definitions\n",
616 AslGbl_ExternalRefFilename, ImportCount);
619 fclose (ExternalRefFile);
623 /*******************************************************************************
625 * FUNCTION: AcpiDmAddOpToExternalList
627 * PARAMETERS: Op - Current parser Op
628 * Path - Internal (AML) path to the object
629 * Type - ACPI object type to be added
630 * Value - Arg count if adding a Method object
631 * Flags - To be passed to the external object
633 * RETURN: None
635 * DESCRIPTION: Insert a new name into the global list of Externals which
636 * will in turn be later emitted as an External() declaration
637 * in the disassembled output.
639 * This function handles the most common case where the referenced
640 * name is simply not found in the constructed namespace.
642 ******************************************************************************/
644 void
645 AcpiDmAddOpToExternalList (
646 ACPI_PARSE_OBJECT *Op,
647 char *Path,
648 UINT8 Type,
649 UINT32 Value,
650 UINT16 Flags)
652 char *ExternalPath;
653 char *InternalPath = Path;
654 char *Temp;
655 ACPI_STATUS Status;
658 ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
661 if (!Path)
663 return_VOID;
666 /* Remove a root backslash if present */
668 if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
670 Path++;
673 /* Externalize the pathname */
675 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
676 NULL, &ExternalPath);
677 if (ACPI_FAILURE (Status))
679 return_VOID;
683 * Get the full pathname from the root if "Path" has one or more
684 * parent prefixes (^). Note: path will not contain a leading '\'.
686 if (*Path == (UINT8) AML_PARENT_PREFIX)
688 Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
690 /* Set new external path */
692 ACPI_FREE (ExternalPath);
693 ExternalPath = Temp;
694 if (!Temp)
696 return_VOID;
699 /* Create the new internal pathname */
701 Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
702 Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
703 if (ACPI_FAILURE (Status))
705 ACPI_FREE (ExternalPath);
706 return_VOID;
710 /* Create the new External() declaration node */
712 Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
713 Type, Value, Flags);
714 if (ACPI_FAILURE (Status))
716 ACPI_FREE (ExternalPath);
717 if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
719 ACPI_FREE (InternalPath);
723 return_VOID;
727 /*******************************************************************************
729 * FUNCTION: AcpiDmGetExternalAndInternalPath
731 * PARAMETERS: Node - Namespace node for object to be added
732 * ExternalPath - Will contain the external path of the node
733 * InternalPath - Will contain the internal path of the node
735 * RETURN: None
737 * DESCRIPTION: Get the External and Internal path from the given node.
739 ******************************************************************************/
741 static ACPI_STATUS
742 AcpiDmGetExternalAndInternalPath (
743 ACPI_NAMESPACE_NODE *Node,
744 char **ExternalPath,
745 char **InternalPath)
747 ACPI_STATUS Status;
750 if (!Node)
752 return (AE_BAD_PARAMETER);
755 /* Get the full external and internal pathnames to the node */
757 *ExternalPath = AcpiNsGetExternalPathname (Node);
758 if (!*ExternalPath)
760 return (AE_BAD_PATHNAME);
763 Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);
764 if (ACPI_FAILURE (Status))
766 ACPI_FREE (*ExternalPath);
767 return (Status);
770 return (AE_OK);
774 /*******************************************************************************
776 * FUNCTION: AcpiDmRemoveRootPrefix
778 * PARAMETERS: Path - Remove Root prefix from this Path
780 * RETURN: None
782 * DESCRIPTION: Remove the root prefix character '\' from Path.
784 ******************************************************************************/
786 static ACPI_STATUS
787 AcpiDmRemoveRootPrefix (
788 char **Path)
790 char *InputPath = *Path;
793 if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))
795 if (!memmove(InputPath, InputPath+1, strlen(InputPath)))
797 return (AE_ERROR);
800 *Path = InputPath;
803 return (AE_OK);
807 /*******************************************************************************
809 * FUNCTION: AcpiDmAddNodeToExternalList
811 * PARAMETERS: Node - Namespace node for object to be added
812 * Type - ACPI object type to be added
813 * Value - Arg count if adding a Method object
814 * Flags - To be passed to the external object
816 * RETURN: None
818 * DESCRIPTION: Insert a new name into the global list of Externals which
819 * will in turn be later emitted as an External() declaration
820 * in the disassembled output.
822 * This function handles the case where the referenced name has
823 * been found in the namespace, but the name originated in a
824 * table other than the one that is being disassembled (such
825 * as a table that is added via the iASL -e option).
827 ******************************************************************************/
829 void
830 AcpiDmAddNodeToExternalList (
831 ACPI_NAMESPACE_NODE *Node,
832 UINT8 Type,
833 UINT32 Value,
834 UINT16 Flags)
836 char *ExternalPath;
837 char *InternalPath;
838 ACPI_STATUS Status;
841 ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
843 /* Get the full external and internal pathnames to the node */
845 Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);
846 if (ACPI_FAILURE (Status))
848 return_VOID;
851 /* Remove the root backslash */
853 Status = AcpiDmRemoveRootPrefix (&ExternalPath);
854 if (ACPI_FAILURE (Status))
856 ACPI_FREE (ExternalPath);
857 ACPI_FREE (InternalPath);
858 return_VOID;
861 /* Create the new External() declaration node */
863 Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
864 Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
865 if (ACPI_FAILURE (Status))
867 ACPI_FREE (ExternalPath);
868 ACPI_FREE (InternalPath);
871 return_VOID;
875 /*******************************************************************************
877 * FUNCTION: AcpiDmAddPathToExternalList
879 * PARAMETERS: Path - External name of the object to be added
880 * Type - ACPI object type to be added
881 * Value - Arg count if adding a Method object
882 * Flags - To be passed to the external object
884 * RETURN: None
886 * DESCRIPTION: Insert a new name into the global list of Externals which
887 * will in turn be later emitted as an External() declaration
888 * in the disassembled output.
890 * This function currently is used to add externals via a
891 * reference file (via the -fe iASL option).
893 ******************************************************************************/
895 static void
896 AcpiDmAddPathToExternalList (
897 char *Path,
898 UINT8 Type,
899 UINT32 Value,
900 UINT16 Flags)
902 char *InternalPath;
903 char *ExternalPath;
904 ACPI_STATUS Status;
907 ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
910 if (!Path)
912 return_VOID;
915 /* Remove a root backslash if present */
917 if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
919 Path++;
922 /* Create the internal and external pathnames */
924 Status = AcpiNsInternalizeName (Path, &InternalPath);
925 if (ACPI_FAILURE (Status))
927 return_VOID;
930 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
931 NULL, &ExternalPath);
932 if (ACPI_FAILURE (Status))
934 ACPI_FREE (InternalPath);
935 return_VOID;
938 /* Create the new External() declaration node */
940 Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
941 Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
942 if (ACPI_FAILURE (Status))
944 ACPI_FREE (ExternalPath);
945 ACPI_FREE (InternalPath);
948 return_VOID;
952 /*******************************************************************************
954 * FUNCTION: AcpiDmCreateNewExternal
956 * PARAMETERS: ExternalPath - External path to the object
957 * InternalPath - Internal (AML) path to the object
958 * Type - ACPI object type to be added
959 * Value - Arg count if adding a Method object
960 * Flags - To be passed to the external object
962 * RETURN: Status
964 * DESCRIPTION: Common low-level function to insert a new name into the global
965 * list of Externals which will in turn be later emitted as
966 * External() declarations in the disassembled output.
968 * Note: The external name should not include a root prefix
969 * (backslash). We do not want External() statements to contain
970 * a leading '\', as this prevents duplicate external statements
971 * of the form:
973 * External (\ABCD)
974 * External (ABCD)
976 * This would cause a compile time error when the disassembled
977 * output file is recompiled.
979 * There are two cases that are handled here. For both, we emit
980 * an External() statement:
981 * 1) The name was simply not found in the namespace.
982 * 2) The name was found, but it originated in a table other than
983 * the table that is being disassembled.
985 ******************************************************************************/
987 static ACPI_STATUS
988 AcpiDmCreateNewExternal (
989 char *ExternalPath,
990 char *InternalPath,
991 UINT8 Type,
992 UINT32 Value,
993 UINT16 Flags)
995 ACPI_EXTERNAL_LIST *NewExternal;
996 ACPI_EXTERNAL_LIST *NextExternal;
997 ACPI_EXTERNAL_LIST *PrevExternal = NULL;
1000 ACPI_FUNCTION_TRACE (DmCreateNewExternal);
1003 /* Check all existing externals to ensure no duplicates */
1005 NextExternal = AcpiGbl_ExternalList;
1006 while (NextExternal)
1008 /* Check for duplicates */
1010 if (!strcmp (ExternalPath, NextExternal->Path))
1013 * If this external came from an External() opcode, we are
1014 * finished with this one. (No need to check any further).
1016 if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
1018 return_ACPI_STATUS (AE_ALREADY_EXISTS);
1021 /* Allow upgrade of type from ANY */
1023 else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
1024 (Type != ACPI_TYPE_ANY))
1026 NextExternal->Type = Type;
1029 /* Update the argument count as necessary */
1031 if (Value < NextExternal->Value)
1033 NextExternal->Value = Value;
1036 /* Update flags. */
1038 NextExternal->Flags |= Flags;
1039 NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
1041 return_ACPI_STATUS (AE_ALREADY_EXISTS);
1044 NextExternal = NextExternal->Next;
1047 /* Allocate and init a new External() descriptor */
1049 NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
1050 if (!NewExternal)
1052 return_ACPI_STATUS (AE_NO_MEMORY);
1055 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
1056 "Adding external reference node (%s) type [%s]\n",
1057 ExternalPath, AcpiUtGetTypeName (Type)));
1059 NewExternal->Flags = Flags;
1060 NewExternal->Value = Value;
1061 NewExternal->Path = ExternalPath;
1062 NewExternal->Type = Type;
1063 NewExternal->Length = (UINT16) strlen (ExternalPath);
1064 NewExternal->InternalPath = InternalPath;
1066 /* Link the new descriptor into the global list, alphabetically ordered */
1068 NextExternal = AcpiGbl_ExternalList;
1069 while (NextExternal)
1071 if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
1073 if (PrevExternal)
1075 PrevExternal->Next = NewExternal;
1077 else
1079 AcpiGbl_ExternalList = NewExternal;
1082 NewExternal->Next = NextExternal;
1083 return_ACPI_STATUS (AE_OK);
1086 PrevExternal = NextExternal;
1087 NextExternal = NextExternal->Next;
1090 if (PrevExternal)
1092 PrevExternal->Next = NewExternal;
1094 else
1096 AcpiGbl_ExternalList = NewExternal;
1099 return_ACPI_STATUS (AE_OK);
1103 /*******************************************************************************
1105 * FUNCTION: AcpiDmResolveExternal
1107 * PARAMETERS: Path - Path of the external
1108 * Type - Type of the external
1109 * Node - Input node for AcpiNsLookup
1111 * RETURN: Status
1113 * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.
1114 * If the returned node is an external and has the same type
1115 * we assume that it was either an existing external or a
1117 ******************************************************************************/
1119 static ACPI_STATUS
1120 AcpiDmResolveExternal (
1121 char *Path,
1122 UINT8 Type,
1123 ACPI_NAMESPACE_NODE **Node)
1125 ACPI_STATUS Status;
1128 Status = AcpiNsLookup (NULL, Path, Type,
1129 ACPI_IMODE_LOAD_PASS1,
1130 ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
1131 NULL, Node);
1133 if (!Node)
1135 ACPI_EXCEPTION ((AE_INFO, Status,
1136 "while adding external to namespace [%s]", Path));
1139 /* Note the asl code "external(a) external(a)" is acceptable ASL */
1141 else if ((*Node)->Type == Type &&
1142 (*Node)->Flags & ANOBJ_IS_EXTERNAL)
1144 return (AE_OK);
1146 else
1148 ACPI_EXCEPTION ((AE_INFO, AE_ERROR,
1149 "[%s] has conflicting declarations", Path));
1152 return (AE_ERROR);
1156 /*******************************************************************************
1158 * FUNCTION: AcpiDmCreateSubobjectForExternal
1160 * PARAMETERS: Type - Type of the external
1161 * Node - Namespace node from AcpiNsLookup
1162 * ParamCount - Value to be used for Method
1164 * RETURN: None
1166 * DESCRIPTION: Add one external to the namespace. Allows external to be
1167 * "resolved".
1169 ******************************************************************************/
1171 void
1172 AcpiDmCreateSubobjectForExternal (
1173 UINT8 Type,
1174 ACPI_NAMESPACE_NODE **Node,
1175 UINT32 ParamCount)
1177 ACPI_OPERAND_OBJECT *ObjDesc;
1180 switch (Type)
1182 case ACPI_TYPE_METHOD:
1184 /* For methods, we need to save the argument count */
1186 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
1187 ObjDesc->Method.ParamCount = (UINT8) ParamCount;
1188 (*Node)->Object = ObjDesc;
1189 break;
1191 case ACPI_TYPE_REGION:
1193 /* Regions require a region sub-object */
1195 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
1196 ObjDesc->Region.Node = *Node;
1197 (*Node)->Object = ObjDesc;
1198 break;
1200 default:
1202 break;
1207 /*******************************************************************************
1209 * FUNCTION: AcpiDmAddOneExternalToNamespace
1211 * PARAMETERS: Path - External parse object
1212 * Type - Type of parse object
1213 * ParamCount - External method parameter count
1215 * RETURN: None
1217 * DESCRIPTION: Add one external to the namespace by resolvign the external
1218 * (by performing a namespace lookup) and annotating the resulting
1219 * namespace node with the appropriate information if the type
1220 * is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
1222 ******************************************************************************/
1224 void
1225 AcpiDmAddOneExternalToNamespace (
1226 char *Path,
1227 UINT8 Type,
1228 UINT32 ParamCount)
1230 ACPI_STATUS Status;
1231 ACPI_NAMESPACE_NODE *Node;
1234 Status = AcpiDmResolveExternal (Path, Type, &Node);
1236 if (ACPI_FAILURE (Status))
1238 return;
1241 AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);
1246 /*******************************************************************************
1248 * FUNCTION: AcpiDmAddExternalListToNamespace
1250 * PARAMETERS: None
1252 * RETURN: None
1254 * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.
1255 * Allows externals to be "resolved".
1257 ******************************************************************************/
1259 void
1260 AcpiDmAddExternalListToNamespace (
1261 void)
1263 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
1266 while (External)
1268 AcpiDmAddOneExternalToNamespace (External->InternalPath,
1269 External->Type, External->Value);
1270 External = External->Next;
1275 /*******************************************************************************
1277 * FUNCTION: AcpiDmGetUnresolvedExternalMethodCount
1279 * PARAMETERS: None
1281 * RETURN: The number of unresolved control method externals in the
1282 * external list
1284 * DESCRIPTION: Return the number of unresolved external methods that have been
1285 * generated. If any unresolved control method externals have been
1286 * found, we must re-parse the entire definition block with the new
1287 * information (number of arguments for the methods.)
1288 * This is limitation of AML, we don't know the number of arguments
1289 * from the control method invocation itself.
1291 * Note: resolved external control methods are external control
1292 * methods encoded with the AML_EXTERNAL_OP bytecode within the
1293 * AML being disassembled.
1295 ******************************************************************************/
1297 UINT32
1298 AcpiDmGetUnresolvedExternalMethodCount (
1299 void)
1301 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
1302 UINT32 Count = 0;
1305 while (External)
1307 if (External->Type == ACPI_TYPE_METHOD &&
1308 !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))
1310 Count++;
1313 External = External->Next;
1316 return (Count);
1320 /*******************************************************************************
1322 * FUNCTION: AcpiDmClearExternalList
1324 * PARAMETERS: None
1326 * RETURN: None
1328 * DESCRIPTION: Free the entire External info list
1330 ******************************************************************************/
1332 void
1333 AcpiDmClearExternalList (
1334 void)
1336 ACPI_EXTERNAL_LIST *NextExternal;
1339 while (AcpiGbl_ExternalList)
1341 NextExternal = AcpiGbl_ExternalList->Next;
1342 ACPI_FREE (AcpiGbl_ExternalList->Path);
1343 ACPI_FREE (AcpiGbl_ExternalList);
1344 AcpiGbl_ExternalList = NextExternal;
1349 /*******************************************************************************
1351 * FUNCTION: AcpiDmEmitExternals
1353 * PARAMETERS: None
1355 * RETURN: None
1357 * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1358 * the global external info list.
1360 ******************************************************************************/
1362 void
1363 AcpiDmEmitExternals (
1364 void)
1366 ACPI_EXTERNAL_LIST *NextExternal;
1369 if (!AcpiGbl_ExternalList)
1371 return;
1375 * Determine the number of control methods in the external list, and
1376 * also how many of those externals were resolved via the namespace.
1378 NextExternal = AcpiGbl_ExternalList;
1379 while (NextExternal)
1381 if (NextExternal->Type == ACPI_TYPE_METHOD)
1383 AcpiGbl_NumExternalMethods++;
1384 if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
1386 AcpiGbl_ResolvedExternalMethods++;
1390 NextExternal = NextExternal->Next;
1393 /* Check if any control methods were unresolved */
1395 AcpiDmUnresolvedWarning (1);
1397 if (AslGbl_ExternalRefFilename)
1399 AcpiOsPrintf (
1400 " /*\n * External declarations were imported from\n"
1401 " * a reference file -- %s\n */\n\n",
1402 AslGbl_ExternalRefFilename);
1406 * Walk and emit the list of externals found during the AML parsing
1408 while (AcpiGbl_ExternalList)
1410 if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
1412 AcpiOsPrintf (" External (%s%s)",
1413 AcpiGbl_ExternalList->Path,
1414 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1416 /* Check for "unresolved" method reference */
1418 if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
1419 (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
1421 AcpiOsPrintf (" // Warning: Unknown method, "
1422 "guessing %u arguments",
1423 AcpiGbl_ExternalList->Value);
1426 /* Check for external from a external references file */
1428 else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
1430 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1432 AcpiOsPrintf (" // %u Arguments",
1433 AcpiGbl_ExternalList->Value);
1436 AcpiOsPrintf (" // From external reference file");
1439 /* This is the normal external case */
1441 else
1443 /* For methods, add a comment with the number of arguments */
1445 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1447 AcpiOsPrintf (" // %u Arguments",
1448 AcpiGbl_ExternalList->Value);
1452 if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)
1454 AcpiOsPrintf ("%s", ExternalConflictMessage);
1455 AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);
1457 AcpiOsPrintf ("\n");
1460 /* Free this external info block and move on to next external */
1462 NextExternal = AcpiGbl_ExternalList->Next;
1463 if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
1465 ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1468 ACPI_FREE (AcpiGbl_ExternalList->Path);
1469 ACPI_FREE (AcpiGbl_ExternalList);
1470 AcpiGbl_ExternalList = NextExternal;
1473 AcpiOsPrintf ("\n");
1477 /*******************************************************************************
1479 * FUNCTION: AcpiDmMarkExternalConflict
1481 * PARAMETERS: Path - Namepath to search
1483 * RETURN: ExternalList
1485 * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path
1487 ******************************************************************************/
1489 void
1490 AcpiDmMarkExternalConflict (
1491 ACPI_NAMESPACE_NODE *Node)
1493 ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
1494 char *ExternalPath;
1495 char *InternalPath;
1496 char *Temp;
1497 ACPI_STATUS Status;
1500 ACPI_FUNCTION_TRACE (DmMarkExternalConflict);
1503 if (Node->Flags & ANOBJ_IS_EXTERNAL)
1505 return_VOID;
1508 /* Get the full external and internal pathnames to the node */
1510 Status = AcpiDmGetExternalAndInternalPath (Node,
1511 &ExternalPath, &InternalPath);
1512 if (ACPI_FAILURE (Status))
1514 return_VOID;
1517 /* Remove the root backslash */
1519 Status = AcpiDmRemoveRootPrefix (&InternalPath);
1520 if (ACPI_FAILURE (Status))
1522 ACPI_FREE (InternalPath);
1523 ACPI_FREE (ExternalPath);
1524 return_VOID;
1527 while (ExternalList)
1529 Temp = ExternalList->InternalPath;
1530 if ((*ExternalList->InternalPath == AML_ROOT_PREFIX) &&
1531 (ExternalList->InternalPath[1]))
1533 Temp++;
1536 if (!strcmp (ExternalList->InternalPath, InternalPath))
1538 ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;
1540 ExternalList = ExternalList->Next;
1543 ACPI_FREE (InternalPath);
1544 ACPI_FREE (ExternalPath);
1546 return_VOID;
1550 /*******************************************************************************
1552 * FUNCTION: AcpiDmConflictingDeclaration
1554 * PARAMETERS: Path - Path with conflicting declaration
1556 * RETURN: None
1558 * DESCRIPTION: Emit a warning when printing conflicting ASL external
1559 * declarations.
1561 ******************************************************************************/
1563 static void
1564 AcpiDmConflictingDeclaration (
1565 char *Path)
1567 fprintf (stderr,
1568 " Warning - Emitting ASL code \"External (%s)\"\n"
1569 " This is a conflicting declaration with some "
1570 "other declaration within the ASL code.\n"
1571 " This external declaration may need to be "
1572 "deleted in order to recompile the dsl file.\n\n",
1573 Path);
1577 /*******************************************************************************
1579 * FUNCTION: AcpiDmEmitExternal
1581 * PARAMETERS: Op External Parse Object
1583 * RETURN: None
1585 * DESCRIPTION: Emit an External() ASL statement for the current External
1586 * parse object. Note: External Ops are named types so the
1587 * namepath is contained within NameOp->Name.Path.
1589 ******************************************************************************/
1591 void
1592 AcpiDmEmitExternal (
1593 ACPI_PARSE_OBJECT *NameOp,
1594 ACPI_PARSE_OBJECT *TypeOp)
1596 AcpiOsPrintf ("External (");
1597 AcpiDmNamestring (NameOp->Named.Path);
1598 AcpiOsPrintf ("%s)",
1599 AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
1600 AcpiDmCheckForExternalConflict (NameOp->Named.Path);
1601 AcpiOsPrintf ("\n");
1605 /*******************************************************************************
1607 * FUNCTION: AcpiDmCheckForExternalConflict
1609 * PARAMETERS: Path - Path to check
1611 * RETURN: None
1613 * DESCRIPTION: Search the External List to see if the input Path has a
1614 * conflicting declaration.
1616 ******************************************************************************/
1618 static void
1619 AcpiDmCheckForExternalConflict (
1620 char *Path)
1622 ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
1623 char *ListItemPath;
1624 char *InputPath;
1627 if (!Path)
1629 return;
1632 /* Move past the root prefix '\' */
1634 InputPath = Path;
1635 if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])
1637 InputPath++;
1640 while (ExternalList)
1642 ListItemPath = ExternalList->Path;
1643 if (ListItemPath)
1645 /* Move past the root prefix '\' */
1647 if ((*ListItemPath == AML_ROOT_PREFIX) &&
1648 ListItemPath[1])
1650 ListItemPath++;
1653 if (!strcmp (ListItemPath, InputPath) &&
1654 (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))
1656 AcpiOsPrintf ("%s", ExternalConflictMessage);
1657 AcpiDmConflictingDeclaration (Path);
1659 return;
1662 ExternalList = ExternalList->Next;
1665 /*******************************************************************************
1667 * FUNCTION: AcpiDmUnresolvedWarning
1669 * PARAMETERS: Type - Where to output the warning.
1670 * 0 means write to stderr
1671 * 1 means write to AcpiOsPrintf
1673 * RETURN: None
1675 * DESCRIPTION: Issue warning message if there are unresolved external control
1676 * methods within the disassembly.
1678 ******************************************************************************/
1681 Summary of the external control method problem:
1683 When the -e option is used with disassembly, the various SSDTs are simply
1684 loaded into a global namespace for the disassembler to use in order to
1685 resolve control method references (invocations).
1687 The disassembler tracks any such references, and will emit an External()
1688 statement for these types of methods, with the proper number of arguments .
1690 Without the SSDTs, the AML does not contain enough information to properly
1691 disassemble the control method invocation -- because the disassembler does
1692 not know how many arguments to parse.
1694 An example: Assume we have two control methods. ABCD has one argument, and
1695 EFGH has zero arguments. Further, we have two additional control methods
1696 that invoke ABCD and EFGH, named T1 and T2:
1698 Method (ABCD, 1)
1701 Method (EFGH, 0)
1704 Method (T1)
1706 ABCD (Add (2, 7, Local0))
1708 Method (T2)
1710 EFGH ()
1711 Add (2, 7, Local0)
1714 Here is the AML code that is generated for T1 and T2:
1716 185: Method (T1)
1718 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__."
1720 186: {
1721 187: ABCD (Add (2, 7, Local0))
1723 00000353: 41 42 43 44 ............ "ABCD"
1724 00000357: 72 0A 02 0A 07 60 ...... "r....`"
1726 188: }
1728 190: Method (T2)
1730 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__."
1732 191: {
1733 192: EFGH ()
1735 00000364: 45 46 47 48 ............ "EFGH"
1737 193: Add (2, 7, Local0)
1739 00000368: 72 0A 02 0A 07 60 ...... "r....`"
1740 194: }
1742 Note that the AML code for T1 and T2 is essentially identical. When
1743 disassembling this code, the methods ABCD and EFGH must be known to the
1744 disassembler, otherwise it does not know how to handle the method invocations.
1746 In other words, if ABCD and EFGH are actually external control methods
1747 appearing in an SSDT, the disassembler does not know what to do unless
1748 the owning SSDT has been loaded via the -e option.
1751 static char ExternalWarningPart1[600];
1752 static char ExternalWarningPart2[400];
1753 static char ExternalWarningPart3[400];
1754 static char ExternalWarningPart4[200];
1756 void
1757 AcpiDmUnresolvedWarning (
1758 UINT8 Type)
1760 char *Format;
1761 char Pad[] = " *";
1762 char NoPad[] = "";
1765 if (!AcpiGbl_NumExternalMethods)
1767 return;
1770 if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
1772 return;
1775 Format = Type ? Pad : NoPad;
1777 sprintf (ExternalWarningPart1,
1778 "%s iASL Warning: There %s %u external control method%s found during\n"
1779 "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1780 "%s ACPI tables may be required to properly disassemble the code. This\n"
1781 "%s resulting disassembler output file may not compile because the\n"
1782 "%s disassembler did not know how many arguments to assign to the\n"
1783 "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
1784 "%s runtime and may or may not be available via the host OS.\n",
1785 Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
1786 AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
1787 Format, AcpiGbl_ResolvedExternalMethods,
1788 (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
1789 (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
1790 Format, Format, Format, Format, Format);
1792 sprintf (ExternalWarningPart2,
1793 "%s To specify the tables needed to resolve external control method\n"
1794 "%s references, the -e option can be used to specify the filenames.\n"
1795 "%s Example iASL invocations:\n"
1796 "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1797 "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1798 "%s iasl -e ssdt*.aml -d dsdt.aml\n",
1799 Format, Format, Format, Format, Format, Format);
1801 sprintf (ExternalWarningPart3,
1802 "%s In addition, the -fe option can be used to specify a file containing\n"
1803 "%s control method external declarations with the associated method\n"
1804 "%s argument counts. Each line of the file must be of the form:\n"
1805 "%s External (<method pathname>, MethodObj, <argument count>)\n"
1806 "%s Invocation:\n"
1807 "%s iasl -fe refs.txt -d dsdt.aml\n",
1808 Format, Format, Format, Format, Format, Format);
1810 sprintf (ExternalWarningPart4,
1811 "%s The following methods were unresolved and many not compile properly\n"
1812 "%s because the disassembler had to guess at the number of arguments\n"
1813 "%s required for each:\n",
1814 Format, Format, Format);
1816 if (Type)
1818 if (!AcpiGbl_ExternalFileList)
1820 /* The -e option was not specified */
1822 AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n",
1823 ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
1824 ExternalWarningPart4);
1826 else
1828 /* The -e option was specified, but there are still some unresolved externals */
1830 AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n",
1831 ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
1834 else
1836 if (!AcpiGbl_ExternalFileList)
1838 /* The -e option was not specified */
1840 fprintf (stderr, "\n%s\n%s\n%s\n",
1841 ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
1843 else
1845 /* The -e option was specified, but there are still some unresolved externals */
1847 fprintf (stderr, "\n%s\n%s\n",
1848 ExternalWarningPart1, ExternalWarningPart3);