1198054Sjkim/****************************************************************************** 2198054Sjkim * 3198054Sjkim * Module Name: dmextern - Support for External() ASL statements 4198054Sjkim * 5198054Sjkim *****************************************************************************/ 6198054Sjkim 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9198054Sjkim * All rights reserved. 10198054Sjkim * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25198054Sjkim * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29198054Sjkim * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43198054Sjkim 44198237Sjkim#include <contrib/dev/acpica/include/acpi.h> 45198237Sjkim#include <contrib/dev/acpica/include/accommon.h> 46198237Sjkim#include <contrib/dev/acpica/include/amlcode.h> 47198237Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48198237Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 49254745Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 50246849Sjkim#include <stdio.h> 51254745Sjkim#include <errno.h> 52198054Sjkim 53198054Sjkim 54198054Sjkim/* 55198054Sjkim * This module is used for application-level code (iASL disassembler) only. 56198054Sjkim * 57198054Sjkim * It contains the code to create and emit any necessary External() ASL 58198054Sjkim * statements for the module being disassembled. 59198054Sjkim */ 60198054Sjkim#define _COMPONENT ACPI_CA_DISASSEMBLER 61198054Sjkim ACPI_MODULE_NAME ("dmextern") 62198054Sjkim 63198054Sjkim 64198054Sjkim/* 65198054Sjkim * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL 66198054Sjkim * ObjectTypeKeyword. Used to generate typed external declarations 67198054Sjkim */ 68198054Sjkimstatic const char *AcpiGbl_DmTypeNames[] = 69198054Sjkim{ 70281075Sdim /* 00 */ ", UnknownObj", /* Type ANY */ 71198054Sjkim /* 01 */ ", IntObj", 72198054Sjkim /* 02 */ ", StrObj", 73198054Sjkim /* 03 */ ", BuffObj", 74198054Sjkim /* 04 */ ", PkgObj", 75198054Sjkim /* 05 */ ", FieldUnitObj", 76198054Sjkim /* 06 */ ", DeviceObj", 77198054Sjkim /* 07 */ ", EventObj", 78198054Sjkim /* 08 */ ", MethodObj", 79198054Sjkim /* 09 */ ", MutexObj", 80198054Sjkim /* 10 */ ", OpRegionObj", 81198054Sjkim /* 11 */ ", PowerResObj", 82198054Sjkim /* 12 */ ", ProcessorObj", 83198054Sjkim /* 13 */ ", ThermalZoneObj", 84198054Sjkim /* 14 */ ", BuffFieldObj", 85198054Sjkim /* 15 */ ", DDBHandleObj", 86198054Sjkim /* 16 */ "", /* Debug object */ 87198054Sjkim /* 17 */ ", FieldUnitObj", 88198054Sjkim /* 18 */ ", FieldUnitObj", 89198054Sjkim /* 19 */ ", FieldUnitObj" 90198054Sjkim}; 91198054Sjkim 92254745Sjkim#define METHOD_SEPARATORS " \t,()\n" 93198054Sjkim 94254745Sjkim 95198054Sjkim/* Local prototypes */ 96198054Sjkim 97198054Sjkimstatic const char * 98198054SjkimAcpiDmGetObjectTypeName ( 99198054Sjkim ACPI_OBJECT_TYPE Type); 100198054Sjkim 101198054Sjkimstatic char * 102198054SjkimAcpiDmNormalizeParentPrefix ( 103198054Sjkim ACPI_PARSE_OBJECT *Op, 104198054Sjkim char *Path); 105198054Sjkim 106254745Sjkimstatic void 107281075SdimAcpiDmAddPathToExternalList ( 108254745Sjkim char *Path, 109254745Sjkim UINT8 Type, 110281075Sdim UINT32 Value, 111281075Sdim UINT16 Flags); 112198054Sjkim 113281075Sdimstatic ACPI_STATUS 114281075SdimAcpiDmCreateNewExternal ( 115281075Sdim char *ExternalPath, 116281075Sdim char *InternalPath, 117281075Sdim UINT8 Type, 118281075Sdim UINT32 Value, 119281075Sdim UINT16 Flags); 120254745Sjkim 121281075Sdim 122198054Sjkim/******************************************************************************* 123198054Sjkim * 124198054Sjkim * FUNCTION: AcpiDmGetObjectTypeName 125198054Sjkim * 126198054Sjkim * PARAMETERS: Type - An ACPI_OBJECT_TYPE 127198054Sjkim * 128198054Sjkim * RETURN: Pointer to a string 129198054Sjkim * 130198054Sjkim * DESCRIPTION: Map an object type to the ASL object type string. 131198054Sjkim * 132198054Sjkim ******************************************************************************/ 133198054Sjkim 134198054Sjkimstatic const char * 135198054SjkimAcpiDmGetObjectTypeName ( 136198054Sjkim ACPI_OBJECT_TYPE Type) 137198054Sjkim{ 138198054Sjkim 139198054Sjkim if (Type == ACPI_TYPE_LOCAL_SCOPE) 140198054Sjkim { 141198054Sjkim Type = ACPI_TYPE_DEVICE; 142198054Sjkim } 143198054Sjkim else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) 144198054Sjkim { 145198054Sjkim return (""); 146198054Sjkim } 147198054Sjkim 148198054Sjkim return (AcpiGbl_DmTypeNames[Type]); 149198054Sjkim} 150198054Sjkim 151198054Sjkim 152198054Sjkim/******************************************************************************* 153198054Sjkim * 154198054Sjkim * FUNCTION: AcpiDmNormalizeParentPrefix 155198054Sjkim * 156198054Sjkim * PARAMETERS: Op - Parse op 157198054Sjkim * Path - Path with parent prefix 158198054Sjkim * 159198054Sjkim * RETURN: The full pathname to the object (from the namespace root) 160198054Sjkim * 161198054Sjkim * DESCRIPTION: Returns the full pathname of a path with parent prefix 162198054Sjkim * The caller must free the fullpath returned. 163198054Sjkim * 164198054Sjkim ******************************************************************************/ 165198054Sjkim 166198054Sjkimstatic char * 167198054SjkimAcpiDmNormalizeParentPrefix ( 168198054Sjkim ACPI_PARSE_OBJECT *Op, 169198054Sjkim char *Path) 170198054Sjkim{ 171198054Sjkim ACPI_NAMESPACE_NODE *Node; 172198054Sjkim char *Fullpath; 173198054Sjkim char *ParentPath; 174198054Sjkim ACPI_SIZE Length; 175243347Sjkim UINT32 Index = 0; 176198054Sjkim 177198054Sjkim 178243347Sjkim if (!Op) 179243347Sjkim { 180243347Sjkim return (NULL); 181243347Sjkim } 182198054Sjkim 183243347Sjkim /* Search upwards in the parse tree until we reach the next namespace node */ 184243347Sjkim 185243347Sjkim Op = Op->Common.Parent; 186198054Sjkim while (Op) 187198054Sjkim { 188198054Sjkim if (Op->Common.Node) 189198054Sjkim { 190198054Sjkim break; 191198054Sjkim } 192198054Sjkim 193198054Sjkim Op = Op->Common.Parent; 194198054Sjkim } 195198054Sjkim 196198054Sjkim if (!Op) 197198054Sjkim { 198198054Sjkim return (NULL); 199198054Sjkim } 200198054Sjkim 201198054Sjkim /* 202198054Sjkim * Find the actual parent node for the reference: 203198054Sjkim * Remove all carat prefixes from the input path. 204198054Sjkim * There may be multiple parent prefixes (For example, ^^^M000) 205198054Sjkim */ 206198054Sjkim Node = Op->Common.Node; 207198054Sjkim while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) 208198054Sjkim { 209209746Sjkim Node = Node->Parent; 210198054Sjkim Path++; 211198054Sjkim } 212198054Sjkim 213198054Sjkim if (!Node) 214198054Sjkim { 215198054Sjkim return (NULL); 216198054Sjkim } 217198054Sjkim 218198054Sjkim /* Get the full pathname for the parent node */ 219198054Sjkim 220198054Sjkim ParentPath = AcpiNsGetExternalPathname (Node); 221198054Sjkim if (!ParentPath) 222198054Sjkim { 223198054Sjkim return (NULL); 224198054Sjkim } 225198054Sjkim 226306536Sjkim Length = (strlen (ParentPath) + strlen (Path) + 1); 227206117Sjkim if (ParentPath[1]) 228206117Sjkim { 229206117Sjkim /* 230206117Sjkim * If ParentPath is not just a simple '\', increment the length 231206117Sjkim * for the required dot separator (ParentPath.Path) 232206117Sjkim */ 233206117Sjkim Length++; 234243347Sjkim 235243347Sjkim /* For External() statements, we do not want a leading '\' */ 236243347Sjkim 237243347Sjkim if (*ParentPath == AML_ROOT_PREFIX) 238243347Sjkim { 239243347Sjkim Index = 1; 240243347Sjkim } 241206117Sjkim } 242206117Sjkim 243198054Sjkim Fullpath = ACPI_ALLOCATE_ZEROED (Length); 244198054Sjkim if (!Fullpath) 245198054Sjkim { 246198054Sjkim goto Cleanup; 247198054Sjkim } 248198054Sjkim 249198054Sjkim /* 250198054Sjkim * Concatenate parent fullpath and path. For example, 251198054Sjkim * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" 252198054Sjkim * 253198054Sjkim * Copy the parent path 254198054Sjkim */ 255306536Sjkim strcpy (Fullpath, &ParentPath[Index]); 256198054Sjkim 257237412Sjkim /* 258237412Sjkim * Add dot separator 259237412Sjkim * (don't need dot if parent fullpath is a single backslash) 260237412Sjkim */ 261198054Sjkim if (ParentPath[1]) 262198054Sjkim { 263306536Sjkim strcat (Fullpath, "."); 264198054Sjkim } 265198054Sjkim 266198054Sjkim /* Copy child path (carat parent prefix(es) were skipped above) */ 267198054Sjkim 268306536Sjkim strcat (Fullpath, Path); 269198054Sjkim 270198054SjkimCleanup: 271198054Sjkim ACPI_FREE (ParentPath); 272198054Sjkim return (Fullpath); 273198054Sjkim} 274198054Sjkim 275198054Sjkim 276198054Sjkim/******************************************************************************* 277198054Sjkim * 278210976Sjkim * FUNCTION: AcpiDmAddToExternalFileList 279210976Sjkim * 280210976Sjkim * PARAMETERS: PathList - Single path or list separated by comma 281210976Sjkim * 282210976Sjkim * RETURN: None 283210976Sjkim * 284210976Sjkim * DESCRIPTION: Add external files to global list 285210976Sjkim * 286210976Sjkim ******************************************************************************/ 287210976Sjkim 288210976SjkimACPI_STATUS 289210976SjkimAcpiDmAddToExternalFileList ( 290281075Sdim char *Pathname) 291210976Sjkim{ 292210976Sjkim ACPI_EXTERNAL_FILE *ExternalFile; 293281075Sdim char *LocalPathname; 294210976Sjkim 295210976Sjkim 296281075Sdim if (!Pathname) 297210976Sjkim { 298210976Sjkim return (AE_OK); 299210976Sjkim } 300210976Sjkim 301281075Sdim LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1); 302281075Sdim if (!LocalPathname) 303281075Sdim { 304281075Sdim return (AE_NO_MEMORY); 305281075Sdim } 306210976Sjkim 307281075Sdim ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE)); 308281075Sdim if (!ExternalFile) 309210976Sjkim { 310281075Sdim ACPI_FREE (LocalPathname); 311281075Sdim return (AE_NO_MEMORY); 312281075Sdim } 313210976Sjkim 314281075Sdim /* Take a copy of the file pathname */ 315210976Sjkim 316281075Sdim strcpy (LocalPathname, Pathname); 317281075Sdim ExternalFile->Path = LocalPathname; 318210976Sjkim 319281075Sdim if (AcpiGbl_ExternalFileList) 320281075Sdim { 321281075Sdim ExternalFile->Next = AcpiGbl_ExternalFileList; 322210976Sjkim } 323210976Sjkim 324281075Sdim AcpiGbl_ExternalFileList = ExternalFile; 325210976Sjkim return (AE_OK); 326210976Sjkim} 327210976Sjkim 328210976Sjkim 329210976Sjkim/******************************************************************************* 330210976Sjkim * 331210976Sjkim * FUNCTION: AcpiDmClearExternalFileList 332210976Sjkim * 333210976Sjkim * PARAMETERS: None 334210976Sjkim * 335210976Sjkim * RETURN: None 336210976Sjkim * 337210976Sjkim * DESCRIPTION: Clear the external file list 338210976Sjkim * 339210976Sjkim ******************************************************************************/ 340210976Sjkim 341210976Sjkimvoid 342210976SjkimAcpiDmClearExternalFileList ( 343210976Sjkim void) 344210976Sjkim{ 345210976Sjkim ACPI_EXTERNAL_FILE *NextExternal; 346210976Sjkim 347210976Sjkim 348210976Sjkim while (AcpiGbl_ExternalFileList) 349210976Sjkim { 350210976Sjkim NextExternal = AcpiGbl_ExternalFileList->Next; 351210976Sjkim ACPI_FREE (AcpiGbl_ExternalFileList->Path); 352210976Sjkim ACPI_FREE (AcpiGbl_ExternalFileList); 353210976Sjkim AcpiGbl_ExternalFileList = NextExternal; 354210976Sjkim } 355210976Sjkim} 356210976Sjkim 357210976Sjkim 358210976Sjkim/******************************************************************************* 359210976Sjkim * 360281075Sdim * FUNCTION: AcpiDmGetExternalsFromFile 361198054Sjkim * 362281075Sdim * PARAMETERS: None 363281075Sdim * 364281075Sdim * RETURN: None 365281075Sdim * 366281075Sdim * DESCRIPTION: Process the optional external reference file. 367281075Sdim * 368281075Sdim * Each line in the file should be of the form: 369281075Sdim * External (<Method namepath>, MethodObj, <ArgCount>) 370281075Sdim * 371281075Sdim * Example: 372281075Sdim * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4) 373281075Sdim * 374281075Sdim ******************************************************************************/ 375281075Sdim 376281075Sdimvoid 377281075SdimAcpiDmGetExternalsFromFile ( 378281075Sdim void) 379281075Sdim{ 380281075Sdim FILE *ExternalRefFile; 381281075Sdim char *Token; 382281075Sdim char *MethodName; 383281075Sdim UINT32 ArgCount; 384281075Sdim UINT32 ImportCount = 0; 385281075Sdim 386281075Sdim 387281075Sdim if (!Gbl_ExternalRefFilename) 388281075Sdim { 389281075Sdim return; 390281075Sdim } 391281075Sdim 392281075Sdim /* Open the file */ 393281075Sdim 394281075Sdim ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r"); 395281075Sdim if (!ExternalRefFile) 396281075Sdim { 397281075Sdim fprintf (stderr, "Could not open external reference file \"%s\"\n", 398281075Sdim Gbl_ExternalRefFilename); 399281075Sdim AslAbort (); 400281075Sdim return; 401281075Sdim } 402281075Sdim 403281075Sdim /* Each line defines a method */ 404281075Sdim 405281075Sdim while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile)) 406281075Sdim { 407281075Sdim Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */ 408281075Sdim if (!Token) 409281075Sdim { 410281075Sdim continue; 411281075Sdim } 412306536Sjkim 413281075Sdim if (strcmp (Token, "External")) 414281075Sdim { 415281075Sdim continue; 416281075Sdim } 417281075Sdim 418281075Sdim MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */ 419281075Sdim if (!MethodName) 420281075Sdim { 421281075Sdim continue; 422281075Sdim } 423281075Sdim 424281075Sdim Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */ 425281075Sdim if (!Token) 426281075Sdim { 427281075Sdim continue; 428281075Sdim } 429281075Sdim 430281075Sdim if (strcmp (Token, "MethodObj")) 431281075Sdim { 432281075Sdim continue; 433281075Sdim } 434281075Sdim 435281075Sdim Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */ 436281075Sdim if (!Token) 437281075Sdim { 438281075Sdim continue; 439281075Sdim } 440281075Sdim 441281075Sdim /* Convert arg count string to an integer */ 442281075Sdim 443281075Sdim errno = 0; 444281075Sdim ArgCount = strtoul (Token, NULL, 0); 445281075Sdim if (errno) 446281075Sdim { 447281075Sdim fprintf (stderr, "Invalid argument count (%s)\n", Token); 448281075Sdim continue; 449281075Sdim } 450306536Sjkim 451281075Sdim if (ArgCount > 7) 452281075Sdim { 453281075Sdim fprintf (stderr, "Invalid argument count (%u)\n", ArgCount); 454281075Sdim continue; 455281075Sdim } 456281075Sdim 457281075Sdim /* Add this external to the global list */ 458281075Sdim 459281075Sdim AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n", 460281075Sdim Gbl_ExternalRefFilename, ArgCount, MethodName); 461281075Sdim 462281075Sdim AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD, 463281075Sdim ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE)); 464281075Sdim ImportCount++; 465281075Sdim } 466281075Sdim 467281075Sdim if (!ImportCount) 468281075Sdim { 469306536Sjkim fprintf (stderr, 470306536Sjkim "Did not find any external methods in reference file \"%s\"\n", 471281075Sdim Gbl_ExternalRefFilename); 472281075Sdim } 473281075Sdim else 474281075Sdim { 475281075Sdim /* Add the external(s) to the namespace */ 476281075Sdim 477281075Sdim AcpiDmAddExternalsToNamespace (); 478281075Sdim 479281075Sdim AcpiOsPrintf ("%s: Imported %u external method definitions\n", 480281075Sdim Gbl_ExternalRefFilename, ImportCount); 481281075Sdim } 482281075Sdim 483281075Sdim fclose (ExternalRefFile); 484281075Sdim} 485281075Sdim 486281075Sdim 487281075Sdim/******************************************************************************* 488281075Sdim * 489281075Sdim * FUNCTION: AcpiDmAddOpToExternalList 490281075Sdim * 491198054Sjkim * PARAMETERS: Op - Current parser Op 492198054Sjkim * Path - Internal (AML) path to the object 493198054Sjkim * Type - ACPI object type to be added 494198054Sjkim * Value - Arg count if adding a Method object 495281075Sdim * Flags - To be passed to the external object 496198054Sjkim * 497198054Sjkim * RETURN: None 498198054Sjkim * 499198054Sjkim * DESCRIPTION: Insert a new name into the global list of Externals which 500198054Sjkim * will in turn be later emitted as an External() declaration 501198054Sjkim * in the disassembled output. 502198054Sjkim * 503281075Sdim * This function handles the most common case where the referenced 504281075Sdim * name is simply not found in the constructed namespace. 505281075Sdim * 506198054Sjkim ******************************************************************************/ 507198054Sjkim 508198054Sjkimvoid 509281075SdimAcpiDmAddOpToExternalList ( 510198054Sjkim ACPI_PARSE_OBJECT *Op, 511198054Sjkim char *Path, 512198054Sjkim UINT8 Type, 513281075Sdim UINT32 Value, 514281075Sdim UINT16 Flags) 515198054Sjkim{ 516198054Sjkim char *ExternalPath; 517281075Sdim char *InternalPath = Path; 518281075Sdim char *Temp; 519198054Sjkim ACPI_STATUS Status; 520198054Sjkim 521198054Sjkim 522281075Sdim ACPI_FUNCTION_TRACE (DmAddOpToExternalList); 523281075Sdim 524281075Sdim 525198054Sjkim if (!Path) 526198054Sjkim { 527281075Sdim return_VOID; 528198054Sjkim } 529198054Sjkim 530281075Sdim /* Remove a root backslash if present */ 531246849Sjkim 532243347Sjkim if ((*Path == AML_ROOT_PREFIX) && (Path[1])) 533243347Sjkim { 534243347Sjkim Path++; 535243347Sjkim } 536198054Sjkim 537281075Sdim /* Externalize the pathname */ 538243347Sjkim 539198054Sjkim Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, 540281075Sdim NULL, &ExternalPath); 541198054Sjkim if (ACPI_FAILURE (Status)) 542198054Sjkim { 543281075Sdim return_VOID; 544198054Sjkim } 545198054Sjkim 546243347Sjkim /* 547243347Sjkim * Get the full pathname from the root if "Path" has one or more 548243347Sjkim * parent prefixes (^). Note: path will not contain a leading '\'. 549243347Sjkim */ 550198054Sjkim if (*Path == (UINT8) AML_PARENT_PREFIX) 551198054Sjkim { 552281075Sdim Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath); 553198054Sjkim 554281075Sdim /* Set new external path */ 555198054Sjkim 556281075Sdim ACPI_FREE (ExternalPath); 557281075Sdim ExternalPath = Temp; 558281075Sdim if (!Temp) 559198054Sjkim { 560281075Sdim return_VOID; 561198054Sjkim } 562198054Sjkim 563281075Sdim /* Create the new internal pathname */ 564198054Sjkim 565281075Sdim Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED; 566281075Sdim Status = AcpiNsInternalizeName (ExternalPath, &InternalPath); 567198054Sjkim if (ACPI_FAILURE (Status)) 568198054Sjkim { 569198054Sjkim ACPI_FREE (ExternalPath); 570281075Sdim return_VOID; 571198054Sjkim } 572198054Sjkim } 573198054Sjkim 574281075Sdim /* Create the new External() declaration node */ 575198054Sjkim 576281075Sdim Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, 577281075Sdim Type, Value, Flags); 578281075Sdim if (ACPI_FAILURE (Status)) 579198054Sjkim { 580281075Sdim ACPI_FREE (ExternalPath); 581281075Sdim if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED) 582198054Sjkim { 583281075Sdim ACPI_FREE (InternalPath); 584198054Sjkim } 585198054Sjkim } 586198054Sjkim 587281075Sdim return_VOID; 588198054Sjkim} 589198054Sjkim 590198054Sjkim 591198054Sjkim/******************************************************************************* 592198054Sjkim * 593281075Sdim * FUNCTION: AcpiDmAddNodeToExternalList 594254745Sjkim * 595281075Sdim * PARAMETERS: Node - Namespace node for object to be added 596281075Sdim * Type - ACPI object type to be added 597281075Sdim * Value - Arg count if adding a Method object 598281075Sdim * Flags - To be passed to the external object 599254745Sjkim * 600254745Sjkim * RETURN: None 601254745Sjkim * 602281075Sdim * DESCRIPTION: Insert a new name into the global list of Externals which 603281075Sdim * will in turn be later emitted as an External() declaration 604281075Sdim * in the disassembled output. 605254745Sjkim * 606281075Sdim * This function handles the case where the referenced name has 607281075Sdim * been found in the namespace, but the name originated in a 608281075Sdim * table other than the one that is being disassembled (such 609281075Sdim * as a table that is added via the iASL -e option). 610254745Sjkim * 611254745Sjkim ******************************************************************************/ 612254745Sjkim 613254745Sjkimvoid 614281075SdimAcpiDmAddNodeToExternalList ( 615281075Sdim ACPI_NAMESPACE_NODE *Node, 616281075Sdim UINT8 Type, 617281075Sdim UINT32 Value, 618281075Sdim UINT16 Flags) 619254745Sjkim{ 620281075Sdim char *ExternalPath; 621281075Sdim char *InternalPath; 622281075Sdim char *Temp; 623281075Sdim ACPI_STATUS Status; 624254745Sjkim 625254745Sjkim 626281075Sdim ACPI_FUNCTION_TRACE (DmAddNodeToExternalList); 627281075Sdim 628281075Sdim 629281075Sdim if (!Node) 630254745Sjkim { 631281075Sdim return_VOID; 632254745Sjkim } 633254745Sjkim 634281075Sdim /* Get the full external and internal pathnames to the node */ 635254745Sjkim 636281075Sdim ExternalPath = AcpiNsGetExternalPathname (Node); 637281075Sdim if (!ExternalPath) 638254745Sjkim { 639281075Sdim return_VOID; 640254745Sjkim } 641254745Sjkim 642281075Sdim Status = AcpiNsInternalizeName (ExternalPath, &InternalPath); 643281075Sdim if (ACPI_FAILURE (Status)) 644254745Sjkim { 645281075Sdim ACPI_FREE (ExternalPath); 646281075Sdim return_VOID; 647281075Sdim } 648254745Sjkim 649281075Sdim /* Remove the root backslash */ 650254745Sjkim 651281075Sdim if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1])) 652281075Sdim { 653306536Sjkim Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1); 654281075Sdim if (!Temp) 655254745Sjkim { 656281075Sdim return_VOID; 657254745Sjkim } 658254745Sjkim 659306536Sjkim strcpy (Temp, &ExternalPath[1]); 660281075Sdim ACPI_FREE (ExternalPath); 661281075Sdim ExternalPath = Temp; 662281075Sdim } 663254745Sjkim 664281075Sdim /* Create the new External() declaration node */ 665254745Sjkim 666281075Sdim Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type, 667281075Sdim Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED)); 668281075Sdim if (ACPI_FAILURE (Status)) 669254745Sjkim { 670281075Sdim ACPI_FREE (ExternalPath); 671281075Sdim ACPI_FREE (InternalPath); 672254745Sjkim } 673254745Sjkim 674281075Sdim return_VOID; 675254745Sjkim} 676254745Sjkim 677254745Sjkim 678254745Sjkim/******************************************************************************* 679254745Sjkim * 680281075Sdim * FUNCTION: AcpiDmAddPathToExternalList 681254745Sjkim * 682281075Sdim * PARAMETERS: Path - External name of the object to be added 683254745Sjkim * Type - ACPI object type to be added 684254745Sjkim * Value - Arg count if adding a Method object 685281075Sdim * Flags - To be passed to the external object 686254745Sjkim * 687254745Sjkim * RETURN: None 688254745Sjkim * 689254745Sjkim * DESCRIPTION: Insert a new name into the global list of Externals which 690254745Sjkim * will in turn be later emitted as an External() declaration 691254745Sjkim * in the disassembled output. 692254745Sjkim * 693281075Sdim * This function currently is used to add externals via a 694281075Sdim * reference file (via the -fe iASL option). 695281075Sdim * 696254745Sjkim ******************************************************************************/ 697254745Sjkim 698254745Sjkimstatic void 699281075SdimAcpiDmAddPathToExternalList ( 700254745Sjkim char *Path, 701254745Sjkim UINT8 Type, 702281075Sdim UINT32 Value, 703281075Sdim UINT16 Flags) 704254745Sjkim{ 705254745Sjkim char *InternalPath; 706254745Sjkim char *ExternalPath; 707254745Sjkim ACPI_STATUS Status; 708254745Sjkim 709254745Sjkim 710281075Sdim ACPI_FUNCTION_TRACE (DmAddPathToExternalList); 711281075Sdim 712281075Sdim 713254745Sjkim if (!Path) 714254745Sjkim { 715281075Sdim return_VOID; 716254745Sjkim } 717254745Sjkim 718281075Sdim /* Remove a root backslash if present */ 719254745Sjkim 720281075Sdim if ((*Path == AML_ROOT_PREFIX) && (Path[1])) 721254745Sjkim { 722281075Sdim Path++; 723254745Sjkim } 724254745Sjkim 725281075Sdim /* Create the internal and external pathnames */ 726281075Sdim 727281075Sdim Status = AcpiNsInternalizeName (Path, &InternalPath); 728281075Sdim if (ACPI_FAILURE (Status)) 729254745Sjkim { 730281075Sdim return_VOID; 731254745Sjkim } 732254745Sjkim 733281075Sdim Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath, 734281075Sdim NULL, &ExternalPath); 735281075Sdim if (ACPI_FAILURE (Status)) 736281075Sdim { 737281075Sdim ACPI_FREE (InternalPath); 738281075Sdim return_VOID; 739281075Sdim } 740281075Sdim 741281075Sdim /* Create the new External() declaration node */ 742281075Sdim 743281075Sdim Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, 744281075Sdim Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED)); 745281075Sdim if (ACPI_FAILURE (Status)) 746281075Sdim { 747281075Sdim ACPI_FREE (ExternalPath); 748281075Sdim ACPI_FREE (InternalPath); 749281075Sdim } 750281075Sdim 751281075Sdim return_VOID; 752281075Sdim} 753281075Sdim 754281075Sdim 755281075Sdim/******************************************************************************* 756281075Sdim * 757281075Sdim * FUNCTION: AcpiDmCreateNewExternal 758281075Sdim * 759281075Sdim * PARAMETERS: ExternalPath - External path to the object 760281075Sdim * InternalPath - Internal (AML) path to the object 761281075Sdim * Type - ACPI object type to be added 762281075Sdim * Value - Arg count if adding a Method object 763281075Sdim * Flags - To be passed to the external object 764281075Sdim * 765281075Sdim * RETURN: Status 766281075Sdim * 767281075Sdim * DESCRIPTION: Common low-level function to insert a new name into the global 768281075Sdim * list of Externals which will in turn be later emitted as 769281075Sdim * External() declarations in the disassembled output. 770281075Sdim * 771281075Sdim * Note: The external name should not include a root prefix 772281075Sdim * (backslash). We do not want External() statements to contain 773281075Sdim * a leading '\', as this prevents duplicate external statements 774281075Sdim * of the form: 775281075Sdim * 776281075Sdim * External (\ABCD) 777281075Sdim * External (ABCD) 778281075Sdim * 779281075Sdim * This would cause a compile time error when the disassembled 780281075Sdim * output file is recompiled. 781281075Sdim * 782281075Sdim * There are two cases that are handled here. For both, we emit 783281075Sdim * an External() statement: 784281075Sdim * 1) The name was simply not found in the namespace. 785281075Sdim * 2) The name was found, but it originated in a table other than 786281075Sdim * the table that is being disassembled. 787281075Sdim * 788281075Sdim ******************************************************************************/ 789281075Sdim 790281075Sdimstatic ACPI_STATUS 791281075SdimAcpiDmCreateNewExternal ( 792281075Sdim char *ExternalPath, 793281075Sdim char *InternalPath, 794281075Sdim UINT8 Type, 795281075Sdim UINT32 Value, 796281075Sdim UINT16 Flags) 797281075Sdim{ 798281075Sdim ACPI_EXTERNAL_LIST *NewExternal; 799281075Sdim ACPI_EXTERNAL_LIST *NextExternal; 800281075Sdim ACPI_EXTERNAL_LIST *PrevExternal = NULL; 801281075Sdim 802281075Sdim 803281075Sdim ACPI_FUNCTION_TRACE (DmCreateNewExternal); 804281075Sdim 805281075Sdim 806254745Sjkim /* Check all existing externals to ensure no duplicates */ 807254745Sjkim 808254745Sjkim NextExternal = AcpiGbl_ExternalList; 809254745Sjkim while (NextExternal) 810254745Sjkim { 811306536Sjkim /* Check for duplicates */ 812306536Sjkim 813306536Sjkim if (!strcmp (ExternalPath, NextExternal->Path)) 814254745Sjkim { 815306536Sjkim /* 816306536Sjkim * If this external came from an External() opcode, we are 817306536Sjkim * finished with this one. (No need to check any further). 818306536Sjkim */ 819306536Sjkim if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE) 820254745Sjkim { 821306536Sjkim return_ACPI_STATUS (AE_ALREADY_EXISTS); 822254745Sjkim } 823254745Sjkim 824254745Sjkim /* Allow upgrade of type from ANY */ 825254745Sjkim 826306536Sjkim else if ((NextExternal->Type == ACPI_TYPE_ANY) && 827306536Sjkim (Type != ACPI_TYPE_ANY)) 828254745Sjkim { 829254745Sjkim NextExternal->Type = Type; 830306536Sjkim } 831306536Sjkim 832306536Sjkim /* Update the argument count as necessary */ 833306536Sjkim 834306536Sjkim if (Value < NextExternal->Value) 835306536Sjkim { 836254745Sjkim NextExternal->Value = Value; 837254745Sjkim } 838254745Sjkim 839306536Sjkim /* Update flags. */ 840306536Sjkim 841306536Sjkim NextExternal->Flags |= Flags; 842306536Sjkim NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED; 843306536Sjkim 844281075Sdim return_ACPI_STATUS (AE_ALREADY_EXISTS); 845254745Sjkim } 846254745Sjkim 847254745Sjkim NextExternal = NextExternal->Next; 848254745Sjkim } 849254745Sjkim 850254745Sjkim /* Allocate and init a new External() descriptor */ 851254745Sjkim 852254745Sjkim NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); 853254745Sjkim if (!NewExternal) 854254745Sjkim { 855281075Sdim return_ACPI_STATUS (AE_NO_MEMORY); 856254745Sjkim } 857254745Sjkim 858281075Sdim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 859281075Sdim "Adding external reference node (%s) type [%s]\n", 860281075Sdim ExternalPath, AcpiUtGetTypeName (Type))); 861254745Sjkim 862281075Sdim NewExternal->Flags = Flags; 863281075Sdim NewExternal->Value = Value; 864254745Sjkim NewExternal->Path = ExternalPath; 865254745Sjkim NewExternal->Type = Type; 866306536Sjkim NewExternal->Length = (UINT16) strlen (ExternalPath); 867254745Sjkim NewExternal->InternalPath = InternalPath; 868254745Sjkim 869254745Sjkim /* Link the new descriptor into the global list, alphabetically ordered */ 870254745Sjkim 871254745Sjkim NextExternal = AcpiGbl_ExternalList; 872254745Sjkim while (NextExternal) 873254745Sjkim { 874254745Sjkim if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0) 875254745Sjkim { 876254745Sjkim if (PrevExternal) 877254745Sjkim { 878254745Sjkim PrevExternal->Next = NewExternal; 879254745Sjkim } 880254745Sjkim else 881254745Sjkim { 882254745Sjkim AcpiGbl_ExternalList = NewExternal; 883254745Sjkim } 884254745Sjkim 885254745Sjkim NewExternal->Next = NextExternal; 886281075Sdim return_ACPI_STATUS (AE_OK); 887254745Sjkim } 888254745Sjkim 889254745Sjkim PrevExternal = NextExternal; 890254745Sjkim NextExternal = NextExternal->Next; 891254745Sjkim } 892254745Sjkim 893254745Sjkim if (PrevExternal) 894254745Sjkim { 895254745Sjkim PrevExternal->Next = NewExternal; 896254745Sjkim } 897254745Sjkim else 898254745Sjkim { 899254745Sjkim AcpiGbl_ExternalList = NewExternal; 900254745Sjkim } 901281075Sdim 902281075Sdim return_ACPI_STATUS (AE_OK); 903254745Sjkim} 904254745Sjkim 905254745Sjkim 906254745Sjkim/******************************************************************************* 907254745Sjkim * 908198054Sjkim * FUNCTION: AcpiDmAddExternalsToNamespace 909198054Sjkim * 910198054Sjkim * PARAMETERS: None 911198054Sjkim * 912198054Sjkim * RETURN: None 913198054Sjkim * 914198054Sjkim * DESCRIPTION: Add all externals to the namespace. Allows externals to be 915198054Sjkim * "resolved". 916198054Sjkim * 917198054Sjkim ******************************************************************************/ 918198054Sjkim 919198054Sjkimvoid 920198054SjkimAcpiDmAddExternalsToNamespace ( 921198054Sjkim void) 922198054Sjkim{ 923198054Sjkim ACPI_STATUS Status; 924198054Sjkim ACPI_NAMESPACE_NODE *Node; 925235945Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 926198054Sjkim ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 927198054Sjkim 928198054Sjkim 929198054Sjkim while (External) 930198054Sjkim { 931198054Sjkim /* Add the external name (object) into the namespace */ 932198054Sjkim 933198054Sjkim Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, 934306536Sjkim ACPI_IMODE_LOAD_PASS1, 935306536Sjkim ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, 936306536Sjkim NULL, &Node); 937198054Sjkim 938198054Sjkim if (ACPI_FAILURE (Status)) 939198054Sjkim { 940198054Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 941198054Sjkim "while adding external to namespace [%s]", 942198054Sjkim External->Path)); 943198054Sjkim } 944235945Sjkim 945235945Sjkim else switch (External->Type) 946198054Sjkim { 947235945Sjkim case ACPI_TYPE_METHOD: 948235945Sjkim 949198054Sjkim /* For methods, we need to save the argument count */ 950198054Sjkim 951235945Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 952235945Sjkim ObjDesc->Method.ParamCount = (UINT8) External->Value; 953235945Sjkim Node->Object = ObjDesc; 954235945Sjkim break; 955235945Sjkim 956235945Sjkim case ACPI_TYPE_REGION: 957235945Sjkim 958235945Sjkim /* Regions require a region sub-object */ 959235945Sjkim 960235945Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 961235945Sjkim ObjDesc->Region.Node = Node; 962235945Sjkim Node->Object = ObjDesc; 963235945Sjkim break; 964235945Sjkim 965235945Sjkim default: 966250838Sjkim 967235945Sjkim break; 968198054Sjkim } 969198054Sjkim 970198054Sjkim External = External->Next; 971198054Sjkim } 972198054Sjkim} 973198054Sjkim 974198054Sjkim 975198054Sjkim/******************************************************************************* 976198054Sjkim * 977198054Sjkim * FUNCTION: AcpiDmGetExternalMethodCount 978198054Sjkim * 979198054Sjkim * PARAMETERS: None 980198054Sjkim * 981198054Sjkim * RETURN: The number of control method externals in the external list 982198054Sjkim * 983198054Sjkim * DESCRIPTION: Return the number of method externals that have been generated. 984198054Sjkim * If any control method externals have been found, we must 985198054Sjkim * re-parse the entire definition block with the new information 986198054Sjkim * (number of arguments for the methods.) This is limitation of 987198054Sjkim * AML, we don't know the number of arguments from the control 988198054Sjkim * method invocation itself. 989198054Sjkim * 990198054Sjkim ******************************************************************************/ 991198054Sjkim 992198054SjkimUINT32 993198054SjkimAcpiDmGetExternalMethodCount ( 994198054Sjkim void) 995198054Sjkim{ 996198054Sjkim ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 997198054Sjkim UINT32 Count = 0; 998198054Sjkim 999198054Sjkim 1000198054Sjkim while (External) 1001198054Sjkim { 1002198054Sjkim if (External->Type == ACPI_TYPE_METHOD) 1003198054Sjkim { 1004198054Sjkim Count++; 1005198054Sjkim } 1006198054Sjkim 1007198054Sjkim External = External->Next; 1008198054Sjkim } 1009198054Sjkim 1010198054Sjkim return (Count); 1011198054Sjkim} 1012198054Sjkim 1013198054Sjkim 1014198054Sjkim/******************************************************************************* 1015198054Sjkim * 1016198054Sjkim * FUNCTION: AcpiDmClearExternalList 1017198054Sjkim * 1018198054Sjkim * PARAMETERS: None 1019198054Sjkim * 1020198054Sjkim * RETURN: None 1021198054Sjkim * 1022198054Sjkim * DESCRIPTION: Free the entire External info list 1023198054Sjkim * 1024198054Sjkim ******************************************************************************/ 1025198054Sjkim 1026198054Sjkimvoid 1027198054SjkimAcpiDmClearExternalList ( 1028198054Sjkim void) 1029198054Sjkim{ 1030198054Sjkim ACPI_EXTERNAL_LIST *NextExternal; 1031198054Sjkim 1032198054Sjkim 1033198054Sjkim while (AcpiGbl_ExternalList) 1034198054Sjkim { 1035198054Sjkim NextExternal = AcpiGbl_ExternalList->Next; 1036198054Sjkim ACPI_FREE (AcpiGbl_ExternalList->Path); 1037198054Sjkim ACPI_FREE (AcpiGbl_ExternalList); 1038198054Sjkim AcpiGbl_ExternalList = NextExternal; 1039198054Sjkim } 1040198054Sjkim} 1041198054Sjkim 1042198054Sjkim 1043198054Sjkim/******************************************************************************* 1044198054Sjkim * 1045198054Sjkim * FUNCTION: AcpiDmEmitExternals 1046198054Sjkim * 1047198054Sjkim * PARAMETERS: None 1048198054Sjkim * 1049198054Sjkim * RETURN: None 1050198054Sjkim * 1051198054Sjkim * DESCRIPTION: Emit an External() ASL statement for each of the externals in 1052198054Sjkim * the global external info list. 1053198054Sjkim * 1054198054Sjkim ******************************************************************************/ 1055198054Sjkim 1056198054Sjkimvoid 1057198054SjkimAcpiDmEmitExternals ( 1058198054Sjkim void) 1059198054Sjkim{ 1060198054Sjkim ACPI_EXTERNAL_LIST *NextExternal; 1061198054Sjkim 1062198054Sjkim 1063198054Sjkim if (!AcpiGbl_ExternalList) 1064198054Sjkim { 1065198054Sjkim return; 1066198054Sjkim } 1067198054Sjkim 1068198054Sjkim /* 1069246849Sjkim * Determine the number of control methods in the external list, and 1070246849Sjkim * also how many of those externals were resolved via the namespace. 1071246849Sjkim */ 1072246849Sjkim NextExternal = AcpiGbl_ExternalList; 1073246849Sjkim while (NextExternal) 1074246849Sjkim { 1075246849Sjkim if (NextExternal->Type == ACPI_TYPE_METHOD) 1076246849Sjkim { 1077246849Sjkim AcpiGbl_NumExternalMethods++; 1078281075Sdim if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE) 1079246849Sjkim { 1080246849Sjkim AcpiGbl_ResolvedExternalMethods++; 1081246849Sjkim } 1082246849Sjkim } 1083246849Sjkim 1084246849Sjkim NextExternal = NextExternal->Next; 1085246849Sjkim } 1086246849Sjkim 1087246849Sjkim /* Check if any control methods were unresolved */ 1088246849Sjkim 1089246849Sjkim AcpiDmUnresolvedWarning (1); 1090246849Sjkim 1091254745Sjkim if (Gbl_ExternalRefFilename) 1092254745Sjkim { 1093254745Sjkim AcpiOsPrintf ( 1094306536Sjkim " /*\n * External declarations were imported from\n" 1095306536Sjkim " * a reference file -- %s\n */\n\n", 1096254745Sjkim Gbl_ExternalRefFilename); 1097254745Sjkim } 1098254745Sjkim 1099246849Sjkim /* 1100306536Sjkim * Walk and emit the list of externals found during the AML parsing 1101198054Sjkim */ 1102198054Sjkim while (AcpiGbl_ExternalList) 1103198054Sjkim { 1104281075Sdim if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED)) 1105253690Sjkim { 1106306536Sjkim AcpiOsPrintf (" External (%s%s)", 1107253690Sjkim AcpiGbl_ExternalList->Path, 1108253690Sjkim AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); 1109198054Sjkim 1110306536Sjkim /* Check for "unresolved" method reference */ 1111253690Sjkim 1112306536Sjkim if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) && 1113306536Sjkim (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE))) 1114246849Sjkim { 1115306536Sjkim AcpiOsPrintf (" // Warning: Unknown method, " 1116306536Sjkim "guessing %u arguments", 1117246849Sjkim AcpiGbl_ExternalList->Value); 1118246849Sjkim } 1119306536Sjkim 1120306536Sjkim /* Check for external from a external references file */ 1121306536Sjkim 1122306536Sjkim else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE) 1123306536Sjkim { 1124306536Sjkim if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 1125306536Sjkim { 1126306536Sjkim AcpiOsPrintf (" // %u Arguments", 1127306536Sjkim AcpiGbl_ExternalList->Value); 1128306536Sjkim } 1129306536Sjkim 1130306536Sjkim AcpiOsPrintf (" // From external reference file"); 1131306536Sjkim } 1132306536Sjkim 1133306536Sjkim /* This is the normal external case */ 1134306536Sjkim 1135246849Sjkim else 1136246849Sjkim { 1137306536Sjkim /* For methods, add a comment with the number of arguments */ 1138306536Sjkim 1139306536Sjkim if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 1140306536Sjkim { 1141306536Sjkim AcpiOsPrintf (" // %u Arguments", 1142306536Sjkim AcpiGbl_ExternalList->Value); 1143306536Sjkim } 1144246849Sjkim } 1145306536Sjkim 1146306536Sjkim AcpiOsPrintf ("\n"); 1147198054Sjkim } 1148198054Sjkim 1149198054Sjkim /* Free this external info block and move on to next external */ 1150198054Sjkim 1151198054Sjkim NextExternal = AcpiGbl_ExternalList->Next; 1152281075Sdim if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED) 1153198054Sjkim { 1154198054Sjkim ACPI_FREE (AcpiGbl_ExternalList->InternalPath); 1155198054Sjkim } 1156198054Sjkim 1157198054Sjkim ACPI_FREE (AcpiGbl_ExternalList->Path); 1158198054Sjkim ACPI_FREE (AcpiGbl_ExternalList); 1159198054Sjkim AcpiGbl_ExternalList = NextExternal; 1160198054Sjkim } 1161198054Sjkim 1162198054Sjkim AcpiOsPrintf ("\n"); 1163198054Sjkim} 1164246849Sjkim 1165246849Sjkim 1166246849Sjkim/******************************************************************************* 1167246849Sjkim * 1168246849Sjkim * FUNCTION: AcpiDmUnresolvedWarning 1169246849Sjkim * 1170246849Sjkim * PARAMETERS: Type - Where to output the warning. 1171246849Sjkim * 0 means write to stderr 1172246849Sjkim * 1 means write to AcpiOsPrintf 1173246849Sjkim * 1174246849Sjkim * RETURN: None 1175246849Sjkim * 1176246849Sjkim * DESCRIPTION: Issue warning message if there are unresolved external control 1177246849Sjkim * methods within the disassembly. 1178246849Sjkim * 1179246849Sjkim ******************************************************************************/ 1180246849Sjkim 1181246849Sjkim#if 0 1182246849SjkimSummary of the external control method problem: 1183246849Sjkim 1184246849SjkimWhen the -e option is used with disassembly, the various SSDTs are simply 1185246849Sjkimloaded into a global namespace for the disassembler to use in order to 1186246849Sjkimresolve control method references (invocations). 1187246849Sjkim 1188246849SjkimThe disassembler tracks any such references, and will emit an External() 1189246849Sjkimstatement for these types of methods, with the proper number of arguments . 1190246849Sjkim 1191246849SjkimWithout the SSDTs, the AML does not contain enough information to properly 1192246849Sjkimdisassemble the control method invocation -- because the disassembler does 1193246849Sjkimnot know how many arguments to parse. 1194246849Sjkim 1195246849SjkimAn example: Assume we have two control methods. ABCD has one argument, and 1196246849SjkimEFGH has zero arguments. Further, we have two additional control methods 1197246849Sjkimthat invoke ABCD and EFGH, named T1 and T2: 1198246849Sjkim 1199246849Sjkim Method (ABCD, 1) 1200246849Sjkim { 1201246849Sjkim } 1202246849Sjkim Method (EFGH, 0) 1203246849Sjkim { 1204246849Sjkim } 1205246849Sjkim Method (T1) 1206246849Sjkim { 1207246849Sjkim ABCD (Add (2, 7, Local0)) 1208246849Sjkim } 1209246849Sjkim Method (T2) 1210246849Sjkim { 1211246849Sjkim EFGH () 1212246849Sjkim Add (2, 7, Local0) 1213246849Sjkim } 1214246849Sjkim 1215246849SjkimHere is the AML code that is generated for T1 and T2: 1216246849Sjkim 1217246849Sjkim 185: Method (T1) 1218246849Sjkim 1219246849Sjkim0000034C: 14 10 54 31 5F 5F 00 ... "..T1__." 1220246849Sjkim 1221246849Sjkim 186: { 1222246849Sjkim 187: ABCD (Add (2, 7, Local0)) 1223246849Sjkim 1224246849Sjkim00000353: 41 42 43 44 ............ "ABCD" 1225246849Sjkim00000357: 72 0A 02 0A 07 60 ...... "r....`" 1226246849Sjkim 1227246849Sjkim 188: } 1228246849Sjkim 1229246849Sjkim 190: Method (T2) 1230246849Sjkim 1231246849Sjkim0000035D: 14 10 54 32 5F 5F 00 ... "..T2__." 1232246849Sjkim 1233246849Sjkim 191: { 1234246849Sjkim 192: EFGH () 1235246849Sjkim 1236246849Sjkim00000364: 45 46 47 48 ............ "EFGH" 1237246849Sjkim 1238246849Sjkim 193: Add (2, 7, Local0) 1239246849Sjkim 1240246849Sjkim00000368: 72 0A 02 0A 07 60 ...... "r....`" 1241246849Sjkim 194: } 1242246849Sjkim 1243246849SjkimNote that the AML code for T1 and T2 is essentially identical. When 1244246849Sjkimdisassembling this code, the methods ABCD and EFGH must be known to the 1245246849Sjkimdisassembler, otherwise it does not know how to handle the method invocations. 1246246849Sjkim 1247246849SjkimIn other words, if ABCD and EFGH are actually external control methods 1248246849Sjkimappearing in an SSDT, the disassembler does not know what to do unless 1249246849Sjkimthe owning SSDT has been loaded via the -e option. 1250246849Sjkim#endif 1251246849Sjkim 1252306536Sjkimstatic char ExternalWarningPart1[600]; 1253306536Sjkimstatic char ExternalWarningPart2[400]; 1254306536Sjkimstatic char ExternalWarningPart3[400]; 1255306536Sjkimstatic char ExternalWarningPart4[200]; 1256306536Sjkim 1257246849Sjkimvoid 1258246849SjkimAcpiDmUnresolvedWarning ( 1259246849Sjkim UINT8 Type) 1260246849Sjkim{ 1261306536Sjkim char *Format; 1262306536Sjkim char Pad[] = " *"; 1263306536Sjkim char NoPad[] = ""; 1264246849Sjkim 1265306536Sjkim 1266246849Sjkim if (!AcpiGbl_NumExternalMethods) 1267246849Sjkim { 1268246849Sjkim return; 1269246849Sjkim } 1270246849Sjkim 1271306536Sjkim if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods) 1272306536Sjkim { 1273306536Sjkim return; 1274306536Sjkim } 1275306536Sjkim 1276306536Sjkim Format = Type ? Pad : NoPad; 1277306536Sjkim 1278306536Sjkim sprintf (ExternalWarningPart1, 1279306536Sjkim "%s iASL Warning: There %s %u external control method%s found during\n" 1280306536Sjkim "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n" 1281306536Sjkim "%s ACPI tables may be required to properly disassemble the code. This\n" 1282306536Sjkim "%s resulting disassembler output file may not compile because the\n" 1283306536Sjkim "%s disassembler did not know how many arguments to assign to the\n" 1284306536Sjkim "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n" 1285306536Sjkim "%s runtime and may or may not be available via the host OS.\n", 1286306536Sjkim Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"), 1287306536Sjkim AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""), 1288306536Sjkim Format, AcpiGbl_ResolvedExternalMethods, 1289306536Sjkim (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"), 1290306536Sjkim (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods), 1291306536Sjkim Format, Format, Format, Format, Format); 1292306536Sjkim 1293306536Sjkim sprintf (ExternalWarningPart2, 1294306536Sjkim "%s To specify the tables needed to resolve external control method\n" 1295306536Sjkim "%s references, the -e option can be used to specify the filenames.\n" 1296306536Sjkim "%s Example iASL invocations:\n" 1297306536Sjkim "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n" 1298306536Sjkim "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n" 1299306536Sjkim "%s iasl -e ssdt*.aml -d dsdt.aml\n", 1300306536Sjkim Format, Format, Format, Format, Format, Format); 1301306536Sjkim 1302306536Sjkim sprintf (ExternalWarningPart3, 1303306536Sjkim "%s In addition, the -fe option can be used to specify a file containing\n" 1304306536Sjkim "%s control method external declarations with the associated method\n" 1305306536Sjkim "%s argument counts. Each line of the file must be of the form:\n" 1306306536Sjkim "%s External (<method pathname>, MethodObj, <argument count>)\n" 1307306536Sjkim "%s Invocation:\n" 1308306536Sjkim "%s iasl -fe refs.txt -d dsdt.aml\n", 1309306536Sjkim Format, Format, Format, Format, Format, Format); 1310306536Sjkim 1311306536Sjkim sprintf (ExternalWarningPart4, 1312306536Sjkim "%s The following methods were unresolved and many not compile properly\n" 1313306536Sjkim "%s because the disassembler had to guess at the number of arguments\n" 1314306536Sjkim "%s required for each:\n", 1315306536Sjkim Format, Format, Format); 1316306536Sjkim 1317246849Sjkim if (Type) 1318246849Sjkim { 1319246849Sjkim if (!AcpiGbl_ExternalFileList) 1320246849Sjkim { 1321246849Sjkim /* The -e option was not specified */ 1322246849Sjkim 1323306536Sjkim AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n", 1324306536Sjkim ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3, 1325306536Sjkim ExternalWarningPart4); 1326246849Sjkim } 1327306536Sjkim else 1328246849Sjkim { 1329246849Sjkim /* The -e option was specified, but there are still some unresolved externals */ 1330246849Sjkim 1331306536Sjkim AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n", 1332306536Sjkim ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4); 1333246849Sjkim } 1334246849Sjkim } 1335246849Sjkim else 1336246849Sjkim { 1337246849Sjkim if (!AcpiGbl_ExternalFileList) 1338246849Sjkim { 1339246849Sjkim /* The -e option was not specified */ 1340246849Sjkim 1341306536Sjkim fprintf (stderr, "\n%s\n%s\n%s\n", 1342306536Sjkim ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3); 1343246849Sjkim } 1344306536Sjkim else 1345246849Sjkim { 1346246849Sjkim /* The -e option was specified, but there are still some unresolved externals */ 1347246849Sjkim 1348306536Sjkim fprintf (stderr, "\n%s\n%s\n", 1349306536Sjkim ExternalWarningPart1, ExternalWarningPart3); 1350246849Sjkim } 1351246849Sjkim } 1352246849Sjkim} 1353