1 /****************************************************************************** 2 * 3 * Module Name: aslopcode - AML opcode generation 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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_DEFINITION_BLOCK)) 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 281 if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX) 282 { 283 Op->Asl.AmlOpcode = AML_WORD_OP; 284 return (2); 285 } 286 287 if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX) 288 { 289 Op->Asl.AmlOpcode = AML_DWORD_OP; 290 return (4); 291 } 292 else 293 { 294 if (AcpiGbl_IntegerByteWidth == 4) 295 { 296 AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH, 297 Op, NULL); 298 299 if (!Gbl_IgnoreErrors) 300 { 301 /* Truncate the integer to 32-bit */ 302 Op->Asl.AmlOpcode = AML_DWORD_OP; 303 return (4); 304 } 305 } 306 307 Op->Asl.AmlOpcode = AML_QWORD_OP; 308 return (8); 309 } 310 } 311 312 313 /******************************************************************************* 314 * 315 * FUNCTION: OpcDoAccessAs 316 * 317 * PARAMETERS: Op - Parse node 318 * 319 * RETURN: None 320 * 321 * DESCRIPTION: Implement the ACCESS_AS ASL keyword. 322 * 323 ******************************************************************************/ 324 325 static void 326 OpcDoAccessAs ( 327 ACPI_PARSE_OBJECT *Op) 328 { 329 ACPI_PARSE_OBJECT *TypeOp; 330 ACPI_PARSE_OBJECT *AttribOp; 331 ACPI_PARSE_OBJECT *LengthOp; 332 UINT8 Attribute; 333 334 335 Op->Asl.AmlOpcodeLength = 1; 336 TypeOp = Op->Asl.Child; 337 338 /* First child is the access type */ 339 340 TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 341 TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 342 343 /* Second child is the optional access attribute */ 344 345 AttribOp = TypeOp->Asl.Next; 346 if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 347 { 348 AttribOp->Asl.Value.Integer = 0; 349 } 350 351 AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 352 AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 353 354 /* Only a few AccessAttributes support AccessLength */ 355 356 Attribute = (UINT8) AttribOp->Asl.Value.Integer; 357 if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) && 358 (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) && 359 (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS)) 360 { 361 return; 362 } 363 364 Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP; 365 366 /* 367 * Child of Attributes is the AccessLength (required for Multibyte, 368 * RawBytes, RawProcess.) 369 */ 370 LengthOp = AttribOp->Asl.Child; 371 if (!LengthOp) 372 { 373 return; 374 } 375 376 /* TBD: probably can remove */ 377 378 if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 379 { 380 LengthOp->Asl.Value.Integer = 16; 381 } 382 383 LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 384 LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 385 } 386 387 388 /******************************************************************************* 389 * 390 * FUNCTION: OpcDoConnection 391 * 392 * PARAMETERS: Op - Parse node 393 * 394 * RETURN: None 395 * 396 * DESCRIPTION: Implement the Connection ASL keyword. 397 * 398 ******************************************************************************/ 399 400 static void 401 OpcDoConnection ( 402 ACPI_PARSE_OBJECT *Op) 403 { 404 ASL_RESOURCE_NODE *Rnode; 405 ACPI_PARSE_OBJECT *BufferOp; 406 ACPI_PARSE_OBJECT *BufferLengthOp; 407 ACPI_PARSE_OBJECT *BufferDataOp; 408 ASL_RESOURCE_INFO Info; 409 UINT8 State; 410 411 412 Op->Asl.AmlOpcodeLength = 1; 413 414 if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP) 415 { 416 return; 417 } 418 419 BufferOp = Op->Asl.Child; 420 BufferLengthOp = BufferOp->Asl.Child; 421 BufferDataOp = BufferLengthOp->Asl.Next; 422 423 Info.DescriptorTypeOp = BufferDataOp->Asl.Next; 424 Info.CurrentByteOffset = 0; 425 State = ACPI_RSTATE_NORMAL; 426 Rnode = RsDoOneResourceDescriptor (&Info, &State); 427 if (!Rnode) 428 { 429 return; /* error */ 430 } 431 432 /* 433 * Transform the nodes into the following 434 * 435 * Op -> AML_BUFFER_OP 436 * First Child -> BufferLength 437 * Second Child -> Descriptor Buffer (raw byte data) 438 */ 439 BufferOp->Asl.ParseOpcode = PARSEOP_BUFFER; 440 BufferOp->Asl.AmlOpcode = AML_BUFFER_OP; 441 BufferOp->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC; 442 UtSetParseOpName (BufferOp); 443 444 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 445 BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength; 446 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 447 UtSetParseOpName (BufferLengthOp); 448 449 BufferDataOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 450 BufferDataOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 451 BufferDataOp->Asl.AmlOpcodeLength = 0; 452 BufferDataOp->Asl.AmlLength = Rnode->BufferLength; 453 BufferDataOp->Asl.Value.Buffer = (UINT8 *) Rnode; 454 UtSetParseOpName (BufferDataOp); 455 } 456 457 458 /******************************************************************************* 459 * 460 * FUNCTION: OpcDoUnicode 461 * 462 * PARAMETERS: Op - Parse node 463 * 464 * RETURN: None 465 * 466 * DESCRIPTION: Implement the UNICODE ASL "macro". Convert the input string 467 * to a unicode buffer. There is no Unicode AML opcode. 468 * 469 * Note: The Unicode string is 16 bits per character, no leading signature, 470 * with a 16-bit terminating NULL. 471 * 472 ******************************************************************************/ 473 474 static void 475 OpcDoUnicode ( 476 ACPI_PARSE_OBJECT *Op) 477 { 478 ACPI_PARSE_OBJECT *InitializerOp; 479 UINT32 Length; 480 UINT32 Count; 481 UINT32 i; 482 UINT8 *AsciiString; 483 UINT16 *UnicodeString; 484 ACPI_PARSE_OBJECT *BufferLengthOp; 485 486 487 /* Change op into a buffer object */ 488 489 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 490 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 491 UtSetParseOpName (Op); 492 493 /* Buffer Length is first, followed by the string */ 494 495 BufferLengthOp = Op->Asl.Child; 496 InitializerOp = BufferLengthOp->Asl.Next; 497 498 AsciiString = (UINT8 *) InitializerOp->Asl.Value.String; 499 500 /* Create a new buffer for the Unicode string */ 501 502 Count = strlen (InitializerOp->Asl.Value.String) + 1; 503 Length = Count * sizeof (UINT16); 504 UnicodeString = UtLocalCalloc (Length); 505 506 /* Convert to Unicode string (including null terminator) */ 507 508 for (i = 0; i < Count; i++) 509 { 510 UnicodeString[i] = (UINT16) AsciiString[i]; 511 } 512 513 /* 514 * Just set the buffer size node to be the buffer length, regardless 515 * of whether it was previously an integer or a default_arg placeholder 516 */ 517 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 518 BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP; 519 BufferLengthOp->Asl.Value.Integer = Length; 520 UtSetParseOpName (BufferLengthOp); 521 522 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 523 524 /* The Unicode string is a raw data buffer */ 525 526 InitializerOp->Asl.Value.Buffer = (UINT8 *) UnicodeString; 527 InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 528 InitializerOp->Asl.AmlLength = Length; 529 InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 530 InitializerOp->Asl.Child = NULL; 531 UtSetParseOpName (InitializerOp); 532 } 533 534 535 /******************************************************************************* 536 * 537 * FUNCTION: OpcDoEisaId 538 * 539 * PARAMETERS: Op - Parse node 540 * 541 * RETURN: None 542 * 543 * DESCRIPTION: Convert a string EISA ID to numeric representation. See the 544 * Pnp BIOS Specification for details. Here is an excerpt: 545 * 546 * A seven character ASCII representation of the product 547 * identifier compressed into a 32-bit identifier. The seven 548 * character ID consists of a three character manufacturer code, 549 * a three character hexadecimal product identifier, and a one 550 * character hexadecimal revision number. The manufacturer code 551 * is a 3 uppercase character code that is compressed into 3 5-bit 552 * values as follows: 553 * 1) Find hex ASCII value for each letter 554 * 2) Subtract 40h from each ASCII value 555 * 3) Retain 5 least significant bits for each letter by 556 * discarding upper 3 bits because they are always 0. 557 * 4) Compressed code = concatenate 0 and the 3 5-bit values 558 * 559 * The format of the compressed product identifier is as follows: 560 * Byte 0: Bit 7 - Reserved (0) 561 * Bits 6-2: - 1st character of compressed mfg code 562 * Bits 1-0 - Upper 2 bits of 2nd character of mfg code 563 * Byte 1: Bits 7-5 - Lower 3 bits of 2nd character of mfg code 564 * Bits 4-0 - 3rd character of mfg code 565 * Byte 2: Bits 7-4 - 1st hex digit of product number 566 * Bits 3-0 - 2nd hex digit of product number 567 * Byte 3: Bits 7-4 - 3st hex digit of product number 568 * Bits 3-0 - Hex digit of the revision number 569 * 570 ******************************************************************************/ 571 572 static void 573 OpcDoEisaId ( 574 ACPI_PARSE_OBJECT *Op) 575 { 576 UINT32 EisaId = 0; 577 UINT32 BigEndianId; 578 char *InString; 579 ACPI_STATUS Status = AE_OK; 580 UINT32 i; 581 582 583 InString = (char *) Op->Asl.Value.String; 584 585 /* 586 * The EISAID string must be exactly 7 characters and of the form 587 * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001") 588 */ 589 if (strlen (InString) != 7) 590 { 591 Status = AE_BAD_PARAMETER; 592 } 593 else 594 { 595 /* Check all 7 characters for correct format */ 596 597 for (i = 0; i < 7; i++) 598 { 599 /* First 3 characters must be uppercase letters */ 600 601 if (i < 3) 602 { 603 if (!isupper ((int) InString[i])) 604 { 605 Status = AE_BAD_PARAMETER; 606 } 607 } 608 609 /* Last 4 characters must be hex digits */ 610 611 else if (!isxdigit ((int) InString[i])) 612 { 613 Status = AE_BAD_PARAMETER; 614 } 615 } 616 } 617 618 if (ACPI_FAILURE (Status)) 619 { 620 AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String); 621 } 622 else 623 { 624 /* Create ID big-endian first (bits are contiguous) */ 625 626 BigEndianId = 627 (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 | 628 (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 | 629 (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 | 630 631 (AcpiUtAsciiCharToHex (InString[3])) << 12 | 632 (AcpiUtAsciiCharToHex (InString[4])) << 8 | 633 (AcpiUtAsciiCharToHex (InString[5])) << 4 | 634 AcpiUtAsciiCharToHex (InString[6]); 635 636 /* Swap to little-endian to get final ID (see function header) */ 637 638 EisaId = AcpiUtDwordByteSwap (BigEndianId); 639 } 640 641 /* 642 * Morph the Op into an integer, regardless of whether there 643 * was an error in the EISAID string 644 */ 645 Op->Asl.Value.Integer = EisaId; 646 647 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 648 Op->Asl.ParseOpcode = PARSEOP_INTEGER; 649 (void) OpcSetOptimalIntegerSize (Op); 650 651 /* Op is now an integer */ 652 653 UtSetParseOpName (Op); 654 } 655 656 657 /******************************************************************************* 658 * 659 * FUNCTION: OpcDoUuId 660 * 661 * PARAMETERS: Op - Parse node 662 * 663 * RETURN: None 664 * 665 * DESCRIPTION: Convert UUID string to 16-byte buffer 666 * 667 ******************************************************************************/ 668 669 static void 670 OpcDoUuId ( 671 ACPI_PARSE_OBJECT *Op) 672 { 673 char *InString; 674 UINT8 *Buffer; 675 ACPI_STATUS Status = AE_OK; 676 ACPI_PARSE_OBJECT *NewOp; 677 678 679 InString = ACPI_CAST_PTR (char, Op->Asl.Value.String); 680 Buffer = UtLocalCalloc (16); 681 682 Status = AuValidateUuid (InString); 683 if (ACPI_FAILURE (Status)) 684 { 685 AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String); 686 } 687 else 688 { 689 AcpiUtConvertStringToUuid (InString, Buffer); 690 } 691 692 /* Change Op to a Buffer */ 693 694 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 695 Op->Common.AmlOpcode = AML_BUFFER_OP; 696 697 /* Disable further optimization */ 698 699 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 700 UtSetParseOpName (Op); 701 702 /* Child node is the buffer length */ 703 704 NewOp = TrAllocateNode (PARSEOP_INTEGER); 705 706 NewOp->Asl.AmlOpcode = AML_BYTE_OP; 707 NewOp->Asl.Value.Integer = 16; 708 NewOp->Asl.Parent = Op; 709 710 Op->Asl.Child = NewOp; 711 Op = NewOp; 712 713 /* Peer to the child is the raw buffer data */ 714 715 NewOp = TrAllocateNode (PARSEOP_RAW_DATA); 716 NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 717 NewOp->Asl.AmlLength = 16; 718 NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer); 719 NewOp->Asl.Parent = Op->Asl.Parent; 720 721 Op->Asl.Next = NewOp; 722 } 723 724 725 /******************************************************************************* 726 * 727 * FUNCTION: OpcGenerateAmlOpcode 728 * 729 * PARAMETERS: Op - Parse node 730 * 731 * RETURN: None 732 * 733 * DESCRIPTION: Generate the AML opcode associated with the node and its 734 * parse (lex/flex) keyword opcode. Essentially implements 735 * a mapping between the parse opcodes and the actual AML opcodes. 736 * 737 ******************************************************************************/ 738 739 void 740 OpcGenerateAmlOpcode ( 741 ACPI_PARSE_OBJECT *Op) 742 { 743 UINT16 Index; 744 745 746 Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE); 747 748 Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode; 749 Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype; 750 Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags; 751 752 if (!Op->Asl.Value.Integer) 753 { 754 Op->Asl.Value.Integer = AslKeywordMapping[Index].Value; 755 } 756 757 /* Special handling for some opcodes */ 758 759 switch (Op->Asl.ParseOpcode) 760 { 761 case PARSEOP_INTEGER: 762 /* 763 * Set the opcode based on the size of the integer 764 */ 765 (void) OpcSetOptimalIntegerSize (Op); 766 break; 767 768 case PARSEOP_OFFSET: 769 770 Op->Asl.AmlOpcodeLength = 1; 771 break; 772 773 case PARSEOP_ACCESSAS: 774 775 OpcDoAccessAs (Op); 776 break; 777 778 case PARSEOP_CONNECTION: 779 780 OpcDoConnection (Op); 781 break; 782 783 case PARSEOP_EISAID: 784 785 OpcDoEisaId (Op); 786 break; 787 788 case PARSEOP_PRINTF: 789 790 OpcDoPrintf (Op); 791 break; 792 793 case PARSEOP_FPRINTF: 794 795 OpcDoFprintf (Op); 796 break; 797 798 case PARSEOP_TOPLD: 799 800 OpcDoPld (Op); 801 break; 802 803 case PARSEOP_TOUUID: 804 805 OpcDoUuId (Op); 806 break; 807 808 case PARSEOP_UNICODE: 809 810 OpcDoUnicode (Op); 811 break; 812 813 case PARSEOP_INCLUDE: 814 815 Gbl_HasIncludeFiles = TRUE; 816 break; 817 818 case PARSEOP_EXTERNAL: 819 820 if (Gbl_DoExternals == FALSE) 821 { 822 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 823 Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 824 } 825 break; 826 827 case PARSEOP_TIMER: 828 829 if (AcpiGbl_IntegerBitWidth == 32) 830 { 831 AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL); 832 } 833 break; 834 835 default: 836 837 /* Nothing to do for other opcodes */ 838 839 break; 840 } 841 842 return; 843 } 844