1 /******************************************************************************
3 * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
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"
50 #define _COMPONENT ACPI_COMPILER
51 ACPI_MODULE_NAME ("aslwalks")
54 /* Local prototypes */
57 AnAnalyzeStoreOperator (
58 ACPI_PARSE_OBJECT *Op);
61 /*******************************************************************************
63 * FUNCTION: AnMethodTypingWalkEnd
65 * PARAMETERS: ASL_WALK_CALLBACK
69 * DESCRIPTION: Ascending callback for typing walk. Complete the method
70 * return analysis. Check methods for:
71 * 1) Initialized local variables
75 ******************************************************************************/
78 AnMethodTypingWalkEnd (
79 ACPI_PARSE_OBJECT *Op,
86 switch (Op->Asl.ParseOpcode)
90 Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
95 if ((Op->Asl.Child) &&
96 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
98 ThisOpBtype = AnGetBtype (Op->Asl.Child);
100 if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
101 (ThisOpBtype == (ACPI_UINT32_MAX -1)))
104 * The called method is untyped at this time (typically a
105 * forward reference).
107 * Check for a recursive method call first.
109 if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
111 /* We must type the method here */
113 TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
114 ASL_WALK_VISIT_UPWARD, NULL,
115 AnMethodTypingWalkEnd, NULL);
117 ThisOpBtype = AnGetBtype (Op->Asl.Child);
121 /* Returns a value, save the value type */
123 if (Op->Asl.ParentMethod)
125 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype;
139 /*******************************************************************************
141 * FUNCTION: AnOperandTypecheckWalkEnd
143 * PARAMETERS: ASL_WALK_CALLBACK
147 * DESCRIPTION: Ascending callback for analysis walk. Complete method
150 ******************************************************************************/
153 AnOperandTypecheckWalkEnd (
154 ACPI_PARSE_OBJECT *Op,
158 const ACPI_OPCODE_INFO *OpInfo;
159 UINT32 RuntimeArgTypes;
160 UINT32 RuntimeArgTypes2;
161 UINT32 RequiredBtypes;
162 UINT32 ThisNodeBtype;
165 ACPI_PARSE_OBJECT *ArgOp;
169 switch (Op->Asl.AmlOpcode)
171 case AML_RAW_DATA_BYTE:
172 case AML_RAW_DATA_WORD:
173 case AML_RAW_DATA_DWORD:
174 case AML_RAW_DATA_QWORD:
175 case AML_RAW_DATA_BUFFER:
176 case AML_RAW_DATA_CHAIN:
177 case AML_PACKAGE_LENGTH:
178 case AML_UNASSIGNED_OPCODE:
179 case AML_DEFAULT_ARG_OP:
181 /* Ignore the internal (compiler-only) AML opcodes */
190 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
196 ArgOp = Op->Asl.Child;
197 OpcodeClass = OpInfo->Class;
198 RuntimeArgTypes = OpInfo->RuntimeArgs;
200 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
202 * Update 11/2008: In practice, we can't perform this check. A simple
203 * analysis is not sufficient. Also, it can cause errors when compiling
204 * disassembled code because of the way Switch operators are implemented
205 * (a While(One) loop with a named temp variable created within.)
209 * If we are creating a named object, check if we are within a while loop
210 * by checking if the parent is a WHILE op. This is a simple analysis, but
211 * probably sufficient for many cases.
213 * Allow Scope(), Buffer(), and Package().
215 if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
216 ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
218 if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
220 AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
226 * Special case for control opcodes IF/RETURN/WHILE since they
227 * have no runtime arg list (at this time)
229 switch (Op->Asl.AmlOpcode)
235 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
237 /* Check for an internal method */
239 if (AnIsInternalMethod (ArgOp))
244 /* The lone arg is a method call, check it */
246 RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
247 if (Op->Asl.AmlOpcode == AML_RETURN_OP)
249 RequiredBtypes = 0xFFFFFFFF;
252 ThisNodeBtype = AnGetBtype (ArgOp);
253 if (ThisNodeBtype == ACPI_UINT32_MAX)
258 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
259 RequiredBtypes, ThisNodeBtype);
263 case AML_EXTERNAL_OP:
265 * Not really a "runtime" opcode since it used by disassembler only.
266 * The parser will find any issues with the operands.
275 /* Ignore the non-executable opcodes */
277 if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
283 * Special handling for certain opcodes.
285 switch (Op->Asl.AmlOpcode)
287 /* BankField has one TermArg */
289 case AML_BANK_FIELD_OP:
291 OpcodeClass = AML_CLASS_EXECUTE;
292 ArgOp = ArgOp->Asl.Next;
293 ArgOp = ArgOp->Asl.Next;
296 /* Operation Region has 2 TermArgs */
300 OpcodeClass = AML_CLASS_EXECUTE;
301 ArgOp = ArgOp->Asl.Next;
302 ArgOp = ArgOp->Asl.Next;
305 /* DataTableRegion has 3 TermArgs */
307 case AML_DATA_REGION_OP:
309 OpcodeClass = AML_CLASS_EXECUTE;
310 ArgOp = ArgOp->Asl.Next;
313 /* Buffers/Packages have a length that is a TermArg */
317 case AML_VAR_PACKAGE_OP:
319 /* If length is a constant, we are done */
321 if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
322 (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA))
328 /* Store can write any object to the Debug object */
332 * If this is a Store() to the Debug object, we don't need
333 * to perform any further validation -- because a Store of
334 * any object to Debug is permitted and supported.
336 if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP)
348 case AML_CLASS_EXECUTE:
349 case AML_CLASS_CREATE:
350 case AML_CLASS_CONTROL:
351 case AML_CLASS_RETURN_VALUE:
353 /* Reverse the runtime argument list */
355 RuntimeArgTypes2 = 0;
356 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
358 RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
359 RuntimeArgTypes2 |= ArgType;
360 INCREMENT_ARG_LIST (RuntimeArgTypes);
363 /* Typecheck each argument */
365 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
367 /* Get the required type(s) for the argument */
369 RequiredBtypes = AnMapArgTypeToBtype (ArgType);
373 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
374 "Null ArgOp in argument loop");
378 /* Get the actual type of the argument */
380 ThisNodeBtype = AnGetBtype (ArgOp);
381 if (ThisNodeBtype == ACPI_UINT32_MAX)
386 /* Examine the arg based on the required type of the arg */
392 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
394 /* ZERO is the placeholder for "don't store result" */
396 ThisNodeBtype = RequiredBtypes;
402 case ARGI_STORE_TARGET:
404 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
407 * This is the case where an original reference to a resource
408 * descriptor field has been replaced by an (Integer) offset.
409 * These named fields are supported at compile-time only;
410 * the names are not passed to the interpreter (via the AML).
412 if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
413 (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
415 AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD,
420 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
427 #ifdef __FUTURE_IMPLEMENTATION
429 * Possible future typechecking support
431 case ARGI_REFERENCE: /* References */
432 case ARGI_INTEGER_REF:
433 case ARGI_OBJECT_REF:
434 case ARGI_DEVICE_REF:
436 switch (ArgOp->Asl.ParseOpcode)
447 /* TBD: implement analysis of current value (type) of the local */
448 /* For now, just treat any local as a typematch */
450 /*ThisNodeBtype = RequiredBtypes;*/
461 /* Hard to analyze argument types, so we won't */
462 /* for now. Just treat any arg as a typematch */
464 /* ThisNodeBtype = RequiredBtypes; */
483 /* Check for a type mismatch (required versus actual) */
485 CommonBtypes = ThisNodeBtype & RequiredBtypes;
487 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
489 if (AnIsInternalMethod (ArgOp))
494 /* Check a method call for a valid return value */
496 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
497 RequiredBtypes, ThisNodeBtype);
501 * Now check if the actual type(s) match at least one
502 * bit to the required type
504 else if (!CommonBtypes)
506 /* No match -- this is a type mismatch error */
508 AnFormatBtype (StringBuffer, ThisNodeBtype);
509 AnFormatBtype (StringBuffer2, RequiredBtypes);
511 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
512 StringBuffer, OpInfo->Name, StringBuffer2);
514 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
519 ArgOp = ArgOp->Asl.Next;
520 INCREMENT_ARG_LIST (RuntimeArgTypes2);
533 /*******************************************************************************
535 * FUNCTION: AnOtherSemanticAnalysisWalkBegin
537 * PARAMETERS: ASL_WALK_CALLBACK
541 * DESCRIPTION: Descending callback for the analysis walk. Checks for
542 * miscellaneous issues in the code.
544 ******************************************************************************/
547 AnOtherSemanticAnalysisWalkBegin (
548 ACPI_PARSE_OBJECT *Op,
552 ACPI_PARSE_OBJECT *ArgOp;
553 ACPI_PARSE_OBJECT *PrevArgOp = NULL;
554 const ACPI_OPCODE_INFO *OpInfo;
555 ACPI_NAMESPACE_NODE *Node;
558 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
562 * Determine if an execution class operator actually does something by
563 * checking if it has a target and/or the function return value is used.
564 * (Target is optional, so a standalone statement can actually do nothing.)
566 if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
567 (OpInfo->Flags & AML_HAS_RETVAL) &&
568 (!AnIsResultUsed (Op)))
570 if (OpInfo->Flags & AML_HAS_TARGET)
573 * Find the target node, it is always the last child. If the target
574 * is not specified in the ASL, a default node of type Zero was
575 * created by the parser.
577 ArgOp = Op->Asl.Child;
578 while (ArgOp->Asl.Next)
581 ArgOp = ArgOp->Asl.Next;
584 /* Divide() is the only weird case, it has two targets */
586 if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
588 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) &&
590 (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO))
592 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
593 Op, Op->Asl.ExternalName);
597 else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
599 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
600 Op, Op->Asl.ExternalName);
606 * Has no target and the result is not used. Only a couple opcodes
607 * can have this combination.
609 switch (Op->Asl.ParseOpcode)
611 case PARSEOP_ACQUIRE:
613 case PARSEOP_LOADTABLE:
619 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
620 Op, Op->Asl.ExternalName);
628 * Semantic checks for individual ASL operators
630 switch (Op->Asl.ParseOpcode)
634 if (Gbl_DoTypechecking)
636 AnAnalyzeStoreOperator (Op);
641 case PARSEOP_ACQUIRE:
644 * Emit a warning if the timeout parameter for these operators is not
645 * ACPI_WAIT_FOREVER, and the result value from the operator is not
646 * checked, meaning that a timeout could happen, but the code
647 * would not know about it.
650 /* First child is the namepath, 2nd child is timeout */
652 ArgOp = Op->Asl.Child;
653 ArgOp = ArgOp->Asl.Next;
656 * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
659 if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
660 (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)) &&
661 (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
667 * The operation could timeout. If the return value is not used
668 * (indicates timeout occurred), issue a warning
670 if (!AnIsResultUsed (Op))
672 AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp,
673 Op->Asl.ExternalName);
677 case PARSEOP_CREATEFIELD:
679 * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
681 ArgOp = Op->Asl.Child;
682 ArgOp = ArgOp->Asl.Next;
683 ArgOp = ArgOp->Asl.Next;
685 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) ||
686 ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) &&
687 (ArgOp->Asl.Value.Integer == 0)))
689 AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgOp, NULL);
693 case PARSEOP_CONNECTION:
695 * Ensure that the referenced operation region has the correct SPACE_ID.
696 * From the grammar/parser, we know the parent is a FIELD definition.
698 ArgOp = Op->Asl.Parent; /* Field definition */
699 ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */
700 Node = ArgOp->Asl.Node; /* OpRegion namespace node */
706 ArgOp = Node->Op; /* OpRegion definition */
707 ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */
708 ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */
711 * The Connection() operator is only valid for the following operation
712 * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
714 if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
715 (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
717 AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
723 * Ensure that fields for GeneralPurposeIo and GenericSerialBus
724 * contain at least one Connection() operator
726 ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */
727 Node = ArgOp->Asl.Node; /* OpRegion namespace node */
733 ArgOp = Node->Op; /* OpRegion definition */
734 ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */
735 ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */
737 /* We are only interested in GeneralPurposeIo and GenericSerialBus */
739 if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
740 (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
745 ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */
746 ArgOp = ArgOp->Asl.Next; /* AccessType */
747 ArgOp = ArgOp->Asl.Next; /* LockRule */
748 ArgOp = ArgOp->Asl.Next; /* UpdateRule */
749 ArgOp = ArgOp->Asl.Next; /* Start of FieldUnitList */
751 /* Walk the FieldUnitList */
755 if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION)
759 else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
761 AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL);
765 ArgOp = ArgOp->Asl.Next;
778 /*******************************************************************************
780 * FUNCTION: AnAnalyzeStoreOperator
782 * PARAMETERS: Op - Store() operator
786 * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package
787 * objects where there are more restrictions than other data
790 ******************************************************************************/
793 AnAnalyzeStoreOperator (
794 ACPI_PARSE_OBJECT *Op)
796 ACPI_NAMESPACE_NODE *SourceNode;
797 ACPI_NAMESPACE_NODE *TargetNode;
798 ACPI_PARSE_OBJECT *SourceOperandOp;
799 ACPI_PARSE_OBJECT *TargetOperandOp;
800 UINT32 SourceOperandBtype;
801 UINT32 TargetOperandBtype;
804 /* Extract the two operands for STORE */
806 SourceOperandOp = Op->Asl.Child;
807 TargetOperandOp = SourceOperandOp->Asl.Next;
810 * Ignore these Source operand opcodes, they cannot be typechecked,
811 * the actual result is unknown here.
813 switch (SourceOperandOp->Asl.ParseOpcode)
815 /* For these, type of the returned value is unknown at compile time */
817 case PARSEOP_DEREFOF:
818 case PARSEOP_METHODCALL:
820 case PARSEOP_COPYOBJECT:
827 if (!Gbl_EnableReferenceTypechecking)
833 * These opcodes always return an object reference, and thus
834 * the result can only be stored to a Local, Arg, or Debug.
836 if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP)
841 if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) ||
842 (TargetOperandOp->Asl.AmlOpcode > AML_ARG6))
844 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
845 "Source [Reference], Target must be [Local/Arg/Debug]");
854 * Ignore these Target operand opcodes, they cannot be typechecked
856 switch (TargetOperandOp->Asl.ParseOpcode)
859 case PARSEOP_DEREFOF:
865 case PARSEOP_METHODCALL:
867 * A target is not allowed to be a method call.
868 * It is technically allowed to be a method call, but this only
869 * makes sense in one case: if the method returns a reference object,
870 * which will then allow the Store to complete successfully.
871 * However, this is not supported by the ACPICA interpreter,
872 * and not supported by the MS ASL compiler
873 * at this time. (09/2015)
875 AslError (ASL_ERROR, ASL_MSG_UNSUPPORTED,
876 TargetOperandOp, "Method invocation cannot be a target");
884 * Ignore typecheck for External() operands of type "UnknownObj",
885 * we don't know the actual type (source or target).
887 SourceNode = SourceOperandOp->Asl.Node;
889 (SourceNode->Flags & ANOBJ_IS_EXTERNAL) &&
890 (SourceNode->Type == ACPI_TYPE_ANY))
895 TargetNode = TargetOperandOp->Asl.Node;
897 (TargetNode->Flags & ANOBJ_IS_EXTERNAL) &&
898 (TargetNode->Type == ACPI_TYPE_ANY))
904 * A NULL node with a namepath AML opcode indicates non-existent
905 * name. Just return, the error message is generated elsewhere.
907 if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) ||
908 (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)))
914 * Simple check for source same as target via NS node.
915 * -- Could be expanded to locals and args.
917 if (SourceNode && TargetNode)
919 if (SourceNode == TargetNode)
921 AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM,
922 TargetOperandOp, "Source is the same as Target");
927 /* Ignore typecheck if either source or target is a local or arg */
929 if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
930 (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6))
932 return; /* Cannot type a local/arg at compile time */
935 if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
936 (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6))
938 return; /* Cannot type a local/arg at compile time */
942 * Package objects are a special case because they cannot by implicitly
943 * converted to/from anything. Check for these two illegal cases:
945 * Store (non-package, package)
946 * Store (package, non-package)
948 SourceOperandBtype = AnGetBtype (SourceOperandOp);
949 TargetOperandBtype = AnGetBtype (TargetOperandOp);
951 /* Check source first for (package, non-package) case */
953 if (SourceOperandBtype & ACPI_BTYPE_PACKAGE)
955 /* If Source is PACKAGE-->Target must be PACKAGE */
957 if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE))
959 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
960 "Source is [Package], Target must be a package also");
964 /* Else check target for (non-package, package) case */
966 else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE)
968 /* If Target is PACKAGE, Source must be PACKAGE */
970 if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE))
972 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp,
973 "Target is [Package], Source must be a package also");