1 /****************************************************************************** 2 * 3 * Module Name: utobject - ACPI object create/delete/size/cache routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acnamesp.h" 47 48 49 #define _COMPONENT ACPI_UTILITIES 50 ACPI_MODULE_NAME ("utobject") 51 52 /* Local prototypes */ 53 54 static ACPI_STATUS 55 AcpiUtGetSimpleObjectSize ( 56 ACPI_OPERAND_OBJECT *Obj, 57 ACPI_SIZE *ObjLength); 58 59 static ACPI_STATUS 60 AcpiUtGetPackageObjectSize ( 61 ACPI_OPERAND_OBJECT *Obj, 62 ACPI_SIZE *ObjLength); 63 64 static ACPI_STATUS 65 AcpiUtGetElementLength ( 66 UINT8 ObjectType, 67 ACPI_OPERAND_OBJECT *SourceObject, 68 ACPI_GENERIC_STATE *State, 69 void *Context); 70 71 72 /******************************************************************************* 73 * 74 * FUNCTION: AcpiUtCreateInternalObjectDbg 75 * 76 * PARAMETERS: ModuleName - Source file name of caller 77 * LineNumber - Line number of caller 78 * ComponentId - Component type of caller 79 * Type - ACPI Type of the new object 80 * 81 * RETURN: A new internal object, null on failure 82 * 83 * DESCRIPTION: Create and initialize a new internal object. 84 * 85 * NOTE: We always allocate the worst-case object descriptor because 86 * these objects are cached, and we want them to be 87 * one-size-satisifies-any-request. This in itself may not be 88 * the most memory efficient, but the efficiency of the object 89 * cache should more than make up for this! 90 * 91 ******************************************************************************/ 92 93 #pragma GCC diagnostic push 94 #pragma GCC diagnostic ignored "-Wcast-qual" 95 96 ACPI_OPERAND_OBJECT * 97 AcpiUtCreateInternalObjectDbg ( 98 const char *ModuleName, 99 UINT32 LineNumber, 100 UINT32 ComponentId, 101 ACPI_OBJECT_TYPE Type) 102 { 103 ACPI_OPERAND_OBJECT *Object; 104 ACPI_OPERAND_OBJECT *SecondObject; 105 106 107 ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg, 108 AcpiUtGetTypeName (Type)); 109 110 111 /* Allocate the raw object descriptor */ 112 113 Object = AcpiUtAllocateObjectDescDbg ( 114 ModuleName, LineNumber, ComponentId); 115 if (!Object) 116 { 117 return_PTR (NULL); 118 } 119 120 switch (Type) 121 { 122 case ACPI_TYPE_REGION: 123 case ACPI_TYPE_BUFFER_FIELD: 124 case ACPI_TYPE_LOCAL_BANK_FIELD: 125 126 /* These types require a secondary object */ 127 128 SecondObject = AcpiUtAllocateObjectDescDbg ( 129 ModuleName, LineNumber, ComponentId); 130 if (!SecondObject) 131 { 132 AcpiUtDeleteObjectDesc (Object); 133 return_PTR (NULL); 134 } 135 136 SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA; 137 SecondObject->Common.ReferenceCount = 1; 138 139 /* Link the second object to the first */ 140 141 Object->Common.NextObject = SecondObject; 142 break; 143 144 default: 145 146 /* All others have no secondary object */ 147 break; 148 } 149 150 /* Save the object type in the object descriptor */ 151 152 Object->Common.Type = (UINT8) Type; 153 154 /* Init the reference count */ 155 156 Object->Common.ReferenceCount = 1; 157 158 /* Any per-type initialization should go here */ 159 160 return_PTR (Object); 161 } 162 163 #pragma GCC diagnostic pop 164 165 166 /******************************************************************************* 167 * 168 * FUNCTION: AcpiUtCreatePackageObject 169 * 170 * PARAMETERS: Count - Number of package elements 171 * 172 * RETURN: Pointer to a new Package object, null on failure 173 * 174 * DESCRIPTION: Create a fully initialized package object 175 * 176 ******************************************************************************/ 177 178 ACPI_OPERAND_OBJECT * 179 AcpiUtCreatePackageObject ( 180 UINT32 Count) 181 { 182 ACPI_OPERAND_OBJECT *PackageDesc; 183 ACPI_OPERAND_OBJECT **PackageElements; 184 185 186 ACPI_FUNCTION_TRACE_U32 (UtCreatePackageObject, Count); 187 188 189 /* Create a new Package object */ 190 191 PackageDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE); 192 if (!PackageDesc) 193 { 194 return_PTR (NULL); 195 } 196 197 /* 198 * Create the element array. Count+1 allows the array to be null 199 * terminated. 200 */ 201 PackageElements = ACPI_ALLOCATE_ZEROED ( 202 ((ACPI_SIZE) Count + 1) * sizeof (void *)); 203 if (!PackageElements) 204 { 205 ACPI_FREE (PackageDesc); 206 return_PTR (NULL); 207 } 208 209 PackageDesc->Package.Count = Count; 210 PackageDesc->Package.Elements = PackageElements; 211 return_PTR (PackageDesc); 212 } 213 214 215 /******************************************************************************* 216 * 217 * FUNCTION: AcpiUtCreateIntegerObject 218 * 219 * PARAMETERS: InitialValue - Initial value for the integer 220 * 221 * RETURN: Pointer to a new Integer object, null on failure 222 * 223 * DESCRIPTION: Create an initialized integer object 224 * 225 ******************************************************************************/ 226 227 ACPI_OPERAND_OBJECT * 228 AcpiUtCreateIntegerObject ( 229 UINT64 InitialValue) 230 { 231 ACPI_OPERAND_OBJECT *IntegerDesc; 232 233 234 ACPI_FUNCTION_TRACE (UtCreateIntegerObject); 235 236 237 /* Create and initialize a new integer object */ 238 239 IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 240 if (!IntegerDesc) 241 { 242 return_PTR (NULL); 243 } 244 245 IntegerDesc->Integer.Value = InitialValue; 246 return_PTR (IntegerDesc); 247 } 248 249 250 /******************************************************************************* 251 * 252 * FUNCTION: AcpiUtCreateBufferObject 253 * 254 * PARAMETERS: BufferSize - Size of buffer to be created 255 * 256 * RETURN: Pointer to a new Buffer object, null on failure 257 * 258 * DESCRIPTION: Create a fully initialized buffer object 259 * 260 ******************************************************************************/ 261 262 ACPI_OPERAND_OBJECT * 263 AcpiUtCreateBufferObject ( 264 ACPI_SIZE BufferSize) 265 { 266 ACPI_OPERAND_OBJECT *BufferDesc; 267 UINT8 *Buffer = NULL; 268 269 270 ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize); 271 272 273 /* Create a new Buffer object */ 274 275 BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); 276 if (!BufferDesc) 277 { 278 return_PTR (NULL); 279 } 280 281 /* Create an actual buffer only if size > 0 */ 282 283 if (BufferSize > 0) 284 { 285 /* Allocate the actual buffer */ 286 287 Buffer = ACPI_ALLOCATE_ZEROED (BufferSize); 288 if (!Buffer) 289 { 290 ACPI_ERROR ((AE_INFO, "Could not allocate size %u", 291 (UINT32) BufferSize)); 292 293 AcpiUtRemoveReference (BufferDesc); 294 return_PTR (NULL); 295 } 296 } 297 298 /* Complete buffer object initialization */ 299 300 BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; 301 BufferDesc->Buffer.Pointer = Buffer; 302 BufferDesc->Buffer.Length = (UINT32) BufferSize; 303 304 /* Return the new buffer descriptor */ 305 306 return_PTR (BufferDesc); 307 } 308 309 310 /******************************************************************************* 311 * 312 * FUNCTION: AcpiUtCreateStringObject 313 * 314 * PARAMETERS: StringSize - Size of string to be created. Does not 315 * include NULL terminator, this is added 316 * automatically. 317 * 318 * RETURN: Pointer to a new String object 319 * 320 * DESCRIPTION: Create a fully initialized string object 321 * 322 ******************************************************************************/ 323 324 ACPI_OPERAND_OBJECT * 325 AcpiUtCreateStringObject ( 326 ACPI_SIZE StringSize) 327 { 328 ACPI_OPERAND_OBJECT *StringDesc; 329 char *String; 330 331 332 ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize); 333 334 335 /* Create a new String object */ 336 337 StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING); 338 if (!StringDesc) 339 { 340 return_PTR (NULL); 341 } 342 343 /* 344 * Allocate the actual string buffer -- (Size + 1) for NULL terminator. 345 * NOTE: Zero-length strings are NULL terminated 346 */ 347 String = ACPI_ALLOCATE_ZEROED (StringSize + 1); 348 if (!String) 349 { 350 ACPI_ERROR ((AE_INFO, "Could not allocate size %u", 351 (UINT32) StringSize)); 352 353 AcpiUtRemoveReference (StringDesc); 354 return_PTR (NULL); 355 } 356 357 /* Complete string object initialization */ 358 359 StringDesc->String.Pointer = String; 360 StringDesc->String.Length = (UINT32) StringSize; 361 362 /* Return the new string descriptor */ 363 364 return_PTR (StringDesc); 365 } 366 367 368 /******************************************************************************* 369 * 370 * FUNCTION: AcpiUtValidInternalObject 371 * 372 * PARAMETERS: Object - Object to be validated 373 * 374 * RETURN: TRUE if object is valid, FALSE otherwise 375 * 376 * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT 377 * 378 ******************************************************************************/ 379 380 BOOLEAN 381 AcpiUtValidInternalObject ( 382 void *Object) 383 { 384 385 ACPI_FUNCTION_NAME (UtValidInternalObject); 386 387 388 /* Check for a null pointer */ 389 390 if (!Object) 391 { 392 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Null Object Ptr\n")); 393 return (FALSE); 394 } 395 396 /* Check the descriptor type field */ 397 398 switch (ACPI_GET_DESCRIPTOR_TYPE (Object)) 399 { 400 case ACPI_DESC_TYPE_OPERAND: 401 402 /* The object appears to be a valid ACPI_OPERAND_OBJECT */ 403 404 return (TRUE); 405 406 default: 407 408 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 409 "%p is not an ACPI operand obj [%s]\n", 410 Object, AcpiUtGetDescriptorName (Object))); 411 break; 412 } 413 414 return (FALSE); 415 } 416 417 418 /******************************************************************************* 419 * 420 * FUNCTION: AcpiUtAllocateObjectDescDbg 421 * 422 * PARAMETERS: ModuleName - Caller's module name (for error output) 423 * LineNumber - Caller's line number (for error output) 424 * ComponentId - Caller's component ID (for error output) 425 * 426 * RETURN: Pointer to newly allocated object descriptor. Null on error 427 * 428 * DESCRIPTION: Allocate a new object descriptor. Gracefully handle 429 * error conditions. 430 * 431 ******************************************************************************/ 432 433 void * 434 AcpiUtAllocateObjectDescDbg ( 435 const char *ModuleName, 436 UINT32 LineNumber, 437 UINT32 ComponentId) 438 { 439 ACPI_OPERAND_OBJECT *Object; 440 441 442 ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg); 443 444 445 Object = AcpiOsAcquireObject (AcpiGbl_OperandCache); 446 if (!Object) 447 { 448 ACPI_ERROR ((ModuleName, LineNumber, 449 "Could not allocate an object descriptor")); 450 451 return_PTR (NULL); 452 } 453 454 /* Mark the descriptor type */ 455 456 ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND); 457 458 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", 459 Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT))); 460 461 return_PTR (Object); 462 } 463 464 465 /******************************************************************************* 466 * 467 * FUNCTION: AcpiUtDeleteObjectDesc 468 * 469 * PARAMETERS: Object - An Acpi internal object to be deleted 470 * 471 * RETURN: None. 472 * 473 * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache 474 * 475 ******************************************************************************/ 476 477 void 478 AcpiUtDeleteObjectDesc ( 479 ACPI_OPERAND_OBJECT *Object) 480 { 481 ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object); 482 483 484 /* Object must be of type ACPI_OPERAND_OBJECT */ 485 486 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND) 487 { 488 ACPI_ERROR ((AE_INFO, 489 "%p is not an ACPI Operand object [%s]", Object, 490 AcpiUtGetDescriptorName (Object))); 491 return_VOID; 492 } 493 494 (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object); 495 return_VOID; 496 } 497 498 499 /******************************************************************************* 500 * 501 * FUNCTION: AcpiUtGetSimpleObjectSize 502 * 503 * PARAMETERS: InternalObject - An ACPI operand object 504 * ObjLength - Where the length is returned 505 * 506 * RETURN: Status 507 * 508 * DESCRIPTION: This function is called to determine the space required to 509 * contain a simple object for return to an external user. 510 * 511 * The length includes the object structure plus any additional 512 * needed space. 513 * 514 ******************************************************************************/ 515 516 static ACPI_STATUS 517 AcpiUtGetSimpleObjectSize ( 518 ACPI_OPERAND_OBJECT *InternalObject, 519 ACPI_SIZE *ObjLength) 520 { 521 ACPI_SIZE Length; 522 ACPI_SIZE Size; 523 ACPI_STATUS Status = AE_OK; 524 525 526 ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject); 527 528 529 /* Start with the length of the (external) Acpi object */ 530 531 Length = sizeof (ACPI_OBJECT); 532 533 /* A NULL object is allowed, can be a legal uninitialized package element */ 534 535 if (!InternalObject) 536 { 537 /* 538 * Object is NULL, just return the length of ACPI_OBJECT 539 * (A NULL ACPI_OBJECT is an object of all zeroes.) 540 */ 541 *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length); 542 return_ACPI_STATUS (AE_OK); 543 } 544 545 /* A Namespace Node should never appear here */ 546 547 if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED) 548 { 549 /* A namespace node should never get here */ 550 551 return_ACPI_STATUS (AE_AML_INTERNAL); 552 } 553 554 /* 555 * The final length depends on the object type 556 * Strings and Buffers are packed right up against the parent object and 557 * must be accessed bytewise or there may be alignment problems on 558 * certain processors 559 */ 560 switch (InternalObject->Common.Type) 561 { 562 case ACPI_TYPE_STRING: 563 564 Length += (ACPI_SIZE) InternalObject->String.Length + 1; 565 break; 566 567 case ACPI_TYPE_BUFFER: 568 569 Length += (ACPI_SIZE) InternalObject->Buffer.Length; 570 break; 571 572 case ACPI_TYPE_INTEGER: 573 case ACPI_TYPE_PROCESSOR: 574 case ACPI_TYPE_POWER: 575 576 /* No extra data for these types */ 577 578 break; 579 580 case ACPI_TYPE_LOCAL_REFERENCE: 581 582 switch (InternalObject->Reference.Class) 583 { 584 case ACPI_REFCLASS_NAME: 585 /* 586 * Get the actual length of the full pathname to this object. 587 * The reference will be converted to the pathname to the object 588 */ 589 Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node); 590 if (!Size) 591 { 592 return_ACPI_STATUS (AE_BAD_PARAMETER); 593 } 594 595 Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size); 596 break; 597 598 default: 599 /* 600 * No other reference opcodes are supported. 601 * Notably, Locals and Args are not supported, but this may be 602 * required eventually. 603 */ 604 ACPI_ERROR ((AE_INFO, "Cannot convert to external object - " 605 "unsupported Reference Class [%s] 0x%X in object %p", 606 AcpiUtGetReferenceName (InternalObject), 607 InternalObject->Reference.Class, InternalObject)); 608 Status = AE_TYPE; 609 break; 610 } 611 break; 612 613 default: 614 615 ACPI_ERROR ((AE_INFO, "Cannot convert to external object - " 616 "unsupported type [%s] 0x%X in object %p", 617 AcpiUtGetObjectTypeName (InternalObject), 618 InternalObject->Common.Type, InternalObject)); 619 Status = AE_TYPE; 620 break; 621 } 622 623 /* 624 * Account for the space required by the object rounded up to the next 625 * multiple of the machine word size. This keeps each object aligned 626 * on a machine word boundary. (preventing alignment faults on some 627 * machines.) 628 */ 629 *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length); 630 return_ACPI_STATUS (Status); 631 } 632 633 634 /******************************************************************************* 635 * 636 * FUNCTION: AcpiUtGetElementLength 637 * 638 * PARAMETERS: ACPI_PKG_CALLBACK 639 * 640 * RETURN: Status 641 * 642 * DESCRIPTION: Get the length of one package element. 643 * 644 ******************************************************************************/ 645 646 static ACPI_STATUS 647 AcpiUtGetElementLength ( 648 UINT8 ObjectType, 649 ACPI_OPERAND_OBJECT *SourceObject, 650 ACPI_GENERIC_STATE *State, 651 void *Context) 652 { 653 ACPI_STATUS Status = AE_OK; 654 ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context; 655 ACPI_SIZE ObjectSpace; 656 657 658 switch (ObjectType) 659 { 660 case ACPI_COPY_TYPE_SIMPLE: 661 /* 662 * Simple object - just get the size (Null object/entry is handled 663 * here also) and sum it into the running package length 664 */ 665 Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace); 666 if (ACPI_FAILURE (Status)) 667 { 668 return (Status); 669 } 670 671 Info->Length += ObjectSpace; 672 break; 673 674 case ACPI_COPY_TYPE_PACKAGE: 675 676 /* Package object - nothing much to do here, let the walk handle it */ 677 678 Info->NumPackages++; 679 State->Pkg.ThisTargetObj = NULL; 680 break; 681 682 default: 683 684 /* No other types allowed */ 685 686 return (AE_BAD_PARAMETER); 687 } 688 689 return (Status); 690 } 691 692 693 /******************************************************************************* 694 * 695 * FUNCTION: AcpiUtGetPackageObjectSize 696 * 697 * PARAMETERS: InternalObject - An ACPI internal object 698 * ObjLength - Where the length is returned 699 * 700 * RETURN: Status 701 * 702 * DESCRIPTION: This function is called to determine the space required to 703 * contain a package object for return to an external user. 704 * 705 * This is moderately complex since a package contains other 706 * objects including packages. 707 * 708 ******************************************************************************/ 709 710 static ACPI_STATUS 711 AcpiUtGetPackageObjectSize ( 712 ACPI_OPERAND_OBJECT *InternalObject, 713 ACPI_SIZE *ObjLength) 714 { 715 ACPI_STATUS Status; 716 ACPI_PKG_INFO Info; 717 718 719 ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject); 720 721 722 Info.Length = 0; 723 Info.ObjectSpace = 0; 724 Info.NumPackages = 1; 725 726 Status = AcpiUtWalkPackageTree ( 727 InternalObject, NULL, AcpiUtGetElementLength, &Info); 728 if (ACPI_FAILURE (Status)) 729 { 730 return_ACPI_STATUS (Status); 731 } 732 733 /* 734 * We have handled all of the objects in all levels of the package. 735 * just add the length of the package objects themselves. 736 * Round up to the next machine word. 737 */ 738 Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD ( 739 sizeof (ACPI_OBJECT)) * (ACPI_SIZE) Info.NumPackages; 740 741 /* Return the total package length */ 742 743 *ObjLength = Info.Length; 744 return_ACPI_STATUS (Status); 745 } 746 747 748 /******************************************************************************* 749 * 750 * FUNCTION: AcpiUtGetObjectSize 751 * 752 * PARAMETERS: InternalObject - An ACPI internal object 753 * ObjLength - Where the length will be returned 754 * 755 * RETURN: Status 756 * 757 * DESCRIPTION: This function is called to determine the space required to 758 * contain an object for return to an API user. 759 * 760 ******************************************************************************/ 761 762 ACPI_STATUS 763 AcpiUtGetObjectSize ( 764 ACPI_OPERAND_OBJECT *InternalObject, 765 ACPI_SIZE *ObjLength) 766 { 767 ACPI_STATUS Status; 768 769 770 ACPI_FUNCTION_ENTRY (); 771 772 773 if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == 774 ACPI_DESC_TYPE_OPERAND) && 775 (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)) 776 { 777 Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength); 778 } 779 else 780 { 781 Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength); 782 } 783 784 return (Status); 785 } 786