1 /****************************************************************************** 2 * 3 * Module Name: aslopcode - AML opcode generation 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include "aslcompiler.y.h" 46 #include <contrib/dev/acpica/include/amlcode.h> 47 48 #define _COMPONENT ACPI_COMPILER 49 ACPI_MODULE_NAME ("aslopcodes") 50 51 52 /* Local prototypes */ 53 54 static void 55 OpcDoAccessAs ( 56 ACPI_PARSE_OBJECT *Op); 57 58 static void 59 OpcDoConnection ( 60 ACPI_PARSE_OBJECT *Op); 61 62 static void 63 OpcDoUnicode ( 64 ACPI_PARSE_OBJECT *Op); 65 66 static void 67 OpcDoEisaId ( 68 ACPI_PARSE_OBJECT *Op); 69 70 static void 71 OpcDoUuId ( 72 ACPI_PARSE_OBJECT *Op); 73 74 75 /******************************************************************************* 76 * 77 * FUNCTION: OpcAmlOpcodeUpdateWalk 78 * 79 * PARAMETERS: ASL_WALK_CALLBACK 80 * 81 * RETURN: Status 82 * 83 * DESCRIPTION: Opcode update walk, ascending callback 84 * 85 ******************************************************************************/ 86 87 ACPI_STATUS 88 OpcAmlOpcodeUpdateWalk ( 89 ACPI_PARSE_OBJECT *Op, 90 UINT32 Level, 91 void *Context) 92 { 93 94 /* 95 * Handle the Package() case where the actual opcode cannot be determined 96 * until the PackageLength operand has been folded and minimized. 97 * (PackageOp versus VarPackageOp) 98 * 99 * This is (as of ACPI 3.0) the only case where the AML opcode can change 100 * based upon the value of a parameter. 101 * 102 * The parser always inserts a VarPackage opcode, which can possibly be 103 * optimized to a Package opcode. 104 */ 105 if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE) 106 { 107 OpnDoPackage (Op); 108 } 109 110 return (AE_OK); 111 } 112 113 114 /******************************************************************************* 115 * 116 * FUNCTION: OpcAmlOpcodeWalk 117 * 118 * PARAMETERS: ASL_WALK_CALLBACK 119 * 120 * RETURN: Status 121 * 122 * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML 123 * operands. 124 * 125 ******************************************************************************/ 126 127 ACPI_STATUS 128 OpcAmlOpcodeWalk ( 129 ACPI_PARSE_OBJECT *Op, 130 UINT32 Level, 131 void *Context) 132 { 133 134 TotalParseNodes++; 135 136 OpcGenerateAmlOpcode (Op); 137 OpnGenerateAmlOperands (Op); 138 return (AE_OK); 139 } 140 141 142 /******************************************************************************* 143 * 144 * FUNCTION: OpcGetIntegerWidth 145 * 146 * PARAMETERS: Op - DEFINITION BLOCK op 147 * 148 * RETURN: none 149 * 150 * DESCRIPTION: Extract integer width from the table revision 151 * 152 ******************************************************************************/ 153 154 void 155 OpcGetIntegerWidth ( 156 ACPI_PARSE_OBJECT *Op) 157 { 158 ACPI_PARSE_OBJECT *Child; 159 160 161 if (!Op) 162 { 163 return; 164 } 165 166 if (Gbl_RevisionOverride) 167 { 168 AcpiUtSetIntegerWidth (Gbl_RevisionOverride); 169 } 170 else 171 { 172 Child = Op->Asl.Child; 173 Child = Child->Asl.Next; 174 Child = Child->Asl.Next; 175 176 /* Use the revision to set the integer width */ 177 178 AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer); 179 } 180 } 181 182 183 /******************************************************************************* 184 * 185 * FUNCTION: OpcSetOptimalIntegerSize 186 * 187 * PARAMETERS: Op - A parse tree node 188 * 189 * RETURN: Integer width, in bytes. Also sets the node AML opcode to the 190 * optimal integer AML prefix opcode. 191 * 192 * DESCRIPTION: Determine the optimal AML encoding of an integer. All leading 193 * zeros can be truncated to squeeze the integer into the 194 * minimal number of AML bytes. 195 * 196 ******************************************************************************/ 197 198 UINT32 199 OpcSetOptimalIntegerSize ( 200 ACPI_PARSE_OBJECT *Op) 201 { 202 203 #if 0 204 /* 205 * TBD: - we don't want to optimize integers in the block header, but the 206 * code below does not work correctly. 207 */ 208 if (Op->Asl.Parent && 209 Op->Asl.Parent->Asl.Parent && 210 (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK)) 211 { 212 return (0); 213 } 214 #endif 215 216 /* 217 * Check for the special AML integers first - Zero, One, Ones. 218 * These are single-byte opcodes that are the smallest possible 219 * representation of an integer. 220 * 221 * This optimization is optional. 222 */ 223 if (Gbl_IntegerOptimizationFlag) 224 { 225 switch (Op->Asl.Value.Integer) 226 { 227 case 0: 228 229 Op->Asl.AmlOpcode = AML_ZERO_OP; 230 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 231 Op, "Zero"); 232 return (1); 233 234 case 1: 235 236 Op->Asl.AmlOpcode = AML_ONE_OP; 237 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 238 Op, "One"); 239 return (1); 240 241 case ACPI_UINT32_MAX: 242 243 /* Check for table integer width (32 or 64) */ 244 245 if (AcpiGbl_IntegerByteWidth == 4) 246 { 247 Op->Asl.AmlOpcode = AML_ONES_OP; 248 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 249 Op, "Ones"); 250 return (1); 251 } 252 break; 253 254 case ACPI_UINT64_MAX: 255 256 /* Check for table integer width (32 or 64) */ 257 258 if (AcpiGbl_IntegerByteWidth == 8) 259 { 260 Op->Asl.AmlOpcode = AML_ONES_OP; 261 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 262 Op, "Ones"); 263 return (1); 264 } 265 break; 266 267 default: 268 269 break; 270 } 271 } 272 273 /* Find the best fit using the various AML integer prefixes */ 274 275 if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX) 276 { 277 Op->Asl.AmlOpcode = AML_BYTE_OP; 278 return (1); 279 } 280 if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX) 281 { 282 Op->Asl.AmlOpcode = AML_WORD_OP; 283 return (2); 284 } 285 if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX) 286 { 287 Op->Asl.AmlOpcode = AML_DWORD_OP; 288 return (4); 289 } 290 else 291 { 292 if (AcpiGbl_IntegerByteWidth == 4) 293 { 294 AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH, 295 Op, NULL); 296 297 if (!Gbl_IgnoreErrors) 298 { 299 /* Truncate the integer to 32-bit */ 300 Op->Asl.AmlOpcode = AML_DWORD_OP; 301 return (4); 302 } 303 } 304 305 Op->Asl.AmlOpcode = AML_QWORD_OP; 306 return (8); 307 } 308 } 309 310 311 /******************************************************************************* 312 * 313 * FUNCTION: OpcDoAccessAs 314 * 315 * PARAMETERS: Op - Parse node 316 * 317 * RETURN: None 318 * 319 * DESCRIPTION: Implement the ACCESS_AS ASL keyword. 320 * 321 ******************************************************************************/ 322 323 static void 324 OpcDoAccessAs ( 325 ACPI_PARSE_OBJECT *Op) 326 { 327 ACPI_PARSE_OBJECT *TypeOp; 328 ACPI_PARSE_OBJECT *AttribOp; 329 ACPI_PARSE_OBJECT *LengthOp; 330 UINT8 Attribute; 331 332 333 Op->Asl.AmlOpcodeLength = 1; 334 TypeOp = Op->Asl.Child; 335 336 /* First child is the access type */ 337 338 TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 339 TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 340 341 /* Second child is the optional access attribute */ 342 343 AttribOp = TypeOp->Asl.Next; 344 if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 345 { 346 AttribOp->Asl.Value.Integer = 0; 347 } 348 AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 349 AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 350 351 /* Only a few AccessAttributes support AccessLength */ 352 353 Attribute = (UINT8) AttribOp->Asl.Value.Integer; 354 if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) && 355 (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) && 356 (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS)) 357 { 358 return; 359 } 360 361 Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP; 362 363 /* 364 * Child of Attributes is the AccessLength (required for Multibyte, 365 * RawBytes, RawProcess.) 366 */ 367 LengthOp = AttribOp->Asl.Child; 368 if (!LengthOp) 369 { 370 return; 371 } 372 373 /* TBD: probably can remove */ 374 375 if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 376 { 377 LengthOp->Asl.Value.Integer = 16; 378 } 379 380 LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 381 LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 382 } 383 384 385 /******************************************************************************* 386 * 387 * FUNCTION: OpcDoConnection 388 * 389 * PARAMETERS: Op - Parse node 390 * 391 * RETURN: None 392 * 393 * DESCRIPTION: Implement the Connection ASL keyword. 394 * 395 ******************************************************************************/ 396 397 static void 398 OpcDoConnection ( 399 ACPI_PARSE_OBJECT *Op) 400 { 401 ASL_RESOURCE_NODE *Rnode; 402 ACPI_PARSE_OBJECT *BufferOp; 403 ACPI_PARSE_OBJECT *BufferLengthOp; 404 ACPI_PARSE_OBJECT *BufferDataOp; 405 ASL_RESOURCE_INFO Info; 406 UINT8 State; 407 408 409 Op->Asl.AmlOpcodeLength = 1; 410 411 if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP) 412 { 413 return; 414 } 415 416 BufferOp = Op->Asl.Child; 417 BufferLengthOp = BufferOp->Asl.Child; 418 BufferDataOp = BufferLengthOp->Asl.Next; 419 420 Info.DescriptorTypeOp = BufferDataOp->Asl.Next; 421 Info.CurrentByteOffset = 0; 422 State = ACPI_RSTATE_NORMAL; 423 Rnode = RsDoOneResourceDescriptor (&Info, &State); 424 if (!Rnode) 425 { 426 return; /* error */ 427 } 428 429 /* 430 * Transform the nodes into the following 431 * 432 * Op -> AML_BUFFER_OP 433 * First Child -> BufferLength 434 * Second Child -> Descriptor Buffer (raw byte data) 435 */ 436 BufferOp->Asl.ParseOpcode = PARSEOP_BUFFER; 437 BufferOp->Asl.AmlOpcode = AML_BUFFER_OP; 438 BufferOp->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC; 439 UtSetParseOpName (BufferOp); 440 441 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 442 BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength; 443 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 444 UtSetParseOpName (BufferLengthOp); 445 446 BufferDataOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 447 BufferDataOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 448 BufferDataOp->Asl.AmlOpcodeLength = 0; 449 BufferDataOp->Asl.AmlLength = Rnode->BufferLength; 450 BufferDataOp->Asl.Value.Buffer = (UINT8 *) Rnode; 451 UtSetParseOpName (BufferDataOp); 452 } 453 454 455 /******************************************************************************* 456 * 457 * FUNCTION: OpcDoUnicode 458 * 459 * PARAMETERS: Op - Parse node 460 * 461 * RETURN: None 462 * 463 * DESCRIPTION: Implement the UNICODE ASL "macro". Convert the input string 464 * to a unicode buffer. There is no Unicode AML opcode. 465 * 466 * Note: The Unicode string is 16 bits per character, no leading signature, 467 * with a 16-bit terminating NULL. 468 * 469 ******************************************************************************/ 470 471 static void 472 OpcDoUnicode ( 473 ACPI_PARSE_OBJECT *Op) 474 { 475 ACPI_PARSE_OBJECT *InitializerOp; 476 UINT32 Length; 477 UINT32 Count; 478 UINT32 i; 479 UINT8 *AsciiString; 480 UINT16 *UnicodeString; 481 ACPI_PARSE_OBJECT *BufferLengthOp; 482 483 484 /* Change op into a buffer object */ 485 486 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 487 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 488 UtSetParseOpName (Op); 489 490 /* Buffer Length is first, followed by the string */ 491 492 BufferLengthOp = Op->Asl.Child; 493 InitializerOp = BufferLengthOp->Asl.Next; 494 495 AsciiString = (UINT8 *) InitializerOp->Asl.Value.String; 496 497 /* Create a new buffer for the Unicode string */ 498 499 Count = strlen (InitializerOp->Asl.Value.String) + 1; 500 Length = Count * sizeof (UINT16); 501 UnicodeString = UtLocalCalloc (Length); 502 503 /* Convert to Unicode string (including null terminator) */ 504 505 for (i = 0; i < Count; i++) 506 { 507 UnicodeString[i] = (UINT16) AsciiString[i]; 508 } 509 510 /* 511 * Just set the buffer size node to be the buffer length, regardless 512 * of whether it was previously an integer or a default_arg placeholder 513 */ 514 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 515 BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP; 516 BufferLengthOp->Asl.Value.Integer = Length; 517 UtSetParseOpName (BufferLengthOp); 518 519 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 520 521 /* The Unicode string is a raw data buffer */ 522 523 InitializerOp->Asl.Value.Buffer = (UINT8 *) UnicodeString; 524 InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 525 InitializerOp->Asl.AmlLength = Length; 526 InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 527 InitializerOp->Asl.Child = NULL; 528 UtSetParseOpName (InitializerOp); 529 } 530 531 532 /******************************************************************************* 533 * 534 * FUNCTION: OpcDoEisaId 535 * 536 * PARAMETERS: Op - Parse node 537 * 538 * RETURN: None 539 * 540 * DESCRIPTION: Convert a string EISA ID to numeric representation. See the 541 * Pnp BIOS Specification for details. Here is an excerpt: 542 * 543 * A seven character ASCII representation of the product 544 * identifier compressed into a 32-bit identifier. The seven 545 * character ID consists of a three character manufacturer code, 546 * a three character hexadecimal product identifier, and a one 547 * character hexadecimal revision number. The manufacturer code 548 * is a 3 uppercase character code that is compressed into 3 5-bit 549 * values as follows: 550 * 1) Find hex ASCII value for each letter 551 * 2) Subtract 40h from each ASCII value 552 * 3) Retain 5 least significant bits for each letter by 553 * discarding upper 3 bits because they are always 0. 554 * 4) Compressed code = concatenate 0 and the 3 5-bit values 555 * 556 * The format of the compressed product identifier is as follows: 557 * Byte 0: Bit 7 - Reserved (0) 558 * Bits 6-2: - 1st character of compressed mfg code 559 * Bits 1-0 - Upper 2 bits of 2nd character of mfg code 560 * Byte 1: Bits 7-5 - Lower 3 bits of 2nd character of mfg code 561 * Bits 4-0 - 3rd character of mfg code 562 * Byte 2: Bits 7-4 - 1st hex digit of product number 563 * Bits 3-0 - 2nd hex digit of product number 564 * Byte 3: Bits 7-4 - 3st hex digit of product number 565 * Bits 3-0 - Hex digit of the revision number 566 * 567 ******************************************************************************/ 568 569 static void 570 OpcDoEisaId ( 571 ACPI_PARSE_OBJECT *Op) 572 { 573 UINT32 EisaId = 0; 574 UINT32 BigEndianId; 575 char *InString; 576 ACPI_STATUS Status = AE_OK; 577 UINT32 i; 578 579 580 InString = (char *) Op->Asl.Value.String; 581 582 /* 583 * The EISAID string must be exactly 7 characters and of the form 584 * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001") 585 */ 586 if (ACPI_STRLEN (InString) != 7) 587 { 588 Status = AE_BAD_PARAMETER; 589 } 590 else 591 { 592 /* Check all 7 characters for correct format */ 593 594 for (i = 0; i < 7; i++) 595 { 596 /* First 3 characters must be uppercase letters */ 597 598 if (i < 3) 599 { 600 if (!isupper ((int) InString[i])) 601 { 602 Status = AE_BAD_PARAMETER; 603 } 604 } 605 606 /* Last 4 characters must be hex digits */ 607 608 else if (!isxdigit ((int) InString[i])) 609 { 610 Status = AE_BAD_PARAMETER; 611 } 612 } 613 } 614 615 if (ACPI_FAILURE (Status)) 616 { 617 AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String); 618 } 619 else 620 { 621 /* Create ID big-endian first (bits are contiguous) */ 622 623 BigEndianId = 624 (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 | 625 (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 | 626 (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 | 627 628 (AcpiUtAsciiCharToHex (InString[3])) << 12 | 629 (AcpiUtAsciiCharToHex (InString[4])) << 8 | 630 (AcpiUtAsciiCharToHex (InString[5])) << 4 | 631 AcpiUtAsciiCharToHex (InString[6]); 632 633 /* Swap to little-endian to get final ID (see function header) */ 634 635 EisaId = AcpiUtDwordByteSwap (BigEndianId); 636 } 637 638 /* 639 * Morph the Op into an integer, regardless of whether there 640 * was an error in the EISAID string 641 */ 642 Op->Asl.Value.Integer = EisaId; 643 644 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 645 Op->Asl.ParseOpcode = PARSEOP_INTEGER; 646 (void) OpcSetOptimalIntegerSize (Op); 647 648 /* Op is now an integer */ 649 650 UtSetParseOpName (Op); 651 } 652 653 654 /******************************************************************************* 655 * 656 * FUNCTION: OpcDoUuId 657 * 658 * PARAMETERS: Op - Parse node 659 * 660 * RETURN: None 661 * 662 * DESCRIPTION: Convert UUID string to 16-byte buffer 663 * 664 ******************************************************************************/ 665 666 static void 667 OpcDoUuId ( 668 ACPI_PARSE_OBJECT *Op) 669 { 670 char *InString; 671 UINT8 *Buffer; 672 ACPI_STATUS Status = AE_OK; 673 ACPI_PARSE_OBJECT *NewOp; 674 675 676 InString = (char *) Op->Asl.Value.String; 677 Buffer = UtLocalCalloc (16); 678 679 Status = AuValidateUuid (InString); 680 if (ACPI_FAILURE (Status)) 681 { 682 AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String); 683 } 684 else 685 { 686 AcpiUtConvertStringToUuid (InString, Buffer); 687 } 688 689 /* Change Op to a Buffer */ 690 691 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 692 Op->Common.AmlOpcode = AML_BUFFER_OP; 693 694 /* Disable further optimization */ 695 696 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 697 UtSetParseOpName (Op); 698 699 /* Child node is the buffer length */ 700 701 NewOp = TrAllocateNode (PARSEOP_INTEGER); 702 703 NewOp->Asl.AmlOpcode = AML_BYTE_OP; 704 NewOp->Asl.Value.Integer = 16; 705 NewOp->Asl.Parent = Op; 706 707 Op->Asl.Child = NewOp; 708 Op = NewOp; 709 710 /* Peer to the child is the raw buffer data */ 711 712 NewOp = TrAllocateNode (PARSEOP_RAW_DATA); 713 NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 714 NewOp->Asl.AmlLength = 16; 715 NewOp->Asl.Value.String = (char *) Buffer; 716 NewOp->Asl.Parent = Op->Asl.Parent; 717 718 Op->Asl.Next = NewOp; 719 } 720 721 722 /******************************************************************************* 723 * 724 * FUNCTION: OpcGenerateAmlOpcode 725 * 726 * PARAMETERS: Op - Parse node 727 * 728 * RETURN: None 729 * 730 * DESCRIPTION: Generate the AML opcode associated with the node and its 731 * parse (lex/flex) keyword opcode. Essentially implements 732 * a mapping between the parse opcodes and the actual AML opcodes. 733 * 734 ******************************************************************************/ 735 736 void 737 OpcGenerateAmlOpcode ( 738 ACPI_PARSE_OBJECT *Op) 739 { 740 741 UINT16 Index; 742 743 744 Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE); 745 746 Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode; 747 Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype; 748 Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags; 749 750 if (!Op->Asl.Value.Integer) 751 { 752 Op->Asl.Value.Integer = AslKeywordMapping[Index].Value; 753 } 754 755 /* Special handling for some opcodes */ 756 757 switch (Op->Asl.ParseOpcode) 758 { 759 case PARSEOP_INTEGER: 760 /* 761 * Set the opcode based on the size of the integer 762 */ 763 (void) OpcSetOptimalIntegerSize (Op); 764 break; 765 766 case PARSEOP_OFFSET: 767 768 Op->Asl.AmlOpcodeLength = 1; 769 break; 770 771 case PARSEOP_ACCESSAS: 772 773 OpcDoAccessAs (Op); 774 break; 775 776 case PARSEOP_CONNECTION: 777 778 OpcDoConnection (Op); 779 break; 780 781 case PARSEOP_EISAID: 782 783 OpcDoEisaId (Op); 784 break; 785 786 case PARSEOP_TOUUID: 787 788 OpcDoUuId (Op); 789 break; 790 791 case PARSEOP_UNICODE: 792 793 OpcDoUnicode (Op); 794 break; 795 796 case PARSEOP_INCLUDE: 797 798 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 799 Gbl_HasIncludeFiles = TRUE; 800 break; 801 802 case PARSEOP_EXTERNAL: 803 804 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 805 Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 806 break; 807 808 case PARSEOP_TIMER: 809 810 if (AcpiGbl_IntegerBitWidth == 32) 811 { 812 AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL); 813 } 814 break; 815 816 default: 817 818 /* Nothing to do for other opcodes */ 819 820 break; 821 } 822 823 return; 824 } 825