Import acpica-20050211 from Intel.
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050211 / compiler / aslanalyze.c
blob7e6344e76b92ee45f3d4142082c50b87dab804af
2 /******************************************************************************
4 * Module Name: aslanalyze.c - check for semantic errors
5 * $Revision: 87 $
7 *****************************************************************************/
9 /******************************************************************************
11 * 1. Copyright Notice
13 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
14 * All rights reserved.
16 * 2. License
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights. You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code. No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
42 * 3. Conditions
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision. In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change. Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee. Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution. In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
82 * 4. Disclaimer and Export Compliance
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government. In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
116 *****************************************************************************/
119 #include "aslcompiler.h"
120 #include "aslcompiler.y.h"
121 #include "acparser.h"
122 #include "amlcode.h"
124 #include <ctype.h>
126 #define _COMPONENT ACPI_COMPILER
127 ACPI_MODULE_NAME ("aslanalyze")
130 /*******************************************************************************
132 * FUNCTION: AnMapArgTypeToBtype
134 * PARAMETERS: ArgType - The ARGI required type(s) for this argument,
135 * from the opcode info table
137 * RETURN: The corresponding Bit-encoded types
139 * DESCRIPTION: Convert an encoded ARGI required argument type code into a
140 * bitfield type code. Implements the implicit source conversion
141 * rules.
143 ******************************************************************************/
145 UINT32
146 AnMapArgTypeToBtype (
147 UINT32 ArgType)
150 switch (ArgType)
153 /* Simple types */
155 case ARGI_ANYTYPE:
156 return (ACPI_BTYPE_OBJECTS_AND_REFS);
158 case ARGI_PACKAGE:
159 return (ACPI_BTYPE_PACKAGE);
161 case ARGI_EVENT:
162 return (ACPI_BTYPE_EVENT);
164 case ARGI_MUTEX:
165 return (ACPI_BTYPE_MUTEX);
167 case ARGI_DDBHANDLE:
168 return (ACPI_BTYPE_DDB_HANDLE);
170 /* Interchangeable types */
172 * Source conversion rules:
173 * Integer, String, and Buffer are all interchangeable
175 case ARGI_INTEGER:
176 case ARGI_STRING:
177 case ARGI_BUFFER:
178 case ARGI_BUFFER_OR_STRING:
179 case ARGI_COMPUTEDATA:
180 return (ACPI_BTYPE_COMPUTE_DATA);
182 /* References */
184 case ARGI_INTEGER_REF:
185 return (ACPI_BTYPE_INTEGER);
187 case ARGI_OBJECT_REF:
188 return (ACPI_BTYPE_ALL_OBJECTS);
190 case ARGI_DEVICE_REF:
191 return (ACPI_BTYPE_DEVICE_OBJECTS);
193 case ARGI_REFERENCE:
194 return (ACPI_BTYPE_REFERENCE);
196 case ARGI_TARGETREF:
197 case ARGI_FIXED_TARGET:
198 case ARGI_SIMPLE_TARGET:
199 return (ACPI_BTYPE_OBJECTS_AND_REFS);
201 /* Complex types */
203 case ARGI_DATAOBJECT:
205 /* Buffer, string, package or reference to a Op - Used only by SizeOf operator*/
207 return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
208 ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
210 case ARGI_COMPLEXOBJ:
212 /* Buffer, String, or package */
214 return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
216 case ARGI_REF_OR_STRING:
217 return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
219 case ARGI_REGION_OR_FIELD:
220 return (ACPI_BTYPE_REGION | ACPI_BTYPE_FIELD_UNIT);
222 case ARGI_DATAREFOBJ:
223 return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
224 ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
226 default:
227 break;
230 return (ACPI_BTYPE_OBJECTS_AND_REFS);
234 /*******************************************************************************
236 * FUNCTION: AnMapEtypeToBtype
238 * PARAMETERS: Etype - Encoded ACPI Type
240 * RETURN: Btype corresponding to the Etype
242 * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
243 * operand conversion rules. In other words, returns the type(s)
244 * this Etype is implicitly converted to during interpretation.
246 ******************************************************************************/
248 UINT32
249 AnMapEtypeToBtype (
250 UINT32 Etype)
254 if (Etype == ACPI_TYPE_ANY)
256 return ACPI_BTYPE_OBJECTS_AND_REFS;
259 /* Try the standard ACPI data types */
261 if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
264 * This switch statement implements the allowed operand conversion
265 * rules as per the "ASL Data Types" section of the ACPI
266 * specification.
268 switch (Etype)
270 case ACPI_TYPE_INTEGER:
271 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
273 case ACPI_TYPE_STRING:
274 case ACPI_TYPE_BUFFER:
275 return (ACPI_BTYPE_COMPUTE_DATA);
277 case ACPI_TYPE_PACKAGE:
278 return (ACPI_BTYPE_PACKAGE);
280 case ACPI_TYPE_FIELD_UNIT:
281 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
283 case ACPI_TYPE_BUFFER_FIELD:
284 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
286 case ACPI_TYPE_DDB_HANDLE:
287 return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
289 case ACPI_BTYPE_DEBUG_OBJECT:
291 /* Cannot be used as a source operand */
293 return (0);
295 default:
296 return (1 << (Etype - 1));
300 /* Try the internal data types */
302 switch (Etype)
304 case ACPI_TYPE_LOCAL_REGION_FIELD:
305 case ACPI_TYPE_LOCAL_BANK_FIELD:
306 case ACPI_TYPE_LOCAL_INDEX_FIELD:
308 /* Named fields can be either Integer/Buffer/String */
310 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
312 case ACPI_TYPE_LOCAL_ALIAS:
314 return (ACPI_BTYPE_INTEGER);
317 case ACPI_TYPE_LOCAL_RESOURCE:
318 case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
320 return (ACPI_BTYPE_REFERENCE);
322 default:
323 printf ("Unhandled encoded type: %X\n", Etype);
324 return (0);
329 /*******************************************************************************
331 * FUNCTION: AnMapBtypeToEtype
333 * PARAMETERS: Btype - Bitfield of ACPI types
335 * RETURN: The Etype corresponding the the Btype
337 * DESCRIPTION: Convert a bitfield type to an encoded type
339 ******************************************************************************/
341 UINT32
342 AnMapBtypeToEtype (
343 UINT32 Btype)
345 UINT32 i;
346 UINT32 Etype;
349 if (Btype == 0)
351 return 0;
354 Etype = 1;
355 for (i = 1; i < Btype; i *= 2)
357 Etype++;
360 return (Etype);
364 /*******************************************************************************
366 * FUNCTION: AnFormatBtype
368 * PARAMETERS: Btype - Bitfield of ACPI types
369 * Buffer - Where to put the ascii string
371 * RETURN: None.
373 * DESCRIPTION: Convert a Btype to a string of ACPI types
375 ******************************************************************************/
377 void
378 AnFormatBtype (
379 char *Buffer,
380 UINT32 Btype)
382 UINT32 Type;
383 BOOLEAN First = TRUE;
386 *Buffer = 0;
388 if (Btype == 0)
390 strcat (Buffer, "NoReturnValue");
391 return;
394 for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
396 if (Btype & 0x00000001)
398 if (!First)
400 strcat (Buffer, "|");
402 First = FALSE;
403 strcat (Buffer, AcpiUtGetTypeName (Type));
405 Btype >>= 1;
408 if (Btype & 0x00000001)
410 if (!First)
412 strcat (Buffer, "|");
414 First = FALSE;
415 strcat (Buffer, "Reference");
418 Btype >>= 1;
419 if (Btype & 0x00000001)
421 if (!First)
423 strcat (Buffer, "|");
425 First = FALSE;
426 strcat (Buffer, "Resource");
431 /*******************************************************************************
433 * FUNCTION: AnGetBtype
435 * PARAMETERS: Op - Parse node whose type will be returned.
437 * RETURN: The Btype associated with the Op.
439 * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
440 * Handles the case where the node is a name or method call and
441 * the actual type must be obtained from the namespace node.
443 ******************************************************************************/
445 UINT32
446 AnGetBtype (
447 ACPI_PARSE_OBJECT *Op)
449 ACPI_NAMESPACE_NODE *Node;
450 ACPI_PARSE_OBJECT *ReferencedNode;
451 UINT32 ThisNodeBtype = 0;
454 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
455 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
456 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
458 Node = Op->Asl.Node;
459 if (!Node)
461 DbgPrint (ASL_DEBUG_OUTPUT,
462 "No attached Nsnode: [%s] at line %d name [%s], ignoring typecheck\n",
463 Op->Asl.ParseOpName, Op->Asl.LineNumber,
464 Op->Asl.ExternalName);
465 return ACPI_UINT32_MAX;
468 ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
471 * Since it was a named reference, enable the
472 * reference bit also
474 ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
476 if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
478 ReferencedNode = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
479 if (!ReferencedNode)
481 printf ("No back ptr to Op: type %X\n", Node->Type);
482 return ACPI_UINT32_MAX;
485 if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
487 ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
489 else
491 return (ACPI_UINT32_MAX -1);
495 else
497 ThisNodeBtype = Op->Asl.AcpiBtype;
500 return (ThisNodeBtype);
504 /*******************************************************************************
506 * FUNCTION: AnCheckForReservedName
508 * PARAMETERS: Op - A parse node
509 * Name - NameSeg to check
511 * RETURN: None
513 * DESCRIPTION: Check a NameSeg against the reserved list.
515 ******************************************************************************/
517 #define ACPI_VALID_RESERVED_NAME_MAX 0x80000000
518 #define ACPI_NOT_RESERVED_NAME ACPI_UINT32_MAX
519 #define ACPI_PREDEFINED_NAME (ACPI_UINT32_MAX - 1)
520 #define ACPI_EVENT_RESERVED_NAME (ACPI_UINT32_MAX - 2)
521 #define ACPI_COMPILER_RESERVED_NAME (ACPI_UINT32_MAX - 3)
523 UINT32
524 AnCheckForReservedName (
525 ACPI_PARSE_OBJECT *Op,
526 char *Name)
528 UINT32 i;
531 if (Name[0] == 0)
533 AcpiOsPrintf ("Found a null name, external = %s\n", Op->Asl.ExternalName);
536 /* All reserved names are prefixed with a single underscore */
538 if (Name[0] != '_')
540 return (ACPI_NOT_RESERVED_NAME);
543 /* Check for a standard reserved method name */
545 for (i = 0; ReservedMethods[i].Name; i++)
547 if (!ACPI_STRNCMP (Name, ReservedMethods[i].Name, ACPI_NAME_SIZE))
549 if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
551 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
552 return (ACPI_PREDEFINED_NAME);
554 else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
556 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
557 return (ACPI_PREDEFINED_NAME);
560 /* Return index into reserved array */
562 return i;
567 * Now check for the "special" reserved names --
568 * GPE: _Lxx
569 * GPE: _Exx
570 * EC: _Qxx
572 if ((Name[1] == 'L') ||
573 (Name[1] == 'E') ||
574 (Name[1] == 'Q'))
576 /* The next two characters must be hex digits */
578 if ((isxdigit (Name[2])) &&
579 (isxdigit (Name[3])))
581 return (ACPI_EVENT_RESERVED_NAME);
586 /* Check for the names reserved for the compiler itself: _T_x */
588 else if ((Op->Asl.ExternalName[1] == 'T') &&
589 (Op->Asl.ExternalName[2] == '_'))
591 /* Ignore if actually emitted by the compiler */
593 if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
595 return (ACPI_NOT_RESERVED_NAME);
598 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
599 return (ACPI_COMPILER_RESERVED_NAME);
603 * The name didn't match any of the known reserved names. Flag it as a
604 * warning, since the entire namespace starting with an underscore is
605 * reserved by the ACPI spec.
607 AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op, Op->Asl.ExternalName);
609 return (ACPI_NOT_RESERVED_NAME);
613 /*******************************************************************************
615 * FUNCTION: AnCheckForReservedMethod
617 * PARAMETERS: Op - A parse node of type "METHOD".
618 * MethodInfo - Saved info about this method
620 * RETURN: None
622 * DESCRIPTION: If method is a reserved name, check that the number of arguments
623 * and the return type (returns a value or not) is correct.
625 ******************************************************************************/
627 void
628 AnCheckForReservedMethod (
629 ACPI_PARSE_OBJECT *Op,
630 ASL_METHOD_INFO *MethodInfo)
632 UINT32 Index;
635 /* Check for a match against the reserved name list */
637 Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
639 switch (Index)
641 case ACPI_NOT_RESERVED_NAME:
642 case ACPI_PREDEFINED_NAME:
643 case ACPI_COMPILER_RESERVED_NAME:
645 /* Just return, nothing to do */
646 break;
649 case ACPI_EVENT_RESERVED_NAME:
651 Gbl_ReservedMethods++;
653 /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
655 if (MethodInfo->NumArguments != 0)
657 sprintf (MsgBuffer, " %s requires %d",
658 Op->Asl.ExternalName, 0);
660 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
662 break;
665 default:
667 Gbl_ReservedMethods++;
669 /* Matched a reserved method name */
671 if (MethodInfo->NumArguments != ReservedMethods[Index].NumArguments)
673 sprintf (MsgBuffer, " %s requires %d",
674 ReservedMethods[Index].Name,
675 ReservedMethods[Index].NumArguments);
677 if (MethodInfo->NumArguments > ReservedMethods[Index].NumArguments)
679 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
681 else
683 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op, MsgBuffer);
687 if (MethodInfo->NumReturnNoValue &&
688 ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
690 sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
692 AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
694 break;
699 UINT32
700 AnMapObjTypeToBtype (
701 ACPI_PARSE_OBJECT *Op)
704 switch (Op->Asl.ParseOpcode)
706 case PARSEOP_OBJECTTYPE_BFF: /* "BuffFieldObj" */
707 return (ACPI_BTYPE_BUFFER_FIELD);
709 case PARSEOP_OBJECTTYPE_BUF: /* "BuffObj" */
710 return (ACPI_BTYPE_BUFFER);
712 case PARSEOP_OBJECTTYPE_DDB: /* "DDBHandleObj" */
713 return (ACPI_BTYPE_DDB_HANDLE);
715 case PARSEOP_OBJECTTYPE_DEV: /* "DeviceObj" */
716 return (ACPI_BTYPE_DEVICE);
718 case PARSEOP_OBJECTTYPE_EVT: /* "EventObj" */
719 return (ACPI_BTYPE_EVENT);
721 case PARSEOP_OBJECTTYPE_FLD: /* "FieldUnitObj" */
722 return (ACPI_BTYPE_FIELD_UNIT);
724 case PARSEOP_OBJECTTYPE_INT: /* "IntObj" */
725 return (ACPI_BTYPE_INTEGER);
727 case PARSEOP_OBJECTTYPE_MTH: /* "MethodObj" */
728 return (ACPI_BTYPE_METHOD);
730 case PARSEOP_OBJECTTYPE_MTX: /* "MutexObj" */
731 return (ACPI_BTYPE_MUTEX);
733 case PARSEOP_OBJECTTYPE_OPR: /* "OpRegionObj" */
734 return (ACPI_BTYPE_REGION);
736 case PARSEOP_OBJECTTYPE_PKG: /* "PkgObj" */
737 return (ACPI_BTYPE_PACKAGE);
739 case PARSEOP_OBJECTTYPE_POW: /* "PowerResObj" */
740 return (ACPI_BTYPE_POWER);
742 case PARSEOP_OBJECTTYPE_STR: /* "StrObj" */
743 return (ACPI_BTYPE_STRING);
745 case PARSEOP_OBJECTTYPE_THZ: /* "ThermalZoneObj" */
746 return (ACPI_BTYPE_THERMAL);
748 case PARSEOP_OBJECTTYPE_UNK: /* "UnknownObj" */
749 return (ACPI_BTYPE_OBJECTS_AND_REFS);
751 default:
752 return (0);
757 /*******************************************************************************
759 * FUNCTION: AnMethodAnalysisWalkBegin
761 * PARAMETERS: ASL_WALK_CALLBACK
763 * RETURN: Status
765 * DESCRIPTION: Descending callback for the analysis walk. Check methods for :
766 * 1) Initialized local variables
767 * 2) Valid arguments
768 * 3) Return types
770 ******************************************************************************/
772 ACPI_STATUS
773 AnMethodAnalysisWalkBegin (
774 ACPI_PARSE_OBJECT *Op,
775 UINT32 Level,
776 void *Context)
778 ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
779 ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
780 ACPI_PARSE_OBJECT *Next;
781 UINT32 RegisterNumber;
782 UINT32 i;
783 char LocalName[] = "Local0";
784 char ArgName[] = "Arg0";
785 ACPI_PARSE_OBJECT *ArgNode;
786 ACPI_PARSE_OBJECT *NextType;
787 ACPI_PARSE_OBJECT *NextParamType;
788 char ActualArgs = 0;
791 ACPI_FUNCTION_NAME ("AnMethodAnalysisWalkBegin");
794 switch (Op->Asl.ParseOpcode)
796 case PARSEOP_METHOD:
798 TotalMethods++;
801 * Create and init method info
803 MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
804 MethodInfo->Next = WalkInfo->MethodStack;
805 MethodInfo->Op = Op;
807 WalkInfo->MethodStack = MethodInfo;
809 /* Get the name node, ignored here */
811 Next = Op->Asl.Child;
813 /* Get the NumArguments node */
815 Next = Next->Asl.Next;
816 MethodInfo->NumArguments = (UINT8) (((UINT8) Next->Asl.Value.Integer) & 0x07);
818 /* Get the SerializeRule and SyncLevel nodes, ignored here */
820 Next = Next->Asl.Next;
821 Next = Next->Asl.Next;
822 ArgNode = Next;
824 /* Get the ReturnType node */
826 Next = Next->Asl.Next;
828 NextType = Next->Asl.Child;
829 while (NextType)
831 /* Get and map each of the ReturnTypes */
833 MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
834 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
835 NextType = NextType->Asl.Next;
838 /* Get the ParameterType node */
840 Next = Next->Asl.Next;
842 NextType = Next->Asl.Child;
843 while (NextType)
845 if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
847 NextParamType = NextType->Asl.Child;
848 while (NextParamType)
850 MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
851 NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
852 NextParamType = NextParamType->Asl.Next;
855 else
857 MethodInfo->ValidArgTypes[ActualArgs] = AnMapObjTypeToBtype (NextType);
858 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
861 ActualArgs++;
862 NextType = NextType->Asl.Next;
865 if ((MethodInfo->NumArguments) &&
866 (MethodInfo->NumArguments != ActualArgs))
868 /* error: Param list did not match number of args */
871 /* Allow numarguments == 0 for Function() */
873 if ((!MethodInfo->NumArguments) && (ActualArgs))
875 MethodInfo->NumArguments = ActualArgs;
876 ArgNode->Asl.Value.Integer |= ActualArgs;
880 * Actual arguments are initialized at method entry.
881 * All other ArgX "registers" can be used as locals, so we
882 * track their initialization.
884 for (i = 0; i < MethodInfo->NumArguments; i++)
886 MethodInfo->ArgInitialized[i] = TRUE;
888 break;
891 case PARSEOP_METHODCALL:
893 if (MethodInfo &&
894 (Op->Asl.Node == MethodInfo->Op->Asl.Node))
896 AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
898 break;
901 case PARSEOP_LOCAL0:
902 case PARSEOP_LOCAL1:
903 case PARSEOP_LOCAL2:
904 case PARSEOP_LOCAL3:
905 case PARSEOP_LOCAL4:
906 case PARSEOP_LOCAL5:
907 case PARSEOP_LOCAL6:
908 case PARSEOP_LOCAL7:
910 if (!MethodInfo)
912 /* Probably was an error in the method declaration, no additional error here */
914 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
915 return (AE_ERROR);
918 RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
921 * If the local is being used as a target, mark the local
922 * initialized
924 if (Op->Asl.CompileFlags & NODE_IS_TARGET)
926 MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
930 * Otherwise, this is a reference, check if the local
931 * has been previously initialized.
933 * The only operator that accepts an uninitialized value is ObjectType()
935 else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
936 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
938 LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
939 AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
941 break;
944 case PARSEOP_ARG0:
945 case PARSEOP_ARG1:
946 case PARSEOP_ARG2:
947 case PARSEOP_ARG3:
948 case PARSEOP_ARG4:
949 case PARSEOP_ARG5:
950 case PARSEOP_ARG6:
952 if (!MethodInfo)
954 /* Probably was an error in the method declaration, no additional error here */
956 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
957 return (AE_ERROR);
960 RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
961 ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
964 * If the Arg is being used as a target, mark the local
965 * initialized
967 if (Op->Asl.CompileFlags & NODE_IS_TARGET)
969 MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
973 * Otherwise, this is a reference, check if the Arg
974 * has been previously initialized.
976 * The only operator that accepts an uninitialized value is ObjectType()
978 else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
979 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
981 AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
984 /* Flag this arg if it is not a "real" argument to the method */
986 if (RegisterNumber >= MethodInfo->NumArguments)
988 AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
990 break;
993 case PARSEOP_RETURN:
995 if (!MethodInfo)
997 /* Probably was an error in the method declaration, no additional error here */
999 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
1000 return (AE_ERROR);
1003 /* Child indicates a return value */
1005 if ((Op->Asl.Child) &&
1006 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1008 MethodInfo->NumReturnWithValue++;
1010 else
1012 MethodInfo->NumReturnNoValue++;
1014 break;
1017 case PARSEOP_BREAK:
1018 case PARSEOP_CONTINUE:
1020 Next = Op->Asl.Parent;
1021 while (Next)
1023 if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
1025 break;
1027 Next = Next->Asl.Parent;
1030 if (!Next)
1032 AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
1034 break;
1037 case PARSEOP_STALL:
1039 if (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)
1041 AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
1043 break;
1046 case PARSEOP_DEVICE:
1047 case PARSEOP_EVENT:
1048 case PARSEOP_MUTEX:
1049 case PARSEOP_OPERATIONREGION:
1050 case PARSEOP_POWERRESOURCE:
1051 case PARSEOP_PROCESSOR:
1052 case PARSEOP_THERMALZONE:
1055 * The first operand is a name to be created in the namespace.
1056 * Check against the reserved list.
1058 i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1059 if (i < ACPI_VALID_RESERVED_NAME_MAX)
1061 AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
1063 break;
1066 case PARSEOP_NAME:
1068 i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1069 if (i < ACPI_VALID_RESERVED_NAME_MAX)
1071 if (ReservedMethods[i].NumArguments > 0)
1074 * This reserved name must be a control method because
1075 * it must have arguments
1077 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, "with arguments");
1081 * Typechecking for _HID
1083 else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
1085 /* Examine the second operand to typecheck it */
1087 Next = Op->Asl.Child->Asl.Next;
1089 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
1090 (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
1092 /* _HID must be a string or an integer */
1094 AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, "String or Integer");
1097 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
1100 * _HID is a string, all characters must be alphanumeric.
1101 * One of the things we want to catch here is the use of
1102 * a leading asterisk in the string.
1104 for (i = 0; Next->Asl.Value.String[i]; i++)
1106 if (!isalnum (Next->Asl.Value.String[i]))
1108 AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, Next, Next->Asl.Value.String);
1109 break;
1116 break;
1119 default:
1120 break;
1123 return AE_OK;
1127 /*******************************************************************************
1129 * FUNCTION: AnLastStatementIsReturn
1131 * PARAMETERS: Op - A method parse node
1133 * RETURN: TRUE if last statement is an ASL RETURN. False otherwise
1135 * DESCRIPTION: Walk down the list of top level statements within a method
1136 * to find the last one. Check if that last statement is in
1137 * fact a RETURN statement.
1139 ******************************************************************************/
1141 BOOLEAN
1142 AnLastStatementIsReturn (
1143 ACPI_PARSE_OBJECT *Op)
1145 ACPI_PARSE_OBJECT *Next;
1149 * Check if last statement is a return
1151 Next = ASL_GET_CHILD_NODE (Op);
1152 while (Next)
1154 if ((!Next->Asl.Next) &&
1155 (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1157 return TRUE;
1160 Next = ASL_GET_PEER_NODE (Next);
1163 return FALSE;
1167 /*******************************************************************************
1169 * FUNCTION: AnMethodAnalysisWalkEnd
1171 * PARAMETERS: ASL_WALK_CALLBACK
1173 * RETURN: Status
1175 * DESCRIPTION: Ascending callback for analysis walk. Complete method
1176 * return analysis.
1178 ******************************************************************************/
1180 ACPI_STATUS
1181 AnMethodAnalysisWalkEnd (
1182 ACPI_PARSE_OBJECT *Op,
1183 UINT32 Level,
1184 void *Context)
1186 ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1187 ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack;
1190 switch (Op->Asl.ParseOpcode)
1192 case PARSEOP_METHOD:
1193 case PARSEOP_RETURN:
1194 if (!MethodInfo)
1196 printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1197 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "No method info for this method");
1198 CmCleanupAndExit ();
1199 return (AE_AML_INTERNAL);
1201 break;
1203 default:
1204 break;
1207 switch (Op->Asl.ParseOpcode)
1209 case PARSEOP_METHOD:
1211 WalkInfo->MethodStack = MethodInfo->Next;
1214 * Check if there is no return statement at the end of the
1215 * method AND we can actually get there -- i.e., the execution
1216 * of the method can possibly terminate without a return statement.
1218 if ((!AnLastStatementIsReturn (Op)) &&
1219 (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1222 * No return statement, and execution can possibly exit
1223 * via this path. This is equivalent to Return ()
1225 MethodInfo->NumReturnNoValue++;
1229 * Check for case where some return statements have a return value
1230 * and some do not. Exit without a return statement is a return with
1231 * no value
1233 if (MethodInfo->NumReturnNoValue &&
1234 MethodInfo->NumReturnWithValue)
1236 AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, Op->Asl.ExternalName);
1240 * If there are any RETURN() statements with no value, or there is a
1241 * control path that allows the method to exit without a return value,
1242 * we mark the method as a method that does not return a value. This
1243 * knowledge can be used to check method invocations that expect a
1244 * returned value.
1246 if (MethodInfo->NumReturnNoValue)
1248 if (MethodInfo->NumReturnWithValue)
1250 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1252 else
1254 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1259 * Check predefined method names for correct return behavior
1260 * and correct number of arguments
1262 AnCheckForReservedMethod (Op, MethodInfo);
1263 ACPI_MEM_FREE (MethodInfo);
1264 break;
1267 case PARSEOP_RETURN:
1270 * The parent block does not "exit" and continue execution -- the
1271 * method is terminated here with the Return() statement.
1273 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1274 Op->Asl.ParentMethod = MethodInfo->Op; /* Used in the "typing" pass later */
1277 * If there is a peer node after the return statement, then this
1278 * node is unreachable code -- i.e., it won't be executed because of the
1279 * preceeding Return() statement.
1281 if (Op->Asl.Next)
1283 AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1285 break;
1288 case PARSEOP_IF:
1290 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1291 (Op->Asl.Next) &&
1292 (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1295 * This IF has a corresponding ELSE. The IF block has no exit,
1296 * (it contains an unconditional Return)
1297 * mark the ELSE block to remember this fact.
1299 Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1301 break;
1304 case PARSEOP_ELSE:
1306 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1307 (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1310 * This ELSE block has no exit and the corresponding IF block
1311 * has no exit either. Therefore, the parent node has no exit.
1313 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1315 break;
1318 default:
1320 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1321 (Op->Asl.Parent))
1323 /* If this node has no exit, then the parent has no exit either */
1325 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1327 break;
1330 return AE_OK;
1334 /*******************************************************************************
1336 * FUNCTION: AnMethodTypingWalkBegin
1338 * PARAMETERS: ASL_WALK_CALLBACK
1340 * RETURN: Status
1342 * DESCRIPTION: Descending callback for the typing walk.
1344 ******************************************************************************/
1346 ACPI_STATUS
1347 AnMethodTypingWalkBegin (
1348 ACPI_PARSE_OBJECT *Op,
1349 UINT32 Level,
1350 void *Context)
1353 return AE_OK;
1357 /*******************************************************************************
1359 * FUNCTION: AnMethodTypingWalkEnd
1361 * PARAMETERS: ASL_WALK_CALLBACK
1363 * RETURN: Status
1365 * DESCRIPTION: Ascending callback for typing walk. Complete method
1366 * return analysis. Check methods for :
1367 * 1) Initialized local variables
1368 * 2) Valid arguments
1369 * 3) Return types
1371 ******************************************************************************/
1373 ACPI_STATUS
1374 AnMethodTypingWalkEnd (
1375 ACPI_PARSE_OBJECT *Op,
1376 UINT32 Level,
1377 void *Context)
1379 UINT32 ThisNodeBtype;
1382 switch (Op->Asl.ParseOpcode)
1384 case PARSEOP_METHOD:
1386 Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
1387 break;
1389 case PARSEOP_RETURN:
1391 if ((Op->Asl.Child) &&
1392 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1394 ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1396 if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
1397 (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1400 * The method is untyped at this time (typically a forward reference).
1401 * We must recursively type the method here
1403 TrWalkParseTree (ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Op->Asl.Child->Asl.Node->Object),
1404 ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1405 AnMethodTypingWalkEnd, NULL);
1407 ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1410 /* Returns a value, get it's type */
1412 if (Op->Asl.ParentMethod)
1414 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1417 break;
1419 default:
1420 break;
1423 return AE_OK;
1427 /*******************************************************************************
1429 * FUNCTION: AnCheckMethodReturnValue
1431 * PARAMETERS: Op - Parent
1432 * OpInfo - Parent info
1433 * ArgOp - Method invocation op
1434 * RequiredBtypes - What caller requires
1435 * ThisNodeBtype - What this node returns (if anything)
1437 * RETURN: None
1439 * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1440 * in fact return a value, 2) check the type of the return value.
1442 ******************************************************************************/
1444 void
1445 AnCheckMethodReturnValue (
1446 ACPI_PARSE_OBJECT *Op,
1447 const ACPI_OPCODE_INFO *OpInfo,
1448 ACPI_PARSE_OBJECT *ArgOp,
1449 UINT32 RequiredBtypes,
1450 UINT32 ThisNodeBtype)
1452 ACPI_PARSE_OBJECT *OwningOp;
1453 ACPI_NAMESPACE_NODE *Node;
1456 Node = ArgOp->Asl.Node;
1459 /* Examine the parent op of this method */
1461 OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
1462 if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1465 * Method NEVER returns a value
1467 AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
1469 else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1472 * Method SOMETIMES returns a value, SOMETIMES not
1474 AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
1476 else if (!(ThisNodeBtype & RequiredBtypes))
1479 * Method returns a value, but the type is wrong
1481 AnFormatBtype (StringBuffer, ThisNodeBtype);
1482 AnFormatBtype (StringBuffer2, RequiredBtypes);
1486 * The case where the method does not return any value at all
1487 * was already handled in the namespace cross reference
1488 * -- Only issue an error if the method in fact returns a value,
1489 * but it is of the wrong type
1491 if (ThisNodeBtype != 0)
1493 sprintf (MsgBuffer, "Method returns [%s], %s operator requires [%s]",
1494 StringBuffer, OpInfo->Name, StringBuffer2);
1496 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1502 /*******************************************************************************
1504 * FUNCTION: AnOperandTypecheckWalkBegin
1506 * PARAMETERS: ASL_WALK_CALLBACK
1508 * RETURN: Status
1510 * DESCRIPTION: Descending callback for the analysis walk. Check methods for :
1511 * 1) Initialized local variables
1512 * 2) Valid arguments
1513 * 3) Return types
1515 ******************************************************************************/
1517 ACPI_STATUS
1518 AnOperandTypecheckWalkBegin (
1519 ACPI_PARSE_OBJECT *Op,
1520 UINT32 Level,
1521 void *Context)
1524 return AE_OK;
1528 /*******************************************************************************
1530 * FUNCTION: AnOperandTypecheckWalkEnd
1532 * PARAMETERS: ASL_WALK_CALLBACK
1534 * RETURN: Status
1536 * DESCRIPTION: Ascending callback for analysis walk. Complete method
1537 * return analysis.
1539 ******************************************************************************/
1541 ACPI_STATUS
1542 AnOperandTypecheckWalkEnd (
1543 ACPI_PARSE_OBJECT *Op,
1544 UINT32 Level,
1545 void *Context)
1547 const ACPI_OPCODE_INFO *OpInfo;
1548 UINT32 RuntimeArgTypes;
1549 UINT32 RuntimeArgTypes2;
1550 UINT32 RequiredBtypes;
1551 UINT32 ThisNodeBtype;
1552 UINT32 CommonBtypes;
1553 UINT32 OpcodeClass;
1554 ACPI_PARSE_OBJECT *ArgOp;
1555 UINT32 ArgType;
1558 switch (Op->Asl.AmlOpcode)
1560 case AML_RAW_DATA_BYTE:
1561 case AML_RAW_DATA_WORD:
1562 case AML_RAW_DATA_DWORD:
1563 case AML_RAW_DATA_QWORD:
1564 case AML_RAW_DATA_BUFFER:
1565 case AML_RAW_DATA_CHAIN:
1566 case AML_PACKAGE_LENGTH:
1567 case AML_UNASSIGNED_OPCODE:
1568 case AML_DEFAULT_ARG_OP:
1570 /* Ignore the internal (compiler-only) AML opcodes */
1572 return (AE_OK);
1574 default:
1575 break;
1578 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1579 if (!OpInfo)
1581 return (AE_OK);
1584 ArgOp = Op->Asl.Child;
1585 RuntimeArgTypes = OpInfo->RuntimeArgs;
1586 OpcodeClass = OpInfo->Class;
1590 * Special case for control opcodes IF/RETURN/WHILE since they
1591 * have no runtime arg list (at this time)
1593 switch (Op->Asl.AmlOpcode)
1595 case AML_IF_OP:
1596 case AML_WHILE_OP:
1597 case AML_RETURN_OP:
1599 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1601 /* The lone arg is a method call, check it */
1603 RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
1604 if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1606 RequiredBtypes = 0xFFFFFFFF;
1609 ThisNodeBtype = AnGetBtype (ArgOp);
1610 if (ThisNodeBtype == ACPI_UINT32_MAX)
1612 return (AE_OK);
1614 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1616 return (AE_OK);
1618 default:
1619 break;
1622 /* Ignore the non-executable opcodes */
1624 if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
1626 return (AE_OK);
1629 switch (OpcodeClass)
1631 case AML_CLASS_EXECUTE:
1632 case AML_CLASS_CREATE:
1633 case AML_CLASS_CONTROL:
1634 case AML_CLASS_RETURN_VALUE:
1636 /* TBD: Change class or fix typechecking for these */
1638 if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) ||
1639 (Op->Asl.AmlOpcode == AML_PACKAGE_OP) ||
1640 (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1642 break;
1645 /* Reverse the runtime argument list */
1647 RuntimeArgTypes2 = 0;
1648 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1650 RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1651 RuntimeArgTypes2 |= ArgType;
1652 INCREMENT_ARG_LIST (RuntimeArgTypes);
1655 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
1657 RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1659 ThisNodeBtype = AnGetBtype (ArgOp);
1660 if (ThisNodeBtype == ACPI_UINT32_MAX)
1662 goto NextArgument;
1665 /* Examine the arg based on the required type of the arg */
1667 switch (ArgType)
1669 case ARGI_TARGETREF:
1671 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
1673 /* ZERO is the placeholder for "don't store result" */
1675 ThisNodeBtype = RequiredBtypes;
1676 break;
1679 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
1682 * This is the case where an original reference to a resource
1683 * descriptor field has been replaced by an (Integer) offset.
1684 * These named fields are supported at compile-time only;
1685 * the names are not passed to the interpreter (via the AML).
1687 if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1688 (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1690 AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1692 else
1694 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1696 break;
1699 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1700 (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1702 break;
1705 ThisNodeBtype = RequiredBtypes;
1706 break;
1709 case ARGI_REFERENCE: /* References */
1710 case ARGI_INTEGER_REF:
1711 case ARGI_OBJECT_REF:
1712 case ARGI_DEVICE_REF:
1714 switch (ArgOp->Asl.ParseOpcode)
1716 case PARSEOP_LOCAL0:
1717 case PARSEOP_LOCAL1:
1718 case PARSEOP_LOCAL2:
1719 case PARSEOP_LOCAL3:
1720 case PARSEOP_LOCAL4:
1721 case PARSEOP_LOCAL5:
1722 case PARSEOP_LOCAL6:
1723 case PARSEOP_LOCAL7:
1725 /* TBD: implement analysis of current value (type) of the local */
1726 /* For now, just treat any local as a typematch */
1728 /*ThisNodeBtype = RequiredBtypes;*/
1729 break;
1731 case PARSEOP_ARG0:
1732 case PARSEOP_ARG1:
1733 case PARSEOP_ARG2:
1734 case PARSEOP_ARG3:
1735 case PARSEOP_ARG4:
1736 case PARSEOP_ARG5:
1737 case PARSEOP_ARG6:
1739 /* Hard to analyze argument types, sow we won't */
1740 /* For now, just treat any arg as a typematch */
1742 /* ThisNodeBtype = RequiredBtypes; */
1743 break;
1745 case PARSEOP_DEBUG:
1746 break;
1748 case PARSEOP_REFOF:
1749 case PARSEOP_INDEX:
1750 default:
1751 break;
1754 break;
1756 case ARGI_INTEGER:
1757 default:
1758 break;
1762 CommonBtypes = ThisNodeBtype & RequiredBtypes;
1764 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1766 /* Check a method call for a valid return value */
1768 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1772 * Now check if the actual type(s) match at least one
1773 * bit to the required type
1775 else if (!CommonBtypes)
1777 /* No match -- this is a type mismatch error */
1779 AnFormatBtype (StringBuffer, ThisNodeBtype);
1780 AnFormatBtype (StringBuffer2, RequiredBtypes);
1782 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
1783 StringBuffer, OpInfo->Name, StringBuffer2);
1785 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1788 NextArgument:
1789 ArgOp = ArgOp->Asl.Next;
1790 INCREMENT_ARG_LIST (RuntimeArgTypes2);
1792 break;
1794 default:
1795 break;
1798 return (AE_OK);
1802 /*******************************************************************************
1804 * FUNCTION: AnOtherSemanticAnalysisWalkBegin
1806 * PARAMETERS: ASL_WALK_CALLBACK
1808 * RETURN: Status
1810 * DESCRIPTION: Descending callback for the analysis walk. Check methods for :
1811 * 1) Initialized local variables
1812 * 2) Valid arguments
1813 * 3) Return types
1815 ******************************************************************************/
1817 ACPI_STATUS
1818 AnOtherSemanticAnalysisWalkBegin (
1819 ACPI_PARSE_OBJECT *Op,
1820 UINT32 Level,
1821 void *Context)
1824 return AE_OK;
1828 /*******************************************************************************
1830 * FUNCTION: AnOtherSemanticAnalysisWalkEnd
1832 * PARAMETERS: ASL_WALK_CALLBACK
1834 * RETURN: Status
1836 * DESCRIPTION: Ascending callback for analysis walk. Complete method
1837 * return analysis.
1839 ******************************************************************************/
1841 ACPI_STATUS
1842 AnOtherSemanticAnalysisWalkEnd (
1843 ACPI_PARSE_OBJECT *Op,
1844 UINT32 Level,
1845 void *Context)
1848 return AE_OK;