psargs.c revision 204773
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: psargs - Parse AML opcode arguments 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 767754Smsmith/****************************************************************************** 867754Smsmith * 967754Smsmith * 1. Copyright Notice 1067754Smsmith * 11202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 1467754Smsmith * 2. License 1567754Smsmith * 1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1767754Smsmith * rights. You may have additional license terms from the party that provided 1867754Smsmith * you this software, covering your right to use that party's intellectual 1967754Smsmith * property rights. 2067754Smsmith * 2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2667754Smsmith * Code in any form, with the right to sublicense such rights; and 2767754Smsmith * 2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2967754Smsmith * license (with the right to sublicense), under only those claims of Intel 3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3367754Smsmith * license, and in no event shall the patent license extend to any additions 3467754Smsmith * to or modifications of the Original Intel Code. No other license or right 3567754Smsmith * is granted directly or by implication, estoppel or otherwise; 3667754Smsmith * 3767754Smsmith * The above copyright and patent license is granted only if the following 3867754Smsmith * conditions are met: 3967754Smsmith * 4067754Smsmith * 3. Conditions 4167754Smsmith * 4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4367754Smsmith * Redistribution of source code of any substantial portion of the Covered 4467754Smsmith * Code or modification with rights to further distribute source must include 4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4667754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered 4967754Smsmith * Code and the date of any change. Licensee must include in that file the 5067754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5167754Smsmith * must include a prominent statement that the modification is derived, 5267754Smsmith * directly or indirectly, from Original Intel Code. 5367754Smsmith * 5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5567754Smsmith * Redistribution of source code of any substantial portion of the Covered 5667754Smsmith * Code or modification without rights to further distribute source must 5767754Smsmith * include the following Disclaimer and Export Compliance provision in the 5867754Smsmith * documentation and/or other materials provided with distribution. In 5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6167754Smsmith * license from Licensee to its licensee is limited to the intellectual 6267754Smsmith * property embodied in the software Licensee provides to its licensee, and 6367754Smsmith * not to intellectual property embodied in modifications its licensee may 6467754Smsmith * make. 6567754Smsmith * 6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 6967754Smsmith * provision in the documentation and/or other materials provided with the 7067754Smsmith * distribution. 7167754Smsmith * 7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7367754Smsmith * Intel Code. 7467754Smsmith * 7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7767754Smsmith * other dealings in products derived from or relating to the Covered Code 7867754Smsmith * without prior written authorization from Intel. 7967754Smsmith * 8067754Smsmith * 4. Disclaimer and Export Compliance 8167754Smsmith * 8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8367754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8867754Smsmith * PARTICULAR PURPOSE. 8967754Smsmith * 9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9767754Smsmith * LIMITED REMEDY. 9867754Smsmith * 9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10067754Smsmith * software or system incorporating such software without first obtaining any 10167754Smsmith * required license or other approval from the U. S. Department of Commerce or 10267754Smsmith * any other agency or department of the United States Government. In the 10367754Smsmith * event Licensee exports any such software from the United States or 10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10567754Smsmith * ensure that the distribution and export/re-export of the software is in 10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 10967754Smsmith * software, or service, directly or indirectly, to any country for which the 11067754Smsmith * United States government or any agency thereof requires an export license, 11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11267754Smsmith * such license, approval or letter. 11367754Smsmith * 11467754Smsmith *****************************************************************************/ 11567754Smsmith 11667754Smsmith#define __PSARGS_C__ 11767754Smsmith 118193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 119193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 120193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 121193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 122193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 123193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 12467754Smsmith 12577424Smsmith#define _COMPONENT ACPI_PARSER 12691116Smsmith ACPI_MODULE_NAME ("psargs") 12767754Smsmith 128151937Sjkim/* Local prototypes */ 12967754Smsmith 130151937Sjkimstatic UINT32 131151937SjkimAcpiPsGetNextPackageLength ( 132151937Sjkim ACPI_PARSE_STATE *ParserState); 133151937Sjkim 134151937Sjkimstatic ACPI_PARSE_OBJECT * 135151937SjkimAcpiPsGetNextField ( 136151937Sjkim ACPI_PARSE_STATE *ParserState); 137151937Sjkim 138151937Sjkim 13967754Smsmith/******************************************************************************* 14067754Smsmith * 14167754Smsmith * FUNCTION: AcpiPsGetNextPackageLength 14267754Smsmith * 14367754Smsmith * PARAMETERS: ParserState - Current parser state object 14467754Smsmith * 145167802Sjkim * RETURN: Decoded package length. On completion, the AML pointer points 14667754Smsmith * past the length byte or bytes. 14767754Smsmith * 148167802Sjkim * DESCRIPTION: Decode and return a package length field. 149167802Sjkim * Note: Largest package length is 28 bits, from ACPI specification 15067754Smsmith * 15167754Smsmith ******************************************************************************/ 15267754Smsmith 153151937Sjkimstatic UINT32 15467754SmsmithAcpiPsGetNextPackageLength ( 15567754Smsmith ACPI_PARSE_STATE *ParserState) 15667754Smsmith{ 157167802Sjkim UINT8 *Aml = ParserState->Aml; 158167802Sjkim UINT32 PackageLength = 0; 159193267Sjkim UINT32 ByteCount; 160167802Sjkim UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */ 16167754Smsmith 16267754Smsmith 163167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextPackageLength); 16467754Smsmith 16567754Smsmith 166167802Sjkim /* 167167802Sjkim * Byte 0 bits [6:7] contain the number of additional bytes 168167802Sjkim * used to encode the package length, either 0,1,2, or 3 169167802Sjkim */ 170167802Sjkim ByteCount = (Aml[0] >> 6); 171193267Sjkim ParserState->Aml += ((ACPI_SIZE) ByteCount + 1); 17267754Smsmith 173167802Sjkim /* Get bytes 3, 2, 1 as needed */ 174167802Sjkim 175167802Sjkim while (ByteCount) 17667754Smsmith { 177167802Sjkim /* 178167802Sjkim * Final bit positions for the package length bytes: 179167802Sjkim * Byte3->[20:27] 180167802Sjkim * Byte2->[12:19] 181167802Sjkim * Byte1->[04:11] 182167802Sjkim * Byte0->[00:03] 183167802Sjkim */ 184167802Sjkim PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4)); 18567754Smsmith 186167802Sjkim ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */ 187167802Sjkim ByteCount--; 188167802Sjkim } 18967754Smsmith 190167802Sjkim /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 19167754Smsmith 192167802Sjkim PackageLength |= (Aml[0] & ByteZeroMask); 193167802Sjkim return_UINT32 (PackageLength); 19467754Smsmith} 19567754Smsmith 19667754Smsmith 19767754Smsmith/******************************************************************************* 19867754Smsmith * 19967754Smsmith * FUNCTION: AcpiPsGetNextPackageEnd 20067754Smsmith * 20167754Smsmith * PARAMETERS: ParserState - Current parser state object 20267754Smsmith * 20367754Smsmith * RETURN: Pointer to end-of-package +1 20467754Smsmith * 20567754Smsmith * DESCRIPTION: Get next package length and return a pointer past the end of 20667754Smsmith * the package. Consumes the package length field 20767754Smsmith * 20867754Smsmith ******************************************************************************/ 20967754Smsmith 21067754SmsmithUINT8 * 21167754SmsmithAcpiPsGetNextPackageEnd ( 21267754Smsmith ACPI_PARSE_STATE *ParserState) 21367754Smsmith{ 21467754Smsmith UINT8 *Start = ParserState->Aml; 215167802Sjkim UINT32 PackageLength; 21667754Smsmith 21767754Smsmith 218167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextPackageEnd); 21967754Smsmith 22067754Smsmith 221167802Sjkim /* Function below updates ParserState->Aml */ 222107325Siwasaki 223167802Sjkim PackageLength = AcpiPsGetNextPackageLength (ParserState); 22467754Smsmith 225167802Sjkim return_PTR (Start + PackageLength); /* end of package */ 22667754Smsmith} 22767754Smsmith 22867754Smsmith 22967754Smsmith/******************************************************************************* 23067754Smsmith * 23167754Smsmith * FUNCTION: AcpiPsGetNextNamestring 23267754Smsmith * 23367754Smsmith * PARAMETERS: ParserState - Current parser state object 23467754Smsmith * 23567754Smsmith * RETURN: Pointer to the start of the name string (pointer points into 23667754Smsmith * the AML. 23767754Smsmith * 23867754Smsmith * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 23967754Smsmith * prefix characters. Set parser state to point past the string. 24067754Smsmith * (Name is consumed from the AML.) 24167754Smsmith * 24267754Smsmith ******************************************************************************/ 24367754Smsmith 244114237Snjlchar * 24567754SmsmithAcpiPsGetNextNamestring ( 24667754Smsmith ACPI_PARSE_STATE *ParserState) 24767754Smsmith{ 24899679Siwasaki UINT8 *Start = ParserState->Aml; 24999679Siwasaki UINT8 *End = ParserState->Aml; 25067754Smsmith 25167754Smsmith 252167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextNamestring); 25367754Smsmith 25467754Smsmith 255167802Sjkim /* Point past any namestring prefix characters (backslash or carat) */ 25667754Smsmith 257167802Sjkim while (AcpiPsIsPrefixChar (*End)) 25867754Smsmith { 25967754Smsmith End++; 26067754Smsmith } 26167754Smsmith 262167802Sjkim /* Decode the path prefix character */ 26367754Smsmith 264167802Sjkim switch (*End) 26567754Smsmith { 26667754Smsmith case 0: 26767754Smsmith 26867754Smsmith /* NullName */ 26967754Smsmith 27067754Smsmith if (End == Start) 27167754Smsmith { 27267754Smsmith Start = NULL; 27367754Smsmith } 27467754Smsmith End++; 27567754Smsmith break; 27667754Smsmith 27767754Smsmith case AML_DUAL_NAME_PREFIX: 27867754Smsmith 27999679Siwasaki /* Two name segments */ 28067754Smsmith 281107325Siwasaki End += 1 + (2 * ACPI_NAME_SIZE); 28267754Smsmith break; 28367754Smsmith 28467754Smsmith case AML_MULTI_NAME_PREFIX_OP: 28567754Smsmith 286167802Sjkim /* Multiple name segments, 4 chars each, count in next byte */ 28767754Smsmith 288167802Sjkim End += 2 + (*(End + 1) * ACPI_NAME_SIZE); 28967754Smsmith break; 29067754Smsmith 29167754Smsmith default: 29267754Smsmith 29399679Siwasaki /* Single name segment */ 29467754Smsmith 295107325Siwasaki End += ACPI_NAME_SIZE; 29667754Smsmith break; 29767754Smsmith } 29867754Smsmith 299167802Sjkim ParserState->Aml = End; 300114237Snjl return_PTR ((char *) Start); 30167754Smsmith} 30267754Smsmith 30367754Smsmith 30467754Smsmith/******************************************************************************* 30567754Smsmith * 30667754Smsmith * FUNCTION: AcpiPsGetNextNamepath 30767754Smsmith * 30867754Smsmith * PARAMETERS: ParserState - Current parser state object 30967754Smsmith * Arg - Where the namepath will be stored 31067754Smsmith * ArgCount - If the namepath points to a control method 31167754Smsmith * the method's argument is returned here. 312167802Sjkim * PossibleMethodCall - Whether the namepath can possibly be the 313107325Siwasaki * start of a method call 31467754Smsmith * 315102550Siwasaki * RETURN: Status 31667754Smsmith * 317102550Siwasaki * DESCRIPTION: Get next name (if method call, return # of required args). 318102550Siwasaki * Names are looked up in the internal namespace to determine 319102550Siwasaki * if the name represents a control method. If a method 32067754Smsmith * is found, the number of arguments to the method is returned. 32167754Smsmith * This information is critical for parsing to continue correctly. 32267754Smsmith * 32367754Smsmith ******************************************************************************/ 32467754Smsmith 325102550SiwasakiACPI_STATUS 32667754SmsmithAcpiPsGetNextNamepath ( 327107325Siwasaki ACPI_WALK_STATE *WalkState, 32867754Smsmith ACPI_PARSE_STATE *ParserState, 32967754Smsmith ACPI_PARSE_OBJECT *Arg, 330167802Sjkim BOOLEAN PossibleMethodCall) 33167754Smsmith{ 332193267Sjkim ACPI_STATUS Status; 333114237Snjl char *Path; 33467754Smsmith ACPI_PARSE_OBJECT *NameOp; 335102550Siwasaki ACPI_OPERAND_OBJECT *MethodDesc; 336102550Siwasaki ACPI_NAMESPACE_NODE *Node; 337193267Sjkim UINT8 *Start = ParserState->Aml; 33867754Smsmith 33967754Smsmith 340167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextNamepath); 34167754Smsmith 34267754Smsmith 34367754Smsmith Path = AcpiPsGetNextNamestring (ParserState); 344167802Sjkim AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 34567754Smsmith 346167802Sjkim /* Null path case is allowed, just exit */ 34767754Smsmith 348167802Sjkim if (!Path) 34967754Smsmith { 350167802Sjkim Arg->Common.Value.Name = Path; 351167802Sjkim return_ACPI_STATUS (AE_OK); 352167802Sjkim } 353167802Sjkim 354167802Sjkim /* 355193267Sjkim * Lookup the name in the internal namespace, starting with the current 356193267Sjkim * scope. We don't want to add anything new to the namespace here, 357193267Sjkim * however, so we use MODE_EXECUTE. 358167802Sjkim * Allow searching of the parent tree, but don't open a new scope - 359167802Sjkim * we just want to lookup the object (must be mode EXECUTE to perform 360167802Sjkim * the upsearch) 361167802Sjkim */ 362193267Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 363193267Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 364167802Sjkim ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 365167802Sjkim 366167802Sjkim /* 367167802Sjkim * If this name is a control method invocation, we must 368167802Sjkim * setup the method call 369167802Sjkim */ 370167802Sjkim if (ACPI_SUCCESS (Status) && 371167802Sjkim PossibleMethodCall && 372167802Sjkim (Node->Type == ACPI_TYPE_METHOD)) 373167802Sjkim { 374193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 375193267Sjkim { 376193267Sjkim /* 377193267Sjkim * AcpiPsGetNextNamestring has increased the AML pointer, 378193267Sjkim * so we need to restore the saved AML pointer for method call. 379193267Sjkim */ 380193267Sjkim WalkState->ParserState.Aml = Start; 381193267Sjkim WalkState->ArgCount = 1; 382193267Sjkim AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 383193267Sjkim return_ACPI_STATUS (AE_OK); 384193267Sjkim } 385193267Sjkim 386167802Sjkim /* This name is actually a control method invocation */ 387167802Sjkim 388167802Sjkim MethodDesc = AcpiNsGetAttachedObject (Node); 389167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 390167802Sjkim "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path)); 391167802Sjkim 392167802Sjkim NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 393167802Sjkim if (!NameOp) 39467754Smsmith { 395167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 39667754Smsmith } 39767754Smsmith 398167802Sjkim /* Change Arg into a METHOD CALL and attach name to it */ 399151937Sjkim 400167802Sjkim AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 401167802Sjkim NameOp->Common.Value.Name = Path; 402102550Siwasaki 403167802Sjkim /* Point METHODCALL/NAME to the METHOD Node */ 40467754Smsmith 405167802Sjkim NameOp->Common.Node = Node; 406167802Sjkim AcpiPsAppendArg (Arg, NameOp); 40767754Smsmith 408167802Sjkim if (!MethodDesc) 409167802Sjkim { 410167802Sjkim ACPI_ERROR ((AE_INFO, 411167802Sjkim "Control Method %p has no attached object", 412167802Sjkim Node)); 413167802Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 414167802Sjkim } 41567754Smsmith 416167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 417167802Sjkim "Control Method - %p Args %X\n", 418167802Sjkim Node, MethodDesc->Method.ParamCount)); 41967754Smsmith 420167802Sjkim /* Get the number of arguments to expect */ 421102550Siwasaki 422167802Sjkim WalkState->ArgCount = MethodDesc->Method.ParamCount; 423167802Sjkim return_ACPI_STATUS (AE_OK); 424167802Sjkim } 42567754Smsmith 426167802Sjkim /* 427167802Sjkim * Special handling if the name was not found during the lookup - 428167802Sjkim * some NotFound cases are allowed 429167802Sjkim */ 430167802Sjkim if (Status == AE_NOT_FOUND) 431167802Sjkim { 432167802Sjkim /* 1) NotFound is ok during load pass 1/2 (allow forward references) */ 433102550Siwasaki 434167802Sjkim if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) != 435167802Sjkim ACPI_PARSE_EXECUTE) 436167802Sjkim { 437167802Sjkim Status = AE_OK; 438167802Sjkim } 439107325Siwasaki 440167802Sjkim /* 2) NotFound during a CondRefOf(x) is ok by definition */ 44167754Smsmith 442167802Sjkim else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP) 443167802Sjkim { 444167802Sjkim Status = AE_OK; 44567754Smsmith } 446107325Siwasaki 447167802Sjkim /* 448167802Sjkim * 3) NotFound while building a Package is ok at this point, we 449167802Sjkim * may flag as an error later if slack mode is not enabled. 450167802Sjkim * (Some ASL code depends on allowing this behavior) 451167802Sjkim */ 452167802Sjkim else if ((Arg->Common.Parent) && 453167802Sjkim ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 454167802Sjkim (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 455107325Siwasaki { 456167802Sjkim Status = AE_OK; 457167802Sjkim } 458167802Sjkim } 459107325Siwasaki 460167802Sjkim /* Final exception check (may have been changed from code above) */ 461117521Snjl 462167802Sjkim if (ACPI_FAILURE (Status)) 463167802Sjkim { 464167802Sjkim ACPI_ERROR_NAMESPACE (Path, Status); 465117521Snjl 466167802Sjkim if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == 467167802Sjkim ACPI_PARSE_EXECUTE) 468167802Sjkim { 469167802Sjkim /* Report a control method execution error */ 470117521Snjl 471167802Sjkim Status = AcpiDsMethodError (Status, WalkState); 472107325Siwasaki } 47367754Smsmith } 47467754Smsmith 475167802Sjkim /* Save the namepath */ 476167802Sjkim 47799679Siwasaki Arg->Common.Value.Name = Path; 478102550Siwasaki return_ACPI_STATUS (Status); 47967754Smsmith} 48067754Smsmith 48167754Smsmith 48267754Smsmith/******************************************************************************* 48367754Smsmith * 48467754Smsmith * FUNCTION: AcpiPsGetNextSimpleArg 48567754Smsmith * 48667754Smsmith * PARAMETERS: ParserState - Current parser state object 48767754Smsmith * ArgType - The argument type (AML_*_ARG) 48867754Smsmith * Arg - Where the argument is returned 48967754Smsmith * 49067754Smsmith * RETURN: None 49167754Smsmith * 49267754Smsmith * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 49367754Smsmith * 49467754Smsmith ******************************************************************************/ 49567754Smsmith 49667754Smsmithvoid 49767754SmsmithAcpiPsGetNextSimpleArg ( 49867754Smsmith ACPI_PARSE_STATE *ParserState, 49967754Smsmith UINT32 ArgType, 50067754Smsmith ACPI_PARSE_OBJECT *Arg) 50167754Smsmith{ 502167802Sjkim UINT32 Length; 503167802Sjkim UINT16 Opcode; 504167802Sjkim UINT8 *Aml = ParserState->Aml; 50567754Smsmith 50667754Smsmith 507167802Sjkim ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType); 50867754Smsmith 509167802Sjkim 51067754Smsmith switch (ArgType) 51167754Smsmith { 51267754Smsmith case ARGP_BYTEDATA: 51367754Smsmith 514167802Sjkim /* Get 1 byte from the AML stream */ 515167802Sjkim 516167802Sjkim Opcode = AML_BYTE_OP; 517202771Sjkim Arg->Common.Value.Integer = (UINT64) *Aml; 518167802Sjkim Length = 1; 51967754Smsmith break; 52067754Smsmith 52167754Smsmith 52267754Smsmith case ARGP_WORDDATA: 52367754Smsmith 52467754Smsmith /* Get 2 bytes from the AML stream */ 52567754Smsmith 526167802Sjkim Opcode = AML_WORD_OP; 527167802Sjkim ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); 528167802Sjkim Length = 2; 52967754Smsmith break; 53067754Smsmith 53167754Smsmith 53267754Smsmith case ARGP_DWORDDATA: 53367754Smsmith 53467754Smsmith /* Get 4 bytes from the AML stream */ 53567754Smsmith 536167802Sjkim Opcode = AML_DWORD_OP; 537167802Sjkim ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); 538167802Sjkim Length = 4; 53967754Smsmith break; 54067754Smsmith 54167754Smsmith 54282367Smsmith case ARGP_QWORDDATA: 54382367Smsmith 54482367Smsmith /* Get 8 bytes from the AML stream */ 54582367Smsmith 546167802Sjkim Opcode = AML_QWORD_OP; 547167802Sjkim ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); 548167802Sjkim Length = 8; 54982367Smsmith break; 55082367Smsmith 55182367Smsmith 55267754Smsmith case ARGP_CHARLIST: 55367754Smsmith 554167802Sjkim /* Get a pointer to the string, point past the string */ 55567754Smsmith 556167802Sjkim Opcode = AML_STRING_OP; 557167802Sjkim Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); 558167802Sjkim 559167802Sjkim /* Find the null terminator */ 560167802Sjkim 561167802Sjkim Length = 0; 562167802Sjkim while (Aml[Length]) 56367754Smsmith { 564167802Sjkim Length++; 56567754Smsmith } 566167802Sjkim Length++; 56767754Smsmith break; 56867754Smsmith 56967754Smsmith 57067754Smsmith case ARGP_NAME: 57167754Smsmith case ARGP_NAMESTRING: 57267754Smsmith 57377424Smsmith AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 57499679Siwasaki Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 575167802Sjkim return_VOID; 57699679Siwasaki 57799679Siwasaki 57899679Siwasaki default: 579107325Siwasaki 580204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType)); 581167802Sjkim return_VOID; 58267754Smsmith } 58367754Smsmith 584167802Sjkim AcpiPsInitOp (Arg, Opcode); 585167802Sjkim ParserState->Aml += Length; 58667754Smsmith return_VOID; 58767754Smsmith} 58867754Smsmith 58967754Smsmith 59067754Smsmith/******************************************************************************* 59167754Smsmith * 59267754Smsmith * FUNCTION: AcpiPsGetNextField 59367754Smsmith * 59467754Smsmith * PARAMETERS: ParserState - Current parser state object 59567754Smsmith * 59667754Smsmith * RETURN: A newly allocated FIELD op 59767754Smsmith * 59867754Smsmith * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField) 59967754Smsmith * 60067754Smsmith ******************************************************************************/ 60167754Smsmith 602151937Sjkimstatic ACPI_PARSE_OBJECT * 60367754SmsmithAcpiPsGetNextField ( 60467754Smsmith ACPI_PARSE_STATE *ParserState) 60567754Smsmith{ 606151937Sjkim UINT32 AmlOffset = (UINT32) 607151937Sjkim ACPI_PTR_DIFF (ParserState->Aml, 608151937Sjkim ParserState->AmlStart); 60967754Smsmith ACPI_PARSE_OBJECT *Field; 61067754Smsmith UINT16 Opcode; 61167754Smsmith UINT32 Name; 61267754Smsmith 61367754Smsmith 614167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextField); 61567754Smsmith 61667754Smsmith 617151937Sjkim /* Determine field type */ 61867754Smsmith 61991116Smsmith switch (ACPI_GET8 (ParserState->Aml)) 62067754Smsmith { 62167754Smsmith default: 62267754Smsmith 62377424Smsmith Opcode = AML_INT_NAMEDFIELD_OP; 62467754Smsmith break; 62567754Smsmith 62667754Smsmith case 0x00: 62767754Smsmith 62877424Smsmith Opcode = AML_INT_RESERVEDFIELD_OP; 62967754Smsmith ParserState->Aml++; 63067754Smsmith break; 63167754Smsmith 63267754Smsmith case 0x01: 63367754Smsmith 63477424Smsmith Opcode = AML_INT_ACCESSFIELD_OP; 63567754Smsmith ParserState->Aml++; 63667754Smsmith break; 63767754Smsmith } 63867754Smsmith 63967754Smsmith /* Allocate a new field op */ 64067754Smsmith 64167754Smsmith Field = AcpiPsAllocOp (Opcode); 64299679Siwasaki if (!Field) 64367754Smsmith { 64499679Siwasaki return_PTR (NULL); 64599679Siwasaki } 64667754Smsmith 64799679Siwasaki Field->Common.AmlOffset = AmlOffset; 64867754Smsmith 64999679Siwasaki /* Decode the field type */ 65067754Smsmith 65199679Siwasaki switch (Opcode) 65299679Siwasaki { 65399679Siwasaki case AML_INT_NAMEDFIELD_OP: 65467754Smsmith 65599679Siwasaki /* Get the 4-character name */ 65667754Smsmith 657117521Snjl ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 65899679Siwasaki AcpiPsSetName (Field, Name); 659107325Siwasaki ParserState->Aml += ACPI_NAME_SIZE; 66067754Smsmith 66199679Siwasaki /* Get the length which is encoded as a package length */ 66267754Smsmith 66399679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 66499679Siwasaki break; 66567754Smsmith 66667754Smsmith 66799679Siwasaki case AML_INT_RESERVEDFIELD_OP: 66867754Smsmith 66999679Siwasaki /* Get the length which is encoded as a package length */ 67067754Smsmith 67199679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 67299679Siwasaki break; 67367754Smsmith 67467754Smsmith 67599679Siwasaki case AML_INT_ACCESSFIELD_OP: 67699679Siwasaki 67799679Siwasaki /* 67899679Siwasaki * Get AccessType and AccessAttrib and merge into the field Op 67999679Siwasaki * AccessType is first operand, AccessAttribute is second 68099679Siwasaki */ 681167802Sjkim Field->Common.Value.Integer = (((UINT32) ACPI_GET8 (ParserState->Aml) << 8)); 68299679Siwasaki ParserState->Aml++; 683117521Snjl Field->Common.Value.Integer |= ACPI_GET8 (ParserState->Aml); 68499679Siwasaki ParserState->Aml++; 68599679Siwasaki break; 68699679Siwasaki 68799679Siwasaki default: 688107325Siwasaki 68999679Siwasaki /* Opcode was set in previous switch */ 69099679Siwasaki break; 69167754Smsmith } 69267754Smsmith 69367754Smsmith return_PTR (Field); 69467754Smsmith} 69567754Smsmith 69667754Smsmith 69767754Smsmith/******************************************************************************* 69867754Smsmith * 69967754Smsmith * FUNCTION: AcpiPsGetNextArg 70067754Smsmith * 701151937Sjkim * PARAMETERS: WalkState - Current state 702151937Sjkim * ParserState - Current parser state object 70367754Smsmith * ArgType - The argument type (AML_*_ARG) 704151937Sjkim * ReturnArg - Where the next arg is returned 70567754Smsmith * 706102550Siwasaki * RETURN: Status, and an op object containing the next argument. 70767754Smsmith * 70867754Smsmith * DESCRIPTION: Get next argument (including complex list arguments that require 70967754Smsmith * pushing the parser stack) 71067754Smsmith * 71167754Smsmith ******************************************************************************/ 71267754Smsmith 713102550SiwasakiACPI_STATUS 71467754SmsmithAcpiPsGetNextArg ( 715107325Siwasaki ACPI_WALK_STATE *WalkState, 71667754Smsmith ACPI_PARSE_STATE *ParserState, 71767754Smsmith UINT32 ArgType, 718102550Siwasaki ACPI_PARSE_OBJECT **ReturnArg) 71967754Smsmith{ 72067754Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 72167754Smsmith ACPI_PARSE_OBJECT *Prev = NULL; 72267754Smsmith ACPI_PARSE_OBJECT *Field; 72367754Smsmith UINT32 Subop; 724102550Siwasaki ACPI_STATUS Status = AE_OK; 72567754Smsmith 72667754Smsmith 727167802Sjkim ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 72867754Smsmith 72967754Smsmith 73067754Smsmith switch (ArgType) 73167754Smsmith { 73267754Smsmith case ARGP_BYTEDATA: 73367754Smsmith case ARGP_WORDDATA: 73467754Smsmith case ARGP_DWORDDATA: 73567754Smsmith case ARGP_CHARLIST: 73667754Smsmith case ARGP_NAME: 73767754Smsmith case ARGP_NAMESTRING: 73867754Smsmith 739151937Sjkim /* Constants, strings, and namestrings are all the same size */ 74067754Smsmith 74167754Smsmith Arg = AcpiPsAllocOp (AML_BYTE_OP); 742102550Siwasaki if (!Arg) 74367754Smsmith { 744102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 74567754Smsmith } 746102550Siwasaki AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 74767754Smsmith break; 74867754Smsmith 74967754Smsmith 75067754Smsmith case ARGP_PKGLENGTH: 75167754Smsmith 752102550Siwasaki /* Package length, nothing returned */ 75367754Smsmith 75467754Smsmith ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 75567754Smsmith break; 75667754Smsmith 75767754Smsmith 75867754Smsmith case ARGP_FIELDLIST: 75967754Smsmith 76067754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 76167754Smsmith { 762102550Siwasaki /* Non-empty list */ 76367754Smsmith 76467754Smsmith while (ParserState->Aml < ParserState->PkgEnd) 76567754Smsmith { 76667754Smsmith Field = AcpiPsGetNextField (ParserState); 76767754Smsmith if (!Field) 76867754Smsmith { 769102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 77067754Smsmith } 77167754Smsmith 77267754Smsmith if (Prev) 77367754Smsmith { 77499679Siwasaki Prev->Common.Next = Field; 77567754Smsmith } 77667754Smsmith else 77767754Smsmith { 77867754Smsmith Arg = Field; 77967754Smsmith } 78067754Smsmith Prev = Field; 78167754Smsmith } 78267754Smsmith 783102550Siwasaki /* Skip to End of byte data */ 78467754Smsmith 78567754Smsmith ParserState->Aml = ParserState->PkgEnd; 78667754Smsmith } 78767754Smsmith break; 78867754Smsmith 78967754Smsmith 79067754Smsmith case ARGP_BYTELIST: 79167754Smsmith 79267754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 79367754Smsmith { 794102550Siwasaki /* Non-empty list */ 79567754Smsmith 79677424Smsmith Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); 797102550Siwasaki if (!Arg) 79867754Smsmith { 799102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 80067754Smsmith } 80167754Smsmith 802102550Siwasaki /* Fill in bytelist data */ 80367754Smsmith 804151937Sjkim Arg->Common.Value.Size = (UINT32) 805151937Sjkim ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml); 806102550Siwasaki Arg->Named.Data = ParserState->Aml; 807102550Siwasaki 808102550Siwasaki /* Skip to End of byte data */ 809102550Siwasaki 81067754Smsmith ParserState->Aml = ParserState->PkgEnd; 81167754Smsmith } 81267754Smsmith break; 81367754Smsmith 81467754Smsmith 81567754Smsmith case ARGP_TARGET: 81667754Smsmith case ARGP_SUPERNAME: 81791116Smsmith case ARGP_SIMPLENAME: 818102550Siwasaki 819102550Siwasaki Subop = AcpiPsPeekOpcode (ParserState); 820102550Siwasaki if (Subop == 0 || 821102550Siwasaki AcpiPsIsLeadingChar (Subop) || 822102550Siwasaki AcpiPsIsPrefixChar (Subop)) 82367754Smsmith { 824102550Siwasaki /* NullName or NameString */ 825102550Siwasaki 826102550Siwasaki Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 827102550Siwasaki if (!Arg) 82867754Smsmith { 829102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 83067754Smsmith } 83167754Smsmith 832193267Sjkim /* To support SuperName arg of Unload */ 833193267Sjkim 834193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 835193267Sjkim { 836193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1); 837193267Sjkim 838193267Sjkim /* 839193267Sjkim * If the SuperName arg of Unload is a method call, 840193267Sjkim * we have restored the AML pointer, just free this Arg 841193267Sjkim */ 842193267Sjkim if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) 843193267Sjkim { 844193267Sjkim AcpiPsFreeOp (Arg); 845193267Sjkim Arg = NULL; 846193267Sjkim } 847193267Sjkim } 848193267Sjkim else 849193267Sjkim { 850193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0); 851193267Sjkim } 852102550Siwasaki } 853102550Siwasaki else 854102550Siwasaki { 855151937Sjkim /* Single complex argument, nothing returned */ 85667754Smsmith 857107325Siwasaki WalkState->ArgCount = 1; 85867754Smsmith } 85967754Smsmith break; 86067754Smsmith 86167754Smsmith 86267754Smsmith case ARGP_DATAOBJ: 86367754Smsmith case ARGP_TERMARG: 86467754Smsmith 865151937Sjkim /* Single complex argument, nothing returned */ 86667754Smsmith 867107325Siwasaki WalkState->ArgCount = 1; 86867754Smsmith break; 86967754Smsmith 87067754Smsmith 87167754Smsmith case ARGP_DATAOBJLIST: 87267754Smsmith case ARGP_TERMLIST: 87367754Smsmith case ARGP_OBJLIST: 87467754Smsmith 87567754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 87667754Smsmith { 877151937Sjkim /* Non-empty list of variable arguments, nothing returned */ 87867754Smsmith 879107325Siwasaki WalkState->ArgCount = ACPI_VAR_ARGS; 88067754Smsmith } 88167754Smsmith break; 88299679Siwasaki 883102550Siwasaki 88499679Siwasaki default: 885102550Siwasaki 886204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 887102550Siwasaki Status = AE_AML_OPERAND_TYPE; 88899679Siwasaki break; 88967754Smsmith } 89067754Smsmith 891102550Siwasaki *ReturnArg = Arg; 892102550Siwasaki return_ACPI_STATUS (Status); 89367754Smsmith} 894