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 <contrib/dev/acpica/compiler/aslcompiler.h>
45 #include "aslcompiler.y.h"
46 #include <contrib/dev/acpica/include/amlcode.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 (ACPI_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: OpcStrupr (strupr)
796 * PARAMETERS: SrcString - The source string to convert
800 * DESCRIPTION: Convert string to uppercase
802 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
804 ******************************************************************************/
818 /* Walk entire string, uppercasing the letters */
820 for (String = SrcString; *String; String++)
822 *String = (char) toupper ((int) *String);
829 /*******************************************************************************
831 * FUNCTION: OpcFindName
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
837 * RETURN: TRUE if any names matched, FALSE otherwise
839 * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to
840 * equivalent parameter value.
842 ******************************************************************************/
856 for (i = 0, Str = List[0]; Str; i++, Str = List[i])
858 if (!(ACPI_STRNCMP (Str, Name, ACPI_STRLEN (Name))))
869 /*******************************************************************************
873 * PARAMETERS: Op - Parse node
877 * DESCRIPTION: Convert ToPLD macro to 20-byte buffer
879 ******************************************************************************/
883 ACPI_PARSE_OBJECT *Op)
886 ACPI_PARSE_OBJECT *Node;
887 ACPI_PLD_INFO PldInfo;
888 ACPI_PARSE_OBJECT *NewOp;
893 AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL);
897 if (Op->Asl.ParseOpcode != PARSEOP_TOPLD)
899 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL);
903 Buffer = UtLocalCalloc (ACPI_PLD_BUFFER_SIZE);
906 AslError(ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, Op, NULL);
910 ACPI_MEMSET (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
912 Node = Op->Asl.Child;
915 switch (Node->Asl.ParseOpcode)
917 case PARSEOP_PLD_REVISION:
919 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
921 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
925 if (Node->Asl.Child->Asl.Value.Integer > 127)
927 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
931 PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer;
934 case PARSEOP_PLD_IGNORECOLOR:
936 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
938 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
942 if (Node->Asl.Child->Asl.Value.Integer > 1)
944 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
948 PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer;
951 case PARSEOP_PLD_RED:
952 case PARSEOP_PLD_GREEN:
953 case PARSEOP_PLD_BLUE:
955 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
957 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
961 if (Node->Asl.Child->Asl.Value.Integer > 255)
963 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
967 if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED)
969 PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer;
971 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN)
973 PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer;
975 else /* PARSEOP_PLD_BLUE */
977 PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer;
981 case PARSEOP_PLD_WIDTH:
982 case PARSEOP_PLD_HEIGHT:
984 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
986 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
990 if (Node->Asl.Child->Asl.Value.Integer > 65535)
992 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
996 if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH)
998 PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1000 else /* PARSEOP_PLD_HEIGHT */
1002 PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1007 case PARSEOP_PLD_USERVISIBLE:
1008 case PARSEOP_PLD_DOCK:
1009 case PARSEOP_PLD_LID:
1011 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1013 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1017 if (Node->Asl.Child->Asl.Value.Integer > 1)
1019 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1023 if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE)
1025 PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1027 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK)
1029 PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1033 PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1038 case PARSEOP_PLD_PANEL:
1040 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1042 if (Node->Asl.Child->Asl.Value.Integer > 6)
1044 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1048 else /* PARSEOP_STRING */
1050 if (!OpcFindName(AslPldPanelList,
1051 Node->Asl.Child->Asl.Value.String,
1052 &Node->Asl.Child->Asl.Value.Integer))
1054 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1059 PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1062 case PARSEOP_PLD_VERTICALPOSITION:
1064 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1066 if (Node->Asl.Child->Asl.Value.Integer > 2)
1068 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1072 else /* PARSEOP_STRING */
1074 if (!OpcFindName(AslPldVerticalPositionList,
1075 Node->Asl.Child->Asl.Value.String,
1076 &Node->Asl.Child->Asl.Value.Integer))
1078 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1083 PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1086 case PARSEOP_PLD_HORIZONTALPOSITION:
1088 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1090 if (Node->Asl.Child->Asl.Value.Integer > 2)
1092 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1096 else /* PARSEOP_STRING */
1098 if (!OpcFindName(AslPldHorizontalPositionList,
1099 Node->Asl.Child->Asl.Value.String,
1100 &Node->Asl.Child->Asl.Value.Integer))
1102 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1107 PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1110 case PARSEOP_PLD_SHAPE:
1112 if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1114 if (Node->Asl.Child->Asl.Value.Integer > 8)
1116 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1120 else /* PARSEOP_STRING */
1122 if (!OpcFindName(AslPldShapeList,
1123 Node->Asl.Child->Asl.Value.String,
1124 &Node->Asl.Child->Asl.Value.Integer))
1126 AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1131 PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1134 case PARSEOP_PLD_GROUPORIENTATION:
1136 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1138 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1142 if (Node->Asl.Child->Asl.Value.Integer > 1)
1144 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1148 PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1151 case PARSEOP_PLD_GROUPTOKEN:
1152 case PARSEOP_PLD_GROUPPOSITION:
1154 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1156 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1160 if (Node->Asl.Child->Asl.Value.Integer > 255)
1162 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1167 if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN)
1169 PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1171 else /* PARSEOP_PLD_GROUPPOSITION */
1173 PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1178 case PARSEOP_PLD_BAY:
1179 case PARSEOP_PLD_EJECTABLE:
1180 case PARSEOP_PLD_EJECTREQUIRED:
1182 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1184 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1188 if (Node->Asl.Child->Asl.Value.Integer > 1)
1190 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1194 if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY)
1196 PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1198 else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE)
1200 PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1202 else /* PARSEOP_PLD_EJECTREQUIRED */
1204 PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1209 case PARSEOP_PLD_CABINETNUMBER:
1210 case PARSEOP_PLD_CARDCAGENUMBER:
1212 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1214 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1218 if (Node->Asl.Child->Asl.Value.Integer > 255)
1220 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1224 if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER)
1226 PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1228 else /* PARSEOP_PLD_CARDCAGENUMBER */
1230 PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1235 case PARSEOP_PLD_REFERENCE:
1237 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1239 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1243 if (Node->Asl.Child->Asl.Value.Integer > 1)
1245 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1249 PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1252 case PARSEOP_PLD_ROTATION:
1254 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1256 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1260 if (Node->Asl.Child->Asl.Value.Integer > 7)
1262 switch (Node->Asl.Child->Asl.Value.Integer)
1266 Node->Asl.Child->Asl.Value.Integer = 1;
1271 Node->Asl.Child->Asl.Value.Integer = 2;
1276 Node->Asl.Child->Asl.Value.Integer = 3;
1281 Node->Asl.Child->Asl.Value.Integer = 4;
1286 Node->Asl.Child->Asl.Value.Integer = 5;
1291 Node->Asl.Child->Asl.Value.Integer = 6;
1296 Node->Asl.Child->Asl.Value.Integer = 7;
1301 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1306 PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1309 case PARSEOP_PLD_ORDER:
1311 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1313 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1317 if (Node->Asl.Child->Asl.Value.Integer > 31)
1319 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1323 PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1326 case PARSEOP_PLD_VERTICALOFFSET:
1327 case PARSEOP_PLD_HORIZONTALOFFSET:
1329 if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1331 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1335 if (Node->Asl.Child->Asl.Value.Integer > 65535)
1337 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1341 if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET)
1343 PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1345 else /* PARSEOP_PLD_HORIZONTALOFFSET */
1347 PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1354 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1358 Node = Node->Asl.Next;
1361 Buffer = OpcEncodePldBuffer(&PldInfo);
1363 /* Change Op to a Buffer */
1365 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1366 Op->Common.AmlOpcode = AML_BUFFER_OP;
1368 /* Disable further optimization */
1370 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
1371 UtSetParseOpName (Op);
1373 /* Child node is the buffer length */
1375 NewOp = TrAllocateNode (PARSEOP_INTEGER);
1377 NewOp->Asl.AmlOpcode = AML_BYTE_OP;
1378 NewOp->Asl.Value.Integer = 20;
1379 NewOp->Asl.Parent = Op;
1381 Op->Asl.Child = NewOp;
1384 /* Peer to the child is the raw buffer data */
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;
1392 Op->Asl.Next = NewOp;
1396 /*******************************************************************************
1398 * FUNCTION: OpcDoUuId
1400 * PARAMETERS: Op - Parse node
1404 * DESCRIPTION: Convert UUID string to 16-byte buffer
1406 ******************************************************************************/
1410 ACPI_PARSE_OBJECT *Op)
1414 ACPI_STATUS Status = AE_OK;
1415 ACPI_PARSE_OBJECT *NewOp;
1418 InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
1419 Buffer = UtLocalCalloc (16);
1421 Status = AuValidateUuid (InString);
1422 if (ACPI_FAILURE (Status))
1424 AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
1428 AcpiUtConvertStringToUuid (InString, Buffer);
1431 /* Change Op to a Buffer */
1433 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1434 Op->Common.AmlOpcode = AML_BUFFER_OP;
1436 /* Disable further optimization */
1438 Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
1439 UtSetParseOpName (Op);
1441 /* Child node is the buffer length */
1443 NewOp = TrAllocateNode (PARSEOP_INTEGER);
1445 NewOp->Asl.AmlOpcode = AML_BYTE_OP;
1446 NewOp->Asl.Value.Integer = 16;
1447 NewOp->Asl.Parent = Op;
1449 Op->Asl.Child = NewOp;
1452 /* Peer to the child is the raw buffer data */
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;
1460 Op->Asl.Next = NewOp;
1464 /*******************************************************************************
1466 * FUNCTION: OpcGenerateAmlOpcode
1468 * PARAMETERS: Op - Parse node
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.
1476 ******************************************************************************/
1479 OpcGenerateAmlOpcode (
1480 ACPI_PARSE_OBJECT *Op)
1485 Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
1487 Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode;
1488 Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype;
1489 Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
1491 if (!Op->Asl.Value.Integer)
1493 Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
1496 /* Special handling for some opcodes */
1498 switch (Op->Asl.ParseOpcode)
1500 case PARSEOP_INTEGER:
1502 * Set the opcode based on the size of the integer
1504 (void) OpcSetOptimalIntegerSize (Op);
1507 case PARSEOP_OFFSET:
1509 Op->Asl.AmlOpcodeLength = 1;
1512 case PARSEOP_ACCESSAS:
1517 case PARSEOP_CONNECTION:
1519 OpcDoConnection (Op);
1522 case PARSEOP_EISAID:
1527 case PARSEOP_PRINTF:
1532 case PARSEOP_FPRINTF:
1542 case PARSEOP_TOUUID:
1547 case PARSEOP_UNICODE:
1552 case PARSEOP_INCLUDE:
1554 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1555 Gbl_HasIncludeFiles = TRUE;
1558 case PARSEOP_EXTERNAL:
1560 Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1561 Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1566 if (AcpiGbl_IntegerBitWidth == 32)
1568 AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
1574 /* Nothing to do for other opcodes */