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 <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 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: OpcStrupr (strupr) 795 * 796 * PARAMETERS: SrcString - The source string to convert 797 * 798 * RETURN: None 799 * 800 * DESCRIPTION: Convert string to uppercase 801 * 802 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 803 * 804 ******************************************************************************/ 805 806 static void 807 OpcStrupr ( 808 char *SrcString) 809 { 810 char *String; 811 812 813 if (!SrcString) 814 { 815 return; 816 } 817 818 /* Walk entire string, uppercasing the letters */ 819 820 for (String = SrcString; *String; String++) 821 { 822 *String = (char) toupper ((int) *String); 823 } 824 825 return; 826 } 827 828 829 /******************************************************************************* 830 * 831 * FUNCTION: OpcFindName 832 * 833 * PARAMETERS: List - Array of char strings to be searched 834 * Name - Char string to string for 835 * Index - Index value to set if found 836 * 837 * RETURN: TRUE if any names matched, FALSE otherwise 838 * 839 * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to 840 * equivalent parameter value. 841 * 842 ******************************************************************************/ 843 844 static BOOLEAN 845 OpcFindName ( 846 char **List, 847 char *Name, 848 UINT64 *Index) 849 { 850 char *Str; 851 UINT32 i; 852 853 854 OpcStrupr (Name); 855 856 for (i = 0, Str = List[0]; Str; i++, Str = List[i]) 857 { 858 if (!(strncmp (Str, Name, strlen (Name)))) 859 { 860 *Index = i; 861 return (TRUE); 862 } 863 } 864 865 return (FALSE); 866 } 867 868 869 /******************************************************************************* 870 * 871 * FUNCTION: OpcDoPld 872 * 873 * PARAMETERS: Op - Parse node 874 * 875 * RETURN: None 876 * 877 * DESCRIPTION: Convert ToPLD macro to 20-byte buffer 878 * 879 ******************************************************************************/ 880 881 static void 882 OpcDoPld ( 883 ACPI_PARSE_OBJECT *Op) 884 { 885 UINT8 *Buffer; 886 ACPI_PARSE_OBJECT *Node; 887 ACPI_PLD_INFO PldInfo; 888 ACPI_PARSE_OBJECT *NewOp; 889 890 891 if (!Op) 892 { 893 AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL); 894 return; 895 } 896 897 if (Op->Asl.ParseOpcode != PARSEOP_TOPLD) 898 { 899 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL); 900 return; 901 } 902 903 Buffer = UtLocalCalloc (ACPI_PLD_BUFFER_SIZE); 904 if (!Buffer) 905 { 906 AslError(ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, Op, NULL); 907 return; 908 } 909 910 memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO)); 911 912 Node = Op->Asl.Child; 913 while (Node) 914 { 915 switch (Node->Asl.ParseOpcode) 916 { 917 case PARSEOP_PLD_REVISION: 918 919 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 920 { 921 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 922 break; 923 } 924 925 if (Node->Asl.Child->Asl.Value.Integer > 127) 926 { 927 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 928 break; 929 } 930 931 PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer; 932 break; 933 934 case PARSEOP_PLD_IGNORECOLOR: 935 936 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 937 { 938 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 939 break; 940 } 941 942 if (Node->Asl.Child->Asl.Value.Integer > 1) 943 { 944 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 945 break; 946 } 947 948 PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer; 949 break; 950 951 case PARSEOP_PLD_RED: 952 case PARSEOP_PLD_GREEN: 953 case PARSEOP_PLD_BLUE: 954 955 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 956 { 957 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 958 break; 959 } 960 961 if (Node->Asl.Child->Asl.Value.Integer > 255) 962 { 963 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 964 break; 965 } 966 967 if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED) 968 { 969 PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer; 970 } 971 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN) 972 { 973 PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer; 974 } 975 else /* PARSEOP_PLD_BLUE */ 976 { 977 PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer; 978 } 979 break; 980 981 case PARSEOP_PLD_WIDTH: 982 case PARSEOP_PLD_HEIGHT: 983 984 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 985 { 986 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 987 break; 988 } 989 990 if (Node->Asl.Child->Asl.Value.Integer > 65535) 991 { 992 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 993 break; 994 } 995 996 if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH) 997 { 998 PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer; 999 } 1000 else /* PARSEOP_PLD_HEIGHT */ 1001 { 1002 PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer; 1003 } 1004 1005 break; 1006 1007 case PARSEOP_PLD_USERVISIBLE: 1008 case PARSEOP_PLD_DOCK: 1009 case PARSEOP_PLD_LID: 1010 1011 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1012 { 1013 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1014 break; 1015 } 1016 1017 if (Node->Asl.Child->Asl.Value.Integer > 1) 1018 { 1019 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1020 break; 1021 } 1022 1023 if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE) 1024 { 1025 PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1026 } 1027 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK) 1028 { 1029 PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1030 } 1031 else 1032 { 1033 PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1034 } 1035 1036 break; 1037 1038 case PARSEOP_PLD_PANEL: 1039 1040 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1041 { 1042 if (Node->Asl.Child->Asl.Value.Integer > 6) 1043 { 1044 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1045 break; 1046 } 1047 } 1048 else /* PARSEOP_STRING */ 1049 { 1050 if (!OpcFindName(AslPldPanelList, 1051 Node->Asl.Child->Asl.Value.String, 1052 &Node->Asl.Child->Asl.Value.Integer)) 1053 { 1054 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1055 break; 1056 } 1057 } 1058 1059 PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1060 break; 1061 1062 case PARSEOP_PLD_VERTICALPOSITION: 1063 1064 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1065 { 1066 if (Node->Asl.Child->Asl.Value.Integer > 2) 1067 { 1068 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1069 break; 1070 } 1071 } 1072 else /* PARSEOP_STRING */ 1073 { 1074 if (!OpcFindName(AslPldVerticalPositionList, 1075 Node->Asl.Child->Asl.Value.String, 1076 &Node->Asl.Child->Asl.Value.Integer)) 1077 { 1078 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1079 break; 1080 } 1081 } 1082 1083 PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1084 break; 1085 1086 case PARSEOP_PLD_HORIZONTALPOSITION: 1087 1088 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1089 { 1090 if (Node->Asl.Child->Asl.Value.Integer > 2) 1091 { 1092 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1093 break; 1094 } 1095 } 1096 else /* PARSEOP_STRING */ 1097 { 1098 if (!OpcFindName(AslPldHorizontalPositionList, 1099 Node->Asl.Child->Asl.Value.String, 1100 &Node->Asl.Child->Asl.Value.Integer)) 1101 { 1102 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1103 break; 1104 } 1105 } 1106 1107 PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1108 break; 1109 1110 case PARSEOP_PLD_SHAPE: 1111 1112 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) 1113 { 1114 if (Node->Asl.Child->Asl.Value.Integer > 8) 1115 { 1116 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1117 break; 1118 } 1119 } 1120 else /* PARSEOP_STRING */ 1121 { 1122 if (!OpcFindName(AslPldShapeList, 1123 Node->Asl.Child->Asl.Value.String, 1124 &Node->Asl.Child->Asl.Value.Integer)) 1125 { 1126 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); 1127 break; 1128 } 1129 } 1130 1131 PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1132 break; 1133 1134 case PARSEOP_PLD_GROUPORIENTATION: 1135 1136 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1137 { 1138 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1139 break; 1140 } 1141 1142 if (Node->Asl.Child->Asl.Value.Integer > 1) 1143 { 1144 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1145 break; 1146 } 1147 1148 PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1149 break; 1150 1151 case PARSEOP_PLD_GROUPTOKEN: 1152 case PARSEOP_PLD_GROUPPOSITION: 1153 1154 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1155 { 1156 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1157 break; 1158 } 1159 1160 if (Node->Asl.Child->Asl.Value.Integer > 255) 1161 { 1162 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1163 break; 1164 } 1165 1166 1167 if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN) 1168 { 1169 PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1170 } 1171 else /* PARSEOP_PLD_GROUPPOSITION */ 1172 { 1173 PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1174 } 1175 1176 break; 1177 1178 case PARSEOP_PLD_BAY: 1179 case PARSEOP_PLD_EJECTABLE: 1180 case PARSEOP_PLD_EJECTREQUIRED: 1181 1182 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1183 { 1184 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1185 break; 1186 } 1187 1188 if (Node->Asl.Child->Asl.Value.Integer > 1) 1189 { 1190 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1191 break; 1192 } 1193 1194 if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY) 1195 { 1196 PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1197 } 1198 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE) 1199 { 1200 PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1201 } 1202 else /* PARSEOP_PLD_EJECTREQUIRED */ 1203 { 1204 PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1205 } 1206 1207 break; 1208 1209 case PARSEOP_PLD_CABINETNUMBER: 1210 case PARSEOP_PLD_CARDCAGENUMBER: 1211 1212 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1213 { 1214 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1215 break; 1216 } 1217 1218 if (Node->Asl.Child->Asl.Value.Integer > 255) 1219 { 1220 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1221 break; 1222 } 1223 1224 if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER) 1225 { 1226 PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1227 } 1228 else /* PARSEOP_PLD_CARDCAGENUMBER */ 1229 { 1230 PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1231 } 1232 1233 break; 1234 1235 case PARSEOP_PLD_REFERENCE: 1236 1237 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1238 { 1239 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1240 break; 1241 } 1242 1243 if (Node->Asl.Child->Asl.Value.Integer > 1) 1244 { 1245 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1246 break; 1247 } 1248 1249 PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1250 break; 1251 1252 case PARSEOP_PLD_ROTATION: 1253 1254 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1255 { 1256 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1257 break; 1258 } 1259 1260 if (Node->Asl.Child->Asl.Value.Integer > 7) 1261 { 1262 switch (Node->Asl.Child->Asl.Value.Integer) 1263 { 1264 case 45: 1265 1266 Node->Asl.Child->Asl.Value.Integer = 1; 1267 break; 1268 1269 case 90: 1270 1271 Node->Asl.Child->Asl.Value.Integer = 2; 1272 break; 1273 1274 case 135: 1275 1276 Node->Asl.Child->Asl.Value.Integer = 3; 1277 break; 1278 1279 case 180: 1280 1281 Node->Asl.Child->Asl.Value.Integer = 4; 1282 break; 1283 1284 case 225: 1285 1286 Node->Asl.Child->Asl.Value.Integer = 5; 1287 break; 1288 1289 case 270: 1290 1291 Node->Asl.Child->Asl.Value.Integer = 6; 1292 break; 1293 1294 case 315: 1295 1296 Node->Asl.Child->Asl.Value.Integer = 7; 1297 break; 1298 1299 default: 1300 1301 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1302 break; 1303 } 1304 } 1305 1306 PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1307 break; 1308 1309 case PARSEOP_PLD_ORDER: 1310 1311 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1312 { 1313 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1314 break; 1315 } 1316 1317 if (Node->Asl.Child->Asl.Value.Integer > 31) 1318 { 1319 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1320 break; 1321 } 1322 1323 PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer; 1324 break; 1325 1326 case PARSEOP_PLD_VERTICALOFFSET: 1327 case PARSEOP_PLD_HORIZONTALOFFSET: 1328 1329 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) 1330 { 1331 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1332 break; 1333 } 1334 1335 if (Node->Asl.Child->Asl.Value.Integer > 65535) 1336 { 1337 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); 1338 break; 1339 } 1340 1341 if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET) 1342 { 1343 PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; 1344 } 1345 else /* PARSEOP_PLD_HORIZONTALOFFSET */ 1346 { 1347 PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; 1348 } 1349 1350 break; 1351 1352 default: 1353 1354 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); 1355 break; 1356 } 1357 1358 Node = Node->Asl.Next; 1359 } 1360 1361 Buffer = OpcEncodePldBuffer(&PldInfo); 1362 1363 /* Change Op to a Buffer */ 1364 1365 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1366 Op->Common.AmlOpcode = AML_BUFFER_OP; 1367 1368 /* Disable further optimization */ 1369 1370 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 1371 UtSetParseOpName (Op); 1372 1373 /* Child node is the buffer length */ 1374 1375 NewOp = TrAllocateNode (PARSEOP_INTEGER); 1376 1377 NewOp->Asl.AmlOpcode = AML_BYTE_OP; 1378 NewOp->Asl.Value.Integer = 20; 1379 NewOp->Asl.Parent = Op; 1380 1381 Op->Asl.Child = NewOp; 1382 Op = NewOp; 1383 1384 /* Peer to the child is the raw buffer data */ 1385 1386 NewOp = TrAllocateNode (PARSEOP_RAW_DATA); 1387 NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 1388 NewOp->Asl.AmlLength = 20; 1389 NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer); 1390 NewOp->Asl.Parent = Op->Asl.Parent; 1391 1392 Op->Asl.Next = NewOp; 1393 } 1394 1395 1396 /******************************************************************************* 1397 * 1398 * FUNCTION: OpcDoUuId 1399 * 1400 * PARAMETERS: Op - Parse node 1401 * 1402 * RETURN: None 1403 * 1404 * DESCRIPTION: Convert UUID string to 16-byte buffer 1405 * 1406 ******************************************************************************/ 1407 1408 static void 1409 OpcDoUuId ( 1410 ACPI_PARSE_OBJECT *Op) 1411 { 1412 char *InString; 1413 UINT8 *Buffer; 1414 ACPI_STATUS Status = AE_OK; 1415 ACPI_PARSE_OBJECT *NewOp; 1416 1417 1418 InString = ACPI_CAST_PTR (char, Op->Asl.Value.String); 1419 Buffer = UtLocalCalloc (16); 1420 1421 Status = AuValidateUuid (InString); 1422 if (ACPI_FAILURE (Status)) 1423 { 1424 AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String); 1425 } 1426 else 1427 { 1428 AcpiUtConvertStringToUuid (InString, Buffer); 1429 } 1430 1431 /* Change Op to a Buffer */ 1432 1433 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1434 Op->Common.AmlOpcode = AML_BUFFER_OP; 1435 1436 /* Disable further optimization */ 1437 1438 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; 1439 UtSetParseOpName (Op); 1440 1441 /* Child node is the buffer length */ 1442 1443 NewOp = TrAllocateNode (PARSEOP_INTEGER); 1444 1445 NewOp->Asl.AmlOpcode = AML_BYTE_OP; 1446 NewOp->Asl.Value.Integer = 16; 1447 NewOp->Asl.Parent = Op; 1448 1449 Op->Asl.Child = NewOp; 1450 Op = NewOp; 1451 1452 /* Peer to the child is the raw buffer data */ 1453 1454 NewOp = TrAllocateNode (PARSEOP_RAW_DATA); 1455 NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 1456 NewOp->Asl.AmlLength = 16; 1457 NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer); 1458 NewOp->Asl.Parent = Op->Asl.Parent; 1459 1460 Op->Asl.Next = NewOp; 1461 } 1462 1463 1464 /******************************************************************************* 1465 * 1466 * FUNCTION: OpcGenerateAmlOpcode 1467 * 1468 * PARAMETERS: Op - Parse node 1469 * 1470 * RETURN: None 1471 * 1472 * DESCRIPTION: Generate the AML opcode associated with the node and its 1473 * parse (lex/flex) keyword opcode. Essentially implements 1474 * a mapping between the parse opcodes and the actual AML opcodes. 1475 * 1476 ******************************************************************************/ 1477 1478 void 1479 OpcGenerateAmlOpcode ( 1480 ACPI_PARSE_OBJECT *Op) 1481 { 1482 UINT16 Index; 1483 1484 1485 Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE); 1486 1487 Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode; 1488 Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype; 1489 Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags; 1490 1491 if (!Op->Asl.Value.Integer) 1492 { 1493 Op->Asl.Value.Integer = AslKeywordMapping[Index].Value; 1494 } 1495 1496 /* Special handling for some opcodes */ 1497 1498 switch (Op->Asl.ParseOpcode) 1499 { 1500 case PARSEOP_INTEGER: 1501 /* 1502 * Set the opcode based on the size of the integer 1503 */ 1504 (void) OpcSetOptimalIntegerSize (Op); 1505 break; 1506 1507 case PARSEOP_OFFSET: 1508 1509 Op->Asl.AmlOpcodeLength = 1; 1510 break; 1511 1512 case PARSEOP_ACCESSAS: 1513 1514 OpcDoAccessAs (Op); 1515 break; 1516 1517 case PARSEOP_CONNECTION: 1518 1519 OpcDoConnection (Op); 1520 break; 1521 1522 case PARSEOP_EISAID: 1523 1524 OpcDoEisaId (Op); 1525 break; 1526 1527 case PARSEOP_PRINTF: 1528 1529 OpcDoPrintf (Op); 1530 break; 1531 1532 case PARSEOP_FPRINTF: 1533 1534 OpcDoFprintf (Op); 1535 break; 1536 1537 case PARSEOP_TOPLD: 1538 1539 OpcDoPld (Op); 1540 break; 1541 1542 case PARSEOP_TOUUID: 1543 1544 OpcDoUuId (Op); 1545 break; 1546 1547 case PARSEOP_UNICODE: 1548 1549 OpcDoUnicode (Op); 1550 break; 1551 1552 case PARSEOP_INCLUDE: 1553 1554 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1555 Gbl_HasIncludeFiles = TRUE; 1556 break; 1557 1558 case PARSEOP_EXTERNAL: 1559 1560 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1561 Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1562 break; 1563 1564 case PARSEOP_TIMER: 1565 1566 if (AcpiGbl_IntegerBitWidth == 32) 1567 { 1568 AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL); 1569 } 1570 break; 1571 1572 default: 1573 1574 /* Nothing to do for other opcodes */ 1575 1576 break; 1577 } 1578 1579 return; 1580 } 1581