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