]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - namespace/nspredef.c
Import ACPICA 20120111.
[FreeBSD/FreeBSD.git] / namespace / nspredef.c
1 /******************************************************************************
2  *
3  * Module Name: nspredef - Validation of ACPI predefined methods and objects
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2012, 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 #define ACPI_CREATE_PREDEFINED_TABLE
45
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acnamesp.h"
49 #include "acpredef.h"
50
51
52 #define _COMPONENT          ACPI_NAMESPACE
53         ACPI_MODULE_NAME    ("nspredef")
54
55
56 /*******************************************************************************
57  *
58  * This module validates predefined ACPI objects that appear in the namespace,
59  * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
60  * validation is to detect problems with BIOS-exposed predefined ACPI objects
61  * before the results are returned to the ACPI-related drivers.
62  *
63  * There are several areas that are validated:
64  *
65  *  1) The number of input arguments as defined by the method/object in the
66  *      ASL is validated against the ACPI specification.
67  *  2) The type of the return object (if any) is validated against the ACPI
68  *      specification.
69  *  3) For returned package objects, the count of package elements is
70  *      validated, as well as the type of each package element. Nested
71  *      packages are supported.
72  *
73  * For any problems found, a warning message is issued.
74  *
75  ******************************************************************************/
76
77
78 /* Local prototypes */
79
80 static ACPI_STATUS
81 AcpiNsCheckPackage (
82     ACPI_PREDEFINED_DATA        *Data,
83     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
84
85 static ACPI_STATUS
86 AcpiNsCheckPackageList (
87     ACPI_PREDEFINED_DATA        *Data,
88     const ACPI_PREDEFINED_INFO  *Package,
89     ACPI_OPERAND_OBJECT         **Elements,
90     UINT32                      Count);
91
92 static ACPI_STATUS
93 AcpiNsCheckPackageElements (
94     ACPI_PREDEFINED_DATA        *Data,
95     ACPI_OPERAND_OBJECT         **Elements,
96     UINT8                       Type1,
97     UINT32                      Count1,
98     UINT8                       Type2,
99     UINT32                      Count2,
100     UINT32                      StartIndex);
101
102 static ACPI_STATUS
103 AcpiNsCheckObjectType (
104     ACPI_PREDEFINED_DATA        *Data,
105     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
106     UINT32                      ExpectedBtypes,
107     UINT32                      PackageIndex);
108
109 static ACPI_STATUS
110 AcpiNsCheckReference (
111     ACPI_PREDEFINED_DATA        *Data,
112     ACPI_OPERAND_OBJECT         *ReturnObject);
113
114 static void
115 AcpiNsGetExpectedTypes (
116     char                        *Buffer,
117     UINT32                      ExpectedBtypes);
118
119 /*
120  * Names for the types that can be returned by the predefined objects.
121  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
122  */
123 static const char   *AcpiRtypeNames[] =
124 {
125     "/Integer",
126     "/String",
127     "/Buffer",
128     "/Package",
129     "/Reference",
130 };
131
132
133 /*******************************************************************************
134  *
135  * FUNCTION:    AcpiNsCheckPredefinedNames
136  *
137  * PARAMETERS:  Node            - Namespace node for the method/object
138  *              UserParamCount  - Number of parameters actually passed
139  *              ReturnStatus    - Status from the object evaluation
140  *              ReturnObjectPtr - Pointer to the object returned from the
141  *                                evaluation of a method or object
142  *
143  * RETURN:      Status
144  *
145  * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
146  *
147  ******************************************************************************/
148
149 ACPI_STATUS
150 AcpiNsCheckPredefinedNames (
151     ACPI_NAMESPACE_NODE         *Node,
152     UINT32                      UserParamCount,
153     ACPI_STATUS                 ReturnStatus,
154     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
155 {
156     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
157     ACPI_STATUS                 Status = AE_OK;
158     const ACPI_PREDEFINED_INFO  *Predefined;
159     char                        *Pathname;
160     ACPI_PREDEFINED_DATA        *Data;
161
162
163     /* Match the name for this method/object against the predefined list */
164
165     Predefined = AcpiNsCheckForPredefinedName (Node);
166
167     /* Get the full pathname to the object, for use in warning messages */
168
169     Pathname = AcpiNsGetExternalPathname (Node);
170     if (!Pathname)
171     {
172         return (AE_OK); /* Could not get pathname, ignore */
173     }
174
175     /*
176      * Check that the parameter count for this method matches the ASL
177      * definition. For predefined names, ensure that both the caller and
178      * the method itself are in accordance with the ACPI specification.
179      */
180     AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
181
182     /* If not a predefined name, we cannot validate the return object */
183
184     if (!Predefined)
185     {
186         goto Cleanup;
187     }
188
189     /*
190      * If the method failed or did not actually return an object, we cannot
191      * validate the return object
192      */
193     if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
194     {
195         goto Cleanup;
196     }
197
198     /*
199      * If there is no return value, check if we require a return value for
200      * this predefined name. Either one return value is expected, or none,
201      * for both methods and other objects.
202      *
203      * Exit now if there is no return object. Warning if one was expected.
204      */
205     if (!ReturnObject)
206     {
207         if ((Predefined->Info.ExpectedBtypes) &&
208             (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
209         {
210             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
211                 "Missing expected return value"));
212
213             Status = AE_AML_NO_RETURN_VALUE;
214         }
215         goto Cleanup;
216     }
217
218     /*
219      * Return value validation and possible repair.
220      *
221      * 1) Don't perform return value validation/repair if this feature
222      * has been disabled via a global option.
223      *
224      * 2) We have a return value, but if one wasn't expected, just exit,
225      * this is not a problem. For example, if the "Implicit Return"
226      * feature is enabled, methods will always return a value.
227      *
228      * 3) If the return value can be of any type, then we cannot perform
229      * any validation, just exit.
230      */
231     if (AcpiGbl_DisableAutoRepair ||
232         (!Predefined->Info.ExpectedBtypes) ||
233         (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL))
234     {
235         goto Cleanup;
236     }
237
238     /* Create the parameter data block for object validation */
239
240     Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA));
241     if (!Data)
242     {
243         goto Cleanup;
244     }
245     Data->Predefined = Predefined;
246     Data->Node = Node;
247     Data->NodeFlags = Node->Flags;
248     Data->Pathname = Pathname;
249
250     /*
251      * Check that the type of the main return object is what is expected
252      * for this predefined name
253      */
254     Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
255                 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
256     if (ACPI_FAILURE (Status))
257     {
258         goto Exit;
259     }
260
261     /*
262      * For returned Package objects, check the type of all sub-objects.
263      * Note: Package may have been newly created by call above.
264      */
265     if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
266     {
267         Data->ParentPackage = *ReturnObjectPtr;
268         Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
269         if (ACPI_FAILURE (Status))
270         {
271             goto Exit;
272         }
273     }
274
275     /*
276      * The return object was OK, or it was successfully repaired above.
277      * Now make some additional checks such as verifying that package
278      * objects are sorted correctly (if required) or buffer objects have
279      * the correct data width (bytes vs. dwords). These repairs are
280      * performed on a per-name basis, i.e., the code is specific to
281      * particular predefined names.
282      */
283     Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr);
284
285 Exit:
286     /*
287      * If the object validation failed or if we successfully repaired one
288      * or more objects, mark the parent node to suppress further warning
289      * messages during the next evaluation of the same method/object.
290      */
291     if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED))
292     {
293         Node->Flags |= ANOBJ_EVALUATED;
294     }
295     ACPI_FREE (Data);
296
297 Cleanup:
298     ACPI_FREE (Pathname);
299     return (Status);
300 }
301
302
303 /*******************************************************************************
304  *
305  * FUNCTION:    AcpiNsCheckParameterCount
306  *
307  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
308  *              Node            - Namespace node for the method/object
309  *              UserParamCount  - Number of args passed in by the caller
310  *              Predefined      - Pointer to entry in predefined name table
311  *
312  * RETURN:      None
313  *
314  * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
315  *              predefined name is what is expected (i.e., what is defined in
316  *              the ACPI specification for this predefined name.)
317  *
318  ******************************************************************************/
319
320 void
321 AcpiNsCheckParameterCount (
322     char                        *Pathname,
323     ACPI_NAMESPACE_NODE         *Node,
324     UINT32                      UserParamCount,
325     const ACPI_PREDEFINED_INFO  *Predefined)
326 {
327     UINT32                      ParamCount;
328     UINT32                      RequiredParamsCurrent;
329     UINT32                      RequiredParamsOld;
330
331
332     /* Methods have 0-7 parameters. All other types have zero. */
333
334     ParamCount = 0;
335     if (Node->Type == ACPI_TYPE_METHOD)
336     {
337         ParamCount = Node->Object->Method.ParamCount;
338     }
339
340     if (!Predefined)
341     {
342         /*
343          * Check the parameter count for non-predefined methods/objects.
344          *
345          * Warning if too few or too many arguments have been passed by the
346          * caller. An incorrect number of arguments may not cause the method
347          * to fail. However, the method will fail if there are too few
348          * arguments and the method attempts to use one of the missing ones.
349          */
350         if (UserParamCount < ParamCount)
351         {
352             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
353                 "Insufficient arguments - needs %u, found %u",
354                 ParamCount, UserParamCount));
355         }
356         else if (UserParamCount > ParamCount)
357         {
358             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
359                 "Excess arguments - needs %u, found %u",
360                 ParamCount, UserParamCount));
361         }
362         return;
363     }
364
365     /*
366      * Validate the user-supplied parameter count.
367      * Allow two different legal argument counts (_SCP, etc.)
368      */
369     RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
370     RequiredParamsOld = Predefined->Info.ParamCount >> 4;
371
372     if (UserParamCount != ACPI_UINT32_MAX)
373     {
374         if ((UserParamCount != RequiredParamsCurrent) &&
375             (UserParamCount != RequiredParamsOld))
376         {
377             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
378                 "Parameter count mismatch - "
379                 "caller passed %u, ACPI requires %u",
380                 UserParamCount, RequiredParamsCurrent));
381         }
382     }
383
384     /*
385      * Check that the ASL-defined parameter count is what is expected for
386      * this predefined name (parameter count as defined by the ACPI
387      * specification)
388      */
389     if ((ParamCount != RequiredParamsCurrent) &&
390         (ParamCount != RequiredParamsOld))
391     {
392         ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags,
393             "Parameter count mismatch - ASL declared %u, ACPI requires %u",
394             ParamCount, RequiredParamsCurrent));
395     }
396 }
397
398
399 /*******************************************************************************
400  *
401  * FUNCTION:    AcpiNsCheckForPredefinedName
402  *
403  * PARAMETERS:  Node            - Namespace node for the method/object
404  *
405  * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
406  *
407  * DESCRIPTION: Check an object name against the predefined object list.
408  *
409  ******************************************************************************/
410
411 const ACPI_PREDEFINED_INFO *
412 AcpiNsCheckForPredefinedName (
413     ACPI_NAMESPACE_NODE         *Node)
414 {
415     const ACPI_PREDEFINED_INFO  *ThisName;
416
417
418     /* Quick check for a predefined name, first character must be underscore */
419
420     if (Node->Name.Ascii[0] != '_')
421     {
422         return (NULL);
423     }
424
425     /* Search info table for a predefined method/object name */
426
427     ThisName = PredefinedNames;
428     while (ThisName->Info.Name[0])
429     {
430         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
431         {
432             return (ThisName);
433         }
434
435         /*
436          * Skip next entry in the table if this name returns a Package
437          * (next entry contains the package info)
438          */
439         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
440         {
441             ThisName++;
442         }
443
444         ThisName++;
445     }
446
447     return (NULL); /* Not found */
448 }
449
450
451 /*******************************************************************************
452  *
453  * FUNCTION:    AcpiNsCheckPackage
454  *
455  * PARAMETERS:  Data            - Pointer to validation data structure
456  *              ReturnObjectPtr - Pointer to the object returned from the
457  *                                evaluation of a method or object
458  *
459  * RETURN:      Status
460  *
461  * DESCRIPTION: Check a returned package object for the correct count and
462  *              correct type of all sub-objects.
463  *
464  ******************************************************************************/
465
466 static ACPI_STATUS
467 AcpiNsCheckPackage (
468     ACPI_PREDEFINED_DATA        *Data,
469     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
470 {
471     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
472     const ACPI_PREDEFINED_INFO  *Package;
473     ACPI_OPERAND_OBJECT         **Elements;
474     ACPI_STATUS                 Status = AE_OK;
475     UINT32                      ExpectedCount;
476     UINT32                      Count;
477     UINT32                      i;
478
479
480     ACPI_FUNCTION_NAME (NsCheckPackage);
481
482
483     /* The package info for this name is in the next table entry */
484
485     Package = Data->Predefined + 1;
486
487     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
488         "%s Validating return Package of Type %X, Count %X\n",
489         Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
490
491     /*
492      * For variable-length Packages, we can safely remove all embedded
493      * and trailing NULL package elements
494      */
495     AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject);
496
497     /* Extract package count and elements array */
498
499     Elements = ReturnObject->Package.Elements;
500     Count = ReturnObject->Package.Count;
501
502     /* The package must have at least one element, else invalid */
503
504     if (!Count)
505     {
506         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
507             "Return Package has no elements (empty)"));
508
509         return (AE_AML_OPERAND_VALUE);
510     }
511
512     /*
513      * Decode the type of the expected package contents
514      *
515      * PTYPE1 packages contain no subpackages
516      * PTYPE2 packages contain sub-packages
517      */
518     switch (Package->RetInfo.Type)
519     {
520     case ACPI_PTYPE1_FIXED:
521
522         /*
523          * The package count is fixed and there are no sub-packages
524          *
525          * If package is too small, exit.
526          * If package is larger than expected, issue warning but continue
527          */
528         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
529         if (Count < ExpectedCount)
530         {
531             goto PackageTooSmall;
532         }
533         else if (Count > ExpectedCount)
534         {
535             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
536                 "%s: Return Package is larger than needed - "
537                 "found %u, expected %u\n",
538                 Data->Pathname, Count, ExpectedCount));
539         }
540
541         /* Validate all elements of the returned package */
542
543         Status = AcpiNsCheckPackageElements (Data, Elements,
544                     Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
545                     Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
546         break;
547
548
549     case ACPI_PTYPE1_VAR:
550
551         /*
552          * The package count is variable, there are no sub-packages, and all
553          * elements must be of the same type
554          */
555         for (i = 0; i < Count; i++)
556         {
557             Status = AcpiNsCheckObjectType (Data, Elements,
558                         Package->RetInfo.ObjectType1, i);
559             if (ACPI_FAILURE (Status))
560             {
561                 return (Status);
562             }
563             Elements++;
564         }
565         break;
566
567
568     case ACPI_PTYPE1_OPTION:
569
570         /*
571          * The package count is variable, there are no sub-packages. There are
572          * a fixed number of required elements, and a variable number of
573          * optional elements.
574          *
575          * Check if package is at least as large as the minimum required
576          */
577         ExpectedCount = Package->RetInfo3.Count;
578         if (Count < ExpectedCount)
579         {
580             goto PackageTooSmall;
581         }
582
583         /* Variable number of sub-objects */
584
585         for (i = 0; i < Count; i++)
586         {
587             if (i < Package->RetInfo3.Count)
588             {
589                 /* These are the required package elements (0, 1, or 2) */
590
591                 Status = AcpiNsCheckObjectType (Data, Elements,
592                             Package->RetInfo3.ObjectType[i], i);
593                 if (ACPI_FAILURE (Status))
594                 {
595                     return (Status);
596                 }
597             }
598             else
599             {
600                 /* These are the optional package elements */
601
602                 Status = AcpiNsCheckObjectType (Data, Elements,
603                             Package->RetInfo3.TailObjectType, i);
604                 if (ACPI_FAILURE (Status))
605                 {
606                     return (Status);
607                 }
608             }
609             Elements++;
610         }
611         break;
612
613
614     case ACPI_PTYPE2_REV_FIXED:
615
616         /* First element is the (Integer) revision */
617
618         Status = AcpiNsCheckObjectType (Data, Elements,
619                     ACPI_RTYPE_INTEGER, 0);
620         if (ACPI_FAILURE (Status))
621         {
622             return (Status);
623         }
624
625         Elements++;
626         Count--;
627
628         /* Examine the sub-packages */
629
630         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
631         break;
632
633
634     case ACPI_PTYPE2_PKG_COUNT:
635
636         /* First element is the (Integer) count of sub-packages to follow */
637
638         Status = AcpiNsCheckObjectType (Data, Elements,
639                     ACPI_RTYPE_INTEGER, 0);
640         if (ACPI_FAILURE (Status))
641         {
642             return (Status);
643         }
644
645         /*
646          * Count cannot be larger than the parent package length, but allow it
647          * to be smaller. The >= accounts for the Integer above.
648          */
649         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
650         if (ExpectedCount >= Count)
651         {
652             goto PackageTooSmall;
653         }
654
655         Count = ExpectedCount;
656         Elements++;
657
658         /* Examine the sub-packages */
659
660         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
661         break;
662
663
664     case ACPI_PTYPE2:
665     case ACPI_PTYPE2_FIXED:
666     case ACPI_PTYPE2_MIN:
667     case ACPI_PTYPE2_COUNT:
668     case ACPI_PTYPE2_FIX_VAR:
669
670         /*
671          * These types all return a single Package that consists of a
672          * variable number of sub-Packages.
673          *
674          * First, ensure that the first element is a sub-Package. If not,
675          * the BIOS may have incorrectly returned the object as a single
676          * package instead of a Package of Packages (a common error if
677          * there is only one entry). We may be able to repair this by
678          * wrapping the returned Package with a new outer Package.
679          */
680         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
681         {
682             /* Create the new outer package and populate it */
683
684             Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr);
685             if (ACPI_FAILURE (Status))
686             {
687                 return (Status);
688             }
689
690             /* Update locals to point to the new package (of 1 element) */
691
692             ReturnObject = *ReturnObjectPtr;
693             Elements = ReturnObject->Package.Elements;
694             Count = 1;
695         }
696
697         /* Examine the sub-packages */
698
699         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
700         break;
701
702
703     default:
704
705         /* Should not get here if predefined info table is correct */
706
707         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
708             "Invalid internal return type in table entry: %X",
709             Package->RetInfo.Type));
710
711         return (AE_AML_INTERNAL);
712     }
713
714     return (Status);
715
716
717 PackageTooSmall:
718
719     /* Error exit for the case with an incorrect package count */
720
721     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
722         "Return Package is too small - found %u elements, expected %u",
723         Count, ExpectedCount));
724
725     return (AE_AML_OPERAND_VALUE);
726 }
727
728
729 /*******************************************************************************
730  *
731  * FUNCTION:    AcpiNsCheckPackageList
732  *
733  * PARAMETERS:  Data            - Pointer to validation data structure
734  *              Package         - Pointer to package-specific info for method
735  *              Elements        - Element list of parent package. All elements
736  *                                of this list should be of type Package.
737  *              Count           - Count of subpackages
738  *
739  * RETURN:      Status
740  *
741  * DESCRIPTION: Examine a list of subpackages
742  *
743  ******************************************************************************/
744
745 static ACPI_STATUS
746 AcpiNsCheckPackageList (
747     ACPI_PREDEFINED_DATA        *Data,
748     const ACPI_PREDEFINED_INFO  *Package,
749     ACPI_OPERAND_OBJECT         **Elements,
750     UINT32                      Count)
751 {
752     ACPI_OPERAND_OBJECT         *SubPackage;
753     ACPI_OPERAND_OBJECT         **SubElements;
754     ACPI_STATUS                 Status;
755     UINT32                      ExpectedCount;
756     UINT32                      i;
757     UINT32                      j;
758
759
760     /*
761      * Validate each sub-Package in the parent Package
762      *
763      * NOTE: assumes list of sub-packages contains no NULL elements.
764      * Any NULL elements should have been removed by earlier call
765      * to AcpiNsRemoveNullElements.
766      */
767     for (i = 0; i < Count; i++)
768     {
769         SubPackage = *Elements;
770         SubElements = SubPackage->Package.Elements;
771         Data->ParentPackage = SubPackage;
772
773         /* Each sub-object must be of type Package */
774
775         Status = AcpiNsCheckObjectType (Data, &SubPackage,
776                     ACPI_RTYPE_PACKAGE, i);
777         if (ACPI_FAILURE (Status))
778         {
779             return (Status);
780         }
781
782         /* Examine the different types of expected sub-packages */
783
784         Data->ParentPackage = SubPackage;
785         switch (Package->RetInfo.Type)
786         {
787         case ACPI_PTYPE2:
788         case ACPI_PTYPE2_PKG_COUNT:
789         case ACPI_PTYPE2_REV_FIXED:
790
791             /* Each subpackage has a fixed number of elements */
792
793             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
794             if (SubPackage->Package.Count < ExpectedCount)
795             {
796                 goto PackageTooSmall;
797             }
798
799             Status = AcpiNsCheckPackageElements (Data, SubElements,
800                         Package->RetInfo.ObjectType1,
801                         Package->RetInfo.Count1,
802                         Package->RetInfo.ObjectType2,
803                         Package->RetInfo.Count2, 0);
804             if (ACPI_FAILURE (Status))
805             {
806                 return (Status);
807             }
808             break;
809
810
811         case ACPI_PTYPE2_FIX_VAR:
812             /*
813              * Each subpackage has a fixed number of elements and an
814              * optional element
815              */
816             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
817             if (SubPackage->Package.Count < ExpectedCount)
818             {
819                 goto PackageTooSmall;
820             }
821
822             Status = AcpiNsCheckPackageElements (Data, SubElements,
823                         Package->RetInfo.ObjectType1,
824                         Package->RetInfo.Count1,
825                         Package->RetInfo.ObjectType2,
826                         SubPackage->Package.Count - Package->RetInfo.Count1, 0);
827             if (ACPI_FAILURE (Status))
828             {
829                 return (Status);
830             }
831             break;
832
833
834         case ACPI_PTYPE2_FIXED:
835
836             /* Each sub-package has a fixed length */
837
838             ExpectedCount = Package->RetInfo2.Count;
839             if (SubPackage->Package.Count < ExpectedCount)
840             {
841                 goto PackageTooSmall;
842             }
843
844             /* Check the type of each sub-package element */
845
846             for (j = 0; j < ExpectedCount; j++)
847             {
848                 Status = AcpiNsCheckObjectType (Data, &SubElements[j],
849                             Package->RetInfo2.ObjectType[j], j);
850                 if (ACPI_FAILURE (Status))
851                 {
852                     return (Status);
853                 }
854             }
855             break;
856
857
858         case ACPI_PTYPE2_MIN:
859
860             /* Each sub-package has a variable but minimum length */
861
862             ExpectedCount = Package->RetInfo.Count1;
863             if (SubPackage->Package.Count < ExpectedCount)
864             {
865                 goto PackageTooSmall;
866             }
867
868             /* Check the type of each sub-package element */
869
870             Status = AcpiNsCheckPackageElements (Data, SubElements,
871                         Package->RetInfo.ObjectType1,
872                         SubPackage->Package.Count, 0, 0, 0);
873             if (ACPI_FAILURE (Status))
874             {
875                 return (Status);
876             }
877             break;
878
879
880         case ACPI_PTYPE2_COUNT:
881
882             /*
883              * First element is the (Integer) count of elements, including
884              * the count field (the ACPI name is NumElements)
885              */
886             Status = AcpiNsCheckObjectType (Data, SubElements,
887                         ACPI_RTYPE_INTEGER, 0);
888             if (ACPI_FAILURE (Status))
889             {
890                 return (Status);
891             }
892
893             /*
894              * Make sure package is large enough for the Count and is
895              * is as large as the minimum size
896              */
897             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
898             if (SubPackage->Package.Count < ExpectedCount)
899             {
900                 goto PackageTooSmall;
901             }
902             if (SubPackage->Package.Count < Package->RetInfo.Count1)
903             {
904                 ExpectedCount = Package->RetInfo.Count1;
905                 goto PackageTooSmall;
906             }
907             if (ExpectedCount == 0)
908             {
909                 /*
910                  * Either the NumEntries element was originally zero or it was
911                  * a NULL element and repaired to an Integer of value zero.
912                  * In either case, repair it by setting NumEntries to be the
913                  * actual size of the subpackage.
914                  */
915                 ExpectedCount = SubPackage->Package.Count;
916                 (*SubElements)->Integer.Value = ExpectedCount;
917             }
918
919             /* Check the type of each sub-package element */
920
921             Status = AcpiNsCheckPackageElements (Data, (SubElements + 1),
922                         Package->RetInfo.ObjectType1,
923                         (ExpectedCount - 1), 0, 0, 1);
924             if (ACPI_FAILURE (Status))
925             {
926                 return (Status);
927             }
928             break;
929
930
931         default: /* Should not get here, type was validated by caller */
932
933             return (AE_AML_INTERNAL);
934         }
935
936         Elements++;
937     }
938
939     return (AE_OK);
940
941
942 PackageTooSmall:
943
944     /* The sub-package count was smaller than required */
945
946     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
947         "Return Sub-Package[%u] is too small - found %u elements, expected %u",
948         i, SubPackage->Package.Count, ExpectedCount));
949
950     return (AE_AML_OPERAND_VALUE);
951 }
952
953
954 /*******************************************************************************
955  *
956  * FUNCTION:    AcpiNsCheckPackageElements
957  *
958  * PARAMETERS:  Data            - Pointer to validation data structure
959  *              Elements        - Pointer to the package elements array
960  *              Type1           - Object type for first group
961  *              Count1          - Count for first group
962  *              Type2           - Object type for second group
963  *              Count2          - Count for second group
964  *              StartIndex      - Start of the first group of elements
965  *
966  * RETURN:      Status
967  *
968  * DESCRIPTION: Check that all elements of a package are of the correct object
969  *              type. Supports up to two groups of different object types.
970  *
971  ******************************************************************************/
972
973 static ACPI_STATUS
974 AcpiNsCheckPackageElements (
975     ACPI_PREDEFINED_DATA        *Data,
976     ACPI_OPERAND_OBJECT         **Elements,
977     UINT8                       Type1,
978     UINT32                      Count1,
979     UINT8                       Type2,
980     UINT32                      Count2,
981     UINT32                      StartIndex)
982 {
983     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
984     ACPI_STATUS                 Status;
985     UINT32                      i;
986
987
988     /*
989      * Up to two groups of package elements are supported by the data
990      * structure. All elements in each group must be of the same type.
991      * The second group can have a count of zero.
992      */
993     for (i = 0; i < Count1; i++)
994     {
995         Status = AcpiNsCheckObjectType (Data, ThisElement,
996                     Type1, i + StartIndex);
997         if (ACPI_FAILURE (Status))
998         {
999             return (Status);
1000         }
1001         ThisElement++;
1002     }
1003
1004     for (i = 0; i < Count2; i++)
1005     {
1006         Status = AcpiNsCheckObjectType (Data, ThisElement,
1007                     Type2, (i + Count1 + StartIndex));
1008         if (ACPI_FAILURE (Status))
1009         {
1010             return (Status);
1011         }
1012         ThisElement++;
1013     }
1014
1015     return (AE_OK);
1016 }
1017
1018
1019 /*******************************************************************************
1020  *
1021  * FUNCTION:    AcpiNsCheckObjectType
1022  *
1023  * PARAMETERS:  Data            - Pointer to validation data structure
1024  *              ReturnObjectPtr - Pointer to the object returned from the
1025  *                                evaluation of a method or object
1026  *              ExpectedBtypes  - Bitmap of expected return type(s)
1027  *              PackageIndex    - Index of object within parent package (if
1028  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
1029  *                                otherwise)
1030  *
1031  * RETURN:      Status
1032  *
1033  * DESCRIPTION: Check the type of the return object against the expected object
1034  *              type(s). Use of Btype allows multiple expected object types.
1035  *
1036  ******************************************************************************/
1037
1038 static ACPI_STATUS
1039 AcpiNsCheckObjectType (
1040     ACPI_PREDEFINED_DATA        *Data,
1041     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
1042     UINT32                      ExpectedBtypes,
1043     UINT32                      PackageIndex)
1044 {
1045     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1046     ACPI_STATUS                 Status = AE_OK;
1047     UINT32                      ReturnBtype;
1048     char                        TypeBuffer[48]; /* Room for 5 types */
1049
1050
1051     /*
1052      * If we get a NULL ReturnObject here, it is a NULL package element.
1053      * Since all extraneous NULL package elements were removed earlier by a
1054      * call to AcpiNsRemoveNullElements, this is an unexpected NULL element.
1055      * We will attempt to repair it.
1056      */
1057     if (!ReturnObject)
1058     {
1059         Status = AcpiNsRepairNullElement (Data, ExpectedBtypes,
1060                     PackageIndex, ReturnObjectPtr);
1061         if (ACPI_SUCCESS (Status))
1062         {
1063             return (AE_OK); /* Repair was successful */
1064         }
1065         goto TypeErrorExit;
1066     }
1067
1068     /* A Namespace node should not get here, but make sure */
1069
1070     if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
1071     {
1072         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1073             "Invalid return type - Found a Namespace node [%4.4s] type %s",
1074             ReturnObject->Node.Name.Ascii,
1075             AcpiUtGetTypeName (ReturnObject->Node.Type)));
1076         return (AE_AML_OPERAND_TYPE);
1077     }
1078
1079     /*
1080      * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
1081      * The bitmapped type allows multiple possible return types.
1082      *
1083      * Note, the cases below must handle all of the possible types returned
1084      * from all of the predefined names (including elements of returned
1085      * packages)
1086      */
1087     switch (ReturnObject->Common.Type)
1088     {
1089     case ACPI_TYPE_INTEGER:
1090         ReturnBtype = ACPI_RTYPE_INTEGER;
1091         break;
1092
1093     case ACPI_TYPE_BUFFER:
1094         ReturnBtype = ACPI_RTYPE_BUFFER;
1095         break;
1096
1097     case ACPI_TYPE_STRING:
1098         ReturnBtype = ACPI_RTYPE_STRING;
1099         break;
1100
1101     case ACPI_TYPE_PACKAGE:
1102         ReturnBtype = ACPI_RTYPE_PACKAGE;
1103         break;
1104
1105     case ACPI_TYPE_LOCAL_REFERENCE:
1106         ReturnBtype = ACPI_RTYPE_REFERENCE;
1107         break;
1108
1109     default:
1110         /* Not one of the supported objects, must be incorrect */
1111
1112         goto TypeErrorExit;
1113     }
1114
1115     /* Is the object one of the expected types? */
1116
1117     if (ReturnBtype & ExpectedBtypes)
1118     {
1119         /* For reference objects, check that the reference type is correct */
1120
1121         if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1122         {
1123             Status = AcpiNsCheckReference (Data, ReturnObject);
1124         }
1125
1126         return (Status);
1127     }
1128
1129     /* Type mismatch -- attempt repair of the returned object */
1130
1131     Status = AcpiNsRepairObject (Data, ExpectedBtypes,
1132                 PackageIndex, ReturnObjectPtr);
1133     if (ACPI_SUCCESS (Status))
1134     {
1135         return (AE_OK); /* Repair was successful */
1136     }
1137
1138
1139 TypeErrorExit:
1140
1141     /* Create a string with all expected types for this predefined object */
1142
1143     AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);
1144
1145     if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
1146     {
1147         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1148             "Return type mismatch - found %s, expected %s",
1149             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1150     }
1151     else
1152     {
1153         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1154             "Return Package type mismatch at index %u - "
1155             "found %s, expected %s", PackageIndex,
1156             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1157     }
1158
1159     return (AE_AML_OPERAND_TYPE);
1160 }
1161
1162
1163 /*******************************************************************************
1164  *
1165  * FUNCTION:    AcpiNsCheckReference
1166  *
1167  * PARAMETERS:  Data            - Pointer to validation data structure
1168  *              ReturnObject    - Object returned from the evaluation of a
1169  *                                method or object
1170  *
1171  * RETURN:      Status
1172  *
1173  * DESCRIPTION: Check a returned reference object for the correct reference
1174  *              type. The only reference type that can be returned from a
1175  *              predefined method is a named reference. All others are invalid.
1176  *
1177  ******************************************************************************/
1178
1179 static ACPI_STATUS
1180 AcpiNsCheckReference (
1181     ACPI_PREDEFINED_DATA        *Data,
1182     ACPI_OPERAND_OBJECT         *ReturnObject)
1183 {
1184
1185     /*
1186      * Check the reference object for the correct reference type (opcode).
1187      * The only type of reference that can be converted to an ACPI_OBJECT is
1188      * a reference to a named object (reference class: NAME)
1189      */
1190     if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1191     {
1192         return (AE_OK);
1193     }
1194
1195     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
1196         "Return type mismatch - unexpected reference object type [%s] %2.2X",
1197         AcpiUtGetReferenceName (ReturnObject),
1198         ReturnObject->Reference.Class));
1199
1200     return (AE_AML_OPERAND_TYPE);
1201 }
1202
1203
1204 /*******************************************************************************
1205  *
1206  * FUNCTION:    AcpiNsGetExpectedTypes
1207  *
1208  * PARAMETERS:  Buffer          - Pointer to where the string is returned
1209  *              ExpectedBtypes  - Bitmap of expected return type(s)
1210  *
1211  * RETURN:      Buffer is populated with type names.
1212  *
1213  * DESCRIPTION: Translate the expected types bitmap into a string of ascii
1214  *              names of expected types, for use in warning messages.
1215  *
1216  ******************************************************************************/
1217
1218 static void
1219 AcpiNsGetExpectedTypes (
1220     char                        *Buffer,
1221     UINT32                      ExpectedBtypes)
1222 {
1223     UINT32                      ThisRtype;
1224     UINT32                      i;
1225     UINT32                      j;
1226
1227
1228     j = 1;
1229     Buffer[0] = 0;
1230     ThisRtype = ACPI_RTYPE_INTEGER;
1231
1232     for (i = 0; i < ACPI_NUM_RTYPES; i++)
1233     {
1234         /* If one of the expected types, concatenate the name of this type */
1235
1236         if (ExpectedBtypes & ThisRtype)
1237         {
1238             ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
1239             j = 0;              /* Use name separator from now on */
1240         }
1241         ThisRtype <<= 1;    /* Next Rtype */
1242     }
1243 }