1198054Sjkim/****************************************************************************** 2198054Sjkim * 3198054Sjkim * Module Name: dmextern - Support for External() ASL statements 4198054Sjkim * 5198054Sjkim *****************************************************************************/ 6198054Sjkim 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12198054Sjkim * All rights reserved. 13198054Sjkim * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119217365Sjkim * Redistribution and use in source and binary forms, with or without 120217365Sjkim * modification, are permitted provided that the following conditions 121217365Sjkim * are met: 122217365Sjkim * 1. Redistributions of source code must retain the above copyright 123217365Sjkim * notice, this list of conditions, and the following disclaimer, 124217365Sjkim * without modification. 125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128217365Sjkim * including a substantially similar Disclaimer requirement for further 129217365Sjkim * binary redistribution. 130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131217365Sjkim * of any contributors may be used to endorse or promote products derived 132217365Sjkim * from this software without specific prior written permission. 133198054Sjkim * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148217365Sjkim * Software Foundation. 149198054Sjkim * 150316303Sjkim *****************************************************************************/ 151198054Sjkim 152198237Sjkim#include <contrib/dev/acpica/include/acpi.h> 153198237Sjkim#include <contrib/dev/acpica/include/accommon.h> 154198237Sjkim#include <contrib/dev/acpica/include/amlcode.h> 155198237Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 156198237Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 157254745Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 158246849Sjkim#include <stdio.h> 159254745Sjkim#include <errno.h> 160198054Sjkim 161198054Sjkim 162198054Sjkim/* 163198054Sjkim * This module is used for application-level code (iASL disassembler) only. 164198054Sjkim * 165198054Sjkim * It contains the code to create and emit any necessary External() ASL 166198054Sjkim * statements for the module being disassembled. 167198054Sjkim */ 168198054Sjkim#define _COMPONENT ACPI_CA_DISASSEMBLER 169198054Sjkim ACPI_MODULE_NAME ("dmextern") 170198054Sjkim 171198054Sjkim 172198054Sjkim/* 173198054Sjkim * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL 174198054Sjkim * ObjectTypeKeyword. Used to generate typed external declarations 175198054Sjkim */ 176198054Sjkimstatic const char *AcpiGbl_DmTypeNames[] = 177198054Sjkim{ 178272444Sjkim /* 00 */ ", UnknownObj", /* Type ANY */ 179198054Sjkim /* 01 */ ", IntObj", 180198054Sjkim /* 02 */ ", StrObj", 181198054Sjkim /* 03 */ ", BuffObj", 182198054Sjkim /* 04 */ ", PkgObj", 183198054Sjkim /* 05 */ ", FieldUnitObj", 184198054Sjkim /* 06 */ ", DeviceObj", 185198054Sjkim /* 07 */ ", EventObj", 186198054Sjkim /* 08 */ ", MethodObj", 187198054Sjkim /* 09 */ ", MutexObj", 188198054Sjkim /* 10 */ ", OpRegionObj", 189198054Sjkim /* 11 */ ", PowerResObj", 190198054Sjkim /* 12 */ ", ProcessorObj", 191198054Sjkim /* 13 */ ", ThermalZoneObj", 192198054Sjkim /* 14 */ ", BuffFieldObj", 193198054Sjkim /* 15 */ ", DDBHandleObj", 194198054Sjkim /* 16 */ "", /* Debug object */ 195198054Sjkim /* 17 */ ", FieldUnitObj", 196198054Sjkim /* 18 */ ", FieldUnitObj", 197198054Sjkim /* 19 */ ", FieldUnitObj" 198198054Sjkim}; 199198054Sjkim 200254745Sjkim#define METHOD_SEPARATORS " \t,()\n" 201198054Sjkim 202322877Sjkimstatic const char *ExternalConflictMessage = 203322877Sjkim " // Conflicts with a later declaration"; 204254745Sjkim 205322877Sjkim 206198054Sjkim/* Local prototypes */ 207198054Sjkim 208198054Sjkimstatic const char * 209198054SjkimAcpiDmGetObjectTypeName ( 210198054Sjkim ACPI_OBJECT_TYPE Type); 211198054Sjkim 212198054Sjkimstatic char * 213198054SjkimAcpiDmNormalizeParentPrefix ( 214198054Sjkim ACPI_PARSE_OBJECT *Op, 215198054Sjkim char *Path); 216198054Sjkim 217322877Sjkimstatic ACPI_STATUS 218322877SjkimAcpiDmGetExternalAndInternalPath ( 219322877Sjkim ACPI_NAMESPACE_NODE *Node, 220322877Sjkim char **ExternalPath, 221322877Sjkim char **InternalPath); 222322877Sjkim 223322877Sjkimstatic ACPI_STATUS 224322877SjkimAcpiDmRemoveRootPrefix ( 225322877Sjkim char **Path); 226322877Sjkim 227254745Sjkimstatic void 228272444SjkimAcpiDmAddPathToExternalList ( 229254745Sjkim char *Path, 230254745Sjkim UINT8 Type, 231272444Sjkim UINT32 Value, 232272444Sjkim UINT16 Flags); 233198054Sjkim 234272444Sjkimstatic ACPI_STATUS 235272444SjkimAcpiDmCreateNewExternal ( 236272444Sjkim char *ExternalPath, 237272444Sjkim char *InternalPath, 238272444Sjkim UINT8 Type, 239272444Sjkim UINT32 Value, 240272444Sjkim UINT16 Flags); 241254745Sjkim 242322877Sjkimstatic void 243322877SjkimAcpiDmCheckForExternalConflict ( 244322877Sjkim char *Path); 245272444Sjkim 246322877Sjkimstatic ACPI_STATUS 247322877SjkimAcpiDmResolveExternal ( 248322877Sjkim char *Path, 249322877Sjkim UINT8 Type, 250322877Sjkim ACPI_NAMESPACE_NODE **Node); 251322877Sjkim 252322877Sjkim 253322877Sjkimstatic void 254322877SjkimAcpiDmConflictingDeclaration ( 255322877Sjkim char *Path); 256322877Sjkim 257322877Sjkim 258198054Sjkim/******************************************************************************* 259198054Sjkim * 260198054Sjkim * FUNCTION: AcpiDmGetObjectTypeName 261198054Sjkim * 262198054Sjkim * PARAMETERS: Type - An ACPI_OBJECT_TYPE 263198054Sjkim * 264198054Sjkim * RETURN: Pointer to a string 265198054Sjkim * 266198054Sjkim * DESCRIPTION: Map an object type to the ASL object type string. 267198054Sjkim * 268198054Sjkim ******************************************************************************/ 269198054Sjkim 270198054Sjkimstatic const char * 271198054SjkimAcpiDmGetObjectTypeName ( 272198054Sjkim ACPI_OBJECT_TYPE Type) 273198054Sjkim{ 274198054Sjkim 275198054Sjkim if (Type == ACPI_TYPE_LOCAL_SCOPE) 276198054Sjkim { 277198054Sjkim Type = ACPI_TYPE_DEVICE; 278198054Sjkim } 279198054Sjkim else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) 280198054Sjkim { 281198054Sjkim return (""); 282198054Sjkim } 283198054Sjkim 284198054Sjkim return (AcpiGbl_DmTypeNames[Type]); 285198054Sjkim} 286198054Sjkim 287198054Sjkim 288198054Sjkim/******************************************************************************* 289198054Sjkim * 290198054Sjkim * FUNCTION: AcpiDmNormalizeParentPrefix 291198054Sjkim * 292198054Sjkim * PARAMETERS: Op - Parse op 293198054Sjkim * Path - Path with parent prefix 294198054Sjkim * 295198054Sjkim * RETURN: The full pathname to the object (from the namespace root) 296198054Sjkim * 297198054Sjkim * DESCRIPTION: Returns the full pathname of a path with parent prefix 298198054Sjkim * The caller must free the fullpath returned. 299198054Sjkim * 300198054Sjkim ******************************************************************************/ 301198054Sjkim 302198054Sjkimstatic char * 303198054SjkimAcpiDmNormalizeParentPrefix ( 304198054Sjkim ACPI_PARSE_OBJECT *Op, 305198054Sjkim char *Path) 306198054Sjkim{ 307198054Sjkim ACPI_NAMESPACE_NODE *Node; 308198054Sjkim char *Fullpath; 309198054Sjkim char *ParentPath; 310198054Sjkim ACPI_SIZE Length; 311243347Sjkim UINT32 Index = 0; 312198054Sjkim 313198054Sjkim 314243347Sjkim if (!Op) 315243347Sjkim { 316243347Sjkim return (NULL); 317243347Sjkim } 318198054Sjkim 319243347Sjkim /* Search upwards in the parse tree until we reach the next namespace node */ 320243347Sjkim 321243347Sjkim Op = Op->Common.Parent; 322198054Sjkim while (Op) 323198054Sjkim { 324198054Sjkim if (Op->Common.Node) 325198054Sjkim { 326198054Sjkim break; 327198054Sjkim } 328198054Sjkim 329198054Sjkim Op = Op->Common.Parent; 330198054Sjkim } 331198054Sjkim 332198054Sjkim if (!Op) 333198054Sjkim { 334198054Sjkim return (NULL); 335198054Sjkim } 336198054Sjkim 337198054Sjkim /* 338198054Sjkim * Find the actual parent node for the reference: 339198054Sjkim * Remove all carat prefixes from the input path. 340198054Sjkim * There may be multiple parent prefixes (For example, ^^^M000) 341198054Sjkim */ 342198054Sjkim Node = Op->Common.Node; 343198054Sjkim while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) 344198054Sjkim { 345209746Sjkim Node = Node->Parent; 346198054Sjkim Path++; 347198054Sjkim } 348198054Sjkim 349198054Sjkim if (!Node) 350198054Sjkim { 351198054Sjkim return (NULL); 352198054Sjkim } 353198054Sjkim 354198054Sjkim /* Get the full pathname for the parent node */ 355198054Sjkim 356198054Sjkim ParentPath = AcpiNsGetExternalPathname (Node); 357198054Sjkim if (!ParentPath) 358198054Sjkim { 359198054Sjkim return (NULL); 360198054Sjkim } 361198054Sjkim 362284583Sjkim Length = (strlen (ParentPath) + strlen (Path) + 1); 363206117Sjkim if (ParentPath[1]) 364206117Sjkim { 365206117Sjkim /* 366206117Sjkim * If ParentPath is not just a simple '\', increment the length 367206117Sjkim * for the required dot separator (ParentPath.Path) 368206117Sjkim */ 369206117Sjkim Length++; 370243347Sjkim 371243347Sjkim /* For External() statements, we do not want a leading '\' */ 372243347Sjkim 373243347Sjkim if (*ParentPath == AML_ROOT_PREFIX) 374243347Sjkim { 375243347Sjkim Index = 1; 376243347Sjkim } 377206117Sjkim } 378206117Sjkim 379198054Sjkim Fullpath = ACPI_ALLOCATE_ZEROED (Length); 380198054Sjkim if (!Fullpath) 381198054Sjkim { 382198054Sjkim goto Cleanup; 383198054Sjkim } 384198054Sjkim 385198054Sjkim /* 386198054Sjkim * Concatenate parent fullpath and path. For example, 387198054Sjkim * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" 388198054Sjkim * 389198054Sjkim * Copy the parent path 390198054Sjkim */ 391284583Sjkim strcpy (Fullpath, &ParentPath[Index]); 392198054Sjkim 393237412Sjkim /* 394237412Sjkim * Add dot separator 395237412Sjkim * (don't need dot if parent fullpath is a single backslash) 396237412Sjkim */ 397198054Sjkim if (ParentPath[1]) 398198054Sjkim { 399284583Sjkim strcat (Fullpath, "."); 400198054Sjkim } 401198054Sjkim 402198054Sjkim /* Copy child path (carat parent prefix(es) were skipped above) */ 403198054Sjkim 404284583Sjkim strcat (Fullpath, Path); 405198054Sjkim 406198054SjkimCleanup: 407198054Sjkim ACPI_FREE (ParentPath); 408198054Sjkim return (Fullpath); 409198054Sjkim} 410198054Sjkim 411198054Sjkim 412198054Sjkim/******************************************************************************* 413198054Sjkim * 414210976Sjkim * FUNCTION: AcpiDmAddToExternalFileList 415210976Sjkim * 416210976Sjkim * PARAMETERS: PathList - Single path or list separated by comma 417210976Sjkim * 418210976Sjkim * RETURN: None 419210976Sjkim * 420210976Sjkim * DESCRIPTION: Add external files to global list 421210976Sjkim * 422210976Sjkim ******************************************************************************/ 423210976Sjkim 424210976SjkimACPI_STATUS 425210976SjkimAcpiDmAddToExternalFileList ( 426272444Sjkim char *Pathname) 427210976Sjkim{ 428210976Sjkim ACPI_EXTERNAL_FILE *ExternalFile; 429272444Sjkim char *LocalPathname; 430210976Sjkim 431210976Sjkim 432272444Sjkim if (!Pathname) 433210976Sjkim { 434210976Sjkim return (AE_OK); 435210976Sjkim } 436210976Sjkim 437272444Sjkim LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1); 438272444Sjkim if (!LocalPathname) 439272444Sjkim { 440272444Sjkim return (AE_NO_MEMORY); 441272444Sjkim } 442210976Sjkim 443272444Sjkim ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE)); 444272444Sjkim if (!ExternalFile) 445210976Sjkim { 446272444Sjkim ACPI_FREE (LocalPathname); 447272444Sjkim return (AE_NO_MEMORY); 448272444Sjkim } 449210976Sjkim 450272444Sjkim /* Take a copy of the file pathname */ 451210976Sjkim 452272444Sjkim strcpy (LocalPathname, Pathname); 453272444Sjkim ExternalFile->Path = LocalPathname; 454210976Sjkim 455272444Sjkim if (AcpiGbl_ExternalFileList) 456272444Sjkim { 457272444Sjkim ExternalFile->Next = AcpiGbl_ExternalFileList; 458210976Sjkim } 459210976Sjkim 460272444Sjkim AcpiGbl_ExternalFileList = ExternalFile; 461210976Sjkim return (AE_OK); 462210976Sjkim} 463210976Sjkim 464210976Sjkim 465210976Sjkim/******************************************************************************* 466210976Sjkim * 467210976Sjkim * FUNCTION: AcpiDmClearExternalFileList 468210976Sjkim * 469210976Sjkim * PARAMETERS: None 470210976Sjkim * 471210976Sjkim * RETURN: None 472210976Sjkim * 473210976Sjkim * DESCRIPTION: Clear the external file list 474210976Sjkim * 475210976Sjkim ******************************************************************************/ 476210976Sjkim 477210976Sjkimvoid 478210976SjkimAcpiDmClearExternalFileList ( 479210976Sjkim void) 480210976Sjkim{ 481210976Sjkim ACPI_EXTERNAL_FILE *NextExternal; 482210976Sjkim 483210976Sjkim 484210976Sjkim while (AcpiGbl_ExternalFileList) 485210976Sjkim { 486210976Sjkim NextExternal = AcpiGbl_ExternalFileList->Next; 487210976Sjkim ACPI_FREE (AcpiGbl_ExternalFileList->Path); 488210976Sjkim ACPI_FREE (AcpiGbl_ExternalFileList); 489210976Sjkim AcpiGbl_ExternalFileList = NextExternal; 490210976Sjkim } 491210976Sjkim} 492210976Sjkim 493210976Sjkim 494210976Sjkim/******************************************************************************* 495210976Sjkim * 496272444Sjkim * FUNCTION: AcpiDmGetExternalsFromFile 497198054Sjkim * 498272444Sjkim * PARAMETERS: None 499272444Sjkim * 500272444Sjkim * RETURN: None 501272444Sjkim * 502272444Sjkim * DESCRIPTION: Process the optional external reference file. 503272444Sjkim * 504272444Sjkim * Each line in the file should be of the form: 505272444Sjkim * External (<Method namepath>, MethodObj, <ArgCount>) 506272444Sjkim * 507272444Sjkim * Example: 508272444Sjkim * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4) 509272444Sjkim * 510272444Sjkim ******************************************************************************/ 511272444Sjkim 512272444Sjkimvoid 513272444SjkimAcpiDmGetExternalsFromFile ( 514272444Sjkim void) 515272444Sjkim{ 516272444Sjkim FILE *ExternalRefFile; 517272444Sjkim char *Token; 518272444Sjkim char *MethodName; 519272444Sjkim UINT32 ArgCount; 520272444Sjkim UINT32 ImportCount = 0; 521272444Sjkim 522272444Sjkim 523272444Sjkim if (!Gbl_ExternalRefFilename) 524272444Sjkim { 525272444Sjkim return; 526272444Sjkim } 527272444Sjkim 528272444Sjkim /* Open the file */ 529272444Sjkim 530272444Sjkim ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r"); 531272444Sjkim if (!ExternalRefFile) 532272444Sjkim { 533272444Sjkim fprintf (stderr, "Could not open external reference file \"%s\"\n", 534272444Sjkim Gbl_ExternalRefFilename); 535272444Sjkim AslAbort (); 536272444Sjkim return; 537272444Sjkim } 538272444Sjkim 539272444Sjkim /* Each line defines a method */ 540272444Sjkim 541272444Sjkim while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile)) 542272444Sjkim { 543272444Sjkim Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */ 544272444Sjkim if (!Token) 545272444Sjkim { 546272444Sjkim continue; 547272444Sjkim } 548298714Sjkim 549272444Sjkim if (strcmp (Token, "External")) 550272444Sjkim { 551272444Sjkim continue; 552272444Sjkim } 553272444Sjkim 554272444Sjkim MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */ 555272444Sjkim if (!MethodName) 556272444Sjkim { 557272444Sjkim continue; 558272444Sjkim } 559272444Sjkim 560272444Sjkim Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */ 561272444Sjkim if (!Token) 562272444Sjkim { 563272444Sjkim continue; 564272444Sjkim } 565272444Sjkim 566272444Sjkim if (strcmp (Token, "MethodObj")) 567272444Sjkim { 568272444Sjkim continue; 569272444Sjkim } 570272444Sjkim 571272444Sjkim Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */ 572272444Sjkim if (!Token) 573272444Sjkim { 574272444Sjkim continue; 575272444Sjkim } 576272444Sjkim 577272444Sjkim /* Convert arg count string to an integer */ 578272444Sjkim 579272444Sjkim errno = 0; 580272444Sjkim ArgCount = strtoul (Token, NULL, 0); 581272444Sjkim if (errno) 582272444Sjkim { 583272444Sjkim fprintf (stderr, "Invalid argument count (%s)\n", Token); 584272444Sjkim continue; 585272444Sjkim } 586298714Sjkim 587272444Sjkim if (ArgCount > 7) 588272444Sjkim { 589272444Sjkim fprintf (stderr, "Invalid argument count (%u)\n", ArgCount); 590272444Sjkim continue; 591272444Sjkim } 592272444Sjkim 593272444Sjkim /* Add this external to the global list */ 594272444Sjkim 595272444Sjkim AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n", 596272444Sjkim Gbl_ExternalRefFilename, ArgCount, MethodName); 597272444Sjkim 598272444Sjkim AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD, 599272444Sjkim ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE)); 600272444Sjkim ImportCount++; 601272444Sjkim } 602272444Sjkim 603272444Sjkim if (!ImportCount) 604272444Sjkim { 605298714Sjkim fprintf (stderr, 606298714Sjkim "Did not find any external methods in reference file \"%s\"\n", 607272444Sjkim Gbl_ExternalRefFilename); 608272444Sjkim } 609272444Sjkim else 610272444Sjkim { 611272444Sjkim /* Add the external(s) to the namespace */ 612272444Sjkim 613322877Sjkim AcpiDmAddExternalListToNamespace (); 614272444Sjkim 615272444Sjkim AcpiOsPrintf ("%s: Imported %u external method definitions\n", 616272444Sjkim Gbl_ExternalRefFilename, ImportCount); 617272444Sjkim } 618272444Sjkim 619272444Sjkim fclose (ExternalRefFile); 620272444Sjkim} 621272444Sjkim 622272444Sjkim 623272444Sjkim/******************************************************************************* 624272444Sjkim * 625272444Sjkim * FUNCTION: AcpiDmAddOpToExternalList 626272444Sjkim * 627198054Sjkim * PARAMETERS: Op - Current parser Op 628198054Sjkim * Path - Internal (AML) path to the object 629198054Sjkim * Type - ACPI object type to be added 630198054Sjkim * Value - Arg count if adding a Method object 631272444Sjkim * Flags - To be passed to the external object 632198054Sjkim * 633198054Sjkim * RETURN: None 634198054Sjkim * 635198054Sjkim * DESCRIPTION: Insert a new name into the global list of Externals which 636198054Sjkim * will in turn be later emitted as an External() declaration 637198054Sjkim * in the disassembled output. 638198054Sjkim * 639272444Sjkim * This function handles the most common case where the referenced 640272444Sjkim * name is simply not found in the constructed namespace. 641272444Sjkim * 642198054Sjkim ******************************************************************************/ 643198054Sjkim 644198054Sjkimvoid 645272444SjkimAcpiDmAddOpToExternalList ( 646198054Sjkim ACPI_PARSE_OBJECT *Op, 647198054Sjkim char *Path, 648198054Sjkim UINT8 Type, 649272444Sjkim UINT32 Value, 650272444Sjkim UINT16 Flags) 651198054Sjkim{ 652198054Sjkim char *ExternalPath; 653272444Sjkim char *InternalPath = Path; 654272444Sjkim char *Temp; 655198054Sjkim ACPI_STATUS Status; 656198054Sjkim 657198054Sjkim 658272444Sjkim ACPI_FUNCTION_TRACE (DmAddOpToExternalList); 659272444Sjkim 660272444Sjkim 661198054Sjkim if (!Path) 662198054Sjkim { 663272444Sjkim return_VOID; 664198054Sjkim } 665198054Sjkim 666272444Sjkim /* Remove a root backslash if present */ 667246849Sjkim 668243347Sjkim if ((*Path == AML_ROOT_PREFIX) && (Path[1])) 669243347Sjkim { 670243347Sjkim Path++; 671243347Sjkim } 672198054Sjkim 673272444Sjkim /* Externalize the pathname */ 674243347Sjkim 675198054Sjkim Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, 676272444Sjkim NULL, &ExternalPath); 677198054Sjkim if (ACPI_FAILURE (Status)) 678198054Sjkim { 679272444Sjkim return_VOID; 680198054Sjkim } 681198054Sjkim 682243347Sjkim /* 683243347Sjkim * Get the full pathname from the root if "Path" has one or more 684243347Sjkim * parent prefixes (^). Note: path will not contain a leading '\'. 685243347Sjkim */ 686198054Sjkim if (*Path == (UINT8) AML_PARENT_PREFIX) 687198054Sjkim { 688272444Sjkim Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath); 689198054Sjkim 690272444Sjkim /* Set new external path */ 691198054Sjkim 692272444Sjkim ACPI_FREE (ExternalPath); 693272444Sjkim ExternalPath = Temp; 694272444Sjkim if (!Temp) 695198054Sjkim { 696272444Sjkim return_VOID; 697198054Sjkim } 698198054Sjkim 699272444Sjkim /* Create the new internal pathname */ 700198054Sjkim 701272444Sjkim Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED; 702272444Sjkim Status = AcpiNsInternalizeName (ExternalPath, &InternalPath); 703198054Sjkim if (ACPI_FAILURE (Status)) 704198054Sjkim { 705198054Sjkim ACPI_FREE (ExternalPath); 706272444Sjkim return_VOID; 707198054Sjkim } 708198054Sjkim } 709198054Sjkim 710272444Sjkim /* Create the new External() declaration node */ 711198054Sjkim 712272444Sjkim Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, 713272444Sjkim Type, Value, Flags); 714272444Sjkim if (ACPI_FAILURE (Status)) 715198054Sjkim { 716272444Sjkim ACPI_FREE (ExternalPath); 717272444Sjkim if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED) 718198054Sjkim { 719272444Sjkim ACPI_FREE (InternalPath); 720198054Sjkim } 721198054Sjkim } 722198054Sjkim 723272444Sjkim return_VOID; 724198054Sjkim} 725198054Sjkim 726198054Sjkim 727198054Sjkim/******************************************************************************* 728198054Sjkim * 729322877Sjkim * FUNCTION: AcpiDmGetExternalAndInternalPath 730322877Sjkim * 731322877Sjkim * PARAMETERS: Node - Namespace node for object to be added 732322877Sjkim * ExternalPath - Will contain the external path of the node 733322877Sjkim * InternalPath - Will contain the internal path of the node 734322877Sjkim * 735322877Sjkim * RETURN: None 736322877Sjkim * 737322877Sjkim * DESCRIPTION: Get the External and Internal path from the given node. 738322877Sjkim * 739322877Sjkim ******************************************************************************/ 740322877Sjkim 741322877Sjkimstatic ACPI_STATUS 742322877SjkimAcpiDmGetExternalAndInternalPath ( 743322877Sjkim ACPI_NAMESPACE_NODE *Node, 744322877Sjkim char **ExternalPath, 745322877Sjkim char **InternalPath) 746322877Sjkim{ 747322877Sjkim ACPI_STATUS Status; 748322877Sjkim 749322877Sjkim 750322877Sjkim if (!Node) 751322877Sjkim { 752322877Sjkim return (AE_BAD_PARAMETER); 753322877Sjkim } 754322877Sjkim 755322877Sjkim /* Get the full external and internal pathnames to the node */ 756322877Sjkim 757322877Sjkim *ExternalPath = AcpiNsGetExternalPathname (Node); 758322877Sjkim if (!*ExternalPath) 759322877Sjkim { 760322877Sjkim return (AE_BAD_PATHNAME); 761322877Sjkim } 762322877Sjkim 763322877Sjkim Status = AcpiNsInternalizeName (*ExternalPath, InternalPath); 764322877Sjkim if (ACPI_FAILURE (Status)) 765322877Sjkim { 766322877Sjkim ACPI_FREE (*ExternalPath); 767322877Sjkim return (Status); 768322877Sjkim } 769322877Sjkim 770322877Sjkim return (AE_OK); 771322877Sjkim} 772322877Sjkim 773322877Sjkim 774322877Sjkim/******************************************************************************* 775322877Sjkim * 776322877Sjkim * FUNCTION: AcpiDmRemoveRootPrefix 777322877Sjkim * 778322877Sjkim * PARAMETERS: Path - Remove Root prefix from this Path 779322877Sjkim * 780322877Sjkim * RETURN: None 781322877Sjkim * 782322877Sjkim * DESCRIPTION: Remove the root prefix character '\' from Path. 783322877Sjkim * 784322877Sjkim ******************************************************************************/ 785322877Sjkim 786322877Sjkimstatic ACPI_STATUS 787322877SjkimAcpiDmRemoveRootPrefix ( 788322877Sjkim char **Path) 789322877Sjkim{ 790322877Sjkim char *InputPath = *Path; 791322877Sjkim 792322877Sjkim 793322877Sjkim if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1])) 794322877Sjkim { 795322877Sjkim if (!memmove(InputPath, InputPath+1, strlen(InputPath))) 796322877Sjkim { 797322877Sjkim return (AE_ERROR); 798322877Sjkim } 799322877Sjkim 800322877Sjkim *Path = InputPath; 801322877Sjkim } 802322877Sjkim 803322877Sjkim return (AE_OK); 804322877Sjkim} 805322877Sjkim 806322877Sjkim 807322877Sjkim/******************************************************************************* 808322877Sjkim * 809272444Sjkim * FUNCTION: AcpiDmAddNodeToExternalList 810254745Sjkim * 811272444Sjkim * PARAMETERS: Node - Namespace node for object to be added 812272444Sjkim * Type - ACPI object type to be added 813272444Sjkim * Value - Arg count if adding a Method object 814272444Sjkim * Flags - To be passed to the external object 815254745Sjkim * 816254745Sjkim * RETURN: None 817254745Sjkim * 818272444Sjkim * DESCRIPTION: Insert a new name into the global list of Externals which 819272444Sjkim * will in turn be later emitted as an External() declaration 820272444Sjkim * in the disassembled output. 821254745Sjkim * 822272444Sjkim * This function handles the case where the referenced name has 823272444Sjkim * been found in the namespace, but the name originated in a 824272444Sjkim * table other than the one that is being disassembled (such 825272444Sjkim * as a table that is added via the iASL -e option). 826254745Sjkim * 827254745Sjkim ******************************************************************************/ 828254745Sjkim 829254745Sjkimvoid 830272444SjkimAcpiDmAddNodeToExternalList ( 831272444Sjkim ACPI_NAMESPACE_NODE *Node, 832272444Sjkim UINT8 Type, 833272444Sjkim UINT32 Value, 834272444Sjkim UINT16 Flags) 835254745Sjkim{ 836272444Sjkim char *ExternalPath; 837272444Sjkim char *InternalPath; 838272444Sjkim ACPI_STATUS Status; 839254745Sjkim 840254745Sjkim 841272444Sjkim ACPI_FUNCTION_TRACE (DmAddNodeToExternalList); 842272444Sjkim 843272444Sjkim /* Get the full external and internal pathnames to the node */ 844254745Sjkim 845322877Sjkim Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath); 846272444Sjkim if (ACPI_FAILURE (Status)) 847254745Sjkim { 848272444Sjkim return_VOID; 849272444Sjkim } 850254745Sjkim 851272444Sjkim /* Remove the root backslash */ 852254745Sjkim 853322877Sjkim Status = AcpiDmRemoveRootPrefix (&ExternalPath); 854322877Sjkim if (ACPI_FAILURE (Status)) 855272444Sjkim { 856272444Sjkim ACPI_FREE (ExternalPath); 857322877Sjkim ACPI_FREE (InternalPath); 858322877Sjkim return_VOID; 859272444Sjkim } 860254745Sjkim 861272444Sjkim /* Create the new External() declaration node */ 862254745Sjkim 863272444Sjkim Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type, 864272444Sjkim Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED)); 865272444Sjkim if (ACPI_FAILURE (Status)) 866254745Sjkim { 867272444Sjkim ACPI_FREE (ExternalPath); 868272444Sjkim ACPI_FREE (InternalPath); 869254745Sjkim } 870254745Sjkim 871272444Sjkim return_VOID; 872254745Sjkim} 873254745Sjkim 874254745Sjkim 875254745Sjkim/******************************************************************************* 876254745Sjkim * 877272444Sjkim * FUNCTION: AcpiDmAddPathToExternalList 878254745Sjkim * 879272444Sjkim * PARAMETERS: Path - External name of the object to be added 880254745Sjkim * Type - ACPI object type to be added 881254745Sjkim * Value - Arg count if adding a Method object 882272444Sjkim * Flags - To be passed to the external object 883254745Sjkim * 884254745Sjkim * RETURN: None 885254745Sjkim * 886254745Sjkim * DESCRIPTION: Insert a new name into the global list of Externals which 887254745Sjkim * will in turn be later emitted as an External() declaration 888254745Sjkim * in the disassembled output. 889254745Sjkim * 890272444Sjkim * This function currently is used to add externals via a 891272444Sjkim * reference file (via the -fe iASL option). 892272444Sjkim * 893254745Sjkim ******************************************************************************/ 894254745Sjkim 895254745Sjkimstatic void 896272444SjkimAcpiDmAddPathToExternalList ( 897254745Sjkim char *Path, 898254745Sjkim UINT8 Type, 899272444Sjkim UINT32 Value, 900272444Sjkim UINT16 Flags) 901254745Sjkim{ 902254745Sjkim char *InternalPath; 903254745Sjkim char *ExternalPath; 904254745Sjkim ACPI_STATUS Status; 905254745Sjkim 906254745Sjkim 907272444Sjkim ACPI_FUNCTION_TRACE (DmAddPathToExternalList); 908272444Sjkim 909272444Sjkim 910254745Sjkim if (!Path) 911254745Sjkim { 912272444Sjkim return_VOID; 913254745Sjkim } 914254745Sjkim 915272444Sjkim /* Remove a root backslash if present */ 916254745Sjkim 917272444Sjkim if ((*Path == AML_ROOT_PREFIX) && (Path[1])) 918254745Sjkim { 919272444Sjkim Path++; 920254745Sjkim } 921254745Sjkim 922272444Sjkim /* Create the internal and external pathnames */ 923272444Sjkim 924272444Sjkim Status = AcpiNsInternalizeName (Path, &InternalPath); 925272444Sjkim if (ACPI_FAILURE (Status)) 926254745Sjkim { 927272444Sjkim return_VOID; 928254745Sjkim } 929254745Sjkim 930272444Sjkim Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath, 931272444Sjkim NULL, &ExternalPath); 932272444Sjkim if (ACPI_FAILURE (Status)) 933272444Sjkim { 934272444Sjkim ACPI_FREE (InternalPath); 935272444Sjkim return_VOID; 936272444Sjkim } 937272444Sjkim 938272444Sjkim /* Create the new External() declaration node */ 939272444Sjkim 940272444Sjkim Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, 941272444Sjkim Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED)); 942272444Sjkim if (ACPI_FAILURE (Status)) 943272444Sjkim { 944272444Sjkim ACPI_FREE (ExternalPath); 945272444Sjkim ACPI_FREE (InternalPath); 946272444Sjkim } 947272444Sjkim 948272444Sjkim return_VOID; 949272444Sjkim} 950272444Sjkim 951272444Sjkim 952272444Sjkim/******************************************************************************* 953272444Sjkim * 954272444Sjkim * FUNCTION: AcpiDmCreateNewExternal 955272444Sjkim * 956272444Sjkim * PARAMETERS: ExternalPath - External path to the object 957272444Sjkim * InternalPath - Internal (AML) path to the object 958272444Sjkim * Type - ACPI object type to be added 959272444Sjkim * Value - Arg count if adding a Method object 960272444Sjkim * Flags - To be passed to the external object 961272444Sjkim * 962272444Sjkim * RETURN: Status 963272444Sjkim * 964272444Sjkim * DESCRIPTION: Common low-level function to insert a new name into the global 965272444Sjkim * list of Externals which will in turn be later emitted as 966272444Sjkim * External() declarations in the disassembled output. 967272444Sjkim * 968272444Sjkim * Note: The external name should not include a root prefix 969272444Sjkim * (backslash). We do not want External() statements to contain 970272444Sjkim * a leading '\', as this prevents duplicate external statements 971272444Sjkim * of the form: 972272444Sjkim * 973272444Sjkim * External (\ABCD) 974272444Sjkim * External (ABCD) 975272444Sjkim * 976272444Sjkim * This would cause a compile time error when the disassembled 977272444Sjkim * output file is recompiled. 978272444Sjkim * 979272444Sjkim * There are two cases that are handled here. For both, we emit 980272444Sjkim * an External() statement: 981272444Sjkim * 1) The name was simply not found in the namespace. 982272444Sjkim * 2) The name was found, but it originated in a table other than 983272444Sjkim * the table that is being disassembled. 984272444Sjkim * 985272444Sjkim ******************************************************************************/ 986272444Sjkim 987272444Sjkimstatic ACPI_STATUS 988272444SjkimAcpiDmCreateNewExternal ( 989272444Sjkim char *ExternalPath, 990272444Sjkim char *InternalPath, 991272444Sjkim UINT8 Type, 992272444Sjkim UINT32 Value, 993272444Sjkim UINT16 Flags) 994272444Sjkim{ 995272444Sjkim ACPI_EXTERNAL_LIST *NewExternal; 996272444Sjkim ACPI_EXTERNAL_LIST *NextExternal; 997272444Sjkim ACPI_EXTERNAL_LIST *PrevExternal = NULL; 998272444Sjkim 999272444Sjkim 1000272444Sjkim ACPI_FUNCTION_TRACE (DmCreateNewExternal); 1001272444Sjkim 1002272444Sjkim 1003254745Sjkim /* Check all existing externals to ensure no duplicates */ 1004254745Sjkim 1005254745Sjkim NextExternal = AcpiGbl_ExternalList; 1006254745Sjkim while (NextExternal) 1007254745Sjkim { 1008298714Sjkim /* Check for duplicates */ 1009298714Sjkim 1010284583Sjkim if (!strcmp (ExternalPath, NextExternal->Path)) 1011254745Sjkim { 1012298714Sjkim /* 1013298714Sjkim * If this external came from an External() opcode, we are 1014298714Sjkim * finished with this one. (No need to check any further). 1015298714Sjkim */ 1016298714Sjkim if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE) 1017254745Sjkim { 1018298714Sjkim return_ACPI_STATUS (AE_ALREADY_EXISTS); 1019254745Sjkim } 1020254745Sjkim 1021254745Sjkim /* Allow upgrade of type from ANY */ 1022254745Sjkim 1023298714Sjkim else if ((NextExternal->Type == ACPI_TYPE_ANY) && 1024298714Sjkim (Type != ACPI_TYPE_ANY)) 1025254745Sjkim { 1026254745Sjkim NextExternal->Type = Type; 1027298714Sjkim } 1028298714Sjkim 1029298714Sjkim /* Update the argument count as necessary */ 1030298714Sjkim 1031298714Sjkim if (Value < NextExternal->Value) 1032298714Sjkim { 1033254745Sjkim NextExternal->Value = Value; 1034254745Sjkim } 1035254745Sjkim 1036298714Sjkim /* Update flags. */ 1037298714Sjkim 1038298714Sjkim NextExternal->Flags |= Flags; 1039298714Sjkim NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED; 1040298714Sjkim 1041272444Sjkim return_ACPI_STATUS (AE_ALREADY_EXISTS); 1042254745Sjkim } 1043254745Sjkim 1044254745Sjkim NextExternal = NextExternal->Next; 1045254745Sjkim } 1046254745Sjkim 1047254745Sjkim /* Allocate and init a new External() descriptor */ 1048254745Sjkim 1049254745Sjkim NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); 1050254745Sjkim if (!NewExternal) 1051254745Sjkim { 1052272444Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 1053254745Sjkim } 1054254745Sjkim 1055272444Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 1056272444Sjkim "Adding external reference node (%s) type [%s]\n", 1057272444Sjkim ExternalPath, AcpiUtGetTypeName (Type))); 1058254745Sjkim 1059272444Sjkim NewExternal->Flags = Flags; 1060272444Sjkim NewExternal->Value = Value; 1061254745Sjkim NewExternal->Path = ExternalPath; 1062254745Sjkim NewExternal->Type = Type; 1063284583Sjkim NewExternal->Length = (UINT16) strlen (ExternalPath); 1064254745Sjkim NewExternal->InternalPath = InternalPath; 1065254745Sjkim 1066254745Sjkim /* Link the new descriptor into the global list, alphabetically ordered */ 1067254745Sjkim 1068254745Sjkim NextExternal = AcpiGbl_ExternalList; 1069254745Sjkim while (NextExternal) 1070254745Sjkim { 1071254745Sjkim if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0) 1072254745Sjkim { 1073254745Sjkim if (PrevExternal) 1074254745Sjkim { 1075254745Sjkim PrevExternal->Next = NewExternal; 1076254745Sjkim } 1077254745Sjkim else 1078254745Sjkim { 1079254745Sjkim AcpiGbl_ExternalList = NewExternal; 1080254745Sjkim } 1081254745Sjkim 1082254745Sjkim NewExternal->Next = NextExternal; 1083272444Sjkim return_ACPI_STATUS (AE_OK); 1084254745Sjkim } 1085254745Sjkim 1086254745Sjkim PrevExternal = NextExternal; 1087254745Sjkim NextExternal = NextExternal->Next; 1088254745Sjkim } 1089254745Sjkim 1090254745Sjkim if (PrevExternal) 1091254745Sjkim { 1092254745Sjkim PrevExternal->Next = NewExternal; 1093254745Sjkim } 1094254745Sjkim else 1095254745Sjkim { 1096254745Sjkim AcpiGbl_ExternalList = NewExternal; 1097254745Sjkim } 1098272444Sjkim 1099272444Sjkim return_ACPI_STATUS (AE_OK); 1100254745Sjkim} 1101254745Sjkim 1102254745Sjkim 1103254745Sjkim/******************************************************************************* 1104254745Sjkim * 1105322877Sjkim * FUNCTION: AcpiDmResolveExternal 1106198054Sjkim * 1107322877Sjkim * PARAMETERS: Path - Path of the external 1108322877Sjkim * Type - Type of the external 1109322877Sjkim * Node - Input node for AcpiNsLookup 1110198054Sjkim * 1111322877Sjkim * RETURN: Status 1112322877Sjkim * 1113322877Sjkim * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup. 1114322877Sjkim * If the returned node is an external and has the same type 1115322877Sjkim * we assume that it was either an existing external or a 1116322877Sjkim * 1117322877Sjkim ******************************************************************************/ 1118322877Sjkim 1119322877Sjkimstatic ACPI_STATUS 1120322877SjkimAcpiDmResolveExternal ( 1121322877Sjkim char *Path, 1122322877Sjkim UINT8 Type, 1123322877Sjkim ACPI_NAMESPACE_NODE **Node) 1124322877Sjkim{ 1125322877Sjkim ACPI_STATUS Status; 1126322877Sjkim 1127322877Sjkim 1128322877Sjkim Status = AcpiNsLookup (NULL, Path, Type, 1129322877Sjkim ACPI_IMODE_LOAD_PASS1, 1130322877Sjkim ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, 1131322877Sjkim NULL, Node); 1132322877Sjkim 1133322877Sjkim if (!Node) 1134322877Sjkim { 1135322877Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 1136322877Sjkim "while adding external to namespace [%s]", Path)); 1137322877Sjkim } 1138322877Sjkim 1139322877Sjkim /* Note the asl code "external(a) external(a)" is acceptable ASL */ 1140322877Sjkim 1141322877Sjkim else if ((*Node)->Type == Type && 1142322877Sjkim (*Node)->Flags & ANOBJ_IS_EXTERNAL) 1143322877Sjkim { 1144322877Sjkim return (AE_OK); 1145322877Sjkim } 1146322877Sjkim else 1147322877Sjkim { 1148322877Sjkim ACPI_EXCEPTION ((AE_INFO, AE_ERROR, 1149322877Sjkim "[%s] has conflicting declarations", Path)); 1150322877Sjkim } 1151322877Sjkim 1152322877Sjkim return (AE_ERROR); 1153322877Sjkim} 1154322877Sjkim 1155322877Sjkim 1156322877Sjkim/******************************************************************************* 1157322877Sjkim * 1158322877Sjkim * FUNCTION: AcpiDmCreateSubobjectForExternal 1159322877Sjkim * 1160322877Sjkim * PARAMETERS: Type - Type of the external 1161322877Sjkim * Node - Namespace node from AcpiNsLookup 1162322877Sjkim * ParamCount - Value to be used for Method 1163322877Sjkim * 1164198054Sjkim * RETURN: None 1165198054Sjkim * 1166322877Sjkim * DESCRIPTION: Add one external to the namespace. Allows external to be 1167198054Sjkim * "resolved". 1168198054Sjkim * 1169198054Sjkim ******************************************************************************/ 1170198054Sjkim 1171198054Sjkimvoid 1172322877SjkimAcpiDmCreateSubobjectForExternal ( 1173322877Sjkim UINT8 Type, 1174322877Sjkim ACPI_NAMESPACE_NODE **Node, 1175322877Sjkim UINT32 ParamCount) 1176198054Sjkim{ 1177235945Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 1178198054Sjkim 1179198054Sjkim 1180322877Sjkim switch (Type) 1181198054Sjkim { 1182322877Sjkim case ACPI_TYPE_METHOD: 1183198054Sjkim 1184322877Sjkim /* For methods, we need to save the argument count */ 1185198054Sjkim 1186322877Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 1187322877Sjkim ObjDesc->Method.ParamCount = (UINT8) ParamCount; 1188322877Sjkim (*Node)->Object = ObjDesc; 1189322877Sjkim break; 1190235945Sjkim 1191322877Sjkim case ACPI_TYPE_REGION: 1192235945Sjkim 1193322877Sjkim /* Regions require a region sub-object */ 1194198054Sjkim 1195322877Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 1196322877Sjkim ObjDesc->Region.Node = *Node; 1197322877Sjkim (*Node)->Object = ObjDesc; 1198322877Sjkim break; 1199235945Sjkim 1200322877Sjkim default: 1201235945Sjkim 1202322877Sjkim break; 1203322877Sjkim } 1204322877Sjkim} 1205235945Sjkim 1206235945Sjkim 1207322877Sjkim/******************************************************************************* 1208322877Sjkim * 1209322877Sjkim * FUNCTION: AcpiDmAddOneExternalToNamespace 1210322877Sjkim * 1211322877Sjkim * PARAMETERS: Path - External parse object 1212322877Sjkim * Type - Type of parse object 1213322877Sjkim * ParamCount - External method parameter count 1214322877Sjkim * 1215322877Sjkim * RETURN: None 1216322877Sjkim * 1217322877Sjkim * DESCRIPTION: Add one external to the namespace by resolvign the external 1218322877Sjkim * (by performing a namespace lookup) and annotating the resulting 1219322877Sjkim * namespace node with the approperiate information if the type 1220322877Sjkim * is ACPI_TYPE_REGION or ACPI_TYPE_METHOD. 1221322877Sjkim * 1222322877Sjkim ******************************************************************************/ 1223250838Sjkim 1224322877Sjkimvoid 1225322877SjkimAcpiDmAddOneExternalToNamespace ( 1226322877Sjkim char *Path, 1227322877Sjkim UINT8 Type, 1228322877Sjkim UINT32 ParamCount) 1229322877Sjkim{ 1230322877Sjkim ACPI_STATUS Status; 1231322877Sjkim ACPI_NAMESPACE_NODE *Node; 1232198054Sjkim 1233322877Sjkim 1234322877Sjkim Status = AcpiDmResolveExternal (Path, Type, &Node); 1235322877Sjkim 1236322877Sjkim if (ACPI_FAILURE (Status)) 1237322877Sjkim { 1238322877Sjkim return; 1239322877Sjkim } 1240322877Sjkim 1241322877Sjkim AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount); 1242322877Sjkim 1243322877Sjkim} 1244322877Sjkim 1245322877Sjkim 1246322877Sjkim/******************************************************************************* 1247322877Sjkim * 1248322877Sjkim * FUNCTION: AcpiDmAddExternalListToNamespace 1249322877Sjkim * 1250322877Sjkim * PARAMETERS: None 1251322877Sjkim * 1252322877Sjkim * RETURN: None 1253322877Sjkim * 1254322877Sjkim * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace. 1255322877Sjkim * Allows externals to be "resolved". 1256322877Sjkim * 1257322877Sjkim ******************************************************************************/ 1258322877Sjkim 1259322877Sjkimvoid 1260322877SjkimAcpiDmAddExternalListToNamespace ( 1261322877Sjkim void) 1262322877Sjkim{ 1263322877Sjkim ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 1264322877Sjkim 1265322877Sjkim 1266322877Sjkim while (External) 1267322877Sjkim { 1268322877Sjkim AcpiDmAddOneExternalToNamespace (External->InternalPath, 1269322877Sjkim External->Type, External->Value); 1270198054Sjkim External = External->Next; 1271198054Sjkim } 1272198054Sjkim} 1273198054Sjkim 1274198054Sjkim 1275198054Sjkim/******************************************************************************* 1276198054Sjkim * 1277322877Sjkim * FUNCTION: AcpiDmGetUnresolvedExternalMethodCount 1278198054Sjkim * 1279198054Sjkim * PARAMETERS: None 1280198054Sjkim * 1281322877Sjkim * RETURN: The number of unresolved control method externals in the 1282322877Sjkim * external list 1283198054Sjkim * 1284322877Sjkim * DESCRIPTION: Return the number of unresolved external methods that have been 1285322877Sjkim * generated. If any unresolved control method externals have been 1286322877Sjkim * found, we must re-parse the entire definition block with the new 1287322877Sjkim * information (number of arguments for the methods.) 1288322877Sjkim * This is limitation of AML, we don't know the number of arguments 1289322877Sjkim * from the control method invocation itself. 1290198054Sjkim * 1291322877Sjkim * Note: resolved external control methods are external control 1292322877Sjkim * methods encoded with the AML_EXTERNAL_OP bytecode within the 1293322877Sjkim * AML being disassembled. 1294322877Sjkim * 1295198054Sjkim ******************************************************************************/ 1296198054Sjkim 1297198054SjkimUINT32 1298322877SjkimAcpiDmGetUnresolvedExternalMethodCount ( 1299198054Sjkim void) 1300198054Sjkim{ 1301198054Sjkim ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 1302198054Sjkim UINT32 Count = 0; 1303198054Sjkim 1304198054Sjkim 1305198054Sjkim while (External) 1306198054Sjkim { 1307322877Sjkim if (External->Type == ACPI_TYPE_METHOD && 1308322877Sjkim !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)) 1309198054Sjkim { 1310198054Sjkim Count++; 1311198054Sjkim } 1312198054Sjkim 1313198054Sjkim External = External->Next; 1314198054Sjkim } 1315198054Sjkim 1316198054Sjkim return (Count); 1317198054Sjkim} 1318198054Sjkim 1319198054Sjkim 1320198054Sjkim/******************************************************************************* 1321198054Sjkim * 1322198054Sjkim * FUNCTION: AcpiDmClearExternalList 1323198054Sjkim * 1324198054Sjkim * PARAMETERS: None 1325198054Sjkim * 1326198054Sjkim * RETURN: None 1327198054Sjkim * 1328198054Sjkim * DESCRIPTION: Free the entire External info list 1329198054Sjkim * 1330198054Sjkim ******************************************************************************/ 1331198054Sjkim 1332198054Sjkimvoid 1333198054SjkimAcpiDmClearExternalList ( 1334198054Sjkim void) 1335198054Sjkim{ 1336198054Sjkim ACPI_EXTERNAL_LIST *NextExternal; 1337198054Sjkim 1338198054Sjkim 1339198054Sjkim while (AcpiGbl_ExternalList) 1340198054Sjkim { 1341198054Sjkim NextExternal = AcpiGbl_ExternalList->Next; 1342198054Sjkim ACPI_FREE (AcpiGbl_ExternalList->Path); 1343198054Sjkim ACPI_FREE (AcpiGbl_ExternalList); 1344198054Sjkim AcpiGbl_ExternalList = NextExternal; 1345198054Sjkim } 1346198054Sjkim} 1347198054Sjkim 1348198054Sjkim 1349198054Sjkim/******************************************************************************* 1350198054Sjkim * 1351198054Sjkim * FUNCTION: AcpiDmEmitExternals 1352198054Sjkim * 1353198054Sjkim * PARAMETERS: None 1354198054Sjkim * 1355198054Sjkim * RETURN: None 1356198054Sjkim * 1357198054Sjkim * DESCRIPTION: Emit an External() ASL statement for each of the externals in 1358198054Sjkim * the global external info list. 1359198054Sjkim * 1360198054Sjkim ******************************************************************************/ 1361198054Sjkim 1362198054Sjkimvoid 1363198054SjkimAcpiDmEmitExternals ( 1364198054Sjkim void) 1365198054Sjkim{ 1366198054Sjkim ACPI_EXTERNAL_LIST *NextExternal; 1367198054Sjkim 1368198054Sjkim 1369198054Sjkim if (!AcpiGbl_ExternalList) 1370198054Sjkim { 1371198054Sjkim return; 1372198054Sjkim } 1373198054Sjkim 1374198054Sjkim /* 1375246849Sjkim * Determine the number of control methods in the external list, and 1376246849Sjkim * also how many of those externals were resolved via the namespace. 1377246849Sjkim */ 1378246849Sjkim NextExternal = AcpiGbl_ExternalList; 1379246849Sjkim while (NextExternal) 1380246849Sjkim { 1381246849Sjkim if (NextExternal->Type == ACPI_TYPE_METHOD) 1382246849Sjkim { 1383246849Sjkim AcpiGbl_NumExternalMethods++; 1384272444Sjkim if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE) 1385246849Sjkim { 1386246849Sjkim AcpiGbl_ResolvedExternalMethods++; 1387246849Sjkim } 1388246849Sjkim } 1389246849Sjkim 1390246849Sjkim NextExternal = NextExternal->Next; 1391246849Sjkim } 1392246849Sjkim 1393246849Sjkim /* Check if any control methods were unresolved */ 1394246849Sjkim 1395246849Sjkim AcpiDmUnresolvedWarning (1); 1396246849Sjkim 1397254745Sjkim if (Gbl_ExternalRefFilename) 1398254745Sjkim { 1399254745Sjkim AcpiOsPrintf ( 1400298714Sjkim " /*\n * External declarations were imported from\n" 1401298714Sjkim " * a reference file -- %s\n */\n\n", 1402254745Sjkim Gbl_ExternalRefFilename); 1403254745Sjkim } 1404254745Sjkim 1405246849Sjkim /* 1406298714Sjkim * Walk and emit the list of externals found during the AML parsing 1407198054Sjkim */ 1408198054Sjkim while (AcpiGbl_ExternalList) 1409198054Sjkim { 1410272444Sjkim if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED)) 1411253690Sjkim { 1412298714Sjkim AcpiOsPrintf (" External (%s%s)", 1413253690Sjkim AcpiGbl_ExternalList->Path, 1414253690Sjkim AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); 1415198054Sjkim 1416298714Sjkim /* Check for "unresolved" method reference */ 1417253690Sjkim 1418298714Sjkim if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) && 1419298714Sjkim (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE))) 1420246849Sjkim { 1421298714Sjkim AcpiOsPrintf (" // Warning: Unknown method, " 1422298714Sjkim "guessing %u arguments", 1423246849Sjkim AcpiGbl_ExternalList->Value); 1424246849Sjkim } 1425298714Sjkim 1426298714Sjkim /* Check for external from a external references file */ 1427298714Sjkim 1428298714Sjkim else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE) 1429298714Sjkim { 1430298714Sjkim if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 1431298714Sjkim { 1432298714Sjkim AcpiOsPrintf (" // %u Arguments", 1433298714Sjkim AcpiGbl_ExternalList->Value); 1434298714Sjkim } 1435298714Sjkim 1436298714Sjkim AcpiOsPrintf (" // From external reference file"); 1437298714Sjkim } 1438298714Sjkim 1439298714Sjkim /* This is the normal external case */ 1440298714Sjkim 1441246849Sjkim else 1442246849Sjkim { 1443298714Sjkim /* For methods, add a comment with the number of arguments */ 1444298714Sjkim 1445298714Sjkim if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 1446298714Sjkim { 1447298714Sjkim AcpiOsPrintf (" // %u Arguments", 1448298714Sjkim AcpiGbl_ExternalList->Value); 1449298714Sjkim } 1450246849Sjkim } 1451298714Sjkim 1452322877Sjkim if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION) 1453322877Sjkim { 1454322877Sjkim AcpiOsPrintf ("%s", ExternalConflictMessage); 1455322877Sjkim AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path); 1456322877Sjkim } 1457298714Sjkim AcpiOsPrintf ("\n"); 1458198054Sjkim } 1459198054Sjkim 1460198054Sjkim /* Free this external info block and move on to next external */ 1461198054Sjkim 1462198054Sjkim NextExternal = AcpiGbl_ExternalList->Next; 1463272444Sjkim if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED) 1464198054Sjkim { 1465198054Sjkim ACPI_FREE (AcpiGbl_ExternalList->InternalPath); 1466198054Sjkim } 1467198054Sjkim 1468198054Sjkim ACPI_FREE (AcpiGbl_ExternalList->Path); 1469198054Sjkim ACPI_FREE (AcpiGbl_ExternalList); 1470198054Sjkim AcpiGbl_ExternalList = NextExternal; 1471198054Sjkim } 1472198054Sjkim 1473198054Sjkim AcpiOsPrintf ("\n"); 1474198054Sjkim} 1475246849Sjkim 1476246849Sjkim 1477246849Sjkim/******************************************************************************* 1478246849Sjkim * 1479322877Sjkim * FUNCTION: AcpiDmMarkExternalConflict 1480322877Sjkim * 1481322877Sjkim * PARAMETERS: Path - Namepath to search 1482322877Sjkim * 1483322877Sjkim * RETURN: ExternalList 1484322877Sjkim * 1485322877Sjkim * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path 1486322877Sjkim * 1487322877Sjkim ******************************************************************************/ 1488322877Sjkim 1489322877Sjkimvoid 1490322877SjkimAcpiDmMarkExternalConflict ( 1491322877Sjkim ACPI_NAMESPACE_NODE *Node) 1492322877Sjkim{ 1493322877Sjkim ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList; 1494322877Sjkim char *ExternalPath; 1495322877Sjkim char *InternalPath; 1496322877Sjkim char *Temp; 1497322877Sjkim ACPI_STATUS Status; 1498322877Sjkim 1499322877Sjkim 1500322877Sjkim ACPI_FUNCTION_TRACE (DmMarkExternalConflict); 1501322877Sjkim 1502322877Sjkim 1503322877Sjkim if (Node->Flags & ANOBJ_IS_EXTERNAL) 1504322877Sjkim { 1505322877Sjkim return_VOID; 1506322877Sjkim } 1507322877Sjkim 1508322877Sjkim /* Get the full external and internal pathnames to the node */ 1509322877Sjkim 1510322877Sjkim Status = AcpiDmGetExternalAndInternalPath (Node, 1511322877Sjkim &ExternalPath, &InternalPath); 1512322877Sjkim if (ACPI_FAILURE (Status)) 1513322877Sjkim { 1514322877Sjkim return_VOID; 1515322877Sjkim } 1516322877Sjkim 1517322877Sjkim /* Remove the root backslash */ 1518322877Sjkim 1519322877Sjkim Status = AcpiDmRemoveRootPrefix (&InternalPath); 1520322877Sjkim if (ACPI_FAILURE (Status)) 1521322877Sjkim { 1522322877Sjkim ACPI_FREE (InternalPath); 1523322877Sjkim ACPI_FREE (ExternalPath); 1524322877Sjkim return_VOID; 1525322877Sjkim } 1526322877Sjkim 1527322877Sjkim while (ExternalList) 1528322877Sjkim { 1529322877Sjkim Temp = ExternalList->InternalPath; 1530322877Sjkim if ((*ExternalList->InternalPath == AML_ROOT_PREFIX) && 1531322877Sjkim (ExternalList->InternalPath[1])) 1532322877Sjkim { 1533322877Sjkim Temp++; 1534322877Sjkim } 1535322877Sjkim 1536322877Sjkim if (!strcmp (ExternalList->InternalPath, InternalPath)) 1537322877Sjkim { 1538322877Sjkim ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION; 1539322877Sjkim } 1540322877Sjkim ExternalList = ExternalList->Next; 1541322877Sjkim } 1542322877Sjkim 1543322877Sjkim ACPI_FREE (InternalPath); 1544322877Sjkim ACPI_FREE (ExternalPath); 1545322877Sjkim 1546322877Sjkim return_VOID; 1547322877Sjkim} 1548322877Sjkim 1549322877Sjkim 1550322877Sjkim/******************************************************************************* 1551322877Sjkim * 1552322877Sjkim * FUNCTION: AcpiDmConflictingDeclaration 1553322877Sjkim * 1554322877Sjkim * PARAMETERS: Path - Path with conflicting declaration 1555322877Sjkim * 1556322877Sjkim * RETURN: None 1557322877Sjkim * 1558322877Sjkim * DESCRIPTION: Emit a warning when printing conflicting ASL external 1559322877Sjkim * declarations. 1560322877Sjkim * 1561322877Sjkim ******************************************************************************/ 1562322877Sjkim 1563322877Sjkimstatic void 1564322877SjkimAcpiDmConflictingDeclaration ( 1565322877Sjkim char *Path) 1566322877Sjkim{ 1567322877Sjkim fprintf (stderr, 1568322877Sjkim " Warning - Emitting ASL code \"External (%s)\"\n" 1569322877Sjkim " This is a conflicting declaration with some " 1570322877Sjkim "other declaration within the ASL code.\n" 1571322877Sjkim " This external declaration may need to be " 1572322877Sjkim "deleted in order to recompile the dsl file.\n\n", 1573322877Sjkim Path); 1574322877Sjkim} 1575322877Sjkim 1576322877Sjkim 1577322877Sjkim/******************************************************************************* 1578322877Sjkim * 1579316303Sjkim * FUNCTION: AcpiDmEmitExternal 1580316303Sjkim * 1581316303Sjkim * PARAMETERS: Op External Parse Object 1582316303Sjkim * 1583316303Sjkim * RETURN: None 1584316303Sjkim * 1585316303Sjkim * DESCRIPTION: Emit an External() ASL statement for the current External 1586322877Sjkim * parse object. Note: External Ops are named types so the 1587322877Sjkim * namepath is contained within NameOp->Name.Path. 1588316303Sjkim * 1589316303Sjkim ******************************************************************************/ 1590316303Sjkim 1591316303Sjkimvoid 1592316303SjkimAcpiDmEmitExternal ( 1593316303Sjkim ACPI_PARSE_OBJECT *NameOp, 1594316303Sjkim ACPI_PARSE_OBJECT *TypeOp) 1595316303Sjkim{ 1596316303Sjkim AcpiOsPrintf ("External ("); 1597322877Sjkim AcpiDmNamestring (NameOp->Named.Path); 1598322877Sjkim AcpiOsPrintf ("%s)", 1599316303Sjkim AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer)); 1600322877Sjkim AcpiDmCheckForExternalConflict (NameOp->Named.Path); 1601322877Sjkim AcpiOsPrintf ("\n"); 1602316303Sjkim} 1603316303Sjkim 1604316303Sjkim 1605316303Sjkim/******************************************************************************* 1606316303Sjkim * 1607322877Sjkim * FUNCTION: AcpiDmCheckForExternalConflict 1608322877Sjkim * 1609322877Sjkim * PARAMETERS: Path - Path to check 1610322877Sjkim * 1611322877Sjkim * RETURN: None 1612322877Sjkim * 1613322877Sjkim * DESCRIPTION: Search the External List to see if the input Path has a 1614322877Sjkim * conflicting declaration. 1615322877Sjkim * 1616322877Sjkim ******************************************************************************/ 1617322877Sjkim 1618322877Sjkimstatic void 1619322877SjkimAcpiDmCheckForExternalConflict ( 1620322877Sjkim char *Path) 1621322877Sjkim{ 1622322877Sjkim ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList; 1623322877Sjkim char *ListItemPath; 1624322877Sjkim char *InputPath; 1625322877Sjkim 1626322877Sjkim 1627322877Sjkim if (!Path) 1628322877Sjkim { 1629322877Sjkim return; 1630322877Sjkim } 1631322877Sjkim 1632322877Sjkim /* Move past the root prefix '\' */ 1633322877Sjkim 1634322877Sjkim InputPath = Path; 1635322877Sjkim if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1]) 1636322877Sjkim { 1637322877Sjkim InputPath++; 1638322877Sjkim } 1639322877Sjkim 1640322877Sjkim while (ExternalList) 1641322877Sjkim { 1642322877Sjkim ListItemPath = ExternalList->Path; 1643322877Sjkim if (ListItemPath) 1644322877Sjkim { 1645322877Sjkim /* Move past the root prefix '\' */ 1646322877Sjkim 1647322877Sjkim if ((*ListItemPath == AML_ROOT_PREFIX) && 1648322877Sjkim ListItemPath[1]) 1649322877Sjkim { 1650322877Sjkim ListItemPath++; 1651322877Sjkim } 1652322877Sjkim 1653322877Sjkim if (!strcmp (ListItemPath, InputPath) && 1654322877Sjkim (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION)) 1655322877Sjkim { 1656322877Sjkim AcpiOsPrintf ("%s", ExternalConflictMessage); 1657322877Sjkim AcpiDmConflictingDeclaration (Path); 1658322877Sjkim 1659322877Sjkim return; 1660322877Sjkim } 1661322877Sjkim } 1662322877Sjkim ExternalList = ExternalList->Next; 1663322877Sjkim } 1664322877Sjkim} 1665322877Sjkim/******************************************************************************* 1666322877Sjkim * 1667246849Sjkim * FUNCTION: AcpiDmUnresolvedWarning 1668246849Sjkim * 1669246849Sjkim * PARAMETERS: Type - Where to output the warning. 1670246849Sjkim * 0 means write to stderr 1671246849Sjkim * 1 means write to AcpiOsPrintf 1672246849Sjkim * 1673246849Sjkim * RETURN: None 1674246849Sjkim * 1675246849Sjkim * DESCRIPTION: Issue warning message if there are unresolved external control 1676246849Sjkim * methods within the disassembly. 1677246849Sjkim * 1678246849Sjkim ******************************************************************************/ 1679246849Sjkim 1680322877Sjkim/* 1681246849SjkimSummary of the external control method problem: 1682246849Sjkim 1683246849SjkimWhen the -e option is used with disassembly, the various SSDTs are simply 1684246849Sjkimloaded into a global namespace for the disassembler to use in order to 1685246849Sjkimresolve control method references (invocations). 1686246849Sjkim 1687246849SjkimThe disassembler tracks any such references, and will emit an External() 1688246849Sjkimstatement for these types of methods, with the proper number of arguments . 1689246849Sjkim 1690246849SjkimWithout the SSDTs, the AML does not contain enough information to properly 1691246849Sjkimdisassemble the control method invocation -- because the disassembler does 1692246849Sjkimnot know how many arguments to parse. 1693246849Sjkim 1694246849SjkimAn example: Assume we have two control methods. ABCD has one argument, and 1695246849SjkimEFGH has zero arguments. Further, we have two additional control methods 1696246849Sjkimthat invoke ABCD and EFGH, named T1 and T2: 1697246849Sjkim 1698246849Sjkim Method (ABCD, 1) 1699246849Sjkim { 1700246849Sjkim } 1701246849Sjkim Method (EFGH, 0) 1702246849Sjkim { 1703246849Sjkim } 1704246849Sjkim Method (T1) 1705246849Sjkim { 1706246849Sjkim ABCD (Add (2, 7, Local0)) 1707246849Sjkim } 1708246849Sjkim Method (T2) 1709246849Sjkim { 1710246849Sjkim EFGH () 1711246849Sjkim Add (2, 7, Local0) 1712246849Sjkim } 1713246849Sjkim 1714246849SjkimHere is the AML code that is generated for T1 and T2: 1715246849Sjkim 1716246849Sjkim 185: Method (T1) 1717246849Sjkim 1718246849Sjkim0000034C: 14 10 54 31 5F 5F 00 ... "..T1__." 1719246849Sjkim 1720246849Sjkim 186: { 1721246849Sjkim 187: ABCD (Add (2, 7, Local0)) 1722246849Sjkim 1723246849Sjkim00000353: 41 42 43 44 ............ "ABCD" 1724246849Sjkim00000357: 72 0A 02 0A 07 60 ...... "r....`" 1725246849Sjkim 1726246849Sjkim 188: } 1727246849Sjkim 1728246849Sjkim 190: Method (T2) 1729246849Sjkim 1730246849Sjkim0000035D: 14 10 54 32 5F 5F 00 ... "..T2__." 1731246849Sjkim 1732246849Sjkim 191: { 1733246849Sjkim 192: EFGH () 1734246849Sjkim 1735246849Sjkim00000364: 45 46 47 48 ............ "EFGH" 1736246849Sjkim 1737246849Sjkim 193: Add (2, 7, Local0) 1738246849Sjkim 1739246849Sjkim00000368: 72 0A 02 0A 07 60 ...... "r....`" 1740246849Sjkim 194: } 1741246849Sjkim 1742246849SjkimNote that the AML code for T1 and T2 is essentially identical. When 1743246849Sjkimdisassembling this code, the methods ABCD and EFGH must be known to the 1744246849Sjkimdisassembler, otherwise it does not know how to handle the method invocations. 1745246849Sjkim 1746246849SjkimIn other words, if ABCD and EFGH are actually external control methods 1747246849Sjkimappearing in an SSDT, the disassembler does not know what to do unless 1748246849Sjkimthe owning SSDT has been loaded via the -e option. 1749322877Sjkim*/ 1750246849Sjkim 1751298714Sjkimstatic char ExternalWarningPart1[600]; 1752298714Sjkimstatic char ExternalWarningPart2[400]; 1753298714Sjkimstatic char ExternalWarningPart3[400]; 1754298714Sjkimstatic char ExternalWarningPart4[200]; 1755298714Sjkim 1756246849Sjkimvoid 1757246849SjkimAcpiDmUnresolvedWarning ( 1758246849Sjkim UINT8 Type) 1759246849Sjkim{ 1760298714Sjkim char *Format; 1761298714Sjkim char Pad[] = " *"; 1762298714Sjkim char NoPad[] = ""; 1763246849Sjkim 1764298714Sjkim 1765246849Sjkim if (!AcpiGbl_NumExternalMethods) 1766246849Sjkim { 1767246849Sjkim return; 1768246849Sjkim } 1769246849Sjkim 1770298714Sjkim if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods) 1771298714Sjkim { 1772298714Sjkim return; 1773298714Sjkim } 1774298714Sjkim 1775298714Sjkim Format = Type ? Pad : NoPad; 1776298714Sjkim 1777298714Sjkim sprintf (ExternalWarningPart1, 1778298714Sjkim "%s iASL Warning: There %s %u external control method%s found during\n" 1779298714Sjkim "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n" 1780298714Sjkim "%s ACPI tables may be required to properly disassemble the code. This\n" 1781298714Sjkim "%s resulting disassembler output file may not compile because the\n" 1782298714Sjkim "%s disassembler did not know how many arguments to assign to the\n" 1783298714Sjkim "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n" 1784298714Sjkim "%s runtime and may or may not be available via the host OS.\n", 1785298714Sjkim Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"), 1786298714Sjkim AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""), 1787298714Sjkim Format, AcpiGbl_ResolvedExternalMethods, 1788298714Sjkim (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"), 1789298714Sjkim (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods), 1790298714Sjkim Format, Format, Format, Format, Format); 1791298714Sjkim 1792298714Sjkim sprintf (ExternalWarningPart2, 1793298714Sjkim "%s To specify the tables needed to resolve external control method\n" 1794298714Sjkim "%s references, the -e option can be used to specify the filenames.\n" 1795298714Sjkim "%s Example iASL invocations:\n" 1796298714Sjkim "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n" 1797298714Sjkim "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n" 1798298714Sjkim "%s iasl -e ssdt*.aml -d dsdt.aml\n", 1799298714Sjkim Format, Format, Format, Format, Format, Format); 1800298714Sjkim 1801298714Sjkim sprintf (ExternalWarningPart3, 1802298714Sjkim "%s In addition, the -fe option can be used to specify a file containing\n" 1803298714Sjkim "%s control method external declarations with the associated method\n" 1804298714Sjkim "%s argument counts. Each line of the file must be of the form:\n" 1805298714Sjkim "%s External (<method pathname>, MethodObj, <argument count>)\n" 1806298714Sjkim "%s Invocation:\n" 1807298714Sjkim "%s iasl -fe refs.txt -d dsdt.aml\n", 1808298714Sjkim Format, Format, Format, Format, Format, Format); 1809298714Sjkim 1810298714Sjkim sprintf (ExternalWarningPart4, 1811298714Sjkim "%s The following methods were unresolved and many not compile properly\n" 1812298714Sjkim "%s because the disassembler had to guess at the number of arguments\n" 1813298714Sjkim "%s required for each:\n", 1814298714Sjkim Format, Format, Format); 1815298714Sjkim 1816246849Sjkim if (Type) 1817246849Sjkim { 1818246849Sjkim if (!AcpiGbl_ExternalFileList) 1819246849Sjkim { 1820246849Sjkim /* The -e option was not specified */ 1821246849Sjkim 1822298714Sjkim AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n", 1823298714Sjkim ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3, 1824298714Sjkim ExternalWarningPart4); 1825246849Sjkim } 1826298714Sjkim else 1827246849Sjkim { 1828246849Sjkim /* The -e option was specified, but there are still some unresolved externals */ 1829246849Sjkim 1830298714Sjkim AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n", 1831298714Sjkim ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4); 1832246849Sjkim } 1833246849Sjkim } 1834246849Sjkim else 1835246849Sjkim { 1836246849Sjkim if (!AcpiGbl_ExternalFileList) 1837246849Sjkim { 1838246849Sjkim /* The -e option was not specified */ 1839246849Sjkim 1840298714Sjkim fprintf (stderr, "\n%s\n%s\n%s\n", 1841298714Sjkim ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3); 1842246849Sjkim } 1843298714Sjkim else 1844246849Sjkim { 1845246849Sjkim /* The -e option was specified, but there are still some unresolved externals */ 1846246849Sjkim 1847298714Sjkim fprintf (stderr, "\n%s\n%s\n", 1848298714Sjkim ExternalWarningPart1, ExternalWarningPart3); 1849246849Sjkim } 1850246849Sjkim } 1851246849Sjkim} 1852