167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: psargs - Parse AML opcode arguments 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, 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, 290193267Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 291167802Sjkim 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 319167802Sjkim NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 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) != 362167802Sjkim 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) == 394167802Sjkim 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{ 527228110Sjkim UINT32 AmlOffset; 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 543228110Sjkim AmlOffset = (UINT32) ACPI_PTR_DIFF ( 544228110Sjkim ParserState->Aml, ParserState->AmlStart); 545228110Sjkim 546151937Sjkim /* Determine field type */ 54767754Smsmith 54891116Smsmith switch (ACPI_GET8 (ParserState->Aml)) 54967754Smsmith { 550228110Sjkim case AML_FIELD_OFFSET_OP: 55167754Smsmith 552228110Sjkim Opcode = AML_INT_RESERVEDFIELD_OP; 553228110Sjkim ParserState->Aml++; 55467754Smsmith break; 55567754Smsmith 556228110Sjkim case AML_FIELD_ACCESS_OP: 55767754Smsmith 558228110Sjkim Opcode = AML_INT_ACCESSFIELD_OP; 55967754Smsmith ParserState->Aml++; 56067754Smsmith break; 56167754Smsmith 562228110Sjkim case AML_FIELD_CONNECTION_OP: 56367754Smsmith 564228110Sjkim Opcode = AML_INT_CONNECTION_OP; 56567754Smsmith ParserState->Aml++; 56667754Smsmith break; 567228110Sjkim 568228110Sjkim case AML_FIELD_EXT_ACCESS_OP: 569228110Sjkim 570228110Sjkim Opcode = AML_INT_EXTACCESSFIELD_OP; 571228110Sjkim ParserState->Aml++; 572228110Sjkim break; 573228110Sjkim 574228110Sjkim default: 575228110Sjkim 576228110Sjkim Opcode = AML_INT_NAMEDFIELD_OP; 577228110Sjkim break; 57867754Smsmith } 57967754Smsmith 58067754Smsmith /* Allocate a new field op */ 58167754Smsmith 58267754Smsmith Field = AcpiPsAllocOp (Opcode); 58399679Siwasaki if (!Field) 58467754Smsmith { 58599679Siwasaki return_PTR (NULL); 58699679Siwasaki } 58767754Smsmith 58899679Siwasaki Field->Common.AmlOffset = AmlOffset; 58967754Smsmith 59099679Siwasaki /* Decode the field type */ 59167754Smsmith 59299679Siwasaki switch (Opcode) 59399679Siwasaki { 59499679Siwasaki case AML_INT_NAMEDFIELD_OP: 59567754Smsmith 59699679Siwasaki /* Get the 4-character name */ 59767754Smsmith 598117521Snjl ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 59999679Siwasaki AcpiPsSetName (Field, Name); 600107325Siwasaki ParserState->Aml += ACPI_NAME_SIZE; 60167754Smsmith 60299679Siwasaki /* Get the length which is encoded as a package length */ 60367754Smsmith 60499679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 60599679Siwasaki break; 60667754Smsmith 60767754Smsmith 60899679Siwasaki case AML_INT_RESERVEDFIELD_OP: 60967754Smsmith 61099679Siwasaki /* Get the length which is encoded as a package length */ 61167754Smsmith 61299679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 61399679Siwasaki break; 61467754Smsmith 61567754Smsmith 61699679Siwasaki case AML_INT_ACCESSFIELD_OP: 617228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 61899679Siwasaki 61999679Siwasaki /* 62099679Siwasaki * Get AccessType and AccessAttrib and merge into the field Op 621228110Sjkim * AccessType is first operand, AccessAttribute is second. stuff 622228110Sjkim * these bytes into the node integer value for convenience. 62399679Siwasaki */ 624228110Sjkim 625228110Sjkim /* Get the two bytes (Type/Attribute) */ 626228110Sjkim 627228110Sjkim AccessType = ACPI_GET8 (ParserState->Aml); 62899679Siwasaki ParserState->Aml++; 629228110Sjkim AccessAttribute = ACPI_GET8 (ParserState->Aml); 63099679Siwasaki ParserState->Aml++; 631228110Sjkim 632228110Sjkim Field->Common.Value.Integer = (UINT8) AccessType; 633228110Sjkim Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8); 634228110Sjkim 635228110Sjkim /* This opcode has a third byte, AccessLength */ 636228110Sjkim 637228110Sjkim if (Opcode == AML_INT_EXTACCESSFIELD_OP) 638228110Sjkim { 639228110Sjkim AccessLength = ACPI_GET8 (ParserState->Aml); 640228110Sjkim ParserState->Aml++; 641228110Sjkim 642228110Sjkim Field->Common.Value.Integer |= (UINT32) (AccessLength << 16); 643228110Sjkim } 64499679Siwasaki break; 64599679Siwasaki 646228110Sjkim 647228110Sjkim case AML_INT_CONNECTION_OP: 648228110Sjkim 649228110Sjkim /* 650228110Sjkim * Argument for Connection operator can be either a Buffer 651228110Sjkim * (resource descriptor), or a NameString. 652228110Sjkim */ 653228110Sjkim if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP) 654228110Sjkim { 655228110Sjkim ParserState->Aml++; 656228110Sjkim 657228110Sjkim PkgEnd = ParserState->Aml; 658228110Sjkim PkgLength = AcpiPsGetNextPackageLength (ParserState); 659228110Sjkim PkgEnd += PkgLength; 660228110Sjkim 661228110Sjkim if (ParserState->Aml < PkgEnd) 662228110Sjkim { 663228110Sjkim /* Non-empty list */ 664228110Sjkim 665228110Sjkim Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); 666228110Sjkim if (!Arg) 667228110Sjkim { 668233558Sjkim AcpiPsFreeOp (Field); 669228110Sjkim return_PTR (NULL); 670228110Sjkim } 671228110Sjkim 672228110Sjkim /* Get the actual buffer length argument */ 673228110Sjkim 674228110Sjkim Opcode = ACPI_GET8 (ParserState->Aml); 675228110Sjkim ParserState->Aml++; 676228110Sjkim 677228110Sjkim switch (Opcode) 678228110Sjkim { 679228110Sjkim case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 680250838Sjkim 681228110Sjkim BufferLength = ACPI_GET8 (ParserState->Aml); 682228110Sjkim ParserState->Aml += 1; 683228110Sjkim break; 684228110Sjkim 685228110Sjkim case AML_WORD_OP: /* AML_WORDDATA_ARG */ 686250838Sjkim 687228110Sjkim BufferLength = ACPI_GET16 (ParserState->Aml); 688228110Sjkim ParserState->Aml += 2; 689228110Sjkim break; 690228110Sjkim 691228110Sjkim case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 692250838Sjkim 693228110Sjkim BufferLength = ACPI_GET32 (ParserState->Aml); 694228110Sjkim ParserState->Aml += 4; 695228110Sjkim break; 696228110Sjkim 697228110Sjkim default: 698250838Sjkim 699228110Sjkim BufferLength = 0; 700228110Sjkim break; 701228110Sjkim } 702228110Sjkim 703228110Sjkim /* Fill in bytelist data */ 704228110Sjkim 705228110Sjkim Arg->Named.Value.Size = BufferLength; 706228110Sjkim Arg->Named.Data = ParserState->Aml; 707228110Sjkim } 708228110Sjkim 709228110Sjkim /* Skip to End of byte data */ 710228110Sjkim 711228110Sjkim ParserState->Aml = PkgEnd; 712228110Sjkim } 713228110Sjkim else 714228110Sjkim { 715228110Sjkim Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 716228110Sjkim if (!Arg) 717228110Sjkim { 718233558Sjkim AcpiPsFreeOp (Field); 719228110Sjkim return_PTR (NULL); 720228110Sjkim } 721228110Sjkim 722228110Sjkim /* Get the Namestring argument */ 723228110Sjkim 724228110Sjkim Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 725228110Sjkim } 726228110Sjkim 727228110Sjkim /* Link the buffer/namestring to parent (CONNECTION_OP) */ 728228110Sjkim 729228110Sjkim AcpiPsAppendArg (Field, Arg); 730228110Sjkim break; 731228110Sjkim 732228110Sjkim 73399679Siwasaki default: 734107325Siwasaki 73599679Siwasaki /* Opcode was set in previous switch */ 73699679Siwasaki break; 73767754Smsmith } 73867754Smsmith 73967754Smsmith return_PTR (Field); 74067754Smsmith} 74167754Smsmith 74267754Smsmith 74367754Smsmith/******************************************************************************* 74467754Smsmith * 74567754Smsmith * FUNCTION: AcpiPsGetNextArg 74667754Smsmith * 747151937Sjkim * PARAMETERS: WalkState - Current state 748151937Sjkim * ParserState - Current parser state object 74967754Smsmith * ArgType - The argument type (AML_*_ARG) 750151937Sjkim * ReturnArg - Where the next arg is returned 75167754Smsmith * 752102550Siwasaki * RETURN: Status, and an op object containing the next argument. 75367754Smsmith * 75467754Smsmith * DESCRIPTION: Get next argument (including complex list arguments that require 75567754Smsmith * pushing the parser stack) 75667754Smsmith * 75767754Smsmith ******************************************************************************/ 75867754Smsmith 759102550SiwasakiACPI_STATUS 76067754SmsmithAcpiPsGetNextArg ( 761107325Siwasaki ACPI_WALK_STATE *WalkState, 76267754Smsmith ACPI_PARSE_STATE *ParserState, 76367754Smsmith UINT32 ArgType, 764102550Siwasaki ACPI_PARSE_OBJECT **ReturnArg) 76567754Smsmith{ 76667754Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 76767754Smsmith ACPI_PARSE_OBJECT *Prev = NULL; 76867754Smsmith ACPI_PARSE_OBJECT *Field; 76967754Smsmith UINT32 Subop; 770102550Siwasaki ACPI_STATUS Status = AE_OK; 77167754Smsmith 77267754Smsmith 773167802Sjkim ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 77467754Smsmith 77567754Smsmith 77667754Smsmith switch (ArgType) 77767754Smsmith { 77867754Smsmith case ARGP_BYTEDATA: 77967754Smsmith case ARGP_WORDDATA: 78067754Smsmith case ARGP_DWORDDATA: 78167754Smsmith case ARGP_CHARLIST: 78267754Smsmith case ARGP_NAME: 78367754Smsmith case ARGP_NAMESTRING: 78467754Smsmith 785151937Sjkim /* Constants, strings, and namestrings are all the same size */ 78667754Smsmith 78767754Smsmith Arg = AcpiPsAllocOp (AML_BYTE_OP); 788102550Siwasaki if (!Arg) 78967754Smsmith { 790102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 79167754Smsmith } 792102550Siwasaki AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 79367754Smsmith break; 79467754Smsmith 79567754Smsmith case ARGP_PKGLENGTH: 79667754Smsmith 797102550Siwasaki /* Package length, nothing returned */ 79867754Smsmith 79967754Smsmith ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 80067754Smsmith break; 80167754Smsmith 80267754Smsmith case ARGP_FIELDLIST: 80367754Smsmith 80467754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 80567754Smsmith { 806102550Siwasaki /* Non-empty list */ 80767754Smsmith 80867754Smsmith while (ParserState->Aml < ParserState->PkgEnd) 80967754Smsmith { 81067754Smsmith Field = AcpiPsGetNextField (ParserState); 81167754Smsmith if (!Field) 81267754Smsmith { 813102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 81467754Smsmith } 81567754Smsmith 81667754Smsmith if (Prev) 81767754Smsmith { 81899679Siwasaki Prev->Common.Next = Field; 81967754Smsmith } 82067754Smsmith else 82167754Smsmith { 82267754Smsmith Arg = Field; 82367754Smsmith } 82467754Smsmith Prev = Field; 82567754Smsmith } 82667754Smsmith 827102550Siwasaki /* Skip to End of byte data */ 82867754Smsmith 82967754Smsmith ParserState->Aml = ParserState->PkgEnd; 83067754Smsmith } 83167754Smsmith break; 83267754Smsmith 83367754Smsmith case ARGP_BYTELIST: 83467754Smsmith 83567754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 83667754Smsmith { 837102550Siwasaki /* Non-empty list */ 83867754Smsmith 83977424Smsmith Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); 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: 860102550Siwasaki 861102550Siwasaki Subop = AcpiPsPeekOpcode (ParserState); 862102550Siwasaki if (Subop == 0 || 863102550Siwasaki AcpiPsIsLeadingChar (Subop) || 864245582Sjkim ACPI_IS_ROOT_PREFIX (Subop) || 865245582Sjkim ACPI_IS_PARENT_PREFIX (Subop)) 86667754Smsmith { 867102550Siwasaki /* NullName or NameString */ 868102550Siwasaki 869102550Siwasaki Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 870102550Siwasaki if (!Arg) 87167754Smsmith { 872102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 87367754Smsmith } 87467754Smsmith 875193267Sjkim /* To support SuperName arg of Unload */ 876193267Sjkim 877193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 878193267Sjkim { 879193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1); 880193267Sjkim 881193267Sjkim /* 882193267Sjkim * If the SuperName arg of Unload is a method call, 883193267Sjkim * we have restored the AML pointer, just free this Arg 884193267Sjkim */ 885193267Sjkim if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) 886193267Sjkim { 887193267Sjkim AcpiPsFreeOp (Arg); 888193267Sjkim Arg = NULL; 889193267Sjkim } 890193267Sjkim } 891193267Sjkim else 892193267Sjkim { 893193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0); 894193267Sjkim } 895102550Siwasaki } 896102550Siwasaki else 897102550Siwasaki { 898151937Sjkim /* Single complex argument, nothing returned */ 89967754Smsmith 900107325Siwasaki WalkState->ArgCount = 1; 90167754Smsmith } 90267754Smsmith break; 90367754Smsmith 90467754Smsmith case ARGP_DATAOBJ: 90567754Smsmith case ARGP_TERMARG: 90667754Smsmith 907151937Sjkim /* Single complex argument, nothing returned */ 90867754Smsmith 909107325Siwasaki WalkState->ArgCount = 1; 91067754Smsmith break; 91167754Smsmith 91267754Smsmith case ARGP_DATAOBJLIST: 91367754Smsmith case ARGP_TERMLIST: 91467754Smsmith case ARGP_OBJLIST: 91567754Smsmith 91667754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 91767754Smsmith { 918151937Sjkim /* Non-empty list of variable arguments, nothing returned */ 91967754Smsmith 920107325Siwasaki WalkState->ArgCount = ACPI_VAR_ARGS; 92167754Smsmith } 92267754Smsmith break; 92399679Siwasaki 92499679Siwasaki default: 925102550Siwasaki 926204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 927102550Siwasaki Status = AE_AML_OPERAND_TYPE; 92899679Siwasaki break; 92967754Smsmith } 93067754Smsmith 931102550Siwasaki *ReturnArg = Arg; 932102550Siwasaki return_ACPI_STATUS (Status); 93367754Smsmith} 934