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