ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 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

dsobject.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: dsobject - Dispatcher object management routines
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 __DSOBJECT_C__
00117 
00118 #include "acpi.h"
00119 #include "accommon.h"
00120 #include "acparser.h"
00121 #include "amlcode.h"
00122 #include "acdispat.h"
00123 #include "acnamesp.h"
00124 #include "acinterp.h"
00125 
00126 #define _COMPONENT          ACPI_DISPATCHER
00127         ACPI_MODULE_NAME    ("dsobject")
00128 
00129 /* Local prototypes */
00130 
00131 static ACPI_STATUS
00132 AcpiDsBuildInternalObject (
00133     ACPI_WALK_STATE         *WalkState,
00134     ACPI_PARSE_OBJECT       *Op,
00135     ACPI_OPERAND_OBJECT     **ObjDescPtr);
00136 
00137 
00138 #ifndef ACPI_NO_METHOD_EXECUTION
00139 /*******************************************************************************
00140  *
00141  * FUNCTION:    AcpiDsBuildInternalObject
00142  *
00143  * PARAMETERS:  WalkState       - Current walk state
00144  *              Op              - Parser object to be translated
00145  *              ObjDescPtr      - Where the ACPI internal object is returned
00146  *
00147  * RETURN:      Status
00148  *
00149  * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
00150  *              Simple objects are any objects other than a package object!
00151  *
00152  ******************************************************************************/
00153 
00154 static ACPI_STATUS
00155 AcpiDsBuildInternalObject (
00156     ACPI_WALK_STATE         *WalkState,
00157     ACPI_PARSE_OBJECT       *Op,
00158     ACPI_OPERAND_OBJECT     **ObjDescPtr)
00159 {
00160     ACPI_OPERAND_OBJECT     *ObjDesc;
00161     ACPI_STATUS             Status;
00162     ACPI_OBJECT_TYPE        Type;
00163 
00164 
00165     ACPI_FUNCTION_TRACE (DsBuildInternalObject);
00166 
00167 
00168     *ObjDescPtr = NULL;
00169     if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
00170     {
00171         /*
00172          * This is a named object reference. If this name was
00173          * previously looked up in the namespace, it was stored in this op.
00174          * Otherwise, go ahead and look it up now
00175          */
00176         if (!Op->Common.Node)
00177         {
00178             Status = AcpiNsLookup (WalkState->ScopeInfo,
00179                         Op->Common.Value.String,
00180                         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
00181                         ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
00182                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
00183             if (ACPI_FAILURE (Status))
00184             {
00185                 /* Check if we are resolving a named reference within a package */
00186 
00187                 if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) &&
00188 
00189                     ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
00190                      (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
00191                 {
00192                     /*
00193                      * We didn't find the target and we are populating elements
00194                      * of a package - ignore if slack enabled. Some ASL code
00195                      * contains dangling invalid references in packages and
00196                      * expects that no exception will be issued. Leave the
00197                      * element as a null element. It cannot be used, but it
00198                      * can be overwritten by subsequent ASL code - this is
00199                      * typically the case.
00200                      */
00201                     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
00202                         "Ignoring unresolved reference in package [%4.4s]\n",
00203                         WalkState->ScopeInfo->Scope.Node->Name.Ascii));
00204 
00205                     return_ACPI_STATUS (AE_OK);
00206                 }
00207                 else
00208                 {
00209                     ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status);
00210                 }
00211 
00212                 return_ACPI_STATUS (Status);
00213             }
00214         }
00215 
00216         /* Special object resolution for elements of a package */
00217 
00218         if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
00219             (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
00220         {
00221             /*
00222              * Attempt to resolve the node to a value before we insert it into
00223              * the package. If this is a reference to a common data type,
00224              * resolve it immediately. According to the ACPI spec, package
00225              * elements can only be "data objects" or method references.
00226              * Attempt to resolve to an Integer, Buffer, String or Package.
00227              * If cannot, return the named reference (for things like Devices,
00228              * Methods, etc.) Buffer Fields and Fields will resolve to simple
00229              * objects (int/buf/str/pkg).
00230              *
00231              * NOTE: References to things like Devices, Methods, Mutexes, etc.
00232              * will remain as named references. This behavior is not described
00233              * in the ACPI spec, but it appears to be an oversight.
00234              */
00235             ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node);
00236 
00237             Status = AcpiExResolveNodeToValue (
00238                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc),
00239                         WalkState);
00240             if (ACPI_FAILURE (Status))
00241             {
00242                 return_ACPI_STATUS (Status);
00243             }
00244 
00245             /*
00246              * Special handling for Alias objects. We need to setup the type
00247              * and the Op->Common.Node to point to the Alias target. Note,
00248              * Alias has at most one level of indirection internally.
00249              */
00250             Type = Op->Common.Node->Type;
00251             if (Type == ACPI_TYPE_LOCAL_ALIAS)
00252             {
00253                 Type = ObjDesc->Common.Type;
00254                 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
00255                     Op->Common.Node->Object);
00256             }
00257 
00258             switch (Type)
00259             {
00260             /*
00261              * For these types, we need the actual node, not the subobject.
00262              * However, the subobject did not get an extra reference count above.
00263              *
00264              * TBD: should ExResolveNodeToValue be changed to fix this?
00265              */
00266             case ACPI_TYPE_DEVICE:
00267             case ACPI_TYPE_THERMAL:
00268 
00269                 AcpiUtAddReference (Op->Common.Node->Object);
00270 
00271                 /*lint -fallthrough */
00272             /*
00273              * For these types, we need the actual node, not the subobject.
00274              * The subobject got an extra reference count in ExResolveNodeToValue.
00275              */
00276             case ACPI_TYPE_MUTEX:
00277             case ACPI_TYPE_METHOD:
00278             case ACPI_TYPE_POWER:
00279             case ACPI_TYPE_PROCESSOR:
00280             case ACPI_TYPE_EVENT:
00281             case ACPI_TYPE_REGION:
00282 
00283                 /* We will create a reference object for these types below */
00284                 break;
00285 
00286             default:
00287                 /*
00288                  * All other types - the node was resolved to an actual
00289                  * object, we are done.
00290                  */
00291                 goto Exit;
00292             }
00293         }
00294     }
00295 
00296     /* Create and init a new internal ACPI object */
00297 
00298     ObjDesc = AcpiUtCreateInternalObject (
00299                 (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);
00300     if (!ObjDesc)
00301     {
00302         return_ACPI_STATUS (AE_NO_MEMORY);
00303     }
00304 
00305     Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode,
00306                 &ObjDesc);
00307     if (ACPI_FAILURE (Status))
00308     {
00309         AcpiUtRemoveReference (ObjDesc);
00310         return_ACPI_STATUS (Status);
00311     }
00312 
00313 Exit:
00314     *ObjDescPtr = ObjDesc;
00315     return_ACPI_STATUS (Status);
00316 }
00317 
00318 
00319 /*******************************************************************************
00320  *
00321  * FUNCTION:    AcpiDsBuildInternalBufferObj
00322  *
00323  * PARAMETERS:  WalkState       - Current walk state
00324  *              Op              - Parser object to be translated
00325  *              BufferLength    - Length of the buffer
00326  *              ObjDescPtr      - Where the ACPI internal object is returned
00327  *
00328  * RETURN:      Status
00329  *
00330  * DESCRIPTION: Translate a parser Op package object to the equivalent
00331  *              namespace object
00332  *
00333  ******************************************************************************/
00334 
00335 ACPI_STATUS
00336 AcpiDsBuildInternalBufferObj (
00337     ACPI_WALK_STATE         *WalkState,
00338     ACPI_PARSE_OBJECT       *Op,
00339     UINT32                  BufferLength,
00340     ACPI_OPERAND_OBJECT     **ObjDescPtr)
00341 {
00342     ACPI_PARSE_OBJECT       *Arg;
00343     ACPI_OPERAND_OBJECT     *ObjDesc;
00344     ACPI_PARSE_OBJECT       *ByteList;
00345     UINT32                  ByteListLength = 0;
00346 
00347 
00348     ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);
00349 
00350 
00351     /*
00352      * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
00353      * The buffer object already exists (from the NS node), otherwise it must
00354      * be created.
00355      */
00356     ObjDesc = *ObjDescPtr;
00357     if (!ObjDesc)
00358     {
00359         /* Create a new buffer object */
00360 
00361         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
00362         *ObjDescPtr = ObjDesc;
00363         if (!ObjDesc)
00364         {
00365             return_ACPI_STATUS (AE_NO_MEMORY);
00366         }
00367     }
00368 
00369     /*
00370      * Second arg is the buffer data (optional) ByteList can be either
00371      * individual bytes or a string initializer.  In either case, a
00372      * ByteList appears in the AML.
00373      */
00374     Arg = Op->Common.Value.Arg;         /* skip first arg */
00375 
00376     ByteList = Arg->Named.Next;
00377     if (ByteList)
00378     {
00379         if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
00380         {
00381             ACPI_ERROR ((AE_INFO,
00382                 "Expecting bytelist, found AML opcode 0x%X in op %p",
00383                 ByteList->Common.AmlOpcode, ByteList));
00384 
00385             AcpiUtRemoveReference (ObjDesc);
00386             return (AE_TYPE);
00387         }
00388 
00389         ByteListLength = (UINT32) ByteList->Common.Value.Integer;
00390     }
00391 
00392     /*
00393      * The buffer length (number of bytes) will be the larger of:
00394      * 1) The specified buffer length and
00395      * 2) The length of the initializer byte list
00396      */
00397     ObjDesc->Buffer.Length = BufferLength;
00398     if (ByteListLength > BufferLength)
00399     {
00400         ObjDesc->Buffer.Length = ByteListLength;
00401     }
00402 
00403     /* Allocate the buffer */
00404 
00405     if (ObjDesc->Buffer.Length == 0)
00406     {
00407         ObjDesc->Buffer.Pointer = NULL;
00408         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
00409             "Buffer defined with zero length in AML, creating\n"));
00410     }
00411     else
00412     {
00413         ObjDesc->Buffer.Pointer = ACPI_ALLOCATE_ZEROED (
00414                                         ObjDesc->Buffer.Length);
00415         if (!ObjDesc->Buffer.Pointer)
00416         {
00417             AcpiUtDeleteObjectDesc (ObjDesc);
00418             return_ACPI_STATUS (AE_NO_MEMORY);
00419         }
00420 
00421         /* Initialize buffer from the ByteList (if present) */
00422 
00423         if (ByteList)
00424         {
00425             ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
00426                          ByteListLength);
00427         }
00428     }
00429 
00430     ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
00431     Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
00432     return_ACPI_STATUS (AE_OK);
00433 }
00434 
00435 
00436 /*******************************************************************************
00437  *
00438  * FUNCTION:    AcpiDsBuildInternalPackageObj
00439  *
00440  * PARAMETERS:  WalkState       - Current walk state
00441  *              Op              - Parser object to be translated
00442  *              ElementCount    - Number of elements in the package - this is
00443  *                                the NumElements argument to Package()
00444  *              ObjDescPtr      - Where the ACPI internal object is returned
00445  *
00446  * RETURN:      Status
00447  *
00448  * DESCRIPTION: Translate a parser Op package object to the equivalent
00449  *              namespace object
00450  *
00451  * NOTE: The number of elements in the package will be always be the NumElements
00452  * count, regardless of the number of elements in the package list. If
00453  * NumElements is smaller, only that many package list elements are used.
00454  * if NumElements is larger, the Package object is padded out with
00455  * objects of type Uninitialized (as per ACPI spec.)
00456  *
00457  * Even though the ASL compilers do not allow NumElements to be smaller
00458  * than the Package list length (for the fixed length package opcode), some
00459  * BIOS code modifies the AML on the fly to adjust the NumElements, and
00460  * this code compensates for that. This also provides compatibility with
00461  * other AML interpreters.
00462  *
00463  ******************************************************************************/
00464 
00465 ACPI_STATUS
00466 AcpiDsBuildInternalPackageObj (
00467     ACPI_WALK_STATE         *WalkState,
00468     ACPI_PARSE_OBJECT       *Op,
00469     UINT32                  ElementCount,
00470     ACPI_OPERAND_OBJECT     **ObjDescPtr)
00471 {
00472     ACPI_PARSE_OBJECT       *Arg;
00473     ACPI_PARSE_OBJECT       *Parent;
00474     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
00475     ACPI_STATUS             Status = AE_OK;
00476     UINT32                  i;
00477     UINT16                  Index;
00478     UINT16                  ReferenceCount;
00479 
00480 
00481     ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
00482 
00483 
00484     /* Find the parent of a possibly nested package */
00485 
00486     Parent = Op->Common.Parent;
00487     while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
00488            (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
00489     {
00490         Parent = Parent->Common.Parent;
00491     }
00492 
00493     /*
00494      * If we are evaluating a Named package object "Name (xxxx, Package)",
00495      * the package object already exists, otherwise it must be created.
00496      */
00497     ObjDesc = *ObjDescPtr;
00498     if (!ObjDesc)
00499     {
00500         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
00501         *ObjDescPtr = ObjDesc;
00502         if (!ObjDesc)
00503         {
00504             return_ACPI_STATUS (AE_NO_MEMORY);
00505         }
00506 
00507         ObjDesc->Package.Node = Parent->Common.Node;
00508     }
00509 
00510     /*
00511      * Allocate the element array (array of pointers to the individual
00512      * objects) based on the NumElements parameter. Add an extra pointer slot
00513      * so that the list is always null terminated.
00514      */
00515     ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
00516         ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
00517 
00518     if (!ObjDesc->Package.Elements)
00519     {
00520         AcpiUtDeleteObjectDesc (ObjDesc);
00521         return_ACPI_STATUS (AE_NO_MEMORY);
00522     }
00523 
00524     ObjDesc->Package.Count = ElementCount;
00525 
00526     /*
00527      * Initialize the elements of the package, up to the NumElements count.
00528      * Package is automatically padded with uninitialized (NULL) elements
00529      * if NumElements is greater than the package list length. Likewise,
00530      * Package is truncated if NumElements is less than the list length.
00531      */
00532     Arg = Op->Common.Value.Arg;
00533     Arg = Arg->Common.Next;
00534     for (i = 0; Arg && (i < ElementCount); i++)
00535     {
00536         if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
00537         {
00538             if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
00539             {
00540                 /*
00541                  * A method reference "looks" to the parser to be a method
00542                  * invocation, so we special case it here
00543                  */
00544                 Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
00545                 Status = AcpiDsBuildInternalObject (WalkState, Arg,
00546                             &ObjDesc->Package.Elements[i]);
00547             }
00548             else
00549             {
00550                 /* This package element is already built, just get it */
00551 
00552                 ObjDesc->Package.Elements[i] =
00553                     ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
00554             }
00555         }
00556         else
00557         {
00558             Status = AcpiDsBuildInternalObject (WalkState, Arg,
00559                         &ObjDesc->Package.Elements[i]);
00560         }
00561 
00562         if (*ObjDescPtr)
00563         {
00564             /* Existing package, get existing reference count */
00565 
00566             ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
00567             if (ReferenceCount > 1)
00568             {
00569                 /* Make new element ref count match original ref count */
00570 
00571                 for (Index = 0; Index < (ReferenceCount - 1); Index++)
00572                 {
00573                     AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
00574                 }
00575             }
00576         }
00577 
00578         Arg = Arg->Common.Next;
00579     }
00580 
00581     /* Check for match between NumElements and actual length of PackageList */
00582 
00583     if (Arg)
00584     {
00585         /*
00586          * NumElements was exhausted, but there are remaining elements in the
00587          * PackageList. Truncate the package to NumElements.
00588          *
00589          * Note: technically, this is an error, from ACPI spec: "It is an error
00590          * for NumElements to be less than the number of elements in the
00591          * PackageList". However, we just print a message and
00592          * no exception is returned. This provides Windows compatibility. Some
00593          * BIOSs will alter the NumElements on the fly, creating this type
00594          * of ill-formed package object.
00595          */
00596         while (Arg)
00597         {
00598             /*
00599              * We must delete any package elements that were created earlier
00600              * and are not going to be used because of the package truncation.
00601              */
00602             if (Arg->Common.Node)
00603             {
00604                 AcpiUtRemoveReference (
00605                     ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
00606                 Arg->Common.Node = NULL;
00607             }
00608 
00609             /* Find out how many elements there really are */
00610 
00611             i++;
00612             Arg = Arg->Common.Next;
00613         }
00614 
00615         ACPI_INFO ((AE_INFO,
00616             "Actual Package length (%u) is larger than NumElements field (%u), truncated\n",
00617             i, ElementCount));
00618     }
00619     else if (i < ElementCount)
00620     {
00621         /*
00622          * Arg list (elements) was exhausted, but we did not reach NumElements count.
00623          * Note: this is not an error, the package is padded out with NULLs.
00624          */
00625         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
00626             "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
00627             i, ElementCount));
00628     }
00629 
00630     ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
00631     Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
00632     return_ACPI_STATUS (Status);
00633 }
00634 
00635 
00636 /*******************************************************************************
00637  *
00638  * FUNCTION:    AcpiDsCreateNode
00639  *
00640  * PARAMETERS:  WalkState       - Current walk state
00641  *              Node            - NS Node to be initialized
00642  *              Op              - Parser object to be translated
00643  *
00644  * RETURN:      Status
00645  *
00646  * DESCRIPTION: Create the object to be associated with a namespace node
00647  *
00648  ******************************************************************************/
00649 
00650 ACPI_STATUS
00651 AcpiDsCreateNode (
00652     ACPI_WALK_STATE         *WalkState,
00653     ACPI_NAMESPACE_NODE     *Node,
00654     ACPI_PARSE_OBJECT       *Op)
00655 {
00656     ACPI_STATUS             Status;
00657     ACPI_OPERAND_OBJECT     *ObjDesc;
00658 
00659 
00660     ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);
00661 
00662 
00663     /*
00664      * Because of the execution pass through the non-control-method
00665      * parts of the table, we can arrive here twice.  Only init
00666      * the named object node the first time through
00667      */
00668     if (AcpiNsGetAttachedObject (Node))
00669     {
00670         return_ACPI_STATUS (AE_OK);
00671     }
00672 
00673     if (!Op->Common.Value.Arg)
00674     {
00675         /* No arguments, there is nothing to do */
00676 
00677         return_ACPI_STATUS (AE_OK);
00678     }
00679 
00680     /* Build an internal object for the argument(s) */
00681 
00682     Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg,
00683                 &ObjDesc);
00684     if (ACPI_FAILURE (Status))
00685     {
00686         return_ACPI_STATUS (Status);
00687     }
00688 
00689     /* Re-type the object according to its argument */
00690 
00691     Node->Type = ObjDesc->Common.Type;
00692 
00693     /* Attach obj to node */
00694 
00695     Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);
00696 
00697     /* Remove local reference to the object */
00698 
00699     AcpiUtRemoveReference (ObjDesc);
00700     return_ACPI_STATUS (Status);
00701 }
00702 
00703 #endif /* ACPI_NO_METHOD_EXECUTION */
00704 
00705 
00706 /*******************************************************************************
00707  *
00708  * FUNCTION:    AcpiDsInitObjectFromOp
00709  *
00710  * PARAMETERS:  WalkState       - Current walk state
00711  *              Op              - Parser op used to init the internal object
00712  *              Opcode          - AML opcode associated with the object
00713  *              RetObjDesc      - Namespace object to be initialized
00714  *
00715  * RETURN:      Status
00716  *
00717  * DESCRIPTION: Initialize a namespace object from a parser Op and its
00718  *              associated arguments.  The namespace object is a more compact
00719  *              representation of the Op and its arguments.
00720  *
00721  ******************************************************************************/
00722 
00723 ACPI_STATUS
00724 AcpiDsInitObjectFromOp (
00725     ACPI_WALK_STATE         *WalkState,
00726     ACPI_PARSE_OBJECT       *Op,
00727     UINT16                  Opcode,
00728     ACPI_OPERAND_OBJECT     **RetObjDesc)
00729 {
00730     const ACPI_OPCODE_INFO  *OpInfo;
00731     ACPI_OPERAND_OBJECT     *ObjDesc;
00732     ACPI_STATUS             Status = AE_OK;
00733 
00734 
00735     ACPI_FUNCTION_TRACE (DsInitObjectFromOp);
00736 
00737 
00738     ObjDesc = *RetObjDesc;
00739     OpInfo = AcpiPsGetOpcodeInfo (Opcode);
00740     if (OpInfo->Class == AML_CLASS_UNKNOWN)
00741     {
00742         /* Unknown opcode */
00743 
00744         return_ACPI_STATUS (AE_TYPE);
00745     }
00746 
00747     /* Perform per-object initialization */
00748 
00749     switch (ObjDesc->Common.Type)
00750     {
00751     case ACPI_TYPE_BUFFER:
00752 
00753         /*
00754          * Defer evaluation of Buffer TermArg operand
00755          */
00756         ObjDesc->Buffer.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
00757                                         WalkState->Operands[0]);
00758         ObjDesc->Buffer.AmlStart  = Op->Named.Data;
00759         ObjDesc->Buffer.AmlLength = Op->Named.Length;
00760         break;
00761 
00762 
00763     case ACPI_TYPE_PACKAGE:
00764 
00765         /*
00766          * Defer evaluation of Package TermArg operand
00767          */
00768         ObjDesc->Package.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
00769                                         WalkState->Operands[0]);
00770         ObjDesc->Package.AmlStart  = Op->Named.Data;
00771         ObjDesc->Package.AmlLength = Op->Named.Length;
00772         break;
00773 
00774 
00775     case ACPI_TYPE_INTEGER:
00776 
00777         switch (OpInfo->Type)
00778         {
00779         case AML_TYPE_CONSTANT:
00780             /*
00781              * Resolve AML Constants here - AND ONLY HERE!
00782              * All constants are integers.
00783              * We mark the integer with a flag that indicates that it started
00784              * life as a constant -- so that stores to constants will perform
00785              * as expected (noop). ZeroOp is used as a placeholder for optional
00786              * target operands.
00787              */
00788             ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;
00789 
00790             switch (Opcode)
00791             {
00792             case AML_ZERO_OP:
00793 
00794                 ObjDesc->Integer.Value = 0;
00795                 break;
00796 
00797             case AML_ONE_OP:
00798 
00799                 ObjDesc->Integer.Value = 1;
00800                 break;
00801 
00802             case AML_ONES_OP:
00803 
00804                 ObjDesc->Integer.Value = ACPI_UINT64_MAX;
00805 
00806                 /* Truncate value if we are executing from a 32-bit ACPI table */
00807 
00808 #ifndef ACPI_NO_METHOD_EXECUTION
00809                 AcpiExTruncateFor32bitTable (ObjDesc);
00810 #endif
00811                 break;
00812 
00813             case AML_REVISION_OP:
00814 
00815                 ObjDesc->Integer.Value = ACPI_CA_VERSION;
00816                 break;
00817 
00818             default:
00819 
00820                 ACPI_ERROR ((AE_INFO,
00821                     "Unknown constant opcode 0x%X", Opcode));
00822                 Status = AE_AML_OPERAND_TYPE;
00823                 break;
00824             }
00825             break;
00826 
00827 
00828         case AML_TYPE_LITERAL:
00829 
00830             ObjDesc->Integer.Value = Op->Common.Value.Integer;
00831 #ifndef ACPI_NO_METHOD_EXECUTION
00832             AcpiExTruncateFor32bitTable (ObjDesc);
00833 #endif
00834             break;
00835 
00836 
00837         default:
00838             ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
00839                 OpInfo->Type));
00840             Status = AE_AML_OPERAND_TYPE;
00841             break;
00842         }
00843         break;
00844 
00845 
00846     case ACPI_TYPE_STRING:
00847 
00848         ObjDesc->String.Pointer = Op->Common.Value.String;
00849         ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Op->Common.Value.String);
00850 
00851         /*
00852          * The string is contained in the ACPI table, don't ever try
00853          * to delete it
00854          */
00855         ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
00856         break;
00857 
00858 
00859     case ACPI_TYPE_METHOD:
00860         break;
00861 
00862 
00863     case ACPI_TYPE_LOCAL_REFERENCE:
00864 
00865         switch (OpInfo->Type)
00866         {
00867         case AML_TYPE_LOCAL_VARIABLE:
00868 
00869             /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
00870 
00871             ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP;
00872             ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;
00873 
00874 #ifndef ACPI_NO_METHOD_EXECUTION
00875             Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,
00876                         ObjDesc->Reference.Value, WalkState,
00877                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
00878                             &ObjDesc->Reference.Object));
00879 #endif
00880             break;
00881 
00882 
00883         case AML_TYPE_METHOD_ARGUMENT:
00884 
00885             /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
00886 
00887             ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP;
00888             ObjDesc->Reference.Class = ACPI_REFCLASS_ARG;
00889 
00890 #ifndef ACPI_NO_METHOD_EXECUTION
00891             Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG,
00892                         ObjDesc->Reference.Value, WalkState,
00893                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
00894                             &ObjDesc->Reference.Object));
00895 #endif
00896             break;
00897 
00898         default: /* Object name or Debug object */
00899 
00900             switch (Op->Common.AmlOpcode)
00901             {
00902             case AML_INT_NAMEPATH_OP:
00903 
00904                 /* Node was saved in Op */
00905 
00906                 ObjDesc->Reference.Node = Op->Common.Node;
00907                 ObjDesc->Reference.Object = Op->Common.Node->Object;
00908                 ObjDesc->Reference.Class = ACPI_REFCLASS_NAME;
00909                 break;
00910 
00911             case AML_DEBUG_OP:
00912 
00913                 ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG;
00914                 break;
00915 
00916             default:
00917 
00918                 ACPI_ERROR ((AE_INFO,
00919                     "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
00920                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
00921             }
00922             break;
00923         }
00924         break;
00925 
00926 
00927     default:
00928 
00929         ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
00930             ObjDesc->Common.Type));
00931 
00932         Status = AE_AML_OPERAND_TYPE;
00933         break;
00934     }
00935 
00936     return_ACPI_STATUS (Status);
00937 }
00938 
00939 

Generated on Sun May 27 2012 04:27:15 for ReactOS by doxygen 1.7.6.1

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