167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: psargs - Parse AML opcode arguments 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 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. 2567754Smsmith * 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. 2967754Smsmith * 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 */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 49193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 5067754Smsmith 5177424Smsmith#define _COMPONENT ACPI_PARSER 5291116Smsmith ACPI_MODULE_NAME ("psargs") 5367754Smsmith 54151937Sjkim/* Local prototypes */ 5567754Smsmith 56151937Sjkimstatic UINT32 57151937SjkimAcpiPsGetNextPackageLength ( 58151937Sjkim ACPI_PARSE_STATE *ParserState); 59151937Sjkim 60151937Sjkimstatic ACPI_PARSE_OBJECT * 61151937SjkimAcpiPsGetNextField ( 62151937Sjkim ACPI_PARSE_STATE *ParserState); 63151937Sjkim 64151937Sjkim 6567754Smsmith/******************************************************************************* 6667754Smsmith * 6767754Smsmith * FUNCTION: AcpiPsGetNextPackageLength 6867754Smsmith * 6967754Smsmith * PARAMETERS: ParserState - Current parser state object 7067754Smsmith * 71167802Sjkim * RETURN: Decoded package length. On completion, the AML pointer points 7267754Smsmith * past the length byte or bytes. 7367754Smsmith * 74167802Sjkim * DESCRIPTION: Decode and return a package length field. 75167802Sjkim * Note: Largest package length is 28 bits, from ACPI specification 7667754Smsmith * 7767754Smsmith ******************************************************************************/ 7867754Smsmith 79151937Sjkimstatic UINT32 8067754SmsmithAcpiPsGetNextPackageLength ( 8167754Smsmith ACPI_PARSE_STATE *ParserState) 8267754Smsmith{ 83167802Sjkim UINT8 *Aml = ParserState->Aml; 84167802Sjkim UINT32 PackageLength = 0; 85193267Sjkim UINT32 ByteCount; 86167802Sjkim UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */ 8767754Smsmith 8867754Smsmith 89167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextPackageLength); 9067754Smsmith 9167754Smsmith 92167802Sjkim /* 93167802Sjkim * Byte 0 bits [6:7] contain the number of additional bytes 94167802Sjkim * used to encode the package length, either 0,1,2, or 3 95167802Sjkim */ 96167802Sjkim ByteCount = (Aml[0] >> 6); 97193267Sjkim ParserState->Aml += ((ACPI_SIZE) ByteCount + 1); 9867754Smsmith 99167802Sjkim /* Get bytes 3, 2, 1 as needed */ 100167802Sjkim 101167802Sjkim while (ByteCount) 10267754Smsmith { 103167802Sjkim /* 104167802Sjkim * Final bit positions for the package length bytes: 105167802Sjkim * Byte3->[20:27] 106167802Sjkim * Byte2->[12:19] 107167802Sjkim * Byte1->[04:11] 108167802Sjkim * Byte0->[00:03] 109167802Sjkim */ 110167802Sjkim PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4)); 11167754Smsmith 112167802Sjkim ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */ 113167802Sjkim ByteCount--; 114167802Sjkim } 11567754Smsmith 116167802Sjkim /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 11767754Smsmith 118167802Sjkim PackageLength |= (Aml[0] & ByteZeroMask); 119246849Sjkim return_UINT32 (PackageLength); 12067754Smsmith} 12167754Smsmith 12267754Smsmith 12367754Smsmith/******************************************************************************* 12467754Smsmith * 12567754Smsmith * FUNCTION: AcpiPsGetNextPackageEnd 12667754Smsmith * 12767754Smsmith * PARAMETERS: ParserState - Current parser state object 12867754Smsmith * 12967754Smsmith * RETURN: Pointer to end-of-package +1 13067754Smsmith * 13167754Smsmith * DESCRIPTION: Get next package length and return a pointer past the end of 132241973Sjkim * the package. Consumes the package length field 13367754Smsmith * 13467754Smsmith ******************************************************************************/ 13567754Smsmith 13667754SmsmithUINT8 * 13767754SmsmithAcpiPsGetNextPackageEnd ( 13867754Smsmith ACPI_PARSE_STATE *ParserState) 13967754Smsmith{ 14067754Smsmith UINT8 *Start = ParserState->Aml; 141167802Sjkim UINT32 PackageLength; 14267754Smsmith 14367754Smsmith 144167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextPackageEnd); 14567754Smsmith 14667754Smsmith 147167802Sjkim /* Function below updates ParserState->Aml */ 148107325Siwasaki 149167802Sjkim PackageLength = AcpiPsGetNextPackageLength (ParserState); 15067754Smsmith 151167802Sjkim return_PTR (Start + PackageLength); /* end of package */ 15267754Smsmith} 15367754Smsmith 15467754Smsmith 15567754Smsmith/******************************************************************************* 15667754Smsmith * 15767754Smsmith * FUNCTION: AcpiPsGetNextNamestring 15867754Smsmith * 15967754Smsmith * PARAMETERS: ParserState - Current parser state object 16067754Smsmith * 16167754Smsmith * RETURN: Pointer to the start of the name string (pointer points into 16267754Smsmith * the AML. 16367754Smsmith * 164241973Sjkim * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 165241973Sjkim * prefix characters. Set parser state to point past the string. 16667754Smsmith * (Name is consumed from the AML.) 16767754Smsmith * 16867754Smsmith ******************************************************************************/ 16967754Smsmith 170114237Snjlchar * 17167754SmsmithAcpiPsGetNextNamestring ( 17267754Smsmith ACPI_PARSE_STATE *ParserState) 17367754Smsmith{ 17499679Siwasaki UINT8 *Start = ParserState->Aml; 17599679Siwasaki UINT8 *End = ParserState->Aml; 17667754Smsmith 17767754Smsmith 178167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextNamestring); 17967754Smsmith 18067754Smsmith 181167802Sjkim /* Point past any namestring prefix characters (backslash or carat) */ 18267754Smsmith 183245582Sjkim while (ACPI_IS_ROOT_PREFIX (*End) || 184245582Sjkim ACPI_IS_PARENT_PREFIX (*End)) 18567754Smsmith { 18667754Smsmith End++; 18767754Smsmith } 18867754Smsmith 189167802Sjkim /* Decode the path prefix character */ 19067754Smsmith 191167802Sjkim switch (*End) 19267754Smsmith { 19367754Smsmith case 0: 19467754Smsmith 19567754Smsmith /* NullName */ 19667754Smsmith 19767754Smsmith if (End == Start) 19867754Smsmith { 19967754Smsmith Start = NULL; 20067754Smsmith } 20167754Smsmith End++; 20267754Smsmith break; 20367754Smsmith 20467754Smsmith case AML_DUAL_NAME_PREFIX: 20567754Smsmith 20699679Siwasaki /* Two name segments */ 20767754Smsmith 208107325Siwasaki End += 1 + (2 * ACPI_NAME_SIZE); 20967754Smsmith break; 21067754Smsmith 21167754Smsmith case AML_MULTI_NAME_PREFIX_OP: 21267754Smsmith 213167802Sjkim /* Multiple name segments, 4 chars each, count in next byte */ 21467754Smsmith 215167802Sjkim End += 2 + (*(End + 1) * ACPI_NAME_SIZE); 21667754Smsmith break; 21767754Smsmith 21867754Smsmith default: 21967754Smsmith 22099679Siwasaki /* Single name segment */ 22167754Smsmith 222107325Siwasaki End += ACPI_NAME_SIZE; 22367754Smsmith break; 22467754Smsmith } 22567754Smsmith 226167802Sjkim ParserState->Aml = End; 227114237Snjl return_PTR ((char *) Start); 22867754Smsmith} 22967754Smsmith 23067754Smsmith 23167754Smsmith/******************************************************************************* 23267754Smsmith * 23367754Smsmith * FUNCTION: AcpiPsGetNextNamepath 23467754Smsmith * 23567754Smsmith * PARAMETERS: ParserState - Current parser state object 23667754Smsmith * Arg - Where the namepath will be stored 23767754Smsmith * ArgCount - If the namepath points to a control method 23867754Smsmith * the method's argument is returned here. 239167802Sjkim * PossibleMethodCall - Whether the namepath can possibly be the 240107325Siwasaki * start of a method call 24167754Smsmith * 242102550Siwasaki * RETURN: Status 24367754Smsmith * 244102550Siwasaki * DESCRIPTION: Get next name (if method call, return # of required args). 245102550Siwasaki * Names are looked up in the internal namespace to determine 246241973Sjkim * if the name represents a control method. If a method 24767754Smsmith * is found, the number of arguments to the method is returned. 24867754Smsmith * This information is critical for parsing to continue correctly. 24967754Smsmith * 25067754Smsmith ******************************************************************************/ 25167754Smsmith 252102550SiwasakiACPI_STATUS 25367754SmsmithAcpiPsGetNextNamepath ( 254107325Siwasaki ACPI_WALK_STATE *WalkState, 25567754Smsmith ACPI_PARSE_STATE *ParserState, 25667754Smsmith ACPI_PARSE_OBJECT *Arg, 257167802Sjkim BOOLEAN PossibleMethodCall) 25867754Smsmith{ 259193267Sjkim ACPI_STATUS Status; 260114237Snjl char *Path; 26167754Smsmith ACPI_PARSE_OBJECT *NameOp; 262102550Siwasaki ACPI_OPERAND_OBJECT *MethodDesc; 263102550Siwasaki ACPI_NAMESPACE_NODE *Node; 264193267Sjkim UINT8 *Start = ParserState->Aml; 26567754Smsmith 26667754Smsmith 267167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextNamepath); 26867754Smsmith 26967754Smsmith 27067754Smsmith Path = AcpiPsGetNextNamestring (ParserState); 271167802Sjkim AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 27267754Smsmith 273167802Sjkim /* Null path case is allowed, just exit */ 27467754Smsmith 275167802Sjkim if (!Path) 27667754Smsmith { 277167802Sjkim Arg->Common.Value.Name = Path; 278167802Sjkim return_ACPI_STATUS (AE_OK); 279167802Sjkim } 280167802Sjkim 281167802Sjkim /* 282193267Sjkim * Lookup the name in the internal namespace, starting with the current 283193267Sjkim * scope. We don't want to add anything new to the namespace here, 284193267Sjkim * however, so we use MODE_EXECUTE. 285167802Sjkim * Allow searching of the parent tree, but don't open a new scope - 286167802Sjkim * we just want to lookup the object (must be mode EXECUTE to perform 287167802Sjkim * the upsearch) 288167802Sjkim */ 289193267Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 290306536Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 291306536Sjkim ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 292167802Sjkim 293167802Sjkim /* 294167802Sjkim * If this name is a control method invocation, we must 295167802Sjkim * setup the method call 296167802Sjkim */ 297167802Sjkim if (ACPI_SUCCESS (Status) && 298167802Sjkim PossibleMethodCall && 299167802Sjkim (Node->Type == ACPI_TYPE_METHOD)) 300167802Sjkim { 301193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 302193267Sjkim { 303193267Sjkim /* 304193267Sjkim * AcpiPsGetNextNamestring has increased the AML pointer, 305193267Sjkim * so we need to restore the saved AML pointer for method call. 306193267Sjkim */ 307193267Sjkim WalkState->ParserState.Aml = Start; 308193267Sjkim WalkState->ArgCount = 1; 309193267Sjkim AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 310193267Sjkim return_ACPI_STATUS (AE_OK); 311193267Sjkim } 312193267Sjkim 313167802Sjkim /* This name is actually a control method invocation */ 314167802Sjkim 315167802Sjkim MethodDesc = AcpiNsGetAttachedObject (Node); 316167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 317167802Sjkim "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path)); 318167802Sjkim 319306536Sjkim NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start); 320167802Sjkim if (!NameOp) 32167754Smsmith { 322167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 32367754Smsmith } 32467754Smsmith 325167802Sjkim /* Change Arg into a METHOD CALL and attach name to it */ 326151937Sjkim 327167802Sjkim AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 328167802Sjkim NameOp->Common.Value.Name = Path; 329102550Siwasaki 330167802Sjkim /* Point METHODCALL/NAME to the METHOD Node */ 33167754Smsmith 332167802Sjkim NameOp->Common.Node = Node; 333167802Sjkim AcpiPsAppendArg (Arg, NameOp); 33467754Smsmith 335167802Sjkim if (!MethodDesc) 336167802Sjkim { 337167802Sjkim ACPI_ERROR ((AE_INFO, 338167802Sjkim "Control Method %p has no attached object", 339167802Sjkim Node)); 340167802Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 341167802Sjkim } 34267754Smsmith 343167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 344167802Sjkim "Control Method - %p Args %X\n", 345167802Sjkim Node, MethodDesc->Method.ParamCount)); 34667754Smsmith 347167802Sjkim /* Get the number of arguments to expect */ 348102550Siwasaki 349167802Sjkim WalkState->ArgCount = MethodDesc->Method.ParamCount; 350167802Sjkim return_ACPI_STATUS (AE_OK); 351167802Sjkim } 35267754Smsmith 353167802Sjkim /* 354167802Sjkim * Special handling if the name was not found during the lookup - 355167802Sjkim * some NotFound cases are allowed 356167802Sjkim */ 357167802Sjkim if (Status == AE_NOT_FOUND) 358167802Sjkim { 359167802Sjkim /* 1) NotFound is ok during load pass 1/2 (allow forward references) */ 360102550Siwasaki 361167802Sjkim if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) != 362306536Sjkim ACPI_PARSE_EXECUTE) 363167802Sjkim { 364167802Sjkim Status = AE_OK; 365167802Sjkim } 366107325Siwasaki 367167802Sjkim /* 2) NotFound during a CondRefOf(x) is ok by definition */ 36867754Smsmith 369167802Sjkim else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP) 370167802Sjkim { 371167802Sjkim Status = AE_OK; 37267754Smsmith } 373107325Siwasaki 374167802Sjkim /* 375167802Sjkim * 3) NotFound while building a Package is ok at this point, we 376167802Sjkim * may flag as an error later if slack mode is not enabled. 377167802Sjkim * (Some ASL code depends on allowing this behavior) 378167802Sjkim */ 379167802Sjkim else if ((Arg->Common.Parent) && 380167802Sjkim ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 381167802Sjkim (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 382107325Siwasaki { 383167802Sjkim Status = AE_OK; 384167802Sjkim } 385167802Sjkim } 386107325Siwasaki 387167802Sjkim /* Final exception check (may have been changed from code above) */ 388117521Snjl 389167802Sjkim if (ACPI_FAILURE (Status)) 390167802Sjkim { 391167802Sjkim ACPI_ERROR_NAMESPACE (Path, Status); 392117521Snjl 393167802Sjkim if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == 394306536Sjkim ACPI_PARSE_EXECUTE) 395167802Sjkim { 396167802Sjkim /* Report a control method execution error */ 397117521Snjl 398167802Sjkim Status = AcpiDsMethodError (Status, WalkState); 399107325Siwasaki } 40067754Smsmith } 40167754Smsmith 402167802Sjkim /* Save the namepath */ 403167802Sjkim 40499679Siwasaki Arg->Common.Value.Name = Path; 405102550Siwasaki return_ACPI_STATUS (Status); 40667754Smsmith} 40767754Smsmith 40867754Smsmith 40967754Smsmith/******************************************************************************* 41067754Smsmith * 41167754Smsmith * FUNCTION: AcpiPsGetNextSimpleArg 41267754Smsmith * 41367754Smsmith * PARAMETERS: ParserState - Current parser state object 41467754Smsmith * ArgType - The argument type (AML_*_ARG) 41567754Smsmith * Arg - Where the argument is returned 41667754Smsmith * 41767754Smsmith * RETURN: None 41867754Smsmith * 41967754Smsmith * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 42067754Smsmith * 42167754Smsmith ******************************************************************************/ 42267754Smsmith 42367754Smsmithvoid 42467754SmsmithAcpiPsGetNextSimpleArg ( 42567754Smsmith ACPI_PARSE_STATE *ParserState, 42667754Smsmith UINT32 ArgType, 42767754Smsmith ACPI_PARSE_OBJECT *Arg) 42867754Smsmith{ 429167802Sjkim UINT32 Length; 430167802Sjkim UINT16 Opcode; 431167802Sjkim UINT8 *Aml = ParserState->Aml; 43267754Smsmith 43367754Smsmith 434167802Sjkim ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType); 43567754Smsmith 436167802Sjkim 43767754Smsmith switch (ArgType) 43867754Smsmith { 43967754Smsmith case ARGP_BYTEDATA: 44067754Smsmith 441167802Sjkim /* Get 1 byte from the AML stream */ 442167802Sjkim 443167802Sjkim Opcode = AML_BYTE_OP; 444202771Sjkim Arg->Common.Value.Integer = (UINT64) *Aml; 445167802Sjkim Length = 1; 44667754Smsmith break; 44767754Smsmith 44867754Smsmith case ARGP_WORDDATA: 44967754Smsmith 45067754Smsmith /* Get 2 bytes from the AML stream */ 45167754Smsmith 452167802Sjkim Opcode = AML_WORD_OP; 453167802Sjkim ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); 454167802Sjkim Length = 2; 45567754Smsmith break; 45667754Smsmith 45767754Smsmith case ARGP_DWORDDATA: 45867754Smsmith 45967754Smsmith /* Get 4 bytes from the AML stream */ 46067754Smsmith 461167802Sjkim Opcode = AML_DWORD_OP; 462167802Sjkim ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); 463167802Sjkim Length = 4; 46467754Smsmith break; 46567754Smsmith 46682367Smsmith case ARGP_QWORDDATA: 46782367Smsmith 46882367Smsmith /* Get 8 bytes from the AML stream */ 46982367Smsmith 470167802Sjkim Opcode = AML_QWORD_OP; 471167802Sjkim ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); 472167802Sjkim Length = 8; 47382367Smsmith break; 47482367Smsmith 47567754Smsmith case ARGP_CHARLIST: 47667754Smsmith 477167802Sjkim /* Get a pointer to the string, point past the string */ 47867754Smsmith 479167802Sjkim Opcode = AML_STRING_OP; 480167802Sjkim Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); 481167802Sjkim 482167802Sjkim /* Find the null terminator */ 483167802Sjkim 484167802Sjkim Length = 0; 485167802Sjkim while (Aml[Length]) 48667754Smsmith { 487167802Sjkim Length++; 48867754Smsmith } 489167802Sjkim Length++; 49067754Smsmith break; 49167754Smsmith 49267754Smsmith case ARGP_NAME: 49367754Smsmith case ARGP_NAMESTRING: 49467754Smsmith 49577424Smsmith AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 49699679Siwasaki Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 497167802Sjkim return_VOID; 49899679Siwasaki 49999679Siwasaki default: 500107325Siwasaki 501204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType)); 502167802Sjkim return_VOID; 50367754Smsmith } 50467754Smsmith 505167802Sjkim AcpiPsInitOp (Arg, Opcode); 506167802Sjkim ParserState->Aml += Length; 50767754Smsmith return_VOID; 50867754Smsmith} 50967754Smsmith 51067754Smsmith 51167754Smsmith/******************************************************************************* 51267754Smsmith * 51367754Smsmith * FUNCTION: AcpiPsGetNextField 51467754Smsmith * 51567754Smsmith * PARAMETERS: ParserState - Current parser state object 51667754Smsmith * 51767754Smsmith * RETURN: A newly allocated FIELD op 51867754Smsmith * 51967754Smsmith * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField) 52067754Smsmith * 52167754Smsmith ******************************************************************************/ 52267754Smsmith 523151937Sjkimstatic ACPI_PARSE_OBJECT * 52467754SmsmithAcpiPsGetNextField ( 52567754Smsmith ACPI_PARSE_STATE *ParserState) 52667754Smsmith{ 527306536Sjkim UINT8 *Aml; 52867754Smsmith ACPI_PARSE_OBJECT *Field; 529228110Sjkim ACPI_PARSE_OBJECT *Arg = NULL; 53067754Smsmith UINT16 Opcode; 53167754Smsmith UINT32 Name; 532228110Sjkim UINT8 AccessType; 533228110Sjkim UINT8 AccessAttribute; 534228110Sjkim UINT8 AccessLength; 535228110Sjkim UINT32 PkgLength; 536228110Sjkim UINT8 *PkgEnd; 537228110Sjkim UINT32 BufferLength; 53867754Smsmith 53967754Smsmith 540167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextField); 54167754Smsmith 54267754Smsmith 543306536Sjkim Aml = ParserState->Aml; 544228110Sjkim 545151937Sjkim /* Determine field type */ 54667754Smsmith 54791116Smsmith switch (ACPI_GET8 (ParserState->Aml)) 54867754Smsmith { 549228110Sjkim case AML_FIELD_OFFSET_OP: 55067754Smsmith 551228110Sjkim Opcode = AML_INT_RESERVEDFIELD_OP; 552228110Sjkim ParserState->Aml++; 55367754Smsmith break; 55467754Smsmith 555228110Sjkim case AML_FIELD_ACCESS_OP: 55667754Smsmith 557228110Sjkim Opcode = AML_INT_ACCESSFIELD_OP; 55867754Smsmith ParserState->Aml++; 55967754Smsmith break; 56067754Smsmith 561228110Sjkim case AML_FIELD_CONNECTION_OP: 56267754Smsmith 563228110Sjkim Opcode = AML_INT_CONNECTION_OP; 56467754Smsmith ParserState->Aml++; 56567754Smsmith break; 566228110Sjkim 567228110Sjkim case AML_FIELD_EXT_ACCESS_OP: 568228110Sjkim 569228110Sjkim Opcode = AML_INT_EXTACCESSFIELD_OP; 570228110Sjkim ParserState->Aml++; 571228110Sjkim break; 572228110Sjkim 573228110Sjkim default: 574228110Sjkim 575228110Sjkim Opcode = AML_INT_NAMEDFIELD_OP; 576228110Sjkim break; 57767754Smsmith } 57867754Smsmith 57967754Smsmith /* Allocate a new field op */ 58067754Smsmith 581306536Sjkim Field = AcpiPsAllocOp (Opcode, Aml); 58299679Siwasaki if (!Field) 58367754Smsmith { 58499679Siwasaki return_PTR (NULL); 58599679Siwasaki } 58667754Smsmith 58799679Siwasaki /* Decode the field type */ 58867754Smsmith 58999679Siwasaki switch (Opcode) 59099679Siwasaki { 59199679Siwasaki case AML_INT_NAMEDFIELD_OP: 59267754Smsmith 59399679Siwasaki /* Get the 4-character name */ 59467754Smsmith 595117521Snjl ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 59699679Siwasaki AcpiPsSetName (Field, Name); 597107325Siwasaki ParserState->Aml += ACPI_NAME_SIZE; 59867754Smsmith 59999679Siwasaki /* Get the length which is encoded as a package length */ 60067754Smsmith 60199679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 60299679Siwasaki break; 60367754Smsmith 60467754Smsmith 60599679Siwasaki case AML_INT_RESERVEDFIELD_OP: 60667754Smsmith 60799679Siwasaki /* Get the length which is encoded as a package length */ 60867754Smsmith 60999679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 61099679Siwasaki break; 61167754Smsmith 61267754Smsmith 61399679Siwasaki case AML_INT_ACCESSFIELD_OP: 614228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 61599679Siwasaki 61699679Siwasaki /* 61799679Siwasaki * Get AccessType and AccessAttrib and merge into the field Op 618228110Sjkim * AccessType is first operand, AccessAttribute is second. stuff 619228110Sjkim * these bytes into the node integer value for convenience. 62099679Siwasaki */ 621228110Sjkim 622228110Sjkim /* Get the two bytes (Type/Attribute) */ 623228110Sjkim 624228110Sjkim AccessType = ACPI_GET8 (ParserState->Aml); 62599679Siwasaki ParserState->Aml++; 626228110Sjkim AccessAttribute = ACPI_GET8 (ParserState->Aml); 62799679Siwasaki ParserState->Aml++; 628228110Sjkim 629228110Sjkim Field->Common.Value.Integer = (UINT8) AccessType; 630228110Sjkim Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8); 631228110Sjkim 632228110Sjkim /* This opcode has a third byte, AccessLength */ 633228110Sjkim 634228110Sjkim if (Opcode == AML_INT_EXTACCESSFIELD_OP) 635228110Sjkim { 636228110Sjkim AccessLength = ACPI_GET8 (ParserState->Aml); 637228110Sjkim ParserState->Aml++; 638228110Sjkim 639228110Sjkim Field->Common.Value.Integer |= (UINT32) (AccessLength << 16); 640228110Sjkim } 64199679Siwasaki break; 64299679Siwasaki 643228110Sjkim 644228110Sjkim case AML_INT_CONNECTION_OP: 645228110Sjkim 646228110Sjkim /* 647228110Sjkim * Argument for Connection operator can be either a Buffer 648228110Sjkim * (resource descriptor), or a NameString. 649228110Sjkim */ 650306536Sjkim Aml = ParserState->Aml; 651228110Sjkim if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP) 652228110Sjkim { 653228110Sjkim ParserState->Aml++; 654228110Sjkim 655228110Sjkim PkgEnd = ParserState->Aml; 656228110Sjkim PkgLength = AcpiPsGetNextPackageLength (ParserState); 657228110Sjkim PkgEnd += PkgLength; 658228110Sjkim 659228110Sjkim if (ParserState->Aml < PkgEnd) 660228110Sjkim { 661228110Sjkim /* Non-empty list */ 662228110Sjkim 663306536Sjkim Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml); 664228110Sjkim if (!Arg) 665228110Sjkim { 666233558Sjkim AcpiPsFreeOp (Field); 667228110Sjkim return_PTR (NULL); 668228110Sjkim } 669228110Sjkim 670228110Sjkim /* Get the actual buffer length argument */ 671228110Sjkim 672228110Sjkim Opcode = ACPI_GET8 (ParserState->Aml); 673228110Sjkim ParserState->Aml++; 674228110Sjkim 675228110Sjkim switch (Opcode) 676228110Sjkim { 677228110Sjkim case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 678250838Sjkim 679228110Sjkim BufferLength = ACPI_GET8 (ParserState->Aml); 680228110Sjkim ParserState->Aml += 1; 681228110Sjkim break; 682228110Sjkim 683228110Sjkim case AML_WORD_OP: /* AML_WORDDATA_ARG */ 684250838Sjkim 685228110Sjkim BufferLength = ACPI_GET16 (ParserState->Aml); 686228110Sjkim ParserState->Aml += 2; 687228110Sjkim break; 688228110Sjkim 689228110Sjkim case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 690250838Sjkim 691228110Sjkim BufferLength = ACPI_GET32 (ParserState->Aml); 692228110Sjkim ParserState->Aml += 4; 693228110Sjkim break; 694228110Sjkim 695228110Sjkim default: 696250838Sjkim 697228110Sjkim BufferLength = 0; 698228110Sjkim break; 699228110Sjkim } 700228110Sjkim 701228110Sjkim /* Fill in bytelist data */ 702228110Sjkim 703228110Sjkim Arg->Named.Value.Size = BufferLength; 704228110Sjkim Arg->Named.Data = ParserState->Aml; 705228110Sjkim } 706228110Sjkim 707228110Sjkim /* Skip to End of byte data */ 708228110Sjkim 709228110Sjkim ParserState->Aml = PkgEnd; 710228110Sjkim } 711228110Sjkim else 712228110Sjkim { 713306536Sjkim Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml); 714228110Sjkim if (!Arg) 715228110Sjkim { 716233558Sjkim AcpiPsFreeOp (Field); 717228110Sjkim return_PTR (NULL); 718228110Sjkim } 719228110Sjkim 720228110Sjkim /* Get the Namestring argument */ 721228110Sjkim 722228110Sjkim Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 723228110Sjkim } 724228110Sjkim 725228110Sjkim /* Link the buffer/namestring to parent (CONNECTION_OP) */ 726228110Sjkim 727228110Sjkim AcpiPsAppendArg (Field, Arg); 728228110Sjkim break; 729228110Sjkim 730228110Sjkim 73199679Siwasaki default: 732107325Siwasaki 73399679Siwasaki /* Opcode was set in previous switch */ 73499679Siwasaki break; 73567754Smsmith } 73667754Smsmith 73767754Smsmith return_PTR (Field); 73867754Smsmith} 73967754Smsmith 74067754Smsmith 74167754Smsmith/******************************************************************************* 74267754Smsmith * 74367754Smsmith * FUNCTION: AcpiPsGetNextArg 74467754Smsmith * 745151937Sjkim * PARAMETERS: WalkState - Current state 746151937Sjkim * ParserState - Current parser state object 74767754Smsmith * ArgType - The argument type (AML_*_ARG) 748151937Sjkim * ReturnArg - Where the next arg is returned 74967754Smsmith * 750102550Siwasaki * RETURN: Status, and an op object containing the next argument. 75167754Smsmith * 75267754Smsmith * DESCRIPTION: Get next argument (including complex list arguments that require 75367754Smsmith * pushing the parser stack) 75467754Smsmith * 75567754Smsmith ******************************************************************************/ 75667754Smsmith 757102550SiwasakiACPI_STATUS 75867754SmsmithAcpiPsGetNextArg ( 759107325Siwasaki ACPI_WALK_STATE *WalkState, 76067754Smsmith ACPI_PARSE_STATE *ParserState, 76167754Smsmith UINT32 ArgType, 762102550Siwasaki ACPI_PARSE_OBJECT **ReturnArg) 76367754Smsmith{ 76467754Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 76567754Smsmith ACPI_PARSE_OBJECT *Prev = NULL; 76667754Smsmith ACPI_PARSE_OBJECT *Field; 76767754Smsmith UINT32 Subop; 768102550Siwasaki ACPI_STATUS Status = AE_OK; 76967754Smsmith 77067754Smsmith 771167802Sjkim ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 77267754Smsmith 77367754Smsmith 77467754Smsmith switch (ArgType) 77567754Smsmith { 77667754Smsmith case ARGP_BYTEDATA: 77767754Smsmith case ARGP_WORDDATA: 77867754Smsmith case ARGP_DWORDDATA: 77967754Smsmith case ARGP_CHARLIST: 78067754Smsmith case ARGP_NAME: 78167754Smsmith case ARGP_NAMESTRING: 78267754Smsmith 783151937Sjkim /* Constants, strings, and namestrings are all the same size */ 78467754Smsmith 785306536Sjkim Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml); 786102550Siwasaki if (!Arg) 78767754Smsmith { 788102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 78967754Smsmith } 790306536Sjkim 791102550Siwasaki AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 79267754Smsmith break; 79367754Smsmith 79467754Smsmith case ARGP_PKGLENGTH: 79567754Smsmith 796102550Siwasaki /* Package length, nothing returned */ 79767754Smsmith 79867754Smsmith ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 79967754Smsmith break; 80067754Smsmith 80167754Smsmith case ARGP_FIELDLIST: 80267754Smsmith 80367754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 80467754Smsmith { 805102550Siwasaki /* Non-empty list */ 80667754Smsmith 80767754Smsmith while (ParserState->Aml < ParserState->PkgEnd) 80867754Smsmith { 80967754Smsmith Field = AcpiPsGetNextField (ParserState); 81067754Smsmith if (!Field) 81167754Smsmith { 812102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 81367754Smsmith } 81467754Smsmith 81567754Smsmith if (Prev) 81667754Smsmith { 81799679Siwasaki Prev->Common.Next = Field; 81867754Smsmith } 81967754Smsmith else 82067754Smsmith { 82167754Smsmith Arg = Field; 82267754Smsmith } 82367754Smsmith Prev = Field; 82467754Smsmith } 82567754Smsmith 826102550Siwasaki /* Skip to End of byte data */ 82767754Smsmith 82867754Smsmith ParserState->Aml = ParserState->PkgEnd; 82967754Smsmith } 83067754Smsmith break; 83167754Smsmith 83267754Smsmith case ARGP_BYTELIST: 83367754Smsmith 83467754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 83567754Smsmith { 836102550Siwasaki /* Non-empty list */ 83767754Smsmith 838306536Sjkim Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, 839306536Sjkim ParserState->Aml); 840102550Siwasaki if (!Arg) 84167754Smsmith { 842102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 84367754Smsmith } 84467754Smsmith 845102550Siwasaki /* Fill in bytelist data */ 84667754Smsmith 847151937Sjkim Arg->Common.Value.Size = (UINT32) 848151937Sjkim ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml); 849102550Siwasaki Arg->Named.Data = ParserState->Aml; 850102550Siwasaki 851102550Siwasaki /* Skip to End of byte data */ 852102550Siwasaki 85367754Smsmith ParserState->Aml = ParserState->PkgEnd; 85467754Smsmith } 85567754Smsmith break; 85667754Smsmith 85767754Smsmith case ARGP_TARGET: 85867754Smsmith case ARGP_SUPERNAME: 85991116Smsmith case ARGP_SIMPLENAME: 860306536Sjkim case ARGP_NAME_OR_REF: 861102550Siwasaki 862102550Siwasaki Subop = AcpiPsPeekOpcode (ParserState); 863102550Siwasaki if (Subop == 0 || 864102550Siwasaki AcpiPsIsLeadingChar (Subop) || 865245582Sjkim ACPI_IS_ROOT_PREFIX (Subop) || 866245582Sjkim ACPI_IS_PARENT_PREFIX (Subop)) 86767754Smsmith { 868102550Siwasaki /* NullName or NameString */ 869102550Siwasaki 870306536Sjkim Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml); 871102550Siwasaki if (!Arg) 87267754Smsmith { 873102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 87467754Smsmith } 87567754Smsmith 876193267Sjkim /* To support SuperName arg of Unload */ 877193267Sjkim 878193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 879193267Sjkim { 880306536Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, 881306536Sjkim Arg, ACPI_POSSIBLE_METHOD_CALL); 882193267Sjkim 883193267Sjkim /* 884306536Sjkim * If the SuperName argument is a method call, we have 885306536Sjkim * already restored the AML pointer, just free this Arg 886193267Sjkim */ 887193267Sjkim if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) 888193267Sjkim { 889193267Sjkim AcpiPsFreeOp (Arg); 890193267Sjkim Arg = NULL; 891193267Sjkim } 892193267Sjkim } 893193267Sjkim else 894193267Sjkim { 895306536Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, 896306536Sjkim Arg, ACPI_NOT_METHOD_CALL); 897193267Sjkim } 898102550Siwasaki } 899102550Siwasaki else 900102550Siwasaki { 901151937Sjkim /* Single complex argument, nothing returned */ 90267754Smsmith 903107325Siwasaki WalkState->ArgCount = 1; 90467754Smsmith } 90567754Smsmith break; 90667754Smsmith 90767754Smsmith case ARGP_DATAOBJ: 90867754Smsmith case ARGP_TERMARG: 90967754Smsmith 910151937Sjkim /* Single complex argument, nothing returned */ 91167754Smsmith 912107325Siwasaki WalkState->ArgCount = 1; 91367754Smsmith break; 91467754Smsmith 91567754Smsmith case ARGP_DATAOBJLIST: 91667754Smsmith case ARGP_TERMLIST: 91767754Smsmith case ARGP_OBJLIST: 91867754Smsmith 91967754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 92067754Smsmith { 921151937Sjkim /* Non-empty list of variable arguments, nothing returned */ 92267754Smsmith 923107325Siwasaki WalkState->ArgCount = ACPI_VAR_ARGS; 92467754Smsmith } 92567754Smsmith break; 92699679Siwasaki 92799679Siwasaki default: 928102550Siwasaki 929204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 930102550Siwasaki Status = AE_AML_OPERAND_TYPE; 93199679Siwasaki break; 93267754Smsmith } 93367754Smsmith 934102550Siwasaki *ReturnArg = Arg; 935102550Siwasaki return_ACPI_STATUS (Status); 93667754Smsmith} 937