Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:03

0001 /******************************************************************************
0002  *
0003  * Module Name: utcopy - Internal to external object translation utilities
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #include "acpi.h"
0153 #include "accommon.h"
0154 #include "acnamesp.h"
0155 
0156 
0157 #define _COMPONENT          ACPI_UTILITIES
0158         ACPI_MODULE_NAME    ("utcopy")
0159 
0160 /* Local prototypes */
0161 
0162 static ACPI_STATUS
0163 AcpiUtCopyIsimpleToEsimple (
0164     ACPI_OPERAND_OBJECT     *InternalObject,
0165     ACPI_OBJECT             *ExternalObject,
0166     UINT8                   *DataSpace,
0167     ACPI_SIZE               *BufferSpaceUsed);
0168 
0169 static ACPI_STATUS
0170 AcpiUtCopyIelementToIelement (
0171     UINT8                   ObjectType,
0172     ACPI_OPERAND_OBJECT     *SourceObject,
0173     ACPI_GENERIC_STATE      *State,
0174     void                    *Context);
0175 
0176 static ACPI_STATUS
0177 AcpiUtCopyIpackageToEpackage (
0178     ACPI_OPERAND_OBJECT     *InternalObject,
0179     UINT8                   *Buffer,
0180     ACPI_SIZE               *SpaceUsed);
0181 
0182 static ACPI_STATUS
0183 AcpiUtCopyEsimpleToIsimple(
0184     ACPI_OBJECT             *UserObj,
0185     ACPI_OPERAND_OBJECT     **ReturnObj);
0186 
0187 static ACPI_STATUS
0188 AcpiUtCopyEpackageToIpackage (
0189     ACPI_OBJECT             *ExternalObject,
0190     ACPI_OPERAND_OBJECT     **InternalObject);
0191 
0192 static ACPI_STATUS
0193 AcpiUtCopySimpleObject (
0194     ACPI_OPERAND_OBJECT     *SourceDesc,
0195     ACPI_OPERAND_OBJECT     *DestDesc);
0196 
0197 static ACPI_STATUS
0198 AcpiUtCopyIelementToEelement (
0199     UINT8                   ObjectType,
0200     ACPI_OPERAND_OBJECT     *SourceObject,
0201     ACPI_GENERIC_STATE      *State,
0202     void                    *Context);
0203 
0204 static ACPI_STATUS
0205 AcpiUtCopyIpackageToIpackage (
0206     ACPI_OPERAND_OBJECT     *SourceObj,
0207     ACPI_OPERAND_OBJECT     *DestObj,
0208     ACPI_WALK_STATE         *WalkState);
0209 
0210 
0211 /*******************************************************************************
0212  *
0213  * FUNCTION:    AcpiUtCopyIsimpleToEsimple
0214  *
0215  * PARAMETERS:  InternalObject      - Source object to be copied
0216  *              ExternalObject      - Where to return the copied object
0217  *              DataSpace           - Where object data is returned (such as
0218  *                                    buffer and string data)
0219  *              BufferSpaceUsed     - Length of DataSpace that was used
0220  *
0221  * RETURN:      Status
0222  *
0223  * DESCRIPTION: This function is called to copy a simple internal object to
0224  *              an external object.
0225  *
0226  *              The DataSpace buffer is assumed to have sufficient space for
0227  *              the object.
0228  *
0229  ******************************************************************************/
0230 
0231 static ACPI_STATUS
0232 AcpiUtCopyIsimpleToEsimple (
0233     ACPI_OPERAND_OBJECT     *InternalObject,
0234     ACPI_OBJECT             *ExternalObject,
0235     UINT8                   *DataSpace,
0236     ACPI_SIZE               *BufferSpaceUsed)
0237 {
0238     ACPI_STATUS             Status = AE_OK;
0239 
0240 
0241     ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple);
0242 
0243 
0244     *BufferSpaceUsed = 0;
0245 
0246     /*
0247      * Check for NULL object case (could be an uninitialized
0248      * package element)
0249      */
0250     if (!InternalObject)
0251     {
0252         return_ACPI_STATUS (AE_OK);
0253     }
0254 
0255     /* Always clear the external object */
0256 
0257     memset (ExternalObject, 0, sizeof (ACPI_OBJECT));
0258 
0259     /*
0260      * In general, the external object will be the same type as
0261      * the internal object
0262      */
0263     ExternalObject->Type = InternalObject->Common.Type;
0264 
0265     /* However, only a limited number of external types are supported */
0266 
0267     switch (InternalObject->Common.Type)
0268     {
0269     case ACPI_TYPE_STRING:
0270 
0271         ExternalObject->String.Pointer = (char *) DataSpace;
0272         ExternalObject->String.Length  = InternalObject->String.Length;
0273         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
0274             (ACPI_SIZE) InternalObject->String.Length + 1);
0275 
0276         memcpy ((void *) DataSpace,
0277             (void *) InternalObject->String.Pointer,
0278             (ACPI_SIZE) InternalObject->String.Length + 1);
0279         break;
0280 
0281     case ACPI_TYPE_BUFFER:
0282 
0283         ExternalObject->Buffer.Pointer = DataSpace;
0284         ExternalObject->Buffer.Length  = InternalObject->Buffer.Length;
0285         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
0286             InternalObject->String.Length);
0287 
0288         memcpy ((void *) DataSpace,
0289             (void *) InternalObject->Buffer.Pointer,
0290             InternalObject->Buffer.Length);
0291         break;
0292 
0293     case ACPI_TYPE_INTEGER:
0294 
0295         ExternalObject->Integer.Value = InternalObject->Integer.Value;
0296         break;
0297 
0298     case ACPI_TYPE_LOCAL_REFERENCE:
0299 
0300         /* This is an object reference. */
0301 
0302         switch (InternalObject->Reference.Class)
0303         {
0304         case ACPI_REFCLASS_NAME:
0305             /*
0306              * For namepath, return the object handle ("reference")
0307              * We are referring to the namespace node
0308              */
0309             ExternalObject->Reference.Handle =
0310                 InternalObject->Reference.Node;
0311             ExternalObject->Reference.ActualType =
0312                 AcpiNsGetType (InternalObject->Reference.Node);
0313             break;
0314 
0315         default:
0316 
0317             /* All other reference types are unsupported */
0318 
0319             return_ACPI_STATUS (AE_TYPE);
0320         }
0321         break;
0322 
0323     case ACPI_TYPE_PROCESSOR:
0324 
0325         ExternalObject->Processor.ProcId =
0326             InternalObject->Processor.ProcId;
0327         ExternalObject->Processor.PblkAddress =
0328             InternalObject->Processor.Address;
0329         ExternalObject->Processor.PblkLength =
0330             InternalObject->Processor.Length;
0331         break;
0332 
0333     case ACPI_TYPE_POWER:
0334 
0335         ExternalObject->PowerResource.SystemLevel =
0336             InternalObject->PowerResource.SystemLevel;
0337 
0338         ExternalObject->PowerResource.ResourceOrder =
0339             InternalObject->PowerResource.ResourceOrder;
0340         break;
0341 
0342     default:
0343         /*
0344          * There is no corresponding external object type
0345          */
0346         ACPI_ERROR ((AE_INFO,
0347             "Unsupported object type, cannot convert to external object: %s",
0348             AcpiUtGetTypeName (InternalObject->Common.Type)));
0349 
0350         return_ACPI_STATUS (AE_SUPPORT);
0351     }
0352 
0353     return_ACPI_STATUS (Status);
0354 }
0355 
0356 
0357 /*******************************************************************************
0358  *
0359  * FUNCTION:    AcpiUtCopyIelementToEelement
0360  *
0361  * PARAMETERS:  ACPI_PKG_CALLBACK
0362  *
0363  * RETURN:      Status
0364  *
0365  * DESCRIPTION: Copy one package element to another package element
0366  *
0367  ******************************************************************************/
0368 
0369 static ACPI_STATUS
0370 AcpiUtCopyIelementToEelement (
0371     UINT8                   ObjectType,
0372     ACPI_OPERAND_OBJECT     *SourceObject,
0373     ACPI_GENERIC_STATE      *State,
0374     void                    *Context)
0375 {
0376     ACPI_STATUS             Status = AE_OK;
0377     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
0378     ACPI_SIZE               ObjectSpace;
0379     UINT32                  ThisIndex;
0380     ACPI_OBJECT             *TargetObject;
0381 
0382 
0383     ACPI_FUNCTION_ENTRY ();
0384 
0385 
0386     ThisIndex = State->Pkg.Index;
0387     TargetObject = (ACPI_OBJECT *) &((ACPI_OBJECT *)
0388         (State->Pkg.DestObject))->Package.Elements[ThisIndex];
0389 
0390     switch (ObjectType)
0391     {
0392     case ACPI_COPY_TYPE_SIMPLE:
0393         /*
0394          * This is a simple or null object
0395          */
0396         Status = AcpiUtCopyIsimpleToEsimple (SourceObject,
0397             TargetObject, Info->FreeSpace, &ObjectSpace);
0398         if (ACPI_FAILURE (Status))
0399         {
0400             return (Status);
0401         }
0402         break;
0403 
0404     case ACPI_COPY_TYPE_PACKAGE:
0405         /*
0406          * Build the package object
0407          */
0408         TargetObject->Type = ACPI_TYPE_PACKAGE;
0409         TargetObject->Package.Count = SourceObject->Package.Count;
0410         TargetObject->Package.Elements =
0411             ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace);
0412 
0413         /*
0414          * Pass the new package object back to the package walk routine
0415          */
0416         State->Pkg.ThisTargetObj = TargetObject;
0417 
0418         /*
0419          * Save space for the array of objects (Package elements)
0420          * update the buffer length counter
0421          */
0422         ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD (
0423             (ACPI_SIZE) TargetObject->Package.Count *
0424             sizeof (ACPI_OBJECT));
0425         break;
0426 
0427     default:
0428 
0429         return (AE_BAD_PARAMETER);
0430     }
0431 
0432     Info->FreeSpace += ObjectSpace;
0433     Info->Length += ObjectSpace;
0434     return (Status);
0435 }
0436 
0437 
0438 /*******************************************************************************
0439  *
0440  * FUNCTION:    AcpiUtCopyIpackageToEpackage
0441  *
0442  * PARAMETERS:  InternalObject      - Pointer to the object we are returning
0443  *              Buffer              - Where the object is returned
0444  *              SpaceUsed           - Where the object length is returned
0445  *
0446  * RETURN:      Status
0447  *
0448  * DESCRIPTION: This function is called to place a package object in a user
0449  *              buffer. A package object by definition contains other objects.
0450  *
0451  *              The buffer is assumed to have sufficient space for the object.
0452  *              The caller must have verified the buffer length needed using
0453  *              the AcpiUtGetObjectSize function before calling this function.
0454  *
0455  ******************************************************************************/
0456 
0457 static ACPI_STATUS
0458 AcpiUtCopyIpackageToEpackage (
0459     ACPI_OPERAND_OBJECT     *InternalObject,
0460     UINT8                   *Buffer,
0461     ACPI_SIZE               *SpaceUsed)
0462 {
0463     ACPI_OBJECT             *ExternalObject;
0464     ACPI_STATUS             Status;
0465     ACPI_PKG_INFO           Info;
0466 
0467 
0468     ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage);
0469 
0470 
0471     /*
0472      * First package at head of the buffer
0473      */
0474     ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer);
0475 
0476     /*
0477      * Free space begins right after the first package
0478      */
0479     Info.Length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
0480     Info.FreeSpace = Buffer +
0481         ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
0482     Info.ObjectSpace = 0;
0483     Info.NumPackages = 1;
0484 
0485     ExternalObject->Type = InternalObject->Common.Type;
0486     ExternalObject->Package.Count = InternalObject->Package.Count;
0487     ExternalObject->Package.Elements =
0488         ACPI_CAST_PTR (ACPI_OBJECT, Info.FreeSpace);
0489 
0490     /*
0491      * Leave room for an array of ACPI_OBJECTS in the buffer
0492      * and move the free space past it
0493      */
0494     Info.Length += (ACPI_SIZE) ExternalObject->Package.Count *
0495         ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
0496     Info.FreeSpace += ExternalObject->Package.Count *
0497         ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
0498 
0499     Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject,
0500         AcpiUtCopyIelementToEelement, &Info);
0501 
0502     *SpaceUsed = Info.Length;
0503     return_ACPI_STATUS (Status);
0504 }
0505 
0506 
0507 /*******************************************************************************
0508  *
0509  * FUNCTION:    AcpiUtCopyIobjectToEobject
0510  *
0511  * PARAMETERS:  InternalObject      - The internal object to be converted
0512  *              RetBuffer           - Where the object is returned
0513  *
0514  * RETURN:      Status
0515  *
0516  * DESCRIPTION: This function is called to build an API object to be returned
0517  *              to the caller.
0518  *
0519  ******************************************************************************/
0520 
0521 ACPI_STATUS
0522 AcpiUtCopyIobjectToEobject (
0523     ACPI_OPERAND_OBJECT     *InternalObject,
0524     ACPI_BUFFER             *RetBuffer)
0525 {
0526     ACPI_STATUS             Status;
0527 
0528 
0529     ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject);
0530 
0531 
0532     if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)
0533     {
0534         /*
0535          * Package object:  Copy all subobjects (including
0536          * nested packages)
0537          */
0538         Status = AcpiUtCopyIpackageToEpackage (InternalObject,
0539             RetBuffer->Pointer, &RetBuffer->Length);
0540     }
0541     else
0542     {
0543         /*
0544          * Build a simple object (no nested objects)
0545          */
0546         Status = AcpiUtCopyIsimpleToEsimple (InternalObject,
0547             ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer),
0548             ACPI_ADD_PTR (UINT8, RetBuffer->Pointer,
0549                 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
0550             &RetBuffer->Length);
0551         /*
0552          * build simple does not include the object size in the length
0553          * so we add it in here
0554          */
0555         RetBuffer->Length += sizeof (ACPI_OBJECT);
0556     }
0557 
0558     return_ACPI_STATUS (Status);
0559 }
0560 
0561 
0562 /*******************************************************************************
0563  *
0564  * FUNCTION:    AcpiUtCopyEsimpleToIsimple
0565  *
0566  * PARAMETERS:  ExternalObject      - The external object to be converted
0567  *              RetInternalObject   - Where the internal object is returned
0568  *
0569  * RETURN:      Status
0570  *
0571  * DESCRIPTION: This function copies an external object to an internal one.
0572  *              NOTE: Pointers can be copied, we don't need to copy data.
0573  *              (The pointers have to be valid in our address space no matter
0574  *              what we do with them!)
0575  *
0576  ******************************************************************************/
0577 
0578 static ACPI_STATUS
0579 AcpiUtCopyEsimpleToIsimple (
0580     ACPI_OBJECT             *ExternalObject,
0581     ACPI_OPERAND_OBJECT     **RetInternalObject)
0582 {
0583     ACPI_OPERAND_OBJECT     *InternalObject;
0584 
0585 
0586     ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple);
0587 
0588 
0589     /*
0590      * Simple types supported are: String, Buffer, Integer
0591      */
0592     switch (ExternalObject->Type)
0593     {
0594     case ACPI_TYPE_STRING:
0595     case ACPI_TYPE_BUFFER:
0596     case ACPI_TYPE_INTEGER:
0597     case ACPI_TYPE_LOCAL_REFERENCE:
0598 
0599         InternalObject = AcpiUtCreateInternalObject (
0600             (UINT8) ExternalObject->Type);
0601         if (!InternalObject)
0602         {
0603             return_ACPI_STATUS (AE_NO_MEMORY);
0604         }
0605         break;
0606 
0607     case ACPI_TYPE_ANY: /* This is the case for a NULL object */
0608 
0609         *RetInternalObject = NULL;
0610         return_ACPI_STATUS (AE_OK);
0611 
0612     default:
0613 
0614         /* All other types are not supported */
0615 
0616         ACPI_ERROR ((AE_INFO,
0617             "Unsupported object type, cannot convert to internal object: %s",
0618             AcpiUtGetTypeName (ExternalObject->Type)));
0619 
0620         return_ACPI_STATUS (AE_SUPPORT);
0621     }
0622 
0623 
0624     /* Must COPY string and buffer contents */
0625 
0626     switch (ExternalObject->Type)
0627     {
0628     case ACPI_TYPE_STRING:
0629 
0630         InternalObject->String.Pointer =
0631             ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
0632                 ExternalObject->String.Length + 1);
0633 
0634         if (!InternalObject->String.Pointer)
0635         {
0636             goto ErrorExit;
0637         }
0638 
0639         memcpy (InternalObject->String.Pointer,
0640             ExternalObject->String.Pointer,
0641             ExternalObject->String.Length);
0642 
0643         InternalObject->String.Length = ExternalObject->String.Length;
0644         break;
0645 
0646     case ACPI_TYPE_BUFFER:
0647 
0648         InternalObject->Buffer.Pointer =
0649             ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length);
0650         if (!InternalObject->Buffer.Pointer)
0651         {
0652             goto ErrorExit;
0653         }
0654 
0655         memcpy (InternalObject->Buffer.Pointer,
0656             ExternalObject->Buffer.Pointer,
0657             ExternalObject->Buffer.Length);
0658 
0659         InternalObject->Buffer.Length = ExternalObject->Buffer.Length;
0660 
0661         /* Mark buffer data valid */
0662 
0663         InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID;
0664         break;
0665 
0666     case ACPI_TYPE_INTEGER:
0667 
0668         InternalObject->Integer.Value = ExternalObject->Integer.Value;
0669         break;
0670 
0671     case ACPI_TYPE_LOCAL_REFERENCE:
0672 
0673         /* An incoming reference is defined to be a namespace node */
0674 
0675         InternalObject->Reference.Class = ACPI_REFCLASS_REFOF;
0676         InternalObject->Reference.Object = ExternalObject->Reference.Handle;
0677         break;
0678 
0679     default:
0680 
0681         /* Other types can't get here */
0682 
0683         break;
0684     }
0685 
0686     *RetInternalObject = InternalObject;
0687     return_ACPI_STATUS (AE_OK);
0688 
0689 
0690 ErrorExit:
0691     AcpiUtRemoveReference (InternalObject);
0692     return_ACPI_STATUS (AE_NO_MEMORY);
0693 }
0694 
0695 
0696 /*******************************************************************************
0697  *
0698  * FUNCTION:    AcpiUtCopyEpackageToIpackage
0699  *
0700  * PARAMETERS:  ExternalObject      - The external object to be converted
0701  *              InternalObject      - Where the internal object is returned
0702  *
0703  * RETURN:      Status
0704  *
0705  * DESCRIPTION: Copy an external package object to an internal package.
0706  *              Handles nested packages.
0707  *
0708  ******************************************************************************/
0709 
0710 static ACPI_STATUS
0711 AcpiUtCopyEpackageToIpackage (
0712     ACPI_OBJECT             *ExternalObject,
0713     ACPI_OPERAND_OBJECT     **InternalObject)
0714 {
0715     ACPI_STATUS             Status = AE_OK;
0716     ACPI_OPERAND_OBJECT     *PackageObject;
0717     ACPI_OPERAND_OBJECT     **PackageElements;
0718     UINT32                  i;
0719 
0720 
0721     ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage);
0722 
0723 
0724     /* Create the package object */
0725 
0726     PackageObject = AcpiUtCreatePackageObject (
0727         ExternalObject->Package.Count);
0728     if (!PackageObject)
0729     {
0730         return_ACPI_STATUS (AE_NO_MEMORY);
0731     }
0732 
0733     PackageElements = PackageObject->Package.Elements;
0734 
0735     /*
0736      * Recursive implementation. Probably ok, since nested external
0737      * packages as parameters should be very rare.
0738      */
0739     for (i = 0; i < ExternalObject->Package.Count; i++)
0740     {
0741         Status = AcpiUtCopyEobjectToIobject (
0742             &ExternalObject->Package.Elements[i],
0743             &PackageElements[i]);
0744         if (ACPI_FAILURE (Status))
0745         {
0746             /* Truncate package and delete it */
0747 
0748             PackageObject->Package.Count = i;
0749             PackageElements[i] = NULL;
0750             AcpiUtRemoveReference (PackageObject);
0751             return_ACPI_STATUS (Status);
0752         }
0753     }
0754 
0755     /* Mark package data valid */
0756 
0757     PackageObject->Package.Flags |= AOPOBJ_DATA_VALID;
0758 
0759     *InternalObject = PackageObject;
0760     return_ACPI_STATUS (Status);
0761 }
0762 
0763 
0764 /*******************************************************************************
0765  *
0766  * FUNCTION:    AcpiUtCopyEobjectToIobject
0767  *
0768  * PARAMETERS:  ExternalObject      - The external object to be converted
0769  *              InternalObject      - Where the internal object is returned
0770  *
0771  * RETURN:      Status
0772  *
0773  * DESCRIPTION: Converts an external object to an internal object.
0774  *
0775  ******************************************************************************/
0776 
0777 ACPI_STATUS
0778 AcpiUtCopyEobjectToIobject (
0779     ACPI_OBJECT             *ExternalObject,
0780     ACPI_OPERAND_OBJECT     **InternalObject)
0781 {
0782     ACPI_STATUS             Status;
0783 
0784 
0785     ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject);
0786 
0787 
0788     if (ExternalObject->Type == ACPI_TYPE_PACKAGE)
0789     {
0790         Status = AcpiUtCopyEpackageToIpackage (
0791             ExternalObject, InternalObject);
0792     }
0793     else
0794     {
0795         /*
0796          * Build a simple object (no nested objects)
0797          */
0798         Status = AcpiUtCopyEsimpleToIsimple (ExternalObject,
0799             InternalObject);
0800     }
0801 
0802     return_ACPI_STATUS (Status);
0803 }
0804 
0805 
0806 /*******************************************************************************
0807  *
0808  * FUNCTION:    AcpiUtCopySimpleObject
0809  *
0810  * PARAMETERS:  SourceDesc          - The internal object to be copied
0811  *              DestDesc            - New target object
0812  *
0813  * RETURN:      Status
0814  *
0815  * DESCRIPTION: Simple copy of one internal object to another. Reference count
0816  *              of the destination object is preserved.
0817  *
0818  ******************************************************************************/
0819 
0820 static ACPI_STATUS
0821 AcpiUtCopySimpleObject (
0822     ACPI_OPERAND_OBJECT     *SourceDesc,
0823     ACPI_OPERAND_OBJECT     *DestDesc)
0824 {
0825     UINT16                  ReferenceCount;
0826     ACPI_OPERAND_OBJECT     *NextObject;
0827     ACPI_STATUS             Status;
0828     ACPI_SIZE               CopySize;
0829 
0830 
0831     /* Save fields from destination that we don't want to overwrite */
0832 
0833     ReferenceCount = DestDesc->Common.ReferenceCount;
0834     NextObject = DestDesc->Common.NextObject;
0835 
0836     /*
0837      * Copy the entire source object over the destination object.
0838      * Note: Source can be either an operand object or namespace node.
0839      */
0840     CopySize = sizeof (ACPI_OPERAND_OBJECT);
0841     if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
0842     {
0843         CopySize = sizeof (ACPI_NAMESPACE_NODE);
0844     }
0845 
0846     memcpy (ACPI_CAST_PTR (char, DestDesc),
0847         ACPI_CAST_PTR (char, SourceDesc), CopySize);
0848 
0849     /* Restore the saved fields */
0850 
0851     DestDesc->Common.ReferenceCount = ReferenceCount;
0852     DestDesc->Common.NextObject = NextObject;
0853 
0854     /* New object is not static, regardless of source */
0855 
0856     DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
0857 
0858     /* Handle the objects with extra data */
0859 
0860     switch (DestDesc->Common.Type)
0861     {
0862     case ACPI_TYPE_BUFFER:
0863         /*
0864          * Allocate and copy the actual buffer if and only if:
0865          * 1) There is a valid buffer pointer
0866          * 2) The buffer has a length > 0
0867          */
0868         if ((SourceDesc->Buffer.Pointer) &&
0869             (SourceDesc->Buffer.Length))
0870         {
0871             DestDesc->Buffer.Pointer =
0872                 ACPI_ALLOCATE (SourceDesc->Buffer.Length);
0873             if (!DestDesc->Buffer.Pointer)
0874             {
0875                 return (AE_NO_MEMORY);
0876             }
0877 
0878             /* Copy the actual buffer data */
0879 
0880             memcpy (DestDesc->Buffer.Pointer,
0881                 SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
0882         }
0883         break;
0884 
0885     case ACPI_TYPE_STRING:
0886         /*
0887          * Allocate and copy the actual string if and only if:
0888          * 1) There is a valid string pointer
0889          * (Pointer to a NULL string is allowed)
0890          */
0891         if (SourceDesc->String.Pointer)
0892         {
0893             DestDesc->String.Pointer =
0894                 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
0895             if (!DestDesc->String.Pointer)
0896             {
0897                 return (AE_NO_MEMORY);
0898             }
0899 
0900             /* Copy the actual string data */
0901 
0902             memcpy (DestDesc->String.Pointer, SourceDesc->String.Pointer,
0903                 (ACPI_SIZE) SourceDesc->String.Length + 1);
0904         }
0905         break;
0906 
0907     case ACPI_TYPE_LOCAL_REFERENCE:
0908         /*
0909          * We copied the reference object, so we now must add a reference
0910          * to the object pointed to by the reference
0911          *
0912          * DDBHandle reference (from Load/LoadTable) is a special reference,
0913          * it does not have a Reference.Object, so does not need to
0914          * increase the reference count
0915          */
0916         if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
0917         {
0918             break;
0919         }
0920 
0921         AcpiUtAddReference (SourceDesc->Reference.Object);
0922         break;
0923 
0924     case ACPI_TYPE_REGION:
0925         /*
0926          * We copied the Region Handler, so we now must add a reference
0927          */
0928         if (DestDesc->Region.Handler)
0929         {
0930             AcpiUtAddReference (DestDesc->Region.Handler);
0931         }
0932         break;
0933 
0934     /*
0935      * For Mutex and Event objects, we cannot simply copy the underlying
0936      * OS object. We must create a new one.
0937      */
0938     case ACPI_TYPE_MUTEX:
0939 
0940         Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
0941         if (ACPI_FAILURE (Status))
0942         {
0943             return (Status);
0944         }
0945         break;
0946 
0947     case ACPI_TYPE_EVENT:
0948 
0949         Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
0950             &DestDesc->Event.OsSemaphore);
0951         if (ACPI_FAILURE (Status))
0952         {
0953             return (Status);
0954         }
0955         break;
0956 
0957     default:
0958 
0959         /* Nothing to do for other simple objects */
0960 
0961         break;
0962     }
0963 
0964     return (AE_OK);
0965 }
0966 
0967 
0968 /*******************************************************************************
0969  *
0970  * FUNCTION:    AcpiUtCopyIelementToIelement
0971  *
0972  * PARAMETERS:  ACPI_PKG_CALLBACK
0973  *
0974  * RETURN:      Status
0975  *
0976  * DESCRIPTION: Copy one package element to another package element
0977  *
0978  ******************************************************************************/
0979 
0980 static ACPI_STATUS
0981 AcpiUtCopyIelementToIelement (
0982     UINT8                   ObjectType,
0983     ACPI_OPERAND_OBJECT     *SourceObject,
0984     ACPI_GENERIC_STATE      *State,
0985     void                    *Context)
0986 {
0987     ACPI_STATUS             Status = AE_OK;
0988     UINT32                  ThisIndex;
0989     ACPI_OPERAND_OBJECT     **ThisTargetPtr;
0990     ACPI_OPERAND_OBJECT     *TargetObject;
0991 
0992 
0993     ACPI_FUNCTION_ENTRY ();
0994 
0995 
0996     ThisIndex = State->Pkg.Index;
0997     ThisTargetPtr = (ACPI_OPERAND_OBJECT **)
0998         &State->Pkg.DestObject->Package.Elements[ThisIndex];
0999 
1000     switch (ObjectType)
1001     {
1002     case ACPI_COPY_TYPE_SIMPLE:
1003 
1004         /* A null source object indicates a (legal) null package element */
1005 
1006         if (SourceObject)
1007         {
1008             /*
1009              * This is a simple object, just copy it
1010              */
1011             TargetObject = AcpiUtCreateInternalObject (
1012                 SourceObject->Common.Type);
1013             if (!TargetObject)
1014             {
1015                 return (AE_NO_MEMORY);
1016             }
1017 
1018             Status = AcpiUtCopySimpleObject (SourceObject, TargetObject);
1019             if (ACPI_FAILURE (Status))
1020             {
1021                 goto ErrorExit;
1022             }
1023 
1024             *ThisTargetPtr = TargetObject;
1025         }
1026         else
1027         {
1028             /* Pass through a null element */
1029 
1030             *ThisTargetPtr = NULL;
1031         }
1032         break;
1033 
1034     case ACPI_COPY_TYPE_PACKAGE:
1035         /*
1036          * This object is a package - go down another nesting level
1037          * Create and build the package object
1038          */
1039         TargetObject = AcpiUtCreatePackageObject (
1040             SourceObject->Package.Count);
1041         if (!TargetObject)
1042         {
1043             return (AE_NO_MEMORY);
1044         }
1045 
1046         TargetObject->Common.Flags = SourceObject->Common.Flags;
1047 
1048         /* Pass the new package object back to the package walk routine */
1049 
1050         State->Pkg.ThisTargetObj = TargetObject;
1051 
1052         /* Store the object pointer in the parent package object */
1053 
1054         *ThisTargetPtr = TargetObject;
1055         break;
1056 
1057     default:
1058 
1059         return (AE_BAD_PARAMETER);
1060     }
1061 
1062     return (Status);
1063 
1064 ErrorExit:
1065     AcpiUtRemoveReference (TargetObject);
1066     return (Status);
1067 }
1068 
1069 
1070 /*******************************************************************************
1071  *
1072  * FUNCTION:    AcpiUtCopyIpackageToIpackage
1073  *
1074  * PARAMETERS:  SourceObj       - Pointer to the source package object
1075  *              DestObj         - Where the internal object is returned
1076  *              WalkState       - Current Walk state descriptor
1077  *
1078  * RETURN:      Status
1079  *
1080  * DESCRIPTION: This function is called to copy an internal package object
1081  *              into another internal package object.
1082  *
1083  ******************************************************************************/
1084 
1085 static ACPI_STATUS
1086 AcpiUtCopyIpackageToIpackage (
1087     ACPI_OPERAND_OBJECT     *SourceObj,
1088     ACPI_OPERAND_OBJECT     *DestObj,
1089     ACPI_WALK_STATE         *WalkState)
1090 {
1091     ACPI_STATUS             Status = AE_OK;
1092 
1093 
1094     ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage);
1095 
1096 
1097     DestObj->Common.Type = SourceObj->Common.Type;
1098     DestObj->Common.Flags = SourceObj->Common.Flags;
1099     DestObj->Package.Count = SourceObj->Package.Count;
1100 
1101     /*
1102      * Create the object array and walk the source package tree
1103      */
1104     DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED (
1105         ((ACPI_SIZE) SourceObj->Package.Count + 1) *
1106         sizeof (void *));
1107     if (!DestObj->Package.Elements)
1108     {
1109         ACPI_ERROR ((AE_INFO, "Package allocation failure"));
1110         return_ACPI_STATUS (AE_NO_MEMORY);
1111     }
1112 
1113     /*
1114      * Copy the package element-by-element by walking the package "tree".
1115      * This handles nested packages of arbitrary depth.
1116      */
1117     Status = AcpiUtWalkPackageTree (SourceObj, DestObj,
1118         AcpiUtCopyIelementToIelement, WalkState);
1119     if (ACPI_FAILURE (Status))
1120     {
1121         /* On failure, delete the destination package object */
1122 
1123         AcpiUtRemoveReference (DestObj);
1124     }
1125 
1126     return_ACPI_STATUS (Status);
1127 }
1128 
1129 
1130 /*******************************************************************************
1131  *
1132  * FUNCTION:    AcpiUtCopyIobjectToIobject
1133  *
1134  * PARAMETERS:  SourceDesc          - The internal object to be copied
1135  *              DestDesc            - Where the copied object is returned
1136  *              WalkState           - Current walk state
1137  *
1138  * RETURN:      Status
1139  *
1140  * DESCRIPTION: Copy an internal object to a new internal object
1141  *
1142  ******************************************************************************/
1143 
1144 ACPI_STATUS
1145 AcpiUtCopyIobjectToIobject (
1146     ACPI_OPERAND_OBJECT     *SourceDesc,
1147     ACPI_OPERAND_OBJECT     **DestDesc,
1148     ACPI_WALK_STATE         *WalkState)
1149 {
1150     ACPI_STATUS             Status = AE_OK;
1151 
1152 
1153     ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject);
1154 
1155 
1156     /* Create the top level object */
1157 
1158     *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type);
1159     if (!*DestDesc)
1160     {
1161         return_ACPI_STATUS (AE_NO_MEMORY);
1162     }
1163 
1164     /* Copy the object and possible subobjects */
1165 
1166     if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE)
1167     {
1168         Status = AcpiUtCopyIpackageToIpackage (
1169             SourceDesc, *DestDesc, WalkState);
1170     }
1171     else
1172     {
1173         Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc);
1174     }
1175 
1176     /* Delete the allocated object if copy failed */
1177 
1178     if (ACPI_FAILURE (Status))
1179     {
1180         AcpiUtRemoveReference (*DestDesc);
1181     }
1182 
1183     return_ACPI_STATUS (Status);
1184 }