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 - 2026, 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 UINT32 Remaining; 201 202 203 ACPI_FUNCTION_TRACE (PsGetNextPackageLength); 204 205 206 /* 207 * Byte 0 bits [6:7] contain the number of additional bytes 208 * used to encode the package length, either 0,1,2, or 3 209 */ 210 211 /* Check if we have at least one byte to read */ 212 Remaining = (UINT32) ACPI_PTR_DIFF (ParserState->AmlEnd, Aml); 213 if (Remaining == 0) 214 { 215 return_UINT32 (0); 216 } 217 218 ByteCount = (Aml[0] >> 6); 219 220 /* Validate ByteCount and ensure we have enough bytes to read */ 221 if (ByteCount >= Remaining) 222 { 223 /* Clamp to available bytes and advance to end */ 224 ParserState->Aml = ParserState->AmlEnd; 225 return_UINT32 (0); 226 } 227 228 ParserState->Aml += ((ACPI_SIZE) ByteCount + 1); 229 230 /* Get bytes 3, 2, 1 as needed */ 231 232 while (ByteCount) 233 { 234 /* 235 * Final bit positions for the package length bytes: 236 * Byte3->[20:27] 237 * Byte2->[12:19] 238 * Byte1->[04:11] 239 * Byte0->[00:03] 240 */ 241 PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4)); 242 243 ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */ 244 ByteCount--; 245 } 246 247 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 248 249 PackageLength |= (Aml[0] & ByteZeroMask); 250 return_UINT32 (PackageLength); 251 } 252 253 254 /******************************************************************************* 255 * 256 * FUNCTION: AcpiPsGetNextPackageEnd 257 * 258 * PARAMETERS: ParserState - Current parser state object 259 * 260 * RETURN: Pointer to end-of-package +1 261 * 262 * DESCRIPTION: Get next package length and return a pointer past the end of 263 * the package. Consumes the package length field 264 * 265 ******************************************************************************/ 266 267 UINT8 * 268 AcpiPsGetNextPackageEnd ( 269 ACPI_PARSE_STATE *ParserState) 270 { 271 UINT8 *Start = ParserState->Aml; 272 UINT32 PackageLength; 273 274 275 ACPI_FUNCTION_TRACE (PsGetNextPackageEnd); 276 277 278 /* Function below updates ParserState->Aml */ 279 280 PackageLength = AcpiPsGetNextPackageLength (ParserState); 281 282 return_PTR (Start + PackageLength); /* end of package */ 283 } 284 285 286 /******************************************************************************* 287 * 288 * FUNCTION: AcpiPsGetNextNamestring 289 * 290 * PARAMETERS: ParserState - Current parser state object 291 * 292 * RETURN: Pointer to the start of the name string (pointer points into 293 * the AML. 294 * 295 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 296 * prefix characters. Set parser state to point past the string. 297 * (Name is consumed from the AML.) 298 * 299 ******************************************************************************/ 300 301 char * 302 AcpiPsGetNextNamestring ( 303 ACPI_PARSE_STATE *ParserState) 304 { 305 UINT8 *Start = ParserState->Aml; 306 UINT8 *End = ParserState->Aml; 307 308 309 ACPI_FUNCTION_TRACE (PsGetNextNamestring); 310 311 312 /* Point past any namestring prefix characters (backslash or carat) */ 313 314 while (ACPI_IS_ROOT_PREFIX (*End) || 315 ACPI_IS_PARENT_PREFIX (*End)) 316 { 317 End++; 318 } 319 320 /* Decode the path prefix character */ 321 322 switch (*End) 323 { 324 case 0: 325 326 /* NullName */ 327 328 if (End == Start) 329 { 330 Start = NULL; 331 } 332 End++; 333 break; 334 335 case AML_DUAL_NAME_PREFIX: 336 337 /* Two name segments */ 338 339 End += 1 + (2 * ACPI_NAMESEG_SIZE); 340 break; 341 342 case AML_MULTI_NAME_PREFIX: 343 344 /* Multiple name segments, 4 chars each, count in next byte */ 345 346 End += 2 + (*(End + 1) * ACPI_NAMESEG_SIZE); 347 break; 348 349 default: 350 351 /* Single name segment */ 352 353 End += ACPI_NAMESEG_SIZE; 354 break; 355 } 356 357 ParserState->Aml = End; 358 return_PTR ((char *) Start); 359 } 360 361 362 /******************************************************************************* 363 * 364 * FUNCTION: AcpiPsGetNextNamepath 365 * 366 * PARAMETERS: ParserState - Current parser state object 367 * Arg - Where the namepath will be stored 368 * ArgCount - If the namepath points to a control method 369 * the method's argument is returned here. 370 * PossibleMethodCall - Whether the namepath can possibly be the 371 * start of a method call 372 * 373 * RETURN: Status 374 * 375 * DESCRIPTION: Get next name (if method call, return # of required args). 376 * Names are looked up in the internal namespace to determine 377 * if the name represents a control method. If a method 378 * is found, the number of arguments to the method is returned. 379 * This information is critical for parsing to continue correctly. 380 * 381 ******************************************************************************/ 382 383 ACPI_STATUS 384 AcpiPsGetNextNamepath ( 385 ACPI_WALK_STATE *WalkState, 386 ACPI_PARSE_STATE *ParserState, 387 ACPI_PARSE_OBJECT *Arg, 388 BOOLEAN PossibleMethodCall) 389 { 390 ACPI_STATUS Status; 391 char *Path; 392 ACPI_PARSE_OBJECT *NameOp; 393 ACPI_OPERAND_OBJECT *MethodDesc; 394 ACPI_NAMESPACE_NODE *Node; 395 UINT8 *Start = ParserState->Aml; 396 397 398 ACPI_FUNCTION_TRACE (PsGetNextNamepath); 399 400 401 Path = AcpiPsGetNextNamestring (ParserState); 402 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 403 404 /* Null path case is allowed, just exit */ 405 406 if (!Path) 407 { 408 Arg->Common.Value.Name = Path; 409 return_ACPI_STATUS (AE_OK); 410 } 411 412 /* 413 * Lookup the name in the internal namespace, starting with the current 414 * scope. We don't want to add anything new to the namespace here, 415 * however, so we use MODE_EXECUTE. 416 * Allow searching of the parent tree, but don't open a new scope - 417 * we just want to lookup the object (must be mode EXECUTE to perform 418 * the upsearch) 419 */ 420 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 421 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 422 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 423 424 /* 425 * If this name is a control method invocation, we must 426 * setup the method call 427 */ 428 if (ACPI_SUCCESS (Status) && 429 PossibleMethodCall && 430 (Node->Type == ACPI_TYPE_METHOD)) 431 { 432 if ((GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_SUPERNAME) || 433 (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_TARGET)) 434 { 435 /* 436 * AcpiPsGetNextNamestring has increased the AML pointer past 437 * the method invocation namestring, so we need to restore the 438 * saved AML pointer back to the original method invocation 439 * namestring. 440 */ 441 WalkState->ParserState.Aml = Start; 442 WalkState->ArgCount = 1; 443 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 444 } 445 446 /* This name is actually a control method invocation */ 447 448 MethodDesc = AcpiNsGetAttachedObject (Node); 449 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 450 "Control Method invocation %4.4s - %p Desc %p Path=%p\n", 451 Node->Name.Ascii, Node, MethodDesc, Path)); 452 453 NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start); 454 if (!NameOp) 455 { 456 return_ACPI_STATUS (AE_NO_MEMORY); 457 } 458 459 /* Change Arg into a METHOD CALL and attach name to it */ 460 461 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); 462 NameOp->Common.Value.Name = Path; 463 464 /* Point METHODCALL/NAME to the METHOD Node */ 465 466 NameOp->Common.Node = Node; 467 AcpiPsAppendArg (Arg, NameOp); 468 469 if (!MethodDesc) 470 { 471 ACPI_ERROR ((AE_INFO, 472 "Control Method %p has no attached object", 473 Node)); 474 return_ACPI_STATUS (AE_AML_INTERNAL); 475 } 476 477 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 478 "Control Method - %p Args %X\n", 479 Node, MethodDesc->Method.ParamCount)); 480 481 /* Get the number of arguments to expect */ 482 483 WalkState->ArgCount = MethodDesc->Method.ParamCount; 484 return_ACPI_STATUS (AE_OK); 485 } 486 487 /* 488 * Special handling if the name was not found during the lookup - 489 * some NotFound cases are allowed 490 */ 491 if (Status == AE_NOT_FOUND) 492 { 493 /* 1) NotFound is ok during load pass 1/2 (allow forward references) */ 494 495 if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) != 496 ACPI_PARSE_EXECUTE) 497 { 498 Status = AE_OK; 499 } 500 501 /* 2) NotFound during a CondRefOf(x) is ok by definition */ 502 503 else if (WalkState->Op->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP) 504 { 505 Status = AE_OK; 506 } 507 508 /* 509 * 3) NotFound while building a Package is ok at this point, we 510 * may flag as an error later if slack mode is not enabled. 511 * (Some ASL code depends on allowing this behavior) 512 */ 513 else if ((Arg->Common.Parent) && 514 ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 515 (Arg->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))) 516 { 517 Status = AE_OK; 518 } 519 } 520 521 /* Final exception check (may have been changed from code above) */ 522 523 if (ACPI_FAILURE (Status)) 524 { 525 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status); 526 527 if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == 528 ACPI_PARSE_EXECUTE) 529 { 530 /* Report a control method execution error */ 531 532 Status = AcpiDsMethodError (Status, WalkState); 533 } 534 } 535 536 /* Save the namepath */ 537 538 Arg->Common.Value.Name = Path; 539 return_ACPI_STATUS (Status); 540 } 541 542 543 /******************************************************************************* 544 * 545 * FUNCTION: AcpiPsGetNextSimpleArg 546 * 547 * PARAMETERS: ParserState - Current parser state object 548 * ArgType - The argument type (AML_*_ARG) 549 * Arg - Where the argument is returned 550 * 551 * RETURN: None 552 * 553 * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 554 * 555 ******************************************************************************/ 556 557 void 558 AcpiPsGetNextSimpleArg ( 559 ACPI_PARSE_STATE *ParserState, 560 UINT32 ArgType, 561 ACPI_PARSE_OBJECT *Arg) 562 { 563 UINT32 Length; 564 UINT16 Opcode; 565 UINT8 *Aml = ParserState->Aml; 566 UINT32 Remaining = (UINT32) ACPI_PTR_DIFF (ParserState->AmlEnd, Aml); 567 UINT64 PartialValue; 568 569 570 ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType); 571 572 573 switch (ArgType) 574 { 575 case ARGP_BYTEDATA: 576 577 /* Get 1 byte from the AML stream */ 578 579 Opcode = AML_BYTE_OP; 580 if (Remaining >= 1) 581 { 582 Arg->Common.Value.Integer = (UINT64) *Aml; 583 Length = 1; 584 } 585 else 586 { 587 Arg->Common.Value.Integer = 0; 588 Length = 0; 589 } 590 break; 591 592 case ARGP_WORDDATA: 593 594 /* Get 2 bytes from the AML stream */ 595 596 Opcode = AML_WORD_OP; 597 if (Remaining >= 2) 598 { 599 ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); 600 Length = 2; 601 } 602 else 603 { 604 Arg->Common.Value.Integer = 0; 605 Length = 0; 606 if (Remaining > 0) 607 { 608 PartialValue = 0; 609 memcpy (&PartialValue, Aml, Remaining); 610 Arg->Common.Value.Integer = PartialValue; 611 Length = Remaining; 612 } 613 } 614 break; 615 616 case ARGP_DWORDDATA: 617 618 /* Get 4 bytes from the AML stream */ 619 620 Opcode = AML_DWORD_OP; 621 if (Remaining >= 4) 622 { 623 ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); 624 Length = 4; 625 } 626 else 627 { 628 Arg->Common.Value.Integer = 0; 629 Length = 0; 630 if (Remaining > 0) 631 { 632 PartialValue = 0; 633 memcpy (&PartialValue, Aml, Remaining); 634 Arg->Common.Value.Integer = PartialValue; 635 Length = Remaining; 636 } 637 } 638 break; 639 640 case ARGP_QWORDDATA: 641 642 /* Get 8 bytes from the AML stream */ 643 644 Opcode = AML_QWORD_OP; 645 if (Remaining >= 8) 646 { 647 ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); 648 Length = 8; 649 } 650 else 651 { 652 Arg->Common.Value.Integer = 0; 653 Length = 0; 654 if (Remaining > 0) 655 { 656 PartialValue = 0; 657 memcpy (&PartialValue, Aml, Remaining); 658 Arg->Common.Value.Integer = PartialValue; 659 Length = Remaining; 660 } 661 } 662 break; 663 664 case ARGP_CHARLIST: 665 666 /* Get a pointer to the string, point past the string */ 667 668 Opcode = AML_STRING_OP; 669 Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); 670 671 /* Find the null terminator */ 672 673 Length = 0; 674 while ((Length < Remaining) && Aml[Length]) 675 { 676 Length++; 677 } 678 if (Length < Remaining) 679 { 680 /* Account for the terminating null */ 681 Length++; 682 } 683 else 684 { 685 /* 686 * No terminator found - add null at buffer boundary 687 * and report a warning 688 */ 689 ACPI_WARNING ((AE_INFO, 690 "Invalid AML string: no null terminator, truncating at offset %u", 691 (UINT32) (Aml - ParserState->Aml))); 692 693 /* Add null terminator at the boundary */ 694 if (Remaining > 0) 695 { 696 Aml[Remaining - 1] = 0; 697 Length = Remaining; 698 } 699 } 700 break; 701 702 case ARGP_NAME: 703 case ARGP_NAMESTRING: 704 705 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); 706 Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 707 return_VOID; 708 709 default: 710 711 ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType)); 712 return_VOID; 713 } 714 715 AcpiPsInitOp (Arg, Opcode); 716 ParserState->Aml += Length; 717 return_VOID; 718 } 719 720 721 /******************************************************************************* 722 * 723 * FUNCTION: AcpiPsGetNextField 724 * 725 * PARAMETERS: ParserState - Current parser state object 726 * 727 * RETURN: A newly allocated FIELD op 728 * 729 * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField) 730 * 731 ******************************************************************************/ 732 733 static ACPI_PARSE_OBJECT * 734 AcpiPsGetNextField ( 735 ACPI_PARSE_STATE *ParserState) 736 { 737 UINT8 *Aml; 738 ACPI_PARSE_OBJECT *Field; 739 ACPI_PARSE_OBJECT *Arg = NULL; 740 UINT16 Opcode; 741 UINT32 Name; 742 UINT8 AccessType; 743 UINT8 AccessAttribute; 744 UINT8 AccessLength; 745 UINT32 PkgLength; 746 UINT8 *PkgEnd; 747 UINT32 BufferLength; 748 749 750 ACPI_FUNCTION_TRACE (PsGetNextField); 751 752 753 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 754 Aml = ParserState->Aml; 755 756 if (Aml >= ParserState->AmlEnd) 757 { 758 return_PTR (NULL); 759 } 760 761 /* Determine field type */ 762 763 switch (ACPI_GET8 (ParserState->Aml)) 764 { 765 case AML_FIELD_OFFSET_OP: 766 767 Opcode = AML_INT_RESERVEDFIELD_OP; 768 ParserState->Aml++; 769 break; 770 771 case AML_FIELD_ACCESS_OP: 772 773 Opcode = AML_INT_ACCESSFIELD_OP; 774 ParserState->Aml++; 775 break; 776 777 case AML_FIELD_CONNECTION_OP: 778 779 Opcode = AML_INT_CONNECTION_OP; 780 ParserState->Aml++; 781 break; 782 783 case AML_FIELD_EXT_ACCESS_OP: 784 785 Opcode = AML_INT_EXTACCESSFIELD_OP; 786 ParserState->Aml++; 787 break; 788 789 default: 790 791 Opcode = AML_INT_NAMEDFIELD_OP; 792 break; 793 } 794 795 /* Allocate a new field op */ 796 797 Field = AcpiPsAllocOp (Opcode, Aml); 798 if (!Field) 799 { 800 return_PTR (NULL); 801 } 802 803 /* Decode the field type */ 804 805 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 806 switch (Opcode) 807 { 808 case AML_INT_NAMEDFIELD_OP: 809 810 /* Get the 4-character name */ 811 812 if ((ParserState->Aml + ACPI_NAMESEG_SIZE) > ParserState->AmlEnd) 813 { 814 AcpiPsFreeOp (Field); 815 return_PTR (NULL); 816 } 817 ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml); 818 AcpiPsSetName (Field, Name); 819 ParserState->Aml += ACPI_NAMESEG_SIZE; 820 821 822 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 823 824 #ifdef ACPI_ASL_COMPILER 825 /* 826 * Because the package length isn't represented as a parse tree object, 827 * take comments surrounding this and add to the previously created 828 * parse node. 829 */ 830 if (Field->Common.InlineComment) 831 { 832 Field->Common.NameComment = Field->Common.InlineComment; 833 } 834 Field->Common.InlineComment = AcpiGbl_CurrentInlineComment; 835 AcpiGbl_CurrentInlineComment = NULL; 836 #endif 837 838 /* Get the length which is encoded as a package length */ 839 840 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 841 break; 842 843 844 case AML_INT_RESERVEDFIELD_OP: 845 846 /* Get the length which is encoded as a package length */ 847 848 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState); 849 break; 850 851 852 case AML_INT_ACCESSFIELD_OP: 853 case AML_INT_EXTACCESSFIELD_OP: 854 855 /* 856 * Get AccessType and AccessAttrib and merge into the field Op 857 * AccessType is first operand, AccessAttribute is second. stuff 858 * these bytes into the node integer value for convenience. 859 */ 860 861 /* Get the two bytes (Type/Attribute) */ 862 863 if ((ParserState->Aml + 2) > ParserState->AmlEnd) 864 { 865 AcpiPsFreeOp (Field); 866 return_PTR (NULL); 867 } 868 AccessType = ACPI_GET8 (ParserState->Aml); 869 ParserState->Aml++; 870 AccessAttribute = ACPI_GET8 (ParserState->Aml); 871 ParserState->Aml++; 872 873 Field->Common.Value.Integer = (UINT8) AccessType; 874 Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8); 875 876 /* This opcode has a third byte, AccessLength */ 877 878 if (Opcode == AML_INT_EXTACCESSFIELD_OP) 879 { 880 if (ParserState->Aml >= ParserState->AmlEnd) 881 { 882 AcpiPsFreeOp (Field); 883 return_PTR (NULL); 884 } 885 AccessLength = ACPI_GET8 (ParserState->Aml); 886 ParserState->Aml++; 887 888 Field->Common.Value.Integer |= (UINT32) (AccessLength << 16); 889 } 890 break; 891 892 893 case AML_INT_CONNECTION_OP: 894 895 /* 896 * Argument for Connection operator can be either a Buffer 897 * (resource descriptor), or a NameString. 898 */ 899 Aml = ParserState->Aml; 900 if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP) 901 { 902 ParserState->Aml++; 903 904 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 905 PkgEnd = ParserState->Aml; 906 PkgLength = AcpiPsGetNextPackageLength (ParserState); 907 PkgEnd += PkgLength; 908 909 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 910 if (ParserState->Aml < PkgEnd) 911 { 912 /* Non-empty list */ 913 914 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml); 915 if (!Arg) 916 { 917 AcpiPsFreeOp (Field); 918 return_PTR (NULL); 919 } 920 921 /* Get the actual buffer length argument */ 922 923 Opcode = ACPI_GET8 (ParserState->Aml); 924 ParserState->Aml++; 925 926 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 927 switch (Opcode) 928 { 929 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 930 931 BufferLength = ACPI_GET8 (ParserState->Aml); 932 ParserState->Aml += 1; 933 break; 934 935 case AML_WORD_OP: /* AML_WORDDATA_ARG */ 936 937 BufferLength = ACPI_GET16 (ParserState->Aml); 938 ParserState->Aml += 2; 939 break; 940 941 case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 942 943 BufferLength = ACPI_GET32 (ParserState->Aml); 944 ParserState->Aml += 4; 945 break; 946 947 default: 948 949 BufferLength = 0; 950 break; 951 } 952 953 /* Fill in bytelist data */ 954 955 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState); 956 Arg->Named.Value.Size = BufferLength; 957 Arg->Named.Data = ParserState->Aml; 958 } 959 960 /* Skip to End of byte data */ 961 962 ParserState->Aml = PkgEnd; 963 } 964 else 965 { 966 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml); 967 if (!Arg) 968 { 969 AcpiPsFreeOp (Field); 970 return_PTR (NULL); 971 } 972 973 /* Get the Namestring argument */ 974 975 Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); 976 } 977 978 /* Link the buffer/namestring to parent (CONNECTION_OP) */ 979 980 AcpiPsAppendArg (Field, Arg); 981 break; 982 983 984 default: 985 986 /* Opcode was set in previous switch */ 987 break; 988 } 989 990 return_PTR (Field); 991 } 992 993 /******************************************************************************* 994 * 995 * FUNCTION: AcpiPsFreeFieldList 996 * 997 * PARAMETERS: Start - First Op in field list 998 * 999 * RETURN: None. 1000 * 1001 * DESCRIPTION: Free all Op objects inside a field list. 1002 * 1003 ******************************************************************************/ 1004 1005 static void 1006 AcpiPsFreeFieldList ( 1007 ACPI_PARSE_OBJECT *Start) 1008 { 1009 ACPI_PARSE_OBJECT *Current = Start; 1010 ACPI_PARSE_OBJECT *Next; 1011 ACPI_PARSE_OBJECT *Arg; 1012 1013 while (Current) 1014 { 1015 Next = Current->Common.Next; 1016 1017 /* AML_INT_CONNECTION_OP can have a single argument */ 1018 1019 Arg = AcpiPsGetArg (Current, 0); 1020 if (Arg) 1021 { 1022 AcpiPsFreeOp (Arg); 1023 } 1024 1025 AcpiPsFreeOp(Current); 1026 Current = Next; 1027 } 1028 } 1029 1030 1031 /******************************************************************************* 1032 * 1033 * FUNCTION: AcpiPsGetNextArg 1034 * 1035 * PARAMETERS: WalkState - Current state 1036 * ParserState - Current parser state object 1037 * ArgType - The argument type (AML_*_ARG) 1038 * ReturnArg - Where the next arg is returned 1039 * 1040 * RETURN: Status, and an op object containing the next argument. 1041 * 1042 * DESCRIPTION: Get next argument (including complex list arguments that require 1043 * pushing the parser stack) 1044 * 1045 ******************************************************************************/ 1046 1047 ACPI_STATUS 1048 AcpiPsGetNextArg ( 1049 ACPI_WALK_STATE *WalkState, 1050 ACPI_PARSE_STATE *ParserState, 1051 UINT32 ArgType, 1052 ACPI_PARSE_OBJECT **ReturnArg) 1053 { 1054 ACPI_PARSE_OBJECT *Arg = NULL; 1055 ACPI_PARSE_OBJECT *Prev = NULL; 1056 ACPI_PARSE_OBJECT *Field; 1057 UINT32 Subop; 1058 ACPI_STATUS Status = AE_OK; 1059 1060 1061 ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); 1062 1063 1064 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1065 "Expected argument type ARGP: %s (%2.2X)\n", 1066 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 1067 1068 switch (ArgType) 1069 { 1070 case ARGP_BYTEDATA: 1071 case ARGP_WORDDATA: 1072 case ARGP_DWORDDATA: 1073 case ARGP_CHARLIST: 1074 case ARGP_NAME: 1075 case ARGP_NAMESTRING: 1076 1077 /* Constants, strings, and namestrings are all the same size */ 1078 1079 Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml); 1080 if (!Arg) 1081 { 1082 return_ACPI_STATUS (AE_NO_MEMORY); 1083 } 1084 1085 AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); 1086 break; 1087 1088 case ARGP_PKGLENGTH: 1089 1090 /* Package length, nothing returned */ 1091 1092 ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); 1093 break; 1094 1095 case ARGP_FIELDLIST: 1096 1097 if (ParserState->Aml < ParserState->PkgEnd) 1098 { 1099 /* Non-empty list */ 1100 1101 while (ParserState->Aml < ParserState->PkgEnd) 1102 { 1103 Field = AcpiPsGetNextField (ParserState); 1104 if (!Field) 1105 { 1106 if (Arg) 1107 { 1108 AcpiPsFreeFieldList(Arg); 1109 } 1110 1111 return_ACPI_STATUS (AE_NO_MEMORY); 1112 } 1113 1114 if (Prev) 1115 { 1116 Prev->Common.Next = Field; 1117 } 1118 else 1119 { 1120 Arg = Field; 1121 } 1122 Prev = Field; 1123 } 1124 1125 /* Skip to End of byte data */ 1126 1127 ParserState->Aml = ParserState->PkgEnd; 1128 } 1129 break; 1130 1131 case ARGP_BYTELIST: 1132 1133 if (ParserState->Aml < ParserState->PkgEnd) 1134 { 1135 /* Non-empty list */ 1136 1137 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, 1138 ParserState->Aml); 1139 if (!Arg) 1140 { 1141 return_ACPI_STATUS (AE_NO_MEMORY); 1142 } 1143 1144 /* Fill in bytelist data */ 1145 1146 Arg->Common.Value.Size = (UINT32) 1147 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml); 1148 Arg->Named.Data = ParserState->Aml; 1149 1150 /* Skip to End of byte data */ 1151 1152 ParserState->Aml = ParserState->PkgEnd; 1153 } 1154 break; 1155 1156 case ARGP_SIMPLENAME: 1157 case ARGP_NAME_OR_REF: 1158 1159 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1160 "**** SimpleName/NameOrRef: %s (%2.2X)\n", 1161 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 1162 1163 Subop = AcpiPsPeekOpcode (ParserState); 1164 if (Subop == 0 || 1165 AcpiPsIsLeadingChar (Subop) || 1166 ACPI_IS_ROOT_PREFIX (Subop) || 1167 ACPI_IS_PARENT_PREFIX (Subop)) 1168 { 1169 /* NullName or NameString */ 1170 1171 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml); 1172 if (!Arg) 1173 { 1174 return_ACPI_STATUS (AE_NO_MEMORY); 1175 } 1176 1177 Status = AcpiPsGetNextNamepath (WalkState, ParserState, 1178 Arg, ACPI_NOT_METHOD_CALL); 1179 if (ACPI_FAILURE(Status)) 1180 { 1181 AcpiPsFreeOp (Arg); 1182 return_ACPI_STATUS (Status); 1183 } 1184 } 1185 else 1186 { 1187 /* Single complex argument, nothing returned */ 1188 1189 WalkState->ArgCount = 1; 1190 } 1191 break; 1192 1193 case ARGP_TARGET: 1194 case ARGP_SUPERNAME: 1195 1196 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1197 "**** Target/Supername: %s (%2.2X)\n", 1198 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 1199 1200 Subop = AcpiPsPeekOpcode (ParserState); 1201 if (Subop == 0 || 1202 AcpiPsIsLeadingChar (Subop) || 1203 ACPI_IS_ROOT_PREFIX (Subop) || 1204 ACPI_IS_PARENT_PREFIX (Subop)) 1205 { 1206 /* NULL target (zero). Convert to a NULL namepath */ 1207 1208 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml); 1209 if (!Arg) 1210 { 1211 return_ACPI_STATUS (AE_NO_MEMORY); 1212 } 1213 1214 Status = AcpiPsGetNextNamepath (WalkState, ParserState, 1215 Arg, ACPI_POSSIBLE_METHOD_CALL); 1216 if (ACPI_FAILURE(Status)) 1217 { 1218 AcpiPsFreeOp (Arg); 1219 return_ACPI_STATUS (Status); 1220 } 1221 1222 if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) 1223 { 1224 /* Free method call op and corresponding namestring sub-ob */ 1225 1226 AcpiPsFreeOp (Arg->Common.Value.Arg); 1227 AcpiPsFreeOp (Arg); 1228 Arg = NULL; 1229 WalkState->ArgCount = 1; 1230 } 1231 } 1232 else 1233 { 1234 /* Single complex argument, nothing returned */ 1235 1236 WalkState->ArgCount = 1; 1237 } 1238 break; 1239 1240 case ARGP_DATAOBJ: 1241 case ARGP_TERMARG: 1242 1243 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1244 "**** TermArg/DataObj: %s (%2.2X)\n", 1245 AcpiUtGetArgumentTypeName (ArgType), ArgType)); 1246 1247 /* Single complex argument, nothing returned */ 1248 1249 WalkState->ArgCount = 1; 1250 break; 1251 1252 case ARGP_DATAOBJLIST: 1253 case ARGP_TERMLIST: 1254 case ARGP_OBJLIST: 1255 1256 if (ParserState->Aml < ParserState->PkgEnd) 1257 { 1258 /* Non-empty list of variable arguments, nothing returned */ 1259 1260 WalkState->ArgCount = ACPI_VAR_ARGS; 1261 } 1262 break; 1263 1264 default: 1265 1266 ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType)); 1267 Status = AE_AML_OPERAND_TYPE; 1268 break; 1269 } 1270 1271 *ReturnArg = Arg; 1272 return_ACPI_STATUS (Status); 1273 } 1274