1/****************************************************************************** 2 * 3 * Module Name: asloperands - AML operand processing 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116#include "aslcompiler.h" 117#include "aslcompiler.y.h" 118#include "amlcode.h" 119 120#define _COMPONENT ACPI_COMPILER 121 ACPI_MODULE_NAME ("asloperands") 122 123/* Local prototypes */ 124 125static void 126OpnDoField ( 127 ACPI_PARSE_OBJECT *Op); 128 129static void 130OpnDoBankField ( 131 ACPI_PARSE_OBJECT *Op); 132 133static void 134OpnDoBuffer ( 135 ACPI_PARSE_OBJECT *Op); 136 137static void 138OpnDoDefinitionBlock ( 139 ACPI_PARSE_OBJECT *Op); 140 141static void 142OpnDoFieldCommon ( 143 ACPI_PARSE_OBJECT *FieldOp, 144 ACPI_PARSE_OBJECT *Op); 145 146static void 147OpnDoIndexField ( 148 ACPI_PARSE_OBJECT *Op); 149 150static void 151OpnDoLoadTable ( 152 ACPI_PARSE_OBJECT *Op); 153 154static void 155OpnDoMethod ( 156 ACPI_PARSE_OBJECT *Op); 157 158static void 159OpnDoMutex ( 160 ACPI_PARSE_OBJECT *Op); 161 162static void 163OpnDoRegion ( 164 ACPI_PARSE_OBJECT *Op); 165 166static void 167OpnAttachNameToNode ( 168 ACPI_PARSE_OBJECT *Op); 169 170 171/******************************************************************************* 172 * 173 * FUNCTION: OpnDoMutex 174 * 175 * PARAMETERS: Op - The parent parse node 176 * 177 * RETURN: None 178 * 179 * DESCRIPTION: Construct the operands for the MUTEX ASL keyword. 180 * 181 ******************************************************************************/ 182 183static void 184OpnDoMutex ( 185 ACPI_PARSE_OBJECT *Op) 186{ 187 ACPI_PARSE_OBJECT *Next; 188 189 190 Next = Op->Asl.Child; 191 Next = Next->Asl.Next; 192 193 if (Next->Asl.Value.Integer > 15) 194 { 195 AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL); 196 } 197 return; 198} 199 200 201/******************************************************************************* 202 * 203 * FUNCTION: OpnDoMethod 204 * 205 * PARAMETERS: Op - The parent parse node 206 * 207 * RETURN: None 208 * 209 * DESCRIPTION: Construct the operands for the METHOD ASL keyword. 210 * 211 ******************************************************************************/ 212 213static void 214OpnDoMethod ( 215 ACPI_PARSE_OBJECT *Op) 216{ 217 ACPI_PARSE_OBJECT *Next; 218 219 /* Optional arguments for this opcode with defaults */ 220 221 UINT8 NumArgs = 0; 222 UINT8 Serialized = 0; 223 UINT8 Concurrency = 0; 224 UINT8 MethodFlags; 225 226 227 /* Opcode and package length first */ 228 /* Method name */ 229 230 Next = Op->Asl.Child; 231 232 /* Num args */ 233 234 Next = Next->Asl.Next; 235 if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 236 { 237 NumArgs = (UINT8) Next->Asl.Value.Integer; 238 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 239 } 240 241 /* Serialized Flag */ 242 243 Next = Next->Asl.Next; 244 if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 245 { 246 Serialized = (UINT8) Next->Asl.Value.Integer; 247 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 248 } 249 250 /* Concurrency value (valid values are 0-15) */ 251 252 Next = Next->Asl.Next; 253 if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 254 { 255 /* This is a ByteConstExpr, so eval the constant now */ 256 257 OpcAmlConstantWalk (Next, 0, NULL); 258 259 if (Next->Asl.Value.Integer > 15) 260 { 261 AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL); 262 } 263 264 Concurrency = (UINT8) Next->Asl.Value.Integer; 265 } 266 267 /* Put the bits in their proper places */ 268 269 MethodFlags = (UINT8) 270 ((NumArgs & 0x7) | 271 ((Serialized & 0x1) << 3) | 272 ((Concurrency & 0xF) << 4)); 273 274 /* Use the last node for the combined flags byte */ 275 276 Next->Asl.Value.Integer = MethodFlags; 277 Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 278 Next->Asl.AmlLength = 1; 279 Next->Asl.ParseOpcode = PARSEOP_RAW_DATA; 280 281 /* Save the arg count in the first node */ 282 283 Op->Asl.Extra = NumArgs; 284} 285 286 287/******************************************************************************* 288 * 289 * FUNCTION: OpnDoFieldCommon 290 * 291 * PARAMETERS: FieldOp - Node for an ASL field 292 * Op - The parent parse node 293 * 294 * RETURN: None 295 * 296 * DESCRIPTION: Construct the AML operands for the various field keywords, 297 * FIELD, BANKFIELD, INDEXFIELD 298 * 299 ******************************************************************************/ 300 301static void 302OpnDoFieldCommon ( 303 ACPI_PARSE_OBJECT *FieldOp, 304 ACPI_PARSE_OBJECT *Op) 305{ 306 ACPI_PARSE_OBJECT *Next; 307 ACPI_PARSE_OBJECT *PkgLengthNode; 308 UINT32 CurrentBitOffset; 309 UINT32 NewBitOffset; 310 UINT8 AccessType; 311 UINT8 LockRule; 312 UINT8 UpdateRule; 313 UINT8 FieldFlags; 314 UINT32 MinimumLength; 315 316 317 /* AccessType -- not optional, so no need to check for DEFAULT_ARG */ 318 319 AccessType = (UINT8) Op->Asl.Value.Integer; 320 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 321 322 /* Set the access type in the parent (field) node for use later */ 323 324 FieldOp->Asl.Value.Integer = AccessType; 325 326 /* LockRule -- not optional, so no need to check for DEFAULT_ARG */ 327 328 Next = Op->Asl.Next; 329 LockRule = (UINT8) Next->Asl.Value.Integer; 330 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 331 332 /* UpdateRule -- not optional, so no need to check for DEFAULT_ARG */ 333 334 Next = Next->Asl.Next; 335 UpdateRule = (UINT8) Next->Asl.Value.Integer; 336 337 /* 338 * Generate the flags byte. The various fields are already 339 * in the right bit position via translation from the 340 * keywords by the parser. 341 */ 342 FieldFlags = (UINT8) (AccessType | LockRule | UpdateRule); 343 344 /* Use the previous node to be the FieldFlags node */ 345 346 /* Set the node to RAW_DATA */ 347 348 Next->Asl.Value.Integer = FieldFlags; 349 Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 350 Next->Asl.AmlLength = 1; 351 Next->Asl.ParseOpcode = PARSEOP_RAW_DATA; 352 353 /* Process the FieldUnitList */ 354 355 Next = Next->Asl.Next; 356 CurrentBitOffset = 0; 357 358 while (Next) 359 { 360 /* Save the offset of this field unit */ 361 362 Next->Asl.ExtraValue = CurrentBitOffset; 363 364 switch (Next->Asl.ParseOpcode) 365 { 366 case PARSEOP_ACCESSAS: 367 368 PkgLengthNode = Next->Asl.Child; 369 AccessType = (UINT8) PkgLengthNode->Asl.Value.Integer; 370 371 /* Nothing additional to do */ 372 break; 373 374 case PARSEOP_OFFSET: 375 376 /* New offset into the field */ 377 378 PkgLengthNode = Next->Asl.Child; 379 NewBitOffset = ((UINT32) PkgLengthNode->Asl.Value.Integer) * 8; 380 381 /* 382 * Examine the specified offset in relation to the 383 * current offset counter. 384 */ 385 if (NewBitOffset < CurrentBitOffset) 386 { 387 /* 388 * Not allowed to specify a backwards offset! 389 * Issue error and ignore this node. 390 */ 391 AslError (ASL_ERROR, ASL_MSG_BACKWARDS_OFFSET, PkgLengthNode, 392 NULL); 393 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 394 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 395 } 396 else if (NewBitOffset == CurrentBitOffset) 397 { 398 /* 399 * Offset is redundant; we don't need to output an 400 * offset opcode. Just set these nodes to default 401 */ 402 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 403 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 404 } 405 else 406 { 407 /* 408 * Valid new offset - set the value to be inserted into the AML 409 * and update the offset counter. 410 */ 411 PkgLengthNode->Asl.Value.Integer = 412 NewBitOffset - CurrentBitOffset; 413 CurrentBitOffset = NewBitOffset; 414 } 415 break; 416 417 case PARSEOP_NAMESEG: 418 case PARSEOP_RESERVED_BYTES: 419 420 /* Named or reserved field entry */ 421 422 PkgLengthNode = Next->Asl.Child; 423 NewBitOffset = (UINT32) PkgLengthNode->Asl.Value.Integer; 424 CurrentBitOffset += NewBitOffset; 425 426 /* Save the current AccessAs value for error checking later */ 427 428 switch (AccessType) 429 { 430 case AML_FIELD_ACCESS_ANY: 431 case AML_FIELD_ACCESS_BYTE: 432 case AML_FIELD_ACCESS_BUFFER: 433 default: 434 435 MinimumLength = 8; 436 break; 437 438 case AML_FIELD_ACCESS_WORD: 439 MinimumLength = 16; 440 break; 441 442 case AML_FIELD_ACCESS_DWORD: 443 MinimumLength = 32; 444 break; 445 446 case AML_FIELD_ACCESS_QWORD: 447 MinimumLength = 64; 448 break; 449 } 450 451 PkgLengthNode->Asl.ExtraValue = MinimumLength; 452 break; 453 454 default: 455 456 /* All supported field opcodes must appear above */ 457 458 break; 459 } 460 461 /* Move on to next entry in the field list */ 462 463 Next = Next->Asl.Next; 464 } 465} 466 467 468/******************************************************************************* 469 * 470 * FUNCTION: OpnDoField 471 * 472 * PARAMETERS: Op - The parent parse node 473 * 474 * RETURN: None 475 * 476 * DESCRIPTION: Construct the AML operands for the FIELD ASL keyword 477 * 478 ******************************************************************************/ 479 480static void 481OpnDoField ( 482 ACPI_PARSE_OBJECT *Op) 483{ 484 ACPI_PARSE_OBJECT *Next; 485 486 487 /* Opcode is parent node */ 488 /* First child is field name */ 489 490 Next = Op->Asl.Child; 491 492 /* Second child is the AccessType */ 493 494 OpnDoFieldCommon (Op, Next->Asl.Next); 495} 496 497 498/******************************************************************************* 499 * 500 * FUNCTION: OpnDoIndexField 501 * 502 * PARAMETERS: Op - The parent parse node 503 * 504 * RETURN: None 505 * 506 * DESCRIPTION: Construct the AML operands for the INDEXFIELD ASL keyword 507 * 508 ******************************************************************************/ 509 510static void 511OpnDoIndexField ( 512 ACPI_PARSE_OBJECT *Op) 513{ 514 ACPI_PARSE_OBJECT *Next; 515 516 517 /* Opcode is parent node */ 518 /* First child is the index name */ 519 520 Next = Op->Asl.Child; 521 522 /* Second child is the data name */ 523 524 Next = Next->Asl.Next; 525 526 /* Third child is the AccessType */ 527 528 OpnDoFieldCommon (Op, Next->Asl.Next); 529} 530 531 532/******************************************************************************* 533 * 534 * FUNCTION: OpnDoBankField 535 * 536 * PARAMETERS: Op - The parent parse node 537 * 538 * RETURN: None 539 * 540 * DESCRIPTION: Construct the AML operands for the BANKFIELD ASL keyword 541 * 542 ******************************************************************************/ 543 544static void 545OpnDoBankField ( 546 ACPI_PARSE_OBJECT *Op) 547{ 548 ACPI_PARSE_OBJECT *Next; 549 550 551 /* Opcode is parent node */ 552 /* First child is the region name */ 553 554 Next = Op->Asl.Child; 555 556 /* Second child is the bank name */ 557 558 Next = Next->Asl.Next; 559 560 /* Third child is the bank value */ 561 562 Next = Next->Asl.Next; 563 564 /* Fourth child is the AccessType */ 565 566 OpnDoFieldCommon (Op, Next->Asl.Next); 567} 568 569 570/******************************************************************************* 571 * 572 * FUNCTION: OpnDoRegion 573 * 574 * PARAMETERS: Op - The parent parse node 575 * 576 * RETURN: None 577 * 578 * DESCRIPTION: Tries to get the length of the region. Can only do this at 579 * compile time if the length is a constant. 580 * 581 ******************************************************************************/ 582 583static void 584OpnDoRegion ( 585 ACPI_PARSE_OBJECT *Op) 586{ 587 ACPI_PARSE_OBJECT *Next; 588 589 590 /* Opcode is parent node */ 591 /* First child is the region name */ 592 593 Next = Op->Asl.Child; 594 595 /* Second child is the space ID*/ 596 597 Next = Next->Asl.Next; 598 599 /* Third child is the region offset */ 600 601 Next = Next->Asl.Next; 602 603 /* Fourth child is the region length */ 604 605 Next = Next->Asl.Next; 606 if (Next->Asl.ParseOpcode == PARSEOP_INTEGER) 607 { 608 Op->Asl.Value.Integer = Next->Asl.Value.Integer; 609 } 610 else 611 { 612 Op->Asl.Value.Integer = ACPI_UINT64_MAX; 613 } 614} 615 616 617/******************************************************************************* 618 * 619 * FUNCTION: OpnDoBuffer 620 * 621 * PARAMETERS: Op - The parent parse node 622 * 623 * RETURN: None 624 * 625 * DESCRIPTION: Construct the AML operands for the BUFFER ASL keyword. We 626 * build a single raw byte buffer from the initialization nodes, 627 * each parse node contains a buffer byte. 628 * 629 ******************************************************************************/ 630 631static void 632OpnDoBuffer ( 633 ACPI_PARSE_OBJECT *Op) 634{ 635 ACPI_PARSE_OBJECT *InitializerOp; 636 ACPI_PARSE_OBJECT *BufferLengthOp; 637 638 /* Optional arguments for this opcode with defaults */ 639 640 UINT32 BufferLength = 0; 641 642 643 /* Opcode and package length first */ 644 /* Buffer Length is next, followed by the initializer list */ 645 646 BufferLengthOp = Op->Asl.Child; 647 InitializerOp = BufferLengthOp->Asl.Next; 648 649 /* 650 * If the BufferLength is not an INTEGER or was not specified in the ASL 651 * (DEFAULT_ARG), it is a TermArg that is 652 * evaluated at run-time, and we are therefore finished. 653 */ 654 if ((BufferLengthOp->Asl.ParseOpcode != PARSEOP_INTEGER) && 655 (BufferLengthOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 656 { 657 return; 658 } 659 660 /* 661 * We want to count the number of items in the initializer list, because if 662 * it is larger than the buffer length, we will define the buffer size 663 * to be the size of the initializer list (as per the ACPI Specification) 664 */ 665 switch (InitializerOp->Asl.ParseOpcode) 666 { 667 case PARSEOP_INTEGER: 668 case PARSEOP_BYTECONST: 669 case PARSEOP_WORDCONST: 670 case PARSEOP_DWORDCONST: 671 672 /* The peer list contains the byte list (if any...) */ 673 674 while (InitializerOp) 675 { 676 /* For buffers, this is a list of raw bytes */ 677 678 InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 679 InitializerOp->Asl.AmlLength = 1; 680 InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 681 682 BufferLength++; 683 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 684 } 685 break; 686 687 case PARSEOP_STRING_LITERAL: 688 689 /* 690 * Only one initializer, the string. Buffer must be big enough to hold 691 * the string plus the null termination byte 692 */ 693 BufferLength = strlen (InitializerOp->Asl.Value.String) + 1; 694 695 InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 696 InitializerOp->Asl.AmlLength = BufferLength; 697 InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 698 break; 699 700 case PARSEOP_RAW_DATA: 701 702 /* Buffer nodes are already initialized (e.g. Unicode operator) */ 703 return; 704 705 case PARSEOP_DEFAULT_ARG: 706 break; 707 708 default: 709 710 AslError (ASL_ERROR, ASL_MSG_INVALID_OPERAND, InitializerOp, 711 "Unknown buffer initializer opcode"); 712 printf ("Unknown buffer initializer opcode [%s]\n", 713 UtGetOpName (InitializerOp->Asl.ParseOpcode)); 714 return; 715 } 716 717 /* Check if initializer list is longer than the buffer length */ 718 719 if (BufferLengthOp->Asl.Value.Integer > BufferLength) 720 { 721 BufferLength = (UINT32) BufferLengthOp->Asl.Value.Integer; 722 } 723 724 if (!BufferLength) 725 { 726 /* No length AND no items -- issue notice */ 727 728 AslError (ASL_REMARK, ASL_MSG_BUFFER_LENGTH, BufferLengthOp, NULL); 729 730 /* But go ahead and put the buffer length of zero into the AML */ 731 } 732 733 /* 734 * Just set the buffer size node to be the buffer length, regardless 735 * of whether it was previously an integer or a default_arg placeholder 736 */ 737 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 738 BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP; 739 BufferLengthOp->Asl.Value.Integer = BufferLength; 740 741 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 742 743 /* Remaining nodes are handled via the tree walk */ 744} 745 746 747/******************************************************************************* 748 * 749 * FUNCTION: OpnDoPackage 750 * 751 * PARAMETERS: Op - The parent parse node 752 * 753 * RETURN: None 754 * 755 * DESCRIPTION: Construct the AML operands for the PACKAGE ASL keyword. NOTE: 756 * can only be called after constants have been folded, to ensure 757 * that the PackageLength operand has been fully reduced. 758 * 759 ******************************************************************************/ 760 761void 762OpnDoPackage ( 763 ACPI_PARSE_OBJECT *Op) 764{ 765 ACPI_PARSE_OBJECT *InitializerOp; 766 ACPI_PARSE_OBJECT *PackageLengthOp; 767 UINT32 PackageLength = 0; 768 769 770 /* Opcode and package length first, followed by the initializer list */ 771 772 PackageLengthOp = Op->Asl.Child; 773 InitializerOp = PackageLengthOp->Asl.Next; 774 775 /* Count the number of items in the initializer list */ 776 777 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 778 { 779 /* The peer list contains the byte list (if any...) */ 780 781 while (InitializerOp) 782 { 783 PackageLength++; 784 InitializerOp = InitializerOp->Asl.Next; 785 } 786 } 787 788 /* If package length is a constant, compare to the initializer list */ 789 790 if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) || 791 (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST)) 792 { 793 if (PackageLengthOp->Asl.Value.Integer > PackageLength) 794 { 795 /* 796 * Allow package length to be longer than the initializer 797 * list -- but if the length of initializer list is nonzero, 798 * issue a message since this is probably a coding error, 799 * even though technically legal. 800 */ 801 if (PackageLength > 0) 802 { 803 AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, 804 PackageLengthOp, NULL); 805 } 806 807 PackageLength = (UINT32) PackageLengthOp->Asl.Value.Integer; 808 } 809 else if (PackageLengthOp->Asl.Value.Integer < PackageLength) 810 { 811 /* 812 * The package length is smaller than the length of the 813 * initializer list. This is an error as per the ACPI spec. 814 */ 815 AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, 816 PackageLengthOp, NULL); 817 } 818 } 819 820 if (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 821 { 822 /* 823 * This is the case if the PackageLength was left empty - Package() 824 * The package length becomes the length of the initializer list 825 */ 826 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_INTEGER; 827 Op->Asl.Child->Asl.Value.Integer = PackageLength; 828 829 /* Set the AML opcode */ 830 831 (void) OpcSetOptimalIntegerSize (Op->Asl.Child); 832 } 833 834 /* If not a variable-length package, check for a zero package length */ 835 836 if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) || 837 (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST) || 838 (PackageLengthOp->Asl.ParseOpcode == PARSEOP_ZERO) || 839 (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)) 840 { 841 if (!PackageLength) 842 { 843 /* No length AND no initializer list -- issue a remark */ 844 845 AslError (ASL_REMARK, ASL_MSG_PACKAGE_LENGTH, 846 PackageLengthOp, NULL); 847 848 /* But go ahead and put the buffer length of zero into the AML */ 849 } 850 } 851 852 /* 853 * If the PackageLength is a constant <= 255, we can change the 854 * AML opcode from VarPackage to a simple (ACPI 1.0) Package opcode. 855 */ 856 if (((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) && 857 (Op->Asl.Child->Asl.Value.Integer <= 255)) || 858 (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONE) || 859 (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONES)|| 860 (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ZERO)) 861 { 862 Op->Asl.AmlOpcode = AML_PACKAGE_OP; 863 Op->Asl.ParseOpcode = PARSEOP_PACKAGE; 864 865 /* 866 * Just set the package size node to be the package length, regardless 867 * of whether it was previously an integer or a default_arg placeholder 868 */ 869 PackageLengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 870 PackageLengthOp->Asl.AmlLength = 1; 871 PackageLengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 872 PackageLengthOp->Asl.Value.Integer = PackageLength; 873 } 874 875 /* Remaining nodes are handled via the tree walk */ 876} 877 878 879/******************************************************************************* 880 * 881 * FUNCTION: OpnDoLoadTable 882 * 883 * PARAMETERS: Op - The parent parse node 884 * 885 * RETURN: None 886 * 887 * DESCRIPTION: Construct the AML operands for the LOADTABLE ASL keyword. 888 * 889 ******************************************************************************/ 890 891static void 892OpnDoLoadTable ( 893 ACPI_PARSE_OBJECT *Op) 894{ 895 ACPI_PARSE_OBJECT *Next; 896 897 898 /* Opcode is parent node */ 899 /* First child is the table signature */ 900 901 Next = Op->Asl.Child; 902 903 /* Second child is the OEM ID*/ 904 905 Next = Next->Asl.Next; 906 907 /* Third child is the OEM table ID */ 908 909 Next = Next->Asl.Next; 910 911 /* Fourth child is the RootPath string */ 912 913 Next = Next->Asl.Next; 914 if (Next->Asl.ParseOpcode == PARSEOP_ZERO) 915 { 916 Next->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; 917 Next->Asl.Value.String = "\\"; 918 Next->Asl.AmlLength = 2; 919 OpcGenerateAmlOpcode (Next); 920 } 921 922#ifdef ASL_FUTURE_IMPLEMENTATION 923 924 /* TBD: NOT IMPLEMENTED */ 925 /* Fifth child is the [optional] ParameterPathString */ 926 /* Sixth child is the [optional] ParameterData */ 927 928 Next = Next->Asl.Next; 929 if (Next->Asl.ParseOpcode == DEFAULT_ARG) 930 { 931 Next->Asl.AmlLength = 1; 932 Next->Asl.ParseOpcode = ZERO; 933 OpcGenerateAmlOpcode (Next); 934 } 935 936 937 Next = Next->Asl.Next; 938 if (Next->Asl.ParseOpcode == DEFAULT_ARG) 939 { 940 Next->Asl.AmlLength = 1; 941 Next->Asl.ParseOpcode = ZERO; 942 OpcGenerateAmlOpcode (Next); 943 } 944#endif 945} 946 947 948/******************************************************************************* 949 * 950 * FUNCTION: OpnDoDefinitionBlock 951 * 952 * PARAMETERS: Op - The parent parse node 953 * 954 * RETURN: None 955 * 956 * DESCRIPTION: Construct the AML operands for the DEFINITIONBLOCK ASL keyword 957 * 958 ******************************************************************************/ 959 960static void 961OpnDoDefinitionBlock ( 962 ACPI_PARSE_OBJECT *Op) 963{ 964 ACPI_PARSE_OBJECT *Child; 965 ACPI_SIZE Length; 966 UINT32 i; 967 char *Filename; 968 969 970 /* 971 * These nodes get stuffed into the table header. They are special 972 * cased when the table is written to the output file. 973 * 974 * Mark all of these nodes as non-usable so they won't get output 975 * as AML opcodes! 976 */ 977 978 /* Get AML filename. Use it if non-null */ 979 980 Child = Op->Asl.Child; 981 if (Child->Asl.Value.Buffer && 982 *Child->Asl.Value.Buffer && 983 (Gbl_UseDefaultAmlFilename)) 984 { 985 /* 986 * We will use the AML filename that is embedded in the source file 987 * for the output filename. 988 */ 989 Filename = UtStringCacheCalloc (strlen (Gbl_DirectoryPath) + 990 strlen ((char *) Child->Asl.Value.Buffer) + 1); 991 992 /* Prepend the current directory path */ 993 994 strcpy (Filename, Gbl_DirectoryPath); 995 strcat (Filename, (char *) Child->Asl.Value.Buffer); 996 997 Gbl_OutputFilenamePrefix = Filename; 998 UtConvertBackslashes (Gbl_OutputFilenamePrefix); 999 } 1000 1001 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1002 1003 /* Signature */ 1004 1005 Child = Child->Asl.Next; 1006 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1007 if (Child->Asl.Value.String) 1008 { 1009 Gbl_TableSignature = Child->Asl.Value.String; 1010 if (strlen (Gbl_TableSignature) != ACPI_NAME_SIZE) 1011 { 1012 AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child, 1013 "Length is not exactly 4"); 1014 } 1015 1016 for (i = 0; i < ACPI_NAME_SIZE; i++) 1017 { 1018 if (!isalnum ((int) Gbl_TableSignature[i])) 1019 { 1020 AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child, 1021 "Contains non-alphanumeric characters"); 1022 } 1023 } 1024 } 1025 1026 /* Revision */ 1027 1028 Child = Child->Asl.Next; 1029 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1030 /* 1031 * We used the revision to set the integer width earlier 1032 */ 1033 1034 /* OEMID */ 1035 1036 Child = Child->Asl.Next; 1037 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1038 1039 /* OEM TableID */ 1040 1041 Child = Child->Asl.Next; 1042 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1043 if (Child->Asl.Value.String) 1044 { 1045 Length = strlen (Child->Asl.Value.String); 1046 Gbl_TableId = UtStringCacheCalloc (Length + 1); 1047 strcpy (Gbl_TableId, Child->Asl.Value.String); 1048 1049 /* 1050 * Convert anything non-alphanumeric to an underscore. This 1051 * allows us to use the TableID to generate unique C symbols. 1052 */ 1053 for (i = 0; i < Length; i++) 1054 { 1055 if (!isalnum ((int) Gbl_TableId[i])) 1056 { 1057 Gbl_TableId[i] = '_'; 1058 } 1059 } 1060 } 1061 1062 /* OEM Revision */ 1063 1064 Child = Child->Asl.Next; 1065 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1066} 1067 1068 1069/******************************************************************************* 1070 * 1071 * FUNCTION: UtGetArg 1072 * 1073 * PARAMETERS: Op - Get an argument for this op 1074 * Argn - Nth argument to get 1075 * 1076 * RETURN: The argument (as an Op object). NULL if argument does not exist 1077 * 1078 * DESCRIPTION: Get the specified op's argument (peer) 1079 * 1080 ******************************************************************************/ 1081 1082ACPI_PARSE_OBJECT * 1083UtGetArg ( 1084 ACPI_PARSE_OBJECT *Op, 1085 UINT32 Argn) 1086{ 1087 ACPI_PARSE_OBJECT *Arg = NULL; 1088 1089 1090 /* Get the requested argument object */ 1091 1092 Arg = Op->Asl.Child; 1093 while (Arg && Argn) 1094 { 1095 Argn--; 1096 Arg = Arg->Asl.Next; 1097 } 1098 1099 return (Arg); 1100} 1101 1102 1103/******************************************************************************* 1104 * 1105 * FUNCTION: OpnAttachNameToNode 1106 * 1107 * PARAMETERS: Op - The parent parse node 1108 * 1109 * RETURN: None 1110 * 1111 * DESCRIPTION: For the named ASL/AML operators, get the actual name from the 1112 * argument list and attach it to the parent node so that we 1113 * can get to it quickly later. 1114 * 1115 ******************************************************************************/ 1116 1117static void 1118OpnAttachNameToNode ( 1119 ACPI_PARSE_OBJECT *Op) 1120{ 1121 ACPI_PARSE_OBJECT *Child = NULL; 1122 1123 1124 switch (Op->Asl.AmlOpcode) 1125 { 1126 case AML_DATA_REGION_OP: 1127 case AML_DEVICE_OP: 1128 case AML_EVENT_OP: 1129 case AML_EXTERNAL_OP: 1130 case AML_METHOD_OP: 1131 case AML_MUTEX_OP: 1132 case AML_REGION_OP: 1133 case AML_POWER_RES_OP: 1134 case AML_PROCESSOR_OP: 1135 case AML_THERMAL_ZONE_OP: 1136 case AML_NAME_OP: 1137 case AML_SCOPE_OP: 1138 1139 Child = UtGetArg (Op, 0); 1140 break; 1141 1142 case AML_ALIAS_OP: 1143 1144 Child = UtGetArg (Op, 1); 1145 break; 1146 1147 case AML_CREATE_BIT_FIELD_OP: 1148 case AML_CREATE_BYTE_FIELD_OP: 1149 case AML_CREATE_WORD_FIELD_OP: 1150 case AML_CREATE_DWORD_FIELD_OP: 1151 case AML_CREATE_QWORD_FIELD_OP: 1152 1153 Child = UtGetArg (Op, 2); 1154 break; 1155 1156 case AML_CREATE_FIELD_OP: 1157 1158 Child = UtGetArg (Op, 3); 1159 break; 1160 1161 case AML_BANK_FIELD_OP: 1162 case AML_INDEX_FIELD_OP: 1163 case AML_FIELD_OP: 1164 1165 return; 1166 1167 default: 1168 1169 return; 1170 } 1171 1172 if (Child) 1173 { 1174 UtAttachNamepathToOwner (Op, Child); 1175 } 1176} 1177 1178 1179/******************************************************************************* 1180 * 1181 * FUNCTION: OpnGenerateAmlOperands 1182 * 1183 * PARAMETERS: Op - The parent parse node 1184 * 1185 * RETURN: None 1186 * 1187 * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more 1188 * complex AML opcodes require processing of the child nodes 1189 * (arguments/operands). 1190 * 1191 ******************************************************************************/ 1192 1193void 1194OpnGenerateAmlOperands ( 1195 ACPI_PARSE_OBJECT *Op) 1196{ 1197 1198 1199 if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE) 1200 { 1201 return; 1202 } 1203 1204 switch (Op->Asl.ParseOpcode) 1205 { 1206 case PARSEOP_DEFINITION_BLOCK: 1207 1208 OpnDoDefinitionBlock (Op); 1209 break; 1210 1211 case PARSEOP_METHOD: 1212 1213 OpnDoMethod (Op); 1214 break; 1215 1216 case PARSEOP_MUTEX: 1217 1218 OpnDoMutex (Op); 1219 break; 1220 1221 case PARSEOP_FIELD: 1222 1223 OpnDoField (Op); 1224 break; 1225 1226 case PARSEOP_INDEXFIELD: 1227 1228 OpnDoIndexField (Op); 1229 break; 1230 1231 case PARSEOP_BANKFIELD: 1232 1233 OpnDoBankField (Op); 1234 break; 1235 1236 case PARSEOP_BUFFER: 1237 1238 OpnDoBuffer (Op); 1239 break; 1240 1241 case PARSEOP_LOADTABLE: 1242 1243 OpnDoLoadTable (Op); 1244 break; 1245 1246 case PARSEOP_OPERATIONREGION: 1247 1248 OpnDoRegion (Op); 1249 break; 1250 1251 case PARSEOP_RESOURCETEMPLATE: 1252 1253 RsDoResourceTemplate (Op); 1254 break; 1255 1256 case PARSEOP_NAMESEG: 1257 case PARSEOP_NAMESTRING: 1258 case PARSEOP_METHODCALL: 1259 case PARSEOP_STRING_LITERAL: 1260 default: 1261 1262 break; 1263 } 1264 1265 /* TBD: move */ 1266 1267 OpnAttachNameToNode (Op); 1268} 1269