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