1 /******************************************************************************
3 * Module Name: aslopcode - AML opcode generation
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
44 #include "aslcompiler.h"
45 #include "aslcompiler.y.h"
48 #define _COMPONENT ACPI_COMPILER
49 ACPI_MODULE_NAME ("aslopcodes")
52 /* Local prototypes */
56 ACPI_PARSE_OBJECT *Op);
60 ACPI_PARSE_OBJECT *Op);
64 ACPI_PARSE_OBJECT *Op);
68 ACPI_PARSE_OBJECT *Op);
72 ACPI_PARSE_OBJECT *Op);
76 ACPI_PARSE_OBJECT *Op);
80 ACPI_PLD_INFO *PldInfo);
85 static char *AslPldPanelList[] =
97 static char *AslPldVerticalPositionList[] =
105 static char *AslPldHorizontalPositionList[] =
113 static char *AslPldShapeList[] =
119 "HORIZONTALRECTANGLE",
121 "HORIZONTALTRAPEZOID",
128 /*******************************************************************************
130 * FUNCTION: OpcAmlOpcodeUpdateWalk
132 * PARAMETERS: ASL_WALK_CALLBACK
136 * DESCRIPTION: Opcode update walk, ascending callback
138 ******************************************************************************/
141 OpcAmlOpcodeUpdateWalk (
142 ACPI_PARSE_OBJECT *Op,
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)
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.
155 * The parser always inserts a VarPackage opcode, which can possibly be
156 * optimized to a Package opcode.
158 if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)
167 /*******************************************************************************
169 * FUNCTION: OpcAmlOpcodeWalk
171 * PARAMETERS: ASL_WALK_CALLBACK
175 * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
178 ******************************************************************************/
182 ACPI_PARSE_OBJECT *Op,
189 OpcGenerateAmlOpcode (Op);
190 OpnGenerateAmlOperands (Op);
195 /*******************************************************************************
197 * FUNCTION: OpcGetIntegerWidth
199 * PARAMETERS: Op - DEFINITION BLOCK op
203 * DESCRIPTION: Extract integer width from the table revision
205 ******************************************************************************/
209 ACPI_PARSE_OBJECT *Op)
211 ACPI_PARSE_OBJECT *Child;
219 if (Gbl_RevisionOverride)
221 AcpiUtSetIntegerWidth (Gbl_RevisionOverride);
225 Child = Op->Asl.Child;
226 Child = Child->Asl.Next;
227 Child = Child->Asl.Next;
229 /* Use the revision to set the integer width */
231 AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer);
236 /*******************************************************************************
238 * FUNCTION: OpcSetOptimalIntegerSize
240 * PARAMETERS: Op - A parse tree node
242 * RETURN: Integer width, in bytes. Also sets the node AML opcode to the
243 * optimal integer AML prefix opcode.
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.
249 ******************************************************************************/
252 OpcSetOptimalIntegerSize (
253 ACPI_PARSE_OBJECT *Op)
258 * TBD: - we don't want to optimize integers in the block header, but the
259 * code below does not work correctly.
261 if (Op->Asl.Parent &&
262 Op->Asl.Parent->Asl.Parent &&
263 (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK))
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.
274 * This optimization is optional.
276 if (Gbl_IntegerOptimizationFlag)
278 switch (Op->Asl.Value.Integer)
282 Op->Asl.AmlOpcode = AML_ZERO_OP;
283 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
289 Op->Asl.AmlOpcode = AML_ONE_OP;
290 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
294 case ACPI_UINT32_MAX:
296 /* Check for table integer width (32 or 64) */
298 if (AcpiGbl_IntegerByteWidth == 4)
300 Op->Asl.AmlOpcode = AML_ONES_OP;
301 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
307 case ACPI_UINT64_MAX:
309 /* Check for table integer width (32 or 64) */
311 if (AcpiGbl_IntegerByteWidth == 8)
313 Op->Asl.AmlOpcode = AML_ONES_OP;
314 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
326 /* Find the best fit using the various AML integer prefixes */
328 if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX)
330 Op->Asl.AmlOpcode = AML_BYTE_OP;
333 if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
335 Op->Asl.AmlOpcode = AML_WORD_OP;
338 if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
340 Op->Asl.AmlOpcode = AML_DWORD_OP;
345 if (AcpiGbl_IntegerByteWidth == 4)
347 AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
350 if (!Gbl_IgnoreErrors)
352 /* Truncate the integer to 32-bit */
353 Op->Asl.AmlOpcode = AML_DWORD_OP;
358 Op->Asl.AmlOpcode = AML_QWORD_OP;
364 /*******************************************************************************
366 * FUNCTION: OpcDoAccessAs
368 * PARAMETERS: Op - Parse node
372 * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
374 ******************************************************************************/
378 ACPI_PARSE_OBJECT *Op)
380 ACPI_PARSE_OBJECT *TypeOp;
381 ACPI_PARSE_OBJECT *AttribOp;
382 ACPI_PARSE_OBJECT *LengthOp;
386 Op->Asl.AmlOpcodeLength = 1;
387 TypeOp = Op->Asl.Child;
389 /* First child is the access type */
391 TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
392 TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
394 /* Second child is the optional access attribute */
396 AttribOp = TypeOp->Asl.Next;
397 if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
399 AttribOp->Asl.Value.Integer = 0;
401 AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
402 AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
404 /* Only a few AccessAttributes support AccessLength */
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))
414 Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
417 * Child of Attributes is the AccessLength (required for Multibyte,
418 * RawBytes, RawProcess.)
420 LengthOp = AttribOp->Asl.Child;
426 /* TBD: probably can remove */
428 if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
430 LengthOp->Asl.Value.Integer = 16;
433 LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
434 LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
438 /*******************************************************************************
440 * FUNCTION: OpcDoConnection
442 * PARAMETERS: Op - Parse node
446 * DESCRIPTION: Implement the Connection ASL keyword.
448 ******************************************************************************/
452 ACPI_PARSE_OBJECT *Op)
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;
462 Op->Asl.AmlOpcodeLength = 1;
464 if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
469 BufferOp = Op->Asl.Child;
470 BufferLengthOp = BufferOp->Asl.Child;
471 BufferDataOp = BufferLengthOp->Asl.Next;
473 Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
474 Info.CurrentByteOffset = 0;
475 State = ACPI_RSTATE_NORMAL;
476 Rnode = RsDoOneResourceDescriptor (&Info, &State);
483 * Transform the nodes into the following
485 * Op -> AML_BUFFER_OP
486 * First Child -> BufferLength
487 * Second Child -> Descriptor Buffer (raw byte data)
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);
494 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
495 BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
496 (void) OpcSetOptimalIntegerSize (BufferLengthOp);
497 UtSetParseOpName (BufferLengthOp);
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);
508 /*******************************************************************************
510 * FUNCTION: OpcDoUnicode
512 * PARAMETERS: Op - Parse node
516 * DESCRIPTION: Implement the UNICODE ASL "macro". Convert the input string
517 * to a unicode buffer. There is no Unicode AML opcode.
519 * Note: The Unicode string is 16 bits per character, no leading signature,
520 * with a 16-bit terminating NULL.
522 ******************************************************************************/
526 ACPI_PARSE_OBJECT *Op)
528 ACPI_PARSE_OBJECT *InitializerOp;
533 UINT16 *UnicodeString;
534 ACPI_PARSE_OBJECT *BufferLengthOp;
537 /* Change op into a buffer object */
539 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
540 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
541 UtSetParseOpName (Op);
543 /* Buffer Length is first, followed by the string */
545 BufferLengthOp = Op->Asl.Child;
546 InitializerOp = BufferLengthOp->Asl.Next;
548 AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
550 /* Create a new buffer for the Unicode string */
552 Count = strlen (InitializerOp->Asl.Value.String) + 1;
553 Length = Count * sizeof (UINT16);
554 UnicodeString = UtLocalCalloc (Length);
556 /* Convert to Unicode string (including null terminator) */
558 for (i = 0; i < Count; i++)
560 UnicodeString[i] = (UINT16) AsciiString[i];
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
567 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
568 BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP;
569 BufferLengthOp->Asl.Value.Integer = Length;
570 UtSetParseOpName (BufferLengthOp);
572 (void) OpcSetOptimalIntegerSize (BufferLengthOp);
574 /* The Unicode string is a raw data buffer */
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);
585 /*******************************************************************************
587 * FUNCTION: OpcDoEisaId
589 * PARAMETERS: Op - Parse node
593 * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
594 * Pnp BIOS Specification for details. Here is an excerpt:
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
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
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
620 ******************************************************************************/
624 ACPI_PARSE_OBJECT *Op)
629 ACPI_STATUS Status = AE_OK;
633 InString = (char *) Op->Asl.Value.String;
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")
639 if (strlen (InString) != 7)
641 Status = AE_BAD_PARAMETER;
645 /* Check all 7 characters for correct format */
647 for (i = 0; i < 7; i++)
649 /* First 3 characters must be uppercase letters */
653 if (!isupper ((int) InString[i]))
655 Status = AE_BAD_PARAMETER;
659 /* Last 4 characters must be hex digits */
661 else if (!isxdigit ((int) InString[i]))
663 Status = AE_BAD_PARAMETER;
668 if (ACPI_FAILURE (Status))
670 AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
674 /* Create ID big-endian first (bits are contiguous) */
677 (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
678 (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
679 (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
681 (AcpiUtAsciiCharToHex (InString[3])) << 12 |
682 (AcpiUtAsciiCharToHex (InString[4])) << 8 |
683 (AcpiUtAsciiCharToHex (InString[5])) << 4 |
684 AcpiUtAsciiCharToHex (InString[6]);
686 /* Swap to little-endian to get final ID (see function header) */
688 EisaId = AcpiUtDwordByteSwap (BigEndianId);
692 * Morph the Op into an integer, regardless of whether there
693 * was an error in the EISAID string
695 Op->Asl.Value.Integer = EisaId;
697 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
698 Op->Asl.ParseOpcode = PARSEOP_INTEGER;
699 (void) OpcSetOptimalIntegerSize (Op);
701 /* Op is now an integer */
703 UtSetParseOpName (Op);
707 /*******************************************************************************
709 * FUNCTION: OpcEncodePldBuffer
711 * PARAMETERS: PldInfo - _PLD buffer struct (Using local struct)
713 * RETURN: Encode _PLD buffer suitable for return value from _PLD
715 * DESCRIPTION: Bit-packs a _PLD buffer struct.
717 ******************************************************************************/
721 ACPI_PLD_INFO *PldInfo)
727 Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE);
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);
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);
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);
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);
778 if (PldInfo->Revision >= 2)
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);
788 return (ACPI_CAST_PTR (UINT8, Buffer));
792 /*******************************************************************************
794 * FUNCTION: OpcFindName
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
800 * RETURN: TRUE if any names matched, FALSE otherwise
802 * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to
803 * equivalent parameter value.
805 ******************************************************************************/
819 for (i = 0, Str = List[0]; Str; i++, Str = List[i])
821 if (!(strncmp (Str, Name, strlen (Name))))
832 /*******************************************************************************
836 * PARAMETERS: Op - Parse node
840 * DESCRIPTION: Convert ToPLD macro to 20-byte buffer
842 ******************************************************************************/
846 ACPI_PARSE_OBJECT *Op)
849 ACPI_PARSE_OBJECT *Node;
850 ACPI_PLD_INFO PldInfo;
851 ACPI_PARSE_OBJECT *NewOp;
856 AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL);
860 if (Op->Asl.ParseOpcode != PARSEOP_TOPLD)
862 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL);
866 memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
868 Node = Op->Asl.Child;
871 switch (Node->Asl.ParseOpcode)
873 case PARSEOP_PLD_REVISION:
875 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
877 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
881 if (Node->Asl.Child->Asl.Value.Integer > 127)
883 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
887 PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer;
890 case PARSEOP_PLD_IGNORECOLOR:
892 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
894 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
898 if (Node->Asl.Child->Asl.Value.Integer > 1)
900 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
904 PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer;
907 case PARSEOP_PLD_RED:
908 case PARSEOP_PLD_GREEN:
909 case PARSEOP_PLD_BLUE:
911 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
913 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
917 if (Node->Asl.Child->Asl.Value.Integer > 255)
919 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
923 if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED)
925 PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer;
927 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN)
929 PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer;
931 else /* PARSEOP_PLD_BLUE */
933 PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer;
937 case PARSEOP_PLD_WIDTH:
938 case PARSEOP_PLD_HEIGHT:
940 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
942 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
946 if (Node->Asl.Child->Asl.Value.Integer > 65535)
948 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
952 if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH)
954 PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer;
956 else /* PARSEOP_PLD_HEIGHT */
958 PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer;
963 case PARSEOP_PLD_USERVISIBLE:
964 case PARSEOP_PLD_DOCK:
965 case PARSEOP_PLD_LID:
967 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
969 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
973 if (Node->Asl.Child->Asl.Value.Integer > 1)
975 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
979 if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE)
981 PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer;
983 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK)
985 PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer;
989 PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer;
994 case PARSEOP_PLD_PANEL:
996 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
998 if (Node->Asl.Child->Asl.Value.Integer > 6)
1000 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1004 else /* PARSEOP_STRING */
1006 if (!OpcFindName(AslPldPanelList,
1007 Node->Asl.Child->Asl.Value.String,
1008 &Node->Asl.Child->Asl.Value.Integer))
1010 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1015 PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1018 case PARSEOP_PLD_VERTICALPOSITION:
1020 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1022 if (Node->Asl.Child->Asl.Value.Integer > 2)
1024 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1028 else /* PARSEOP_STRING */
1030 if (!OpcFindName(AslPldVerticalPositionList,
1031 Node->Asl.Child->Asl.Value.String,
1032 &Node->Asl.Child->Asl.Value.Integer))
1034 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1039 PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1042 case PARSEOP_PLD_HORIZONTALPOSITION:
1044 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1046 if (Node->Asl.Child->Asl.Value.Integer > 2)
1048 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1052 else /* PARSEOP_STRING */
1054 if (!OpcFindName(AslPldHorizontalPositionList,
1055 Node->Asl.Child->Asl.Value.String,
1056 &Node->Asl.Child->Asl.Value.Integer))
1058 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1063 PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1066 case PARSEOP_PLD_SHAPE:
1068 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1070 if (Node->Asl.Child->Asl.Value.Integer > 8)
1072 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1076 else /* PARSEOP_STRING */
1078 if (!OpcFindName(AslPldShapeList,
1079 Node->Asl.Child->Asl.Value.String,
1080 &Node->Asl.Child->Asl.Value.Integer))
1082 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1087 PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1090 case PARSEOP_PLD_GROUPORIENTATION:
1092 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1094 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1098 if (Node->Asl.Child->Asl.Value.Integer > 1)
1100 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1104 PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1107 case PARSEOP_PLD_GROUPTOKEN:
1108 case PARSEOP_PLD_GROUPPOSITION:
1110 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1112 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1116 if (Node->Asl.Child->Asl.Value.Integer > 255)
1118 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1123 if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN)
1125 PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1127 else /* PARSEOP_PLD_GROUPPOSITION */
1129 PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1134 case PARSEOP_PLD_BAY:
1135 case PARSEOP_PLD_EJECTABLE:
1136 case PARSEOP_PLD_EJECTREQUIRED:
1138 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1140 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1144 if (Node->Asl.Child->Asl.Value.Integer > 1)
1146 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1150 if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY)
1152 PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1154 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE)
1156 PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1158 else /* PARSEOP_PLD_EJECTREQUIRED */
1160 PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1165 case PARSEOP_PLD_CABINETNUMBER:
1166 case PARSEOP_PLD_CARDCAGENUMBER:
1168 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1170 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1174 if (Node->Asl.Child->Asl.Value.Integer > 255)
1176 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1180 if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER)
1182 PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1184 else /* PARSEOP_PLD_CARDCAGENUMBER */
1186 PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1191 case PARSEOP_PLD_REFERENCE:
1193 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1195 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1199 if (Node->Asl.Child->Asl.Value.Integer > 1)
1201 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1205 PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1208 case PARSEOP_PLD_ROTATION:
1210 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1212 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1216 if (Node->Asl.Child->Asl.Value.Integer > 7)
1218 switch (Node->Asl.Child->Asl.Value.Integer)
1222 Node->Asl.Child->Asl.Value.Integer = 1;
1227 Node->Asl.Child->Asl.Value.Integer = 2;
1232 Node->Asl.Child->Asl.Value.Integer = 3;
1237 Node->Asl.Child->Asl.Value.Integer = 4;
1242 Node->Asl.Child->Asl.Value.Integer = 5;
1247 Node->Asl.Child->Asl.Value.Integer = 6;
1252 Node->Asl.Child->Asl.Value.Integer = 7;
1257 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1262 PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1265 case PARSEOP_PLD_ORDER:
1267 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1269 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1273 if (Node->Asl.Child->Asl.Value.Integer > 31)
1275 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1279 PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1282 case PARSEOP_PLD_VERTICALOFFSET:
1283 case PARSEOP_PLD_HORIZONTALOFFSET:
1285 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1287 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1291 if (Node->Asl.Child->Asl.Value.Integer > 65535)
1293 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1297 if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET)
1299 PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1301 else /* PARSEOP_PLD_HORIZONTALOFFSET */
1303 PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1310 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1314 Node = Node->Asl.Next;
1317 Buffer = OpcEncodePldBuffer(&PldInfo);
1319 /* Change Op to a Buffer */
1321 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1322 Op->Common.AmlOpcode = AML_BUFFER_OP;
1324 /* Disable further optimization */
1326 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
1327 UtSetParseOpName (Op);
1329 /* Child node is the buffer length */
1331 NewOp = TrAllocateNode (PARSEOP_INTEGER);
1333 NewOp->Asl.AmlOpcode = AML_BYTE_OP;
1334 NewOp->Asl.Value.Integer = 20;
1335 NewOp->Asl.Parent = Op;
1337 Op->Asl.Child = NewOp;
1340 /* Peer to the child is the raw buffer data */
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;
1348 Op->Asl.Next = NewOp;
1352 /*******************************************************************************
1354 * FUNCTION: OpcDoUuId
1356 * PARAMETERS: Op - Parse node
1360 * DESCRIPTION: Convert UUID string to 16-byte buffer
1362 ******************************************************************************/
1366 ACPI_PARSE_OBJECT *Op)
1370 ACPI_STATUS Status = AE_OK;
1371 ACPI_PARSE_OBJECT *NewOp;
1374 InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
1375 Buffer = UtLocalCalloc (16);
1377 Status = AuValidateUuid (InString);
1378 if (ACPI_FAILURE (Status))
1380 AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
1384 AcpiUtConvertStringToUuid (InString, Buffer);
1387 /* Change Op to a Buffer */
1389 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1390 Op->Common.AmlOpcode = AML_BUFFER_OP;
1392 /* Disable further optimization */
1394 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
1395 UtSetParseOpName (Op);
1397 /* Child node is the buffer length */
1399 NewOp = TrAllocateNode (PARSEOP_INTEGER);
1401 NewOp->Asl.AmlOpcode = AML_BYTE_OP;
1402 NewOp->Asl.Value.Integer = 16;
1403 NewOp->Asl.Parent = Op;
1405 Op->Asl.Child = NewOp;
1408 /* Peer to the child is the raw buffer data */
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;
1416 Op->Asl.Next = NewOp;
1420 /*******************************************************************************
1422 * FUNCTION: OpcGenerateAmlOpcode
1424 * PARAMETERS: Op - Parse node
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.
1432 ******************************************************************************/
1435 OpcGenerateAmlOpcode (
1436 ACPI_PARSE_OBJECT *Op)
1441 Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
1443 Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode;
1444 Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype;
1445 Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
1447 if (!Op->Asl.Value.Integer)
1449 Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
1452 /* Special handling for some opcodes */
1454 switch (Op->Asl.ParseOpcode)
1456 case PARSEOP_INTEGER:
1458 * Set the opcode based on the size of the integer
1460 (void) OpcSetOptimalIntegerSize (Op);
1463 case PARSEOP_OFFSET:
1465 Op->Asl.AmlOpcodeLength = 1;
1468 case PARSEOP_ACCESSAS:
1473 case PARSEOP_CONNECTION:
1475 OpcDoConnection (Op);
1478 case PARSEOP_EISAID:
1483 case PARSEOP_PRINTF:
1488 case PARSEOP_FPRINTF:
1498 case PARSEOP_TOUUID:
1503 case PARSEOP_UNICODE:
1508 case PARSEOP_INCLUDE:
1510 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1511 Gbl_HasIncludeFiles = TRUE;
1514 case PARSEOP_EXTERNAL:
1516 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1517 Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1522 if (AcpiGbl_IntegerBitWidth == 32)
1524 AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
1530 /* Nothing to do for other opcodes */