psargs.c revision 246849
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 45167754Smsmith case ARGP_WORDDATA: 45267754Smsmith 45367754Smsmith /* Get 2 bytes from the AML stream */ 45467754Smsmith 455167802Sjkim Opcode = AML_WORD_OP; 456167802Sjkim ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); 457167802Sjkim Length = 2; 45867754Smsmith break; 45967754Smsmith 46067754Smsmith 46167754Smsmith case ARGP_DWORDDATA: 46267754Smsmith 46367754Smsmith /* Get 4 bytes from the AML stream */ 46467754Smsmith 465167802Sjkim Opcode = AML_DWORD_OP; 466167802Sjkim ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); 467167802Sjkim Length = 4; 46867754Smsmith break; 46967754Smsmith 47067754Smsmith 47182367Smsmith case ARGP_QWORDDATA: 47282367Smsmith 47382367Smsmith /* Get 8 bytes from the AML stream */ 47482367Smsmith 475167802Sjkim Opcode = AML_QWORD_OP; 476167802Sjkim ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); 477167802Sjkim Length = 8; 47882367Smsmith break; 47982367Smsmith 48082367Smsmith 48167754Smsmith case ARGP_CHARLIST: 48267754Smsmith 483167802Sjkim /* Get a pointer to the string, point past the string */ 48467754Smsmith 485167802Sjkim Opcode = AML_STRING_OP; 486167802Sjkim Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); 487167802Sjkim 488167802Sjkim /* Find the null terminator */ 489167802Sjkim 490167802Sjkim Length = 0; 491167802Sjkim while (Aml[Length]) 49267754Smsmith { 493167802Sjkim Length++; 49467754Smsmith } 495167802Sjkim Length++; 49667754Smsmith break; 49767754Smsmith 49867754Smsmith 49967754Smsmith case ARGP_NAME: 50067754Smsmith case ARGP_NAMESTRING: 50167754Smsmith 50277424Smsmith AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 50399679Siwasaki Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 504167802Sjkim return_VOID; 50599679Siwasaki 50699679Siwasaki 50799679Siwasaki default: 508107325Siwasaki 509204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType)); 510167802Sjkim return_VOID; 51167754Smsmith } 51267754Smsmith 513167802Sjkim AcpiPsInitOp (Arg, Opcode); 514167802Sjkim ParserState->Aml += Length; 51567754Smsmith return_VOID; 51667754Smsmith} 51767754Smsmith 51867754Smsmith 51967754Smsmith/******************************************************************************* 52067754Smsmith * 52167754Smsmith * FUNCTION: AcpiPsGetNextField 52267754Smsmith * 52367754Smsmith * PARAMETERS: ParserState - Current parser state object 52467754Smsmith * 52567754Smsmith * RETURN: A newly allocated FIELD op 52667754Smsmith * 52767754Smsmith * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField) 52867754Smsmith * 52967754Smsmith ******************************************************************************/ 53067754Smsmith 531151937Sjkimstatic ACPI_PARSE_OBJECT * 53267754SmsmithAcpiPsGetNextField ( 53367754Smsmith ACPI_PARSE_STATE *ParserState) 53467754Smsmith{ 535228110Sjkim UINT32 AmlOffset; 53667754Smsmith ACPI_PARSE_OBJECT *Field; 537228110Sjkim ACPI_PARSE_OBJECT *Arg = NULL; 53867754Smsmith UINT16 Opcode; 53967754Smsmith UINT32 Name; 540228110Sjkim UINT8 AccessType; 541228110Sjkim UINT8 AccessAttribute; 542228110Sjkim UINT8 AccessLength; 543228110Sjkim UINT32 PkgLength; 544228110Sjkim UINT8 *PkgEnd; 545228110Sjkim UINT32 BufferLength; 54667754Smsmith 54767754Smsmith 548167802Sjkim ACPI_FUNCTION_TRACE (PsGetNextField); 54967754Smsmith 55067754Smsmith 551228110Sjkim AmlOffset = (UINT32) ACPI_PTR_DIFF ( 552228110Sjkim ParserState->Aml, ParserState->AmlStart); 553228110Sjkim 554151937Sjkim /* Determine field type */ 55567754Smsmith 55691116Smsmith switch (ACPI_GET8 (ParserState->Aml)) 55767754Smsmith { 558228110Sjkim case AML_FIELD_OFFSET_OP: 55967754Smsmith 560228110Sjkim Opcode = AML_INT_RESERVEDFIELD_OP; 561228110Sjkim ParserState->Aml++; 56267754Smsmith break; 56367754Smsmith 564228110Sjkim case AML_FIELD_ACCESS_OP: 56567754Smsmith 566228110Sjkim Opcode = AML_INT_ACCESSFIELD_OP; 56767754Smsmith ParserState->Aml++; 56867754Smsmith break; 56967754Smsmith 570228110Sjkim case AML_FIELD_CONNECTION_OP: 57167754Smsmith 572228110Sjkim Opcode = AML_INT_CONNECTION_OP; 57367754Smsmith ParserState->Aml++; 57467754Smsmith break; 575228110Sjkim 576228110Sjkim case AML_FIELD_EXT_ACCESS_OP: 577228110Sjkim 578228110Sjkim Opcode = AML_INT_EXTACCESSFIELD_OP; 579228110Sjkim ParserState->Aml++; 580228110Sjkim break; 581228110Sjkim 582228110Sjkim default: 583228110Sjkim 584228110Sjkim Opcode = AML_INT_NAMEDFIELD_OP; 585228110Sjkim break; 58667754Smsmith } 58767754Smsmith 58867754Smsmith /* Allocate a new field op */ 58967754Smsmith 59067754Smsmith Field = AcpiPsAllocOp (Opcode); 59199679Siwasaki if (!Field) 59267754Smsmith { 59399679Siwasaki return_PTR (NULL); 59499679Siwasaki } 59567754Smsmith 59699679Siwasaki Field->Common.AmlOffset = AmlOffset; 59767754Smsmith 59899679Siwasaki /* Decode the field type */ 59967754Smsmith 60099679Siwasaki switch (Opcode) 60199679Siwasaki { 60299679Siwasaki case AML_INT_NAMEDFIELD_OP: 60367754Smsmith 60499679Siwasaki /* Get the 4-character name */ 60567754Smsmith 606117521Snjl ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 60799679Siwasaki AcpiPsSetName (Field, Name); 608107325Siwasaki ParserState->Aml += ACPI_NAME_SIZE; 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_RESERVEDFIELD_OP: 61767754Smsmith 61899679Siwasaki /* Get the length which is encoded as a package length */ 61967754Smsmith 62099679Siwasaki Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 62199679Siwasaki break; 62267754Smsmith 62367754Smsmith 62499679Siwasaki case AML_INT_ACCESSFIELD_OP: 625228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 62699679Siwasaki 62799679Siwasaki /* 62899679Siwasaki * Get AccessType and AccessAttrib and merge into the field Op 629228110Sjkim * AccessType is first operand, AccessAttribute is second. stuff 630228110Sjkim * these bytes into the node integer value for convenience. 63199679Siwasaki */ 632228110Sjkim 633228110Sjkim /* Get the two bytes (Type/Attribute) */ 634228110Sjkim 635228110Sjkim AccessType = ACPI_GET8 (ParserState->Aml); 63699679Siwasaki ParserState->Aml++; 637228110Sjkim AccessAttribute = ACPI_GET8 (ParserState->Aml); 63899679Siwasaki ParserState->Aml++; 639228110Sjkim 640228110Sjkim Field->Common.Value.Integer = (UINT8) AccessType; 641228110Sjkim Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8); 642228110Sjkim 643228110Sjkim /* This opcode has a third byte, AccessLength */ 644228110Sjkim 645228110Sjkim if (Opcode == AML_INT_EXTACCESSFIELD_OP) 646228110Sjkim { 647228110Sjkim AccessLength = ACPI_GET8 (ParserState->Aml); 648228110Sjkim ParserState->Aml++; 649228110Sjkim 650228110Sjkim Field->Common.Value.Integer |= (UINT32) (AccessLength << 16); 651228110Sjkim } 65299679Siwasaki break; 65399679Siwasaki 654228110Sjkim 655228110Sjkim case AML_INT_CONNECTION_OP: 656228110Sjkim 657228110Sjkim /* 658228110Sjkim * Argument for Connection operator can be either a Buffer 659228110Sjkim * (resource descriptor), or a NameString. 660228110Sjkim */ 661228110Sjkim if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP) 662228110Sjkim { 663228110Sjkim ParserState->Aml++; 664228110Sjkim 665228110Sjkim PkgEnd = ParserState->Aml; 666228110Sjkim PkgLength = AcpiPsGetNextPackageLength (ParserState); 667228110Sjkim PkgEnd += PkgLength; 668228110Sjkim 669228110Sjkim if (ParserState->Aml < PkgEnd) 670228110Sjkim { 671228110Sjkim /* Non-empty list */ 672228110Sjkim 673228110Sjkim Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); 674228110Sjkim if (!Arg) 675228110Sjkim { 676233558Sjkim AcpiPsFreeOp (Field); 677228110Sjkim return_PTR (NULL); 678228110Sjkim } 679228110Sjkim 680228110Sjkim /* Get the actual buffer length argument */ 681228110Sjkim 682228110Sjkim Opcode = ACPI_GET8 (ParserState->Aml); 683228110Sjkim ParserState->Aml++; 684228110Sjkim 685228110Sjkim switch (Opcode) 686228110Sjkim { 687228110Sjkim case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 688228110Sjkim BufferLength = ACPI_GET8 (ParserState->Aml); 689228110Sjkim ParserState->Aml += 1; 690228110Sjkim break; 691228110Sjkim 692228110Sjkim case AML_WORD_OP: /* AML_WORDDATA_ARG */ 693228110Sjkim BufferLength = ACPI_GET16 (ParserState->Aml); 694228110Sjkim ParserState->Aml += 2; 695228110Sjkim break; 696228110Sjkim 697228110Sjkim case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 698228110Sjkim BufferLength = ACPI_GET32 (ParserState->Aml); 699228110Sjkim ParserState->Aml += 4; 700228110Sjkim break; 701228110Sjkim 702228110Sjkim default: 703228110Sjkim BufferLength = 0; 704228110Sjkim break; 705228110Sjkim } 706228110Sjkim 707228110Sjkim /* Fill in bytelist data */ 708228110Sjkim 709228110Sjkim Arg->Named.Value.Size = BufferLength; 710228110Sjkim Arg->Named.Data = ParserState->Aml; 711228110Sjkim } 712228110Sjkim 713228110Sjkim /* Skip to End of byte data */ 714228110Sjkim 715228110Sjkim ParserState->Aml = PkgEnd; 716228110Sjkim } 717228110Sjkim else 718228110Sjkim { 719228110Sjkim Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 720228110Sjkim if (!Arg) 721228110Sjkim { 722233558Sjkim AcpiPsFreeOp (Field); 723228110Sjkim return_PTR (NULL); 724228110Sjkim } 725228110Sjkim 726228110Sjkim /* Get the Namestring argument */ 727228110Sjkim 728228110Sjkim Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 729228110Sjkim } 730228110Sjkim 731228110Sjkim /* Link the buffer/namestring to parent (CONNECTION_OP) */ 732228110Sjkim 733228110Sjkim AcpiPsAppendArg (Field, Arg); 734228110Sjkim break; 735228110Sjkim 736228110Sjkim 73799679Siwasaki default: 738107325Siwasaki 73999679Siwasaki /* Opcode was set in previous switch */ 74099679Siwasaki break; 74167754Smsmith } 74267754Smsmith 74367754Smsmith return_PTR (Field); 74467754Smsmith} 74567754Smsmith 74667754Smsmith 74767754Smsmith/******************************************************************************* 74867754Smsmith * 74967754Smsmith * FUNCTION: AcpiPsGetNextArg 75067754Smsmith * 751151937Sjkim * PARAMETERS: WalkState - Current state 752151937Sjkim * ParserState - Current parser state object 75367754Smsmith * ArgType - The argument type (AML_*_ARG) 754151937Sjkim * ReturnArg - Where the next arg is returned 75567754Smsmith * 756102550Siwasaki * RETURN: Status, and an op object containing the next argument. 75767754Smsmith * 75867754Smsmith * DESCRIPTION: Get next argument (including complex list arguments that require 75967754Smsmith * pushing the parser stack) 76067754Smsmith * 76167754Smsmith ******************************************************************************/ 76267754Smsmith 763102550SiwasakiACPI_STATUS 76467754SmsmithAcpiPsGetNextArg ( 765107325Siwasaki ACPI_WALK_STATE *WalkState, 76667754Smsmith ACPI_PARSE_STATE *ParserState, 76767754Smsmith UINT32 ArgType, 768102550Siwasaki ACPI_PARSE_OBJECT **ReturnArg) 76967754Smsmith{ 77067754Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 77167754Smsmith ACPI_PARSE_OBJECT *Prev = NULL; 77267754Smsmith ACPI_PARSE_OBJECT *Field; 77367754Smsmith UINT32 Subop; 774102550Siwasaki ACPI_STATUS Status = AE_OK; 77567754Smsmith 77667754Smsmith 777167802Sjkim ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 77867754Smsmith 77967754Smsmith 78067754Smsmith switch (ArgType) 78167754Smsmith { 78267754Smsmith case ARGP_BYTEDATA: 78367754Smsmith case ARGP_WORDDATA: 78467754Smsmith case ARGP_DWORDDATA: 78567754Smsmith case ARGP_CHARLIST: 78667754Smsmith case ARGP_NAME: 78767754Smsmith case ARGP_NAMESTRING: 78867754Smsmith 789151937Sjkim /* Constants, strings, and namestrings are all the same size */ 79067754Smsmith 79167754Smsmith Arg = AcpiPsAllocOp (AML_BYTE_OP); 792102550Siwasaki if (!Arg) 79367754Smsmith { 794102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 79567754Smsmith } 796102550Siwasaki AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 79767754Smsmith break; 79867754Smsmith 79967754Smsmith 80067754Smsmith case ARGP_PKGLENGTH: 80167754Smsmith 802102550Siwasaki /* Package length, nothing returned */ 80367754Smsmith 80467754Smsmith ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 80567754Smsmith break; 80667754Smsmith 80767754Smsmith 80867754Smsmith case ARGP_FIELDLIST: 80967754Smsmith 81067754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 81167754Smsmith { 812102550Siwasaki /* Non-empty list */ 81367754Smsmith 81467754Smsmith while (ParserState->Aml < ParserState->PkgEnd) 81567754Smsmith { 81667754Smsmith Field = AcpiPsGetNextField (ParserState); 81767754Smsmith if (!Field) 81867754Smsmith { 819102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 82067754Smsmith } 82167754Smsmith 82267754Smsmith if (Prev) 82367754Smsmith { 82499679Siwasaki Prev->Common.Next = Field; 82567754Smsmith } 82667754Smsmith else 82767754Smsmith { 82867754Smsmith Arg = Field; 82967754Smsmith } 83067754Smsmith Prev = Field; 83167754Smsmith } 83267754Smsmith 833102550Siwasaki /* Skip to End of byte data */ 83467754Smsmith 83567754Smsmith ParserState->Aml = ParserState->PkgEnd; 83667754Smsmith } 83767754Smsmith break; 83867754Smsmith 83967754Smsmith 84067754Smsmith case ARGP_BYTELIST: 84167754Smsmith 84267754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 84367754Smsmith { 844102550Siwasaki /* Non-empty list */ 84567754Smsmith 84677424Smsmith Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); 847102550Siwasaki if (!Arg) 84867754Smsmith { 849102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 85067754Smsmith } 85167754Smsmith 852102550Siwasaki /* Fill in bytelist data */ 85367754Smsmith 854151937Sjkim Arg->Common.Value.Size = (UINT32) 855151937Sjkim ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml); 856102550Siwasaki Arg->Named.Data = ParserState->Aml; 857102550Siwasaki 858102550Siwasaki /* Skip to End of byte data */ 859102550Siwasaki 86067754Smsmith ParserState->Aml = ParserState->PkgEnd; 86167754Smsmith } 86267754Smsmith break; 86367754Smsmith 86467754Smsmith 86567754Smsmith case ARGP_TARGET: 86667754Smsmith case ARGP_SUPERNAME: 86791116Smsmith case ARGP_SIMPLENAME: 868102550Siwasaki 869102550Siwasaki Subop = AcpiPsPeekOpcode (ParserState); 870102550Siwasaki if (Subop == 0 || 871102550Siwasaki AcpiPsIsLeadingChar (Subop) || 872245582Sjkim ACPI_IS_ROOT_PREFIX (Subop) || 873245582Sjkim ACPI_IS_PARENT_PREFIX (Subop)) 87467754Smsmith { 875102550Siwasaki /* NullName or NameString */ 876102550Siwasaki 877102550Siwasaki Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); 878102550Siwasaki if (!Arg) 87967754Smsmith { 880102550Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 88167754Smsmith } 88267754Smsmith 883193267Sjkim /* To support SuperName arg of Unload */ 884193267Sjkim 885193267Sjkim if (WalkState->Opcode == AML_UNLOAD_OP) 886193267Sjkim { 887193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1); 888193267Sjkim 889193267Sjkim /* 890193267Sjkim * If the SuperName arg of Unload is a method call, 891193267Sjkim * we have restored the AML pointer, just free this Arg 892193267Sjkim */ 893193267Sjkim if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) 894193267Sjkim { 895193267Sjkim AcpiPsFreeOp (Arg); 896193267Sjkim Arg = NULL; 897193267Sjkim } 898193267Sjkim } 899193267Sjkim else 900193267Sjkim { 901193267Sjkim Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0); 902193267Sjkim } 903102550Siwasaki } 904102550Siwasaki else 905102550Siwasaki { 906151937Sjkim /* Single complex argument, nothing returned */ 90767754Smsmith 908107325Siwasaki WalkState->ArgCount = 1; 90967754Smsmith } 91067754Smsmith break; 91167754Smsmith 91267754Smsmith 91367754Smsmith case ARGP_DATAOBJ: 91467754Smsmith case ARGP_TERMARG: 91567754Smsmith 916151937Sjkim /* Single complex argument, nothing returned */ 91767754Smsmith 918107325Siwasaki WalkState->ArgCount = 1; 91967754Smsmith break; 92067754Smsmith 92167754Smsmith 92267754Smsmith case ARGP_DATAOBJLIST: 92367754Smsmith case ARGP_TERMLIST: 92467754Smsmith case ARGP_OBJLIST: 92567754Smsmith 92667754Smsmith if (ParserState->Aml < ParserState->PkgEnd) 92767754Smsmith { 928151937Sjkim /* Non-empty list of variable arguments, nothing returned */ 92967754Smsmith 930107325Siwasaki WalkState->ArgCount = ACPI_VAR_ARGS; 93167754Smsmith } 93267754Smsmith break; 93399679Siwasaki 934102550Siwasaki 93599679Siwasaki default: 936102550Siwasaki 937204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 938102550Siwasaki Status = AE_AML_OPERAND_TYPE; 93999679Siwasaki break; 94067754Smsmith } 94167754Smsmith 942102550Siwasaki *ReturnArg = Arg; 943102550Siwasaki return_ACPI_STATUS (Status); 94467754Smsmith} 945