1f556842eSJung-uk Kim /****************************************************************************** 2f556842eSJung-uk Kim * 3f556842eSJung-uk Kim * Module Name: dmextern - Support for External() ASL statements 4f556842eSJung-uk Kim * 5f556842eSJung-uk Kim *****************************************************************************/ 6f556842eSJung-uk Kim 7d244b227SJung-uk Kim /* 8ec3fc72fSJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 9f556842eSJung-uk Kim * All rights reserved. 10f556842eSJung-uk Kim * 11d244b227SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12d244b227SJung-uk Kim * modification, are permitted provided that the following conditions 13d244b227SJung-uk Kim * are met: 14d244b227SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15d244b227SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16d244b227SJung-uk Kim * without modification. 17d244b227SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18d244b227SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19d244b227SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20d244b227SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21d244b227SJung-uk Kim * binary redistribution. 22d244b227SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23d244b227SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24d244b227SJung-uk Kim * from this software without specific prior written permission. 25f556842eSJung-uk Kim * 26d244b227SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27d244b227SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28d244b227SJung-uk Kim * Software Foundation. 29f556842eSJung-uk Kim * 30d244b227SJung-uk Kim * NO WARRANTY 31d244b227SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32d244b227SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33d244b227SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34d244b227SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35d244b227SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36d244b227SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37d244b227SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38d244b227SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39d244b227SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40d244b227SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41d244b227SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42d244b227SJung-uk Kim */ 43f556842eSJung-uk Kim 44f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 45f556842eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 46f556842eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 47f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h> 48f556842eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h> 49f556842eSJung-uk Kim 50f556842eSJung-uk Kim 51f556842eSJung-uk Kim /* 52f556842eSJung-uk Kim * This module is used for application-level code (iASL disassembler) only. 53f556842eSJung-uk Kim * 54f556842eSJung-uk Kim * It contains the code to create and emit any necessary External() ASL 55f556842eSJung-uk Kim * statements for the module being disassembled. 56f556842eSJung-uk Kim */ 57f556842eSJung-uk Kim #define _COMPONENT ACPI_CA_DISASSEMBLER 58f556842eSJung-uk Kim ACPI_MODULE_NAME ("dmextern") 59f556842eSJung-uk Kim 60f556842eSJung-uk Kim 61f556842eSJung-uk Kim /* 62f556842eSJung-uk Kim * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL 63f556842eSJung-uk Kim * ObjectTypeKeyword. Used to generate typed external declarations 64f556842eSJung-uk Kim */ 65f556842eSJung-uk Kim static const char *AcpiGbl_DmTypeNames[] = 66f556842eSJung-uk Kim { 67f556842eSJung-uk Kim /* 00 */ "", /* Type ANY */ 68f556842eSJung-uk Kim /* 01 */ ", IntObj", 69f556842eSJung-uk Kim /* 02 */ ", StrObj", 70f556842eSJung-uk Kim /* 03 */ ", BuffObj", 71f556842eSJung-uk Kim /* 04 */ ", PkgObj", 72f556842eSJung-uk Kim /* 05 */ ", FieldUnitObj", 73f556842eSJung-uk Kim /* 06 */ ", DeviceObj", 74f556842eSJung-uk Kim /* 07 */ ", EventObj", 75f556842eSJung-uk Kim /* 08 */ ", MethodObj", 76f556842eSJung-uk Kim /* 09 */ ", MutexObj", 77f556842eSJung-uk Kim /* 10 */ ", OpRegionObj", 78f556842eSJung-uk Kim /* 11 */ ", PowerResObj", 79f556842eSJung-uk Kim /* 12 */ ", ProcessorObj", 80f556842eSJung-uk Kim /* 13 */ ", ThermalZoneObj", 81f556842eSJung-uk Kim /* 14 */ ", BuffFieldObj", 82f556842eSJung-uk Kim /* 15 */ ", DDBHandleObj", 83f556842eSJung-uk Kim /* 16 */ "", /* Debug object */ 84f556842eSJung-uk Kim /* 17 */ ", FieldUnitObj", 85f556842eSJung-uk Kim /* 18 */ ", FieldUnitObj", 86f556842eSJung-uk Kim /* 19 */ ", FieldUnitObj" 87f556842eSJung-uk Kim }; 88f556842eSJung-uk Kim 89f556842eSJung-uk Kim 90f556842eSJung-uk Kim /* Local prototypes */ 91f556842eSJung-uk Kim 92f556842eSJung-uk Kim static const char * 93f556842eSJung-uk Kim AcpiDmGetObjectTypeName ( 94f556842eSJung-uk Kim ACPI_OBJECT_TYPE Type); 95f556842eSJung-uk Kim 96f556842eSJung-uk Kim static char * 97f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix ( 98f556842eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 99f556842eSJung-uk Kim char *Path); 100f556842eSJung-uk Kim 101f556842eSJung-uk Kim 102f556842eSJung-uk Kim /******************************************************************************* 103f556842eSJung-uk Kim * 104f556842eSJung-uk Kim * FUNCTION: AcpiDmGetObjectTypeName 105f556842eSJung-uk Kim * 106f556842eSJung-uk Kim * PARAMETERS: Type - An ACPI_OBJECT_TYPE 107f556842eSJung-uk Kim * 108f556842eSJung-uk Kim * RETURN: Pointer to a string 109f556842eSJung-uk Kim * 110f556842eSJung-uk Kim * DESCRIPTION: Map an object type to the ASL object type string. 111f556842eSJung-uk Kim * 112f556842eSJung-uk Kim ******************************************************************************/ 113f556842eSJung-uk Kim 114f556842eSJung-uk Kim static const char * 115f556842eSJung-uk Kim AcpiDmGetObjectTypeName ( 116f556842eSJung-uk Kim ACPI_OBJECT_TYPE Type) 117f556842eSJung-uk Kim { 118f556842eSJung-uk Kim 119f556842eSJung-uk Kim if (Type == ACPI_TYPE_LOCAL_SCOPE) 120f556842eSJung-uk Kim { 121f556842eSJung-uk Kim Type = ACPI_TYPE_DEVICE; 122f556842eSJung-uk Kim } 123f556842eSJung-uk Kim 124f556842eSJung-uk Kim else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) 125f556842eSJung-uk Kim { 126f556842eSJung-uk Kim return (""); 127f556842eSJung-uk Kim } 128f556842eSJung-uk Kim 129f556842eSJung-uk Kim return (AcpiGbl_DmTypeNames[Type]); 130f556842eSJung-uk Kim } 131f556842eSJung-uk Kim 132f556842eSJung-uk Kim 133f556842eSJung-uk Kim /******************************************************************************* 134f556842eSJung-uk Kim * 135f556842eSJung-uk Kim * FUNCTION: AcpiDmNormalizeParentPrefix 136f556842eSJung-uk Kim * 137f556842eSJung-uk Kim * PARAMETERS: Op - Parse op 138f556842eSJung-uk Kim * Path - Path with parent prefix 139f556842eSJung-uk Kim * 140f556842eSJung-uk Kim * RETURN: The full pathname to the object (from the namespace root) 141f556842eSJung-uk Kim * 142f556842eSJung-uk Kim * DESCRIPTION: Returns the full pathname of a path with parent prefix 143f556842eSJung-uk Kim * The caller must free the fullpath returned. 144f556842eSJung-uk Kim * 145f556842eSJung-uk Kim ******************************************************************************/ 146f556842eSJung-uk Kim 147f556842eSJung-uk Kim static char * 148f556842eSJung-uk Kim AcpiDmNormalizeParentPrefix ( 149f556842eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 150f556842eSJung-uk Kim char *Path) 151f556842eSJung-uk Kim { 152f556842eSJung-uk Kim ACPI_NAMESPACE_NODE *Node; 153f556842eSJung-uk Kim char *Fullpath; 154f556842eSJung-uk Kim char *ParentPath; 155f556842eSJung-uk Kim ACPI_SIZE Length; 156*ed17e06eSJung-uk Kim UINT32 Index = 0; 157f556842eSJung-uk Kim 158f556842eSJung-uk Kim 159*ed17e06eSJung-uk Kim if (!Op) 160*ed17e06eSJung-uk Kim { 161*ed17e06eSJung-uk Kim return (NULL); 162*ed17e06eSJung-uk Kim } 163f556842eSJung-uk Kim 164*ed17e06eSJung-uk Kim /* Search upwards in the parse tree until we reach the next namespace node */ 165*ed17e06eSJung-uk Kim 166*ed17e06eSJung-uk Kim Op = Op->Common.Parent; 167f556842eSJung-uk Kim while (Op) 168f556842eSJung-uk Kim { 169f556842eSJung-uk Kim if (Op->Common.Node) 170f556842eSJung-uk Kim { 171f556842eSJung-uk Kim break; 172f556842eSJung-uk Kim } 173f556842eSJung-uk Kim 174f556842eSJung-uk Kim Op = Op->Common.Parent; 175f556842eSJung-uk Kim } 176f556842eSJung-uk Kim 177f556842eSJung-uk Kim if (!Op) 178f556842eSJung-uk Kim { 179f556842eSJung-uk Kim return (NULL); 180f556842eSJung-uk Kim } 181f556842eSJung-uk Kim 182f556842eSJung-uk Kim /* 183f556842eSJung-uk Kim * Find the actual parent node for the reference: 184f556842eSJung-uk Kim * Remove all carat prefixes from the input path. 185f556842eSJung-uk Kim * There may be multiple parent prefixes (For example, ^^^M000) 186f556842eSJung-uk Kim */ 187f556842eSJung-uk Kim Node = Op->Common.Node; 188f556842eSJung-uk Kim while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) 189f556842eSJung-uk Kim { 190a88e22b7SJung-uk Kim Node = Node->Parent; 191f556842eSJung-uk Kim Path++; 192f556842eSJung-uk Kim } 193f556842eSJung-uk Kim 194f556842eSJung-uk Kim if (!Node) 195f556842eSJung-uk Kim { 196f556842eSJung-uk Kim return (NULL); 197f556842eSJung-uk Kim } 198f556842eSJung-uk Kim 199f556842eSJung-uk Kim /* Get the full pathname for the parent node */ 200f556842eSJung-uk Kim 201f556842eSJung-uk Kim ParentPath = AcpiNsGetExternalPathname (Node); 202f556842eSJung-uk Kim if (!ParentPath) 203f556842eSJung-uk Kim { 204f556842eSJung-uk Kim return (NULL); 205f556842eSJung-uk Kim } 206f556842eSJung-uk Kim 207f556842eSJung-uk Kim Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); 2088c8be05fSJung-uk Kim if (ParentPath[1]) 2098c8be05fSJung-uk Kim { 2108c8be05fSJung-uk Kim /* 2118c8be05fSJung-uk Kim * If ParentPath is not just a simple '\', increment the length 2128c8be05fSJung-uk Kim * for the required dot separator (ParentPath.Path) 2138c8be05fSJung-uk Kim */ 2148c8be05fSJung-uk Kim Length++; 215*ed17e06eSJung-uk Kim 216*ed17e06eSJung-uk Kim /* For External() statements, we do not want a leading '\' */ 217*ed17e06eSJung-uk Kim 218*ed17e06eSJung-uk Kim if (*ParentPath == AML_ROOT_PREFIX) 219*ed17e06eSJung-uk Kim { 220*ed17e06eSJung-uk Kim Index = 1; 221*ed17e06eSJung-uk Kim } 2228c8be05fSJung-uk Kim } 2238c8be05fSJung-uk Kim 224f556842eSJung-uk Kim Fullpath = ACPI_ALLOCATE_ZEROED (Length); 225f556842eSJung-uk Kim if (!Fullpath) 226f556842eSJung-uk Kim { 227f556842eSJung-uk Kim goto Cleanup; 228f556842eSJung-uk Kim } 229f556842eSJung-uk Kim 230f556842eSJung-uk Kim /* 231f556842eSJung-uk Kim * Concatenate parent fullpath and path. For example, 232f556842eSJung-uk Kim * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" 233f556842eSJung-uk Kim * 234f556842eSJung-uk Kim * Copy the parent path 235f556842eSJung-uk Kim */ 236*ed17e06eSJung-uk Kim ACPI_STRCPY (Fullpath, &ParentPath[Index]); 237f556842eSJung-uk Kim 238f38b0f21SJung-uk Kim /* 239f38b0f21SJung-uk Kim * Add dot separator 240f38b0f21SJung-uk Kim * (don't need dot if parent fullpath is a single backslash) 241f38b0f21SJung-uk Kim */ 242f556842eSJung-uk Kim if (ParentPath[1]) 243f556842eSJung-uk Kim { 244f556842eSJung-uk Kim ACPI_STRCAT (Fullpath, "."); 245f556842eSJung-uk Kim } 246f556842eSJung-uk Kim 247f556842eSJung-uk Kim /* Copy child path (carat parent prefix(es) were skipped above) */ 248f556842eSJung-uk Kim 249f556842eSJung-uk Kim ACPI_STRCAT (Fullpath, Path); 250f556842eSJung-uk Kim 251f556842eSJung-uk Kim Cleanup: 252f556842eSJung-uk Kim ACPI_FREE (ParentPath); 253f556842eSJung-uk Kim return (Fullpath); 254f556842eSJung-uk Kim } 255f556842eSJung-uk Kim 256f556842eSJung-uk Kim 257f556842eSJung-uk Kim /******************************************************************************* 258f556842eSJung-uk Kim * 259709fac06SJung-uk Kim * FUNCTION: AcpiDmAddToExternalFileList 260709fac06SJung-uk Kim * 261709fac06SJung-uk Kim * PARAMETERS: PathList - Single path or list separated by comma 262709fac06SJung-uk Kim * 263709fac06SJung-uk Kim * RETURN: None 264709fac06SJung-uk Kim * 265709fac06SJung-uk Kim * DESCRIPTION: Add external files to global list 266709fac06SJung-uk Kim * 267709fac06SJung-uk Kim ******************************************************************************/ 268709fac06SJung-uk Kim 269709fac06SJung-uk Kim ACPI_STATUS 270709fac06SJung-uk Kim AcpiDmAddToExternalFileList ( 271709fac06SJung-uk Kim char *PathList) 272709fac06SJung-uk Kim { 273709fac06SJung-uk Kim ACPI_EXTERNAL_FILE *ExternalFile; 274709fac06SJung-uk Kim char *Path; 275709fac06SJung-uk Kim char *TmpPath; 276709fac06SJung-uk Kim 277709fac06SJung-uk Kim 278709fac06SJung-uk Kim if (!PathList) 279709fac06SJung-uk Kim { 280709fac06SJung-uk Kim return (AE_OK); 281709fac06SJung-uk Kim } 282709fac06SJung-uk Kim 283709fac06SJung-uk Kim Path = strtok (PathList, ","); 284709fac06SJung-uk Kim 285709fac06SJung-uk Kim while (Path) 286709fac06SJung-uk Kim { 287709fac06SJung-uk Kim TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1); 288709fac06SJung-uk Kim if (!TmpPath) 289709fac06SJung-uk Kim { 290709fac06SJung-uk Kim return (AE_NO_MEMORY); 291709fac06SJung-uk Kim } 292709fac06SJung-uk Kim 293709fac06SJung-uk Kim ACPI_STRCPY (TmpPath, Path); 294709fac06SJung-uk Kim 295709fac06SJung-uk Kim ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE)); 296709fac06SJung-uk Kim if (!ExternalFile) 297709fac06SJung-uk Kim { 298709fac06SJung-uk Kim ACPI_FREE (TmpPath); 299709fac06SJung-uk Kim return (AE_NO_MEMORY); 300709fac06SJung-uk Kim } 301709fac06SJung-uk Kim 302709fac06SJung-uk Kim ExternalFile->Path = TmpPath; 303709fac06SJung-uk Kim 304709fac06SJung-uk Kim if (AcpiGbl_ExternalFileList) 305709fac06SJung-uk Kim { 306709fac06SJung-uk Kim ExternalFile->Next = AcpiGbl_ExternalFileList; 307709fac06SJung-uk Kim } 308709fac06SJung-uk Kim 309709fac06SJung-uk Kim AcpiGbl_ExternalFileList = ExternalFile; 310709fac06SJung-uk Kim Path = strtok (NULL, ","); 311709fac06SJung-uk Kim } 312709fac06SJung-uk Kim 313709fac06SJung-uk Kim return (AE_OK); 314709fac06SJung-uk Kim } 315709fac06SJung-uk Kim 316709fac06SJung-uk Kim 317709fac06SJung-uk Kim /******************************************************************************* 318709fac06SJung-uk Kim * 319709fac06SJung-uk Kim * FUNCTION: AcpiDmClearExternalFileList 320709fac06SJung-uk Kim * 321709fac06SJung-uk Kim * PARAMETERS: None 322709fac06SJung-uk Kim * 323709fac06SJung-uk Kim * RETURN: None 324709fac06SJung-uk Kim * 325709fac06SJung-uk Kim * DESCRIPTION: Clear the external file list 326709fac06SJung-uk Kim * 327709fac06SJung-uk Kim ******************************************************************************/ 328709fac06SJung-uk Kim 329709fac06SJung-uk Kim void 330709fac06SJung-uk Kim AcpiDmClearExternalFileList ( 331709fac06SJung-uk Kim void) 332709fac06SJung-uk Kim { 333709fac06SJung-uk Kim ACPI_EXTERNAL_FILE *NextExternal; 334709fac06SJung-uk Kim 335709fac06SJung-uk Kim 336709fac06SJung-uk Kim while (AcpiGbl_ExternalFileList) 337709fac06SJung-uk Kim { 338709fac06SJung-uk Kim NextExternal = AcpiGbl_ExternalFileList->Next; 339709fac06SJung-uk Kim ACPI_FREE (AcpiGbl_ExternalFileList->Path); 340709fac06SJung-uk Kim ACPI_FREE (AcpiGbl_ExternalFileList); 341709fac06SJung-uk Kim AcpiGbl_ExternalFileList = NextExternal; 342709fac06SJung-uk Kim } 343709fac06SJung-uk Kim } 344709fac06SJung-uk Kim 345709fac06SJung-uk Kim 346709fac06SJung-uk Kim /******************************************************************************* 347709fac06SJung-uk Kim * 348f556842eSJung-uk Kim * FUNCTION: AcpiDmAddToExternalList 349f556842eSJung-uk Kim * 350f556842eSJung-uk Kim * PARAMETERS: Op - Current parser Op 351f556842eSJung-uk Kim * Path - Internal (AML) path to the object 352f556842eSJung-uk Kim * Type - ACPI object type to be added 353f556842eSJung-uk Kim * Value - Arg count if adding a Method object 354f556842eSJung-uk Kim * 355f556842eSJung-uk Kim * RETURN: None 356f556842eSJung-uk Kim * 357f556842eSJung-uk Kim * DESCRIPTION: Insert a new name into the global list of Externals which 358f556842eSJung-uk Kim * will in turn be later emitted as an External() declaration 359f556842eSJung-uk Kim * in the disassembled output. 360f556842eSJung-uk Kim * 361f556842eSJung-uk Kim ******************************************************************************/ 362f556842eSJung-uk Kim 363f556842eSJung-uk Kim void 364f556842eSJung-uk Kim AcpiDmAddToExternalList ( 365f556842eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 366f556842eSJung-uk Kim char *Path, 367f556842eSJung-uk Kim UINT8 Type, 368f556842eSJung-uk Kim UINT32 Value) 369f556842eSJung-uk Kim { 370f556842eSJung-uk Kim char *ExternalPath; 371f556842eSJung-uk Kim char *Fullpath = NULL; 372f556842eSJung-uk Kim ACPI_EXTERNAL_LIST *NewExternal; 373f556842eSJung-uk Kim ACPI_EXTERNAL_LIST *NextExternal; 374f556842eSJung-uk Kim ACPI_EXTERNAL_LIST *PrevExternal = NULL; 375f556842eSJung-uk Kim ACPI_STATUS Status; 376f556842eSJung-uk Kim 377f556842eSJung-uk Kim 378f556842eSJung-uk Kim if (!Path) 379f556842eSJung-uk Kim { 380f556842eSJung-uk Kim return; 381f556842eSJung-uk Kim } 382f556842eSJung-uk Kim 383*ed17e06eSJung-uk Kim /* 384*ed17e06eSJung-uk Kim * We don't want External() statements to contain a leading '\'. 385*ed17e06eSJung-uk Kim * This prevents duplicate external statements of the form: 386*ed17e06eSJung-uk Kim * 387*ed17e06eSJung-uk Kim * External (\ABCD) 388*ed17e06eSJung-uk Kim * External (ABCD) 389*ed17e06eSJung-uk Kim * 390*ed17e06eSJung-uk Kim * This would cause a compile time error when the disassembled 391*ed17e06eSJung-uk Kim * output file is recompiled. 392*ed17e06eSJung-uk Kim */ 393*ed17e06eSJung-uk Kim if ((*Path == AML_ROOT_PREFIX) && (Path[1])) 394*ed17e06eSJung-uk Kim { 395*ed17e06eSJung-uk Kim Path++; 396*ed17e06eSJung-uk Kim } 397*ed17e06eSJung-uk Kim 398*ed17e06eSJung-uk Kim /* Externalize the ACPI pathname */ 399f556842eSJung-uk Kim 400f556842eSJung-uk Kim Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, 401f556842eSJung-uk Kim NULL, &ExternalPath); 402f556842eSJung-uk Kim if (ACPI_FAILURE (Status)) 403f556842eSJung-uk Kim { 404f556842eSJung-uk Kim return; 405f556842eSJung-uk Kim } 406f556842eSJung-uk Kim 407*ed17e06eSJung-uk Kim /* 408*ed17e06eSJung-uk Kim * Get the full pathname from the root if "Path" has one or more 409*ed17e06eSJung-uk Kim * parent prefixes (^). Note: path will not contain a leading '\'. 410*ed17e06eSJung-uk Kim */ 411f556842eSJung-uk Kim if (*Path == (UINT8) AML_PARENT_PREFIX) 412f556842eSJung-uk Kim { 413f556842eSJung-uk Kim Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath); 414f556842eSJung-uk Kim if (Fullpath) 415f556842eSJung-uk Kim { 416f556842eSJung-uk Kim /* Set new external path */ 417f556842eSJung-uk Kim 418f556842eSJung-uk Kim ACPI_FREE (ExternalPath); 419f556842eSJung-uk Kim ExternalPath = Fullpath; 420f556842eSJung-uk Kim } 421f556842eSJung-uk Kim } 422f556842eSJung-uk Kim 423f556842eSJung-uk Kim /* Check all existing externals to ensure no duplicates */ 424f556842eSJung-uk Kim 425f556842eSJung-uk Kim NextExternal = AcpiGbl_ExternalList; 426f556842eSJung-uk Kim while (NextExternal) 427f556842eSJung-uk Kim { 428f556842eSJung-uk Kim if (!ACPI_STRCMP (ExternalPath, NextExternal->Path)) 429f556842eSJung-uk Kim { 430f556842eSJung-uk Kim /* Duplicate method, check that the Value (ArgCount) is the same */ 431f556842eSJung-uk Kim 432f556842eSJung-uk Kim if ((NextExternal->Type == ACPI_TYPE_METHOD) && 433f556842eSJung-uk Kim (NextExternal->Value != Value)) 434f556842eSJung-uk Kim { 435f556842eSJung-uk Kim ACPI_ERROR ((AE_INFO, 436ca3cf4faSJung-uk Kim "Argument count mismatch for method %s %u %u", 437f556842eSJung-uk Kim NextExternal->Path, NextExternal->Value, Value)); 438f556842eSJung-uk Kim } 439f556842eSJung-uk Kim 440f556842eSJung-uk Kim /* Allow upgrade of type from ANY */ 441f556842eSJung-uk Kim 442f556842eSJung-uk Kim else if (NextExternal->Type == ACPI_TYPE_ANY) 443f556842eSJung-uk Kim { 444f556842eSJung-uk Kim NextExternal->Type = Type; 445f556842eSJung-uk Kim NextExternal->Value = Value; 446f556842eSJung-uk Kim } 447f556842eSJung-uk Kim 448f556842eSJung-uk Kim ACPI_FREE (ExternalPath); 449f556842eSJung-uk Kim return; 450f556842eSJung-uk Kim } 451f556842eSJung-uk Kim 452f556842eSJung-uk Kim NextExternal = NextExternal->Next; 453f556842eSJung-uk Kim } 454f556842eSJung-uk Kim 455f556842eSJung-uk Kim /* Allocate and init a new External() descriptor */ 456f556842eSJung-uk Kim 457f556842eSJung-uk Kim NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); 458f556842eSJung-uk Kim if (!NewExternal) 459f556842eSJung-uk Kim { 460f556842eSJung-uk Kim ACPI_FREE (ExternalPath); 461f556842eSJung-uk Kim return; 462f556842eSJung-uk Kim } 463f556842eSJung-uk Kim 464f556842eSJung-uk Kim NewExternal->Path = ExternalPath; 465f556842eSJung-uk Kim NewExternal->Type = Type; 466f556842eSJung-uk Kim NewExternal->Value = Value; 467f556842eSJung-uk Kim NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath); 468f556842eSJung-uk Kim 469f556842eSJung-uk Kim /* Was the external path with parent prefix normalized to a fullpath? */ 470f556842eSJung-uk Kim 471f556842eSJung-uk Kim if (Fullpath == ExternalPath) 472f556842eSJung-uk Kim { 473f556842eSJung-uk Kim /* Get new internal path */ 474f556842eSJung-uk Kim 475f556842eSJung-uk Kim Status = AcpiNsInternalizeName (ExternalPath, &Path); 476f556842eSJung-uk Kim if (ACPI_FAILURE (Status)) 477f556842eSJung-uk Kim { 478f556842eSJung-uk Kim ACPI_FREE (ExternalPath); 479f556842eSJung-uk Kim ACPI_FREE (NewExternal); 480f556842eSJung-uk Kim return; 481f556842eSJung-uk Kim } 482f556842eSJung-uk Kim 483f556842eSJung-uk Kim /* Set flag to indicate External->InternalPath need to be freed */ 484f556842eSJung-uk Kim 485f556842eSJung-uk Kim NewExternal->Flags |= ACPI_IPATH_ALLOCATED; 486f556842eSJung-uk Kim } 487f556842eSJung-uk Kim 488f556842eSJung-uk Kim NewExternal->InternalPath = Path; 489f556842eSJung-uk Kim 490a7a3b383SJung-uk Kim /* Link the new descriptor into the global list, alphabetically ordered */ 491f556842eSJung-uk Kim 492f556842eSJung-uk Kim NextExternal = AcpiGbl_ExternalList; 493f556842eSJung-uk Kim while (NextExternal) 494f556842eSJung-uk Kim { 495a7a3b383SJung-uk Kim if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0) 496f556842eSJung-uk Kim { 497f556842eSJung-uk Kim if (PrevExternal) 498f556842eSJung-uk Kim { 499f556842eSJung-uk Kim PrevExternal->Next = NewExternal; 500f556842eSJung-uk Kim } 501f556842eSJung-uk Kim else 502f556842eSJung-uk Kim { 503f556842eSJung-uk Kim AcpiGbl_ExternalList = NewExternal; 504f556842eSJung-uk Kim } 505f556842eSJung-uk Kim 506f556842eSJung-uk Kim NewExternal->Next = NextExternal; 507f556842eSJung-uk Kim return; 508f556842eSJung-uk Kim } 509f556842eSJung-uk Kim 510f556842eSJung-uk Kim PrevExternal = NextExternal; 511f556842eSJung-uk Kim NextExternal = NextExternal->Next; 512f556842eSJung-uk Kim } 513f556842eSJung-uk Kim 514f556842eSJung-uk Kim if (PrevExternal) 515f556842eSJung-uk Kim { 516f556842eSJung-uk Kim PrevExternal->Next = NewExternal; 517f556842eSJung-uk Kim } 518f556842eSJung-uk Kim else 519f556842eSJung-uk Kim { 520f556842eSJung-uk Kim AcpiGbl_ExternalList = NewExternal; 521f556842eSJung-uk Kim } 522f556842eSJung-uk Kim } 523f556842eSJung-uk Kim 524f556842eSJung-uk Kim 525f556842eSJung-uk Kim /******************************************************************************* 526f556842eSJung-uk Kim * 527f556842eSJung-uk Kim * FUNCTION: AcpiDmAddExternalsToNamespace 528f556842eSJung-uk Kim * 529f556842eSJung-uk Kim * PARAMETERS: None 530f556842eSJung-uk Kim * 531f556842eSJung-uk Kim * RETURN: None 532f556842eSJung-uk Kim * 533f556842eSJung-uk Kim * DESCRIPTION: Add all externals to the namespace. Allows externals to be 534f556842eSJung-uk Kim * "resolved". 535f556842eSJung-uk Kim * 536f556842eSJung-uk Kim ******************************************************************************/ 537f556842eSJung-uk Kim 538f556842eSJung-uk Kim void 539f556842eSJung-uk Kim AcpiDmAddExternalsToNamespace ( 540f556842eSJung-uk Kim void) 541f556842eSJung-uk Kim { 542f556842eSJung-uk Kim ACPI_STATUS Status; 543f556842eSJung-uk Kim ACPI_NAMESPACE_NODE *Node; 544a7a3b383SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 545f556842eSJung-uk Kim ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 546f556842eSJung-uk Kim 547f556842eSJung-uk Kim 548f556842eSJung-uk Kim while (External) 549f556842eSJung-uk Kim { 550f556842eSJung-uk Kim /* Add the external name (object) into the namespace */ 551f556842eSJung-uk Kim 552f556842eSJung-uk Kim Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, 553f556842eSJung-uk Kim ACPI_IMODE_LOAD_PASS1, 554f556842eSJung-uk Kim ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, 555f556842eSJung-uk Kim NULL, &Node); 556f556842eSJung-uk Kim 557f556842eSJung-uk Kim if (ACPI_FAILURE (Status)) 558f556842eSJung-uk Kim { 559f556842eSJung-uk Kim ACPI_EXCEPTION ((AE_INFO, Status, 560f556842eSJung-uk Kim "while adding external to namespace [%s]", 561f556842eSJung-uk Kim External->Path)); 562f556842eSJung-uk Kim } 563a7a3b383SJung-uk Kim 564a7a3b383SJung-uk Kim else switch (External->Type) 565f556842eSJung-uk Kim { 566a7a3b383SJung-uk Kim case ACPI_TYPE_METHOD: 567a7a3b383SJung-uk Kim 568f556842eSJung-uk Kim /* For methods, we need to save the argument count */ 569f556842eSJung-uk Kim 570a7a3b383SJung-uk Kim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 571a7a3b383SJung-uk Kim ObjDesc->Method.ParamCount = (UINT8) External->Value; 572a7a3b383SJung-uk Kim Node->Object = ObjDesc; 573a7a3b383SJung-uk Kim break; 574a7a3b383SJung-uk Kim 575a7a3b383SJung-uk Kim case ACPI_TYPE_REGION: 576a7a3b383SJung-uk Kim 577a7a3b383SJung-uk Kim /* Regions require a region sub-object */ 578a7a3b383SJung-uk Kim 579a7a3b383SJung-uk Kim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 580a7a3b383SJung-uk Kim ObjDesc->Region.Node = Node; 581a7a3b383SJung-uk Kim Node->Object = ObjDesc; 582a7a3b383SJung-uk Kim break; 583a7a3b383SJung-uk Kim 584a7a3b383SJung-uk Kim default: 585a7a3b383SJung-uk Kim break; 586f556842eSJung-uk Kim } 587f556842eSJung-uk Kim 588f556842eSJung-uk Kim External = External->Next; 589f556842eSJung-uk Kim } 590f556842eSJung-uk Kim } 591f556842eSJung-uk Kim 592f556842eSJung-uk Kim 593f556842eSJung-uk Kim /******************************************************************************* 594f556842eSJung-uk Kim * 595f556842eSJung-uk Kim * FUNCTION: AcpiDmGetExternalMethodCount 596f556842eSJung-uk Kim * 597f556842eSJung-uk Kim * PARAMETERS: None 598f556842eSJung-uk Kim * 599f556842eSJung-uk Kim * RETURN: The number of control method externals in the external list 600f556842eSJung-uk Kim * 601f556842eSJung-uk Kim * DESCRIPTION: Return the number of method externals that have been generated. 602f556842eSJung-uk Kim * If any control method externals have been found, we must 603f556842eSJung-uk Kim * re-parse the entire definition block with the new information 604f556842eSJung-uk Kim * (number of arguments for the methods.) This is limitation of 605f556842eSJung-uk Kim * AML, we don't know the number of arguments from the control 606f556842eSJung-uk Kim * method invocation itself. 607f556842eSJung-uk Kim * 608f556842eSJung-uk Kim ******************************************************************************/ 609f556842eSJung-uk Kim 610f556842eSJung-uk Kim UINT32 611f556842eSJung-uk Kim AcpiDmGetExternalMethodCount ( 612f556842eSJung-uk Kim void) 613f556842eSJung-uk Kim { 614f556842eSJung-uk Kim ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 615f556842eSJung-uk Kim UINT32 Count = 0; 616f556842eSJung-uk Kim 617f556842eSJung-uk Kim 618f556842eSJung-uk Kim while (External) 619f556842eSJung-uk Kim { 620f556842eSJung-uk Kim if (External->Type == ACPI_TYPE_METHOD) 621f556842eSJung-uk Kim { 622f556842eSJung-uk Kim Count++; 623f556842eSJung-uk Kim } 624f556842eSJung-uk Kim 625f556842eSJung-uk Kim External = External->Next; 626f556842eSJung-uk Kim } 627f556842eSJung-uk Kim 628f556842eSJung-uk Kim return (Count); 629f556842eSJung-uk Kim } 630f556842eSJung-uk Kim 631f556842eSJung-uk Kim 632f556842eSJung-uk Kim /******************************************************************************* 633f556842eSJung-uk Kim * 634f556842eSJung-uk Kim * FUNCTION: AcpiDmClearExternalList 635f556842eSJung-uk Kim * 636f556842eSJung-uk Kim * PARAMETERS: None 637f556842eSJung-uk Kim * 638f556842eSJung-uk Kim * RETURN: None 639f556842eSJung-uk Kim * 640f556842eSJung-uk Kim * DESCRIPTION: Free the entire External info list 641f556842eSJung-uk Kim * 642f556842eSJung-uk Kim ******************************************************************************/ 643f556842eSJung-uk Kim 644f556842eSJung-uk Kim void 645f556842eSJung-uk Kim AcpiDmClearExternalList ( 646f556842eSJung-uk Kim void) 647f556842eSJung-uk Kim { 648f556842eSJung-uk Kim ACPI_EXTERNAL_LIST *NextExternal; 649f556842eSJung-uk Kim 650f556842eSJung-uk Kim 651f556842eSJung-uk Kim while (AcpiGbl_ExternalList) 652f556842eSJung-uk Kim { 653f556842eSJung-uk Kim NextExternal = AcpiGbl_ExternalList->Next; 654f556842eSJung-uk Kim ACPI_FREE (AcpiGbl_ExternalList->Path); 655f556842eSJung-uk Kim ACPI_FREE (AcpiGbl_ExternalList); 656f556842eSJung-uk Kim AcpiGbl_ExternalList = NextExternal; 657f556842eSJung-uk Kim } 658f556842eSJung-uk Kim } 659f556842eSJung-uk Kim 660f556842eSJung-uk Kim 661f556842eSJung-uk Kim /******************************************************************************* 662f556842eSJung-uk Kim * 663f556842eSJung-uk Kim * FUNCTION: AcpiDmEmitExternals 664f556842eSJung-uk Kim * 665f556842eSJung-uk Kim * PARAMETERS: None 666f556842eSJung-uk Kim * 667f556842eSJung-uk Kim * RETURN: None 668f556842eSJung-uk Kim * 669f556842eSJung-uk Kim * DESCRIPTION: Emit an External() ASL statement for each of the externals in 670f556842eSJung-uk Kim * the global external info list. 671f556842eSJung-uk Kim * 672f556842eSJung-uk Kim ******************************************************************************/ 673f556842eSJung-uk Kim 674f556842eSJung-uk Kim void 675f556842eSJung-uk Kim AcpiDmEmitExternals ( 676f556842eSJung-uk Kim void) 677f556842eSJung-uk Kim { 678f556842eSJung-uk Kim ACPI_EXTERNAL_LIST *NextExternal; 679f556842eSJung-uk Kim 680f556842eSJung-uk Kim 681f556842eSJung-uk Kim if (!AcpiGbl_ExternalList) 682f556842eSJung-uk Kim { 683f556842eSJung-uk Kim return; 684f556842eSJung-uk Kim } 685f556842eSJung-uk Kim 686f556842eSJung-uk Kim /* 687f556842eSJung-uk Kim * Walk the list of externals (unresolved references) 688f556842eSJung-uk Kim * found during the AML parsing 689f556842eSJung-uk Kim */ 690f556842eSJung-uk Kim while (AcpiGbl_ExternalList) 691f556842eSJung-uk Kim { 692f556842eSJung-uk Kim AcpiOsPrintf (" External (%s%s", 693f556842eSJung-uk Kim AcpiGbl_ExternalList->Path, 694f556842eSJung-uk Kim AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); 695f556842eSJung-uk Kim 696f556842eSJung-uk Kim if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 697f556842eSJung-uk Kim { 698a88e22b7SJung-uk Kim AcpiOsPrintf (") // %u Arguments\n", 699f556842eSJung-uk Kim AcpiGbl_ExternalList->Value); 700f556842eSJung-uk Kim } 701f556842eSJung-uk Kim else 702f556842eSJung-uk Kim { 703f556842eSJung-uk Kim AcpiOsPrintf (")\n"); 704f556842eSJung-uk Kim } 705f556842eSJung-uk Kim 706f556842eSJung-uk Kim /* Free this external info block and move on to next external */ 707f556842eSJung-uk Kim 708f556842eSJung-uk Kim NextExternal = AcpiGbl_ExternalList->Next; 709f556842eSJung-uk Kim if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED) 710f556842eSJung-uk Kim { 711f556842eSJung-uk Kim ACPI_FREE (AcpiGbl_ExternalList->InternalPath); 712f556842eSJung-uk Kim } 713f556842eSJung-uk Kim 714f556842eSJung-uk Kim ACPI_FREE (AcpiGbl_ExternalList->Path); 715f556842eSJung-uk Kim ACPI_FREE (AcpiGbl_ExternalList); 716f556842eSJung-uk Kim AcpiGbl_ExternalList = NextExternal; 717f556842eSJung-uk Kim } 718f556842eSJung-uk Kim 719f556842eSJung-uk Kim AcpiOsPrintf ("\n"); 720f556842eSJung-uk Kim } 721