1 2 /****************************************************************************** 3 * 4 * Module Name: asloperands - AML operand processing 5 * $Revision: 45 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2003, 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 "aslcompiler.h" 120 #include "aslcompiler.y.h" 121 #include "amlcode.h" 122 123 #define _COMPONENT ACPI_COMPILER 124 ACPI_MODULE_NAME ("asloperands") 125 126 127 /******************************************************************************* 128 * 129 * FUNCTION: OpnDoMethod 130 * 131 * PARAMETERS: Op - The parent parse node 132 * 133 * RETURN: None 134 * 135 * DESCRIPTION: Construct the operands for the METHOD ASL keyword. 136 * 137 ******************************************************************************/ 138 139 void 140 OpnDoMethod ( 141 ACPI_PARSE_OBJECT *Op) 142 { 143 ACPI_PARSE_OBJECT *Next; 144 145 /* Optional arguments for this opcode with defaults */ 146 147 UINT8 NumArgs = 0; 148 UINT8 Serialized = 0; 149 UINT8 Concurrency = 0; 150 UINT8 MethodFlags; 151 152 153 /* Opcode and package length first */ 154 /* Method name */ 155 156 Next = Op->Asl.Child; 157 158 /* Num args */ 159 160 Next = Next->Asl.Next; 161 if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 162 { 163 NumArgs = (UINT8) Next->Asl.Value.Integer; 164 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 165 } 166 167 /* Serialized Flag */ 168 169 Next = Next->Asl.Next; 170 if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 171 { 172 Serialized = (UINT8) Next->Asl.Value.Integer; 173 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 174 } 175 176 /* Concurrency value (0-15 valid) */ 177 178 Next = Next->Asl.Next; 179 if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 180 { 181 Concurrency = (UINT8) Next->Asl.Value.Integer; 182 } 183 184 /* Put the bits in their proper places */ 185 186 MethodFlags = (UINT8) ((NumArgs & 0x7) | 187 ((Serialized & 0x1) << 3) | 188 ((Concurrency & 0xF) << 4)); 189 190 /* Use the last node for the combined flags byte */ 191 192 Next->Asl.Value.Integer = MethodFlags; 193 Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 194 Next->Asl.AmlLength = 1; 195 Next->Asl.ParseOpcode = PARSEOP_RAW_DATA; 196 197 /* Save the arg count in the first node */ 198 199 Op->Asl.Extra = NumArgs; 200 } 201 202 203 /******************************************************************************* 204 * 205 * FUNCTION: OpnDoFieldCommon 206 * 207 * PARAMETERS: FieldOp - Node for an ASL field 208 * Op - The parent parse node 209 * 210 * RETURN: None 211 * 212 * DESCRIPTION: Construct the AML operands for the various field keywords, 213 * FIELD, BANKFIELD, INDEXFIELD 214 * 215 ******************************************************************************/ 216 217 void 218 OpnDoFieldCommon ( 219 ACPI_PARSE_OBJECT *FieldOp, 220 ACPI_PARSE_OBJECT *Op) 221 { 222 ACPI_PARSE_OBJECT *Next; 223 ACPI_PARSE_OBJECT *PkgLengthNode; 224 UINT32 CurrentBitOffset; 225 UINT32 NewBitOffset; 226 UINT8 AccessType; 227 UINT8 LockRule; 228 UINT8 UpdateRule; 229 UINT8 FieldFlags; 230 UINT32 MinimumLength; 231 232 233 /* AccessType -- not optional, so no need to check for DEFAULT_ARG */ 234 235 AccessType = (UINT8) Op->Asl.Value.Integer; 236 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 237 238 /* Set the access type in the parent (field) node for use later */ 239 240 FieldOp->Asl.Value.Integer = AccessType; 241 242 /* LockRule -- not optional, so no need to check for DEFAULT_ARG */ 243 244 Next = Op->Asl.Next; 245 LockRule = (UINT8) Next->Asl.Value.Integer; 246 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 247 248 /* UpdateRule -- not optional, so no need to check for DEFAULT_ARG */ 249 250 Next = Next->Asl.Next; 251 UpdateRule = (UINT8) Next->Asl.Value.Integer; 252 253 /* 254 * Generate the flags byte. The various fields are already 255 * in the right bit position via translation from the 256 * keywords by the parser. 257 */ 258 FieldFlags = (UINT8) (AccessType | LockRule | UpdateRule); 259 260 /* Use the previous node to be the FieldFlags node */ 261 262 /* Set the node to RAW_DATA */ 263 264 Next->Asl.Value.Integer = FieldFlags; 265 Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 266 Next->Asl.AmlLength = 1; 267 Next->Asl.ParseOpcode = PARSEOP_RAW_DATA; 268 269 /* Process the FieldUnitList */ 270 271 Next = Next->Asl.Next; 272 CurrentBitOffset = 0; 273 274 while (Next) 275 { 276 /* Save the offset of this field unit */ 277 278 Next->Asl.ExtraValue = CurrentBitOffset; 279 280 switch (Next->Asl.ParseOpcode) 281 { 282 case PARSEOP_ACCESSAS: 283 284 PkgLengthNode = Next->Asl.Child; 285 AccessType = (UINT8) PkgLengthNode->Asl.Value.Integer; 286 287 /* Nothing additional to do */ 288 break; 289 290 291 case PARSEOP_OFFSET: 292 293 /* New offset into the field */ 294 295 PkgLengthNode = Next->Asl.Child; 296 NewBitOffset = ((UINT32) PkgLengthNode->Asl.Value.Integer) * 8; 297 298 /* 299 * Examine the specified offset in relation to the 300 * current offset counter. 301 */ 302 if (NewBitOffset < CurrentBitOffset) 303 { 304 /* 305 * Not allowed to specify a backwards offset! 306 * Issue error and ignore this node. 307 */ 308 AslError (ASL_ERROR, ASL_MSG_BACKWARDS_OFFSET, PkgLengthNode, NULL); 309 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 310 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 311 } 312 else if (NewBitOffset == CurrentBitOffset) 313 { 314 /* 315 * Offset is redundant; we don't need to output an 316 * offset opcode. Just set these nodes to default 317 */ 318 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 319 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 320 } 321 else 322 { 323 /* 324 * Valid new offset - set the value to be inserted into the AML 325 * and update the offset counter. 326 */ 327 PkgLengthNode->Asl.Value.Integer = NewBitOffset - CurrentBitOffset; 328 CurrentBitOffset = NewBitOffset; 329 } 330 break; 331 332 333 case PARSEOP_NAMESEG: 334 case PARSEOP_RESERVED_BYTES: 335 336 /* Named or reserved field entry */ 337 338 PkgLengthNode = Next->Asl.Child; 339 NewBitOffset = (UINT32) PkgLengthNode->Asl.Value.Integer; 340 CurrentBitOffset += NewBitOffset; 341 342 /* Save the current AccessAs value for error checking later */ 343 344 switch (AccessType) 345 { 346 case AML_FIELD_ACCESS_ANY: 347 case AML_FIELD_ACCESS_BYTE: 348 case AML_FIELD_ACCESS_BUFFER: 349 default: 350 MinimumLength = 8; 351 break; 352 353 case AML_FIELD_ACCESS_WORD: 354 MinimumLength = 16; 355 break; 356 357 case AML_FIELD_ACCESS_DWORD: 358 MinimumLength = 32; 359 break; 360 361 case AML_FIELD_ACCESS_QWORD: 362 MinimumLength = 64; 363 break; 364 } 365 366 PkgLengthNode->Asl.ExtraValue = MinimumLength; 367 break; 368 369 default: 370 /* All supported field opcodes must appear above */ 371 break; 372 } 373 374 /* Move on to next entry in the field list */ 375 376 Next = Next->Asl.Next; 377 } 378 } 379 380 381 /******************************************************************************* 382 * 383 * FUNCTION: OpnDoField 384 * 385 * PARAMETERS: Op - The parent parse node 386 * 387 * RETURN: None 388 * 389 * DESCRIPTION: Construct the AML operands for the FIELD ASL keyword 390 * 391 ******************************************************************************/ 392 393 void 394 OpnDoField ( 395 ACPI_PARSE_OBJECT *Op) 396 { 397 ACPI_PARSE_OBJECT *Next; 398 399 400 /* Opcode is parent node */ 401 /* First child is field name */ 402 403 Next = Op->Asl.Child; 404 405 /* Second child is the AccessType */ 406 407 OpnDoFieldCommon (Op, Next->Asl.Next); 408 } 409 410 411 /******************************************************************************* 412 * 413 * FUNCTION: OpnDoIndexField 414 * 415 * PARAMETERS: Op - The parent parse node 416 * 417 * RETURN: None 418 * 419 * DESCRIPTION: Construct the AML operands for the INDEXFIELD ASL keyword 420 * 421 ******************************************************************************/ 422 423 void 424 OpnDoIndexField ( 425 ACPI_PARSE_OBJECT *Op) 426 { 427 ACPI_PARSE_OBJECT *Next; 428 429 430 /* Opcode is parent node */ 431 /* First child is the index name */ 432 433 Next = Op->Asl.Child; 434 435 /* Second child is the data name */ 436 437 Next = Next->Asl.Next; 438 439 /* Third child is the AccessType */ 440 441 OpnDoFieldCommon (Op, Next->Asl.Next); 442 } 443 444 445 /******************************************************************************* 446 * 447 * FUNCTION: OpnDoBankField 448 * 449 * PARAMETERS: Op - The parent parse node 450 * 451 * RETURN: None 452 * 453 * DESCRIPTION: Construct the AML operands for the BANKFIELD ASL keyword 454 * 455 ******************************************************************************/ 456 457 void 458 OpnDoBankField ( 459 ACPI_PARSE_OBJECT *Op) 460 { 461 ACPI_PARSE_OBJECT *Next; 462 463 464 /* Opcode is parent node */ 465 /* First child is the region name */ 466 467 Next = Op->Asl.Child; 468 469 /* Second child is the bank name */ 470 471 Next = Next->Asl.Next; 472 473 /* Third child is the bank value */ 474 475 Next = Next->Asl.Next; 476 477 /* Fourth child is the AccessType */ 478 479 OpnDoFieldCommon (Op, Next->Asl.Next); 480 } 481 482 483 /******************************************************************************* 484 * 485 * FUNCTION: OpnDoRegion 486 * 487 * PARAMETERS: Op - The parent parse node 488 * 489 * RETURN: None 490 * 491 * DESCRIPTION: Tries to get the length of the region. Can only do this at 492 * compile time if the length is a constant. 493 * 494 ******************************************************************************/ 495 496 void 497 OpnDoRegion ( 498 ACPI_PARSE_OBJECT *Op) 499 { 500 ACPI_PARSE_OBJECT *Next; 501 502 503 /* Opcode is parent node */ 504 /* First child is the region name */ 505 506 Next = Op->Asl.Child; 507 508 /* Second child is the space ID*/ 509 510 Next = Next->Asl.Next; 511 512 /* Third child is the region offset */ 513 514 Next = Next->Asl.Next; 515 516 /* Fourth child is the region length */ 517 518 Next = Next->Asl.Next; 519 if (Next->Asl.ParseOpcode == PARSEOP_INTEGER) 520 { 521 Op->Asl.Value.Integer = Next->Asl.Value.Integer; 522 } 523 else 524 { 525 Op->Asl.Value.Integer = ACPI_INTEGER_MAX; 526 } 527 } 528 529 530 /******************************************************************************* 531 * 532 * FUNCTION: OpnDoBuffer 533 * 534 * PARAMETERS: Op - The parent parse node 535 * 536 * RETURN: None 537 * 538 * DESCRIPTION: Construct the AML operands for the BUFFER ASL keyword. We 539 * build a single raw byte buffer from the initialization nodes, 540 * each parse node contains a buffer byte. 541 * 542 ******************************************************************************/ 543 544 void 545 OpnDoBuffer ( 546 ACPI_PARSE_OBJECT *Op) 547 { 548 ACPI_PARSE_OBJECT *InitializerOp; 549 ACPI_PARSE_OBJECT *BufferLengthOp; 550 551 /* Optional arguments for this opcode with defaults */ 552 553 UINT32 BufferLength = 0; 554 555 556 /* Opcode and package length first */ 557 /* Buffer Length is next, followed by the initializer list */ 558 559 BufferLengthOp = Op->Asl.Child; 560 InitializerOp = BufferLengthOp->Asl.Next; 561 562 /* 563 * If the BufferLength is not an INTEGER or was not specified in the ASL 564 * (DEFAULT_ARG), it is a TermArg that is 565 * evaluated at run-time, and we are therefore finished. 566 */ 567 if ((BufferLengthOp->Asl.ParseOpcode != PARSEOP_INTEGER) && 568 (BufferLengthOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 569 { 570 return; 571 } 572 573 /* 574 * We want to count the number of items in the initializer list, because if 575 * it is larger than the buffer length, we will define the buffer size 576 * to be the size of the initializer list (as per the ACPI Specification) 577 */ 578 switch (InitializerOp->Asl.ParseOpcode) 579 { 580 case PARSEOP_INTEGER: 581 case PARSEOP_BYTECONST: 582 case PARSEOP_WORDCONST: 583 case PARSEOP_DWORDCONST: 584 585 /* The peer list contains the byte list (if any...) */ 586 587 while (InitializerOp) 588 { 589 /* For buffers, this is a list of raw bytes */ 590 591 InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 592 InitializerOp->Asl.AmlLength = 1; 593 InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 594 595 BufferLength++; 596 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 597 } 598 break; 599 600 601 case PARSEOP_STRING_LITERAL: 602 603 /* 604 * Only one initializer, the string. Buffer must be big enough to hold 605 * the string plus the null termination byte 606 */ 607 BufferLength = strlen (InitializerOp->Asl.Value.String) + 1; 608 609 InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 610 InitializerOp->Asl.AmlLength = BufferLength; 611 InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 612 break; 613 614 615 case PARSEOP_RAW_DATA: 616 617 /* Buffer nodes are already initialized (e.g. Unicode operator) */ 618 return; 619 620 621 case PARSEOP_DEFAULT_ARG: 622 break; 623 624 625 default: 626 AslError (ASL_ERROR, ASL_MSG_INVALID_OPERAND, InitializerOp, 627 "Unknown buffer initializer opcode"); 628 printf ("Unknown buffer initializer opcode [%s]\n", 629 UtGetOpName (InitializerOp->Asl.ParseOpcode)); 630 return; 631 } 632 633 /* Check if initializer list is longer than the buffer length */ 634 635 if (BufferLengthOp->Asl.Value.Integer > BufferLength) 636 { 637 BufferLength = (UINT32) BufferLengthOp->Asl.Value.Integer; 638 } 639 640 if (!BufferLength) 641 { 642 /* No length AND no items -- issue a warning */ 643 644 AslError (ASL_WARNING, ASL_MSG_BUFFER_LENGTH, BufferLengthOp, NULL); 645 646 /* But go ahead and put the buffer length of zero into the AML */ 647 } 648 649 /* 650 * Just set the buffer size node to be the buffer length, regardless 651 * of whether it was previously an integer or a default_arg placeholder 652 */ 653 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 654 BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP; 655 BufferLengthOp->Asl.Value.Integer = BufferLength; 656 657 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 658 659 /* Remaining nodes are handled via the tree walk */ 660 } 661 662 663 /******************************************************************************* 664 * 665 * FUNCTION: OpnDoPackage 666 * 667 * PARAMETERS: Op - The parent parse node 668 * 669 * RETURN: None 670 * 671 * DESCRIPTION: Construct the AML operands for the PACKAGE ASL keyword. 672 * 673 ******************************************************************************/ 674 675 void 676 OpnDoPackage ( 677 ACPI_PARSE_OBJECT *Op) 678 { 679 ACPI_PARSE_OBJECT *InitializerOp; 680 ACPI_PARSE_OBJECT *PackageLengthOp; 681 682 /* Optional arguments for this opcode with defaults */ 683 684 UINT32 PackageLength = 0; 685 686 687 /* Opcode and package length first */ 688 /* Buffer Length is next, followed by the initializer list */ 689 690 PackageLengthOp = Op->Asl.Child; 691 InitializerOp = PackageLengthOp->Asl.Next; 692 693 /* 694 * We always count the number of items in the initializer list, because if 695 * it is larger than the buffer length, we will define the buffer size 696 * to be the size of the initializer list (Per ACPI Spec) 697 */ 698 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 699 { 700 /* The peer list contains the byte list (if any...) */ 701 702 while (InitializerOp) 703 { 704 PackageLength++; 705 InitializerOp = InitializerOp->Asl.Next; 706 } 707 } 708 709 /* Check if initializer list is longer than the buffer length */ 710 711 if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) || 712 (PackageLengthOp->Asl.ParseOpcode == PARSEOP_BYTECONST)) 713 { 714 if (PackageLengthOp->Asl.Value.Integer > PackageLength) 715 { 716 PackageLength = (UINT32) PackageLengthOp->Asl.Value.Integer; 717 } 718 } 719 720 /* 721 * If not a variable-length package, check for a zero 722 * package length 723 */ 724 if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) || 725 (PackageLengthOp->Asl.ParseOpcode == PARSEOP_BYTECONST) || 726 (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)) 727 { 728 if (!PackageLength) 729 { 730 /* No length AND no items -- issue a warning */ 731 732 AslError (ASL_WARNING, ASL_MSG_PACKAGE_LENGTH, PackageLengthOp, NULL); 733 734 /* But go ahead and put the buffer length of zero into the AML */ 735 } 736 } 737 738 /* 739 * Just set the buffer size node to be the buffer length, regardless 740 * of whether it was previously an integer or a default_arg placeholder 741 */ 742 PackageLengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 743 PackageLengthOp->Asl.AmlLength = 1; 744 PackageLengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 745 PackageLengthOp->Asl.Value.Integer = PackageLength; 746 747 /* Remaining nodes are handled via the tree walk */ 748 } 749 750 751 /******************************************************************************* 752 * 753 * FUNCTION: OpnDoLoadTable 754 * 755 * PARAMETERS: Op - The parent parse node 756 * 757 * RETURN: None 758 * 759 * DESCRIPTION: Construct the AML operands for the LOADTABLE ASL keyword. 760 * 761 ******************************************************************************/ 762 763 void 764 OpnDoLoadTable ( 765 ACPI_PARSE_OBJECT *Op) 766 { 767 ACPI_PARSE_OBJECT *Next; 768 769 770 /* Opcode is parent node */ 771 /* First child is the table signature */ 772 773 Next = Op->Asl.Child; 774 775 /* Second child is the OEM ID*/ 776 777 Next = Next->Asl.Next; 778 779 /* Third child is the OEM table ID */ 780 781 Next = Next->Asl.Next; 782 783 /* Fourth child is the RootPath string */ 784 785 Next = Next->Asl.Next; 786 if (Next->Asl.ParseOpcode == PARSEOP_ZERO) 787 { 788 Next->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; 789 Next->Asl.Value.String = "\\"; 790 Next->Asl.AmlLength = 2; 791 OpcGenerateAmlOpcode (Next); 792 } 793 794 /* Fifth child is the [optional] ParameterPathString */ 795 /* Sixth child is the [optional] ParameterData */ 796 797 /* 798 Next = Next->Asl.Next; 799 if (Next->Asl.ParseOpcode == DEFAULT_ARG) 800 { 801 Next->Asl.AmlLength = 1; 802 Next->Asl.ParseOpcode = ZERO; 803 OpcGenerateAmlOpcode (Next); 804 } 805 806 807 Next = Next->Asl.Next; 808 if (Next->Asl.ParseOpcode == DEFAULT_ARG) 809 { 810 Next->Asl.AmlLength = 1; 811 Next->Asl.ParseOpcode = ZERO; 812 OpcGenerateAmlOpcode (Next); 813 } 814 */ 815 } 816 817 818 /******************************************************************************* 819 * 820 * FUNCTION: OpnDoDefinitionBlock 821 * 822 * PARAMETERS: Op - The parent parse node 823 * 824 * RETURN: None 825 * 826 * DESCRIPTION: Construct the AML operands for the DEFINITIONBLOCK ASL keyword 827 * 828 ******************************************************************************/ 829 830 void 831 OpnDoDefinitionBlock ( 832 ACPI_PARSE_OBJECT *Op) 833 { 834 ACPI_PARSE_OBJECT *Child; 835 ACPI_SIZE Length; 836 ACPI_NATIVE_UINT i; 837 838 839 /* 840 * These nodes get stuffed into the table header. They are special 841 * cased when the table is written to the output file. 842 * 843 * Mark all of these nodes as non-usable so they won't get output 844 * as AML opcodes! 845 */ 846 847 /* AML filename */ 848 849 Child = Op->Asl.Child; 850 if ((Child->Asl.Value.Buffer) && (Gbl_UseDefaultAmlFilename)) 851 { 852 Gbl_OutputFilenamePrefix = (char *) Child->Asl.Value.Buffer; 853 } 854 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 855 856 /* Signature */ 857 858 Child = Child->Asl.Next; 859 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 860 if (Child->Asl.Value.String) 861 { 862 Gbl_TableSignature = Child->Asl.Value.String; 863 if (ACPI_STRLEN (Gbl_TableSignature) != 4) 864 { 865 AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child, "Length not exactly 4"); 866 } 867 868 for (i = 0; i < 4; i++) 869 { 870 if (!isalnum (Gbl_TableSignature[i])) 871 { 872 AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child, "Contains non-alphanumeric characters"); 873 } 874 } 875 } 876 877 /* Revision */ 878 879 Child = Child->Asl.Next; 880 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 881 882 /* Use the revision to set the integer width */ 883 884 AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer); 885 886 /* OEMID */ 887 888 Child = Child->Asl.Next; 889 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 890 891 /* OEM TableID */ 892 893 Child = Child->Asl.Next; 894 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 895 if (Child->Asl.Value.String) 896 { 897 Length = ACPI_STRLEN (Child->Asl.Value.String); 898 Gbl_TableId = AcpiOsAllocate (Length + 1); 899 ACPI_STRCPY (Gbl_TableId, Child->Asl.Value.String); 900 901 for (i = 0; i < Length; i++) 902 { 903 if (Gbl_TableId[i] == ' ') 904 { 905 Gbl_TableId[i] = 0; 906 break; 907 } 908 } 909 } 910 911 /* OEM Revision */ 912 913 Child = Child->Asl.Next; 914 Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 915 } 916 917 918 /******************************************************************************* 919 * 920 * FUNCTION: UtGetArg 921 * 922 * PARAMETERS: Op - Get an argument for this op 923 * Argn - Nth argument to get 924 * 925 * RETURN: The argument (as an Op object). NULL if argument does not exist 926 * 927 * DESCRIPTION: Get the specified op's argument (peer) 928 * 929 ******************************************************************************/ 930 931 ACPI_PARSE_OBJECT * 932 UtGetArg ( 933 ACPI_PARSE_OBJECT *Op, 934 UINT32 Argn) 935 { 936 ACPI_PARSE_OBJECT *Arg = NULL; 937 938 939 /* Get the requested argument object */ 940 941 Arg = Op->Asl.Child; 942 while (Arg && Argn) 943 { 944 Argn--; 945 Arg = Arg->Asl.Next; 946 } 947 948 return (Arg); 949 } 950 951 952 /******************************************************************************* 953 * 954 * FUNCTION: OpnAttachNameToNode 955 * 956 * PARAMETERS: Op - The parent parse node 957 * 958 * RETURN: None 959 * 960 * DESCRIPTION: For the named ASL/AML operators, get the actual name from the 961 * argument list and attach it to the parent node so that we 962 * can get to it quickly later. 963 * 964 ******************************************************************************/ 965 966 void 967 OpnAttachNameToNode ( 968 ACPI_PARSE_OBJECT *Op) 969 { 970 ACPI_PARSE_OBJECT *Child = NULL; 971 972 973 if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) 974 { 975 Child = UtGetArg (Op, 0); 976 } 977 else switch (Op->Asl.AmlOpcode) 978 { 979 case AML_DATA_REGION_OP: 980 case AML_DEVICE_OP: 981 case AML_EVENT_OP: 982 case AML_METHOD_OP: 983 case AML_MUTEX_OP: 984 case AML_REGION_OP: 985 case AML_POWER_RES_OP: 986 case AML_PROCESSOR_OP: 987 case AML_THERMAL_ZONE_OP: 988 case AML_NAME_OP: 989 case AML_SCOPE_OP: 990 991 Child = UtGetArg (Op, 0); 992 break; 993 994 case AML_ALIAS_OP: 995 996 Child = UtGetArg (Op, 1); 997 break; 998 999 case AML_CREATE_BIT_FIELD_OP: 1000 case AML_CREATE_BYTE_FIELD_OP: 1001 case AML_CREATE_WORD_FIELD_OP: 1002 case AML_CREATE_DWORD_FIELD_OP: 1003 case AML_CREATE_QWORD_FIELD_OP: 1004 1005 Child = UtGetArg (Op, 2); 1006 break; 1007 1008 case AML_CREATE_FIELD_OP: 1009 1010 Child = UtGetArg (Op, 3); 1011 break; 1012 1013 case AML_BANK_FIELD_OP: 1014 case AML_INDEX_FIELD_OP: 1015 case AML_FIELD_OP: 1016 1017 return; 1018 1019 default: 1020 return; 1021 } 1022 1023 if (Child) 1024 { 1025 UtAttachNamepathToOwner (Op, Child); 1026 } 1027 } 1028 1029 1030 /******************************************************************************* 1031 * 1032 * FUNCTION: OpnGenerateAmlOperands 1033 * 1034 * PARAMETERS: Op - The parent parse node 1035 * 1036 * RETURN: None 1037 * 1038 * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more 1039 * complex AML opcodes require processing of the child nodes 1040 * (arguments/operands). 1041 * 1042 ******************************************************************************/ 1043 1044 void 1045 OpnGenerateAmlOperands ( 1046 ACPI_PARSE_OBJECT *Op) 1047 { 1048 1049 1050 if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE) 1051 { 1052 return; 1053 } 1054 1055 switch (Op->Asl.ParseOpcode) 1056 { 1057 case PARSEOP_DEFINITIONBLOCK: 1058 OpnDoDefinitionBlock (Op); 1059 break; 1060 1061 case PARSEOP_METHOD: 1062 OpnDoMethod (Op); 1063 break; 1064 1065 case PARSEOP_FIELD: 1066 OpnDoField (Op); 1067 break; 1068 1069 case PARSEOP_INDEXFIELD: 1070 OpnDoIndexField (Op); 1071 break; 1072 1073 case PARSEOP_BANKFIELD: 1074 OpnDoBankField (Op); 1075 break; 1076 1077 case PARSEOP_BUFFER: 1078 OpnDoBuffer (Op); 1079 break; 1080 1081 case PARSEOP_LOADTABLE: 1082 OpnDoLoadTable (Op); 1083 break; 1084 1085 case PARSEOP_PACKAGE: 1086 OpnDoPackage (Op); 1087 break; 1088 1089 case PARSEOP_OPERATIONREGION: 1090 OpnDoRegion (Op); 1091 break; 1092 1093 case PARSEOP_RESOURCETEMPLATE: 1094 RsDoResourceTemplate (Op); 1095 break; 1096 1097 case PARSEOP_NAMESEG: 1098 case PARSEOP_NAMESTRING: 1099 case PARSEOP_METHODCALL: 1100 case PARSEOP_STRING_LITERAL: 1101 break; 1102 1103 default: 1104 break; 1105 } 1106 1107 /* TBD: move */ 1108 1109 OpnAttachNameToNode (Op); 1110 } 1111 1112 1113