1118611Snjl/****************************************************************************** 2118611Snjl * 3118611Snjl * Module Name: asllookup- Namespace lookup 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7217365Sjkim/* 8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp. 9118611Snjl * All rights reserved. 10118611Snjl * 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. 25118611Snjl * 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. 29118611Snjl * 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 */ 43118611Snjl 44118611Snjl 45151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 46118611Snjl#include "aslcompiler.y.h" 47118611Snjl 48193529Sjkim#include <contrib/dev/acpica/include/acparser.h> 49193529Sjkim#include <contrib/dev/acpica/include/amlcode.h> 50193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 51193529Sjkim#include <contrib/dev/acpica/include/acdispat.h> 52118611Snjl 53118611Snjl 54118611Snjl#define _COMPONENT ACPI_COMPILER 55118611Snjl ACPI_MODULE_NAME ("asllookup") 56118611Snjl 57151937Sjkim/* Local prototypes */ 58118611Snjl 59151937Sjkimstatic ACPI_STATUS 60151937SjkimLsCompareOneNamespaceObject ( 61151937Sjkim ACPI_HANDLE ObjHandle, 62151937Sjkim UINT32 Level, 63151937Sjkim void *Context, 64151937Sjkim void **ReturnValue); 65151937Sjkim 66151937Sjkimstatic ACPI_STATUS 67151937SjkimLsDoOneNamespaceObject ( 68151937Sjkim ACPI_HANDLE ObjHandle, 69151937Sjkim UINT32 Level, 70151937Sjkim void *Context, 71151937Sjkim void **ReturnValue); 72151937Sjkim 73151937Sjkimstatic BOOLEAN 74151937SjkimLkObjectExists ( 75151937Sjkim char *Name); 76151937Sjkim 77151937Sjkimstatic void 78151937SjkimLkCheckFieldRange ( 79151937Sjkim ACPI_PARSE_OBJECT *Op, 80151937Sjkim UINT32 RegionBitLength, 81151937Sjkim UINT32 FieldBitOffset, 82151937Sjkim UINT32 FieldBitLength, 83151937Sjkim UINT32 AccessBitWidth); 84151937Sjkim 85151937Sjkimstatic ACPI_STATUS 86151937SjkimLkNamespaceLocateBegin ( 87151937Sjkim ACPI_PARSE_OBJECT *Op, 88151937Sjkim UINT32 Level, 89151937Sjkim void *Context); 90151937Sjkim 91151937Sjkimstatic ACPI_STATUS 92151937SjkimLkNamespaceLocateEnd ( 93151937Sjkim ACPI_PARSE_OBJECT *Op, 94151937Sjkim UINT32 Level, 95151937Sjkim void *Context); 96151937Sjkim 97167802Sjkimstatic ACPI_STATUS 98167802SjkimLkIsObjectUsed ( 99167802Sjkim ACPI_HANDLE ObjHandle, 100167802Sjkim UINT32 Level, 101167802Sjkim void *Context, 102167802Sjkim void **ReturnValue); 103151937Sjkim 104193529Sjkimstatic ACPI_STATUS 105193529SjkimLsDoOnePathname ( 106193529Sjkim ACPI_HANDLE ObjHandle, 107193529Sjkim UINT32 Level, 108193529Sjkim void *Context, 109193529Sjkim void **ReturnValue); 110167802Sjkim 111212761Sjkimstatic ACPI_PARSE_OBJECT * 112193529SjkimLkGetNameOp ( 113193529Sjkim ACPI_PARSE_OBJECT *Op); 114193529Sjkim 115193529Sjkim 116118611Snjl/******************************************************************************* 117118611Snjl * 118118611Snjl * FUNCTION: LsDoOneNamespaceObject 119118611Snjl * 120118611Snjl * PARAMETERS: ACPI_WALK_CALLBACK 121118611Snjl * 122118611Snjl * RETURN: Status 123118611Snjl * 124118611Snjl * DESCRIPTION: Dump a namespace object to the namespace output file. 125118611Snjl * Called during the walk of the namespace to dump all objects. 126118611Snjl * 127118611Snjl ******************************************************************************/ 128118611Snjl 129151937Sjkimstatic ACPI_STATUS 130118611SnjlLsDoOneNamespaceObject ( 131118611Snjl ACPI_HANDLE ObjHandle, 132118611Snjl UINT32 Level, 133118611Snjl void *Context, 134118611Snjl void **ReturnValue) 135118611Snjl{ 136118611Snjl ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 137151937Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 138118611Snjl ACPI_PARSE_OBJECT *Op; 139118611Snjl 140118611Snjl 141118611Snjl Gbl_NumNamespaceObjects++; 142118611Snjl 143209746Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u [%u] %*s %4.4s - %s", 144167802Sjkim Gbl_NumNamespaceObjects, Level, (Level * 3), " ", 145167802Sjkim &Node->Name, 146167802Sjkim AcpiUtGetTypeName (Node->Type)); 147118611Snjl 148151937Sjkim Op = Node->Op; 149151937Sjkim ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object); 150118611Snjl 151151937Sjkim if (!Op) 152118611Snjl { 153151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n"); 154151937Sjkim return (AE_OK); 155151937Sjkim } 156151937Sjkim 157151937Sjkim 158151937Sjkim if ((ObjDesc) && 159167802Sjkim (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND)) 160151937Sjkim { 161151937Sjkim switch (Node->Type) 162118611Snjl { 163151937Sjkim case ACPI_TYPE_INTEGER: 164151937Sjkim 165151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 166151937Sjkim " [Initial Value 0x%8.8X%8.8X]", 167151937Sjkim ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 168151937Sjkim break; 169151937Sjkim 170151937Sjkim 171151937Sjkim case ACPI_TYPE_STRING: 172151937Sjkim 173151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 174151937Sjkim " [Initial Value \"%s\"]", 175151937Sjkim ObjDesc->String.Pointer); 176151937Sjkim break; 177151937Sjkim 178151937Sjkim default: 179151937Sjkim /* Nothing to do for other types */ 180151937Sjkim break; 181118611Snjl } 182118611Snjl 183151937Sjkim } 184151937Sjkim else 185151937Sjkim { 186118611Snjl switch (Node->Type) 187118611Snjl { 188118611Snjl case ACPI_TYPE_INTEGER: 189118611Snjl 190151937Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 191151937Sjkim { 192151937Sjkim Op = Op->Asl.Child; 193151937Sjkim } 194118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 195118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 196118611Snjl { 197118611Snjl Op = Op->Asl.Next; 198118611Snjl } 199151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 200151937Sjkim " [Initial Value 0x%8.8X%8.8X]", 201151937Sjkim ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer)); 202151937Sjkim break; 203118611Snjl 204151937Sjkim 205151937Sjkim case ACPI_TYPE_STRING: 206151937Sjkim 207151937Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 208118611Snjl { 209151937Sjkim Op = Op->Asl.Child; 210118611Snjl } 211151937Sjkim if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 212151937Sjkim (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 213118611Snjl { 214151937Sjkim Op = Op->Asl.Next; 215118611Snjl } 216151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 217151937Sjkim " [Initial Value \"%s\"]", 218151937Sjkim Op->Asl.Value.String); 219118611Snjl break; 220118611Snjl 221118611Snjl 222151937Sjkim case ACPI_TYPE_LOCAL_REGION_FIELD: 223118611Snjl 224118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 225118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 226118611Snjl { 227151937Sjkim Op = Op->Asl.Child; 228118611Snjl } 229151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 230151937Sjkim " [Offset 0x%04X Length 0x%04X bits]", 231151937Sjkim Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer); 232151937Sjkim break; 233118611Snjl 234151937Sjkim 235151937Sjkim case ACPI_TYPE_BUFFER_FIELD: 236151937Sjkim 237151937Sjkim switch (Op->Asl.ParseOpcode) 238151937Sjkim { 239151937Sjkim case PARSEOP_CREATEBYTEFIELD: 240151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BYTE ( 8 bit)]"); 241151937Sjkim break; 242151937Sjkim 243151937Sjkim case PARSEOP_CREATEDWORDFIELD: 244151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [DWORD (32 bit)]"); 245151937Sjkim break; 246151937Sjkim 247151937Sjkim case PARSEOP_CREATEQWORDFIELD: 248151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [QWORD (64 bit)]"); 249151937Sjkim break; 250151937Sjkim 251151937Sjkim case PARSEOP_CREATEWORDFIELD: 252151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [WORD (16 bit)]"); 253151937Sjkim break; 254151937Sjkim 255151937Sjkim case PARSEOP_CREATEBITFIELD: 256151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BIT ( 1 bit)]"); 257151937Sjkim break; 258151937Sjkim 259151937Sjkim case PARSEOP_CREATEFIELD: 260151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Arbitrary Bit Field]"); 261151937Sjkim break; 262151937Sjkim 263151937Sjkim default: 264151937Sjkim break; 265151937Sjkim 266151937Sjkim } 267118611Snjl break; 268118611Snjl 269118611Snjl 270151937Sjkim case ACPI_TYPE_PACKAGE: 271118611Snjl 272151937Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 273151937Sjkim { 274151937Sjkim Op = Op->Asl.Child; 275151937Sjkim } 276118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 277118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 278118611Snjl { 279151937Sjkim Op = Op->Asl.Next; 280151937Sjkim } 281151937Sjkim Op = Op->Asl.Child; 282151937Sjkim 283151937Sjkim if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) || 284151937Sjkim (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA)) 285151937Sjkim { 286151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 287151937Sjkim " [Initial Length 0x%.2X elements]", 288151937Sjkim Op->Asl.Value.Integer); 289151937Sjkim } 290151937Sjkim break; 291151937Sjkim 292151937Sjkim 293151937Sjkim case ACPI_TYPE_BUFFER: 294151937Sjkim 295151937Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 296151937Sjkim { 297118611Snjl Op = Op->Asl.Child; 298118611Snjl } 299151937Sjkim if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 300151937Sjkim (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 301151937Sjkim { 302151937Sjkim Op = Op->Asl.Next; 303151937Sjkim } 304151937Sjkim Op = Op->Asl.Child; 305151937Sjkim 306167802Sjkim if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER)) 307151937Sjkim { 308151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 309151937Sjkim " [Initial Length 0x%.2X bytes]", 310151937Sjkim Op->Asl.Value.Integer); 311151937Sjkim } 312118611Snjl break; 313118611Snjl 314118611Snjl 315151937Sjkim case ACPI_TYPE_METHOD: 316151937Sjkim 317151937Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 318151937Sjkim " [Code Length 0x%.4X bytes]", 319151937Sjkim Op->Asl.AmlSubtreeLength); 320151937Sjkim break; 321151937Sjkim 322151937Sjkim 323167802Sjkim case ACPI_TYPE_LOCAL_RESOURCE: 324167802Sjkim 325167802Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 326167802Sjkim " [Desc Offset 0x%.4X Bytes]", Node->Value); 327167802Sjkim break; 328167802Sjkim 329167802Sjkim 330167802Sjkim case ACPI_TYPE_LOCAL_RESOURCE_FIELD: 331167802Sjkim 332167802Sjkim if (Node->Flags & 0x80) 333167802Sjkim { 334167802Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 335167802Sjkim " [Field Offset 0x%.4X Bits 0x%.4X Bytes]", 336167802Sjkim Node->Value, Node->Value / 8); 337167802Sjkim } 338167802Sjkim else 339167802Sjkim { 340167802Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, 341167802Sjkim " [Field Offset 0x%.4X Bytes]", Node->Value); 342167802Sjkim } 343167802Sjkim break; 344167802Sjkim 345167802Sjkim 346118611Snjl default: 347118611Snjl /* Nothing to do for other types */ 348118611Snjl break; 349118611Snjl } 350118611Snjl } 351118611Snjl 352118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n"); 353118611Snjl return (AE_OK); 354118611Snjl} 355118611Snjl 356118611Snjl 357193529Sjkim/******************************************************************************* 358193529Sjkim * 359193529Sjkim * FUNCTION: LsSetupNsList 360193529Sjkim * 361193529Sjkim * PARAMETERS: Handle - local file handle 362193529Sjkim * 363193529Sjkim * RETURN: None 364193529Sjkim * 365193529Sjkim * DESCRIPTION: Set the namespace output file to the input handle 366193529Sjkim * 367193529Sjkim ******************************************************************************/ 368193529Sjkim 369167802Sjkimvoid 370193529SjkimLsSetupNsList ( 371193529Sjkim void *Handle) 372167802Sjkim{ 373167802Sjkim 374167802Sjkim Gbl_NsOutputFlag = TRUE; 375167802Sjkim Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle; 376167802Sjkim} 377167802Sjkim 378167802Sjkim 379118611Snjl/******************************************************************************* 380118611Snjl * 381193529Sjkim * FUNCTION: LsDoOnePathname 382193529Sjkim * 383193529Sjkim * PARAMETERS: ACPI_WALK_CALLBACK 384193529Sjkim * 385193529Sjkim * RETURN: Status 386193529Sjkim * 387193529Sjkim * DESCRIPTION: Print the full pathname for a namespace node. 388193529Sjkim * 389193529Sjkim ******************************************************************************/ 390193529Sjkim 391193529Sjkimstatic ACPI_STATUS 392193529SjkimLsDoOnePathname ( 393193529Sjkim ACPI_HANDLE ObjHandle, 394193529Sjkim UINT32 Level, 395193529Sjkim void *Context, 396193529Sjkim void **ReturnValue) 397193529Sjkim{ 398193529Sjkim ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 399193529Sjkim ACPI_STATUS Status; 400193529Sjkim ACPI_BUFFER TargetPath; 401193529Sjkim 402193529Sjkim 403193529Sjkim TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 404193529Sjkim Status = AcpiNsHandleToPathname (Node, &TargetPath); 405193529Sjkim if (ACPI_FAILURE (Status)) 406193529Sjkim { 407193529Sjkim return (Status); 408193529Sjkim } 409193529Sjkim 410193529Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer); 411193529Sjkim ACPI_FREE (TargetPath.Pointer); 412193529Sjkim 413193529Sjkim return (AE_OK); 414193529Sjkim} 415193529Sjkim 416193529Sjkim 417193529Sjkim/******************************************************************************* 418193529Sjkim * 419118611Snjl * FUNCTION: LsDisplayNamespace 420118611Snjl * 421118611Snjl * PARAMETERS: None 422118611Snjl * 423151937Sjkim * RETURN: Status 424118611Snjl * 425118611Snjl * DESCRIPTION: Walk the namespace an display information about each node 426118611Snjl * in the tree. Information is written to the optional 427118611Snjl * namespace output file. 428118611Snjl * 429118611Snjl ******************************************************************************/ 430118611Snjl 431118611SnjlACPI_STATUS 432118611SnjlLsDisplayNamespace ( 433118611Snjl void) 434118611Snjl{ 435118611Snjl ACPI_STATUS Status; 436118611Snjl 437118611Snjl 438118611Snjl if (!Gbl_NsOutputFlag) 439118611Snjl { 440118611Snjl return (AE_OK); 441118611Snjl } 442118611Snjl 443167802Sjkim Gbl_NumNamespaceObjects = 0; 444167802Sjkim 445118611Snjl /* File header */ 446118611Snjl 447118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n"); 448118611Snjl FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count Depth Name - Type\n\n"); 449118611Snjl 450118611Snjl /* Walk entire namespace from the root */ 451118611Snjl 452118611Snjl Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 453199337Sjkim ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL, 454151937Sjkim NULL, NULL); 455193529Sjkim 456193529Sjkim /* Print the full pathname for each namespace node */ 457193529Sjkim 458193529Sjkim FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n"); 459193529Sjkim 460193529Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 461199337Sjkim ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL, 462193529Sjkim NULL, NULL); 463193529Sjkim 464118611Snjl return (Status); 465118611Snjl} 466118611Snjl 467118611Snjl 468118611Snjl/******************************************************************************* 469118611Snjl * 470118611Snjl * FUNCTION: LsCompareOneNamespaceObject 471118611Snjl * 472118611Snjl * PARAMETERS: ACPI_WALK_CALLBACK 473118611Snjl * 474118611Snjl * RETURN: Status 475118611Snjl * 476118611Snjl * DESCRIPTION: Compare name of one object. 477118611Snjl * 478118611Snjl ******************************************************************************/ 479118611Snjl 480151937Sjkimstatic ACPI_STATUS 481118611SnjlLsCompareOneNamespaceObject ( 482118611Snjl ACPI_HANDLE ObjHandle, 483118611Snjl UINT32 Level, 484118611Snjl void *Context, 485118611Snjl void **ReturnValue) 486118611Snjl{ 487118611Snjl ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 488118611Snjl 489118611Snjl 490118611Snjl /* Simply check the name */ 491118611Snjl 492118611Snjl if (*((UINT32 *) (Context)) == Node->Name.Integer) 493118611Snjl { 494118611Snjl /* Abort walk if we found one instance */ 495118611Snjl 496118611Snjl return (AE_CTRL_TRUE); 497118611Snjl } 498118611Snjl 499118611Snjl return (AE_OK); 500118611Snjl} 501118611Snjl 502118611Snjl 503118611Snjl/******************************************************************************* 504118611Snjl * 505118611Snjl * FUNCTION: LkObjectExists 506118611Snjl * 507118611Snjl * PARAMETERS: Name - 4 char ACPI name 508118611Snjl * 509118611Snjl * RETURN: TRUE if name exists in namespace 510118611Snjl * 511118611Snjl * DESCRIPTION: Walk the namespace to find an object 512118611Snjl * 513118611Snjl ******************************************************************************/ 514118611Snjl 515151937Sjkimstatic BOOLEAN 516118611SnjlLkObjectExists ( 517118611Snjl char *Name) 518118611Snjl{ 519118611Snjl ACPI_STATUS Status; 520118611Snjl 521118611Snjl 522118611Snjl /* Walk entire namespace from the supplied root */ 523118611Snjl 524118611Snjl Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 525199337Sjkim ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL, 526151937Sjkim Name, NULL); 527118611Snjl if (Status == AE_CTRL_TRUE) 528118611Snjl { 529118611Snjl /* At least one instance of the name was found */ 530118611Snjl 531118611Snjl return (TRUE); 532118611Snjl } 533118611Snjl 534118611Snjl return (FALSE); 535118611Snjl} 536118611Snjl 537118611Snjl 538118611Snjl/******************************************************************************* 539118611Snjl * 540167802Sjkim * FUNCTION: LkGetNameOp 541167802Sjkim * 542167802Sjkim * PARAMETERS: Op - Current Op 543167802Sjkim * 544167802Sjkim * RETURN: NameOp associated with the input op 545167802Sjkim * 546167802Sjkim * DESCRIPTION: Find the name declaration op associated with the operator 547167802Sjkim * 548167802Sjkim ******************************************************************************/ 549167802Sjkim 550212761Sjkimstatic ACPI_PARSE_OBJECT * 551167802SjkimLkGetNameOp ( 552167802Sjkim ACPI_PARSE_OBJECT *Op) 553167802Sjkim{ 554167802Sjkim const ACPI_OPCODE_INFO *OpInfo; 555167802Sjkim ACPI_PARSE_OBJECT *NameOp = Op; 556167802Sjkim 557167802Sjkim 558167802Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 559167802Sjkim 560167802Sjkim 561167802Sjkim /* Get the NamePath from the appropriate place */ 562167802Sjkim 563167802Sjkim if (OpInfo->Flags & AML_NAMED) 564167802Sjkim { 565167802Sjkim /* For nearly all NAMED operators, the name reference is the first child */ 566167802Sjkim 567167802Sjkim NameOp = Op->Asl.Child; 568167802Sjkim if (Op->Asl.AmlOpcode == AML_ALIAS_OP) 569167802Sjkim { 570167802Sjkim /* 571167802Sjkim * ALIAS is the only oddball opcode, the name declaration 572167802Sjkim * (alias name) is the second operand 573167802Sjkim */ 574167802Sjkim NameOp = Op->Asl.Child->Asl.Next; 575167802Sjkim } 576167802Sjkim } 577167802Sjkim else if (OpInfo->Flags & AML_CREATE) 578167802Sjkim { 579167802Sjkim /* Name must appear as the last parameter */ 580167802Sjkim 581167802Sjkim NameOp = Op->Asl.Child; 582167802Sjkim while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)) 583167802Sjkim { 584167802Sjkim NameOp = NameOp->Asl.Next; 585167802Sjkim } 586167802Sjkim } 587167802Sjkim 588167802Sjkim return (NameOp); 589167802Sjkim} 590167802Sjkim 591167802Sjkim 592167802Sjkim/******************************************************************************* 593167802Sjkim * 594167802Sjkim * FUNCTION: LkIsObjectUsed 595167802Sjkim * 596167802Sjkim * PARAMETERS: ACPI_WALK_CALLBACK 597167802Sjkim * 598167802Sjkim * RETURN: Status 599167802Sjkim * 600167802Sjkim * DESCRIPTION: Check for an unreferenced namespace object and emit a warning. 601167802Sjkim * We have to be careful, because some types and names are 602167802Sjkim * typically or always unreferenced, we don't want to issue 603167802Sjkim * excessive warnings. 604167802Sjkim * 605167802Sjkim ******************************************************************************/ 606167802Sjkim 607167802Sjkimstatic ACPI_STATUS 608167802SjkimLkIsObjectUsed ( 609167802Sjkim ACPI_HANDLE ObjHandle, 610167802Sjkim UINT32 Level, 611167802Sjkim void *Context, 612167802Sjkim void **ReturnValue) 613167802Sjkim{ 614167802Sjkim ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 615167802Sjkim 616167802Sjkim 617167802Sjkim /* Referenced flag is set during the namespace xref */ 618167802Sjkim 619167802Sjkim if (Node->Flags & ANOBJ_IS_REFERENCED) 620167802Sjkim { 621167802Sjkim return (AE_OK); 622167802Sjkim } 623167802Sjkim 624167802Sjkim /* 625167802Sjkim * Ignore names that start with an underscore, 626167802Sjkim * these are the reserved ACPI names and are typically not referenced, 627167802Sjkim * they are called by the host OS. 628167802Sjkim */ 629167802Sjkim if (Node->Name.Ascii[0] == '_') 630167802Sjkim { 631167802Sjkim return (AE_OK); 632167802Sjkim } 633167802Sjkim 634167802Sjkim /* There are some types that are typically not referenced, ignore them */ 635167802Sjkim 636167802Sjkim switch (Node->Type) 637167802Sjkim { 638167802Sjkim case ACPI_TYPE_DEVICE: 639167802Sjkim case ACPI_TYPE_PROCESSOR: 640167802Sjkim case ACPI_TYPE_POWER: 641167802Sjkim case ACPI_TYPE_LOCAL_RESOURCE: 642167802Sjkim return (AE_OK); 643167802Sjkim 644167802Sjkim default: 645167802Sjkim break; 646167802Sjkim } 647167802Sjkim 648167802Sjkim /* All others are valid unreferenced namespace objects */ 649167802Sjkim 650167802Sjkim if (Node->Op) 651167802Sjkim { 652167802Sjkim AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL); 653167802Sjkim } 654167802Sjkim return (AE_OK); 655167802Sjkim} 656167802Sjkim 657167802Sjkim 658167802Sjkim/******************************************************************************* 659167802Sjkim * 660167802Sjkim * FUNCTION: LkFindUnreferencedObjects 661167802Sjkim * 662167802Sjkim * PARAMETERS: None 663167802Sjkim * 664167802Sjkim * RETURN: None 665167802Sjkim * 666167802Sjkim * DESCRIPTION: Namespace walk to find objects that are not referenced in any 667167802Sjkim * way. Must be called after the namespace has been cross 668167802Sjkim * referenced. 669167802Sjkim * 670167802Sjkim ******************************************************************************/ 671167802Sjkim 672167802Sjkimvoid 673167802SjkimLkFindUnreferencedObjects ( 674167802Sjkim void) 675167802Sjkim{ 676167802Sjkim 677167802Sjkim /* Walk entire namespace from the supplied root */ 678167802Sjkim 679167802Sjkim (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 680199337Sjkim ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL, 681167802Sjkim NULL, NULL); 682167802Sjkim} 683167802Sjkim 684167802Sjkim 685167802Sjkim/******************************************************************************* 686167802Sjkim * 687118611Snjl * FUNCTION: LkCrossReferenceNamespace 688118611Snjl * 689118611Snjl * PARAMETERS: None 690118611Snjl * 691118611Snjl * RETURN: Status 692118611Snjl * 693118611Snjl * DESCRIPTION: Perform a cross reference check of the parse tree against the 694118611Snjl * namespace. Every named referenced within the parse tree 695118611Snjl * should be get resolved with a namespace lookup. If not, the 696118611Snjl * original reference in the ASL code is invalid -- i.e., refers 697118611Snjl * to a non-existent object. 698118611Snjl * 699118611Snjl * NOTE: The ASL "External" operator causes the name to be inserted into the 700118611Snjl * namespace so that references to the external name will be resolved 701118611Snjl * correctly here. 702118611Snjl * 703118611Snjl ******************************************************************************/ 704118611Snjl 705118611SnjlACPI_STATUS 706118611SnjlLkCrossReferenceNamespace ( 707118611Snjl void) 708118611Snjl{ 709118611Snjl ACPI_WALK_STATE *WalkState; 710118611Snjl 711118611Snjl 712118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n"); 713118611Snjl 714118611Snjl /* 715118611Snjl * Create a new walk state for use when looking up names 716118611Snjl * within the namespace (Passed as context to the callbacks) 717118611Snjl */ 718118611Snjl WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 719118611Snjl if (!WalkState) 720118611Snjl { 721118611Snjl return AE_NO_MEMORY; 722118611Snjl } 723118611Snjl 724118611Snjl /* Walk the entire parse tree */ 725118611Snjl 726118611Snjl TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin, 727118611Snjl LkNamespaceLocateEnd, WalkState); 728118611Snjl return AE_OK; 729118611Snjl} 730118611Snjl 731118611Snjl 732118611Snjl/******************************************************************************* 733118611Snjl * 734118611Snjl * FUNCTION: LkCheckFieldRange 735118611Snjl * 736118611Snjl * PARAMETERS: RegionBitLength - Length of entire parent region 737118611Snjl * FieldBitOffset - Start of the field unit (within region) 738118611Snjl * FieldBitLength - Entire length of field unit 739118611Snjl * AccessBitWidth - Access width of the field unit 740118611Snjl * 741118611Snjl * RETURN: None 742118611Snjl * 743118611Snjl * DESCRIPTION: Check one field unit to make sure it fits in the parent 744118611Snjl * op region. 745118611Snjl * 746118611Snjl * Note: AccessBitWidth must be either 8,16,32, or 64 747118611Snjl * 748118611Snjl ******************************************************************************/ 749118611Snjl 750151937Sjkimstatic void 751118611SnjlLkCheckFieldRange ( 752118611Snjl ACPI_PARSE_OBJECT *Op, 753118611Snjl UINT32 RegionBitLength, 754118611Snjl UINT32 FieldBitOffset, 755118611Snjl UINT32 FieldBitLength, 756118611Snjl UINT32 AccessBitWidth) 757118611Snjl{ 758118611Snjl UINT32 FieldEndBitOffset; 759118611Snjl 760151937Sjkim 761118611Snjl /* 762118611Snjl * Check each field unit against the region size. The entire 763118611Snjl * field unit (start offset plus length) must fit within the 764118611Snjl * region. 765118611Snjl */ 766118611Snjl FieldEndBitOffset = FieldBitOffset + FieldBitLength; 767118611Snjl 768118611Snjl if (FieldEndBitOffset > RegionBitLength) 769118611Snjl { 770118611Snjl /* Field definition itself is beyond the end-of-region */ 771118611Snjl 772118611Snjl AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL); 773118611Snjl return; 774118611Snjl } 775118611Snjl 776118611Snjl /* 777118611Snjl * Now check that the field plus AccessWidth doesn't go beyond 778118611Snjl * the end-of-region. Assumes AccessBitWidth is a power of 2 779118611Snjl */ 780118611Snjl FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth); 781118611Snjl 782118611Snjl if (FieldEndBitOffset > RegionBitLength) 783118611Snjl { 784118611Snjl /* Field definition combined with the access is beyond EOR */ 785118611Snjl 786118611Snjl AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL); 787118611Snjl } 788118611Snjl} 789118611Snjl 790118611Snjl/******************************************************************************* 791118611Snjl * 792118611Snjl * FUNCTION: LkNamespaceLocateBegin 793118611Snjl * 794118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 795118611Snjl * 796118611Snjl * RETURN: Status 797118611Snjl * 798118611Snjl * DESCRIPTION: Descending callback used during cross-reference. For named 799118611Snjl * object references, attempt to locate the name in the 800118611Snjl * namespace. 801118611Snjl * 802118611Snjl * NOTE: ASL references to named fields within resource descriptors are 803118611Snjl * resolved to integer values here. Therefore, this step is an 804118611Snjl * important part of the code generation. We don't know that the 805118611Snjl * name refers to a resource descriptor until now. 806118611Snjl * 807118611Snjl ******************************************************************************/ 808118611Snjl 809151937Sjkimstatic ACPI_STATUS 810118611SnjlLkNamespaceLocateBegin ( 811118611Snjl ACPI_PARSE_OBJECT *Op, 812118611Snjl UINT32 Level, 813118611Snjl void *Context) 814118611Snjl{ 815118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 816118611Snjl ACPI_NAMESPACE_NODE *Node; 817118611Snjl ACPI_STATUS Status; 818118611Snjl ACPI_OBJECT_TYPE ObjectType; 819118611Snjl char *Path; 820118611Snjl UINT8 PassedArgs; 821118611Snjl ACPI_PARSE_OBJECT *NextOp; 822118611Snjl ACPI_PARSE_OBJECT *OwningOp; 823118611Snjl ACPI_PARSE_OBJECT *SpaceIdOp; 824118611Snjl UINT32 MinimumLength; 825118611Snjl UINT32 Temp; 826118611Snjl const ACPI_OPCODE_INFO *OpInfo; 827118611Snjl UINT32 Flags; 828118611Snjl 829118611Snjl 830167802Sjkim ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op); 831118611Snjl 832118611Snjl /* 833118611Snjl * If this node is the actual declaration of a name 834118611Snjl * [such as the XXXX name in "Method (XXXX)"], 835118611Snjl * we are not interested in it here. We only care about names that are 836118611Snjl * references to other objects within the namespace and the parent objects 837118611Snjl * of name declarations 838118611Snjl */ 839118611Snjl if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) 840118611Snjl { 841118611Snjl return (AE_OK); 842118611Snjl } 843118611Snjl 844118611Snjl /* We are only interested in opcodes that have an associated name */ 845118611Snjl 846118611Snjl OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 847118611Snjl 848118611Snjl if ((!(OpInfo->Flags & AML_NAMED)) && 849118611Snjl (!(OpInfo->Flags & AML_CREATE)) && 850118611Snjl (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) && 851118611Snjl (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) && 852118611Snjl (Op->Asl.ParseOpcode != PARSEOP_METHODCALL)) 853118611Snjl { 854118611Snjl return (AE_OK); 855118611Snjl } 856118611Snjl 857118611Snjl /* 858193529Sjkim * One special case: CondRefOf operator - we don't care if the name exists 859193529Sjkim * or not at this point, just ignore it, the point of the operator is to 860193529Sjkim * determine if the name exists at runtime. 861193529Sjkim */ 862193529Sjkim if ((Op->Asl.Parent) && 863193529Sjkim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)) 864193529Sjkim { 865193529Sjkim return (AE_OK); 866193529Sjkim } 867193529Sjkim 868193529Sjkim /* 869118611Snjl * We must enable the "search-to-root" for single NameSegs, but 870118611Snjl * we have to be very careful about opening up scopes 871118611Snjl */ 872118611Snjl Flags = ACPI_NS_SEARCH_PARENT; 873118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 874118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 875118611Snjl (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 876118611Snjl { 877118611Snjl /* 878118611Snjl * These are name references, do not push the scope stack 879118611Snjl * for them. 880118611Snjl */ 881118611Snjl Flags |= ACPI_NS_DONT_OPEN_SCOPE; 882118611Snjl } 883118611Snjl 884118611Snjl /* Get the NamePath from the appropriate place */ 885118611Snjl 886118611Snjl if (OpInfo->Flags & AML_NAMED) 887118611Snjl { 888167802Sjkim /* For nearly all NAMED operators, the name reference is the first child */ 889118611Snjl 890118611Snjl Path = Op->Asl.Child->Asl.Value.String; 891118611Snjl if (Op->Asl.AmlOpcode == AML_ALIAS_OP) 892118611Snjl { 893118611Snjl /* 894118611Snjl * ALIAS is the only oddball opcode, the name declaration 895118611Snjl * (alias name) is the second operand 896118611Snjl */ 897118611Snjl Path = Op->Asl.Child->Asl.Next->Asl.Value.String; 898118611Snjl } 899118611Snjl } 900118611Snjl else if (OpInfo->Flags & AML_CREATE) 901118611Snjl { 902118611Snjl /* Name must appear as the last parameter */ 903118611Snjl 904118611Snjl NextOp = Op->Asl.Child; 905118611Snjl while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)) 906118611Snjl { 907118611Snjl NextOp = NextOp->Asl.Next; 908118611Snjl } 909118611Snjl Path = NextOp->Asl.Value.String; 910118611Snjl } 911118611Snjl else 912118611Snjl { 913118611Snjl Path = Op->Asl.Value.String; 914118611Snjl } 915118611Snjl 916118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 917151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 918151937Sjkim "Type=%s\n", AcpiUtGetTypeName (ObjectType))); 919118611Snjl 920118611Snjl /* 921118611Snjl * Lookup the name in the namespace. Name must exist at this point, or it 922118611Snjl * is an invalid reference. 923118611Snjl * 924118611Snjl * The namespace is also used as a lookup table for references to resource 925118611Snjl * descriptors and the fields within them. 926118611Snjl */ 927118611Snjl Gbl_NsLookupCount++; 928118611Snjl 929167802Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 930151937Sjkim ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node)); 931118611Snjl if (ACPI_FAILURE (Status)) 932118611Snjl { 933118611Snjl if (Status == AE_NOT_FOUND) 934118611Snjl { 935118611Snjl /* 936118611Snjl * We didn't find the name reference by path -- we can qualify this 937118611Snjl * a little better before we print an error message 938118611Snjl */ 939118611Snjl if (strlen (Path) == ACPI_NAME_SIZE) 940118611Snjl { 941118611Snjl /* A simple, one-segment ACPI name */ 942118611Snjl 943118611Snjl if (LkObjectExists (Path)) 944118611Snjl { 945151937Sjkim /* 946151937Sjkim * There exists such a name, but we couldn't get to it 947151937Sjkim * from this scope 948151937Sjkim */ 949151937Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op, 950151937Sjkim Op->Asl.ExternalName); 951118611Snjl } 952118611Snjl else 953118611Snjl { 954118611Snjl /* The name doesn't exist, period */ 955118611Snjl 956151937Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, 957151937Sjkim Op, Op->Asl.ExternalName); 958118611Snjl } 959118611Snjl } 960118611Snjl else 961118611Snjl { 962118611Snjl /* Check for a fully qualified path */ 963118611Snjl 964118611Snjl if (Path[0] == AML_ROOT_PREFIX) 965118611Snjl { 966118611Snjl /* Gave full path, the object does not exist */ 967118611Snjl 968151937Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op, 969151937Sjkim Op->Asl.ExternalName); 970118611Snjl } 971118611Snjl else 972118611Snjl { 973151937Sjkim /* 974151937Sjkim * We can't tell whether it doesn't exist or just 975151937Sjkim * can't be reached. 976151937Sjkim */ 977151937Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 978151937Sjkim Op->Asl.ExternalName); 979118611Snjl } 980118611Snjl } 981118611Snjl 982118611Snjl Status = AE_OK; 983118611Snjl } 984118611Snjl return (Status); 985118611Snjl } 986118611Snjl 987167802Sjkim /* Check for a reference vs. name declaration */ 988167802Sjkim 989167802Sjkim if (!(OpInfo->Flags & AML_NAMED) && 990167802Sjkim !(OpInfo->Flags & AML_CREATE)) 991167802Sjkim { 992167802Sjkim /* This node has been referenced, mark it for reference check */ 993167802Sjkim 994167802Sjkim Node->Flags |= ANOBJ_IS_REFERENCED; 995167802Sjkim } 996167802Sjkim 997118611Snjl /* Attempt to optimize the NamePath */ 998118611Snjl 999118611Snjl OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node); 1000118611Snjl 1001118611Snjl /* 1002167802Sjkim * 1) Dereference an alias (A name reference that is an alias) 1003167802Sjkim * Aliases are not nested, the alias always points to the final object 1004118611Snjl */ 1005151937Sjkim if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) && 1006151937Sjkim (Node->Type == ACPI_TYPE_LOCAL_ALIAS)) 1007118611Snjl { 1008118611Snjl /* This node points back to the original PARSEOP_ALIAS */ 1009118611Snjl 1010151937Sjkim NextOp = Node->Op; 1011118611Snjl 1012118611Snjl /* The first child is the alias target op */ 1013118611Snjl 1014118611Snjl NextOp = NextOp->Asl.Child; 1015118611Snjl 1016167802Sjkim /* That in turn points back to original target alias node */ 1017118611Snjl 1018118611Snjl if (NextOp->Asl.Node) 1019118611Snjl { 1020118611Snjl Node = NextOp->Asl.Node; 1021118611Snjl } 1022167802Sjkim 1023167802Sjkim /* Else - forward reference to alias, will be resolved later */ 1024118611Snjl } 1025118611Snjl 1026167802Sjkim /* 2) Check for a reference to a resource descriptor */ 1027118611Snjl 1028167802Sjkim if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 1029118611Snjl (Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 1030118611Snjl { 1031118611Snjl /* 1032118611Snjl * This was a reference to a field within a resource descriptor. Extract 1033118611Snjl * the associated field offset (either a bit or byte offset depending on 1034118611Snjl * the field type) and change the named reference into an integer for 1035118611Snjl * AML code generation 1036118611Snjl */ 1037151937Sjkim Temp = Node->Value; 1038118611Snjl if (Node->Flags & ANOBJ_IS_BIT_OFFSET) 1039118611Snjl { 1040118611Snjl Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET; 1041118611Snjl } 1042118611Snjl 1043118611Snjl /* Perform BitOffset <--> ByteOffset conversion if necessary */ 1044118611Snjl 1045118611Snjl switch (Op->Asl.Parent->Asl.AmlOpcode) 1046118611Snjl { 1047118611Snjl case AML_CREATE_FIELD_OP: 1048118611Snjl 1049118611Snjl /* We allow a Byte offset to Bit Offset conversion for this op */ 1050118611Snjl 1051118611Snjl if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)) 1052118611Snjl { 1053118611Snjl /* Simply multiply byte offset times 8 to get bit offset */ 1054118611Snjl 1055118611Snjl Temp = ACPI_MUL_8 (Temp); 1056118611Snjl } 1057118611Snjl break; 1058118611Snjl 1059118611Snjl 1060118611Snjl case AML_CREATE_BIT_FIELD_OP: 1061118611Snjl 1062118611Snjl /* This op requires a Bit Offset */ 1063118611Snjl 1064118611Snjl if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)) 1065118611Snjl { 1066118611Snjl AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL); 1067118611Snjl } 1068118611Snjl break; 1069118611Snjl 1070118611Snjl 1071118611Snjl case AML_CREATE_BYTE_FIELD_OP: 1072118611Snjl case AML_CREATE_WORD_FIELD_OP: 1073118611Snjl case AML_CREATE_DWORD_FIELD_OP: 1074118611Snjl case AML_CREATE_QWORD_FIELD_OP: 1075118611Snjl case AML_INDEX_OP: 1076118611Snjl 1077118611Snjl /* These Ops require Byte offsets */ 1078118611Snjl 1079118611Snjl if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET) 1080118611Snjl { 1081118611Snjl AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL); 1082118611Snjl } 1083118611Snjl break; 1084118611Snjl 1085118611Snjl 1086118611Snjl default: 1087118611Snjl /* Nothing to do for other opcodes */ 1088118611Snjl break; 1089118611Snjl } 1090118611Snjl 1091118611Snjl /* Now convert this node to an integer whose value is the field offset */ 1092118611Snjl 1093151937Sjkim Op->Asl.AmlLength = 0; 1094118611Snjl Op->Asl.ParseOpcode = PARSEOP_INTEGER; 1095118611Snjl Op->Asl.Value.Integer = (UINT64) Temp; 1096118611Snjl Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 1097118611Snjl 1098118611Snjl OpcGenerateAmlOpcode (Op); 1099118611Snjl } 1100118611Snjl 1101167802Sjkim /* 3) Check for a method invocation */ 1102118611Snjl 1103118611Snjl else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) && 1104118611Snjl (Node->Type == ACPI_TYPE_METHOD) && 1105118611Snjl (Op->Asl.Parent) && 1106118611Snjl (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) || 1107118611Snjl 1108118611Snjl (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 1109118611Snjl { 1110118611Snjl 1111118611Snjl /* 1112151937Sjkim * A reference to a method within one of these opcodes is not an 1113151937Sjkim * invocation of the method, it is simply a reference to the method. 1114151937Sjkim */ 1115151937Sjkim if ((Op->Asl.Parent) && 1116151937Sjkim ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF) || 1117151937Sjkim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF) || 1118151937Sjkim (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE))) 1119151937Sjkim { 1120151937Sjkim return (AE_OK); 1121151937Sjkim } 1122151937Sjkim /* 1123118611Snjl * There are two types of method invocation: 1124151937Sjkim * 1) Invocation with arguments -- the parser recognizes this 1125151937Sjkim * as a METHODCALL. 1126151937Sjkim * 2) Invocation with no arguments --the parser cannot determine that 1127151937Sjkim * this is a method invocation, therefore we have to figure it out 1128151937Sjkim * here. 1129118611Snjl */ 1130118611Snjl if (Node->Type != ACPI_TYPE_METHOD) 1131118611Snjl { 1132151937Sjkim sprintf (MsgBuffer, "%s is a %s", 1133151937Sjkim Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 1134118611Snjl 1135118611Snjl AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer); 1136118611Snjl return (AE_OK); 1137118611Snjl } 1138118611Snjl 1139118611Snjl /* Save the method node in the caller's op */ 1140118611Snjl 1141118611Snjl Op->Asl.Node = Node; 1142118611Snjl if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF) 1143118611Snjl { 1144118611Snjl return (AE_OK); 1145118611Snjl } 1146118611Snjl 1147118611Snjl /* 1148118611Snjl * This is a method invocation, with or without arguments. 1149118611Snjl * Count the number of arguments, each appears as a child 1150118611Snjl * under the parent node 1151118611Snjl */ 1152118611Snjl Op->Asl.ParseOpcode = PARSEOP_METHODCALL; 1153118611Snjl UtSetParseOpName (Op); 1154118611Snjl 1155118611Snjl PassedArgs = 0; 1156118611Snjl NextOp = Op->Asl.Child; 1157118611Snjl 1158118611Snjl while (NextOp) 1159118611Snjl { 1160118611Snjl PassedArgs++; 1161118611Snjl NextOp = NextOp->Asl.Next; 1162118611Snjl } 1163118611Snjl 1164151937Sjkim if (Node->Value != ASL_EXTERNAL_METHOD) 1165118611Snjl { 1166118611Snjl /* 1167118611Snjl * Check the parsed arguments with the number expected by the 1168118611Snjl * method declaration itself 1169118611Snjl */ 1170151937Sjkim if (PassedArgs != Node->Value) 1171118611Snjl { 1172209746Sjkim sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName, 1173151937Sjkim Node->Value); 1174118611Snjl 1175151937Sjkim if (PassedArgs < Node->Value) 1176118611Snjl { 1177118611Snjl AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer); 1178118611Snjl } 1179118611Snjl else 1180118611Snjl { 1181118611Snjl AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer); 1182118611Snjl } 1183118611Snjl } 1184118611Snjl } 1185118611Snjl } 1186118611Snjl 1187167802Sjkim /* 4) Check for an ASL Field definition */ 1188151937Sjkim 1189118611Snjl else if ((Op->Asl.Parent) && 1190118611Snjl ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) || 1191118611Snjl (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD))) 1192118611Snjl { 1193118611Snjl /* 1194118611Snjl * Offset checking for fields. If the parent operation region has a 1195118611Snjl * constant length (known at compile time), we can check fields 1196118611Snjl * defined in that region against the region length. This will catch 1197118611Snjl * fields and field units that cannot possibly fit within the region. 1198118611Snjl * 1199118611Snjl * Note: Index fields do not directly reference an operation region, 1200118611Snjl * thus they are not included in this check. 1201118611Snjl */ 1202118611Snjl if (Op == Op->Asl.Parent->Asl.Child) 1203118611Snjl { 1204118611Snjl /* 1205118611Snjl * This is the first child of the field node, which is 1206118611Snjl * the name of the region. Get the parse node for the 1207118611Snjl * region -- which contains the length of the region. 1208118611Snjl */ 1209151937Sjkim OwningOp = Node->Op; 1210151937Sjkim Op->Asl.Parent->Asl.ExtraValue = 1211151937Sjkim ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer); 1212118611Snjl 1213118611Snjl /* Examine the field access width */ 1214118611Snjl 1215118611Snjl switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer) 1216118611Snjl { 1217118611Snjl case AML_FIELD_ACCESS_ANY: 1218118611Snjl case AML_FIELD_ACCESS_BYTE: 1219118611Snjl case AML_FIELD_ACCESS_BUFFER: 1220118611Snjl default: 1221118611Snjl MinimumLength = 1; 1222118611Snjl break; 1223118611Snjl 1224118611Snjl case AML_FIELD_ACCESS_WORD: 1225118611Snjl MinimumLength = 2; 1226118611Snjl break; 1227118611Snjl 1228118611Snjl case AML_FIELD_ACCESS_DWORD: 1229118611Snjl MinimumLength = 4; 1230118611Snjl break; 1231118611Snjl 1232118611Snjl case AML_FIELD_ACCESS_QWORD: 1233118611Snjl MinimumLength = 8; 1234118611Snjl break; 1235118611Snjl } 1236118611Snjl 1237118611Snjl /* 1238118611Snjl * Is the region at least as big as the access width? 1239118611Snjl * Note: DataTableRegions have 0 length 1240118611Snjl */ 1241118611Snjl if (((UINT32) OwningOp->Asl.Value.Integer) && 1242118611Snjl ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength)) 1243118611Snjl { 1244118611Snjl AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL); 1245118611Snjl } 1246118611Snjl 1247118611Snjl /* 1248118611Snjl * Check EC/CMOS/SMBUS fields to make sure that the correct 1249118611Snjl * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS) 1250118611Snjl */ 1251118611Snjl SpaceIdOp = OwningOp->Asl.Child->Asl.Next; 1252118611Snjl switch ((UINT32) SpaceIdOp->Asl.Value.Integer) 1253118611Snjl { 1254220663Sjkim case ACPI_ADR_SPACE_EC: 1255220663Sjkim case ACPI_ADR_SPACE_CMOS: 1256118611Snjl 1257118611Snjl if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE) 1258118611Snjl { 1259118611Snjl AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL); 1260118611Snjl } 1261118611Snjl break; 1262118611Snjl 1263220663Sjkim case ACPI_ADR_SPACE_SMBUS: 1264220663Sjkim case ACPI_ADR_SPACE_IPMI: 1265118611Snjl 1266118611Snjl if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER) 1267118611Snjl { 1268118611Snjl AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL); 1269118611Snjl } 1270118611Snjl break; 1271118611Snjl 1272118611Snjl default: 1273118611Snjl 1274118611Snjl /* Nothing to do for other address spaces */ 1275118611Snjl break; 1276118611Snjl } 1277118611Snjl } 1278118611Snjl else 1279118611Snjl { 1280118611Snjl /* 1281118611Snjl * This is one element of the field list. Check to make sure 1282118611Snjl * that it does not go beyond the end of the parent operation region. 1283118611Snjl * 1284118611Snjl * In the code below: 1285118611Snjl * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits) 1286118611Snjl * Op->Asl.ExtraValue - Field start offset (bits) 1287118611Snjl * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits) 1288118611Snjl * Op->Asl.Child->Asl.ExtraValue - Field access width (bits) 1289118611Snjl */ 1290118611Snjl if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child) 1291118611Snjl { 1292118611Snjl LkCheckFieldRange (Op, 1293118611Snjl Op->Asl.Parent->Asl.ExtraValue, 1294118611Snjl Op->Asl.ExtraValue, 1295118611Snjl (UINT32) Op->Asl.Child->Asl.Value.Integer, 1296118611Snjl Op->Asl.Child->Asl.ExtraValue); 1297118611Snjl } 1298118611Snjl } 1299118611Snjl } 1300118611Snjl 1301118611Snjl Op->Asl.Node = Node; 1302118611Snjl return (Status); 1303118611Snjl} 1304118611Snjl 1305118611Snjl 1306118611Snjl/******************************************************************************* 1307118611Snjl * 1308118611Snjl * FUNCTION: LkNamespaceLocateEnd 1309118611Snjl * 1310118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 1311118611Snjl * 1312118611Snjl * RETURN: Status 1313118611Snjl * 1314118611Snjl * DESCRIPTION: Ascending callback used during cross reference. We only 1315118611Snjl * need to worry about scope management here. 1316118611Snjl * 1317118611Snjl ******************************************************************************/ 1318118611Snjl 1319151937Sjkimstatic ACPI_STATUS 1320118611SnjlLkNamespaceLocateEnd ( 1321118611Snjl ACPI_PARSE_OBJECT *Op, 1322118611Snjl UINT32 Level, 1323118611Snjl void *Context) 1324118611Snjl{ 1325118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 1326118611Snjl const ACPI_OPCODE_INFO *OpInfo; 1327118611Snjl 1328118611Snjl 1329167802Sjkim ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd); 1330118611Snjl 1331118611Snjl 1332118611Snjl /* We are only interested in opcodes that have an associated name */ 1333118611Snjl 1334118611Snjl OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1335118611Snjl if (!(OpInfo->Flags & AML_NAMED)) 1336118611Snjl { 1337118611Snjl return (AE_OK); 1338118611Snjl } 1339118611Snjl 1340118611Snjl /* Not interested in name references, we did not open a scope for them */ 1341118611Snjl 1342118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 1343118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 1344118611Snjl (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 1345118611Snjl { 1346118611Snjl return (AE_OK); 1347118611Snjl } 1348118611Snjl 1349118611Snjl /* Pop the scope stack if necessary */ 1350118611Snjl 1351118611Snjl if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode))) 1352118611Snjl { 1353118611Snjl 1354118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1355118611Snjl "%s: Popping scope for Op %p\n", 1356118611Snjl AcpiUtGetTypeName (OpInfo->ObjectType), Op)); 1357118611Snjl 1358151937Sjkim (void) AcpiDsScopeStackPop (WalkState); 1359118611Snjl } 1360118611Snjl 1361118611Snjl return (AE_OK); 1362118611Snjl} 1363118611Snjl 1364118611Snjl 1365