asllookup.c revision 118611
1118611Snjl/****************************************************************************** 2118611Snjl * 3118611Snjl * Module Name: asllookup- Namespace lookup 4118611Snjl * $Revision: 82 $ 5118611Snjl * 6118611Snjl *****************************************************************************/ 7118611Snjl 8118611Snjl/****************************************************************************** 9118611Snjl * 10118611Snjl * 1. Copyright Notice 11118611Snjl * 12118611Snjl * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. 13118611Snjl * All rights reserved. 14118611Snjl * 15118611Snjl * 2. License 16118611Snjl * 17118611Snjl * 2.1. This is your license from Intel Corp. under its intellectual property 18118611Snjl * rights. You may have additional license terms from the party that provided 19118611Snjl * you this software, covering your right to use that party's intellectual 20118611Snjl * property rights. 21118611Snjl * 22118611Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23118611Snjl * copy of the source code appearing in this file ("Covered Code") an 24118611Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25118611Snjl * base code distributed originally by Intel ("Original Intel Code") to copy, 26118611Snjl * make derivatives, distribute, use and display any portion of the Covered 27118611Snjl * Code in any form, with the right to sublicense such rights; and 28118611Snjl * 29118611Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30118611Snjl * license (with the right to sublicense), under only those claims of Intel 31118611Snjl * patents that are infringed by the Original Intel Code, to make, use, sell, 32118611Snjl * offer to sell, and import the Covered Code and derivative works thereof 33118611Snjl * solely to the minimum extent necessary to exercise the above copyright 34118611Snjl * license, and in no event shall the patent license extend to any additions 35118611Snjl * to or modifications of the Original Intel Code. No other license or right 36118611Snjl * is granted directly or by implication, estoppel or otherwise; 37118611Snjl * 38118611Snjl * The above copyright and patent license is granted only if the following 39118611Snjl * conditions are met: 40118611Snjl * 41118611Snjl * 3. Conditions 42118611Snjl * 43118611Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44118611Snjl * Redistribution of source code of any substantial portion of the Covered 45118611Snjl * Code or modification with rights to further distribute source must include 46118611Snjl * the above Copyright Notice, the above License, this list of Conditions, 47118611Snjl * and the following Disclaimer and Export Compliance provision. In addition, 48118611Snjl * Licensee must cause all Covered Code to which Licensee contributes to 49118611Snjl * contain a file documenting the changes Licensee made to create that Covered 50118611Snjl * Code and the date of any change. Licensee must include in that file the 51118611Snjl * documentation of any changes made by any predecessor Licensee. Licensee 52118611Snjl * must include a prominent statement that the modification is derived, 53118611Snjl * directly or indirectly, from Original Intel Code. 54118611Snjl * 55118611Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56118611Snjl * Redistribution of source code of any substantial portion of the Covered 57118611Snjl * Code or modification without rights to further distribute source must 58118611Snjl * include the following Disclaimer and Export Compliance provision in the 59118611Snjl * documentation and/or other materials provided with distribution. In 60118611Snjl * addition, Licensee may not authorize further sublicense of source of any 61118611Snjl * portion of the Covered Code, and must include terms to the effect that the 62118611Snjl * license from Licensee to its licensee is limited to the intellectual 63118611Snjl * property embodied in the software Licensee provides to its licensee, and 64118611Snjl * not to intellectual property embodied in modifications its licensee may 65118611Snjl * make. 66118611Snjl * 67118611Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any 68118611Snjl * substantial portion of the Covered Code or modification must reproduce the 69118611Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance 70118611Snjl * provision in the documentation and/or other materials provided with the 71118611Snjl * distribution. 72118611Snjl * 73118611Snjl * 3.4. Intel retains all right, title, and interest in and to the Original 74118611Snjl * Intel Code. 75118611Snjl * 76118611Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77118611Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or 78118611Snjl * other dealings in products derived from or relating to the Covered Code 79118611Snjl * without prior written authorization from Intel. 80118611Snjl * 81118611Snjl * 4. Disclaimer and Export Compliance 82118611Snjl * 83118611Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84118611Snjl * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85118611Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86118611Snjl * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87118611Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88118611Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89118611Snjl * PARTICULAR PURPOSE. 90118611Snjl * 91118611Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92118611Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93118611Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94118611Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95118611Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96118611Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97118611Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98118611Snjl * LIMITED REMEDY. 99118611Snjl * 100118611Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this 101118611Snjl * software or system incorporating such software without first obtaining any 102118611Snjl * required license or other approval from the U. S. Department of Commerce or 103118611Snjl * any other agency or department of the United States Government. In the 104118611Snjl * event Licensee exports any such software from the United States or 105118611Snjl * re-exports any such software from a foreign destination, Licensee shall 106118611Snjl * ensure that the distribution and export/re-export of the software is in 107118611Snjl * compliance with all laws, regulations, orders, or other restrictions of the 108118611Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109118611Snjl * any of its subsidiaries will export/re-export any technical data, process, 110118611Snjl * software, or service, directly or indirectly, to any country for which the 111118611Snjl * United States government or any agency thereof requires an export license, 112118611Snjl * other governmental approval, or letter of assurance, without first obtaining 113118611Snjl * such license, approval or letter. 114118611Snjl * 115118611Snjl *****************************************************************************/ 116118611Snjl 117118611Snjl 118118611Snjl#include "aslcompiler.h" 119118611Snjl#include "aslcompiler.y.h" 120118611Snjl 121118611Snjl#include "acparser.h" 122118611Snjl#include "amlcode.h" 123118611Snjl#include "acnamesp.h" 124118611Snjl#include "acdispat.h" 125118611Snjl 126118611Snjl 127118611Snjl#define _COMPONENT ACPI_COMPILER 128118611Snjl ACPI_MODULE_NAME ("asllookup") 129118611Snjl 130118611Snjl 131118611Snjl/******************************************************************************* 132118611Snjl * 133118611Snjl * FUNCTION: LsDoOneNamespaceObject 134118611Snjl * 135118611Snjl * PARAMETERS: ACPI_WALK_CALLBACK 136118611Snjl * 137118611Snjl * RETURN: Status 138118611Snjl * 139118611Snjl * DESCRIPTION: Dump a namespace object to the namespace output file. 140118611Snjl * Called during the walk of the namespace to dump all objects. 141118611Snjl * 142118611Snjl ******************************************************************************/ 143118611Snjl 144118611SnjlACPI_STATUS 145118611SnjlLsDoOneNamespaceObject ( 146118611Snjl ACPI_HANDLE ObjHandle, 147118611Snjl UINT32 Level, 148118611Snjl void *Context, 149118611Snjl void **ReturnValue) 150118611Snjl{ 151118611Snjl ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 152118611Snjl ACPI_PARSE_OBJECT *Op; 153118611Snjl 154118611Snjl 155118611Snjl Gbl_NumNamespaceObjects++; 156118611Snjl 157118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5d [%d] %*s %4.4s - %s", 158118611Snjl Gbl_NumNamespaceObjects, Level, (Level * 3), " ", 159118611Snjl &Node->Name, 160118611Snjl AcpiUtGetTypeName (Node->Type)); 161118611Snjl 162118611Snjl Op = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object); 163118611Snjl 164118611Snjl if (Op) 165118611Snjl { 166118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_NAME) 167118611Snjl { 168118611Snjl Op = Op->Asl.Child; 169118611Snjl } 170118611Snjl 171118611Snjl switch (Node->Type) 172118611Snjl { 173118611Snjl case ACPI_TYPE_INTEGER: 174118611Snjl 175118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 176118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 177118611Snjl { 178118611Snjl Op = Op->Asl.Next; 179118611Snjl } 180118611Snjl 181118611Snjl if (Op->Asl.Value.Integer > ACPI_UINT32_MAX) 182118611Snjl { 183118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Initial Value = 0x%X%X]", 184118611Snjl ACPI_HIDWORD (Op->Asl.Value.Integer64), (UINT32) Op->Asl.Value.Integer); 185118611Snjl } 186118611Snjl else 187118611Snjl { 188118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Initial Value = 0x%X]", 189118611Snjl (UINT32) Op->Asl.Value.Integer); 190118611Snjl } 191118611Snjl break; 192118611Snjl 193118611Snjl 194118611Snjl case ACPI_TYPE_STRING: 195118611Snjl 196118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 197118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 198118611Snjl { 199118611Snjl Op = Op->Asl.Next; 200118611Snjl } 201118611Snjl 202118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Initial Value = \"%s\"]", 203118611Snjl Op->Asl.Value.String); 204118611Snjl break; 205118611Snjl 206118611Snjl 207118611Snjl case ACPI_TYPE_LOCAL_REGION_FIELD: 208118611Snjl 209118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 210118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 211118611Snjl { 212118611Snjl Op = Op->Asl.Child; 213118611Snjl } 214118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Offset 0x%02X, Length 0x%02X]", 215118611Snjl Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer); 216118611Snjl break; 217118611Snjl 218118611Snjl 219118611Snjl default: 220118611Snjl /* Nothing to do for other types */ 221118611Snjl break; 222118611Snjl } 223118611Snjl } 224118611Snjl 225118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n"); 226118611Snjl return (AE_OK); 227118611Snjl} 228118611Snjl 229118611Snjl 230118611Snjl/******************************************************************************* 231118611Snjl * 232118611Snjl * FUNCTION: LsDisplayNamespace 233118611Snjl * 234118611Snjl * PARAMETERS: None 235118611Snjl * 236118611Snjl * RETURN: None 237118611Snjl * 238118611Snjl * DESCRIPTION: Walk the namespace an display information about each node 239118611Snjl * in the tree. Information is written to the optional 240118611Snjl * namespace output file. 241118611Snjl * 242118611Snjl ******************************************************************************/ 243118611Snjl 244118611SnjlACPI_STATUS 245118611SnjlLsDisplayNamespace ( 246118611Snjl void) 247118611Snjl{ 248118611Snjl ACPI_STATUS Status; 249118611Snjl 250118611Snjl 251118611Snjl if (!Gbl_NsOutputFlag) 252118611Snjl { 253118611Snjl return (AE_OK); 254118611Snjl } 255118611Snjl 256118611Snjl /* File header */ 257118611Snjl 258118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n"); 259118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count Depth Name - Type\n\n"); 260118611Snjl 261118611Snjl /* Walk entire namespace from the root */ 262118611Snjl 263118611Snjl Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 264118611Snjl ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, 265118611Snjl NULL, NULL); 266118611Snjl return (Status); 267118611Snjl} 268118611Snjl 269118611Snjl 270118611Snjl/******************************************************************************* 271118611Snjl * 272118611Snjl * FUNCTION: LsCompareOneNamespaceObject 273118611Snjl * 274118611Snjl * PARAMETERS: ACPI_WALK_CALLBACK 275118611Snjl * 276118611Snjl * RETURN: Status 277118611Snjl * 278118611Snjl * DESCRIPTION: Compare name of one object. 279118611Snjl * 280118611Snjl ******************************************************************************/ 281118611Snjl 282118611SnjlACPI_STATUS 283118611SnjlLsCompareOneNamespaceObject ( 284118611Snjl ACPI_HANDLE ObjHandle, 285118611Snjl UINT32 Level, 286118611Snjl void *Context, 287118611Snjl void **ReturnValue) 288118611Snjl{ 289118611Snjl ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 290118611Snjl 291118611Snjl 292118611Snjl /* Simply check the name */ 293118611Snjl 294118611Snjl if (*((UINT32 *) (Context)) == Node->Name.Integer) 295118611Snjl { 296118611Snjl /* Abort walk if we found one instance */ 297118611Snjl 298118611Snjl return (AE_CTRL_TRUE); 299118611Snjl } 300118611Snjl 301118611Snjl return (AE_OK); 302118611Snjl} 303118611Snjl 304118611Snjl 305118611Snjl/******************************************************************************* 306118611Snjl * 307118611Snjl * FUNCTION: LkObjectExists 308118611Snjl * 309118611Snjl * PARAMETERS: Name - 4 char ACPI name 310118611Snjl * 311118611Snjl * RETURN: TRUE if name exists in namespace 312118611Snjl * 313118611Snjl * DESCRIPTION: Walk the namespace to find an object 314118611Snjl * 315118611Snjl ******************************************************************************/ 316118611Snjl 317118611SnjlBOOLEAN 318118611SnjlLkObjectExists ( 319118611Snjl char *Name) 320118611Snjl{ 321118611Snjl ACPI_STATUS Status; 322118611Snjl 323118611Snjl 324118611Snjl /* Walk entire namespace from the supplied root */ 325118611Snjl 326118611Snjl Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 327118611Snjl ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, 328118611Snjl Name, NULL); 329118611Snjl if (Status == AE_CTRL_TRUE) 330118611Snjl { 331118611Snjl /* At least one instance of the name was found */ 332118611Snjl 333118611Snjl return (TRUE); 334118611Snjl } 335118611Snjl 336118611Snjl return (FALSE); 337118611Snjl} 338118611Snjl 339118611Snjl 340118611Snjl/******************************************************************************* 341118611Snjl * 342118611Snjl * FUNCTION: LkCrossReferenceNamespace 343118611Snjl * 344118611Snjl * PARAMETERS: None 345118611Snjl * 346118611Snjl * RETURN: Status 347118611Snjl * 348118611Snjl * DESCRIPTION: Perform a cross reference check of the parse tree against the 349118611Snjl * namespace. Every named referenced within the parse tree 350118611Snjl * should be get resolved with a namespace lookup. If not, the 351118611Snjl * original reference in the ASL code is invalid -- i.e., refers 352118611Snjl * to a non-existent object. 353118611Snjl * 354118611Snjl * NOTE: The ASL "External" operator causes the name to be inserted into the 355118611Snjl * namespace so that references to the external name will be resolved 356118611Snjl * correctly here. 357118611Snjl * 358118611Snjl ******************************************************************************/ 359118611Snjl 360118611SnjlACPI_STATUS 361118611SnjlLkCrossReferenceNamespace ( 362118611Snjl void) 363118611Snjl{ 364118611Snjl ACPI_WALK_STATE *WalkState; 365118611Snjl 366118611Snjl 367118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n"); 368118611Snjl 369118611Snjl /* 370118611Snjl * Create a new walk state for use when looking up names 371118611Snjl * within the namespace (Passed as context to the callbacks) 372118611Snjl */ 373118611Snjl WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 374118611Snjl if (!WalkState) 375118611Snjl { 376118611Snjl return AE_NO_MEMORY; 377118611Snjl } 378118611Snjl 379118611Snjl /* Walk the entire parse tree */ 380118611Snjl 381118611Snjl TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin, 382118611Snjl LkNamespaceLocateEnd, WalkState); 383118611Snjl return AE_OK; 384118611Snjl} 385118611Snjl 386118611Snjl 387118611Snjl/******************************************************************************* 388118611Snjl * 389118611Snjl * FUNCTION: LkCheckFieldRange 390118611Snjl * 391118611Snjl * PARAMETERS: RegionBitLength - Length of entire parent region 392118611Snjl * FieldBitOffset - Start of the field unit (within region) 393118611Snjl * FieldBitLength - Entire length of field unit 394118611Snjl * AccessBitWidth - Access width of the field unit 395118611Snjl * 396118611Snjl * RETURN: None 397118611Snjl * 398118611Snjl * DESCRIPTION: Check one field unit to make sure it fits in the parent 399118611Snjl * op region. 400118611Snjl * 401118611Snjl * Note: AccessBitWidth must be either 8,16,32, or 64 402118611Snjl * 403118611Snjl ******************************************************************************/ 404118611Snjl 405118611Snjlvoid 406118611SnjlLkCheckFieldRange ( 407118611Snjl ACPI_PARSE_OBJECT *Op, 408118611Snjl UINT32 RegionBitLength, 409118611Snjl UINT32 FieldBitOffset, 410118611Snjl UINT32 FieldBitLength, 411118611Snjl UINT32 AccessBitWidth) 412118611Snjl{ 413118611Snjl UINT32 FieldEndBitOffset; 414118611Snjl 415118611Snjl /* 416118611Snjl * Check each field unit against the region size. The entire 417118611Snjl * field unit (start offset plus length) must fit within the 418118611Snjl * region. 419118611Snjl */ 420118611Snjl FieldEndBitOffset = FieldBitOffset + FieldBitLength; 421118611Snjl 422118611Snjl if (FieldEndBitOffset > RegionBitLength) 423118611Snjl { 424118611Snjl /* Field definition itself is beyond the end-of-region */ 425118611Snjl 426118611Snjl AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL); 427118611Snjl return; 428118611Snjl } 429118611Snjl 430118611Snjl /* 431118611Snjl * Now check that the field plus AccessWidth doesn't go beyond 432118611Snjl * the end-of-region. Assumes AccessBitWidth is a power of 2 433118611Snjl */ 434118611Snjl FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth); 435118611Snjl 436118611Snjl if (FieldEndBitOffset > RegionBitLength) 437118611Snjl { 438118611Snjl /* Field definition combined with the access is beyond EOR */ 439118611Snjl 440118611Snjl AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL); 441118611Snjl } 442118611Snjl} 443118611Snjl 444118611Snjl/******************************************************************************* 445118611Snjl * 446118611Snjl * FUNCTION: LkNamespaceLocateBegin 447118611Snjl * 448118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 449118611Snjl * 450118611Snjl * RETURN: Status 451118611Snjl * 452118611Snjl * DESCRIPTION: Descending callback used during cross-reference. For named 453118611Snjl * object references, attempt to locate the name in the 454118611Snjl * namespace. 455118611Snjl * 456118611Snjl * NOTE: ASL references to named fields within resource descriptors are 457118611Snjl * resolved to integer values here. Therefore, this step is an 458118611Snjl * important part of the code generation. We don't know that the 459118611Snjl * name refers to a resource descriptor until now. 460118611Snjl * 461118611Snjl ******************************************************************************/ 462118611Snjl 463118611SnjlACPI_STATUS 464118611SnjlLkNamespaceLocateBegin ( 465118611Snjl ACPI_PARSE_OBJECT *Op, 466118611Snjl UINT32 Level, 467118611Snjl void *Context) 468118611Snjl{ 469118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 470118611Snjl ACPI_NAMESPACE_NODE *Node; 471118611Snjl ACPI_STATUS Status; 472118611Snjl ACPI_OBJECT_TYPE ObjectType; 473118611Snjl char *Path; 474118611Snjl UINT8 PassedArgs; 475118611Snjl ACPI_PARSE_OBJECT *NextOp; 476118611Snjl ACPI_PARSE_OBJECT *OwningOp; 477118611Snjl ACPI_PARSE_OBJECT *SpaceIdOp; 478118611Snjl UINT32 MinimumLength; 479118611Snjl UINT32 Temp; 480118611Snjl const ACPI_OPCODE_INFO *OpInfo; 481118611Snjl UINT32 Flags; 482118611Snjl 483118611Snjl 484118611Snjl ACPI_FUNCTION_TRACE_PTR ("LkNamespaceLocateBegin", Op); 485118611Snjl 486118611Snjl /* 487118611Snjl * If this node is the actual declaration of a name 488118611Snjl * [such as the XXXX name in "Method (XXXX)"], 489118611Snjl * we are not interested in it here. We only care about names that are 490118611Snjl * references to other objects within the namespace and the parent objects 491118611Snjl * of name declarations 492118611Snjl */ 493118611Snjl if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) 494118611Snjl { 495118611Snjl return (AE_OK); 496118611Snjl } 497118611Snjl 498118611Snjl /* We are only interested in opcodes that have an associated name */ 499118611Snjl 500118611Snjl OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 501118611Snjl 502118611Snjl if ((!(OpInfo->Flags & AML_NAMED)) && 503118611Snjl (!(OpInfo->Flags & AML_CREATE)) && 504118611Snjl (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) && 505118611Snjl (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) && 506118611Snjl (Op->Asl.ParseOpcode != PARSEOP_METHODCALL)) 507118611Snjl { 508118611Snjl return (AE_OK); 509118611Snjl } 510118611Snjl 511118611Snjl /* 512118611Snjl * We must enable the "search-to-root" for single NameSegs, but 513118611Snjl * we have to be very careful about opening up scopes 514118611Snjl */ 515118611Snjl Flags = ACPI_NS_SEARCH_PARENT; 516118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 517118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 518118611Snjl (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 519118611Snjl { 520118611Snjl /* 521118611Snjl * These are name references, do not push the scope stack 522118611Snjl * for them. 523118611Snjl */ 524118611Snjl Flags |= ACPI_NS_DONT_OPEN_SCOPE; 525118611Snjl } 526118611Snjl 527118611Snjl /* Get the NamePath from the appropriate place */ 528118611Snjl 529118611Snjl if (OpInfo->Flags & AML_NAMED) 530118611Snjl { 531118611Snjl /* For all NAMED operators, the name reference is the first child */ 532118611Snjl 533118611Snjl Path = Op->Asl.Child->Asl.Value.String; 534118611Snjl if (Op->Asl.AmlOpcode == AML_ALIAS_OP) 535118611Snjl { 536118611Snjl /* 537118611Snjl * ALIAS is the only oddball opcode, the name declaration 538118611Snjl * (alias name) is the second operand 539118611Snjl */ 540118611Snjl Path = Op->Asl.Child->Asl.Next->Asl.Value.String; 541118611Snjl } 542118611Snjl } 543118611Snjl else if (OpInfo->Flags & AML_CREATE) 544118611Snjl { 545118611Snjl /* Name must appear as the last parameter */ 546118611Snjl 547118611Snjl NextOp = Op->Asl.Child; 548118611Snjl while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)) 549118611Snjl { 550118611Snjl NextOp = NextOp->Asl.Next; 551118611Snjl } 552118611Snjl Path = NextOp->Asl.Value.String; 553118611Snjl } 554118611Snjl else 555118611Snjl { 556118611Snjl Path = Op->Asl.Value.String; 557118611Snjl } 558118611Snjl 559118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 560118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Type=%s\n", AcpiUtGetTypeName (ObjectType))); 561118611Snjl 562118611Snjl /* 563118611Snjl * Lookup the name in the namespace. Name must exist at this point, or it 564118611Snjl * is an invalid reference. 565118611Snjl * 566118611Snjl * The namespace is also used as a lookup table for references to resource 567118611Snjl * descriptors and the fields within them. 568118611Snjl */ 569118611Snjl Gbl_NsLookupCount++; 570118611Snjl 571118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 572118611Snjl ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node)); 573118611Snjl if (ACPI_FAILURE (Status)) 574118611Snjl { 575118611Snjl if (Status == AE_NOT_FOUND) 576118611Snjl { 577118611Snjl /* 578118611Snjl * We didn't find the name reference by path -- we can qualify this 579118611Snjl * a little better before we print an error message 580118611Snjl */ 581118611Snjl if (strlen (Path) == ACPI_NAME_SIZE) 582118611Snjl { 583118611Snjl /* A simple, one-segment ACPI name */ 584118611Snjl 585118611Snjl if (LkObjectExists (Path)) 586118611Snjl { 587118611Snjl /* There exists such a name, but we couldn't get to it from this scope */ 588118611Snjl 589118611Snjl AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op, Op->Asl.ExternalName); 590118611Snjl } 591118611Snjl else 592118611Snjl { 593118611Snjl /* The name doesn't exist, period */ 594118611Snjl 595118611Snjl AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName); 596118611Snjl } 597118611Snjl } 598118611Snjl else 599118611Snjl { 600118611Snjl /* Check for a fully qualified path */ 601118611Snjl 602118611Snjl if (Path[0] == AML_ROOT_PREFIX) 603118611Snjl { 604118611Snjl /* Gave full path, the object does not exist */ 605118611Snjl 606118611Snjl AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, Op->Asl.ExternalName); 607118611Snjl } 608118611Snjl else 609118611Snjl { 610118611Snjl /* We can't tell whether it doesn't exist or just can't be reached. */ 611118611Snjl 612118611Snjl AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName); 613118611Snjl } 614118611Snjl } 615118611Snjl 616118611Snjl Status = AE_OK; 617118611Snjl } 618118611Snjl return (Status); 619118611Snjl } 620118611Snjl 621118611Snjl /* Attempt to optimize the NamePath */ 622118611Snjl 623118611Snjl OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node); 624118611Snjl 625118611Snjl /* 626118611Snjl * Dereference an alias. (A name reference that is an alias.) 627118611Snjl * Aliases are not nested; The alias always points to the final object 628118611Snjl */ 629118611Snjl if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) && (Node->Type == ACPI_TYPE_LOCAL_ALIAS)) 630118611Snjl { 631118611Snjl /* This node points back to the original PARSEOP_ALIAS */ 632118611Snjl 633118611Snjl NextOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object); 634118611Snjl 635118611Snjl /* The first child is the alias target op */ 636118611Snjl 637118611Snjl NextOp = NextOp->Asl.Child; 638118611Snjl 639118611Snjl /* Who in turn points back to original target alias node */ 640118611Snjl 641118611Snjl if (NextOp->Asl.Node) 642118611Snjl { 643118611Snjl Node = NextOp->Asl.Node; 644118611Snjl } 645118611Snjl else 646118611Snjl { 647118611Snjl AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "Missing alias link"); 648118611Snjl } 649118611Snjl } 650118611Snjl 651118611Snjl /* 1) Check for a reference to a resource descriptor */ 652118611Snjl 653118611Snjl else if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 654118611Snjl (Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 655118611Snjl { 656118611Snjl /* 657118611Snjl * This was a reference to a field within a resource descriptor. Extract 658118611Snjl * the associated field offset (either a bit or byte offset depending on 659118611Snjl * the field type) and change the named reference into an integer for 660118611Snjl * AML code generation 661118611Snjl */ 662118611Snjl Temp = (UINT32) Node->OwnerId; 663118611Snjl if (Node->Flags & ANOBJ_IS_BIT_OFFSET) 664118611Snjl { 665118611Snjl Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET; 666118611Snjl } 667118611Snjl 668118611Snjl /* Perform BitOffset <--> ByteOffset conversion if necessary */ 669118611Snjl 670118611Snjl switch (Op->Asl.Parent->Asl.AmlOpcode) 671118611Snjl { 672118611Snjl case AML_CREATE_FIELD_OP: 673118611Snjl 674118611Snjl /* We allow a Byte offset to Bit Offset conversion for this op */ 675118611Snjl 676118611Snjl if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)) 677118611Snjl { 678118611Snjl /* Simply multiply byte offset times 8 to get bit offset */ 679118611Snjl 680118611Snjl Temp = ACPI_MUL_8 (Temp); 681118611Snjl } 682118611Snjl break; 683118611Snjl 684118611Snjl 685118611Snjl case AML_CREATE_BIT_FIELD_OP: 686118611Snjl 687118611Snjl /* This op requires a Bit Offset */ 688118611Snjl 689118611Snjl if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)) 690118611Snjl { 691118611Snjl AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL); 692118611Snjl } 693118611Snjl break; 694118611Snjl 695118611Snjl 696118611Snjl case AML_CREATE_BYTE_FIELD_OP: 697118611Snjl case AML_CREATE_WORD_FIELD_OP: 698118611Snjl case AML_CREATE_DWORD_FIELD_OP: 699118611Snjl case AML_CREATE_QWORD_FIELD_OP: 700118611Snjl case AML_INDEX_OP: 701118611Snjl 702118611Snjl /* These Ops require Byte offsets */ 703118611Snjl 704118611Snjl if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET) 705118611Snjl { 706118611Snjl AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL); 707118611Snjl } 708118611Snjl break; 709118611Snjl 710118611Snjl 711118611Snjl default: 712118611Snjl /* Nothing to do for other opcodes */ 713118611Snjl break; 714118611Snjl } 715118611Snjl 716118611Snjl /* Now convert this node to an integer whose value is the field offset */ 717118611Snjl 718118611Snjl Op->Asl.ParseOpcode = PARSEOP_INTEGER; 719118611Snjl Op->Asl.Value.Integer = (UINT64) Temp; 720118611Snjl Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 721118611Snjl 722118611Snjl OpcGenerateAmlOpcode (Op); 723118611Snjl Op->Asl.AmlLength = OpcSetOptimalIntegerSize (Op); 724118611Snjl } 725118611Snjl 726118611Snjl /* 2) Check for a method invocation */ 727118611Snjl 728118611Snjl else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) && 729118611Snjl (Node->Type == ACPI_TYPE_METHOD) && 730118611Snjl (Op->Asl.Parent) && 731118611Snjl (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) || 732118611Snjl 733118611Snjl (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 734118611Snjl { 735118611Snjl 736118611Snjl /* 737118611Snjl * There are two types of method invocation: 738118611Snjl * 1) Invocation with arguments -- the parser recognizes this as a METHODCALL 739118611Snjl * 2) Invocation with no arguments --the parser cannot determine that this is a method 740118611Snjl * invocation, therefore we have to figure it out here. 741118611Snjl */ 742118611Snjl if (Node->Type != ACPI_TYPE_METHOD) 743118611Snjl { 744118611Snjl sprintf (MsgBuffer, "%s is a %s", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 745118611Snjl 746118611Snjl AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer); 747118611Snjl return (AE_OK); 748118611Snjl } 749118611Snjl 750118611Snjl /* Save the method node in the caller's op */ 751118611Snjl 752118611Snjl Op->Asl.Node = Node; 753118611Snjl if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF) 754118611Snjl { 755118611Snjl return (AE_OK); 756118611Snjl } 757118611Snjl 758118611Snjl /* 759118611Snjl * This is a method invocation, with or without arguments. 760118611Snjl * Count the number of arguments, each appears as a child 761118611Snjl * under the parent node 762118611Snjl */ 763118611Snjl Op->Asl.ParseOpcode = PARSEOP_METHODCALL; 764118611Snjl UtSetParseOpName (Op); 765118611Snjl 766118611Snjl PassedArgs = 0; 767118611Snjl NextOp = Op->Asl.Child; 768118611Snjl 769118611Snjl while (NextOp) 770118611Snjl { 771118611Snjl PassedArgs++; 772118611Snjl NextOp = NextOp->Asl.Next; 773118611Snjl } 774118611Snjl 775118611Snjl if (Node->OwnerId != ASL_EXTERNAL_METHOD) 776118611Snjl { 777118611Snjl /* 778118611Snjl * Check the parsed arguments with the number expected by the 779118611Snjl * method declaration itself 780118611Snjl */ 781118611Snjl if (PassedArgs != Node->OwnerId) 782118611Snjl { 783118611Snjl sprintf (MsgBuffer, "%s requires %d", Op->Asl.ExternalName, 784118611Snjl Node->OwnerId); 785118611Snjl 786118611Snjl if (PassedArgs < Node->OwnerId) 787118611Snjl { 788118611Snjl AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer); 789118611Snjl } 790118611Snjl else 791118611Snjl { 792118611Snjl AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer); 793118611Snjl } 794118611Snjl } 795118611Snjl } 796118611Snjl } 797118611Snjl 798118611Snjl /* 799118611Snjl * 3) Check for an ASL Field definition 800118611Snjl */ 801118611Snjl else if ((Op->Asl.Parent) && 802118611Snjl ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) || 803118611Snjl (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD))) 804118611Snjl { 805118611Snjl /* 806118611Snjl * Offset checking for fields. If the parent operation region has a 807118611Snjl * constant length (known at compile time), we can check fields 808118611Snjl * defined in that region against the region length. This will catch 809118611Snjl * fields and field units that cannot possibly fit within the region. 810118611Snjl * 811118611Snjl * Note: Index fields do not directly reference an operation region, 812118611Snjl * thus they are not included in this check. 813118611Snjl */ 814118611Snjl if (Op == Op->Asl.Parent->Asl.Child) 815118611Snjl { 816118611Snjl /* 817118611Snjl * This is the first child of the field node, which is 818118611Snjl * the name of the region. Get the parse node for the 819118611Snjl * region -- which contains the length of the region. 820118611Snjl */ 821118611Snjl OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object); 822118611Snjl Op->Asl.Parent->Asl.ExtraValue = ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer); 823118611Snjl 824118611Snjl /* Examine the field access width */ 825118611Snjl 826118611Snjl switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer) 827118611Snjl { 828118611Snjl case AML_FIELD_ACCESS_ANY: 829118611Snjl case AML_FIELD_ACCESS_BYTE: 830118611Snjl case AML_FIELD_ACCESS_BUFFER: 831118611Snjl default: 832118611Snjl MinimumLength = 1; 833118611Snjl break; 834118611Snjl 835118611Snjl case AML_FIELD_ACCESS_WORD: 836118611Snjl MinimumLength = 2; 837118611Snjl break; 838118611Snjl 839118611Snjl case AML_FIELD_ACCESS_DWORD: 840118611Snjl MinimumLength = 4; 841118611Snjl break; 842118611Snjl 843118611Snjl case AML_FIELD_ACCESS_QWORD: 844118611Snjl MinimumLength = 8; 845118611Snjl break; 846118611Snjl } 847118611Snjl 848118611Snjl /* 849118611Snjl * Is the region at least as big as the access width? 850118611Snjl * Note: DataTableRegions have 0 length 851118611Snjl */ 852118611Snjl if (((UINT32) OwningOp->Asl.Value.Integer) && 853118611Snjl ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength)) 854118611Snjl { 855118611Snjl AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL); 856118611Snjl } 857118611Snjl 858118611Snjl /* 859118611Snjl * Check EC/CMOS/SMBUS fields to make sure that the correct 860118611Snjl * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS) 861118611Snjl */ 862118611Snjl SpaceIdOp = OwningOp->Asl.Child->Asl.Next; 863118611Snjl switch ((UINT32) SpaceIdOp->Asl.Value.Integer) 864118611Snjl { 865118611Snjl case REGION_EC: 866118611Snjl case REGION_CMOS: 867118611Snjl 868118611Snjl if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE) 869118611Snjl { 870118611Snjl AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL); 871118611Snjl } 872118611Snjl break; 873118611Snjl 874118611Snjl case REGION_SMBUS: 875118611Snjl 876118611Snjl if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER) 877118611Snjl { 878118611Snjl AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL); 879118611Snjl } 880118611Snjl break; 881118611Snjl 882118611Snjl default: 883118611Snjl 884118611Snjl /* Nothing to do for other address spaces */ 885118611Snjl break; 886118611Snjl } 887118611Snjl } 888118611Snjl else 889118611Snjl { 890118611Snjl /* 891118611Snjl * This is one element of the field list. Check to make sure 892118611Snjl * that it does not go beyond the end of the parent operation region. 893118611Snjl * 894118611Snjl * In the code below: 895118611Snjl * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits) 896118611Snjl * Op->Asl.ExtraValue - Field start offset (bits) 897118611Snjl * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits) 898118611Snjl * Op->Asl.Child->Asl.ExtraValue - Field access width (bits) 899118611Snjl */ 900118611Snjl if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child) 901118611Snjl { 902118611Snjl LkCheckFieldRange (Op, 903118611Snjl Op->Asl.Parent->Asl.ExtraValue, 904118611Snjl Op->Asl.ExtraValue, 905118611Snjl (UINT32) Op->Asl.Child->Asl.Value.Integer, 906118611Snjl Op->Asl.Child->Asl.ExtraValue); 907118611Snjl } 908118611Snjl } 909118611Snjl } 910118611Snjl 911118611Snjl Op->Asl.Node = Node; 912118611Snjl return (Status); 913118611Snjl} 914118611Snjl 915118611Snjl 916118611Snjl/******************************************************************************* 917118611Snjl * 918118611Snjl * FUNCTION: LkNamespaceLocateEnd 919118611Snjl * 920118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 921118611Snjl * 922118611Snjl * RETURN: Status 923118611Snjl * 924118611Snjl * DESCRIPTION: Ascending callback used during cross reference. We only 925118611Snjl * need to worry about scope management here. 926118611Snjl * 927118611Snjl ******************************************************************************/ 928118611Snjl 929118611SnjlACPI_STATUS 930118611SnjlLkNamespaceLocateEnd ( 931118611Snjl ACPI_PARSE_OBJECT *Op, 932118611Snjl UINT32 Level, 933118611Snjl void *Context) 934118611Snjl{ 935118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 936118611Snjl const ACPI_OPCODE_INFO *OpInfo; 937118611Snjl 938118611Snjl 939118611Snjl ACPI_FUNCTION_TRACE ("LkNamespaceLocateEnd"); 940118611Snjl 941118611Snjl 942118611Snjl /* We are only interested in opcodes that have an associated name */ 943118611Snjl 944118611Snjl OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 945118611Snjl if (!(OpInfo->Flags & AML_NAMED)) 946118611Snjl { 947118611Snjl return (AE_OK); 948118611Snjl } 949118611Snjl 950118611Snjl /* Not interested in name references, we did not open a scope for them */ 951118611Snjl 952118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 953118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 954118611Snjl (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 955118611Snjl { 956118611Snjl return (AE_OK); 957118611Snjl } 958118611Snjl 959118611Snjl /* Pop the scope stack if necessary */ 960118611Snjl 961118611Snjl if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode))) 962118611Snjl { 963118611Snjl 964118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 965118611Snjl "%s: Popping scope for Op %p\n", 966118611Snjl AcpiUtGetTypeName (OpInfo->ObjectType), Op)); 967118611Snjl 968118611Snjl AcpiDsScopeStackPop (WalkState); 969118611Snjl } 970118611Snjl 971118611Snjl return (AE_OK); 972118611Snjl} 973118611Snjl 974118611Snjl 975