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