gdb - Local mods (compile)
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / aslwalks.c
1 /******************************************************************************
2  *
3  * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include "aslcompiler.h"
45 #include "aslcompiler.y.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48
49
50 #define _COMPONENT          ACPI_COMPILER
51         ACPI_MODULE_NAME    ("aslwalks")
52
53
54 /* Local prototypes */
55
56 static void
57 AnAnalyzeStoreOperator (
58     ACPI_PARSE_OBJECT       *Op);
59
60
61 /*******************************************************************************
62  *
63  * FUNCTION:    AnMethodTypingWalkEnd
64  *
65  * PARAMETERS:  ASL_WALK_CALLBACK
66  *
67  * RETURN:      Status
68  *
69  * DESCRIPTION: Ascending callback for typing walk. Complete the method
70  *              return analysis. Check methods for:
71  *              1) Initialized local variables
72  *              2) Valid arguments
73  *              3) Return types
74  *
75  ******************************************************************************/
76
77 ACPI_STATUS
78 AnMethodTypingWalkEnd (
79     ACPI_PARSE_OBJECT       *Op,
80     UINT32                  Level,
81     void                    *Context)
82 {
83     UINT32                  ThisOpBtype;
84
85
86     switch (Op->Asl.ParseOpcode)
87     {
88     case PARSEOP_METHOD:
89
90         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
91         break;
92
93     case PARSEOP_RETURN:
94
95         if ((Op->Asl.Child) &&
96             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
97         {
98             ThisOpBtype = AnGetBtype (Op->Asl.Child);
99
100             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
101                 (ThisOpBtype == (ACPI_UINT32_MAX -1)))
102             {
103                 /*
104                  * The called method is untyped at this time (typically a
105                  * forward reference).
106                  *
107                  * Check for a recursive method call first.
108                  */
109                 if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
110                 {
111                     /* We must type the method here */
112
113                     TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
114                         ASL_WALK_VISIT_UPWARD, NULL,
115                         AnMethodTypingWalkEnd, NULL);
116
117                     ThisOpBtype = AnGetBtype (Op->Asl.Child);
118                 }
119             }
120
121             /* Returns a value, save the value type */
122
123             if (Op->Asl.ParentMethod)
124             {
125                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype;
126             }
127         }
128         break;
129
130     default:
131
132         break;
133     }
134
135     return (AE_OK);
136 }
137
138
139 /*******************************************************************************
140  *
141  * FUNCTION:    AnOperandTypecheckWalkEnd
142  *
143  * PARAMETERS:  ASL_WALK_CALLBACK
144  *
145  * RETURN:      Status
146  *
147  * DESCRIPTION: Ascending callback for analysis walk. Complete method
148  *              return analysis.
149  *
150  ******************************************************************************/
151
152 ACPI_STATUS
153 AnOperandTypecheckWalkEnd (
154     ACPI_PARSE_OBJECT       *Op,
155     UINT32                  Level,
156     void                    *Context)
157 {
158     const ACPI_OPCODE_INFO  *OpInfo;
159     UINT32                  RuntimeArgTypes;
160     UINT32                  RuntimeArgTypes2;
161     UINT32                  RequiredBtypes;
162     UINT32                  ThisNodeBtype;
163     UINT32                  CommonBtypes;
164     UINT32                  OpcodeClass;
165     ACPI_PARSE_OBJECT       *ArgOp;
166     UINT32                  ArgType;
167
168
169     switch (Op->Asl.AmlOpcode)
170     {
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:
180
181         /* Ignore the internal (compiler-only) AML opcodes */
182
183         return (AE_OK);
184
185     default:
186
187         break;
188     }
189
190     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
191     if (!OpInfo)
192     {
193         return (AE_OK);
194     }
195
196     ArgOp = Op->Asl.Child;
197     OpcodeClass = OpInfo->Class;
198     RuntimeArgTypes = OpInfo->RuntimeArgs;
199
200 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
201     /*
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.)
206      */
207
208     /*
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.
212      *
213      * Allow Scope(), Buffer(), and Package().
214      */
215     if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
216         ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
217     {
218         if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
219         {
220             AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
221         }
222     }
223 #endif
224
225     /*
226      * Special case for control opcodes IF/RETURN/WHILE since they
227      * have no runtime arg list (at this time)
228      */
229     switch (Op->Asl.AmlOpcode)
230     {
231     case AML_IF_OP:
232     case AML_WHILE_OP:
233     case AML_RETURN_OP:
234
235         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
236         {
237             /* Check for an internal method */
238
239             if (AnIsInternalMethod (ArgOp))
240             {
241                 return (AE_OK);
242             }
243
244             /* The lone arg is a method call, check it */
245
246             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
247             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
248             {
249                 RequiredBtypes = 0xFFFFFFFF;
250             }
251
252             ThisNodeBtype = AnGetBtype (ArgOp);
253             if (ThisNodeBtype == ACPI_UINT32_MAX)
254             {
255                 return (AE_OK);
256             }
257
258             AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
259                 RequiredBtypes, ThisNodeBtype);
260         }
261         return (AE_OK);
262
263     case AML_EXTERNAL_OP:
264         /*
265          * Not really a "runtime" opcode since it used by disassembler only.
266          * The parser will find any issues with the operands.
267          */
268         return (AE_OK);
269
270     default:
271
272         break;
273     }
274
275     /* Ignore the non-executable opcodes */
276
277     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
278     {
279         return (AE_OK);
280     }
281
282     /*
283      * Special handling for certain opcodes.
284      */
285     switch (Op->Asl.AmlOpcode)
286     {
287         /* BankField has one TermArg */
288
289     case AML_BANK_FIELD_OP:
290
291         OpcodeClass = AML_CLASS_EXECUTE;
292         ArgOp = ArgOp->Asl.Next;
293         ArgOp = ArgOp->Asl.Next;
294         break;
295
296         /* Operation Region has 2 TermArgs */
297
298     case AML_REGION_OP:
299
300         OpcodeClass = AML_CLASS_EXECUTE;
301         ArgOp = ArgOp->Asl.Next;
302         ArgOp = ArgOp->Asl.Next;
303         break;
304
305         /* DataTableRegion has 3 TermArgs */
306
307     case AML_DATA_REGION_OP:
308
309         OpcodeClass = AML_CLASS_EXECUTE;
310         ArgOp = ArgOp->Asl.Next;
311         break;
312
313         /* Buffers/Packages have a length that is a TermArg */
314
315     case AML_BUFFER_OP:
316     case AML_PACKAGE_OP:
317     case AML_VAR_PACKAGE_OP:
318
319             /* If length is a constant, we are done */
320
321         if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
322             (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA))
323         {
324             return (AE_OK);
325         }
326         break;
327
328         /* Store can write any object to the Debug object */
329
330     case AML_STORE_OP:
331         /*
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.
335          */
336         if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP)
337         {
338             return (AE_OK);
339         }
340         break;
341
342     default:
343         break;
344     }
345
346     switch (OpcodeClass)
347     {
348     case AML_CLASS_EXECUTE:
349     case AML_CLASS_CREATE:
350     case AML_CLASS_CONTROL:
351     case AML_CLASS_RETURN_VALUE:
352
353         /* Reverse the runtime argument list */
354
355         RuntimeArgTypes2 = 0;
356         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
357         {
358             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
359             RuntimeArgTypes2 |= ArgType;
360             INCREMENT_ARG_LIST (RuntimeArgTypes);
361         }
362
363         /* Typecheck each argument */
364
365         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
366         {
367             /* Get the required type(s) for the argument */
368
369             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
370
371             if (!ArgOp)
372             {
373                 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
374                     "Null ArgOp in argument loop");
375                 AslAbort ();
376             }
377
378             /* Get the actual type of the argument */
379
380             ThisNodeBtype = AnGetBtype (ArgOp);
381             if (ThisNodeBtype == ACPI_UINT32_MAX)
382             {
383                 goto NextArgument;
384             }
385
386             /* Examine the arg based on the required type of the arg */
387
388             switch (ArgType)
389             {
390             case ARGI_TARGETREF:
391
392                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
393                 {
394                     /* ZERO is the placeholder for "don't store result" */
395
396                     ThisNodeBtype = RequiredBtypes;
397                     break;
398                 }
399
400             /* Fallthrough */
401
402             case ARGI_STORE_TARGET:
403
404                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
405                 {
406                     /*
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).
411                      */
412                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
413                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
414                     {
415                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD,
416                             ArgOp, NULL);
417                     }
418                     else
419                     {
420                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
421                             ArgOp, NULL);
422                     }
423                 }
424                 break;
425
426
427 #ifdef __FUTURE_IMPLEMENTATION
428 /*
429  * Possible future typechecking support
430  */
431             case ARGI_REFERENCE:            /* References */
432             case ARGI_INTEGER_REF:
433             case ARGI_OBJECT_REF:
434             case ARGI_DEVICE_REF:
435
436                 switch (ArgOp->Asl.ParseOpcode)
437                 {
438                 case PARSEOP_LOCAL0:
439                 case PARSEOP_LOCAL1:
440                 case PARSEOP_LOCAL2:
441                 case PARSEOP_LOCAL3:
442                 case PARSEOP_LOCAL4:
443                 case PARSEOP_LOCAL5:
444                 case PARSEOP_LOCAL6:
445                 case PARSEOP_LOCAL7:
446
447                     /* TBD: implement analysis of current value (type) of the local */
448                     /* For now, just treat any local as a typematch */
449
450                     /*ThisNodeBtype = RequiredBtypes;*/
451                     break;
452
453                 case PARSEOP_ARG0:
454                 case PARSEOP_ARG1:
455                 case PARSEOP_ARG2:
456                 case PARSEOP_ARG3:
457                 case PARSEOP_ARG4:
458                 case PARSEOP_ARG5:
459                 case PARSEOP_ARG6:
460
461                     /* Hard to analyze argument types, so we won't */
462                     /* for now. Just treat any arg as a typematch */
463
464                     /* ThisNodeBtype = RequiredBtypes; */
465                     break;
466
467                 case PARSEOP_DEBUG:
468                 case PARSEOP_REFOF:
469                 case PARSEOP_INDEX:
470                 default:
471
472                     break;
473                 }
474                 break;
475 #endif
476             case ARGI_INTEGER:
477             default:
478
479                 break;
480             }
481
482
483             /* Check for a type mismatch (required versus actual) */
484
485             CommonBtypes = ThisNodeBtype & RequiredBtypes;
486
487             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
488             {
489                 if (AnIsInternalMethod (ArgOp))
490                 {
491                     return (AE_OK);
492                 }
493
494                 /* Check a method call for a valid return value */
495
496                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
497                     RequiredBtypes, ThisNodeBtype);
498             }
499
500             /*
501              * Now check if the actual type(s) match at least one
502              * bit to the required type
503              */
504             else if (!CommonBtypes)
505             {
506                 /* No match -- this is a type mismatch error */
507
508                 AnFormatBtype (StringBuffer, ThisNodeBtype);
509                 AnFormatBtype (StringBuffer2, RequiredBtypes);
510
511                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
512                     StringBuffer, OpInfo->Name, StringBuffer2);
513
514                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
515                     ArgOp, MsgBuffer);
516             }
517
518         NextArgument:
519             ArgOp = ArgOp->Asl.Next;
520             INCREMENT_ARG_LIST (RuntimeArgTypes2);
521         }
522         break;
523
524     default:
525
526         break;
527     }
528
529     return (AE_OK);
530 }
531
532
533 /*******************************************************************************
534  *
535  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
536  *
537  * PARAMETERS:  ASL_WALK_CALLBACK
538  *
539  * RETURN:      Status
540  *
541  * DESCRIPTION: Descending callback for the analysis walk. Checks for
542  *              miscellaneous issues in the code.
543  *
544  ******************************************************************************/
545
546 ACPI_STATUS
547 AnOtherSemanticAnalysisWalkBegin (
548     ACPI_PARSE_OBJECT       *Op,
549     UINT32                  Level,
550     void                    *Context)
551 {
552     ACPI_PARSE_OBJECT       *ArgOp;
553     ACPI_PARSE_OBJECT       *PrevArgOp = NULL;
554     const ACPI_OPCODE_INFO  *OpInfo;
555     ACPI_NAMESPACE_NODE     *Node;
556
557
558     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
559
560
561     /*
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.)
565      */
566     if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
567         (OpInfo->Flags & AML_HAS_RETVAL) &&
568         (!AnIsResultUsed (Op)))
569     {
570         if (OpInfo->Flags & AML_HAS_TARGET)
571         {
572             /*
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.
576              */
577             ArgOp = Op->Asl.Child;
578             while (ArgOp->Asl.Next)
579             {
580                 PrevArgOp = ArgOp;
581                 ArgOp = ArgOp->Asl.Next;
582             }
583
584             /* Divide() is the only weird case, it has two targets */
585
586             if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
587             {
588                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) &&
589                     (PrevArgOp) &&
590                     (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO))
591                 {
592                     AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
593                         Op, Op->Asl.ExternalName);
594                 }
595             }
596
597             else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
598             {
599                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
600                     Op, Op->Asl.ExternalName);
601             }
602         }
603         else
604         {
605             /*
606              * Has no target and the result is not used. Only a couple opcodes
607              * can have this combination.
608              */
609             switch (Op->Asl.ParseOpcode)
610             {
611             case PARSEOP_ACQUIRE:
612             case PARSEOP_WAIT:
613             case PARSEOP_LOADTABLE:
614
615                 break;
616
617             default:
618
619                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
620                     Op, Op->Asl.ExternalName);
621                 break;
622             }
623         }
624     }
625
626
627     /*
628      * Semantic checks for individual ASL operators
629      */
630     switch (Op->Asl.ParseOpcode)
631     {
632     case PARSEOP_STORE:
633
634         if (Gbl_DoTypechecking)
635         {
636             AnAnalyzeStoreOperator (Op);
637         }
638         break;
639
640
641     case PARSEOP_ACQUIRE:
642     case PARSEOP_WAIT:
643         /*
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.
648          */
649
650         /* First child is the namepath, 2nd child is timeout */
651
652         ArgOp = Op->Asl.Child;
653         ArgOp = ArgOp->Asl.Next;
654
655         /*
656          * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
657          * 0xFFFF or greater
658          */
659         if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
660              (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
661              (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
662         {
663             break;
664         }
665
666         /*
667          * The operation could timeout. If the return value is not used
668          * (indicates timeout occurred), issue a warning
669          */
670         if (!AnIsResultUsed (Op))
671         {
672             AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp,
673                 Op->Asl.ExternalName);
674         }
675         break;
676
677     case PARSEOP_CREATEFIELD:
678         /*
679          * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
680          */
681         ArgOp = Op->Asl.Child;
682         ArgOp = ArgOp->Asl.Next;
683         ArgOp = ArgOp->Asl.Next;
684
685         if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) ||
686            ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) &&
687             (ArgOp->Asl.Value.Integer == 0)))
688         {
689             AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgOp, NULL);
690         }
691         break;
692
693     case PARSEOP_CONNECTION:
694         /*
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.
697          */
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 */
701         if (!Node)
702         {
703             break;
704         }
705
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) */
709
710         /*
711          * The Connection() operator is only valid for the following operation
712          * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
713          */
714         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
715             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
716         {
717             AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
718         }
719         break;
720
721     case PARSEOP_FIELD:
722         /*
723          * Ensure that fields for GeneralPurposeIo and GenericSerialBus
724          * contain at least one Connection() operator
725          */
726         ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
727         Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
728         if (!Node)
729         {
730             break;
731         }
732
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) */
736
737         /* We are only interested in GeneralPurposeIo and GenericSerialBus */
738
739         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
740             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
741         {
742             break;
743         }
744
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 */
750
751         /* Walk the FieldUnitList */
752
753         while (ArgOp)
754         {
755             if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION)
756             {
757                 break;
758             }
759             else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
760             {
761                 AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL);
762                 break;
763             }
764
765             ArgOp = ArgOp->Asl.Next;
766         }
767         break;
768
769     default:
770
771         break;
772     }
773
774     return (AE_OK);
775 }
776
777
778 /*******************************************************************************
779  *
780  * FUNCTION:    AnAnalyzeStoreOperator
781  *
782  * PARAMETERS:  Op                  - Store() operator
783  *
784  * RETURN:      None
785  *
786  * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package
787  *              objects where there are more restrictions than other data
788  *              types.
789  *
790  ******************************************************************************/
791
792 static void
793 AnAnalyzeStoreOperator (
794     ACPI_PARSE_OBJECT       *Op)
795 {
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;
802
803
804     /* Extract the two operands for STORE */
805
806     SourceOperandOp = Op->Asl.Child;
807     TargetOperandOp = SourceOperandOp->Asl.Next;
808
809     /*
810      * Ignore these Source operand opcodes, they cannot be typechecked,
811      * the actual result is unknown here.
812      */
813     switch (SourceOperandOp->Asl.ParseOpcode)
814     {
815     /* For these, type of the returned value is unknown at compile time */
816
817     case PARSEOP_DEREFOF:
818     case PARSEOP_METHODCALL:
819     case PARSEOP_STORE:
820     case PARSEOP_COPYOBJECT:
821
822         return;
823
824     case PARSEOP_INDEX:
825     case PARSEOP_REFOF:
826
827         if (!Gbl_EnableReferenceTypechecking)
828         {
829             return;
830         }
831
832         /*
833          * These opcodes always return an object reference, and thus
834          * the result can only be stored to a Local, Arg, or Debug.
835          */
836         if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP)
837         {
838             return;
839         }
840
841         if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) ||
842             (TargetOperandOp->Asl.AmlOpcode > AML_ARG6))
843         {
844             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
845                 "Source [Reference], Target must be [Local/Arg/Debug]");
846         }
847         return;
848
849     default:
850         break;
851     }
852
853     /*
854      * Ignore these Target operand opcodes, they cannot be typechecked
855      */
856     switch (TargetOperandOp->Asl.ParseOpcode)
857     {
858     case PARSEOP_DEBUG:
859     case PARSEOP_DEREFOF:
860     case PARSEOP_REFOF:
861     case PARSEOP_INDEX:
862
863         return;
864
865     case PARSEOP_METHODCALL:
866         /*
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)
874          */
875         AslError (ASL_ERROR, ASL_MSG_UNSUPPORTED,
876             TargetOperandOp, "Method invocation cannot be a target");
877         return;
878
879     default:
880         break;
881     }
882
883     /*
884      * Ignore typecheck for External() operands of type "UnknownObj",
885      * we don't know the actual type (source or target).
886      */
887     SourceNode = SourceOperandOp->Asl.Node;
888     if (SourceNode &&
889         (SourceNode->Flags & ANOBJ_IS_EXTERNAL) &&
890         (SourceNode->Type == ACPI_TYPE_ANY))
891     {
892         return;
893     }
894
895     TargetNode = TargetOperandOp->Asl.Node;
896     if (TargetNode &&
897         (TargetNode->Flags & ANOBJ_IS_EXTERNAL) &&
898         (TargetNode->Type == ACPI_TYPE_ANY))
899     {
900         return;
901     }
902
903     /*
904      * A NULL node with a namepath AML opcode indicates non-existent
905      * name. Just return, the error message is generated elsewhere.
906      */
907     if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) ||
908         (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)))
909     {
910         return;
911     }
912
913     /*
914      * Simple check for source same as target via NS node.
915      * -- Could be expanded to locals and args.
916      */
917     if (SourceNode && TargetNode)
918     {
919         if (SourceNode == TargetNode)
920         {
921             AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM,
922                 TargetOperandOp, "Source is the same as Target");
923             return;
924         }
925     }
926
927     /* Ignore typecheck if either source or target is a local or arg */
928
929     if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
930         (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6))
931     {
932         return; /* Cannot type a local/arg at compile time */
933     }
934
935     if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
936         (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6))
937     {
938         return; /* Cannot type a local/arg at compile time */
939     }
940
941     /*
942      * Package objects are a special case because they cannot by implicitly
943      * converted to/from anything. Check for these two illegal cases:
944      *
945      *      Store (non-package, package)
946      *      Store (package, non-package)
947      */
948     SourceOperandBtype = AnGetBtype (SourceOperandOp);
949     TargetOperandBtype = AnGetBtype (TargetOperandOp);
950
951     /* Check source first for (package, non-package) case */
952
953     if (SourceOperandBtype & ACPI_BTYPE_PACKAGE)
954     {
955         /* If Source is PACKAGE-->Target must be PACKAGE */
956
957         if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE))
958         {
959             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
960                 "Source is [Package], Target must be a package also");
961         }
962     }
963
964     /* Else check target for (non-package, package) case */
965
966     else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE)
967     {
968         /* If Target is PACKAGE, Source must be PACKAGE */
969
970         if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE))
971         {
972             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp,
973                 "Target is [Package], Source must be a package also");
974         }
975     }
976 }