1 /****************************************************************************** 2 * 3 * Module Name: psargs - Parse AML opcode arguments 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/include/acpi.h> 153 #include <contrib/dev/acpica/include/accommon.h> 154 #include <contrib/dev/acpica/include/acparser.h> 155 #include <contrib/dev/acpica/include/amlcode.h> 156 #include <contrib/dev/acpica/include/acnamesp.h> 157 #include <contrib/dev/acpica/include/acdispat.h> 158 #include <contrib/dev/acpica/include/acconvert.h> 159 160 #define _COMPONENT ACPI_PARSER 161 ACPI_MODULE_NAME ("psargs") 162 163 /* Local prototypes */ 164 165 static UINT32 166 AcpiPsGetNextPackageLength ( 167 ACPI_PARSE_STATE *ParserState); 168 169 static ACPI_PARSE_OBJECT * 170 AcpiPsGetNextField ( 171 ACPI_PARSE_STATE *ParserState); 172 173 static void 174 AcpiPsFreeFieldList ( 175 ACPI_PARSE_OBJECT *Start); 176 177 178 /******************************************************************************* 179 * 180 * FUNCTION: AcpiPsGetNextPackageLength 181 * 182 * PARAMETERS: ParserState - Current parser state object 183 * 184 * RETURN: Decoded package length. On completion, the AML pointer points 185 * past the length byte or bytes. 186 * 187 * DESCRIPTION: Decode and return a package length field. 188 * Note: Largest package length is 28 bits, from ACPI specification 189 * 190 ******************************************************************************/ 191 192 static UINT32 193 AcpiPsGetNextPackageLength ( 194 ACPI_PARSE_STATE *ParserState) 195 { 196 UINT8 *Aml = ParserState->Aml; 197 UINT32 PackageLength = 0; 198 UINT32 ByteCount; 199 UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */ 200 201 202 ACPI_FUNCTION_TRACE (PsGetNextPackageLength); 203 204 205 /* 206 * Byte 0 bits [6:7] contain the number of additional bytes 207 * used to encode the package length, either 0,1,2, or 3 208 */ 209 ByteCount = (Aml[0] >> 6); 210 ParserState->Aml += ((ACPI_SIZE) ByteCount + 1); 211 212 /* Get bytes 3, 2, 1 as needed */ 213 214 while (ByteCount) 215 { 216 /* 217 * Final bit positions for the package length bytes: 218 * Byte3->[20:27] 219 * Byte2->[12:19] 220 * Byte1->[04:11] 221 * Byte0->[00:03] 222 */ 223 PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4)); 224 225 ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */ 226 ByteCount--; 227 } 228 229 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 230 231 PackageLength |= (Aml[0] & ByteZeroMask); 232 return_UINT32 (PackageLength); 233 } 234 235 236 /******************************************************************************* 237 * 238 * FUNCTION: AcpiPsGetNextPackageEnd 239 * 240 * PARAMETERS: ParserState - Current parser state object 241 * 242 * RETURN: Pointer to end-of-package +1 243 * 244 * DESCRIPTION: Get next package length and return a pointer past the end of 245 * the package. Consumes the package length field 246 * 247 ******************************************************************************/ 248 249 UINT8 * 250 AcpiPsGetNextPackageEnd ( 251 ACPI_PARSE_STATE *ParserState) 252 { 253 UINT8 *Start = ParserState->Aml; 254 UINT32 PackageLength; 255 256 257 ACPI_FUNCTION_TRACE (PsGetNextPackageEnd); 258 259 260 /* Function below updates ParserState->Aml */ 261 262 PackageLength = AcpiPsGetNextPackageLength (ParserState); 263 264 return_PTR (Start + PackageLength); /* end of package */ 265 } 266 267 268 /******************************************************************************* 269 * 270 * FUNCTION: AcpiPsGetNextNamestring 271 * 272 * PARAMETERS: ParserState - Current parser state object 273 * 274 * RETURN: Pointer to the start of the name string (pointer points into 275 * the AML. 276 * 277 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 278 * prefix characters. Set parser state to point past the string. 279 * (Name is consumed from the AML.) 280 * 281 ******************************************************************************/ 282 283 char * 284 AcpiPsGetNextNamestring ( 285 ACPI_PARSE_STATE *ParserState) 286 { 287 UINT8 *Start = ParserState->Aml; 288 UINT8 *End = ParserState->Aml; 289 290 291 ACPI_FUNCTION_TRACE (PsGetNextNamestring); 292 293 294 /* Point past any namestring prefix characters (backslash or carat) */ 295 296 while (ACPI_IS_ROOT_PREFIX (*End) || 297 ACPI_IS_PARENT_PREFIX (*End)) 298 { 299 End++; 300 } 301 302 /* Decode the path prefix character */ 303 304 switch (*End) 305 { 306 case 0: 307 308 /* NullName */ 309 310 if (End == Start) 311 { 312 Start = NULL; 313 } 314 End++; 315 break; 316 317 case AML_DUAL_NAME_PREFIX: 318 319 /* Two name segments */ 320 321 End += 1 + (2 * ACPI_NAMESEG_SIZE); 322 break; 323 324 case AML_MULTI_NAME_PREFIX: 325 326 /* Multiple name segments, 4 chars each, count in next byte */ 327 328 End += 2 + (*(End + 1) * ACPI_NAMESEG_SIZE); 329 break; 330 331 default: 332 333 /* Single name segment */ 334 335 End += ACPI_NAMESEG_SIZE; 336 break; 337 } 338 339 ParserState->Aml = End; 340 return_PTR ((char *) Start); 341 } 342 343 344 /******************************************************************************* 345 * 346 * FUNCTION: AcpiPsGetNextNamepath 347 * 348 * PARAMETERS: ParserState - Current parser state object 349 * Arg - Where the namepath will be stored 350 * ArgCount - If the namepath points to a control method 351 * the method's argument is returned here. 352 * PossibleMethodCall - Whether the namepath can possibly be the 353 * start of a method call 354 * 355 * RETURN: Status 356 * 357 * DESCRIPTION: Get next name (if method call, return # of required args). 358 * Names are looked up in the internal namespace to determine 359 * if the name represents a control method. If a method 360 * is found, the number of arguments to the method is returned. 361 * This information is critical for parsing to continue correctly. 362 * 363 ******************************************************************************/ 364 365 ACPI_STATUS 366 AcpiPsGetNextNamepath ( 367 ACPI_WALK_STATE *WalkState, 368 ACPI_PARSE_STATE *ParserState, 369 ACPI_PARSE_OBJECT *Arg, 370 BOOLEAN PossibleMethodCall) 371 { 372 ACPI_STATUS Status; 373 char *Path; 374 ACPI_PARSE_OBJECT *NameOp; 375 ACPI_OPERAND_OBJECT *MethodDesc; 376 ACPI_NAMESPACE_NODE *Node; 377 UINT8 *Start = ParserState->Aml; 378 379 380 ACPI_FUNCTION_TRACE (PsGetNextNamepath); 381 382 383 Path = AcpiPsGetNextNamestring (ParserState); 384 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 385 386 /* Null path case is allowed, just exit */ 387 388 if (!Path) 389 { 390 Arg->Common.Value.Name = Path; 391 return_ACPI_STATUS (AE_OK); 392 } 393 394 /* 395 * Lookup the name in the internal namespace, starting with the current 396 * scope. We don't want to add anything new to the namespace here, 397 * however, so we use MODE_EXECUTE. 398 * Allow searching of the parent tree, but don't open a new scope - 399 * we just want to lookup the object (must be mode EXECUTE to perform 400 * the upsearch) 401 */ 402 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 403 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 404 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 405 406 /* 407 * If this name is a control method invocation, we must 408 * setup the method call 409 */ 410 if (ACPI_SUCCESS (Status) && 411 PossibleMethodCall && 412 (Node->Type == ACPI_TYPE_METHOD)) 413 { 414 if ((GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_SUPERNAME) || 415 (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_TARGET)) 416 { 417 /* 418 * AcpiPsGetNextNamestring has increased the AML pointer past 419 * the method invocation namestring, so we need to restore the 420 * saved AML pointer back to the original method invocation 421 * namestring. 422 */ 423 WalkState->ParserState.Aml = Start; 424 WalkState->ArgCount = 1; 425 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 426 } 427 428 /* This name is actually a control method invocation */ 429 430 MethodDesc = AcpiNsGetAttachedObject (Node); 431 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 432 "Control Method invocation %4.4s - %p Desc %p Path=%p\n", 433 Node->Name.Ascii, Node, MethodDesc, Path)); 434 435 NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start); 436 if (!NameOp) 437 { 438 return_ACPI_STATUS (AE_NO_MEMORY); 439 } 440 441 /* Change Arg into a METHOD CALL and attach name to it */ 442 443 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 444 NameOp->Common.Value.Name = Path; 445 446 /* Point METHODCALL/NAME to the METHOD Node */ 447 448 NameOp->Common.Node = Node; 449 AcpiPsAppendArg (Arg, NameOp); 450 451 if (!MethodDesc) 452 { 453 ACPI_ERROR ((AE_INFO, 454 "Control Method %p has no attached object", 455 Node)); 456 return_ACPI_STATUS (AE_AML_INTERNAL); 457 } 458 459 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 460 "Control Method - %p Args %X\n", 461 Node, MethodDesc->Method.ParamCount)); 462 463 /* Get the number of arguments to expect */ 464 465 WalkState->ArgCount = MethodDesc->Method.ParamCount; 466 return_ACPI_STATUS (AE_OK); 467 } 468 469 /* 470 * Special handling if the name was not found during the lookup - 471 * some NotFound cases are allowed 472 */ 473 if (Status == AE_NOT_FOUND) 474 { 475 /* 1) NotFound is ok during load pass 1/2 (allow forward references) */ 476 477 if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) != 478 ACPI_PARSE_EXECUTE) 479 { 480 Status = AE_OK; 481 } 482 483 /* 2) NotFound during a CondRefOf(x) is ok by definition */ 484 485 else if (WalkState->Op->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP) 486 { 487 Status = AE_OK; 488 } 489 490 /* 491 * 3) NotFound while building a Package is ok at this point, we 492 * may flag as an error later if slack mode is not enabled. 493 * (Some ASL code depends on allowing this behavior) 494 */ 495 else if ((Arg->Common.Parent) && 496 ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 497 (Arg->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))) 498 { 499 Status = AE_OK; 500 } 501 } 502 503 /* Final exception check (may have been changed from code above) */ 504 505 if (ACPI_FAILURE (Status)) 506 { 507 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status); 508 509 if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == 510 ACPI_PARSE_EXECUTE) 511 { 512 /* Report a control method execution error */ 513 514 Status = AcpiDsMethodError (Status, WalkState); 515 } 516 } 517 518 /* Save the namepath */ 519 520 Arg->Common.Value.Name = Path; 521 return_ACPI_STATUS (Status); 522 } 523 524 525 /******************************************************************************* 526 * 527 * FUNCTION: AcpiPsGetNextSimpleArg 528 * 529 * PARAMETERS: ParserState - Current parser state object 530 * ArgType - The argument type (AML_*_ARG) 531 * Arg - Where the argument is returned 532 * 533 * RETURN: None 534 * 535 * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 536 * 537 ******************************************************************************/ 538 539 void 540 AcpiPsGetNextSimpleArg ( 541 ACPI_PARSE_STATE *ParserState, 542 UINT32 ArgType, 543 ACPI_PARSE_OBJECT *Arg) 544 { 545 UINT32 Length; 546 UINT16 Opcode; 547 UINT8 *Aml = ParserState->Aml; 548 549 550 ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType); 551 552 553 switch (ArgType) 554 { 555 case ARGP_BYTEDATA: 556 557 /* Get 1 byte from the AML stream */ 558 559 Opcode = AML_BYTE_OP; 560 Arg->Common.Value.Integer = (UINT64) *Aml; 561 Length = 1; 562 break; 563 564 case ARGP_WORDDATA: 565 566 /* Get 2 bytes from the AML stream */ 567 568 Opcode = AML_WORD_OP; 569 ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); 570 Length = 2; 571 break; 572 573 case ARGP_DWORDDATA: 574 575 /* Get 4 bytes from the AML stream */ 576 577 Opcode = AML_DWORD_OP; 578 ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); 579 Length = 4; 580 break; 581 582 case ARGP_QWORDDATA: 583 584 /* Get 8 bytes from the AML stream */ 585 586 Opcode = AML_QWORD_OP; 587 ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); 588 Length = 8; 589 break; 590 591 case ARGP_CHARLIST: 592 593 /* Get a pointer to the string, point past the string */ 594 595 Opcode = AML_STRING_OP; 596 Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); 597 598 /* Find the null terminator */ 599 600 Length = 0; 601 while (Aml[Length]) 602 { 603 Length++; 604 } 605 Length++; 606 break; 607 608 case ARGP_NAME: 609 case ARGP_NAMESTRING: 610 611 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 612 Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 613 return_VOID; 614 615 default: 616 617 ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType)); 618 return_VOID; 619 } 620 621 AcpiPsInitOp (Arg, Opcode); 622 ParserState->Aml += Length; 623 return_VOID; 624 } 625 626 627 /******************************************************************************* 628 * 629 * FUNCTION: AcpiPsGetNextField 630 * 631 * PARAMETERS: ParserState - Current parser state object 632 * 633 * RETURN: A newly allocated FIELD op 634 * 635 * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField) 636 * 637 ******************************************************************************/ 638 639 static ACPI_PARSE_OBJECT * 640 AcpiPsGetNextField ( 641 ACPI_PARSE_STATE *ParserState) 642 { 643 UINT8 *Aml; 644 ACPI_PARSE_OBJECT *Field; 645 ACPI_PARSE_OBJECT *Arg = NULL; 646 UINT16 Opcode; 647 UINT32 Name; 648 UINT8 AccessType; 649 UINT8 AccessAttribute; 650 UINT8 AccessLength; 651 UINT32 PkgLength; 652 UINT8 *PkgEnd; 653 UINT32 BufferLength; 654 655 656 ACPI_FUNCTION_TRACE (PsGetNextField); 657 658 659 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 660 Aml = ParserState->Aml; 661 662 /* Determine field type */ 663 664 switch (ACPI_GET8 (ParserState->Aml)) 665 { 666 case AML_FIELD_OFFSET_OP: 667 668 Opcode = AML_INT_RESERVEDFIELD_OP; 669 ParserState->Aml++; 670 break; 671 672 case AML_FIELD_ACCESS_OP: 673 674 Opcode = AML_INT_ACCESSFIELD_OP; 675 ParserState->Aml++; 676 break; 677 678 case AML_FIELD_CONNECTION_OP: 679 680 Opcode = AML_INT_CONNECTION_OP; 681 ParserState->Aml++; 682 break; 683 684 case AML_FIELD_EXT_ACCESS_OP: 685 686 Opcode = AML_INT_EXTACCESSFIELD_OP; 687 ParserState->Aml++; 688 break; 689 690 default: 691 692 Opcode = AML_INT_NAMEDFIELD_OP; 693 break; 694 } 695 696 /* Allocate a new field op */ 697 698 Field = AcpiPsAllocOp (Opcode, Aml); 699 if (!Field) 700 { 701 return_PTR (NULL); 702 } 703 704 /* Decode the field type */ 705 706 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 707 switch (Opcode) 708 { 709 case AML_INT_NAMEDFIELD_OP: 710 711 /* Get the 4-character name */ 712 713 ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 714 AcpiPsSetName (Field, Name); 715 ParserState->Aml += ACPI_NAMESEG_SIZE; 716 717 718 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 719 720 #ifdef ACPI_ASL_COMPILER 721 /* 722 * Because the package length isn't represented as a parse tree object, 723 * take comments surrounding this and add to the previously created 724 * parse node. 725 */ 726 if (Field->Common.InlineComment) 727 { 728 Field->Common.NameComment = Field->Common.InlineComment; 729 } 730 Field->Common.InlineComment = AcpiGbl_CurrentInlineComment; 731 AcpiGbl_CurrentInlineComment = NULL; 732 #endif 733 734 /* Get the length which is encoded as a package length */ 735 736 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 737 break; 738 739 740 case AML_INT_RESERVEDFIELD_OP: 741 742 /* Get the length which is encoded as a package length */ 743 744 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 745 break; 746 747 748 case AML_INT_ACCESSFIELD_OP: 749 case AML_INT_EXTACCESSFIELD_OP: 750 751 /* 752 * Get AccessType and AccessAttrib and merge into the field Op 753 * AccessType is first operand, AccessAttribute is second. stuff 754 * these bytes into the node integer value for convenience. 755 */ 756 757 /* Get the two bytes (Type/Attribute) */ 758 759 AccessType = ACPI_GET8 (ParserState->Aml); 760 ParserState->Aml++; 761 AccessAttribute = ACPI_GET8 (ParserState->Aml); 762 ParserState->Aml++; 763 764 Field->Common.Value.Integer = (UINT8) AccessType; 765 Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8); 766 767 /* This opcode has a third byte, AccessLength */ 768 769 if (Opcode == AML_INT_EXTACCESSFIELD_OP) 770 { 771 AccessLength = ACPI_GET8 (ParserState->Aml); 772 ParserState->Aml++; 773 774 Field->Common.Value.Integer |= (UINT32) (AccessLength << 16); 775 } 776 break; 777 778 779 case AML_INT_CONNECTION_OP: 780 781 /* 782 * Argument for Connection operator can be either a Buffer 783 * (resource descriptor), or a NameString. 784 */ 785 Aml = ParserState->Aml; 786 if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP) 787 { 788 ParserState->Aml++; 789 790 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 791 PkgEnd = ParserState->Aml; 792 PkgLength = AcpiPsGetNextPackageLength (ParserState); 793 PkgEnd += PkgLength; 794 795 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 796 if (ParserState->Aml < PkgEnd) 797 { 798 /* Non-empty list */ 799 800 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml); 801 if (!Arg) 802 { 803 AcpiPsFreeOp (Field); 804 return_PTR (NULL); 805 } 806 807 /* Get the actual buffer length argument */ 808 809 Opcode = ACPI_GET8 (ParserState->Aml); 810 ParserState->Aml++; 811 812 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 813 switch (Opcode) 814 { 815 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 816 817 BufferLength = ACPI_GET8 (ParserState->Aml); 818 ParserState->Aml += 1; 819 break; 820 821 case AML_WORD_OP: /* AML_WORDDATA_ARG */ 822 823 BufferLength = ACPI_GET16 (ParserState->Aml); 824 ParserState->Aml += 2; 825 break; 826 827 case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 828 829 BufferLength = ACPI_GET32 (ParserState->Aml); 830 ParserState->Aml += 4; 831 break; 832 833 default: 834 835 BufferLength = 0; 836 break; 837 } 838 839 /* Fill in bytelist data */ 840 841 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 842 Arg->Named.Value.Size = BufferLength; 843 Arg->Named.Data = ParserState->Aml; 844 } 845 846 /* Skip to End of byte data */ 847 848 ParserState->Aml = PkgEnd; 849 } 850 else 851 { 852 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml); 853 if (!Arg) 854 { 855 AcpiPsFreeOp (Field); 856 return_PTR (NULL); 857 } 858 859 /* Get the Namestring argument */ 860 861 Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 862 } 863 864 /* Link the buffer/namestring to parent (CONNECTION_OP) */ 865 866 AcpiPsAppendArg (Field, Arg); 867 break; 868 869 870 default: 871 872 /* Opcode was set in previous switch */ 873 break; 874 } 875 876 return_PTR (Field); 877 } 878 879 /******************************************************************************* 880 * 881 * FUNCTION: AcpiPsFreeFieldList 882 * 883 * PARAMETERS: Start - First Op in field list 884 * 885 * RETURN: None. 886 * 887 * DESCRIPTION: Free all Op objects inside a field list. 888 * 889 ******************************************************************************/ 890 891 static void 892 AcpiPsFreeFieldList ( 893 ACPI_PARSE_OBJECT *Start) 894 { 895 ACPI_PARSE_OBJECT *Current = Start; 896 ACPI_PARSE_OBJECT *Next; 897 ACPI_PARSE_OBJECT *Arg; 898 899 while (Current) 900 { 901 Next = Current->Common.Next; 902 903 /* AML_INT_CONNECTION_OP can have a single argument */ 904 905 Arg = AcpiPsGetArg (Current, 0); 906 if (Arg) 907 { 908 AcpiPsFreeOp (Arg); 909 } 910 911 AcpiPsFreeOp(Current); 912 Current = Next; 913 } 914 } 915 916 917 /******************************************************************************* 918 * 919 * FUNCTION: AcpiPsGetNextArg 920 * 921 * PARAMETERS: WalkState - Current state 922 * ParserState - Current parser state object 923 * ArgType - The argument type (AML_*_ARG) 924 * ReturnArg - Where the next arg is returned 925 * 926 * RETURN: Status, and an op object containing the next argument. 927 * 928 * DESCRIPTION: Get next argument (including complex list arguments that require 929 * pushing the parser stack) 930 * 931 ******************************************************************************/ 932 933 ACPI_STATUS 934 AcpiPsGetNextArg ( 935 ACPI_WALK_STATE *WalkState, 936 ACPI_PARSE_STATE *ParserState, 937 UINT32 ArgType, 938 ACPI_PARSE_OBJECT **ReturnArg) 939 { 940 ACPI_PARSE_OBJECT *Arg = NULL; 941 ACPI_PARSE_OBJECT *Prev = NULL; 942 ACPI_PARSE_OBJECT *Field; 943 UINT32 Subop; 944 ACPI_STATUS Status = AE_OK; 945 946 947 ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 948 949 950 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 951 "Expected argument type ARGP: %s (%2.2X)\n", 952 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 953 954 switch (ArgType) 955 { 956 case ARGP_BYTEDATA: 957 case ARGP_WORDDATA: 958 case ARGP_DWORDDATA: 959 case ARGP_CHARLIST: 960 case ARGP_NAME: 961 case ARGP_NAMESTRING: 962 963 /* Constants, strings, and namestrings are all the same size */ 964 965 Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml); 966 if (!Arg) 967 { 968 return_ACPI_STATUS (AE_NO_MEMORY); 969 } 970 971 AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 972 break; 973 974 case ARGP_PKGLENGTH: 975 976 /* Package length, nothing returned */ 977 978 ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 979 break; 980 981 case ARGP_FIELDLIST: 982 983 if (ParserState->Aml < ParserState->PkgEnd) 984 { 985 /* Non-empty list */ 986 987 while (ParserState->Aml < ParserState->PkgEnd) 988 { 989 Field = AcpiPsGetNextField (ParserState); 990 if (!Field) 991 { 992 if (Arg) 993 { 994 AcpiPsFreeFieldList(Arg); 995 } 996 997 return_ACPI_STATUS (AE_NO_MEMORY); 998 } 999 1000 if (Prev) 1001 { 1002 Prev->Common.Next = Field; 1003 } 1004 else 1005 { 1006 Arg = Field; 1007 } 1008 Prev = Field; 1009 } 1010 1011 /* Skip to End of byte data */ 1012 1013 ParserState->Aml = ParserState->PkgEnd; 1014 } 1015 break; 1016 1017 case ARGP_BYTELIST: 1018 1019 if (ParserState->Aml < ParserState->PkgEnd) 1020 { 1021 /* Non-empty list */ 1022 1023 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, 1024 ParserState->Aml); 1025 if (!Arg) 1026 { 1027 return_ACPI_STATUS (AE_NO_MEMORY); 1028 } 1029 1030 /* Fill in bytelist data */ 1031 1032 Arg->Common.Value.Size = (UINT32) 1033 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml); 1034 Arg->Named.Data = ParserState->Aml; 1035 1036 /* Skip to End of byte data */ 1037 1038 ParserState->Aml = ParserState->PkgEnd; 1039 } 1040 break; 1041 1042 case ARGP_SIMPLENAME: 1043 case ARGP_NAME_OR_REF: 1044 1045 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1046 "**** SimpleName/NameOrRef: %s (%2.2X)\n", 1047 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 1048 1049 Subop = AcpiPsPeekOpcode (ParserState); 1050 if (Subop == 0 || 1051 AcpiPsIsLeadingChar (Subop) || 1052 ACPI_IS_ROOT_PREFIX (Subop) || 1053 ACPI_IS_PARENT_PREFIX (Subop)) 1054 { 1055 /* NullName or NameString */ 1056 1057 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml); 1058 if (!Arg) 1059 { 1060 return_ACPI_STATUS (AE_NO_MEMORY); 1061 } 1062 1063 Status = AcpiPsGetNextNamepath (WalkState, ParserState, 1064 Arg, ACPI_NOT_METHOD_CALL); 1065 if (ACPI_FAILURE(Status)) 1066 { 1067 AcpiPsFreeOp (Arg); 1068 return_ACPI_STATUS (Status); 1069 } 1070 } 1071 else 1072 { 1073 /* Single complex argument, nothing returned */ 1074 1075 WalkState->ArgCount = 1; 1076 } 1077 break; 1078 1079 case ARGP_TARGET: 1080 case ARGP_SUPERNAME: 1081 1082 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1083 "**** Target/Supername: %s (%2.2X)\n", 1084 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 1085 1086 Subop = AcpiPsPeekOpcode (ParserState); 1087 if (Subop == 0 || 1088 AcpiPsIsLeadingChar (Subop) || 1089 ACPI_IS_ROOT_PREFIX (Subop) || 1090 ACPI_IS_PARENT_PREFIX (Subop)) 1091 { 1092 /* NULL target (zero). Convert to a NULL namepath */ 1093 1094 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml); 1095 if (!Arg) 1096 { 1097 return_ACPI_STATUS (AE_NO_MEMORY); 1098 } 1099 1100 Status = AcpiPsGetNextNamepath (WalkState, ParserState, 1101 Arg, ACPI_POSSIBLE_METHOD_CALL); 1102 if (ACPI_FAILURE(Status)) 1103 { 1104 AcpiPsFreeOp (Arg); 1105 return_ACPI_STATUS (Status); 1106 } 1107 1108 if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) 1109 { 1110 /* Free method call op and corresponding namestring sub-ob */ 1111 1112 AcpiPsFreeOp (Arg->Common.Value.Arg); 1113 AcpiPsFreeOp (Arg); 1114 Arg = NULL; 1115 WalkState->ArgCount = 1; 1116 } 1117 } 1118 else 1119 { 1120 /* Single complex argument, nothing returned */ 1121 1122 WalkState->ArgCount = 1; 1123 } 1124 break; 1125 1126 case ARGP_DATAOBJ: 1127 case ARGP_TERMARG: 1128 1129 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1130 "**** TermArg/DataObj: %s (%2.2X)\n", 1131 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 1132 1133 /* Single complex argument, nothing returned */ 1134 1135 WalkState->ArgCount = 1; 1136 break; 1137 1138 case ARGP_DATAOBJLIST: 1139 case ARGP_TERMLIST: 1140 case ARGP_OBJLIST: 1141 1142 if (ParserState->Aml < ParserState->PkgEnd) 1143 { 1144 /* Non-empty list of variable arguments, nothing returned */ 1145 1146 WalkState->ArgCount = ACPI_VAR_ARGS; 1147 } 1148 break; 1149 1150 default: 1151 1152 ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 1153 Status = AE_AML_OPERAND_TYPE; 1154 break; 1155 } 1156 1157 *ReturnArg = Arg; 1158 return_ACPI_STATUS (Status); 1159 } 1160