1*3446Smrj /****************************************************************************** 2*3446Smrj * 3*3446Smrj * Module Name: utobject - ACPI object create/delete/size/cache routines 4*3446Smrj * $Revision: 1.103 $ 5*3446Smrj * 6*3446Smrj *****************************************************************************/ 7*3446Smrj 8*3446Smrj /****************************************************************************** 9*3446Smrj * 10*3446Smrj * 1. Copyright Notice 11*3446Smrj * 12*3446Smrj * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp. 13*3446Smrj * All rights reserved. 14*3446Smrj * 15*3446Smrj * 2. License 16*3446Smrj * 17*3446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 18*3446Smrj * rights. You may have additional license terms from the party that provided 19*3446Smrj * you this software, covering your right to use that party's intellectual 20*3446Smrj * property rights. 21*3446Smrj * 22*3446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23*3446Smrj * copy of the source code appearing in this file ("Covered Code") an 24*3446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25*3446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 26*3446Smrj * make derivatives, distribute, use and display any portion of the Covered 27*3446Smrj * Code in any form, with the right to sublicense such rights; and 28*3446Smrj * 29*3446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30*3446Smrj * license (with the right to sublicense), under only those claims of Intel 31*3446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 32*3446Smrj * offer to sell, and import the Covered Code and derivative works thereof 33*3446Smrj * solely to the minimum extent necessary to exercise the above copyright 34*3446Smrj * license, and in no event shall the patent license extend to any additions 35*3446Smrj * to or modifications of the Original Intel Code. No other license or right 36*3446Smrj * is granted directly or by implication, estoppel or otherwise; 37*3446Smrj * 38*3446Smrj * The above copyright and patent license is granted only if the following 39*3446Smrj * conditions are met: 40*3446Smrj * 41*3446Smrj * 3. Conditions 42*3446Smrj * 43*3446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44*3446Smrj * Redistribution of source code of any substantial portion of the Covered 45*3446Smrj * Code or modification with rights to further distribute source must include 46*3446Smrj * the above Copyright Notice, the above License, this list of Conditions, 47*3446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 48*3446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 49*3446Smrj * contain a file documenting the changes Licensee made to create that Covered 50*3446Smrj * Code and the date of any change. Licensee must include in that file the 51*3446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 52*3446Smrj * must include a prominent statement that the modification is derived, 53*3446Smrj * directly or indirectly, from Original Intel Code. 54*3446Smrj * 55*3446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56*3446Smrj * Redistribution of source code of any substantial portion of the Covered 57*3446Smrj * Code or modification without rights to further distribute source must 58*3446Smrj * include the following Disclaimer and Export Compliance provision in the 59*3446Smrj * documentation and/or other materials provided with distribution. In 60*3446Smrj * addition, Licensee may not authorize further sublicense of source of any 61*3446Smrj * portion of the Covered Code, and must include terms to the effect that the 62*3446Smrj * license from Licensee to its licensee is limited to the intellectual 63*3446Smrj * property embodied in the software Licensee provides to its licensee, and 64*3446Smrj * not to intellectual property embodied in modifications its licensee may 65*3446Smrj * make. 66*3446Smrj * 67*3446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 68*3446Smrj * substantial portion of the Covered Code or modification must reproduce the 69*3446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 70*3446Smrj * provision in the documentation and/or other materials provided with the 71*3446Smrj * distribution. 72*3446Smrj * 73*3446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 74*3446Smrj * Intel Code. 75*3446Smrj * 76*3446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77*3446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 78*3446Smrj * other dealings in products derived from or relating to the Covered Code 79*3446Smrj * without prior written authorization from Intel. 80*3446Smrj * 81*3446Smrj * 4. Disclaimer and Export Compliance 82*3446Smrj * 83*3446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84*3446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85*3446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86*3446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87*3446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88*3446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89*3446Smrj * PARTICULAR PURPOSE. 90*3446Smrj * 91*3446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92*3446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93*3446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94*3446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95*3446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96*3446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97*3446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98*3446Smrj * LIMITED REMEDY. 99*3446Smrj * 100*3446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 101*3446Smrj * software or system incorporating such software without first obtaining any 102*3446Smrj * required license or other approval from the U. S. Department of Commerce or 103*3446Smrj * any other agency or department of the United States Government. In the 104*3446Smrj * event Licensee exports any such software from the United States or 105*3446Smrj * re-exports any such software from a foreign destination, Licensee shall 106*3446Smrj * ensure that the distribution and export/re-export of the software is in 107*3446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 108*3446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109*3446Smrj * any of its subsidiaries will export/re-export any technical data, process, 110*3446Smrj * software, or service, directly or indirectly, to any country for which the 111*3446Smrj * United States government or any agency thereof requires an export license, 112*3446Smrj * other governmental approval, or letter of assurance, without first obtaining 113*3446Smrj * such license, approval or letter. 114*3446Smrj * 115*3446Smrj *****************************************************************************/ 116*3446Smrj 117*3446Smrj #define __UTOBJECT_C__ 118*3446Smrj 119*3446Smrj #include "acpi.h" 120*3446Smrj #include "acnamesp.h" 121*3446Smrj #include "amlcode.h" 122*3446Smrj 123*3446Smrj 124*3446Smrj #define _COMPONENT ACPI_UTILITIES 125*3446Smrj ACPI_MODULE_NAME ("utobject") 126*3446Smrj 127*3446Smrj /* Local prototypes */ 128*3446Smrj 129*3446Smrj static ACPI_STATUS 130*3446Smrj AcpiUtGetSimpleObjectSize ( 131*3446Smrj ACPI_OPERAND_OBJECT *Obj, 132*3446Smrj ACPI_SIZE *ObjLength); 133*3446Smrj 134*3446Smrj static ACPI_STATUS 135*3446Smrj AcpiUtGetPackageObjectSize ( 136*3446Smrj ACPI_OPERAND_OBJECT *Obj, 137*3446Smrj ACPI_SIZE *ObjLength); 138*3446Smrj 139*3446Smrj static ACPI_STATUS 140*3446Smrj AcpiUtGetElementLength ( 141*3446Smrj UINT8 ObjectType, 142*3446Smrj ACPI_OPERAND_OBJECT *SourceObject, 143*3446Smrj ACPI_GENERIC_STATE *State, 144*3446Smrj void *Context); 145*3446Smrj 146*3446Smrj 147*3446Smrj /******************************************************************************* 148*3446Smrj * 149*3446Smrj * FUNCTION: AcpiUtCreateInternalObjectDbg 150*3446Smrj * 151*3446Smrj * PARAMETERS: ModuleName - Source file name of caller 152*3446Smrj * LineNumber - Line number of caller 153*3446Smrj * ComponentId - Component type of caller 154*3446Smrj * Type - ACPI Type of the new object 155*3446Smrj * 156*3446Smrj * RETURN: A new internal object, null on failure 157*3446Smrj * 158*3446Smrj * DESCRIPTION: Create and initialize a new internal object. 159*3446Smrj * 160*3446Smrj * NOTE: We always allocate the worst-case object descriptor because 161*3446Smrj * these objects are cached, and we want them to be 162*3446Smrj * one-size-satisifies-any-request. This in itself may not be 163*3446Smrj * the most memory efficient, but the efficiency of the object 164*3446Smrj * cache should more than make up for this! 165*3446Smrj * 166*3446Smrj ******************************************************************************/ 167*3446Smrj 168*3446Smrj ACPI_OPERAND_OBJECT * 169*3446Smrj AcpiUtCreateInternalObjectDbg ( 170*3446Smrj char *ModuleName, 171*3446Smrj UINT32 LineNumber, 172*3446Smrj UINT32 ComponentId, 173*3446Smrj ACPI_OBJECT_TYPE Type) 174*3446Smrj { 175*3446Smrj ACPI_OPERAND_OBJECT *Object; 176*3446Smrj ACPI_OPERAND_OBJECT *SecondObject; 177*3446Smrj 178*3446Smrj 179*3446Smrj ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg, 180*3446Smrj AcpiUtGetTypeName (Type)); 181*3446Smrj 182*3446Smrj 183*3446Smrj /* Allocate the raw object descriptor */ 184*3446Smrj 185*3446Smrj Object = AcpiUtAllocateObjectDescDbg (ModuleName, LineNumber, ComponentId); 186*3446Smrj if (!Object) 187*3446Smrj { 188*3446Smrj return_PTR (NULL); 189*3446Smrj } 190*3446Smrj 191*3446Smrj switch (Type) 192*3446Smrj { 193*3446Smrj case ACPI_TYPE_REGION: 194*3446Smrj case ACPI_TYPE_BUFFER_FIELD: 195*3446Smrj 196*3446Smrj /* These types require a secondary object */ 197*3446Smrj 198*3446Smrj SecondObject = AcpiUtAllocateObjectDescDbg (ModuleName, 199*3446Smrj LineNumber, ComponentId); 200*3446Smrj if (!SecondObject) 201*3446Smrj { 202*3446Smrj AcpiUtDeleteObjectDesc (Object); 203*3446Smrj return_PTR (NULL); 204*3446Smrj } 205*3446Smrj 206*3446Smrj SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA; 207*3446Smrj SecondObject->Common.ReferenceCount = 1; 208*3446Smrj 209*3446Smrj /* Link the second object to the first */ 210*3446Smrj 211*3446Smrj Object->Common.NextObject = SecondObject; 212*3446Smrj break; 213*3446Smrj 214*3446Smrj default: 215*3446Smrj /* All others have no secondary object */ 216*3446Smrj break; 217*3446Smrj } 218*3446Smrj 219*3446Smrj /* Save the object type in the object descriptor */ 220*3446Smrj 221*3446Smrj Object->Common.Type = (UINT8) Type; 222*3446Smrj 223*3446Smrj /* Init the reference count */ 224*3446Smrj 225*3446Smrj Object->Common.ReferenceCount = 1; 226*3446Smrj 227*3446Smrj /* Any per-type initialization should go here */ 228*3446Smrj 229*3446Smrj return_PTR (Object); 230*3446Smrj } 231*3446Smrj 232*3446Smrj 233*3446Smrj /******************************************************************************* 234*3446Smrj * 235*3446Smrj * FUNCTION: AcpiUtCreateBufferObject 236*3446Smrj * 237*3446Smrj * PARAMETERS: BufferSize - Size of buffer to be created 238*3446Smrj * 239*3446Smrj * RETURN: Pointer to a new Buffer object, null on failure 240*3446Smrj * 241*3446Smrj * DESCRIPTION: Create a fully initialized buffer object 242*3446Smrj * 243*3446Smrj ******************************************************************************/ 244*3446Smrj 245*3446Smrj ACPI_OPERAND_OBJECT * 246*3446Smrj AcpiUtCreateBufferObject ( 247*3446Smrj ACPI_SIZE BufferSize) 248*3446Smrj { 249*3446Smrj ACPI_OPERAND_OBJECT *BufferDesc; 250*3446Smrj UINT8 *Buffer = NULL; 251*3446Smrj 252*3446Smrj 253*3446Smrj ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize); 254*3446Smrj 255*3446Smrj 256*3446Smrj /* Create a new Buffer object */ 257*3446Smrj 258*3446Smrj BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); 259*3446Smrj if (!BufferDesc) 260*3446Smrj { 261*3446Smrj return_PTR (NULL); 262*3446Smrj } 263*3446Smrj 264*3446Smrj /* Create an actual buffer only if size > 0 */ 265*3446Smrj 266*3446Smrj if (BufferSize > 0) 267*3446Smrj { 268*3446Smrj /* Allocate the actual buffer */ 269*3446Smrj 270*3446Smrj Buffer = ACPI_ALLOCATE_ZEROED (BufferSize); 271*3446Smrj if (!Buffer) 272*3446Smrj { 273*3446Smrj ACPI_ERROR ((AE_INFO, "Could not allocate size %X", 274*3446Smrj (UINT32) BufferSize)); 275*3446Smrj AcpiUtRemoveReference (BufferDesc); 276*3446Smrj return_PTR (NULL); 277*3446Smrj } 278*3446Smrj } 279*3446Smrj 280*3446Smrj /* Complete buffer object initialization */ 281*3446Smrj 282*3446Smrj BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; 283*3446Smrj BufferDesc->Buffer.Pointer = Buffer; 284*3446Smrj BufferDesc->Buffer.Length = (UINT32) BufferSize; 285*3446Smrj 286*3446Smrj /* Return the new buffer descriptor */ 287*3446Smrj 288*3446Smrj return_PTR (BufferDesc); 289*3446Smrj } 290*3446Smrj 291*3446Smrj 292*3446Smrj /******************************************************************************* 293*3446Smrj * 294*3446Smrj * FUNCTION: AcpiUtCreateStringObject 295*3446Smrj * 296*3446Smrj * PARAMETERS: StringSize - Size of string to be created. Does not 297*3446Smrj * include NULL terminator, this is added 298*3446Smrj * automatically. 299*3446Smrj * 300*3446Smrj * RETURN: Pointer to a new String object 301*3446Smrj * 302*3446Smrj * DESCRIPTION: Create a fully initialized string object 303*3446Smrj * 304*3446Smrj ******************************************************************************/ 305*3446Smrj 306*3446Smrj ACPI_OPERAND_OBJECT * 307*3446Smrj AcpiUtCreateStringObject ( 308*3446Smrj ACPI_SIZE StringSize) 309*3446Smrj { 310*3446Smrj ACPI_OPERAND_OBJECT *StringDesc; 311*3446Smrj char *String; 312*3446Smrj 313*3446Smrj 314*3446Smrj ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize); 315*3446Smrj 316*3446Smrj 317*3446Smrj /* Create a new String object */ 318*3446Smrj 319*3446Smrj StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING); 320*3446Smrj if (!StringDesc) 321*3446Smrj { 322*3446Smrj return_PTR (NULL); 323*3446Smrj } 324*3446Smrj 325*3446Smrj /* 326*3446Smrj * Allocate the actual string buffer -- (Size + 1) for NULL terminator. 327*3446Smrj * NOTE: Zero-length strings are NULL terminated 328*3446Smrj */ 329*3446Smrj String = ACPI_ALLOCATE_ZEROED (StringSize + 1); 330*3446Smrj if (!String) 331*3446Smrj { 332*3446Smrj ACPI_ERROR ((AE_INFO, "Could not allocate size %X", 333*3446Smrj (UINT32) StringSize)); 334*3446Smrj AcpiUtRemoveReference (StringDesc); 335*3446Smrj return_PTR (NULL); 336*3446Smrj } 337*3446Smrj 338*3446Smrj /* Complete string object initialization */ 339*3446Smrj 340*3446Smrj StringDesc->String.Pointer = String; 341*3446Smrj StringDesc->String.Length = (UINT32) StringSize; 342*3446Smrj 343*3446Smrj /* Return the new string descriptor */ 344*3446Smrj 345*3446Smrj return_PTR (StringDesc); 346*3446Smrj } 347*3446Smrj 348*3446Smrj 349*3446Smrj /******************************************************************************* 350*3446Smrj * 351*3446Smrj * FUNCTION: AcpiUtValidInternalObject 352*3446Smrj * 353*3446Smrj * PARAMETERS: Object - Object to be validated 354*3446Smrj * 355*3446Smrj * RETURN: TRUE if object is valid, FALSE otherwise 356*3446Smrj * 357*3446Smrj * DESCRIPTION: Validate a pointer to be an ACPI_OPERAND_OBJECT 358*3446Smrj * 359*3446Smrj ******************************************************************************/ 360*3446Smrj 361*3446Smrj BOOLEAN 362*3446Smrj AcpiUtValidInternalObject ( 363*3446Smrj void *Object) 364*3446Smrj { 365*3446Smrj 366*3446Smrj ACPI_FUNCTION_NAME (UtValidInternalObject); 367*3446Smrj 368*3446Smrj 369*3446Smrj /* Check for a null pointer */ 370*3446Smrj 371*3446Smrj if (!Object) 372*3446Smrj { 373*3446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n")); 374*3446Smrj return (FALSE); 375*3446Smrj } 376*3446Smrj 377*3446Smrj /* Check the descriptor type field */ 378*3446Smrj 379*3446Smrj switch (ACPI_GET_DESCRIPTOR_TYPE (Object)) 380*3446Smrj { 381*3446Smrj case ACPI_DESC_TYPE_OPERAND: 382*3446Smrj 383*3446Smrj /* The object appears to be a valid ACPI_OPERAND_OBJECT */ 384*3446Smrj 385*3446Smrj return (TRUE); 386*3446Smrj 387*3446Smrj default: 388*3446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 389*3446Smrj "%p is not not an ACPI operand obj [%s]\n", 390*3446Smrj Object, AcpiUtGetDescriptorName (Object))); 391*3446Smrj break; 392*3446Smrj } 393*3446Smrj 394*3446Smrj return (FALSE); 395*3446Smrj } 396*3446Smrj 397*3446Smrj 398*3446Smrj /******************************************************************************* 399*3446Smrj * 400*3446Smrj * FUNCTION: AcpiUtAllocateObjectDescDbg 401*3446Smrj * 402*3446Smrj * PARAMETERS: ModuleName - Caller's module name (for error output) 403*3446Smrj * LineNumber - Caller's line number (for error output) 404*3446Smrj * ComponentId - Caller's component ID (for error output) 405*3446Smrj * 406*3446Smrj * RETURN: Pointer to newly allocated object descriptor. Null on error 407*3446Smrj * 408*3446Smrj * DESCRIPTION: Allocate a new object descriptor. Gracefully handle 409*3446Smrj * error conditions. 410*3446Smrj * 411*3446Smrj ******************************************************************************/ 412*3446Smrj 413*3446Smrj void * 414*3446Smrj AcpiUtAllocateObjectDescDbg ( 415*3446Smrj char *ModuleName, 416*3446Smrj UINT32 LineNumber, 417*3446Smrj UINT32 ComponentId) 418*3446Smrj { 419*3446Smrj ACPI_OPERAND_OBJECT *Object; 420*3446Smrj 421*3446Smrj 422*3446Smrj ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg); 423*3446Smrj 424*3446Smrj 425*3446Smrj Object = AcpiOsAcquireObject (AcpiGbl_OperandCache); 426*3446Smrj if (!Object) 427*3446Smrj { 428*3446Smrj ACPI_ERROR ((ModuleName, LineNumber, 429*3446Smrj "Could not allocate an object descriptor")); 430*3446Smrj 431*3446Smrj return_PTR (NULL); 432*3446Smrj } 433*3446Smrj 434*3446Smrj /* Mark the descriptor type */ 435*3446Smrj 436*3446Smrj ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND); 437*3446Smrj 438*3446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", 439*3446Smrj Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT))); 440*3446Smrj 441*3446Smrj return_PTR (Object); 442*3446Smrj } 443*3446Smrj 444*3446Smrj 445*3446Smrj /******************************************************************************* 446*3446Smrj * 447*3446Smrj * FUNCTION: AcpiUtDeleteObjectDesc 448*3446Smrj * 449*3446Smrj * PARAMETERS: Object - An Acpi internal object to be deleted 450*3446Smrj * 451*3446Smrj * RETURN: None. 452*3446Smrj * 453*3446Smrj * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache 454*3446Smrj * 455*3446Smrj ******************************************************************************/ 456*3446Smrj 457*3446Smrj void 458*3446Smrj AcpiUtDeleteObjectDesc ( 459*3446Smrj ACPI_OPERAND_OBJECT *Object) 460*3446Smrj { 461*3446Smrj ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object); 462*3446Smrj 463*3446Smrj 464*3446Smrj /* Object must be an ACPI_OPERAND_OBJECT */ 465*3446Smrj 466*3446Smrj if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND) 467*3446Smrj { 468*3446Smrj ACPI_ERROR ((AE_INFO, 469*3446Smrj "%p is not an ACPI Operand object [%s]", Object, 470*3446Smrj AcpiUtGetDescriptorName (Object))); 471*3446Smrj return_VOID; 472*3446Smrj } 473*3446Smrj 474*3446Smrj (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object); 475*3446Smrj return_VOID; 476*3446Smrj } 477*3446Smrj 478*3446Smrj 479*3446Smrj /******************************************************************************* 480*3446Smrj * 481*3446Smrj * FUNCTION: AcpiUtGetSimpleObjectSize 482*3446Smrj * 483*3446Smrj * PARAMETERS: InternalObject - An ACPI operand object 484*3446Smrj * ObjLength - Where the length is returned 485*3446Smrj * 486*3446Smrj * RETURN: Status 487*3446Smrj * 488*3446Smrj * DESCRIPTION: This function is called to determine the space required to 489*3446Smrj * contain a simple object for return to an external user. 490*3446Smrj * 491*3446Smrj * The length includes the object structure plus any additional 492*3446Smrj * needed space. 493*3446Smrj * 494*3446Smrj ******************************************************************************/ 495*3446Smrj 496*3446Smrj static ACPI_STATUS 497*3446Smrj AcpiUtGetSimpleObjectSize ( 498*3446Smrj ACPI_OPERAND_OBJECT *InternalObject, 499*3446Smrj ACPI_SIZE *ObjLength) 500*3446Smrj { 501*3446Smrj ACPI_SIZE Length; 502*3446Smrj ACPI_STATUS Status = AE_OK; 503*3446Smrj 504*3446Smrj 505*3446Smrj ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject); 506*3446Smrj 507*3446Smrj 508*3446Smrj /* 509*3446Smrj * Handle a null object (Could be a uninitialized package 510*3446Smrj * element -- which is legal) 511*3446Smrj */ 512*3446Smrj if (!InternalObject) 513*3446Smrj { 514*3446Smrj *ObjLength = 0; 515*3446Smrj return_ACPI_STATUS (AE_OK); 516*3446Smrj } 517*3446Smrj 518*3446Smrj /* Start with the length of the Acpi object */ 519*3446Smrj 520*3446Smrj Length = sizeof (ACPI_OBJECT); 521*3446Smrj 522*3446Smrj if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED) 523*3446Smrj { 524*3446Smrj /* Object is a named object (reference), just return the length */ 525*3446Smrj 526*3446Smrj *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length); 527*3446Smrj return_ACPI_STATUS (Status); 528*3446Smrj } 529*3446Smrj 530*3446Smrj /* 531*3446Smrj * The final length depends on the object type 532*3446Smrj * Strings and Buffers are packed right up against the parent object and 533*3446Smrj * must be accessed bytewise or there may be alignment problems on 534*3446Smrj * certain processors 535*3446Smrj */ 536*3446Smrj switch (ACPI_GET_OBJECT_TYPE (InternalObject)) 537*3446Smrj { 538*3446Smrj case ACPI_TYPE_STRING: 539*3446Smrj 540*3446Smrj Length += (ACPI_SIZE) InternalObject->String.Length + 1; 541*3446Smrj break; 542*3446Smrj 543*3446Smrj 544*3446Smrj case ACPI_TYPE_BUFFER: 545*3446Smrj 546*3446Smrj Length += (ACPI_SIZE) InternalObject->Buffer.Length; 547*3446Smrj break; 548*3446Smrj 549*3446Smrj 550*3446Smrj case ACPI_TYPE_INTEGER: 551*3446Smrj case ACPI_TYPE_PROCESSOR: 552*3446Smrj case ACPI_TYPE_POWER: 553*3446Smrj 554*3446Smrj /* 555*3446Smrj * No extra data for these types 556*3446Smrj */ 557*3446Smrj break; 558*3446Smrj 559*3446Smrj 560*3446Smrj case ACPI_TYPE_LOCAL_REFERENCE: 561*3446Smrj 562*3446Smrj switch (InternalObject->Reference.Opcode) 563*3446Smrj { 564*3446Smrj case AML_INT_NAMEPATH_OP: 565*3446Smrj 566*3446Smrj /* 567*3446Smrj * Get the actual length of the full pathname to this object. 568*3446Smrj * The reference will be converted to the pathname to the object 569*3446Smrj */ 570*3446Smrj Length += ACPI_ROUND_UP_TO_NATIVE_WORD ( 571*3446Smrj AcpiNsGetPathnameLength (InternalObject->Reference.Node)); 572*3446Smrj break; 573*3446Smrj 574*3446Smrj default: 575*3446Smrj 576*3446Smrj /* 577*3446Smrj * No other reference opcodes are supported. 578*3446Smrj * Notably, Locals and Args are not supported, but this may be 579*3446Smrj * required eventually. 580*3446Smrj */ 581*3446Smrj ACPI_ERROR ((AE_INFO, 582*3446Smrj "Unsupported Reference opcode=%X in object %p", 583*3446Smrj InternalObject->Reference.Opcode, InternalObject)); 584*3446Smrj Status = AE_TYPE; 585*3446Smrj break; 586*3446Smrj } 587*3446Smrj break; 588*3446Smrj 589*3446Smrj 590*3446Smrj default: 591*3446Smrj 592*3446Smrj ACPI_ERROR ((AE_INFO, "Unsupported type=%X in object %p", 593*3446Smrj ACPI_GET_OBJECT_TYPE (InternalObject), InternalObject)); 594*3446Smrj Status = AE_TYPE; 595*3446Smrj break; 596*3446Smrj } 597*3446Smrj 598*3446Smrj /* 599*3446Smrj * Account for the space required by the object rounded up to the next 600*3446Smrj * multiple of the machine word size. This keeps each object aligned 601*3446Smrj * on a machine word boundary. (preventing alignment faults on some 602*3446Smrj * machines.) 603*3446Smrj */ 604*3446Smrj *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length); 605*3446Smrj return_ACPI_STATUS (Status); 606*3446Smrj } 607*3446Smrj 608*3446Smrj 609*3446Smrj /******************************************************************************* 610*3446Smrj * 611*3446Smrj * FUNCTION: AcpiUtGetElementLength 612*3446Smrj * 613*3446Smrj * PARAMETERS: ACPI_PKG_CALLBACK 614*3446Smrj * 615*3446Smrj * RETURN: Status 616*3446Smrj * 617*3446Smrj * DESCRIPTION: Get the length of one package element. 618*3446Smrj * 619*3446Smrj ******************************************************************************/ 620*3446Smrj 621*3446Smrj static ACPI_STATUS 622*3446Smrj AcpiUtGetElementLength ( 623*3446Smrj UINT8 ObjectType, 624*3446Smrj ACPI_OPERAND_OBJECT *SourceObject, 625*3446Smrj ACPI_GENERIC_STATE *State, 626*3446Smrj void *Context) 627*3446Smrj { 628*3446Smrj ACPI_STATUS Status = AE_OK; 629*3446Smrj ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context; 630*3446Smrj ACPI_SIZE ObjectSpace; 631*3446Smrj 632*3446Smrj 633*3446Smrj switch (ObjectType) 634*3446Smrj { 635*3446Smrj case ACPI_COPY_TYPE_SIMPLE: 636*3446Smrj 637*3446Smrj /* 638*3446Smrj * Simple object - just get the size (Null object/entry is handled 639*3446Smrj * here also) and sum it into the running package length 640*3446Smrj */ 641*3446Smrj Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace); 642*3446Smrj if (ACPI_FAILURE (Status)) 643*3446Smrj { 644*3446Smrj return (Status); 645*3446Smrj } 646*3446Smrj 647*3446Smrj Info->Length += ObjectSpace; 648*3446Smrj break; 649*3446Smrj 650*3446Smrj 651*3446Smrj case ACPI_COPY_TYPE_PACKAGE: 652*3446Smrj 653*3446Smrj /* Package object - nothing much to do here, let the walk handle it */ 654*3446Smrj 655*3446Smrj Info->NumPackages++; 656*3446Smrj State->Pkg.ThisTargetObj = NULL; 657*3446Smrj break; 658*3446Smrj 659*3446Smrj 660*3446Smrj default: 661*3446Smrj 662*3446Smrj /* No other types allowed */ 663*3446Smrj 664*3446Smrj return (AE_BAD_PARAMETER); 665*3446Smrj } 666*3446Smrj 667*3446Smrj return (Status); 668*3446Smrj } 669*3446Smrj 670*3446Smrj 671*3446Smrj /******************************************************************************* 672*3446Smrj * 673*3446Smrj * FUNCTION: AcpiUtGetPackageObjectSize 674*3446Smrj * 675*3446Smrj * PARAMETERS: InternalObject - An ACPI internal object 676*3446Smrj * ObjLength - Where the length is returned 677*3446Smrj * 678*3446Smrj * RETURN: Status 679*3446Smrj * 680*3446Smrj * DESCRIPTION: This function is called to determine the space required to 681*3446Smrj * contain a package object for return to an external user. 682*3446Smrj * 683*3446Smrj * This is moderately complex since a package contains other 684*3446Smrj * objects including packages. 685*3446Smrj * 686*3446Smrj ******************************************************************************/ 687*3446Smrj 688*3446Smrj static ACPI_STATUS 689*3446Smrj AcpiUtGetPackageObjectSize ( 690*3446Smrj ACPI_OPERAND_OBJECT *InternalObject, 691*3446Smrj ACPI_SIZE *ObjLength) 692*3446Smrj { 693*3446Smrj ACPI_STATUS Status; 694*3446Smrj ACPI_PKG_INFO Info; 695*3446Smrj 696*3446Smrj 697*3446Smrj ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject); 698*3446Smrj 699*3446Smrj 700*3446Smrj Info.Length = 0; 701*3446Smrj Info.ObjectSpace = 0; 702*3446Smrj Info.NumPackages = 1; 703*3446Smrj 704*3446Smrj Status = AcpiUtWalkPackageTree (InternalObject, NULL, 705*3446Smrj AcpiUtGetElementLength, &Info); 706*3446Smrj if (ACPI_FAILURE (Status)) 707*3446Smrj { 708*3446Smrj return_ACPI_STATUS (Status); 709*3446Smrj } 710*3446Smrj 711*3446Smrj /* 712*3446Smrj * We have handled all of the objects in all levels of the package. 713*3446Smrj * just add the length of the package objects themselves. 714*3446Smrj * Round up to the next machine word. 715*3446Smrj */ 716*3446Smrj Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) * 717*3446Smrj (ACPI_SIZE) Info.NumPackages; 718*3446Smrj 719*3446Smrj /* Return the total package length */ 720*3446Smrj 721*3446Smrj *ObjLength = Info.Length; 722*3446Smrj return_ACPI_STATUS (Status); 723*3446Smrj } 724*3446Smrj 725*3446Smrj 726*3446Smrj /******************************************************************************* 727*3446Smrj * 728*3446Smrj * FUNCTION: AcpiUtGetObjectSize 729*3446Smrj * 730*3446Smrj * PARAMETERS: InternalObject - An ACPI internal object 731*3446Smrj * ObjLength - Where the length will be returned 732*3446Smrj * 733*3446Smrj * RETURN: Status 734*3446Smrj * 735*3446Smrj * DESCRIPTION: This function is called to determine the space required to 736*3446Smrj * contain an object for return to an API user. 737*3446Smrj * 738*3446Smrj ******************************************************************************/ 739*3446Smrj 740*3446Smrj ACPI_STATUS 741*3446Smrj AcpiUtGetObjectSize ( 742*3446Smrj ACPI_OPERAND_OBJECT *InternalObject, 743*3446Smrj ACPI_SIZE *ObjLength) 744*3446Smrj { 745*3446Smrj ACPI_STATUS Status; 746*3446Smrj 747*3446Smrj 748*3446Smrj ACPI_FUNCTION_ENTRY (); 749*3446Smrj 750*3446Smrj 751*3446Smrj if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_OPERAND) && 752*3446Smrj (ACPI_GET_OBJECT_TYPE (InternalObject) == ACPI_TYPE_PACKAGE)) 753*3446Smrj { 754*3446Smrj Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength); 755*3446Smrj } 756*3446Smrj else 757*3446Smrj { 758*3446Smrj Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength); 759*3446Smrj } 760*3446Smrj 761*3446Smrj return (Status); 762*3446Smrj } 763*3446Smrj 764*3446Smrj 765