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