1 /******************************************************************************* 2 * 3 * Module Name: rscalc - Calculate stream and list lengths 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 <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acresrc.h> 47 #include <contrib/dev/acpica/include/acnamesp.h> 48 49 50 #define _COMPONENT ACPI_RESOURCES 51 ACPI_MODULE_NAME ("rscalc") 52 53 54 /* Local prototypes */ 55 56 static UINT8 57 AcpiRsCountSetBits ( 58 UINT16 BitField); 59 60 static ACPI_RS_LENGTH 61 AcpiRsStructOptionLength ( 62 ACPI_RESOURCE_SOURCE *ResourceSource); 63 64 static UINT32 65 AcpiRsStreamOptionLength ( 66 UINT32 ResourceLength, 67 UINT32 MinimumTotalLength); 68 69 70 /******************************************************************************* 71 * 72 * FUNCTION: AcpiRsCountSetBits 73 * 74 * PARAMETERS: BitField - Field in which to count bits 75 * 76 * RETURN: Number of bits set within the field 77 * 78 * DESCRIPTION: Count the number of bits set in a resource field. Used for 79 * (Short descriptor) interrupt and DMA lists. 80 * 81 ******************************************************************************/ 82 83 static UINT8 84 AcpiRsCountSetBits ( 85 UINT16 BitField) 86 { 87 UINT8 BitsSet; 88 89 90 ACPI_FUNCTION_ENTRY (); 91 92 93 for (BitsSet = 0; BitField; BitsSet++) 94 { 95 /* Zero the least significant bit that is set */ 96 97 BitField &= (UINT16) (BitField - 1); 98 } 99 100 return (BitsSet); 101 } 102 103 104 /******************************************************************************* 105 * 106 * FUNCTION: AcpiRsStructOptionLength 107 * 108 * PARAMETERS: ResourceSource - Pointer to optional descriptor field 109 * 110 * RETURN: Status 111 * 112 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 113 * ResourceSource fields in some Large descriptors. Used during 114 * list-to-stream conversion 115 * 116 ******************************************************************************/ 117 118 static ACPI_RS_LENGTH 119 AcpiRsStructOptionLength ( 120 ACPI_RESOURCE_SOURCE *ResourceSource) 121 { 122 ACPI_FUNCTION_ENTRY (); 123 124 125 /* 126 * If the ResourceSource string is valid, return the size of the string 127 * (StringLength includes the NULL terminator) plus the size of the 128 * ResourceSourceIndex (1). 129 */ 130 if (ResourceSource->StringPtr) 131 { 132 return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1)); 133 } 134 135 return (0); 136 } 137 138 139 /******************************************************************************* 140 * 141 * FUNCTION: AcpiRsStreamOptionLength 142 * 143 * PARAMETERS: ResourceLength - Length from the resource header 144 * MinimumTotalLength - Minimum length of this resource, before 145 * any optional fields. Includes header size 146 * 147 * RETURN: Length of optional string (0 if no string present) 148 * 149 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 150 * ResourceSource fields in some Large descriptors. Used during 151 * stream-to-list conversion 152 * 153 ******************************************************************************/ 154 155 static UINT32 156 AcpiRsStreamOptionLength ( 157 UINT32 ResourceLength, 158 UINT32 MinimumAmlResourceLength) 159 { 160 UINT32 StringLength = 0; 161 162 163 ACPI_FUNCTION_ENTRY (); 164 165 166 /* 167 * The ResourceSourceIndex and ResourceSource are optional elements of 168 * some Large-type resource descriptors. 169 */ 170 171 /* 172 * If the length of the actual resource descriptor is greater than the 173 * ACPI spec-defined minimum length, it means that a ResourceSourceIndex 174 * exists and is followed by a (required) null terminated string. The 175 * string length (including the null terminator) is the resource length 176 * minus the minimum length, minus one byte for the ResourceSourceIndex 177 * itself. 178 */ 179 if (ResourceLength > MinimumAmlResourceLength) 180 { 181 /* Compute the length of the optional string */ 182 183 StringLength = ResourceLength - MinimumAmlResourceLength - 1; 184 } 185 186 /* 187 * Round the length up to a multiple of the native word in order to 188 * guarantee that the entire resource descriptor is native word aligned 189 */ 190 return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength)); 191 } 192 193 194 /******************************************************************************* 195 * 196 * FUNCTION: AcpiRsGetAmlLength 197 * 198 * PARAMETERS: Resource - Pointer to the resource linked list 199 * ResourceListSize - Size of the resource linked list 200 * SizeNeeded - Where the required size is returned 201 * 202 * RETURN: Status 203 * 204 * DESCRIPTION: Takes a linked list of internal resource descriptors and 205 * calculates the size buffer needed to hold the corresponding 206 * external resource byte stream. 207 * 208 ******************************************************************************/ 209 210 ACPI_STATUS 211 AcpiRsGetAmlLength ( 212 ACPI_RESOURCE *Resource, 213 ACPI_SIZE ResourceListSize, 214 ACPI_SIZE *SizeNeeded) 215 { 216 ACPI_SIZE AmlSizeNeeded = 0; 217 ACPI_RESOURCE *ResourceEnd; 218 ACPI_RS_LENGTH TotalSize; 219 220 221 ACPI_FUNCTION_TRACE (RsGetAmlLength); 222 223 224 /* Traverse entire list of internal resource descriptors */ 225 226 ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize); 227 while (Resource < ResourceEnd) 228 { 229 /* Validate the descriptor type */ 230 231 if (Resource->Type > ACPI_RESOURCE_TYPE_MAX) 232 { 233 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 234 } 235 236 /* Sanity check the length. It must not be zero, or we loop forever */ 237 238 if (!Resource->Length) 239 { 240 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); 241 } 242 243 /* Get the base size of the (external stream) resource descriptor */ 244 245 TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type]; 246 247 /* 248 * Augment the base size for descriptors with optional and/or 249 * variable-length fields 250 */ 251 switch (Resource->Type) 252 { 253 case ACPI_RESOURCE_TYPE_IRQ: 254 255 /* Length can be 3 or 2 */ 256 257 if (Resource->Data.Irq.DescriptorLength == 2) 258 { 259 TotalSize--; 260 } 261 break; 262 263 264 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 265 266 /* Length can be 1 or 0 */ 267 268 if (Resource->Data.Irq.DescriptorLength == 0) 269 { 270 TotalSize--; 271 } 272 break; 273 274 275 case ACPI_RESOURCE_TYPE_VENDOR: 276 /* 277 * Vendor Defined Resource: 278 * For a Vendor Specific resource, if the Length is between 1 and 7 279 * it will be created as a Small Resource data type, otherwise it 280 * is a Large Resource data type. 281 */ 282 if (Resource->Data.Vendor.ByteLength > 7) 283 { 284 /* Base size of a Large resource descriptor */ 285 286 TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER); 287 } 288 289 /* Add the size of the vendor-specific data */ 290 291 TotalSize = (ACPI_RS_LENGTH) 292 (TotalSize + Resource->Data.Vendor.ByteLength); 293 break; 294 295 296 case ACPI_RESOURCE_TYPE_END_TAG: 297 /* 298 * End Tag: 299 * We are done -- return the accumulated total size. 300 */ 301 *SizeNeeded = AmlSizeNeeded + TotalSize; 302 303 /* Normal exit */ 304 305 return_ACPI_STATUS (AE_OK); 306 307 308 case ACPI_RESOURCE_TYPE_ADDRESS16: 309 /* 310 * 16-Bit Address Resource: 311 * Add the size of the optional ResourceSource info 312 */ 313 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 314 AcpiRsStructOptionLength ( 315 &Resource->Data.Address16.ResourceSource)); 316 break; 317 318 319 case ACPI_RESOURCE_TYPE_ADDRESS32: 320 /* 321 * 32-Bit Address Resource: 322 * Add the size of the optional ResourceSource info 323 */ 324 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 325 AcpiRsStructOptionLength ( 326 &Resource->Data.Address32.ResourceSource)); 327 break; 328 329 330 case ACPI_RESOURCE_TYPE_ADDRESS64: 331 /* 332 * 64-Bit Address Resource: 333 * Add the size of the optional ResourceSource info 334 */ 335 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 336 AcpiRsStructOptionLength ( 337 &Resource->Data.Address64.ResourceSource)); 338 break; 339 340 341 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 342 /* 343 * Extended IRQ Resource: 344 * Add the size of each additional optional interrupt beyond the 345 * required 1 (4 bytes for each UINT32 interrupt number) 346 */ 347 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 348 ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) + 349 350 /* Add the size of the optional ResourceSource info */ 351 352 AcpiRsStructOptionLength ( 353 &Resource->Data.ExtendedIrq.ResourceSource)); 354 break; 355 356 357 case ACPI_RESOURCE_TYPE_GPIO: 358 359 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 360 (Resource->Data.Gpio.PinTableLength * 2) + 361 Resource->Data.Gpio.ResourceSource.StringLength + 362 Resource->Data.Gpio.VendorLength); 363 364 break; 365 366 367 case ACPI_RESOURCE_TYPE_SERIAL_BUS: 368 369 TotalSize = AcpiGbl_AmlResourceSerialBusSizes [ 370 Resource->Data.CommonSerialBus.Type]; 371 372 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 373 Resource->Data.I2cSerialBus.ResourceSource.StringLength + 374 Resource->Data.I2cSerialBus.VendorLength); 375 376 break; 377 378 default: 379 380 break; 381 } 382 383 /* Update the total */ 384 385 AmlSizeNeeded += TotalSize; 386 387 /* Point to the next object */ 388 389 Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length); 390 } 391 392 /* Did not find an EndTag resource descriptor */ 393 394 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 395 } 396 397 398 /******************************************************************************* 399 * 400 * FUNCTION: AcpiRsGetListLength 401 * 402 * PARAMETERS: AmlBuffer - Pointer to the resource byte stream 403 * AmlBufferLength - Size of AmlBuffer 404 * SizeNeeded - Where the size needed is returned 405 * 406 * RETURN: Status 407 * 408 * DESCRIPTION: Takes an external resource byte stream and calculates the size 409 * buffer needed to hold the corresponding internal resource 410 * descriptor linked list. 411 * 412 ******************************************************************************/ 413 414 ACPI_STATUS 415 AcpiRsGetListLength ( 416 UINT8 *AmlBuffer, 417 UINT32 AmlBufferLength, 418 ACPI_SIZE *SizeNeeded) 419 { 420 ACPI_STATUS Status; 421 UINT8 *EndAml; 422 UINT8 *Buffer; 423 UINT32 BufferSize; 424 UINT16 Temp16; 425 UINT16 ResourceLength; 426 UINT32 ExtraStructBytes; 427 UINT8 ResourceIndex; 428 UINT8 MinimumAmlResourceLength; 429 AML_RESOURCE *AmlResource; 430 431 432 ACPI_FUNCTION_TRACE (RsGetListLength); 433 434 435 *SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */ 436 EndAml = AmlBuffer + AmlBufferLength; 437 438 /* Walk the list of AML resource descriptors */ 439 440 while (AmlBuffer < EndAml) 441 { 442 /* Validate the Resource Type and Resource Length */ 443 444 Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex); 445 if (ACPI_FAILURE (Status)) 446 { 447 /* 448 * Exit on failure. Cannot continue because the descriptor length 449 * may be bogus also. 450 */ 451 return_ACPI_STATUS (Status); 452 } 453 454 AmlResource = (void *) AmlBuffer; 455 456 /* Get the resource length and base (minimum) AML size */ 457 458 ResourceLength = AcpiUtGetResourceLength (AmlBuffer); 459 MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 460 461 /* 462 * Augment the size for descriptors with optional 463 * and/or variable length fields 464 */ 465 ExtraStructBytes = 0; 466 Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); 467 468 switch (AcpiUtGetResourceType (AmlBuffer)) 469 { 470 case ACPI_RESOURCE_NAME_IRQ: 471 /* 472 * IRQ Resource: 473 * Get the number of bits set in the 16-bit IRQ mask 474 */ 475 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 476 ExtraStructBytes = AcpiRsCountSetBits (Temp16); 477 break; 478 479 480 case ACPI_RESOURCE_NAME_DMA: 481 /* 482 * DMA Resource: 483 * Get the number of bits set in the 8-bit DMA mask 484 */ 485 ExtraStructBytes = AcpiRsCountSetBits (*Buffer); 486 break; 487 488 489 case ACPI_RESOURCE_NAME_VENDOR_SMALL: 490 case ACPI_RESOURCE_NAME_VENDOR_LARGE: 491 /* 492 * Vendor Resource: 493 * Get the number of vendor data bytes 494 */ 495 ExtraStructBytes = ResourceLength; 496 497 /* 498 * There is already one byte included in the minimum 499 * descriptor size. If there are extra struct bytes, 500 * subtract one from the count. 501 */ 502 if (ExtraStructBytes) 503 { 504 ExtraStructBytes--; 505 } 506 break; 507 508 509 case ACPI_RESOURCE_NAME_END_TAG: 510 /* 511 * End Tag: This is the normal exit 512 */ 513 return_ACPI_STATUS (AE_OK); 514 515 516 case ACPI_RESOURCE_NAME_ADDRESS32: 517 case ACPI_RESOURCE_NAME_ADDRESS16: 518 case ACPI_RESOURCE_NAME_ADDRESS64: 519 /* 520 * Address Resource: 521 * Add the size of the optional ResourceSource 522 */ 523 ExtraStructBytes = AcpiRsStreamOptionLength ( 524 ResourceLength, MinimumAmlResourceLength); 525 break; 526 527 528 case ACPI_RESOURCE_NAME_EXTENDED_IRQ: 529 /* 530 * Extended IRQ Resource: 531 * Using the InterruptTableLength, add 4 bytes for each additional 532 * interrupt. Note: at least one interrupt is required and is 533 * included in the minimum descriptor size (reason for the -1) 534 */ 535 ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); 536 537 /* Add the size of the optional ResourceSource */ 538 539 ExtraStructBytes += AcpiRsStreamOptionLength ( 540 ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); 541 break; 542 543 case ACPI_RESOURCE_NAME_GPIO: 544 545 /* Vendor data is optional */ 546 547 if (AmlResource->Gpio.VendorLength) 548 { 549 ExtraStructBytes += 550 AmlResource->Gpio.VendorOffset - 551 AmlResource->Gpio.PinTableOffset + 552 AmlResource->Gpio.VendorLength; 553 } 554 else 555 { 556 ExtraStructBytes += 557 AmlResource->LargeHeader.ResourceLength + 558 sizeof (AML_RESOURCE_LARGE_HEADER) - 559 AmlResource->Gpio.PinTableOffset; 560 } 561 break; 562 563 case ACPI_RESOURCE_NAME_SERIAL_BUS: 564 565 MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[ 566 AmlResource->CommonSerialBus.Type]; 567 ExtraStructBytes += 568 AmlResource->CommonSerialBus.ResourceLength - 569 MinimumAmlResourceLength; 570 break; 571 572 default: 573 574 break; 575 } 576 577 /* 578 * Update the required buffer size for the internal descriptor structs 579 * 580 * Important: Round the size up for the appropriate alignment. This 581 * is a requirement on IA64. 582 */ 583 if (AcpiUtGetResourceType (AmlBuffer) == 584 ACPI_RESOURCE_NAME_SERIAL_BUS) 585 { 586 BufferSize = AcpiGbl_ResourceStructSerialBusSizes[ 587 AmlResource->CommonSerialBus.Type] + ExtraStructBytes; 588 } 589 else 590 { 591 BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + 592 ExtraStructBytes; 593 } 594 595 BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); 596 *SizeNeeded += BufferSize; 597 598 ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, 599 "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 600 AcpiUtGetResourceType (AmlBuffer), 601 AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); 602 603 /* 604 * Point to the next resource within the AML stream using the length 605 * contained in the resource descriptor header 606 */ 607 AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); 608 } 609 610 /* Did not find an EndTag resource descriptor */ 611 612 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 613 } 614 615 616 /******************************************************************************* 617 * 618 * FUNCTION: AcpiRsGetPciRoutingTableLength 619 * 620 * PARAMETERS: PackageObject - Pointer to the package object 621 * BufferSizeNeeded - UINT32 pointer of the size buffer 622 * needed to properly return the 623 * parsed data 624 * 625 * RETURN: Status 626 * 627 * DESCRIPTION: Given a package representing a PCI routing table, this 628 * calculates the size of the corresponding linked list of 629 * descriptions. 630 * 631 ******************************************************************************/ 632 633 ACPI_STATUS 634 AcpiRsGetPciRoutingTableLength ( 635 ACPI_OPERAND_OBJECT *PackageObject, 636 ACPI_SIZE *BufferSizeNeeded) 637 { 638 UINT32 NumberOfElements; 639 ACPI_SIZE TempSizeNeeded = 0; 640 ACPI_OPERAND_OBJECT **TopObjectList; 641 UINT32 Index; 642 ACPI_OPERAND_OBJECT *PackageElement; 643 ACPI_OPERAND_OBJECT **SubObjectList; 644 BOOLEAN NameFound; 645 UINT32 TableIndex; 646 647 648 ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength); 649 650 651 NumberOfElements = PackageObject->Package.Count; 652 653 /* 654 * Calculate the size of the return buffer. 655 * The base size is the number of elements * the sizes of the 656 * structures. Additional space for the strings is added below. 657 * The minus one is to subtract the size of the UINT8 Source[1] 658 * member because it is added below. 659 * 660 * But each PRT_ENTRY structure has a pointer to a string and 661 * the size of that string must be found. 662 */ 663 TopObjectList = PackageObject->Package.Elements; 664 665 for (Index = 0; Index < NumberOfElements; Index++) 666 { 667 /* Dereference the subpackage */ 668 669 PackageElement = *TopObjectList; 670 671 /* We must have a valid Package object */ 672 673 if (!PackageElement || 674 (PackageElement->Common.Type != ACPI_TYPE_PACKAGE)) 675 { 676 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 677 } 678 679 /* 680 * The SubObjectList will now point to an array of the 681 * four IRQ elements: Address, Pin, Source and SourceIndex 682 */ 683 SubObjectList = PackageElement->Package.Elements; 684 685 /* Scan the IrqTableElements for the Source Name String */ 686 687 NameFound = FALSE; 688 689 for (TableIndex = 0; 690 TableIndex < PackageElement->Package.Count && !NameFound; 691 TableIndex++) 692 { 693 if (*SubObjectList && /* Null object allowed */ 694 695 ((ACPI_TYPE_STRING == 696 (*SubObjectList)->Common.Type) || 697 698 ((ACPI_TYPE_LOCAL_REFERENCE == 699 (*SubObjectList)->Common.Type) && 700 701 ((*SubObjectList)->Reference.Class == 702 ACPI_REFCLASS_NAME)))) 703 { 704 NameFound = TRUE; 705 } 706 else 707 { 708 /* Look at the next element */ 709 710 SubObjectList++; 711 } 712 } 713 714 TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 715 716 /* Was a String type found? */ 717 718 if (NameFound) 719 { 720 if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING) 721 { 722 /* 723 * The length String.Length field does not include the 724 * terminating NULL, add 1 725 */ 726 TempSizeNeeded += ((ACPI_SIZE) 727 (*SubObjectList)->String.Length + 1); 728 } 729 else 730 { 731 TempSizeNeeded += AcpiNsGetPathnameLength ( 732 (*SubObjectList)->Reference.Node); 733 } 734 } 735 else 736 { 737 /* 738 * If no name was found, then this is a NULL, which is 739 * translated as a UINT32 zero. 740 */ 741 TempSizeNeeded += sizeof (UINT32); 742 } 743 744 /* Round up the size since each element must be aligned */ 745 746 TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded); 747 748 /* Point to the next ACPI_OPERAND_OBJECT */ 749 750 TopObjectList++; 751 } 752 753 /* 754 * Add an extra element to the end of the list, essentially a 755 * NULL terminator 756 */ 757 *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 758 return_ACPI_STATUS (AE_OK); 759 } 760