Merge branch 'vendor/LESS'
[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 - 2016, 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. Note: the
108                  * Child->Node will be null if the method has not been
109                  * resolved.
110                  */
111                 if (Op->Asl.Child->Asl.Node &&
112                     (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op))
113                 {
114                     /* We must type the method here */
115
116                     TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
117                         ASL_WALK_VISIT_UPWARD, NULL,
118                         AnMethodTypingWalkEnd, NULL);
119
120                     ThisOpBtype = AnGetBtype (Op->Asl.Child);
121                 }
122             }
123
124             /* Returns a value, save the value type */
125
126             if (Op->Asl.ParentMethod)
127             {
128                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype;
129             }
130         }
131         break;
132
133     default:
134
135         break;
136     }
137
138     return (AE_OK);
139 }
140
141
142 /*******************************************************************************
143  *
144  * FUNCTION:    AnOperandTypecheckWalkEnd
145  *
146  * PARAMETERS:  ASL_WALK_CALLBACK
147  *
148  * RETURN:      Status
149  *
150  * DESCRIPTION: Ascending callback for analysis walk. Complete method
151  *              return analysis.
152  *
153  ******************************************************************************/
154
155 ACPI_STATUS
156 AnOperandTypecheckWalkEnd (
157     ACPI_PARSE_OBJECT       *Op,
158     UINT32                  Level,
159     void                    *Context)
160 {
161     const ACPI_OPCODE_INFO  *OpInfo;
162     UINT32                  RuntimeArgTypes;
163     UINT32                  RuntimeArgTypes2;
164     UINT32                  RequiredBtypes;
165     UINT32                  ThisNodeBtype;
166     UINT32                  CommonBtypes;
167     UINT32                  OpcodeClass;
168     ACPI_PARSE_OBJECT       *ArgOp;
169     UINT32                  ArgType;
170
171
172     switch (Op->Asl.AmlOpcode)
173     {
174     case AML_RAW_DATA_BYTE:
175     case AML_RAW_DATA_WORD:
176     case AML_RAW_DATA_DWORD:
177     case AML_RAW_DATA_QWORD:
178     case AML_RAW_DATA_BUFFER:
179     case AML_RAW_DATA_CHAIN:
180     case AML_PACKAGE_LENGTH:
181     case AML_UNASSIGNED_OPCODE:
182     case AML_DEFAULT_ARG_OP:
183
184         /* Ignore the internal (compiler-only) AML opcodes */
185
186         return (AE_OK);
187
188     default:
189
190         break;
191     }
192
193     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
194     if (!OpInfo)
195     {
196         return (AE_OK);
197     }
198
199     ArgOp = Op->Asl.Child;
200     OpcodeClass = OpInfo->Class;
201     RuntimeArgTypes = OpInfo->RuntimeArgs;
202
203 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
204     /*
205      * Update 11/2008: In practice, we can't perform this check. A simple
206      * analysis is not sufficient. Also, it can cause errors when compiling
207      * disassembled code because of the way Switch operators are implemented
208      * (a While(One) loop with a named temp variable created within.)
209      */
210
211     /*
212      * If we are creating a named object, check if we are within a while loop
213      * by checking if the parent is a WHILE op. This is a simple analysis, but
214      * probably sufficient for many cases.
215      *
216      * Allow Scope(), Buffer(), and Package().
217      */
218     if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
219         ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
220     {
221         if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
222         {
223             AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
224         }
225     }
226 #endif
227
228     /*
229      * Special case for control opcodes IF/RETURN/WHILE since they
230      * have no runtime arg list (at this time)
231      */
232     switch (Op->Asl.AmlOpcode)
233     {
234     case AML_IF_OP:
235     case AML_WHILE_OP:
236     case AML_RETURN_OP:
237
238         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
239         {
240             /* Check for an internal method */
241
242             if (AnIsInternalMethod (ArgOp))
243             {
244                 return (AE_OK);
245             }
246
247             /* The lone arg is a method call, check it */
248
249             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
250             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
251             {
252                 RequiredBtypes = 0xFFFFFFFF;
253             }
254
255             ThisNodeBtype = AnGetBtype (ArgOp);
256             if (ThisNodeBtype == ACPI_UINT32_MAX)
257             {
258                 return (AE_OK);
259             }
260
261             AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
262                 RequiredBtypes, ThisNodeBtype);
263         }
264         return (AE_OK);
265
266     case AML_EXTERNAL_OP:
267         /*
268          * Not really a "runtime" opcode since it used by disassembler only.
269          * The parser will find any issues with the operands.
270          */
271         return (AE_OK);
272
273     default:
274
275         break;
276     }
277
278     /* Ignore the non-executable opcodes */
279
280     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
281     {
282         return (AE_OK);
283     }
284
285     /*
286      * Special handling for certain opcodes.
287      */
288     switch (Op->Asl.AmlOpcode)
289     {
290         /* BankField has one TermArg */
291
292     case AML_BANK_FIELD_OP:
293
294         OpcodeClass = AML_CLASS_EXECUTE;
295         ArgOp = ArgOp->Asl.Next;
296         ArgOp = ArgOp->Asl.Next;
297         break;
298
299         /* Operation Region has 2 TermArgs */
300
301     case AML_REGION_OP:
302
303         OpcodeClass = AML_CLASS_EXECUTE;
304         ArgOp = ArgOp->Asl.Next;
305         ArgOp = ArgOp->Asl.Next;
306         break;
307
308         /* DataTableRegion has 3 TermArgs */
309
310     case AML_DATA_REGION_OP:
311
312         OpcodeClass = AML_CLASS_EXECUTE;
313         ArgOp = ArgOp->Asl.Next;
314         break;
315
316         /* Buffers/Packages have a length that is a TermArg */
317
318     case AML_BUFFER_OP:
319     case AML_PACKAGE_OP:
320     case AML_VAR_PACKAGE_OP:
321
322             /* If length is a constant, we are done */
323
324         if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
325             (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA))
326         {
327             return (AE_OK);
328         }
329         break;
330
331         /* Store can write any object to the Debug object */
332
333     case AML_STORE_OP:
334         /*
335          * If this is a Store() to the Debug object, we don't need
336          * to perform any further validation -- because a Store of
337          * any object to Debug is permitted and supported.
338          */
339         if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP)
340         {
341             return (AE_OK);
342         }
343         break;
344
345     default:
346         break;
347     }
348
349     switch (OpcodeClass)
350     {
351     case AML_CLASS_EXECUTE:
352     case AML_CLASS_CREATE:
353     case AML_CLASS_CONTROL:
354     case AML_CLASS_RETURN_VALUE:
355
356         /* Reverse the runtime argument list */
357
358         RuntimeArgTypes2 = 0;
359         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
360         {
361             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
362             RuntimeArgTypes2 |= ArgType;
363             INCREMENT_ARG_LIST (RuntimeArgTypes);
364         }
365
366         /* Typecheck each argument */
367
368         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
369         {
370             /* Get the required type(s) for the argument */
371
372             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
373
374             if (!ArgOp)
375             {
376                 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
377                     "Null ArgOp in argument loop");
378                 AslAbort ();
379             }
380
381             /* Get the actual type of the argument */
382
383             ThisNodeBtype = AnGetBtype (ArgOp);
384             if (ThisNodeBtype == ACPI_UINT32_MAX)
385             {
386                 goto NextArgument;
387             }
388
389             /* Examine the arg based on the required type of the arg */
390
391             switch (ArgType)
392             {
393             case ARGI_TARGETREF:
394
395                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
396                 {
397                     /* ZERO is the placeholder for "don't store result" */
398
399                     ThisNodeBtype = RequiredBtypes;
400                     break;
401                 }
402
403             /* Fallthrough */
404
405             case ARGI_STORE_TARGET:
406
407                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
408                 {
409                     /*
410                      * This is the case where an original reference to a resource
411                      * descriptor field has been replaced by an (Integer) offset.
412                      * These named fields are supported at compile-time only;
413                      * the names are not passed to the interpreter (via the AML).
414                      */
415                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
416                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
417                     {
418                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD,
419                             ArgOp, NULL);
420                     }
421                     else
422                     {
423                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
424                             ArgOp, NULL);
425                     }
426                 }
427                 break;
428
429
430 #ifdef __FUTURE_IMPLEMENTATION
431 /*
432  * Possible future typechecking support
433  */
434             case ARGI_REFERENCE:            /* References */
435             case ARGI_INTEGER_REF:
436             case ARGI_OBJECT_REF:
437             case ARGI_DEVICE_REF:
438
439                 switch (ArgOp->Asl.ParseOpcode)
440                 {
441                 case PARSEOP_LOCAL0:
442                 case PARSEOP_LOCAL1:
443                 case PARSEOP_LOCAL2:
444                 case PARSEOP_LOCAL3:
445                 case PARSEOP_LOCAL4:
446                 case PARSEOP_LOCAL5:
447                 case PARSEOP_LOCAL6:
448                 case PARSEOP_LOCAL7:
449
450                     /* TBD: implement analysis of current value (type) of the local */
451                     /* For now, just treat any local as a typematch */
452
453                     /*ThisNodeBtype = RequiredBtypes;*/
454                     break;
455
456                 case PARSEOP_ARG0:
457                 case PARSEOP_ARG1:
458                 case PARSEOP_ARG2:
459                 case PARSEOP_ARG3:
460                 case PARSEOP_ARG4:
461                 case PARSEOP_ARG5:
462                 case PARSEOP_ARG6:
463
464                     /* Hard to analyze argument types, so we won't */
465                     /* for now. Just treat any arg as a typematch */
466
467                     /* ThisNodeBtype = RequiredBtypes; */
468                     break;
469
470                 case PARSEOP_DEBUG:
471                 case PARSEOP_REFOF:
472                 case PARSEOP_INDEX:
473                 default:
474
475                     break;
476                 }
477                 break;
478 #endif
479             case ARGI_INTEGER:
480             default:
481
482                 break;
483             }
484
485
486             /* Check for a type mismatch (required versus actual) */
487
488             CommonBtypes = ThisNodeBtype & RequiredBtypes;
489
490             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
491             {
492                 if (AnIsInternalMethod (ArgOp))
493                 {
494                     return (AE_OK);
495                 }
496
497                 /* Check a method call for a valid return value */
498
499                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
500                     RequiredBtypes, ThisNodeBtype);
501             }
502
503             /*
504              * Now check if the actual type(s) match at least one
505              * bit to the required type
506              */
507             else if (!CommonBtypes)
508             {
509                 /* No match -- this is a type mismatch error */
510
511                 AnFormatBtype (StringBuffer, ThisNodeBtype);
512                 AnFormatBtype (StringBuffer2, RequiredBtypes);
513
514                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
515                     StringBuffer, OpInfo->Name, StringBuffer2);
516
517                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
518                     ArgOp, MsgBuffer);
519             }
520
521         NextArgument:
522             ArgOp = ArgOp->Asl.Next;
523             INCREMENT_ARG_LIST (RuntimeArgTypes2);
524         }
525         break;
526
527     default:
528
529         break;
530     }
531
532     return (AE_OK);
533 }
534
535
536 /*******************************************************************************
537  *
538  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
539  *
540  * PARAMETERS:  ASL_WALK_CALLBACK
541  *
542  * RETURN:      Status
543  *
544  * DESCRIPTION: Descending callback for the analysis walk. Checks for
545  *              miscellaneous issues in the code.
546  *
547  ******************************************************************************/
548
549 ACPI_STATUS
550 AnOtherSemanticAnalysisWalkBegin (
551     ACPI_PARSE_OBJECT       *Op,
552     UINT32                  Level,
553     void                    *Context)
554 {
555     ACPI_PARSE_OBJECT       *ArgOp;
556     ACPI_PARSE_OBJECT       *PrevArgOp = NULL;
557     const ACPI_OPCODE_INFO  *OpInfo;
558     ACPI_NAMESPACE_NODE     *Node;
559
560
561     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
562
563
564     /*
565      * Determine if an execution class operator actually does something by
566      * checking if it has a target and/or the function return value is used.
567      * (Target is optional, so a standalone statement can actually do nothing.)
568      */
569     if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
570         (OpInfo->Flags & AML_HAS_RETVAL) &&
571         (!AnIsResultUsed (Op)))
572     {
573         if (OpInfo->Flags & AML_HAS_TARGET)
574         {
575             /*
576              * Find the target node, it is always the last child. If the target
577              * is not specified in the ASL, a default node of type Zero was
578              * created by the parser.
579              */
580             ArgOp = Op->Asl.Child;
581             while (ArgOp->Asl.Next)
582             {
583                 PrevArgOp = ArgOp;
584                 ArgOp = ArgOp->Asl.Next;
585             }
586
587             /* Divide() is the only weird case, it has two targets */
588
589             if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
590             {
591                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) &&
592                     (PrevArgOp) &&
593                     (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO))
594                 {
595                     AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
596                         Op, Op->Asl.ExternalName);
597                 }
598             }
599
600             else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
601             {
602                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
603                     Op, Op->Asl.ExternalName);
604             }
605         }
606         else
607         {
608             /*
609              * Has no target and the result is not used. Only a couple opcodes
610              * can have this combination.
611              */
612             switch (Op->Asl.ParseOpcode)
613             {
614             case PARSEOP_ACQUIRE:
615             case PARSEOP_WAIT:
616             case PARSEOP_LOADTABLE:
617
618                 break;
619
620             default:
621
622                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
623                     Op, Op->Asl.ExternalName);
624                 break;
625             }
626         }
627     }
628
629
630     /*
631      * Semantic checks for individual ASL operators
632      */
633     switch (Op->Asl.ParseOpcode)
634     {
635     case PARSEOP_STORE:
636
637         if (Gbl_DoTypechecking)
638         {
639             AnAnalyzeStoreOperator (Op);
640         }
641         break;
642
643
644     case PARSEOP_ACQUIRE:
645     case PARSEOP_WAIT:
646         /*
647          * Emit a warning if the timeout parameter for these operators is not
648          * ACPI_WAIT_FOREVER, and the result value from the operator is not
649          * checked, meaning that a timeout could happen, but the code
650          * would not know about it.
651          */
652
653         /* First child is the namepath, 2nd child is timeout */
654
655         ArgOp = Op->Asl.Child;
656         ArgOp = ArgOp->Asl.Next;
657
658         /*
659          * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
660          * 0xFFFF or greater
661          */
662         if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
663              (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
664              (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
665         {
666             break;
667         }
668
669         /*
670          * The operation could timeout. If the return value is not used
671          * (indicates timeout occurred), issue a warning
672          */
673         if (!AnIsResultUsed (Op))
674         {
675             AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp,
676                 Op->Asl.ExternalName);
677         }
678         break;
679
680     case PARSEOP_CREATEFIELD:
681         /*
682          * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
683          */
684         ArgOp = Op->Asl.Child;
685         ArgOp = ArgOp->Asl.Next;
686         ArgOp = ArgOp->Asl.Next;
687
688         if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) ||
689            ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) &&
690             (ArgOp->Asl.Value.Integer == 0)))
691         {
692             AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgOp, NULL);
693         }
694         break;
695
696     case PARSEOP_CONNECTION:
697         /*
698          * Ensure that the referenced operation region has the correct SPACE_ID.
699          * From the grammar/parser, we know the parent is a FIELD definition.
700          */
701         ArgOp = Op->Asl.Parent;     /* Field definition */
702         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
703         Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
704         if (!Node)
705         {
706             break;
707         }
708
709         ArgOp = Node->Op;           /* OpRegion definition */
710         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
711         ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
712
713         /*
714          * The Connection() operator is only valid for the following operation
715          * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
716          */
717         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
718             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
719         {
720             AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
721         }
722         break;
723
724     case PARSEOP_FIELD:
725         /*
726          * Ensure that fields for GeneralPurposeIo and GenericSerialBus
727          * contain at least one Connection() operator
728          */
729         ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
730         Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
731         if (!Node)
732         {
733             break;
734         }
735
736         ArgOp = Node->Op;           /* OpRegion definition */
737         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
738         ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
739
740         /* We are only interested in GeneralPurposeIo and GenericSerialBus */
741
742         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
743             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
744         {
745             break;
746         }
747
748         ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
749         ArgOp = ArgOp->Asl.Next;    /* AccessType */
750         ArgOp = ArgOp->Asl.Next;    /* LockRule */
751         ArgOp = ArgOp->Asl.Next;    /* UpdateRule */
752         ArgOp = ArgOp->Asl.Next;    /* Start of FieldUnitList */
753
754         /* Walk the FieldUnitList */
755
756         while (ArgOp)
757         {
758             if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION)
759             {
760                 break;
761             }
762             else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
763             {
764                 AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL);
765                 break;
766             }
767
768             ArgOp = ArgOp->Asl.Next;
769         }
770         break;
771
772     default:
773
774         break;
775     }
776
777     return (AE_OK);
778 }
779
780
781 /*******************************************************************************
782  *
783  * FUNCTION:    AnAnalyzeStoreOperator
784  *
785  * PARAMETERS:  Op                  - Store() operator
786  *
787  * RETURN:      None
788  *
789  * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package
790  *              objects where there are more restrictions than other data
791  *              types.
792  *
793  ******************************************************************************/
794
795 static void
796 AnAnalyzeStoreOperator (
797     ACPI_PARSE_OBJECT       *Op)
798 {
799     ACPI_NAMESPACE_NODE     *SourceNode;
800     ACPI_NAMESPACE_NODE     *TargetNode;
801     ACPI_PARSE_OBJECT       *SourceOperandOp;
802     ACPI_PARSE_OBJECT       *TargetOperandOp;
803     UINT32                  SourceOperandBtype;
804     UINT32                  TargetOperandBtype;
805
806
807     /* Extract the two operands for STORE */
808
809     SourceOperandOp = Op->Asl.Child;
810     TargetOperandOp = SourceOperandOp->Asl.Next;
811
812     /*
813      * Ignore these Source operand opcodes, they cannot be typechecked,
814      * the actual result is unknown here.
815      */
816     switch (SourceOperandOp->Asl.ParseOpcode)
817     {
818     /* For these, type of the returned value is unknown at compile time */
819
820     case PARSEOP_DEREFOF:
821     case PARSEOP_METHODCALL:
822     case PARSEOP_STORE:
823     case PARSEOP_COPYOBJECT:
824
825         return;
826
827     case PARSEOP_INDEX:
828     case PARSEOP_REFOF:
829
830         if (!Gbl_EnableReferenceTypechecking)
831         {
832             return;
833         }
834
835         /*
836          * These opcodes always return an object reference, and thus
837          * the result can only be stored to a Local, Arg, or Debug.
838          */
839         if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP)
840         {
841             return;
842         }
843
844         if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) ||
845             (TargetOperandOp->Asl.AmlOpcode > AML_ARG6))
846         {
847             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
848                 "Source [Reference], Target must be [Local/Arg/Debug]");
849         }
850         return;
851
852     default:
853         break;
854     }
855
856     /*
857      * Ignore these Target operand opcodes, they cannot be typechecked
858      */
859     switch (TargetOperandOp->Asl.ParseOpcode)
860     {
861     case PARSEOP_DEBUG:
862     case PARSEOP_DEREFOF:
863     case PARSEOP_REFOF:
864     case PARSEOP_INDEX:
865
866         return;
867
868     case PARSEOP_METHODCALL:
869         /*
870          * A target is not allowed to be a method call.
871          * It is not supported by the ACPICA interpreter, nor is it
872          * supported by the MS ASL compiler or the MS interpreter.
873          * Although legal syntax up until ACPI 6.1, support for this
874          * will be removed for ACPI 6.2 (02/2016)
875          */
876         AslError (ASL_ERROR, ASL_MSG_SYNTAX,
877             TargetOperandOp, "Illegal method invocation as a target operand");
878         return;
879
880     default:
881         break;
882     }
883
884     /*
885      * Ignore typecheck for External() operands of type "UnknownObj",
886      * we don't know the actual type (source or target).
887      */
888     SourceNode = SourceOperandOp->Asl.Node;
889     if (SourceNode &&
890         (SourceNode->Flags & ANOBJ_IS_EXTERNAL) &&
891         (SourceNode->Type == ACPI_TYPE_ANY))
892     {
893         return;
894     }
895
896     TargetNode = TargetOperandOp->Asl.Node;
897     if (TargetNode &&
898         (TargetNode->Flags & ANOBJ_IS_EXTERNAL) &&
899         (TargetNode->Type == ACPI_TYPE_ANY))
900     {
901         return;
902     }
903
904     /*
905      * A NULL node with a namepath AML opcode indicates non-existent
906      * name. Just return, the error message is generated elsewhere.
907      */
908     if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) ||
909         (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)))
910     {
911         return;
912     }
913
914     /*
915      * Simple check for source same as target via NS node.
916      * -- Could be expanded to locals and args.
917      */
918     if (SourceNode && TargetNode)
919     {
920         if (SourceNode == TargetNode)
921         {
922             AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM,
923                 TargetOperandOp, "Source is the same as Target");
924             return;
925         }
926     }
927
928     /* Ignore typecheck if either source or target is a local or arg */
929
930     if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
931         (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6))
932     {
933         return; /* Cannot type a local/arg at compile time */
934     }
935
936     if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
937         (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6))
938     {
939         return; /* Cannot type a local/arg at compile time */
940     }
941
942     /*
943      * Package objects are a special case because they cannot by implicitly
944      * converted to/from anything. Check for these two illegal cases:
945      *
946      *      Store (non-package, package)
947      *      Store (package, non-package)
948      */
949     SourceOperandBtype = AnGetBtype (SourceOperandOp);
950     TargetOperandBtype = AnGetBtype (TargetOperandOp);
951
952     /* Check source first for (package, non-package) case */
953
954     if (SourceOperandBtype & ACPI_BTYPE_PACKAGE)
955     {
956         /* If Source is PACKAGE-->Target must be PACKAGE */
957
958         if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE))
959         {
960             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
961                 "Source is [Package], Target must be a package also");
962         }
963     }
964
965     /* Else check target for (non-package, package) case */
966
967     else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE)
968     {
969         /* If Target is PACKAGE, Source must be PACKAGE */
970
971         if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE))
972         {
973             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp,
974                 "Target is [Package], Source must be a package also");
975         }
976     }
977 }