ReactOS Fundraising Campaign 2012
 
€ 3,303 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nspredef.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: nspredef - Validation of ACPI predefined methods and objects
00004  *
00005  *****************************************************************************/
00006 
00007 /******************************************************************************
00008  *
00009  * 1. Copyright Notice
00010  *
00011  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00012  * All rights reserved.
00013  *
00014  * 2. License
00015  *
00016  * 2.1. This is your license from Intel Corp. under its intellectual property
00017  * rights.  You may have additional license terms from the party that provided
00018  * you this software, covering your right to use that party's intellectual
00019  * property rights.
00020  *
00021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00022  * copy of the source code appearing in this file ("Covered Code") an
00023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00024  * base code distributed originally by Intel ("Original Intel Code") to copy,
00025  * make derivatives, distribute, use and display any portion of the Covered
00026  * Code in any form, with the right to sublicense such rights; and
00027  *
00028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00029  * license (with the right to sublicense), under only those claims of Intel
00030  * patents that are infringed by the Original Intel Code, to make, use, sell,
00031  * offer to sell, and import the Covered Code and derivative works thereof
00032  * solely to the minimum extent necessary to exercise the above copyright
00033  * license, and in no event shall the patent license extend to any additions
00034  * to or modifications of the Original Intel Code.  No other license or right
00035  * is granted directly or by implication, estoppel or otherwise;
00036  *
00037  * The above copyright and patent license is granted only if the following
00038  * conditions are met:
00039  *
00040  * 3. Conditions
00041  *
00042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00043  * Redistribution of source code of any substantial portion of the Covered
00044  * Code or modification with rights to further distribute source must include
00045  * the above Copyright Notice, the above License, this list of Conditions,
00046  * and the following Disclaimer and Export Compliance provision.  In addition,
00047  * Licensee must cause all Covered Code to which Licensee contributes to
00048  * contain a file documenting the changes Licensee made to create that Covered
00049  * Code and the date of any change.  Licensee must include in that file the
00050  * documentation of any changes made by any predecessor Licensee.  Licensee
00051  * must include a prominent statement that the modification is derived,
00052  * directly or indirectly, from Original Intel Code.
00053  *
00054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00055  * Redistribution of source code of any substantial portion of the Covered
00056  * Code or modification without rights to further distribute source must
00057  * include the following Disclaimer and Export Compliance provision in the
00058  * documentation and/or other materials provided with distribution.  In
00059  * addition, Licensee may not authorize further sublicense of source of any
00060  * portion of the Covered Code, and must include terms to the effect that the
00061  * license from Licensee to its licensee is limited to the intellectual
00062  * property embodied in the software Licensee provides to its licensee, and
00063  * not to intellectual property embodied in modifications its licensee may
00064  * make.
00065  *
00066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00067  * substantial portion of the Covered Code or modification must reproduce the
00068  * above Copyright Notice, and the following Disclaimer and Export Compliance
00069  * provision in the documentation and/or other materials provided with the
00070  * distribution.
00071  *
00072  * 3.4. Intel retains all right, title, and interest in and to the Original
00073  * Intel Code.
00074  *
00075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00076  * Intel shall be used in advertising or otherwise to promote the sale, use or
00077  * other dealings in products derived from or relating to the Covered Code
00078  * without prior written authorization from Intel.
00079  *
00080  * 4. Disclaimer and Export Compliance
00081  *
00082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00088  * PARTICULAR PURPOSE.
00089  *
00090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00097  * LIMITED REMEDY.
00098  *
00099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00100  * software or system incorporating such software without first obtaining any
00101  * required license or other approval from the U. S. Department of Commerce or
00102  * any other agency or department of the United States Government.  In the
00103  * event Licensee exports any such software from the United States or
00104  * re-exports any such software from a foreign destination, Licensee shall
00105  * ensure that the distribution and export/re-export of the software is in
00106  * compliance with all laws, regulations, orders, or other restrictions of the
00107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00108  * any of its subsidiaries will export/re-export any technical data, process,
00109  * software, or service, directly or indirectly, to any country for which the
00110  * United States government or any agency thereof requires an export license,
00111  * other governmental approval, or letter of assurance, without first obtaining
00112  * such license, approval or letter.
00113  *
00114  *****************************************************************************/
00115 
00116 #define ACPI_CREATE_PREDEFINED_TABLE
00117 
00118 #include "acpi.h"
00119 #include "accommon.h"
00120 #include "acnamesp.h"
00121 #include "acpredef.h"
00122 
00123 
00124 #define _COMPONENT          ACPI_NAMESPACE
00125         ACPI_MODULE_NAME    ("nspredef")
00126 
00127 
00128 /*******************************************************************************
00129  *
00130  * This module validates predefined ACPI objects that appear in the namespace,
00131  * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
00132  * validation is to detect problems with BIOS-exposed predefined ACPI objects
00133  * before the results are returned to the ACPI-related drivers.
00134  *
00135  * There are several areas that are validated:
00136  *
00137  *  1) The number of input arguments as defined by the method/object in the
00138  *      ASL is validated against the ACPI specification.
00139  *  2) The type of the return object (if any) is validated against the ACPI
00140  *      specification.
00141  *  3) For returned package objects, the count of package elements is
00142  *      validated, as well as the type of each package element. Nested
00143  *      packages are supported.
00144  *
00145  * For any problems found, a warning message is issued.
00146  *
00147  ******************************************************************************/
00148 
00149 
00150 /* Local prototypes */
00151 
00152 static ACPI_STATUS
00153 AcpiNsCheckPackage (
00154     ACPI_PREDEFINED_DATA        *Data,
00155     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
00156 
00157 static ACPI_STATUS
00158 AcpiNsCheckPackageList (
00159     ACPI_PREDEFINED_DATA        *Data,
00160     const ACPI_PREDEFINED_INFO  *Package,
00161     ACPI_OPERAND_OBJECT         **Elements,
00162     UINT32                      Count);
00163 
00164 static ACPI_STATUS
00165 AcpiNsCheckPackageElements (
00166     ACPI_PREDEFINED_DATA        *Data,
00167     ACPI_OPERAND_OBJECT         **Elements,
00168     UINT8                       Type1,
00169     UINT32                      Count1,
00170     UINT8                       Type2,
00171     UINT32                      Count2,
00172     UINT32                      StartIndex);
00173 
00174 static ACPI_STATUS
00175 AcpiNsCheckObjectType (
00176     ACPI_PREDEFINED_DATA        *Data,
00177     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
00178     UINT32                      ExpectedBtypes,
00179     UINT32                      PackageIndex);
00180 
00181 static ACPI_STATUS
00182 AcpiNsCheckReference (
00183     ACPI_PREDEFINED_DATA        *Data,
00184     ACPI_OPERAND_OBJECT         *ReturnObject);
00185 
00186 static void
00187 AcpiNsGetExpectedTypes (
00188     char                        *Buffer,
00189     UINT32                      ExpectedBtypes);
00190 
00191 /*
00192  * Names for the types that can be returned by the predefined objects.
00193  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
00194  */
00195 static const char   *AcpiRtypeNames[] =
00196 {
00197     "/Integer",
00198     "/String",
00199     "/Buffer",
00200     "/Package",
00201     "/Reference",
00202 };
00203 
00204 
00205 /*******************************************************************************
00206  *
00207  * FUNCTION:    AcpiNsCheckPredefinedNames
00208  *
00209  * PARAMETERS:  Node            - Namespace node for the method/object
00210  *              UserParamCount  - Number of parameters actually passed
00211  *              ReturnStatus    - Status from the object evaluation
00212  *              ReturnObjectPtr - Pointer to the object returned from the
00213  *                                evaluation of a method or object
00214  *
00215  * RETURN:      Status
00216  *
00217  * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
00218  *
00219  ******************************************************************************/
00220 
00221 ACPI_STATUS
00222 AcpiNsCheckPredefinedNames (
00223     ACPI_NAMESPACE_NODE         *Node,
00224     UINT32                      UserParamCount,
00225     ACPI_STATUS                 ReturnStatus,
00226     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
00227 {
00228     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
00229     ACPI_STATUS                 Status = AE_OK;
00230     const ACPI_PREDEFINED_INFO  *Predefined;
00231     char                        *Pathname;
00232     ACPI_PREDEFINED_DATA        *Data;
00233 
00234 
00235     /* Match the name for this method/object against the predefined list */
00236 
00237     Predefined = AcpiNsCheckForPredefinedName (Node);
00238 
00239     /* Get the full pathname to the object, for use in warning messages */
00240 
00241     Pathname = AcpiNsGetExternalPathname (Node);
00242     if (!Pathname)
00243     {
00244         return (AE_OK); /* Could not get pathname, ignore */
00245     }
00246 
00247     /*
00248      * Check that the parameter count for this method matches the ASL
00249      * definition. For predefined names, ensure that both the caller and
00250      * the method itself are in accordance with the ACPI specification.
00251      */
00252     AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
00253 
00254     /* If not a predefined name, we cannot validate the return object */
00255 
00256     if (!Predefined)
00257     {
00258         goto Cleanup;
00259     }
00260 
00261     /*
00262      * If the method failed or did not actually return an object, we cannot
00263      * validate the return object
00264      */
00265     if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
00266     {
00267         goto Cleanup;
00268     }
00269 
00270     /*
00271      * If there is no return value, check if we require a return value for
00272      * this predefined name. Either one return value is expected, or none,
00273      * for both methods and other objects.
00274      *
00275      * Exit now if there is no return object. Warning if one was expected.
00276      */
00277     if (!ReturnObject)
00278     {
00279         if ((Predefined->Info.ExpectedBtypes) &&
00280             (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
00281         {
00282             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
00283                 "Missing expected return value"));
00284 
00285             Status = AE_AML_NO_RETURN_VALUE;
00286         }
00287         goto Cleanup;
00288     }
00289 
00290     /*
00291      * Return value validation and possible repair.
00292      *
00293      * 1) Don't perform return value validation/repair if this feature
00294      * has been disabled via a global option.
00295      *
00296      * 2) We have a return value, but if one wasn't expected, just exit,
00297      * this is not a problem. For example, if the "Implicit Return"
00298      * feature is enabled, methods will always return a value.
00299      *
00300      * 3) If the return value can be of any type, then we cannot perform
00301      * any validation, just exit.
00302      */
00303     if (AcpiGbl_DisableAutoRepair ||
00304         (!Predefined->Info.ExpectedBtypes) ||
00305         (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL))
00306     {
00307         goto Cleanup;
00308     }
00309 
00310     /* Create the parameter data block for object validation */
00311 
00312     Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA));
00313     if (!Data)
00314     {
00315         goto Cleanup;
00316     }
00317     Data->Predefined = Predefined;
00318     Data->Node = Node;
00319     Data->NodeFlags = Node->Flags;
00320     Data->Pathname = Pathname;
00321 
00322     /*
00323      * Check that the type of the main return object is what is expected
00324      * for this predefined name
00325      */
00326     Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
00327                 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
00328     if (ACPI_FAILURE (Status))
00329     {
00330         goto Exit;
00331     }
00332 
00333     /*
00334      * For returned Package objects, check the type of all sub-objects.
00335      * Note: Package may have been newly created by call above.
00336      */
00337     if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
00338     {
00339         Data->ParentPackage = *ReturnObjectPtr;
00340         Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
00341         if (ACPI_FAILURE (Status))
00342         {
00343             goto Exit;
00344         }
00345     }
00346 
00347     /*
00348      * The return object was OK, or it was successfully repaired above.
00349      * Now make some additional checks such as verifying that package
00350      * objects are sorted correctly (if required) or buffer objects have
00351      * the correct data width (bytes vs. dwords). These repairs are
00352      * performed on a per-name basis, i.e., the code is specific to
00353      * particular predefined names.
00354      */
00355     Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr);
00356 
00357 Exit:
00358     /*
00359      * If the object validation failed or if we successfully repaired one
00360      * or more objects, mark the parent node to suppress further warning
00361      * messages during the next evaluation of the same method/object.
00362      */
00363     if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED))
00364     {
00365         Node->Flags |= ANOBJ_EVALUATED;
00366     }
00367     ACPI_FREE (Data);
00368 
00369 Cleanup:
00370     ACPI_FREE (Pathname);
00371     return (Status);
00372 }
00373 
00374 
00375 /*******************************************************************************
00376  *
00377  * FUNCTION:    AcpiNsCheckParameterCount
00378  *
00379  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
00380  *              Node            - Namespace node for the method/object
00381  *              UserParamCount  - Number of args passed in by the caller
00382  *              Predefined      - Pointer to entry in predefined name table
00383  *
00384  * RETURN:      None
00385  *
00386  * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
00387  *              predefined name is what is expected (i.e., what is defined in
00388  *              the ACPI specification for this predefined name.)
00389  *
00390  ******************************************************************************/
00391 
00392 void
00393 AcpiNsCheckParameterCount (
00394     char                        *Pathname,
00395     ACPI_NAMESPACE_NODE         *Node,
00396     UINT32                      UserParamCount,
00397     const ACPI_PREDEFINED_INFO  *Predefined)
00398 {
00399     UINT32                      ParamCount;
00400     UINT32                      RequiredParamsCurrent;
00401     UINT32                      RequiredParamsOld;
00402 
00403 
00404     /* Methods have 0-7 parameters. All other types have zero. */
00405 
00406     ParamCount = 0;
00407     if (Node->Type == ACPI_TYPE_METHOD)
00408     {
00409         ParamCount = Node->Object->Method.ParamCount;
00410     }
00411 
00412     if (!Predefined)
00413     {
00414         /*
00415          * Check the parameter count for non-predefined methods/objects.
00416          *
00417          * Warning if too few or too many arguments have been passed by the
00418          * caller. An incorrect number of arguments may not cause the method
00419          * to fail. However, the method will fail if there are too few
00420          * arguments and the method attempts to use one of the missing ones.
00421          */
00422         if (UserParamCount < ParamCount)
00423         {
00424             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
00425                 "Insufficient arguments - needs %u, found %u",
00426                 ParamCount, UserParamCount));
00427         }
00428         else if (UserParamCount > ParamCount)
00429         {
00430             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
00431                 "Excess arguments - needs %u, found %u",
00432                 ParamCount, UserParamCount));
00433         }
00434         return;
00435     }
00436 
00437     /*
00438      * Validate the user-supplied parameter count.
00439      * Allow two different legal argument counts (_SCP, etc.)
00440      */
00441     RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
00442     RequiredParamsOld = Predefined->Info.ParamCount >> 4;
00443 
00444     if (UserParamCount != ACPI_UINT32_MAX)
00445     {
00446         if ((UserParamCount != RequiredParamsCurrent) &&
00447             (UserParamCount != RequiredParamsOld))
00448         {
00449             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
00450                 "Parameter count mismatch - "
00451                 "caller passed %u, ACPI requires %u",
00452                 UserParamCount, RequiredParamsCurrent));
00453         }
00454     }
00455 
00456     /*
00457      * Check that the ASL-defined parameter count is what is expected for
00458      * this predefined name (parameter count as defined by the ACPI
00459      * specification)
00460      */
00461     if ((ParamCount != RequiredParamsCurrent) &&
00462         (ParamCount != RequiredParamsOld))
00463     {
00464         ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags,
00465             "Parameter count mismatch - ASL declared %u, ACPI requires %u",
00466             ParamCount, RequiredParamsCurrent));
00467     }
00468 }
00469 
00470 
00471 /*******************************************************************************
00472  *
00473  * FUNCTION:    AcpiNsCheckForPredefinedName
00474  *
00475  * PARAMETERS:  Node            - Namespace node for the method/object
00476  *
00477  * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
00478  *
00479  * DESCRIPTION: Check an object name against the predefined object list.
00480  *
00481  ******************************************************************************/
00482 
00483 const ACPI_PREDEFINED_INFO *
00484 AcpiNsCheckForPredefinedName (
00485     ACPI_NAMESPACE_NODE         *Node)
00486 {
00487     const ACPI_PREDEFINED_INFO  *ThisName;
00488 
00489 
00490     /* Quick check for a predefined name, first character must be underscore */
00491 
00492     if (Node->Name.Ascii[0] != '_')
00493     {
00494         return (NULL);
00495     }
00496 
00497     /* Search info table for a predefined method/object name */
00498 
00499     ThisName = PredefinedNames;
00500     while (ThisName->Info.Name[0])
00501     {
00502         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
00503         {
00504             return (ThisName);
00505         }
00506 
00507         /*
00508          * Skip next entry in the table if this name returns a Package
00509          * (next entry contains the package info)
00510          */
00511         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
00512         {
00513             ThisName++;
00514         }
00515 
00516         ThisName++;
00517     }
00518 
00519     return (NULL); /* Not found */
00520 }
00521 
00522 
00523 /*******************************************************************************
00524  *
00525  * FUNCTION:    AcpiNsCheckPackage
00526  *
00527  * PARAMETERS:  Data            - Pointer to validation data structure
00528  *              ReturnObjectPtr - Pointer to the object returned from the
00529  *                                evaluation of a method or object
00530  *
00531  * RETURN:      Status
00532  *
00533  * DESCRIPTION: Check a returned package object for the correct count and
00534  *              correct type of all sub-objects.
00535  *
00536  ******************************************************************************/
00537 
00538 static ACPI_STATUS
00539 AcpiNsCheckPackage (
00540     ACPI_PREDEFINED_DATA        *Data,
00541     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
00542 {
00543     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
00544     const ACPI_PREDEFINED_INFO  *Package;
00545     ACPI_OPERAND_OBJECT         **Elements;
00546     ACPI_STATUS                 Status = AE_OK;
00547     UINT32                      ExpectedCount;
00548     UINT32                      Count;
00549     UINT32                      i;
00550 
00551 
00552     ACPI_FUNCTION_NAME (NsCheckPackage);
00553 
00554 
00555     /* The package info for this name is in the next table entry */
00556 
00557     Package = Data->Predefined + 1;
00558 
00559     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
00560         "%s Validating return Package of Type %X, Count %X\n",
00561         Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
00562 
00563     /*
00564      * For variable-length Packages, we can safely remove all embedded
00565      * and trailing NULL package elements
00566      */
00567     AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject);
00568 
00569     /* Extract package count and elements array */
00570 
00571     Elements = ReturnObject->Package.Elements;
00572     Count = ReturnObject->Package.Count;
00573 
00574     /* The package must have at least one element, else invalid */
00575 
00576     if (!Count)
00577     {
00578         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
00579             "Return Package has no elements (empty)"));
00580 
00581         return (AE_AML_OPERAND_VALUE);
00582     }
00583 
00584     /*
00585      * Decode the type of the expected package contents
00586      *
00587      * PTYPE1 packages contain no subpackages
00588      * PTYPE2 packages contain sub-packages
00589      */
00590     switch (Package->RetInfo.Type)
00591     {
00592     case ACPI_PTYPE1_FIXED:
00593 
00594         /*
00595          * The package count is fixed and there are no sub-packages
00596          *
00597          * If package is too small, exit.
00598          * If package is larger than expected, issue warning but continue
00599          */
00600         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
00601         if (Count < ExpectedCount)
00602         {
00603             goto PackageTooSmall;
00604         }
00605         else if (Count > ExpectedCount)
00606         {
00607             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
00608                 "%s: Return Package is larger than needed - "
00609                 "found %u, expected %u\n",
00610                 Data->Pathname, Count, ExpectedCount));
00611         }
00612 
00613         /* Validate all elements of the returned package */
00614 
00615         Status = AcpiNsCheckPackageElements (Data, Elements,
00616                     Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
00617                     Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
00618         break;
00619 
00620 
00621     case ACPI_PTYPE1_VAR:
00622 
00623         /*
00624          * The package count is variable, there are no sub-packages, and all
00625          * elements must be of the same type
00626          */
00627         for (i = 0; i < Count; i++)
00628         {
00629             Status = AcpiNsCheckObjectType (Data, Elements,
00630                         Package->RetInfo.ObjectType1, i);
00631             if (ACPI_FAILURE (Status))
00632             {
00633                 return (Status);
00634             }
00635             Elements++;
00636         }
00637         break;
00638 
00639 
00640     case ACPI_PTYPE1_OPTION:
00641 
00642         /*
00643          * The package count is variable, there are no sub-packages. There are
00644          * a fixed number of required elements, and a variable number of
00645          * optional elements.
00646          *
00647          * Check if package is at least as large as the minimum required
00648          */
00649         ExpectedCount = Package->RetInfo3.Count;
00650         if (Count < ExpectedCount)
00651         {
00652             goto PackageTooSmall;
00653         }
00654 
00655         /* Variable number of sub-objects */
00656 
00657         for (i = 0; i < Count; i++)
00658         {
00659             if (i < Package->RetInfo3.Count)
00660             {
00661                 /* These are the required package elements (0, 1, or 2) */
00662 
00663                 Status = AcpiNsCheckObjectType (Data, Elements,
00664                             Package->RetInfo3.ObjectType[i], i);
00665                 if (ACPI_FAILURE (Status))
00666                 {
00667                     return (Status);
00668                 }
00669             }
00670             else
00671             {
00672                 /* These are the optional package elements */
00673 
00674                 Status = AcpiNsCheckObjectType (Data, Elements,
00675                             Package->RetInfo3.TailObjectType, i);
00676                 if (ACPI_FAILURE (Status))
00677                 {
00678                     return (Status);
00679                 }
00680             }
00681             Elements++;
00682         }
00683         break;
00684 
00685 
00686     case ACPI_PTYPE2_REV_FIXED:
00687 
00688         /* First element is the (Integer) revision */
00689 
00690         Status = AcpiNsCheckObjectType (Data, Elements,
00691                     ACPI_RTYPE_INTEGER, 0);
00692         if (ACPI_FAILURE (Status))
00693         {
00694             return (Status);
00695         }
00696 
00697         Elements++;
00698         Count--;
00699 
00700         /* Examine the sub-packages */
00701 
00702         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
00703         break;
00704 
00705 
00706     case ACPI_PTYPE2_PKG_COUNT:
00707 
00708         /* First element is the (Integer) count of sub-packages to follow */
00709 
00710         Status = AcpiNsCheckObjectType (Data, Elements,
00711                     ACPI_RTYPE_INTEGER, 0);
00712         if (ACPI_FAILURE (Status))
00713         {
00714             return (Status);
00715         }
00716 
00717         /*
00718          * Count cannot be larger than the parent package length, but allow it
00719          * to be smaller. The >= accounts for the Integer above.
00720          */
00721         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
00722         if (ExpectedCount >= Count)
00723         {
00724             goto PackageTooSmall;
00725         }
00726 
00727         Count = ExpectedCount;
00728         Elements++;
00729 
00730         /* Examine the sub-packages */
00731 
00732         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
00733         break;
00734 
00735 
00736     case ACPI_PTYPE2:
00737     case ACPI_PTYPE2_FIXED:
00738     case ACPI_PTYPE2_MIN:
00739     case ACPI_PTYPE2_COUNT:
00740 
00741         /*
00742          * These types all return a single Package that consists of a
00743          * variable number of sub-Packages.
00744          *
00745          * First, ensure that the first element is a sub-Package. If not,
00746          * the BIOS may have incorrectly returned the object as a single
00747          * package instead of a Package of Packages (a common error if
00748          * there is only one entry). We may be able to repair this by
00749          * wrapping the returned Package with a new outer Package.
00750          */
00751         if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE))
00752         {
00753             /* Create the new outer package and populate it */
00754 
00755             Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr);
00756             if (ACPI_FAILURE (Status))
00757             {
00758                 return (Status);
00759             }
00760 
00761             /* Update locals to point to the new package (of 1 element) */
00762 
00763             ReturnObject = *ReturnObjectPtr;
00764             Elements = ReturnObject->Package.Elements;
00765             Count = 1;
00766         }
00767 
00768         /* Examine the sub-packages */
00769 
00770         Status = AcpiNsCheckPackageList (Data, Package, Elements, Count);
00771         break;
00772 
00773 
00774     default:
00775 
00776         /* Should not get here if predefined info table is correct */
00777 
00778         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
00779             "Invalid internal return type in table entry: %X",
00780             Package->RetInfo.Type));
00781 
00782         return (AE_AML_INTERNAL);
00783     }
00784 
00785     return (Status);
00786 
00787 
00788 PackageTooSmall:
00789 
00790     /* Error exit for the case with an incorrect package count */
00791 
00792     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
00793         "Return Package is too small - found %u elements, expected %u",
00794         Count, ExpectedCount));
00795 
00796     return (AE_AML_OPERAND_VALUE);
00797 }
00798 
00799 
00800 /*******************************************************************************
00801  *
00802  * FUNCTION:    AcpiNsCheckPackageList
00803  *
00804  * PARAMETERS:  Data            - Pointer to validation data structure
00805  *              Package         - Pointer to package-specific info for method
00806  *              Elements        - Element list of parent package. All elements
00807  *                                of this list should be of type Package.
00808  *              Count           - Count of subpackages
00809  *
00810  * RETURN:      Status
00811  *
00812  * DESCRIPTION: Examine a list of subpackages
00813  *
00814  ******************************************************************************/
00815 
00816 static ACPI_STATUS
00817 AcpiNsCheckPackageList (
00818     ACPI_PREDEFINED_DATA        *Data,
00819     const ACPI_PREDEFINED_INFO  *Package,
00820     ACPI_OPERAND_OBJECT         **Elements,
00821     UINT32                      Count)
00822 {
00823     ACPI_OPERAND_OBJECT         *SubPackage;
00824     ACPI_OPERAND_OBJECT         **SubElements;
00825     ACPI_STATUS                 Status;
00826     UINT32                      ExpectedCount;
00827     UINT32                      i;
00828     UINT32                      j;
00829 
00830 
00831     /*
00832      * Validate each sub-Package in the parent Package
00833      *
00834      * NOTE: assumes list of sub-packages contains no NULL elements.
00835      * Any NULL elements should have been removed by earlier call
00836      * to AcpiNsRemoveNullElements.
00837      */
00838     for (i = 0; i < Count; i++)
00839     {
00840         SubPackage = *Elements;
00841         SubElements = SubPackage->Package.Elements;
00842         Data->ParentPackage = SubPackage;
00843 
00844         /* Each sub-object must be of type Package */
00845 
00846         Status = AcpiNsCheckObjectType (Data, &SubPackage,
00847                     ACPI_RTYPE_PACKAGE, i);
00848         if (ACPI_FAILURE (Status))
00849         {
00850             return (Status);
00851         }
00852 
00853         /* Examine the different types of expected sub-packages */
00854 
00855         Data->ParentPackage = SubPackage;
00856         switch (Package->RetInfo.Type)
00857         {
00858         case ACPI_PTYPE2:
00859         case ACPI_PTYPE2_PKG_COUNT:
00860         case ACPI_PTYPE2_REV_FIXED:
00861 
00862             /* Each subpackage has a fixed number of elements */
00863 
00864             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
00865             if (SubPackage->Package.Count < ExpectedCount)
00866             {
00867                 goto PackageTooSmall;
00868             }
00869 
00870             Status = AcpiNsCheckPackageElements (Data, SubElements,
00871                         Package->RetInfo.ObjectType1,
00872                         Package->RetInfo.Count1,
00873                         Package->RetInfo.ObjectType2,
00874                         Package->RetInfo.Count2, 0);
00875             if (ACPI_FAILURE (Status))
00876             {
00877                 return (Status);
00878             }
00879             break;
00880 
00881 
00882         case ACPI_PTYPE2_FIXED:
00883 
00884             /* Each sub-package has a fixed length */
00885 
00886             ExpectedCount = Package->RetInfo2.Count;
00887             if (SubPackage->Package.Count < ExpectedCount)
00888             {
00889                 goto PackageTooSmall;
00890             }
00891 
00892             /* Check the type of each sub-package element */
00893 
00894             for (j = 0; j < ExpectedCount; j++)
00895             {
00896                 Status = AcpiNsCheckObjectType (Data, &SubElements[j],
00897                             Package->RetInfo2.ObjectType[j], j);
00898                 if (ACPI_FAILURE (Status))
00899                 {
00900                     return (Status);
00901                 }
00902             }
00903             break;
00904 
00905 
00906         case ACPI_PTYPE2_MIN:
00907 
00908             /* Each sub-package has a variable but minimum length */
00909 
00910             ExpectedCount = Package->RetInfo.Count1;
00911             if (SubPackage->Package.Count < ExpectedCount)
00912             {
00913                 goto PackageTooSmall;
00914             }
00915 
00916             /* Check the type of each sub-package element */
00917 
00918             Status = AcpiNsCheckPackageElements (Data, SubElements,
00919                         Package->RetInfo.ObjectType1,
00920                         SubPackage->Package.Count, 0, 0, 0);
00921             if (ACPI_FAILURE (Status))
00922             {
00923                 return (Status);
00924             }
00925             break;
00926 
00927 
00928         case ACPI_PTYPE2_COUNT:
00929 
00930             /*
00931              * First element is the (Integer) count of elements, including
00932              * the count field (the ACPI name is NumElements)
00933              */
00934             Status = AcpiNsCheckObjectType (Data, SubElements,
00935                         ACPI_RTYPE_INTEGER, 0);
00936             if (ACPI_FAILURE (Status))
00937             {
00938                 return (Status);
00939             }
00940 
00941             /*
00942              * Make sure package is large enough for the Count and is
00943              * is as large as the minimum size
00944              */
00945             ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
00946             if (SubPackage->Package.Count < ExpectedCount)
00947             {
00948                 goto PackageTooSmall;
00949             }
00950             if (SubPackage->Package.Count < Package->RetInfo.Count1)
00951             {
00952                 ExpectedCount = Package->RetInfo.Count1;
00953                 goto PackageTooSmall;
00954             }
00955             if (ExpectedCount == 0)
00956             {
00957                 /*
00958                  * Either the NumEntries element was originally zero or it was
00959                  * a NULL element and repaired to an Integer of value zero.
00960                  * In either case, repair it by setting NumEntries to be the
00961                  * actual size of the subpackage.
00962                  */
00963                 ExpectedCount = SubPackage->Package.Count;
00964                 (*SubElements)->Integer.Value = ExpectedCount;
00965             }
00966 
00967             /* Check the type of each sub-package element */
00968 
00969             Status = AcpiNsCheckPackageElements (Data, (SubElements + 1),
00970                         Package->RetInfo.ObjectType1,
00971                         (ExpectedCount - 1), 0, 0, 1);
00972             if (ACPI_FAILURE (Status))
00973             {
00974                 return (Status);
00975             }
00976             break;
00977 
00978 
00979         default: /* Should not get here, type was validated by caller */
00980 
00981             return (AE_AML_INTERNAL);
00982         }
00983 
00984         Elements++;
00985     }
00986 
00987     return (AE_OK);
00988 
00989 
00990 PackageTooSmall:
00991 
00992     /* The sub-package count was smaller than required */
00993 
00994     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
00995         "Return Sub-Package[%u] is too small - found %u elements, expected %u",
00996         i, SubPackage->Package.Count, ExpectedCount));
00997 
00998     return (AE_AML_OPERAND_VALUE);
00999 }
01000 
01001 
01002 /*******************************************************************************
01003  *
01004  * FUNCTION:    AcpiNsCheckPackageElements
01005  *
01006  * PARAMETERS:  Data            - Pointer to validation data structure
01007  *              Elements        - Pointer to the package elements array
01008  *              Type1           - Object type for first group
01009  *              Count1          - Count for first group
01010  *              Type2           - Object type for second group
01011  *              Count2          - Count for second group
01012  *              StartIndex      - Start of the first group of elements
01013  *
01014  * RETURN:      Status
01015  *
01016  * DESCRIPTION: Check that all elements of a package are of the correct object
01017  *              type. Supports up to two groups of different object types.
01018  *
01019  ******************************************************************************/
01020 
01021 static ACPI_STATUS
01022 AcpiNsCheckPackageElements (
01023     ACPI_PREDEFINED_DATA        *Data,
01024     ACPI_OPERAND_OBJECT         **Elements,
01025     UINT8                       Type1,
01026     UINT32                      Count1,
01027     UINT8                       Type2,
01028     UINT32                      Count2,
01029     UINT32                      StartIndex)
01030 {
01031     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
01032     ACPI_STATUS                 Status;
01033     UINT32                      i;
01034 
01035 
01036     /*
01037      * Up to two groups of package elements are supported by the data
01038      * structure. All elements in each group must be of the same type.
01039      * The second group can have a count of zero.
01040      */
01041     for (i = 0; i < Count1; i++)
01042     {
01043         Status = AcpiNsCheckObjectType (Data, ThisElement,
01044                     Type1, i + StartIndex);
01045         if (ACPI_FAILURE (Status))
01046         {
01047             return (Status);
01048         }
01049         ThisElement++;
01050     }
01051 
01052     for (i = 0; i < Count2; i++)
01053     {
01054         Status = AcpiNsCheckObjectType (Data, ThisElement,
01055                     Type2, (i + Count1 + StartIndex));
01056         if (ACPI_FAILURE (Status))
01057         {
01058             return (Status);
01059         }
01060         ThisElement++;
01061     }
01062 
01063     return (AE_OK);
01064 }
01065 
01066 
01067 /*******************************************************************************
01068  *
01069  * FUNCTION:    AcpiNsCheckObjectType
01070  *
01071  * PARAMETERS:  Data            - Pointer to validation data structure
01072  *              ReturnObjectPtr - Pointer to the object returned from the
01073  *                                evaluation of a method or object
01074  *              ExpectedBtypes  - Bitmap of expected return type(s)
01075  *              PackageIndex    - Index of object within parent package (if
01076  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
01077  *                                otherwise)
01078  *
01079  * RETURN:      Status
01080  *
01081  * DESCRIPTION: Check the type of the return object against the expected object
01082  *              type(s). Use of Btype allows multiple expected object types.
01083  *
01084  ******************************************************************************/
01085 
01086 static ACPI_STATUS
01087 AcpiNsCheckObjectType (
01088     ACPI_PREDEFINED_DATA        *Data,
01089     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
01090     UINT32                      ExpectedBtypes,
01091     UINT32                      PackageIndex)
01092 {
01093     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
01094     ACPI_STATUS                 Status = AE_OK;
01095     UINT32                      ReturnBtype;
01096     char                        TypeBuffer[48]; /* Room for 5 types */
01097 
01098 
01099     /*
01100      * If we get a NULL ReturnObject here, it is a NULL package element.
01101      * Since all extraneous NULL package elements were removed earlier by a
01102      * call to AcpiNsRemoveNullElements, this is an unexpected NULL element.
01103      * We will attempt to repair it.
01104      */
01105     if (!ReturnObject)
01106     {
01107         Status = AcpiNsRepairNullElement (Data, ExpectedBtypes,
01108                     PackageIndex, ReturnObjectPtr);
01109         if (ACPI_SUCCESS (Status))
01110         {
01111             return (AE_OK); /* Repair was successful */
01112         }
01113         goto TypeErrorExit;
01114     }
01115 
01116     /* A Namespace node should not get here, but make sure */
01117 
01118     if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
01119     {
01120         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
01121             "Invalid return type - Found a Namespace node [%4.4s] type %s",
01122             ReturnObject->Node.Name.Ascii,
01123             AcpiUtGetTypeName (ReturnObject->Node.Type)));
01124         return (AE_AML_OPERAND_TYPE);
01125     }
01126 
01127     /*
01128      * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
01129      * The bitmapped type allows multiple possible return types.
01130      *
01131      * Note, the cases below must handle all of the possible types returned
01132      * from all of the predefined names (including elements of returned
01133      * packages)
01134      */
01135     switch (ReturnObject->Common.Type)
01136     {
01137     case ACPI_TYPE_INTEGER:
01138         ReturnBtype = ACPI_RTYPE_INTEGER;
01139         break;
01140 
01141     case ACPI_TYPE_BUFFER:
01142         ReturnBtype = ACPI_RTYPE_BUFFER;
01143         break;
01144 
01145     case ACPI_TYPE_STRING:
01146         ReturnBtype = ACPI_RTYPE_STRING;
01147         break;
01148 
01149     case ACPI_TYPE_PACKAGE:
01150         ReturnBtype = ACPI_RTYPE_PACKAGE;
01151         break;
01152 
01153     case ACPI_TYPE_LOCAL_REFERENCE:
01154         ReturnBtype = ACPI_RTYPE_REFERENCE;
01155         break;
01156 
01157     default:
01158         /* Not one of the supported objects, must be incorrect */
01159 
01160         goto TypeErrorExit;
01161     }
01162 
01163     /* Is the object one of the expected types? */
01164 
01165     if (ReturnBtype & ExpectedBtypes)
01166     {
01167         /* For reference objects, check that the reference type is correct */
01168 
01169         if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
01170         {
01171             Status = AcpiNsCheckReference (Data, ReturnObject);
01172         }
01173 
01174         return (Status);
01175     }
01176 
01177     /* Type mismatch -- attempt repair of the returned object */
01178 
01179     Status = AcpiNsRepairObject (Data, ExpectedBtypes,
01180                 PackageIndex, ReturnObjectPtr);
01181     if (ACPI_SUCCESS (Status))
01182     {
01183         return (AE_OK); /* Repair was successful */
01184     }
01185 
01186 
01187 TypeErrorExit:
01188 
01189     /* Create a string with all expected types for this predefined object */
01190 
01191     AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);
01192 
01193     if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
01194     {
01195         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
01196             "Return type mismatch - found %s, expected %s",
01197             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
01198     }
01199     else
01200     {
01201         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
01202             "Return Package type mismatch at index %u - "
01203             "found %s, expected %s", PackageIndex,
01204             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
01205     }
01206 
01207     return (AE_AML_OPERAND_TYPE);
01208 }
01209 
01210 
01211 /*******************************************************************************
01212  *
01213  * FUNCTION:    AcpiNsCheckReference
01214  *
01215  * PARAMETERS:  Data            - Pointer to validation data structure
01216  *              ReturnObject    - Object returned from the evaluation of a
01217  *                                method or object
01218  *
01219  * RETURN:      Status
01220  *
01221  * DESCRIPTION: Check a returned reference object for the correct reference
01222  *              type. The only reference type that can be returned from a
01223  *              predefined method is a named reference. All others are invalid.
01224  *
01225  ******************************************************************************/
01226 
01227 static ACPI_STATUS
01228 AcpiNsCheckReference (
01229     ACPI_PREDEFINED_DATA        *Data,
01230     ACPI_OPERAND_OBJECT         *ReturnObject)
01231 {
01232 
01233     /*
01234      * Check the reference object for the correct reference type (opcode).
01235      * The only type of reference that can be converted to an ACPI_OBJECT is
01236      * a reference to a named object (reference class: NAME)
01237      */
01238     if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
01239     {
01240         return (AE_OK);
01241     }
01242 
01243     ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
01244         "Return type mismatch - unexpected reference object type [%s] %2.2X",
01245         AcpiUtGetReferenceName (ReturnObject),
01246         ReturnObject->Reference.Class));
01247 
01248     return (AE_AML_OPERAND_TYPE);
01249 }
01250 
01251 
01252 /*******************************************************************************
01253  *
01254  * FUNCTION:    AcpiNsGetExpectedTypes
01255  *
01256  * PARAMETERS:  Buffer          - Pointer to where the string is returned
01257  *              ExpectedBtypes  - Bitmap of expected return type(s)
01258  *
01259  * RETURN:      Buffer is populated with type names.
01260  *
01261  * DESCRIPTION: Translate the expected types bitmap into a string of ascii
01262  *              names of expected types, for use in warning messages.
01263  *
01264  ******************************************************************************/
01265 
01266 static void
01267 AcpiNsGetExpectedTypes (
01268     char                        *Buffer,
01269     UINT32                      ExpectedBtypes)
01270 {
01271     UINT32                      ThisRtype;
01272     UINT32                      i;
01273     UINT32                      j;
01274 
01275 
01276     j = 1;
01277     Buffer[0] = 0;
01278     ThisRtype = ACPI_RTYPE_INTEGER;
01279 
01280     for (i = 0; i < ACPI_NUM_RTYPES; i++)
01281     {
01282         /* If one of the expected types, concatenate the name of this type */
01283 
01284         if (ExpectedBtypes & ThisRtype)
01285         {
01286             ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
01287             j = 0;              /* Use name separator from now on */
01288         }
01289         ThisRtype <<= 1;    /* Next Rtype */
01290     }
01291 }

Generated on Tue May 15 04:50:28 2012 for ReactOS by doxygen 1.6.3

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.