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 - 2016, 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 #include "acpi.h" 117 #include "accommon.h" 118 #include "acparser.h" 119 #include "amlcode.h" 120 #include "acnamesp.h" 121 #include "acdispat.h" 122 123 #define _COMPONENT ACPI_PARSER 124 ACPI_MODULE_NAME ("psargs") 125 126 /* Local prototypes */ 127 128 static UINT32 129 AcpiPsGetNextPackageLength ( 130 ACPI_PARSE_STATE *ParserState); 131 132 static ACPI_PARSE_OBJECT * 133 AcpiPsGetNextField ( 134 ACPI_PARSE_STATE *ParserState); 135 136 137 /******************************************************************************* 138 * 139 * FUNCTION: AcpiPsGetNextPackageLength 140 * 141 * PARAMETERS: ParserState - Current parser state object 142 * 143 * RETURN: Decoded package length. On completion, the AML pointer points 144 * past the length byte or bytes. 145 * 146 * DESCRIPTION: Decode and return a package length field. 147 * Note: Largest package length is 28 bits, from ACPI specification 148 * 149 ******************************************************************************/ 150 151 static UINT32 152 AcpiPsGetNextPackageLength ( 153 ACPI_PARSE_STATE *ParserState) 154 { 155 UINT8 *Aml = ParserState->Aml; 156 UINT32 PackageLength = 0; 157 UINT32 ByteCount; 158 UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */ 159 160 161 ACPI_FUNCTION_TRACE (PsGetNextPackageLength); 162 163 164 /* 165 * Byte 0 bits [6:7] contain the number of additional bytes 166 * used to encode the package length, either 0,1,2, or 3 167 */ 168 ByteCount = (Aml[0] >> 6); 169 ParserState->Aml += ((ACPI_SIZE) ByteCount + 1); 170 171 /* Get bytes 3, 2, 1 as needed */ 172 173 while (ByteCount) 174 { 175 /* 176 * Final bit positions for the package length bytes: 177 * Byte3->[20:27] 178 * Byte2->[12:19] 179 * Byte1->[04:11] 180 * Byte0->[00:03] 181 */ 182 PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4)); 183 184 ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */ 185 ByteCount--; 186 } 187 188 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 189 190 PackageLength |= (Aml[0] & ByteZeroMask); 191 return_UINT32 (PackageLength); 192 } 193 194 195 /******************************************************************************* 196 * 197 * FUNCTION: AcpiPsGetNextPackageEnd 198 * 199 * PARAMETERS: ParserState - Current parser state object 200 * 201 * RETURN: Pointer to end-of-package +1 202 * 203 * DESCRIPTION: Get next package length and return a pointer past the end of 204 * the package. Consumes the package length field 205 * 206 ******************************************************************************/ 207 208 UINT8 * 209 AcpiPsGetNextPackageEnd ( 210 ACPI_PARSE_STATE *ParserState) 211 { 212 UINT8 *Start = ParserState->Aml; 213 UINT32 PackageLength; 214 215 216 ACPI_FUNCTION_TRACE (PsGetNextPackageEnd); 217 218 219 /* Function below updates ParserState->Aml */ 220 221 PackageLength = AcpiPsGetNextPackageLength (ParserState); 222 223 return_PTR (Start + PackageLength); /* end of package */ 224 } 225 226 227 /******************************************************************************* 228 * 229 * FUNCTION: AcpiPsGetNextNamestring 230 * 231 * PARAMETERS: ParserState - Current parser state object 232 * 233 * RETURN: Pointer to the start of the name string (pointer points into 234 * the AML. 235 * 236 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 237 * prefix characters. Set parser state to point past the string. 238 * (Name is consumed from the AML.) 239 * 240 ******************************************************************************/ 241 242 char * 243 AcpiPsGetNextNamestring ( 244 ACPI_PARSE_STATE *ParserState) 245 { 246 UINT8 *Start = ParserState->Aml; 247 UINT8 *End = ParserState->Aml; 248 249 250 ACPI_FUNCTION_TRACE (PsGetNextNamestring); 251 252 253 /* Point past any namestring prefix characters (backslash or carat) */ 254 255 while (ACPI_IS_ROOT_PREFIX (*End) || 256 ACPI_IS_PARENT_PREFIX (*End)) 257 { 258 End++; 259 } 260 261 /* Decode the path prefix character */ 262 263 switch (*End) 264 { 265 case 0: 266 267 /* NullName */ 268 269 if (End == Start) 270 { 271 Start = NULL; 272 } 273 End++; 274 break; 275 276 case AML_DUAL_NAME_PREFIX: 277 278 /* Two name segments */ 279 280 End += 1 + (2 * ACPI_NAME_SIZE); 281 break; 282 283 case AML_MULTI_NAME_PREFIX_OP: 284 285 /* Multiple name segments, 4 chars each, count in next byte */ 286 287 End += 2 + (*(End + 1) * ACPI_NAME_SIZE); 288 break; 289 290 default: 291 292 /* Single name segment */ 293 294 End += ACPI_NAME_SIZE; 295 break; 296 } 297 298 ParserState->Aml = End; 299 return_PTR ((char *) Start); 300 } 301 302 303 /******************************************************************************* 304 * 305 * FUNCTION: AcpiPsGetNextNamepath 306 * 307 * PARAMETERS: ParserState - Current parser state object 308 * Arg - Where the namepath will be stored 309 * ArgCount - If the namepath points to a control method 310 * the method's argument is returned here. 311 * PossibleMethodCall - Whether the namepath can possibly be the 312 * start of a method call 313 * 314 * RETURN: Status 315 * 316 * DESCRIPTION: Get next name (if method call, return # of required args). 317 * Names are looked up in the internal namespace to determine 318 * if the name represents a control method. If a method 319 * is found, the number of arguments to the method is returned. 320 * This information is critical for parsing to continue correctly. 321 * 322 ******************************************************************************/ 323 324 ACPI_STATUS 325 AcpiPsGetNextNamepath ( 326 ACPI_WALK_STATE *WalkState, 327 ACPI_PARSE_STATE *ParserState, 328 ACPI_PARSE_OBJECT *Arg, 329 BOOLEAN PossibleMethodCall) 330 { 331 ACPI_STATUS Status; 332 char *Path; 333 ACPI_PARSE_OBJECT *NameOp; 334 ACPI_OPERAND_OBJECT *MethodDesc; 335 ACPI_NAMESPACE_NODE *Node; 336 UINT8 *Start = ParserState->Aml; 337 338 339 ACPI_FUNCTION_TRACE (PsGetNextNamepath); 340 341 342 Path = AcpiPsGetNextNamestring (ParserState); 343 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 344 345 /* Null path case is allowed, just exit */ 346 347 if (!Path) 348 { 349 Arg->Common.Value.Name = Path; 350 return_ACPI_STATUS (AE_OK); 351 } 352 353 /* 354 * Lookup the name in the internal namespace, starting with the current 355 * scope. We don't want to add anything new to the namespace here, 356 * however, so we use MODE_EXECUTE. 357 * Allow searching of the parent tree, but don't open a new scope - 358 * we just want to lookup the object (must be mode EXECUTE to perform 359 * the upsearch) 360 */ 361 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 362 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 363 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 364 365 /* 366 * If this name is a control method invocation, we must 367 * setup the method call 368 */ 369 if (ACPI_SUCCESS (Status) && 370 PossibleMethodCall && 371 (Node->Type == ACPI_TYPE_METHOD)) 372 { 373 if (WalkState->Opcode == AML_UNLOAD_OP) 374 { 375 /* 376 * AcpiPsGetNextNamestring has increased the AML pointer, 377 * so we need to restore the saved AML pointer for method call. 378 */ 379 WalkState->ParserState.Aml = Start; 380 WalkState->ArgCount = 1; 381 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 382 return_ACPI_STATUS (AE_OK); 383 } 384 385 /* This name is actually a control method invocation */ 386 387 MethodDesc = AcpiNsGetAttachedObject (Node); 388 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 389 "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path)); 390 391 NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start); 392 if (!NameOp) 393 { 394 return_ACPI_STATUS (AE_NO_MEMORY); 395 } 396 397 /* Change Arg into a METHOD CALL and attach name to it */ 398 399 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 400 NameOp->Common.Value.Name = Path; 401 402 /* Point METHODCALL/NAME to the METHOD Node */ 403 404 NameOp->Common.Node = Node; 405 AcpiPsAppendArg (Arg, NameOp); 406 407 if (!MethodDesc) 408 { 409 ACPI_ERROR ((AE_INFO, 410 "Control Method %p has no attached object", 411 Node)); 412 return_ACPI_STATUS (AE_AML_INTERNAL); 413 } 414 415 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 416 "Control Method - %p Args %X\n", 417 Node, MethodDesc->Method.ParamCount)); 418 419 /* Get the number of arguments to expect */ 420 421 WalkState->ArgCount = MethodDesc->Method.ParamCount; 422 return_ACPI_STATUS (AE_OK); 423 } 424 425 /* 426 * Special handling if the name was not found during the lookup - 427 * some NotFound cases are allowed 428 */ 429 if (Status == AE_NOT_FOUND) 430 { 431 /* 1) NotFound is ok during load pass 1/2 (allow forward references) */ 432 433 if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) != 434 ACPI_PARSE_EXECUTE) 435 { 436 Status = AE_OK; 437 } 438 439 /* 2) NotFound during a CondRefOf(x) is ok by definition */ 440 441 else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP) 442 { 443 Status = AE_OK; 444 } 445 446 /* 447 * 3) NotFound while building a Package is ok at this point, we 448 * may flag as an error later if slack mode is not enabled. 449 * (Some ASL code depends on allowing this behavior) 450 */ 451 else if ((Arg->Common.Parent) && 452 ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 453 (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 454 { 455 Status = AE_OK; 456 } 457 } 458 459 /* Final exception check (may have been changed from code above) */ 460 461 if (ACPI_FAILURE (Status)) 462 { 463 ACPI_ERROR_NAMESPACE (Path, Status); 464 465 if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == 466 ACPI_PARSE_EXECUTE) 467 { 468 /* Report a control method execution error */ 469 470 Status = AcpiDsMethodError (Status, WalkState); 471 } 472 } 473 474 /* Save the namepath */ 475 476 Arg->Common.Value.Name = Path; 477 return_ACPI_STATUS (Status); 478 } 479 480 481 /******************************************************************************* 482 * 483 * FUNCTION: AcpiPsGetNextSimpleArg 484 * 485 * PARAMETERS: ParserState - Current parser state object 486 * ArgType - The argument type (AML_*_ARG) 487 * Arg - Where the argument is returned 488 * 489 * RETURN: None 490 * 491 * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 492 * 493 ******************************************************************************/ 494 495 void 496 AcpiPsGetNextSimpleArg ( 497 ACPI_PARSE_STATE *ParserState, 498 UINT32 ArgType, 499 ACPI_PARSE_OBJECT *Arg) 500 { 501 UINT32 Length; 502 UINT16 Opcode; 503 UINT8 *Aml = ParserState->Aml; 504 505 506 ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType); 507 508 509 switch (ArgType) 510 { 511 case ARGP_BYTEDATA: 512 513 /* Get 1 byte from the AML stream */ 514 515 Opcode = AML_BYTE_OP; 516 Arg->Common.Value.Integer = (UINT64) *Aml; 517 Length = 1; 518 break; 519 520 case ARGP_WORDDATA: 521 522 /* Get 2 bytes from the AML stream */ 523 524 Opcode = AML_WORD_OP; 525 ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); 526 Length = 2; 527 break; 528 529 case ARGP_DWORDDATA: 530 531 /* Get 4 bytes from the AML stream */ 532 533 Opcode = AML_DWORD_OP; 534 ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); 535 Length = 4; 536 break; 537 538 case ARGP_QWORDDATA: 539 540 /* Get 8 bytes from the AML stream */ 541 542 Opcode = AML_QWORD_OP; 543 ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); 544 Length = 8; 545 break; 546 547 case ARGP_CHARLIST: 548 549 /* Get a pointer to the string, point past the string */ 550 551 Opcode = AML_STRING_OP; 552 Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); 553 554 /* Find the null terminator */ 555 556 Length = 0; 557 while (Aml[Length]) 558 { 559 Length++; 560 } 561 Length++; 562 break; 563 564 case ARGP_NAME: 565 case ARGP_NAMESTRING: 566 567 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 568 Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 569 return_VOID; 570 571 default: 572 573 ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType)); 574 return_VOID; 575 } 576 577 AcpiPsInitOp (Arg, Opcode); 578 ParserState->Aml += Length; 579 return_VOID; 580 } 581 582 583 /******************************************************************************* 584 * 585 * FUNCTION: AcpiPsGetNextField 586 * 587 * PARAMETERS: ParserState - Current parser state object 588 * 589 * RETURN: A newly allocated FIELD op 590 * 591 * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField) 592 * 593 ******************************************************************************/ 594 595 static ACPI_PARSE_OBJECT * 596 AcpiPsGetNextField ( 597 ACPI_PARSE_STATE *ParserState) 598 { 599 UINT8 *Aml; 600 ACPI_PARSE_OBJECT *Field; 601 ACPI_PARSE_OBJECT *Arg = NULL; 602 UINT16 Opcode; 603 UINT32 Name; 604 UINT8 AccessType; 605 UINT8 AccessAttribute; 606 UINT8 AccessLength; 607 UINT32 PkgLength; 608 UINT8 *PkgEnd; 609 UINT32 BufferLength; 610 611 612 ACPI_FUNCTION_TRACE (PsGetNextField); 613 614 615 Aml = ParserState->Aml; 616 617 /* Determine field type */ 618 619 switch (ACPI_GET8 (ParserState->Aml)) 620 { 621 case AML_FIELD_OFFSET_OP: 622 623 Opcode = AML_INT_RESERVEDFIELD_OP; 624 ParserState->Aml++; 625 break; 626 627 case AML_FIELD_ACCESS_OP: 628 629 Opcode = AML_INT_ACCESSFIELD_OP; 630 ParserState->Aml++; 631 break; 632 633 case AML_FIELD_CONNECTION_OP: 634 635 Opcode = AML_INT_CONNECTION_OP; 636 ParserState->Aml++; 637 break; 638 639 case AML_FIELD_EXT_ACCESS_OP: 640 641 Opcode = AML_INT_EXTACCESSFIELD_OP; 642 ParserState->Aml++; 643 break; 644 645 default: 646 647 Opcode = AML_INT_NAMEDFIELD_OP; 648 break; 649 } 650 651 /* Allocate a new field op */ 652 653 Field = AcpiPsAllocOp (Opcode, Aml); 654 if (!Field) 655 { 656 return_PTR (NULL); 657 } 658 659 /* Decode the field type */ 660 661 switch (Opcode) 662 { 663 case AML_INT_NAMEDFIELD_OP: 664 665 /* Get the 4-character name */ 666 667 ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 668 AcpiPsSetName (Field, Name); 669 ParserState->Aml += ACPI_NAME_SIZE; 670 671 /* Get the length which is encoded as a package length */ 672 673 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 674 break; 675 676 677 case AML_INT_RESERVEDFIELD_OP: 678 679 /* Get the length which is encoded as a package length */ 680 681 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 682 break; 683 684 685 case AML_INT_ACCESSFIELD_OP: 686 case AML_INT_EXTACCESSFIELD_OP: 687 688 /* 689 * Get AccessType and AccessAttrib and merge into the field Op 690 * AccessType is first operand, AccessAttribute is second. stuff 691 * these bytes into the node integer value for convenience. 692 */ 693 694 /* Get the two bytes (Type/Attribute) */ 695 696 AccessType = ACPI_GET8 (ParserState->Aml); 697 ParserState->Aml++; 698 AccessAttribute = ACPI_GET8 (ParserState->Aml); 699 ParserState->Aml++; 700 701 Field->Common.Value.Integer = (UINT8) AccessType; 702 Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8); 703 704 /* This opcode has a third byte, AccessLength */ 705 706 if (Opcode == AML_INT_EXTACCESSFIELD_OP) 707 { 708 AccessLength = ACPI_GET8 (ParserState->Aml); 709 ParserState->Aml++; 710 711 Field->Common.Value.Integer |= (UINT32) (AccessLength << 16); 712 } 713 break; 714 715 716 case AML_INT_CONNECTION_OP: 717 718 /* 719 * Argument for Connection operator can be either a Buffer 720 * (resource descriptor), or a NameString. 721 */ 722 Aml = ParserState->Aml; 723 if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP) 724 { 725 ParserState->Aml++; 726 727 PkgEnd = ParserState->Aml; 728 PkgLength = AcpiPsGetNextPackageLength (ParserState); 729 PkgEnd += PkgLength; 730 731 if (ParserState->Aml < PkgEnd) 732 { 733 /* Non-empty list */ 734 735 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml); 736 if (!Arg) 737 { 738 AcpiPsFreeOp (Field); 739 return_PTR (NULL); 740 } 741 742 /* Get the actual buffer length argument */ 743 744 Opcode = ACPI_GET8 (ParserState->Aml); 745 ParserState->Aml++; 746 747 switch (Opcode) 748 { 749 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 750 751 BufferLength = ACPI_GET8 (ParserState->Aml); 752 ParserState->Aml += 1; 753 break; 754 755 case AML_WORD_OP: /* AML_WORDDATA_ARG */ 756 757 BufferLength = ACPI_GET16 (ParserState->Aml); 758 ParserState->Aml += 2; 759 break; 760 761 case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 762 763 BufferLength = ACPI_GET32 (ParserState->Aml); 764 ParserState->Aml += 4; 765 break; 766 767 default: 768 769 BufferLength = 0; 770 break; 771 } 772 773 /* Fill in bytelist data */ 774 775 Arg->Named.Value.Size = BufferLength; 776 Arg->Named.Data = ParserState->Aml; 777 } 778 779 /* Skip to End of byte data */ 780 781 ParserState->Aml = PkgEnd; 782 } 783 else 784 { 785 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml); 786 if (!Arg) 787 { 788 AcpiPsFreeOp (Field); 789 return_PTR (NULL); 790 } 791 792 /* Get the Namestring argument */ 793 794 Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 795 } 796 797 /* Link the buffer/namestring to parent (CONNECTION_OP) */ 798 799 AcpiPsAppendArg (Field, Arg); 800 break; 801 802 803 default: 804 805 /* Opcode was set in previous switch */ 806 break; 807 } 808 809 return_PTR (Field); 810 } 811 812 813 /******************************************************************************* 814 * 815 * FUNCTION: AcpiPsGetNextArg 816 * 817 * PARAMETERS: WalkState - Current state 818 * ParserState - Current parser state object 819 * ArgType - The argument type (AML_*_ARG) 820 * ReturnArg - Where the next arg is returned 821 * 822 * RETURN: Status, and an op object containing the next argument. 823 * 824 * DESCRIPTION: Get next argument (including complex list arguments that require 825 * pushing the parser stack) 826 * 827 ******************************************************************************/ 828 829 ACPI_STATUS 830 AcpiPsGetNextArg ( 831 ACPI_WALK_STATE *WalkState, 832 ACPI_PARSE_STATE *ParserState, 833 UINT32 ArgType, 834 ACPI_PARSE_OBJECT **ReturnArg) 835 { 836 ACPI_PARSE_OBJECT *Arg = NULL; 837 ACPI_PARSE_OBJECT *Prev = NULL; 838 ACPI_PARSE_OBJECT *Field; 839 UINT32 Subop; 840 ACPI_STATUS Status = AE_OK; 841 842 843 ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 844 845 846 switch (ArgType) 847 { 848 case ARGP_BYTEDATA: 849 case ARGP_WORDDATA: 850 case ARGP_DWORDDATA: 851 case ARGP_CHARLIST: 852 case ARGP_NAME: 853 case ARGP_NAMESTRING: 854 855 /* Constants, strings, and namestrings are all the same size */ 856 857 Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml); 858 if (!Arg) 859 { 860 return_ACPI_STATUS (AE_NO_MEMORY); 861 } 862 863 AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 864 break; 865 866 case ARGP_PKGLENGTH: 867 868 /* Package length, nothing returned */ 869 870 ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 871 break; 872 873 case ARGP_FIELDLIST: 874 875 if (ParserState->Aml < ParserState->PkgEnd) 876 { 877 /* Non-empty list */ 878 879 while (ParserState->Aml < ParserState->PkgEnd) 880 { 881 Field = AcpiPsGetNextField (ParserState); 882 if (!Field) 883 { 884 return_ACPI_STATUS (AE_NO_MEMORY); 885 } 886 887 if (Prev) 888 { 889 Prev->Common.Next = Field; 890 } 891 else 892 { 893 Arg = Field; 894 } 895 Prev = Field; 896 } 897 898 /* Skip to End of byte data */ 899 900 ParserState->Aml = ParserState->PkgEnd; 901 } 902 break; 903 904 case ARGP_BYTELIST: 905 906 if (ParserState->Aml < ParserState->PkgEnd) 907 { 908 /* Non-empty list */ 909 910 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, 911 ParserState->Aml); 912 if (!Arg) 913 { 914 return_ACPI_STATUS (AE_NO_MEMORY); 915 } 916 917 /* Fill in bytelist data */ 918 919 Arg->Common.Value.Size = (UINT32) 920 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml); 921 Arg->Named.Data = ParserState->Aml; 922 923 /* Skip to End of byte data */ 924 925 ParserState->Aml = ParserState->PkgEnd; 926 } 927 break; 928 929 case ARGP_TARGET: 930 case ARGP_SUPERNAME: 931 case ARGP_SIMPLENAME: 932 case ARGP_NAME_OR_REF: 933 934 Subop = AcpiPsPeekOpcode (ParserState); 935 if (Subop == 0 || 936 AcpiPsIsLeadingChar (Subop) || 937 ACPI_IS_ROOT_PREFIX (Subop) || 938 ACPI_IS_PARENT_PREFIX (Subop)) 939 { 940 /* NullName or NameString */ 941 942 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml); 943 if (!Arg) 944 { 945 return_ACPI_STATUS (AE_NO_MEMORY); 946 } 947 948 /* To support SuperName arg of Unload */ 949 950 if (WalkState->Opcode == AML_UNLOAD_OP) 951 { 952 Status = AcpiPsGetNextNamepath (WalkState, ParserState, 953 Arg, ACPI_POSSIBLE_METHOD_CALL); 954 955 /* 956 * If the SuperName argument is a method call, we have 957 * already restored the AML pointer, just free this Arg 958 */ 959 if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) 960 { 961 AcpiPsFreeOp (Arg); 962 Arg = NULL; 963 } 964 } 965 else 966 { 967 Status = AcpiPsGetNextNamepath (WalkState, ParserState, 968 Arg, ACPI_NOT_METHOD_CALL); 969 } 970 } 971 else 972 { 973 /* Single complex argument, nothing returned */ 974 975 WalkState->ArgCount = 1; 976 } 977 break; 978 979 case ARGP_DATAOBJ: 980 case ARGP_TERMARG: 981 982 /* Single complex argument, nothing returned */ 983 984 WalkState->ArgCount = 1; 985 break; 986 987 case ARGP_DATAOBJLIST: 988 case ARGP_TERMLIST: 989 case ARGP_OBJLIST: 990 991 if (ParserState->Aml < ParserState->PkgEnd) 992 { 993 /* Non-empty list of variable arguments, nothing returned */ 994 995 WalkState->ArgCount = ACPI_VAR_ARGS; 996 } 997 break; 998 999 default: 1000 1001 ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 1002 Status = AE_AML_OPERAND_TYPE; 1003 break; 1004 } 1005 1006 *ReturnArg = Arg; 1007 return_ACPI_STATUS (Status); 1008 } 1009