167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: psargs - Parse AML opcode arguments 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, 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 4467754Smsmith#define __PSARGS_C__ 4567754Smsmith 46193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 47193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 48193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 49193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 50193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 51193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 5267754Smsmith 5377424Smsmith#define _COMPONENT ACPI_PARSER 5491116Smsmith ACPI_MODULE_NAME ("psargs") 5567754Smsmith 56151937Sjkim/* Local prototypes */ 5767754Smsmith 58151937Sjkimstatic UINT32 59151937SjkimAcpiPsGetNextPackageLength ( 60151937Sjkim ACPI_PARSE_STATE *ParserState); 61151937Sjkim 62151937Sjkimstatic ACPI_PARSE_OBJECT * 63151937SjkimAcpiPsGetNextField ( 64151937Sjkim ACPI_PARSE_STATE *ParserState); 65151937Sjkim 66151937Sjkim 6767754Smsmith/******************************************************************************* 6867754Smsmith * 6967754Smsmith * FUNCTION: AcpiPsGetNextPackageLength 7067754Smsmith * 7167754Smsmith * PARAMETERS: ParserState - Current parser state object 7267754Smsmith * 73167802Sjkim * RETURN: Decoded package length. On completion, the AML pointer points 7467754Smsmith * past the length byte or bytes. 7567754Smsmith * 76167802Sjkim * DESCRIPTION: Decode and return a package length field. 77167802Sjkim * Note: Largest package length is 28 bits, from ACPI specification 7867754Smsmith * 7967754Smsmith ******************************************************************************/ 8067754Smsmith 81151937Sjkimstatic UINT32 8267754SmsmithAcpiPsGetNextPackageLength ( 8367754Smsmith ACPI_PARSE_STATE *ParserState) 8467754Smsmith{ 85167802Sjkim UINT8 *Aml = ParserState->Aml; 86167802Sjkim UINT32 PackageLength = 0; 87193267Sjkim UINT32 ByteCount; 88167802Sjkim UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */ 8967754Smsmith 9067754Smsmith 91167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextPackageLength); 9267754Smsmith 9367754Smsmith 94167802Sjkim /* 95167802Sjkim * Byte 0 bits [6:7] contain the number of additional bytes 96167802Sjkim * used to encode the package length, either 0,1,2, or 3 97167802Sjkim */ 98167802Sjkim ByteCount = (Aml[0] >> 6); 99193267Sjkim ParserState->Aml += ((ACPI_SIZE) ByteCount + 1); 10067754Smsmith 101167802Sjkim /* Get bytes 3, 2, 1 as needed */ 102167802Sjkim 103167802Sjkim while (ByteCount) 10467754Smsmith { 105167802Sjkim /* 106167802Sjkim * Final bit positions for the package length bytes: 107167802Sjkim * Byte3->[20:27] 108167802Sjkim * Byte2->[12:19] 109167802Sjkim * Byte1->[04:11] 110167802Sjkim * Byte0->[00:03] 111167802Sjkim */ 112167802Sjkim PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4)); 11367754Smsmith 114167802Sjkim ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */ 115167802Sjkim ByteCount--; 116167802Sjkim } 11767754Smsmith 118167802Sjkim /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 11967754Smsmith 120167802Sjkim PackageLength |= (Aml[0] & ByteZeroMask); 121246849Sjkim return_UINT32 (PackageLength); 12267754Smsmith} 12367754Smsmith 12467754Smsmith 12567754Smsmith/******************************************************************************* 12667754Smsmith * 12767754Smsmith * FUNCTION: AcpiPsGetNextPackageEnd 12867754Smsmith * 12967754Smsmith * PARAMETERS: ParserState - Current parser state object 13067754Smsmith * 13167754Smsmith * RETURN: Pointer to end-of-package +1 13267754Smsmith * 13367754Smsmith * DESCRIPTION: Get next package length and return a pointer past the end of 134241973Sjkim * the package. Consumes the package length field 13567754Smsmith * 13667754Smsmith ******************************************************************************/ 13767754Smsmith 13867754SmsmithUINT8 * 13967754SmsmithAcpiPsGetNextPackageEnd ( 14067754Smsmith ACPI_PARSE_STATE *ParserState) 14167754Smsmith{ 14267754Smsmith UINT8 *Start = ParserState->Aml; 143167802Sjkim UINT32 PackageLength; 14467754Smsmith 14567754Smsmith 146167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextPackageEnd); 14767754Smsmith 14867754Smsmith 149167802Sjkim /* Function below updates ParserState->Aml */ 150107325Siwasaki 151167802Sjkim PackageLength = AcpiPsGetNextPackageLength (ParserState); 15267754Smsmith 153167802Sjkim return_PTR (Start + PackageLength); /* end of package */ 15467754Smsmith} 15567754Smsmith 15667754Smsmith 15767754Smsmith/******************************************************************************* 15867754Smsmith * 15967754Smsmith * FUNCTION: AcpiPsGetNextNamestring 16067754Smsmith * 16167754Smsmith * PARAMETERS: ParserState - Current parser state object 16267754Smsmith * 16367754Smsmith * RETURN: Pointer to the start of the name string (pointer points into 16467754Smsmith * the AML. 16567754Smsmith * 166241973Sjkim * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 167241973Sjkim * prefix characters. Set parser state to point past the string. 16867754Smsmith * (Name is consumed from the AML.) 16967754Smsmith * 17067754Smsmith ******************************************************************************/ 17167754Smsmith 172114237Snjlchar * 17367754SmsmithAcpiPsGetNextNamestring ( 17467754Smsmith ACPI_PARSE_STATE *ParserState) 17567754Smsmith{ 17699679Siwasaki UINT8 *Start = ParserState->Aml; 17799679Siwasaki UINT8 *End = ParserState->Aml; 17867754Smsmith 17967754Smsmith 180167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextNamestring); 18167754Smsmith 18267754Smsmith 183167802Sjkim /* Point past any namestring prefix characters (backslash or carat) */ 18467754Smsmith 185245582Sjkim while (ACPI_IS_ROOT_PREFIX (*End) || 186245582Sjkim ACPI_IS_PARENT_PREFIX (*End)) 18767754Smsmith { 18867754Smsmith End++; 18967754Smsmith } 19067754Smsmith 191167802Sjkim /* Decode the path prefix character */ 19267754Smsmith 193167802Sjkim switch (*End) 19467754Smsmith { 19567754Smsmith case 0: 19667754Smsmith 19767754Smsmith /* NullName */ 19867754Smsmith 19967754Smsmith if (End == Start) 20067754Smsmith { 20167754Smsmith Start = NULL; 20267754Smsmith } 20367754Smsmith End++; 20467754Smsmith break; 20567754Smsmith 20667754Smsmith case AML_DUAL_NAME_PREFIX: 20767754Smsmith 20899679Siwasaki /* Two name segments */ 20967754Smsmith 210107325Siwasaki End += 1 + (2 * ACPI_NAME_SIZE); 21167754Smsmith break; 21267754Smsmith 21367754Smsmith case AML_MULTI_NAME_PREFIX_OP: 21467754Smsmith 215167802Sjkim /* Multiple name segments, 4 chars each, count in next byte */ 21667754Smsmith 217167802Sjkim End += 2 + (*(End + 1) * ACPI_NAME_SIZE); 21867754Smsmith break; 21967754Smsmith 22067754Smsmith default: 22167754Smsmith 22299679Siwasaki /* Single name segment */ 22367754Smsmith 224107325Siwasaki End += ACPI_NAME_SIZE; 22567754Smsmith break; 22667754Smsmith } 22767754Smsmith 228167802Sjkim ParserState->Aml = End; 229114237Snjl return_PTR ((char *) Start); 23067754Smsmith} 23167754Smsmith 23267754Smsmith 23367754Smsmith/******************************************************************************* 23467754Smsmith * 23567754Smsmith * FUNCTION: AcpiPsGetNextNamepath 23667754Smsmith * 23767754Smsmith * PARAMETERS: ParserState - Current parser state object 23867754Smsmith * Arg - Where the namepath will be stored 23967754Smsmith * ArgCount - If the namepath points to a control method 24067754Smsmith * the method's argument is returned here. 241167802Sjkim * PossibleMethodCall - Whether the namepath can possibly be the 242107325Siwasaki * start of a method call 24367754Smsmith * 244102550Siwasaki * RETURN: Status 24567754Smsmith * 246102550Siwasaki * DESCRIPTION: Get next name (if method call, return # of required args). 247102550Siwasaki * Names are looked up in the internal namespace to determine 248241973Sjkim * if the name represents a control method. If a method 24967754Smsmith * is found, the number of arguments to the method is returned. 25067754Smsmith * This information is critical for parsing to continue correctly. 25167754Smsmith * 25267754Smsmith ******************************************************************************/ 25367754Smsmith 254102550SiwasakiACPI_STATUS 25567754SmsmithAcpiPsGetNextNamepath ( 256107325Siwasaki ACPI_WALK_STATE *WalkState, 25767754Smsmith ACPI_PARSE_STATE *ParserState, 25867754Smsmith ACPI_PARSE_OBJECT *Arg, 259167802Sjkim BOOLEAN PossibleMethodCall) 26067754Smsmith{ 261193267Sjkim ACPI_STATUS Status; 262114237Snjl char *Path; 26367754Smsmith ACPI_PARSE_OBJECT *NameOp; 264102550Siwasaki ACPI_OPERAND_OBJECT *MethodDesc; 265102550Siwasaki ACPI_NAMESPACE_NODE *Node; 266193267Sjkim UINT8 *Start = ParserState->Aml; 26767754Smsmith 26867754Smsmith 269167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextNamepath); 27067754Smsmith 27167754Smsmith 27267754Smsmith Path = AcpiPsGetNextNamestring (ParserState); 273167802Sjkim AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 27467754Smsmith 275167802Sjkim /* Null path case is allowed, just exit */ 27667754Smsmith 277167802Sjkim if (!Path) 27867754Smsmith { 279167802Sjkim Arg->Common.Value.Name = Path; 280167802Sjkim return_ACPI_STATUS (AE_OK); 281167802Sjkim } 282167802Sjkim 283167802Sjkim /* 284193267Sjkim * Lookup the name in the internal namespace, starting with the current 285193267Sjkim * scope. We don't want to add anything new to the namespace here, 286193267Sjkim * however, so we use MODE_EXECUTE. 287167802Sjkim * Allow searching of the parent tree, but don't open a new scope - 288167802Sjkim * we just want to lookup the object (must be mode EXECUTE to perform 289167802Sjkim * the upsearch) 290167802Sjkim */ 291193267Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 292193267Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 293167802Sjkim ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 294167802Sjkim 295167802Sjkim /* 296167802Sjkim * If this name is a control method invocation, we must 297167802Sjkim * setup the method call 298167802Sjkim */ 299167802Sjkim if (ACPI_SUCCESS (Status) && 300167802Sjkim PossibleMethodCall && 301167802Sjkim (Node->Type == ACPI_TYPE_METHOD)) 302167802Sjkim { 303193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 304193267Sjkim { 305193267Sjkim /* 306193267Sjkim * AcpiPsGetNextNamestring has increased the AML pointer, 307193267Sjkim * so we need to restore the saved AML pointer for method call. 308193267Sjkim */ 309193267Sjkim WalkState->ParserState.Aml = Start; 310193267Sjkim WalkState->ArgCount = 1; 311193267Sjkim AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 312193267Sjkim return_ACPI_STATUS (AE_OK); 313193267Sjkim } 314193267Sjkim 315167802Sjkim /* This name is actually a control method invocation */ 316167802Sjkim 317167802Sjkim MethodDesc = AcpiNsGetAttachedObject (Node); 318167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 319167802Sjkim "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path)); 320167802Sjkim 321167802Sjkim NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 322167802Sjkim if (!NameOp) 32367754Smsmith { 324167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 32567754Smsmith } 32667754Smsmith 327167802Sjkim /* Change Arg into a METHOD CALL and attach name to it */ 328151937Sjkim 329167802Sjkim AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 330167802Sjkim NameOp->Common.Value.Name = Path; 331102550Siwasaki 332167802Sjkim /* Point METHODCALL/NAME to the METHOD Node */ 33367754Smsmith 334167802Sjkim NameOp->Common.Node = Node; 335167802Sjkim AcpiPsAppendArg (Arg, NameOp); 33667754Smsmith 337167802Sjkim if (!MethodDesc) 338167802Sjkim { 339167802Sjkim ACPI_ERROR ((AE_INFO, 340167802Sjkim "Control Method %p has no attached object", 341167802Sjkim Node)); 342167802Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 343167802Sjkim } 34467754Smsmith 345167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 346167802Sjkim "Control Method - %p Args %X\n", 347167802Sjkim Node, MethodDesc->Method.ParamCount)); 34867754Smsmith 349167802Sjkim /* Get the number of arguments to expect */ 350102550Siwasaki 351167802Sjkim WalkState->ArgCount = MethodDesc->Method.ParamCount; 352167802Sjkim return_ACPI_STATUS (AE_OK); 353167802Sjkim } 35467754Smsmith 355167802Sjkim /* 356167802Sjkim * Special handling if the name was not found during the lookup - 357167802Sjkim * some NotFound cases are allowed 358167802Sjkim */ 359167802Sjkim if (Status == AE_NOT_FOUND) 360167802Sjkim { 361167802Sjkim /* 1) NotFound is ok during load pass 1/2 (allow forward references) */ 362102550Siwasaki 363167802Sjkim if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) != 364167802Sjkim ACPI_PARSE_EXECUTE) 365167802Sjkim { 366167802Sjkim Status = AE_OK; 367167802Sjkim } 368107325Siwasaki 369167802Sjkim /* 2) NotFound during a CondRefOf(x) is ok by definition */ 37067754Smsmith 371167802Sjkim else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP) 372167802Sjkim { 373167802Sjkim Status = AE_OK; 37467754Smsmith } 375107325Siwasaki 376167802Sjkim /* 377167802Sjkim * 3) NotFound while building a Package is ok at this point, we 378167802Sjkim * may flag as an error later if slack mode is not enabled. 379167802Sjkim * (Some ASL code depends on allowing this behavior) 380167802Sjkim */ 381167802Sjkim else if ((Arg->Common.Parent) && 382167802Sjkim ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 383167802Sjkim (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 384107325Siwasaki { 385167802Sjkim Status = AE_OK; 386167802Sjkim } 387167802Sjkim } 388107325Siwasaki 389167802Sjkim /* Final exception check (may have been changed from code above) */ 390117521Snjl 391167802Sjkim if (ACPI_FAILURE (Status)) 392167802Sjkim { 393167802Sjkim ACPI_ERROR_NAMESPACE (Path, Status); 394117521Snjl 395167802Sjkim if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == 396167802Sjkim ACPI_PARSE_EXECUTE) 397167802Sjkim { 398167802Sjkim /* Report a control method execution error */ 399117521Snjl 400167802Sjkim Status = AcpiDsMethodError (Status, WalkState); 401107325Siwasaki } 40267754Smsmith } 40367754Smsmith 404167802Sjkim /* Save the namepath */ 405167802Sjkim 40699679Siwasaki Arg->Common.Value.Name = Path; 407102550Siwasaki return_ACPI_STATUS (Status); 40867754Smsmith} 40967754Smsmith 41067754Smsmith 41167754Smsmith/******************************************************************************* 41267754Smsmith * 41367754Smsmith * FUNCTION: AcpiPsGetNextSimpleArg 41467754Smsmith * 41567754Smsmith * PARAMETERS: ParserState - Current parser state object 41667754Smsmith * ArgType - The argument type (AML_*_ARG) 41767754Smsmith * Arg - Where the argument is returned 41867754Smsmith * 41967754Smsmith * RETURN: None 42067754Smsmith * 42167754Smsmith * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 42267754Smsmith * 42367754Smsmith ******************************************************************************/ 42467754Smsmith 42567754Smsmithvoid 42667754SmsmithAcpiPsGetNextSimpleArg ( 42767754Smsmith ACPI_PARSE_STATE *ParserState, 42867754Smsmith UINT32 ArgType, 42967754Smsmith ACPI_PARSE_OBJECT *Arg) 43067754Smsmith{ 431167802Sjkim UINT32 Length; 432167802Sjkim UINT16 Opcode; 433167802Sjkim UINT8 *Aml = ParserState->Aml; 43467754Smsmith 43567754Smsmith 436167802Sjkim ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType); 43767754Smsmith 438167802Sjkim 43967754Smsmith switch (ArgType) 44067754Smsmith { 44167754Smsmith case ARGP_BYTEDATA: 44267754Smsmith 443167802Sjkim /* Get 1 byte from the AML stream */ 444167802Sjkim 445167802Sjkim Opcode = AML_BYTE_OP; 446202771Sjkim Arg->Common.Value.Integer = (UINT64) *Aml; 447167802Sjkim Length = 1; 44867754Smsmith break; 44967754Smsmith 45067754Smsmith case ARGP_WORDDATA: 45167754Smsmith 45267754Smsmith /* Get 2 bytes from the AML stream */ 45367754Smsmith 454167802Sjkim Opcode = AML_WORD_OP; 455167802Sjkim ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); 456167802Sjkim Length = 2; 45767754Smsmith break; 45867754Smsmith 45967754Smsmith case ARGP_DWORDDATA: 46067754Smsmith 46167754Smsmith /* Get 4 bytes from the AML stream */ 46267754Smsmith 463167802Sjkim Opcode = AML_DWORD_OP; 464167802Sjkim ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); 465167802Sjkim Length = 4; 46667754Smsmith break; 46767754Smsmith 46882367Smsmith case ARGP_QWORDDATA: 46982367Smsmith 47082367Smsmith /* Get 8 bytes from the AML stream */ 47182367Smsmith 472167802Sjkim Opcode = AML_QWORD_OP; 473167802Sjkim ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); 474167802Sjkim Length = 8; 47582367Smsmith break; 47682367Smsmith 47767754Smsmith case ARGP_CHARLIST: 47867754Smsmith 479167802Sjkim /* Get a pointer to the string, point past the string */ 48067754Smsmith 481167802Sjkim Opcode = AML_STRING_OP; 482167802Sjkim Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); 483167802Sjkim 484167802Sjkim /* Find the null terminator */ 485167802Sjkim 486167802Sjkim Length = 0; 487167802Sjkim while (Aml[Length]) 48867754Smsmith { 489167802Sjkim Length++; 49067754Smsmith } 491167802Sjkim Length++; 49267754Smsmith break; 49367754Smsmith 49467754Smsmith case ARGP_NAME: 49567754Smsmith case ARGP_NAMESTRING: 49667754Smsmith 49777424Smsmith AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 49899679Siwasaki Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 499167802Sjkim return_VOID; 50099679Siwasaki 50199679Siwasaki default: 502107325Siwasaki 503204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType)); 504167802Sjkim return_VOID; 50567754Smsmith } 50667754Smsmith 507167802Sjkim AcpiPsInitOp (Arg, Opcode); 508167802Sjkim ParserState->Aml += Length; 50967754Smsmith return_VOID; 51067754Smsmith} 51167754Smsmith 51267754Smsmith 51367754Smsmith/******************************************************************************* 51467754Smsmith * 51567754Smsmith * FUNCTION: AcpiPsGetNextField 51667754Smsmith * 51767754Smsmith * PARAMETERS: ParserState - Current parser state object 51867754Smsmith * 51967754Smsmith * RETURN: A newly allocated FIELD op 52067754Smsmith * 52167754Smsmith * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField) 52267754Smsmith * 52367754Smsmith ******************************************************************************/ 52467754Smsmith 525151937Sjkimstatic ACPI_PARSE_OBJECT * 52667754SmsmithAcpiPsGetNextField ( 52767754Smsmith ACPI_PARSE_STATE *ParserState) 52867754Smsmith{ 529228110Sjkim UINT32 AmlOffset; 53067754Smsmith ACPI_PARSE_OBJECT *Field; 531228110Sjkim ACPI_PARSE_OBJECT *Arg = NULL; 53267754Smsmith UINT16 Opcode; 53367754Smsmith UINT32 Name; 534228110Sjkim UINT8 AccessType; 535228110Sjkim UINT8 AccessAttribute; 536228110Sjkim UINT8 AccessLength; 537228110Sjkim UINT32 PkgLength; 538228110Sjkim UINT8 *PkgEnd; 539228110Sjkim UINT32 BufferLength; 54067754Smsmith 54167754Smsmith 542167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextField); 54367754Smsmith 54467754Smsmith 545228110Sjkim AmlOffset = (UINT32) ACPI_PTR_DIFF ( 546228110Sjkim ParserState->Aml, ParserState->AmlStart); 547228110Sjkim 548151937Sjkim /* Determine field type */ 54967754Smsmith 55091116Smsmith switch (ACPI_GET8 (ParserState->Aml)) 55167754Smsmith { 552228110Sjkim case AML_FIELD_OFFSET_OP: 55367754Smsmith 554228110Sjkim Opcode = AML_INT_RESERVEDFIELD_OP; 555228110Sjkim ParserState->Aml++; 55667754Smsmith break; 55767754Smsmith 558228110Sjkim case AML_FIELD_ACCESS_OP: 55967754Smsmith 560228110Sjkim Opcode = AML_INT_ACCESSFIELD_OP; 56167754Smsmith ParserState->Aml++; 56267754Smsmith break; 56367754Smsmith 564228110Sjkim case AML_FIELD_CONNECTION_OP: 56567754Smsmith 566228110Sjkim Opcode = AML_INT_CONNECTION_OP; 56767754Smsmith ParserState->Aml++; 56867754Smsmith break; 569228110Sjkim 570228110Sjkim case AML_FIELD_EXT_ACCESS_OP: 571228110Sjkim 572228110Sjkim Opcode = AML_INT_EXTACCESSFIELD_OP; 573228110Sjkim ParserState->Aml++; 574228110Sjkim break; 575228110Sjkim 576228110Sjkim default: 577228110Sjkim 578228110Sjkim Opcode = AML_INT_NAMEDFIELD_OP; 579228110Sjkim break; 58067754Smsmith } 58167754Smsmith 58267754Smsmith /* Allocate a new field op */ 58367754Smsmith 58467754Smsmith Field = AcpiPsAllocOp (Opcode); 58599679Siwasaki if (!Field) 58667754Smsmith { 58799679Siwasaki return_PTR (NULL); 58899679Siwasaki } 58967754Smsmith 59099679Siwasaki Field->Common.AmlOffset = AmlOffset; 59167754Smsmith 59299679Siwasaki /* Decode the field type */ 59367754Smsmith 59499679Siwasaki switch (Opcode) 59599679Siwasaki { 59699679Siwasaki case AML_INT_NAMEDFIELD_OP: 59767754Smsmith 59899679Siwasaki /* Get the 4-character name */ 59967754Smsmith 600117521Snjl ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 60199679Siwasaki AcpiPsSetName (Field, Name); 602107325Siwasaki ParserState->Aml += ACPI_NAME_SIZE; 60367754Smsmith 60499679Siwasaki /* Get the length which is encoded as a package length */ 60567754Smsmith 60699679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 60799679Siwasaki break; 60867754Smsmith 60967754Smsmith 61099679Siwasaki case AML_INT_RESERVEDFIELD_OP: 61167754Smsmith 61299679Siwasaki /* Get the length which is encoded as a package length */ 61367754Smsmith 61499679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 61599679Siwasaki break; 61667754Smsmith 61767754Smsmith 61899679Siwasaki case AML_INT_ACCESSFIELD_OP: 619228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 62099679Siwasaki 62199679Siwasaki /* 62299679Siwasaki * Get AccessType and AccessAttrib and merge into the field Op 623228110Sjkim * AccessType is first operand, AccessAttribute is second. stuff 624228110Sjkim * these bytes into the node integer value for convenience. 62599679Siwasaki */ 626228110Sjkim 627228110Sjkim /* Get the two bytes (Type/Attribute) */ 628228110Sjkim 629228110Sjkim AccessType = ACPI_GET8 (ParserState->Aml); 63099679Siwasaki ParserState->Aml++; 631228110Sjkim AccessAttribute = ACPI_GET8 (ParserState->Aml); 63299679Siwasaki ParserState->Aml++; 633228110Sjkim 634228110Sjkim Field->Common.Value.Integer = (UINT8) AccessType; 635228110Sjkim Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8); 636228110Sjkim 637228110Sjkim /* This opcode has a third byte, AccessLength */ 638228110Sjkim 639228110Sjkim if (Opcode == AML_INT_EXTACCESSFIELD_OP) 640228110Sjkim { 641228110Sjkim AccessLength = ACPI_GET8 (ParserState->Aml); 642228110Sjkim ParserState->Aml++; 643228110Sjkim 644228110Sjkim Field->Common.Value.Integer |= (UINT32) (AccessLength << 16); 645228110Sjkim } 64699679Siwasaki break; 64799679Siwasaki 648228110Sjkim 649228110Sjkim case AML_INT_CONNECTION_OP: 650228110Sjkim 651228110Sjkim /* 652228110Sjkim * Argument for Connection operator can be either a Buffer 653228110Sjkim * (resource descriptor), or a NameString. 654228110Sjkim */ 655228110Sjkim if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP) 656228110Sjkim { 657228110Sjkim ParserState->Aml++; 658228110Sjkim 659228110Sjkim PkgEnd = ParserState->Aml; 660228110Sjkim PkgLength = AcpiPsGetNextPackageLength (ParserState); 661228110Sjkim PkgEnd += PkgLength; 662228110Sjkim 663228110Sjkim if (ParserState->Aml < PkgEnd) 664228110Sjkim { 665228110Sjkim /* Non-empty list */ 666228110Sjkim 667228110Sjkim Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); 668228110Sjkim if (!Arg) 669228110Sjkim { 670233558Sjkim AcpiPsFreeOp (Field); 671228110Sjkim return_PTR (NULL); 672228110Sjkim } 673228110Sjkim 674228110Sjkim /* Get the actual buffer length argument */ 675228110Sjkim 676228110Sjkim Opcode = ACPI_GET8 (ParserState->Aml); 677228110Sjkim ParserState->Aml++; 678228110Sjkim 679228110Sjkim switch (Opcode) 680228110Sjkim { 681228110Sjkim case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 682250838Sjkim 683228110Sjkim BufferLength = ACPI_GET8 (ParserState->Aml); 684228110Sjkim ParserState->Aml += 1; 685228110Sjkim break; 686228110Sjkim 687228110Sjkim case AML_WORD_OP: /* AML_WORDDATA_ARG */ 688250838Sjkim 689228110Sjkim BufferLength = ACPI_GET16 (ParserState->Aml); 690228110Sjkim ParserState->Aml += 2; 691228110Sjkim break; 692228110Sjkim 693228110Sjkim case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 694250838Sjkim 695228110Sjkim BufferLength = ACPI_GET32 (ParserState->Aml); 696228110Sjkim ParserState->Aml += 4; 697228110Sjkim break; 698228110Sjkim 699228110Sjkim default: 700250838Sjkim 701228110Sjkim BufferLength = 0; 702228110Sjkim break; 703228110Sjkim } 704228110Sjkim 705228110Sjkim /* Fill in bytelist data */ 706228110Sjkim 707228110Sjkim Arg->Named.Value.Size = BufferLength; 708228110Sjkim Arg->Named.Data = ParserState->Aml; 709228110Sjkim } 710228110Sjkim 711228110Sjkim /* Skip to End of byte data */ 712228110Sjkim 713228110Sjkim ParserState->Aml = PkgEnd; 714228110Sjkim } 715228110Sjkim else 716228110Sjkim { 717228110Sjkim Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 718228110Sjkim if (!Arg) 719228110Sjkim { 720233558Sjkim AcpiPsFreeOp (Field); 721228110Sjkim return_PTR (NULL); 722228110Sjkim } 723228110Sjkim 724228110Sjkim /* Get the Namestring argument */ 725228110Sjkim 726228110Sjkim Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 727228110Sjkim } 728228110Sjkim 729228110Sjkim /* Link the buffer/namestring to parent (CONNECTION_OP) */ 730228110Sjkim 731228110Sjkim AcpiPsAppendArg (Field, Arg); 732228110Sjkim break; 733228110Sjkim 734228110Sjkim 73599679Siwasaki default: 736107325Siwasaki 73799679Siwasaki /* Opcode was set in previous switch */ 73899679Siwasaki break; 73967754Smsmith } 74067754Smsmith 74167754Smsmith return_PTR (Field); 74267754Smsmith} 74367754Smsmith 74467754Smsmith 74567754Smsmith/******************************************************************************* 74667754Smsmith * 74767754Smsmith * FUNCTION: AcpiPsGetNextArg 74867754Smsmith * 749151937Sjkim * PARAMETERS: WalkState - Current state 750151937Sjkim * ParserState - Current parser state object 75167754Smsmith * ArgType - The argument type (AML_*_ARG) 752151937Sjkim * ReturnArg - Where the next arg is returned 75367754Smsmith * 754102550Siwasaki * RETURN: Status, and an op object containing the next argument. 75567754Smsmith * 75667754Smsmith * DESCRIPTION: Get next argument (including complex list arguments that require 75767754Smsmith * pushing the parser stack) 75867754Smsmith * 75967754Smsmith ******************************************************************************/ 76067754Smsmith 761102550SiwasakiACPI_STATUS 76267754SmsmithAcpiPsGetNextArg ( 763107325Siwasaki ACPI_WALK_STATE *WalkState, 76467754Smsmith ACPI_PARSE_STATE *ParserState, 76567754Smsmith UINT32 ArgType, 766102550Siwasaki ACPI_PARSE_OBJECT **ReturnArg) 76767754Smsmith{ 76867754Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 76967754Smsmith ACPI_PARSE_OBJECT *Prev = NULL; 77067754Smsmith ACPI_PARSE_OBJECT *Field; 77167754Smsmith UINT32 Subop; 772102550Siwasaki ACPI_STATUS Status = AE_OK; 77367754Smsmith 77467754Smsmith 775167802Sjkim ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 77667754Smsmith 77767754Smsmith 77867754Smsmith switch (ArgType) 77967754Smsmith { 78067754Smsmith case ARGP_BYTEDATA: 78167754Smsmith case ARGP_WORDDATA: 78267754Smsmith case ARGP_DWORDDATA: 78367754Smsmith case ARGP_CHARLIST: 78467754Smsmith case ARGP_NAME: 78567754Smsmith case ARGP_NAMESTRING: 78667754Smsmith 787151937Sjkim /* Constants, strings, and namestrings are all the same size */ 78867754Smsmith 78967754Smsmith Arg = AcpiPsAllocOp (AML_BYTE_OP); 790102550Siwasaki if (!Arg) 79167754Smsmith { 792102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 79367754Smsmith } 794102550Siwasaki AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 79567754Smsmith break; 79667754Smsmith 79767754Smsmith case ARGP_PKGLENGTH: 79867754Smsmith 799102550Siwasaki /* Package length, nothing returned */ 80067754Smsmith 80167754Smsmith ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 80267754Smsmith break; 80367754Smsmith 80467754Smsmith case ARGP_FIELDLIST: 80567754Smsmith 80667754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 80767754Smsmith { 808102550Siwasaki /* Non-empty list */ 80967754Smsmith 81067754Smsmith while (ParserState->Aml < ParserState->PkgEnd) 81167754Smsmith { 81267754Smsmith Field = AcpiPsGetNextField (ParserState); 81367754Smsmith if (!Field) 81467754Smsmith { 815102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 81667754Smsmith } 81767754Smsmith 81867754Smsmith if (Prev) 81967754Smsmith { 82099679Siwasaki Prev->Common.Next = Field; 82167754Smsmith } 82267754Smsmith else 82367754Smsmith { 82467754Smsmith Arg = Field; 82567754Smsmith } 82667754Smsmith Prev = Field; 82767754Smsmith } 82867754Smsmith 829102550Siwasaki /* Skip to End of byte data */ 83067754Smsmith 83167754Smsmith ParserState->Aml = ParserState->PkgEnd; 83267754Smsmith } 83367754Smsmith break; 83467754Smsmith 83567754Smsmith case ARGP_BYTELIST: 83667754Smsmith 83767754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 83867754Smsmith { 839102550Siwasaki /* Non-empty list */ 84067754Smsmith 84177424Smsmith Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); 842102550Siwasaki if (!Arg) 84367754Smsmith { 844102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 84567754Smsmith } 84667754Smsmith 847102550Siwasaki /* Fill in bytelist data */ 84867754Smsmith 849151937Sjkim Arg->Common.Value.Size = (UINT32) 850151937Sjkim ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml); 851102550Siwasaki Arg->Named.Data = ParserState->Aml; 852102550Siwasaki 853102550Siwasaki /* Skip to End of byte data */ 854102550Siwasaki 85567754Smsmith ParserState->Aml = ParserState->PkgEnd; 85667754Smsmith } 85767754Smsmith break; 85867754Smsmith 85967754Smsmith case ARGP_TARGET: 86067754Smsmith case ARGP_SUPERNAME: 86191116Smsmith case ARGP_SIMPLENAME: 862102550Siwasaki 863102550Siwasaki Subop = AcpiPsPeekOpcode (ParserState); 864102550Siwasaki if (Subop == 0 || 865102550Siwasaki AcpiPsIsLeadingChar (Subop) || 866245582Sjkim ACPI_IS_ROOT_PREFIX (Subop) || 867245582Sjkim ACPI_IS_PARENT_PREFIX (Subop)) 86867754Smsmith { 869102550Siwasaki /* NullName or NameString */ 870102550Siwasaki 871102550Siwasaki Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 872102550Siwasaki if (!Arg) 87367754Smsmith { 874102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 87567754Smsmith } 87667754Smsmith 877193267Sjkim /* To support SuperName arg of Unload */ 878193267Sjkim 879193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 880193267Sjkim { 881193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1); 882193267Sjkim 883193267Sjkim /* 884193267Sjkim * If the SuperName arg of Unload is a method call, 885193267Sjkim * we have 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 { 895193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0); 896193267Sjkim } 897102550Siwasaki } 898102550Siwasaki else 899102550Siwasaki { 900151937Sjkim /* Single complex argument, nothing returned */ 90167754Smsmith 902107325Siwasaki WalkState->ArgCount = 1; 90367754Smsmith } 90467754Smsmith break; 90567754Smsmith 90667754Smsmith case ARGP_DATAOBJ: 90767754Smsmith case ARGP_TERMARG: 90867754Smsmith 909151937Sjkim /* Single complex argument, nothing returned */ 91067754Smsmith 911107325Siwasaki WalkState->ArgCount = 1; 91267754Smsmith break; 91367754Smsmith 91467754Smsmith case ARGP_DATAOBJLIST: 91567754Smsmith case ARGP_TERMLIST: 91667754Smsmith case ARGP_OBJLIST: 91767754Smsmith 91867754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 91967754Smsmith { 920151937Sjkim /* Non-empty list of variable arguments, nothing returned */ 92167754Smsmith 922107325Siwasaki WalkState->ArgCount = ACPI_VAR_ARGS; 92367754Smsmith } 92467754Smsmith break; 92599679Siwasaki 92699679Siwasaki default: 927102550Siwasaki 928204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 929102550Siwasaki Status = AE_AML_OPERAND_TYPE; 93099679Siwasaki break; 93167754Smsmith } 93267754Smsmith 933102550Siwasaki *ReturnArg = Arg; 934102550Siwasaki return_ACPI_STATUS (Status); 93567754Smsmith} 936