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