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 "aslcompiler.h" 45 #include "aslcompiler.y.h" 46 #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 OpcDoPld ( 72 ACPI_PARSE_OBJECT *Op); 73 74 static void 75 OpcDoUuId ( 76 ACPI_PARSE_OBJECT *Op); 77 78 static UINT8 * 79 OpcEncodePldBuffer ( 80 ACPI_PLD_INFO *PldInfo); 81 82 83 /* ToPld strings */ 84 85 static char *AslPldPanelList[] = 86 { 87 "TOP", 88 "BOTTOM", 89 "LEFT", 90 "RIGHT", 91 "FRONT", 92 "BACK", 93 "UNKNOWN", 94 NULL 95 }; 96 97 static char *AslPldVerticalPositionList[] = 98 { 99 "UPPER", 100 "CENTER", 101 "LOWER", 102 NULL 103 }; 104 105 static char *AslPldHorizontalPositionList[] = 106 { 107 "LEFT", 108 "CENTER", 109 "RIGHT", 110 NULL 111 }; 112 113 static char *AslPldShapeList[] = 114 { 115 "ROUND", 116 "OVAL", 117 "SQUARE", 118 "VERTICALRECTANGLE", 119 "HORIZONTALRECTANGLE", 120 "VERTICALTRAPEZOID", 121 "HORIZONTALTRAPEZOID", 122 "UNKNOWN", 123 "CHAMFERED", 124 NULL 125 }; 126 127 128 /******************************************************************************* 129 * 130 * FUNCTION: OpcAmlOpcodeUpdateWalk 131 * 132 * PARAMETERS: ASL_WALK_CALLBACK 133 * 134 * RETURN: Status 135 * 136 * DESCRIPTION: Opcode update walk, ascending callback 137 * 138 ******************************************************************************/ 139 140 ACPI_STATUS 141 OpcAmlOpcodeUpdateWalk ( 142 ACPI_PARSE_OBJECT *Op, 143 UINT32 Level, 144 void *Context) 145 { 146 147 /* 148 * Handle the Package() case where the actual opcode cannot be determined 149 * until the PackageLength operand has been folded and minimized. 150 * (PackageOp versus VarPackageOp) 151 * 152 * This is (as of ACPI 3.0) the only case where the AML opcode can change 153 * based upon the value of a parameter. 154 * 155 * The parser always inserts a VarPackage opcode, which can possibly be 156 * optimized to a Package opcode. 157 */ 158 if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE) 159 { 160 OpnDoPackage (Op); 161 } 162 163 return (AE_OK); 164 } 165 166 167 /******************************************************************************* 168 * 169 * FUNCTION: OpcAmlOpcodeWalk 170 * 171 * PARAMETERS: ASL_WALK_CALLBACK 172 * 173 * RETURN: Status 174 * 175 * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML 176 * operands. 177 * 178 ******************************************************************************/ 179 180 ACPI_STATUS 181 OpcAmlOpcodeWalk ( 182 ACPI_PARSE_OBJECT *Op, 183 UINT32 Level, 184 void *Context) 185 { 186 187 TotalParseNodes++; 188 189 OpcGenerateAmlOpcode (Op); 190 OpnGenerateAmlOperands (Op); 191 return (AE_OK); 192 } 193 194 195 /******************************************************************************* 196 * 197 * FUNCTION: OpcGetIntegerWidth 198 * 199 * PARAMETERS: Op - DEFINITION BLOCK op 200 * 201 * RETURN: none 202 * 203 * DESCRIPTION: Extract integer width from the table revision 204 * 205 ******************************************************************************/ 206 207 void 208 OpcGetIntegerWidth ( 209 ACPI_PARSE_OBJECT *Op) 210 { 211 ACPI_PARSE_OBJECT *Child; 212 213 214 if (!Op) 215 { 216 return; 217 } 218 219 if (Gbl_RevisionOverride) 220 { 221 AcpiUtSetIntegerWidth (Gbl_RevisionOverride); 222 } 223 else 224 { 225 Child = Op->Asl.Child; 226 Child = Child->Asl.Next; 227 Child = Child->Asl.Next; 228 229 /* Use the revision to set the integer width */ 230 231 AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer); 232 } 233 } 234 235 236 /******************************************************************************* 237 * 238 * FUNCTION: OpcSetOptimalIntegerSize 239 * 240 * PARAMETERS: Op - A parse tree node 241 * 242 * RETURN: Integer width, in bytes. Also sets the node AML opcode to the 243 * optimal integer AML prefix opcode. 244 * 245 * DESCRIPTION: Determine the optimal AML encoding of an integer. All leading 246 * zeros can be truncated to squeeze the integer into the 247 * minimal number of AML bytes. 248 * 249 ******************************************************************************/ 250 251 UINT32 252 OpcSetOptimalIntegerSize ( 253 ACPI_PARSE_OBJECT *Op) 254 { 255 256 #if 0 257 /* 258 * TBD: - we don't want to optimize integers in the block header, but the 259 * code below does not work correctly. 260 */ 261 if (Op->Asl.Parent && 262 Op->Asl.Parent->Asl.Parent && 263 (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)) 264 { 265 return (0); 266 } 267 #endif 268 269 /* 270 * Check for the special AML integers first - Zero, One, Ones. 271 * These are single-byte opcodes that are the smallest possible 272 * representation of an integer. 273 * 274 * This optimization is optional. 275 */ 276 if (Gbl_IntegerOptimizationFlag) 277 { 278 switch (Op->Asl.Value.Integer) 279 { 280 case 0: 281 282 Op->Asl.AmlOpcode = AML_ZERO_OP; 283 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 284 Op, "Zero"); 285 return (1); 286 287 case 1: 288 289 Op->Asl.AmlOpcode = AML_ONE_OP; 290 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 291 Op, "One"); 292 return (1); 293 294 case ACPI_UINT32_MAX: 295 296 /* Check for table integer width (32 or 64) */ 297 298 if (AcpiGbl_IntegerByteWidth == 4) 299 { 300 Op->Asl.AmlOpcode = AML_ONES_OP; 301 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 302 Op, "Ones"); 303 return (1); 304 } 305 break; 306 307 case ACPI_UINT64_MAX: 308 309 /* Check for table integer width (32 or 64) */ 310 311 if (AcpiGbl_IntegerByteWidth == 8) 312 { 313 Op->Asl.AmlOpcode = AML_ONES_OP; 314 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION, 315 Op, "Ones"); 316 return (1); 317 } 318 break; 319 320 default: 321 322 break; 323 } 324 } 325 326 /* Find the best fit using the various AML integer prefixes */ 327 328 if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX) 329 { 330 Op->Asl.AmlOpcode = AML_BYTE_OP; 331 return (1); 332 } 333 334 if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX) 335 { 336 Op->Asl.AmlOpcode = AML_WORD_OP; 337 return (2); 338 } 339 340 if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX) 341 { 342 Op->Asl.AmlOpcode = AML_DWORD_OP; 343 return (4); 344 } 345 else 346 { 347 if (AcpiGbl_IntegerByteWidth == 4) 348 { 349 AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH, 350 Op, NULL); 351 352 if (!Gbl_IgnoreErrors) 353 { 354 /* Truncate the integer to 32-bit */ 355 Op->Asl.AmlOpcode = AML_DWORD_OP; 356 return (4); 357 } 358 } 359 360 Op->Asl.AmlOpcode = AML_QWORD_OP; 361 return (8); 362 } 363 } 364 365 366 /******************************************************************************* 367 * 368 * FUNCTION: OpcDoAccessAs 369 * 370 * PARAMETERS: Op - Parse node 371 * 372 * RETURN: None 373 * 374 * DESCRIPTION: Implement the ACCESS_AS ASL keyword. 375 * 376 ******************************************************************************/ 377 378 static void 379 OpcDoAccessAs ( 380 ACPI_PARSE_OBJECT *Op) 381 { 382 ACPI_PARSE_OBJECT *TypeOp; 383 ACPI_PARSE_OBJECT *AttribOp; 384 ACPI_PARSE_OBJECT *LengthOp; 385 UINT8 Attribute; 386 387 388 Op->Asl.AmlOpcodeLength = 1; 389 TypeOp = Op->Asl.Child; 390 391 /* First child is the access type */ 392 393 TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 394 TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 395 396 /* Second child is the optional access attribute */ 397 398 AttribOp = TypeOp->Asl.Next; 399 if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 400 { 401 AttribOp->Asl.Value.Integer = 0; 402 } 403 404 AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 405 AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 406 407 /* Only a few AccessAttributes support AccessLength */ 408 409 Attribute = (UINT8) AttribOp->Asl.Value.Integer; 410 if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) && 411 (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) && 412 (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS)) 413 { 414 return; 415 } 416 417 Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP; 418 419 /* 420 * Child of Attributes is the AccessLength (required for Multibyte, 421 * RawBytes, RawProcess.) 422 */ 423 LengthOp = AttribOp->Asl.Child; 424 if (!LengthOp) 425 { 426 return; 427 } 428 429 /* TBD: probably can remove */ 430 431 if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 432 { 433 LengthOp->Asl.Value.Integer = 16; 434 } 435 436 LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 437 LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 438 } 439 440 441 /******************************************************************************* 442 * 443 * FUNCTION: OpcDoConnection 444 * 445 * PARAMETERS: Op - Parse node 446 * 447 * RETURN: None 448 * 449 * DESCRIPTION: Implement the Connection ASL keyword. 450 * 451 ******************************************************************************/ 452 453 static void 454 OpcDoConnection ( 455 ACPI_PARSE_OBJECT *Op) 456 { 457 ASL_RESOURCE_NODE *Rnode; 458 ACPI_PARSE_OBJECT *BufferOp; 459 ACPI_PARSE_OBJECT *BufferLengthOp; 460 ACPI_PARSE_OBJECT *BufferDataOp; 461 ASL_RESOURCE_INFO Info; 462 UINT8 State; 463 464 465 Op->Asl.AmlOpcodeLength = 1; 466 467 if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP) 468 { 469 return; 470 } 471 472 BufferOp = Op->Asl.Child; 473 BufferLengthOp = BufferOp->Asl.Child; 474 BufferDataOp = BufferLengthOp->Asl.Next; 475 476 Info.DescriptorTypeOp = BufferDataOp->Asl.Next; 477 Info.CurrentByteOffset = 0; 478 State = ACPI_RSTATE_NORMAL; 479 Rnode = RsDoOneResourceDescriptor (&Info, &State); 480 if (!Rnode) 481 { 482 return; /* error */ 483 } 484 485 /* 486 * Transform the nodes into the following 487 * 488 * Op -> AML_BUFFER_OP 489 * First Child -> BufferLength 490 * Second Child -> Descriptor Buffer (raw byte data) 491 */ 492 BufferOp->Asl.ParseOpcode = PARSEOP_BUFFER; 493 BufferOp->Asl.AmlOpcode = AML_BUFFER_OP; 494 BufferOp->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC; 495 UtSetParseOpName (BufferOp); 496 497 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 498 BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength; 499 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 500 UtSetParseOpName (BufferLengthOp); 501 502 BufferDataOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 503 BufferDataOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 504 BufferDataOp->Asl.AmlOpcodeLength = 0; 505 BufferDataOp->Asl.AmlLength = Rnode->BufferLength; 506 BufferDataOp->Asl.Value.Buffer = (UINT8 *) Rnode; 507 UtSetParseOpName (BufferDataOp); 508 } 509 510 511 /******************************************************************************* 512 * 513 * FUNCTION: OpcDoUnicode 514 * 515 * PARAMETERS: Op - Parse node 516 * 517 * RETURN: None 518 * 519 * DESCRIPTION: Implement the UNICODE ASL "macro". Convert the input string 520 * to a unicode buffer. There is no Unicode AML opcode. 521 * 522 * Note: The Unicode string is 16 bits per character, no leading signature, 523 * with a 16-bit terminating NULL. 524 * 525 ******************************************************************************/ 526 527 static void 528 OpcDoUnicode ( 529 ACPI_PARSE_OBJECT *Op) 530 { 531 ACPI_PARSE_OBJECT *InitializerOp; 532 UINT32 Length; 533 UINT32 Count; 534 UINT32 i; 535 UINT8 *AsciiString; 536 UINT16 *UnicodeString; 537 ACPI_PARSE_OBJECT *BufferLengthOp; 538 539 540 /* Change op into a buffer object */ 541 542 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 543 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 544 UtSetParseOpName (Op); 545 546 /* Buffer Length is first, followed by the string */ 547 548 BufferLengthOp = Op->Asl.Child; 549 InitializerOp = BufferLengthOp->Asl.Next; 550 551 AsciiString = (UINT8 *) InitializerOp->Asl.Value.String; 552 553 /* Create a new buffer for the Unicode string */ 554 555 Count = strlen (InitializerOp->Asl.Value.String) + 1; 556 Length = Count * sizeof (UINT16); 557 UnicodeString = UtLocalCalloc (Length); 558 559 /* Convert to Unicode string (including null terminator) */ 560 561 for (i = 0; i < Count; i++) 562 { 563 UnicodeString[i] = (UINT16) AsciiString[i]; 564 } 565 566 /* 567 * Just set the buffer size node to be the buffer length, regardless 568 * of whether it was previously an integer or a default_arg placeholder 569 */ 570 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 571 BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP; 572 BufferLengthOp->Asl.Value.Integer = Length; 573 UtSetParseOpName (BufferLengthOp); 574 575 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 576 577 /* The Unicode string is a raw data buffer */ 578 579 InitializerOp->Asl.Value.Buffer = (UINT8 *) UnicodeString; 580 InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 581 InitializerOp->Asl.AmlLength = Length; 582 InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 583 InitializerOp->Asl.Child = NULL; 584 UtSetParseOpName (InitializerOp); 585 } 586 587 588 /******************************************************************************* 589 * 590 * FUNCTION: OpcDoEisaId 591 * 592 * PARAMETERS: Op - Parse node 593 * 594 * RETURN: None 595 * 596 * DESCRIPTION: Convert a string EISA ID to numeric representation. See the 597 * Pnp BIOS Specification for details. Here is an excerpt: 598 * 599 * A seven character ASCII representation of the product 600 * identifier compressed into a 32-bit identifier. The seven 601 * character ID consists of a three character manufacturer code, 602 * a three character hexadecimal product identifier, and a one 603 * character hexadecimal revision number. The manufacturer code 604 * is a 3 uppercase character code that is compressed into 3 5-bit 605 * values as follows: 606 * 1) Find hex ASCII value for each letter 607 * 2) Subtract 40h from each ASCII value 608 * 3) Retain 5 least significant bits for each letter by 609 * discarding upper 3 bits because they are always 0. 610 * 4) Compressed code = concatenate 0 and the 3 5-bit values 611 * 612 * The format of the compressed product identifier is as follows: 613 * Byte 0: Bit 7 - Reserved (0) 614 * Bits 6-2: - 1st character of compressed mfg code 615 * Bits 1-0 - Upper 2 bits of 2nd character of mfg code 616 * Byte 1: Bits 7-5 - Lower 3 bits of 2nd character of mfg code 617 * Bits 4-0 - 3rd character of mfg code 618 * Byte 2: Bits 7-4 - 1st hex digit of product number 619 * Bits 3-0 - 2nd hex digit of product number 620 * Byte 3: Bits 7-4 - 3st hex digit of product number 621 * Bits 3-0 - Hex digit of the revision number 622 * 623 ******************************************************************************/ 624 625 static void 626 OpcDoEisaId ( 627 ACPI_PARSE_OBJECT *Op) 628 { 629 UINT32 EisaId = 0; 630 UINT32 BigEndianId; 631 char *InString; 632 ACPI_STATUS Status = AE_OK; 633 UINT32 i; 634 635 636 InString = (char *) Op->Asl.Value.String; 637 638 /* 639 * The EISAID string must be exactly 7 characters and of the form 640 * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001") 641 */ 642 if (strlen (InString) != 7) 643 { 644 Status = AE_BAD_PARAMETER; 645 } 646 else 647 { 648 /* Check all 7 characters for correct format */ 649 650 for (i = 0; i < 7; i++) 651 { 652 /* First 3 characters must be uppercase letters */ 653 654 if (i < 3) 655 { 656 if (!isupper ((int) InString[i])) 657 { 658 Status = AE_BAD_PARAMETER; 659 } 660 } 661 662 /* Last 4 characters must be hex digits */ 663 664 else if (!isxdigit ((int) InString[i])) 665 { 666 Status = AE_BAD_PARAMETER; 667 } 668 } 669 } 670 671 if (ACPI_FAILURE (Status)) 672 { 673 AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String); 674 } 675 else 676 { 677 /* Create ID big-endian first (bits are contiguous) */ 678 679 BigEndianId = 680 (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 | 681 (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 | 682 (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 | 683 684 (AcpiUtAsciiCharToHex (InString[3])) << 12 | 685 (AcpiUtAsciiCharToHex (InString[4])) << 8 | 686 (AcpiUtAsciiCharToHex (InString[5])) << 4 | 687 AcpiUtAsciiCharToHex (InString[6]); 688 689 /* Swap to little-endian to get final ID (see function header) */ 690 691 EisaId = AcpiUtDwordByteSwap (BigEndianId); 692 } 693 694 /* 695 * Morph the Op into an integer, regardless of whether there 696 * was an error in the EISAID string 697 */ 698 Op->Asl.Value.Integer = EisaId; 699 700 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 701 Op->Asl.ParseOpcode = PARSEOP_INTEGER; 702 (void) OpcSetOptimalIntegerSize (Op); 703 704 /* Op is now an integer */ 705 706 UtSetParseOpName (Op); 707 } 708 709 710 /******************************************************************************* 711 * 712 * FUNCTION: OpcEncodePldBuffer 713 * 714 * PARAMETERS: PldInfo - _PLD buffer struct (Using local struct) 715 * 716 * RETURN: Encode _PLD buffer suitable for return value from _PLD 717 * 718 * DESCRIPTION: Bit-packs a _PLD buffer struct. 719 * 720 ******************************************************************************/ 721 722 static UINT8 * 723 OpcEncodePldBuffer ( 724 ACPI_PLD_INFO *PldInfo) 725 { 726 UINT32 *Buffer; 727 UINT32 Dword; 728 729 730 Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE); 731 if (!Buffer) 732 { 733 return (NULL); 734 } 735 736 /* First 32 bits */ 737 738 Dword = 0; 739 ACPI_PLD_SET_REVISION (&Dword, PldInfo->Revision); 740 ACPI_PLD_SET_IGNORE_COLOR (&Dword, PldInfo->IgnoreColor); 741 ACPI_PLD_SET_RED (&Dword, PldInfo->Red); 742 ACPI_PLD_SET_GREEN (&Dword, PldInfo->Green); 743 ACPI_PLD_SET_BLUE (&Dword, PldInfo->Blue); 744 ACPI_MOVE_32_TO_32 (&Buffer[0], &Dword); 745 746 /* Second 32 bits */ 747 748 Dword = 0; 749 ACPI_PLD_SET_WIDTH (&Dword, PldInfo->Width); 750 ACPI_PLD_SET_HEIGHT (&Dword, PldInfo->Height); 751 ACPI_MOVE_32_TO_32 (&Buffer[1], &Dword); 752 753 /* Third 32 bits */ 754 755 Dword = 0; 756 ACPI_PLD_SET_USER_VISIBLE (&Dword, PldInfo->UserVisible); 757 ACPI_PLD_SET_DOCK (&Dword, PldInfo->Dock); 758 ACPI_PLD_SET_LID (&Dword, PldInfo->Lid); 759 ACPI_PLD_SET_PANEL (&Dword, PldInfo->Panel); 760 ACPI_PLD_SET_VERTICAL (&Dword, PldInfo->VerticalPosition); 761 ACPI_PLD_SET_HORIZONTAL (&Dword, PldInfo->HorizontalPosition); 762 ACPI_PLD_SET_SHAPE (&Dword, PldInfo->Shape); 763 ACPI_PLD_SET_ORIENTATION (&Dword, PldInfo->GroupOrientation); 764 ACPI_PLD_SET_TOKEN (&Dword, PldInfo->GroupToken); 765 ACPI_PLD_SET_POSITION (&Dword, PldInfo->GroupPosition); 766 ACPI_PLD_SET_BAY (&Dword, PldInfo->Bay); 767 ACPI_MOVE_32_TO_32 (&Buffer[2], &Dword); 768 769 /* Fourth 32 bits */ 770 771 Dword = 0; 772 ACPI_PLD_SET_EJECTABLE (&Dword, PldInfo->Ejectable); 773 ACPI_PLD_SET_OSPM_EJECT (&Dword, PldInfo->OspmEjectRequired); 774 ACPI_PLD_SET_CABINET (&Dword, PldInfo->CabinetNumber); 775 ACPI_PLD_SET_CARD_CAGE (&Dword, PldInfo->CardCageNumber); 776 ACPI_PLD_SET_REFERENCE (&Dword, PldInfo->Reference); 777 ACPI_PLD_SET_ROTATION (&Dword, PldInfo->Rotation); 778 ACPI_PLD_SET_ORDER (&Dword, PldInfo->Order); 779 ACPI_MOVE_32_TO_32 (&Buffer[3], &Dword); 780 781 if (PldInfo->Revision >= 2) 782 { 783 /* Fifth 32 bits */ 784 785 Dword = 0; 786 ACPI_PLD_SET_VERT_OFFSET (&Dword, PldInfo->VerticalOffset); 787 ACPI_PLD_SET_HORIZ_OFFSET (&Dword, PldInfo->HorizontalOffset); 788 ACPI_MOVE_32_TO_32 (&Buffer[4], &Dword); 789 } 790 791 return (ACPI_CAST_PTR (UINT8, Buffer)); 792 } 793 794 795 /******************************************************************************* 796 * 797 * FUNCTION: OpcFindName 798 * 799 * PARAMETERS: List - Array of char strings to be searched 800 * Name - Char string to string for 801 * Index - Index value to set if found 802 * 803 * RETURN: TRUE if any names matched, FALSE otherwise 804 * 805 * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to 806 * equivalent parameter value. 807 * 808 ******************************************************************************/ 809 810 static BOOLEAN 811 OpcFindName ( 812 char **List, 813 char *Name, 814 UINT64 *Index) 815 { 816 char *Str; 817 UINT32 i; 818 819 820 AcpiUtStrupr (Name); 821 822 for (i = 0, Str = List[0]; Str; i++, Str = List[i]) 823 { 824 if (!(strncmp (Str, Name, strlen (Name)))) 825 { 826 *Index = i; 827 return (TRUE); 828 } 829 } 830 831 return (FALSE); 832 } 833 834 835 /******************************************************************************* 836 * 837 * FUNCTION: OpcDoPld 838 * 839 * PARAMETERS: Op - Parse node 840 * 841 * RETURN: None 842 * 843 * DESCRIPTION: Convert ToPLD macro to 20-byte buffer 844 * 845 ******************************************************************************/ 846 847 static void 848 OpcDoPld ( 849 ACPI_PARSE_OBJECT *Op) 850 { 851 UINT8 *Buffer; 852 ACPI_PARSE_OBJECT *Node; 853 ACPI_PLD_INFO PldInfo; 854 ACPI_PARSE_OBJECT *NewOp; 855 856 857 if (!Op) 858 { 859 AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL); 860 return; 861 } 862 863 if (Op->Asl.ParseOpcode != PARSEOP_TOPLD) 864 { 865 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL); 866 return; 867 } 868 869 memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO)); 870 871 Node = Op->Asl.Child; 872 while (Node) 873 { 874 switch (Node->Asl.ParseOpcode) 875 { 876 case PARSEOP_PLD_REVISION: 877 878 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 879 { 880 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 881 break; 882 } 883 884 if (Node->Asl.Child->Asl.Value.Integer > 127) 885 { 886 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 887 break; 888 } 889 890 PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer; 891 break; 892 893 case PARSEOP_PLD_IGNORECOLOR: 894 895 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 896 { 897 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 898 break; 899 } 900 901 if (Node->Asl.Child->Asl.Value.Integer > 1) 902 { 903 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 904 break; 905 } 906 907 PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer; 908 break; 909 910 case PARSEOP_PLD_RED: 911 case PARSEOP_PLD_GREEN: 912 case PARSEOP_PLD_BLUE: 913 914 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 915 { 916 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 917 break; 918 } 919 920 if (Node->Asl.Child->Asl.Value.Integer > 255) 921 { 922 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 923 break; 924 } 925 926 if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED) 927 { 928 PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer; 929 } 930 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN) 931 { 932 PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer; 933 } 934 else /* PARSEOP_PLD_BLUE */ 935 { 936 PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer; 937 } 938 break; 939 940 case PARSEOP_PLD_WIDTH: 941 case PARSEOP_PLD_HEIGHT: 942 943 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 944 { 945 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 946 break; 947 } 948 949 if (Node->Asl.Child->Asl.Value.Integer > 65535) 950 { 951 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 952 break; 953 } 954 955 if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH) 956 { 957 PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer; 958 } 959 else /* PARSEOP_PLD_HEIGHT */ 960 { 961 PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer; 962 } 963 964 break; 965 966 case PARSEOP_PLD_USERVISIBLE: 967 case PARSEOP_PLD_DOCK: 968 case PARSEOP_PLD_LID: 969 970 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 971 { 972 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 973 break; 974 } 975 976 if (Node->Asl.Child->Asl.Value.Integer > 1) 977 { 978 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 979 break; 980 } 981 982 if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE) 983 { 984 PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer; 985 } 986 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK) 987 { 988 PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer; 989 } 990 else 991 { 992 PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer; 993 } 994 995 break; 996 997 case PARSEOP_PLD_PANEL: 998 999 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1000 { 1001 if (Node->Asl.Child->Asl.Value.Integer > 6) 1002 { 1003 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1004 break; 1005 } 1006 } 1007 else /* PARSEOP_STRING */ 1008 { 1009 if (!OpcFindName(AslPldPanelList, 1010 Node->Asl.Child->Asl.Value.String, 1011 &Node->Asl.Child->Asl.Value.Integer)) 1012 { 1013 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1014 break; 1015 } 1016 } 1017 1018 PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1019 break; 1020 1021 case PARSEOP_PLD_VERTICALPOSITION: 1022 1023 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1024 { 1025 if (Node->Asl.Child->Asl.Value.Integer > 2) 1026 { 1027 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1028 break; 1029 } 1030 } 1031 else /* PARSEOP_STRING */ 1032 { 1033 if (!OpcFindName(AslPldVerticalPositionList, 1034 Node->Asl.Child->Asl.Value.String, 1035 &Node->Asl.Child->Asl.Value.Integer)) 1036 { 1037 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1038 break; 1039 } 1040 } 1041 1042 PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1043 break; 1044 1045 case PARSEOP_PLD_HORIZONTALPOSITION: 1046 1047 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1048 { 1049 if (Node->Asl.Child->Asl.Value.Integer > 2) 1050 { 1051 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1052 break; 1053 } 1054 } 1055 else /* PARSEOP_STRING */ 1056 { 1057 if (!OpcFindName(AslPldHorizontalPositionList, 1058 Node->Asl.Child->Asl.Value.String, 1059 &Node->Asl.Child->Asl.Value.Integer)) 1060 { 1061 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1062 break; 1063 } 1064 } 1065 1066 PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1067 break; 1068 1069 case PARSEOP_PLD_SHAPE: 1070 1071 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1072 { 1073 if (Node->Asl.Child->Asl.Value.Integer > 8) 1074 { 1075 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1076 break; 1077 } 1078 } 1079 else /* PARSEOP_STRING */ 1080 { 1081 if (!OpcFindName(AslPldShapeList, 1082 Node->Asl.Child->Asl.Value.String, 1083 &Node->Asl.Child->Asl.Value.Integer)) 1084 { 1085 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1086 break; 1087 } 1088 } 1089 1090 PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1091 break; 1092 1093 case PARSEOP_PLD_GROUPORIENTATION: 1094 1095 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1096 { 1097 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1098 break; 1099 } 1100 1101 if (Node->Asl.Child->Asl.Value.Integer > 1) 1102 { 1103 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1104 break; 1105 } 1106 1107 PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1108 break; 1109 1110 case PARSEOP_PLD_GROUPTOKEN: 1111 case PARSEOP_PLD_GROUPPOSITION: 1112 1113 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1114 { 1115 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1116 break; 1117 } 1118 1119 if (Node->Asl.Child->Asl.Value.Integer > 255) 1120 { 1121 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1122 break; 1123 } 1124 1125 1126 if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN) 1127 { 1128 PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1129 } 1130 else /* PARSEOP_PLD_GROUPPOSITION */ 1131 { 1132 PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1133 } 1134 1135 break; 1136 1137 case PARSEOP_PLD_BAY: 1138 case PARSEOP_PLD_EJECTABLE: 1139 case PARSEOP_PLD_EJECTREQUIRED: 1140 1141 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1142 { 1143 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1144 break; 1145 } 1146 1147 if (Node->Asl.Child->Asl.Value.Integer > 1) 1148 { 1149 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1150 break; 1151 } 1152 1153 if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY) 1154 { 1155 PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1156 } 1157 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE) 1158 { 1159 PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1160 } 1161 else /* PARSEOP_PLD_EJECTREQUIRED */ 1162 { 1163 PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1164 } 1165 1166 break; 1167 1168 case PARSEOP_PLD_CABINETNUMBER: 1169 case PARSEOP_PLD_CARDCAGENUMBER: 1170 1171 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1172 { 1173 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1174 break; 1175 } 1176 1177 if (Node->Asl.Child->Asl.Value.Integer > 255) 1178 { 1179 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1180 break; 1181 } 1182 1183 if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER) 1184 { 1185 PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1186 } 1187 else /* PARSEOP_PLD_CARDCAGENUMBER */ 1188 { 1189 PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1190 } 1191 1192 break; 1193 1194 case PARSEOP_PLD_REFERENCE: 1195 1196 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1197 { 1198 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1199 break; 1200 } 1201 1202 if (Node->Asl.Child->Asl.Value.Integer > 1) 1203 { 1204 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1205 break; 1206 } 1207 1208 PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1209 break; 1210 1211 case PARSEOP_PLD_ROTATION: 1212 1213 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1214 { 1215 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1216 break; 1217 } 1218 1219 if (Node->Asl.Child->Asl.Value.Integer > 7) 1220 { 1221 switch (Node->Asl.Child->Asl.Value.Integer) 1222 { 1223 case 45: 1224 1225 Node->Asl.Child->Asl.Value.Integer = 1; 1226 break; 1227 1228 case 90: 1229 1230 Node->Asl.Child->Asl.Value.Integer = 2; 1231 break; 1232 1233 case 135: 1234 1235 Node->Asl.Child->Asl.Value.Integer = 3; 1236 break; 1237 1238 case 180: 1239 1240 Node->Asl.Child->Asl.Value.Integer = 4; 1241 break; 1242 1243 case 225: 1244 1245 Node->Asl.Child->Asl.Value.Integer = 5; 1246 break; 1247 1248 case 270: 1249 1250 Node->Asl.Child->Asl.Value.Integer = 6; 1251 break; 1252 1253 case 315: 1254 1255 Node->Asl.Child->Asl.Value.Integer = 7; 1256 break; 1257 1258 default: 1259 1260 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1261 break; 1262 } 1263 } 1264 1265 PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1266 break; 1267 1268 case PARSEOP_PLD_ORDER: 1269 1270 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1271 { 1272 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1273 break; 1274 } 1275 1276 if (Node->Asl.Child->Asl.Value.Integer > 31) 1277 { 1278 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1279 break; 1280 } 1281 1282 PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1283 break; 1284 1285 case PARSEOP_PLD_VERTICALOFFSET: 1286 case PARSEOP_PLD_HORIZONTALOFFSET: 1287 1288 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1289 { 1290 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1291 break; 1292 } 1293 1294 if (Node->Asl.Child->Asl.Value.Integer > 65535) 1295 { 1296 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1297 break; 1298 } 1299 1300 if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET) 1301 { 1302 PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; 1303 } 1304 else /* PARSEOP_PLD_HORIZONTALOFFSET */ 1305 { 1306 PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; 1307 } 1308 1309 break; 1310 1311 default: 1312 1313 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1314 break; 1315 } 1316 1317 Node = Node->Asl.Next; 1318 } 1319 1320 Buffer = OpcEncodePldBuffer(&PldInfo); 1321 1322 /* Change Op to a Buffer */ 1323 1324 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1325 Op->Common.AmlOpcode = AML_BUFFER_OP; 1326 1327 /* Disable further optimization */ 1328 1329 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 1330 UtSetParseOpName (Op); 1331 1332 /* Child node is the buffer length */ 1333 1334 NewOp = TrAllocateNode (PARSEOP_INTEGER); 1335 1336 NewOp->Asl.AmlOpcode = AML_BYTE_OP; 1337 NewOp->Asl.Value.Integer = 20; 1338 NewOp->Asl.Parent = Op; 1339 1340 Op->Asl.Child = NewOp; 1341 Op = NewOp; 1342 1343 /* Peer to the child is the raw buffer data */ 1344 1345 NewOp = TrAllocateNode (PARSEOP_RAW_DATA); 1346 NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 1347 NewOp->Asl.AmlLength = 20; 1348 NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer); 1349 NewOp->Asl.Parent = Op->Asl.Parent; 1350 1351 Op->Asl.Next = NewOp; 1352 } 1353 1354 1355 /******************************************************************************* 1356 * 1357 * FUNCTION: OpcDoUuId 1358 * 1359 * PARAMETERS: Op - Parse node 1360 * 1361 * RETURN: None 1362 * 1363 * DESCRIPTION: Convert UUID string to 16-byte buffer 1364 * 1365 ******************************************************************************/ 1366 1367 static void 1368 OpcDoUuId ( 1369 ACPI_PARSE_OBJECT *Op) 1370 { 1371 char *InString; 1372 UINT8 *Buffer; 1373 ACPI_STATUS Status = AE_OK; 1374 ACPI_PARSE_OBJECT *NewOp; 1375 1376 1377 InString = ACPI_CAST_PTR (char, Op->Asl.Value.String); 1378 Buffer = UtLocalCalloc (16); 1379 1380 Status = AuValidateUuid (InString); 1381 if (ACPI_FAILURE (Status)) 1382 { 1383 AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String); 1384 } 1385 else 1386 { 1387 AcpiUtConvertStringToUuid (InString, Buffer); 1388 } 1389 1390 /* Change Op to a Buffer */ 1391 1392 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1393 Op->Common.AmlOpcode = AML_BUFFER_OP; 1394 1395 /* Disable further optimization */ 1396 1397 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 1398 UtSetParseOpName (Op); 1399 1400 /* Child node is the buffer length */ 1401 1402 NewOp = TrAllocateNode (PARSEOP_INTEGER); 1403 1404 NewOp->Asl.AmlOpcode = AML_BYTE_OP; 1405 NewOp->Asl.Value.Integer = 16; 1406 NewOp->Asl.Parent = Op; 1407 1408 Op->Asl.Child = NewOp; 1409 Op = NewOp; 1410 1411 /* Peer to the child is the raw buffer data */ 1412 1413 NewOp = TrAllocateNode (PARSEOP_RAW_DATA); 1414 NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 1415 NewOp->Asl.AmlLength = 16; 1416 NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer); 1417 NewOp->Asl.Parent = Op->Asl.Parent; 1418 1419 Op->Asl.Next = NewOp; 1420 } 1421 1422 1423 /******************************************************************************* 1424 * 1425 * FUNCTION: OpcGenerateAmlOpcode 1426 * 1427 * PARAMETERS: Op - Parse node 1428 * 1429 * RETURN: None 1430 * 1431 * DESCRIPTION: Generate the AML opcode associated with the node and its 1432 * parse (lex/flex) keyword opcode. Essentially implements 1433 * a mapping between the parse opcodes and the actual AML opcodes. 1434 * 1435 ******************************************************************************/ 1436 1437 void 1438 OpcGenerateAmlOpcode ( 1439 ACPI_PARSE_OBJECT *Op) 1440 { 1441 UINT16 Index; 1442 1443 1444 Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE); 1445 1446 Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode; 1447 Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype; 1448 Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags; 1449 1450 if (!Op->Asl.Value.Integer) 1451 { 1452 Op->Asl.Value.Integer = AslKeywordMapping[Index].Value; 1453 } 1454 1455 /* Special handling for some opcodes */ 1456 1457 switch (Op->Asl.ParseOpcode) 1458 { 1459 case PARSEOP_INTEGER: 1460 /* 1461 * Set the opcode based on the size of the integer 1462 */ 1463 (void) OpcSetOptimalIntegerSize (Op); 1464 break; 1465 1466 case PARSEOP_OFFSET: 1467 1468 Op->Asl.AmlOpcodeLength = 1; 1469 break; 1470 1471 case PARSEOP_ACCESSAS: 1472 1473 OpcDoAccessAs (Op); 1474 break; 1475 1476 case PARSEOP_CONNECTION: 1477 1478 OpcDoConnection (Op); 1479 break; 1480 1481 case PARSEOP_EISAID: 1482 1483 OpcDoEisaId (Op); 1484 break; 1485 1486 case PARSEOP_PRINTF: 1487 1488 OpcDoPrintf (Op); 1489 break; 1490 1491 case PARSEOP_FPRINTF: 1492 1493 OpcDoFprintf (Op); 1494 break; 1495 1496 case PARSEOP_TOPLD: 1497 1498 OpcDoPld (Op); 1499 break; 1500 1501 case PARSEOP_TOUUID: 1502 1503 OpcDoUuId (Op); 1504 break; 1505 1506 case PARSEOP_UNICODE: 1507 1508 OpcDoUnicode (Op); 1509 break; 1510 1511 case PARSEOP_INCLUDE: 1512 1513 Gbl_HasIncludeFiles = TRUE; 1514 break; 1515 1516 case PARSEOP_EXTERNAL: 1517 1518 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1519 Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1520 break; 1521 1522 case PARSEOP_TIMER: 1523 1524 if (AcpiGbl_IntegerBitWidth == 32) 1525 { 1526 AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL); 1527 } 1528 break; 1529 1530 default: 1531 1532 /* Nothing to do for other opcodes */ 1533 1534 break; 1535 } 1536 1537 return; 1538 } 1539