1 /******************************************************************************* 2 * 3 * Module Name: rscalc - Calculate stream and list lengths 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 #define __RSCALC_C__ 45 46 #include "acpi.h" 47 #include "accommon.h" 48 #include "acresrc.h" 49 #include "acnamesp.h" 50 51 52 #define _COMPONENT ACPI_RESOURCES 53 ACPI_MODULE_NAME ("rscalc") 54 55 56 /* Local prototypes */ 57 58 static UINT8 59 AcpiRsCountSetBits ( 60 UINT16 BitField); 61 62 static ACPI_RS_LENGTH 63 AcpiRsStructOptionLength ( 64 ACPI_RESOURCE_SOURCE *ResourceSource); 65 66 static UINT32 67 AcpiRsStreamOptionLength ( 68 UINT32 ResourceLength, 69 UINT32 MinimumTotalLength); 70 71 72 /******************************************************************************* 73 * 74 * FUNCTION: AcpiRsCountSetBits 75 * 76 * PARAMETERS: BitField - Field in which to count bits 77 * 78 * RETURN: Number of bits set within the field 79 * 80 * DESCRIPTION: Count the number of bits set in a resource field. Used for 81 * (Short descriptor) interrupt and DMA lists. 82 * 83 ******************************************************************************/ 84 85 static UINT8 86 AcpiRsCountSetBits ( 87 UINT16 BitField) 88 { 89 UINT8 BitsSet; 90 91 92 ACPI_FUNCTION_ENTRY (); 93 94 95 for (BitsSet = 0; BitField; BitsSet++) 96 { 97 /* Zero the least significant bit that is set */ 98 99 BitField &= (UINT16) (BitField - 1); 100 } 101 102 return (BitsSet); 103 } 104 105 106 /******************************************************************************* 107 * 108 * FUNCTION: AcpiRsStructOptionLength 109 * 110 * PARAMETERS: ResourceSource - Pointer to optional descriptor field 111 * 112 * RETURN: Status 113 * 114 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 115 * ResourceSource fields in some Large descriptors. Used during 116 * list-to-stream conversion 117 * 118 ******************************************************************************/ 119 120 static ACPI_RS_LENGTH 121 AcpiRsStructOptionLength ( 122 ACPI_RESOURCE_SOURCE *ResourceSource) 123 { 124 ACPI_FUNCTION_ENTRY (); 125 126 127 /* 128 * If the ResourceSource string is valid, return the size of the string 129 * (StringLength includes the NULL terminator) plus the size of the 130 * ResourceSourceIndex (1). 131 */ 132 if (ResourceSource->StringPtr) 133 { 134 return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1)); 135 } 136 137 return (0); 138 } 139 140 141 /******************************************************************************* 142 * 143 * FUNCTION: AcpiRsStreamOptionLength 144 * 145 * PARAMETERS: ResourceLength - Length from the resource header 146 * MinimumTotalLength - Minimum length of this resource, before 147 * any optional fields. Includes header size 148 * 149 * RETURN: Length of optional string (0 if no string present) 150 * 151 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 152 * ResourceSource fields in some Large descriptors. Used during 153 * stream-to-list conversion 154 * 155 ******************************************************************************/ 156 157 static UINT32 158 AcpiRsStreamOptionLength ( 159 UINT32 ResourceLength, 160 UINT32 MinimumAmlResourceLength) 161 { 162 UINT32 StringLength = 0; 163 164 165 ACPI_FUNCTION_ENTRY (); 166 167 168 /* 169 * The ResourceSourceIndex and ResourceSource are optional elements of some 170 * Large-type resource descriptors. 171 */ 172 173 /* 174 * If the length of the actual resource descriptor is greater than the ACPI 175 * spec-defined minimum length, it means that a ResourceSourceIndex exists 176 * and is followed by a (required) null terminated string. The string length 177 * (including the null terminator) is the resource length minus the minimum 178 * length, minus one byte for the ResourceSourceIndex itself. 179 */ 180 if (ResourceLength > MinimumAmlResourceLength) 181 { 182 /* Compute the length of the optional string */ 183 184 StringLength = ResourceLength - MinimumAmlResourceLength - 1; 185 } 186 187 /* 188 * Round the length up to a multiple of the native word in order to 189 * guarantee that the entire resource descriptor is native word aligned 190 */ 191 return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength)); 192 } 193 194 195 /******************************************************************************* 196 * 197 * FUNCTION: AcpiRsGetAmlLength 198 * 199 * PARAMETERS: Resource - Pointer to the resource linked list 200 * ResourceListSize - Size of the resource linked list 201 * SizeNeeded - Where the required size is returned 202 * 203 * RETURN: Status 204 * 205 * DESCRIPTION: Takes a linked list of internal resource descriptors and 206 * calculates the size buffer needed to hold the corresponding 207 * external resource byte stream. 208 * 209 ******************************************************************************/ 210 211 ACPI_STATUS 212 AcpiRsGetAmlLength ( 213 ACPI_RESOURCE *Resource, 214 ACPI_SIZE ResourceListSize, 215 ACPI_SIZE *SizeNeeded) 216 { 217 ACPI_SIZE AmlSizeNeeded = 0; 218 ACPI_RESOURCE *ResourceEnd; 219 ACPI_RS_LENGTH TotalSize; 220 221 222 ACPI_FUNCTION_TRACE (RsGetAmlLength); 223 224 225 /* Traverse entire list of internal resource descriptors */ 226 227 ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize); 228 while (Resource < ResourceEnd) 229 { 230 /* Validate the descriptor type */ 231 232 if (Resource->Type > ACPI_RESOURCE_TYPE_MAX) 233 { 234 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 235 } 236 237 /* Sanity check the length. It must not be zero, or we loop forever */ 238 239 if (!Resource->Length) 240 { 241 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); 242 } 243 244 /* Get the base size of the (external stream) resource descriptor */ 245 246 TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type]; 247 248 /* 249 * Augment the base size for descriptors with optional and/or 250 * variable-length fields 251 */ 252 switch (Resource->Type) 253 { 254 case ACPI_RESOURCE_TYPE_IRQ: 255 256 /* Length can be 3 or 2 */ 257 258 if (Resource->Data.Irq.DescriptorLength == 2) 259 { 260 TotalSize--; 261 } 262 break; 263 264 265 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 266 267 /* Length can be 1 or 0 */ 268 269 if (Resource->Data.Irq.DescriptorLength == 0) 270 { 271 TotalSize--; 272 } 273 break; 274 275 276 case ACPI_RESOURCE_TYPE_VENDOR: 277 /* 278 * Vendor Defined Resource: 279 * For a Vendor Specific resource, if the Length is between 1 and 7 280 * it will be created as a Small Resource data type, otherwise it 281 * is a Large Resource data type. 282 */ 283 if (Resource->Data.Vendor.ByteLength > 7) 284 { 285 /* Base size of a Large resource descriptor */ 286 287 TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER); 288 } 289 290 /* Add the size of the vendor-specific data */ 291 292 TotalSize = (ACPI_RS_LENGTH) 293 (TotalSize + Resource->Data.Vendor.ByteLength); 294 break; 295 296 297 case ACPI_RESOURCE_TYPE_END_TAG: 298 /* 299 * End Tag: 300 * We are done -- return the accumulated total size. 301 */ 302 *SizeNeeded = AmlSizeNeeded + TotalSize; 303 304 /* Normal exit */ 305 306 return_ACPI_STATUS (AE_OK); 307 308 309 case ACPI_RESOURCE_TYPE_ADDRESS16: 310 /* 311 * 16-Bit Address Resource: 312 * Add the size of the optional ResourceSource info 313 */ 314 TotalSize = (ACPI_RS_LENGTH) 315 (TotalSize + AcpiRsStructOptionLength ( 316 &Resource->Data.Address16.ResourceSource)); 317 break; 318 319 320 case ACPI_RESOURCE_TYPE_ADDRESS32: 321 /* 322 * 32-Bit Address Resource: 323 * Add the size of the optional ResourceSource info 324 */ 325 TotalSize = (ACPI_RS_LENGTH) 326 (TotalSize + AcpiRsStructOptionLength ( 327 &Resource->Data.Address32.ResourceSource)); 328 break; 329 330 331 case ACPI_RESOURCE_TYPE_ADDRESS64: 332 /* 333 * 64-Bit Address Resource: 334 * Add the size of the optional ResourceSource info 335 */ 336 TotalSize = (ACPI_RS_LENGTH) 337 (TotalSize + AcpiRsStructOptionLength ( 338 &Resource->Data.Address64.ResourceSource)); 339 break; 340 341 342 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 343 /* 344 * Extended IRQ Resource: 345 * Add the size of each additional optional interrupt beyond the 346 * required 1 (4 bytes for each UINT32 interrupt number) 347 */ 348 TotalSize = (ACPI_RS_LENGTH) 349 (TotalSize + 350 ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) + 351 352 /* Add the size of the optional ResourceSource info */ 353 354 AcpiRsStructOptionLength ( 355 &Resource->Data.ExtendedIrq.ResourceSource)); 356 break; 357 358 359 case ACPI_RESOURCE_TYPE_GPIO: 360 361 TotalSize = (ACPI_RS_LENGTH) (TotalSize + (Resource->Data.Gpio.PinTableLength * 2) + 362 Resource->Data.Gpio.ResourceSource.StringLength + 363 Resource->Data.Gpio.VendorLength); 364 365 break; 366 367 368 case ACPI_RESOURCE_TYPE_SERIAL_BUS: 369 370 TotalSize = AcpiGbl_AmlResourceSerialBusSizes [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 += AmlResource->Gpio.VendorOffset - 550 AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength; 551 } 552 else 553 { 554 ExtraStructBytes += AmlResource->LargeHeader.ResourceLength + 555 sizeof (AML_RESOURCE_LARGE_HEADER) - 556 AmlResource->Gpio.PinTableOffset; 557 } 558 break; 559 560 case ACPI_RESOURCE_NAME_SERIAL_BUS: 561 562 MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[ 563 AmlResource->CommonSerialBus.Type]; 564 ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength - 565 MinimumAmlResourceLength; 566 break; 567 568 default: 569 570 break; 571 } 572 573 /* 574 * Update the required buffer size for the internal descriptor structs 575 * 576 * Important: Round the size up for the appropriate alignment. This 577 * is a requirement on IA64. 578 */ 579 if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS) 580 { 581 BufferSize = AcpiGbl_ResourceStructSerialBusSizes[ 582 AmlResource->CommonSerialBus.Type] + ExtraStructBytes; 583 } 584 else 585 { 586 BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + 587 ExtraStructBytes; 588 } 589 BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); 590 591 *SizeNeeded += BufferSize; 592 593 ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, 594 "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 595 AcpiUtGetResourceType (AmlBuffer), 596 AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); 597 598 /* 599 * Point to the next resource within the AML stream using the length 600 * contained in the resource descriptor header 601 */ 602 AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); 603 } 604 605 /* Did not find an EndTag resource descriptor */ 606 607 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 608 } 609 610 611 /******************************************************************************* 612 * 613 * FUNCTION: AcpiRsGetPciRoutingTableLength 614 * 615 * PARAMETERS: PackageObject - Pointer to the package object 616 * BufferSizeNeeded - UINT32 pointer of the size buffer 617 * needed to properly return the 618 * parsed data 619 * 620 * RETURN: Status 621 * 622 * DESCRIPTION: Given a package representing a PCI routing table, this 623 * calculates the size of the corresponding linked list of 624 * descriptions. 625 * 626 ******************************************************************************/ 627 628 ACPI_STATUS 629 AcpiRsGetPciRoutingTableLength ( 630 ACPI_OPERAND_OBJECT *PackageObject, 631 ACPI_SIZE *BufferSizeNeeded) 632 { 633 UINT32 NumberOfElements; 634 ACPI_SIZE TempSizeNeeded = 0; 635 ACPI_OPERAND_OBJECT **TopObjectList; 636 UINT32 Index; 637 ACPI_OPERAND_OBJECT *PackageElement; 638 ACPI_OPERAND_OBJECT **SubObjectList; 639 BOOLEAN NameFound; 640 UINT32 TableIndex; 641 642 643 ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength); 644 645 646 NumberOfElements = PackageObject->Package.Count; 647 648 /* 649 * Calculate the size of the return buffer. 650 * The base size is the number of elements * the sizes of the 651 * structures. Additional space for the strings is added below. 652 * The minus one is to subtract the size of the UINT8 Source[1] 653 * member because it is added below. 654 * 655 * But each PRT_ENTRY structure has a pointer to a string and 656 * the size of that string must be found. 657 */ 658 TopObjectList = PackageObject->Package.Elements; 659 660 for (Index = 0; Index < NumberOfElements; Index++) 661 { 662 /* Dereference the sub-package */ 663 664 PackageElement = *TopObjectList; 665 666 /* We must have a valid Package object */ 667 668 if (!PackageElement || 669 (PackageElement->Common.Type != ACPI_TYPE_PACKAGE)) 670 { 671 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 672 } 673 674 /* 675 * The SubObjectList will now point to an array of the 676 * four IRQ elements: Address, Pin, Source and SourceIndex 677 */ 678 SubObjectList = PackageElement->Package.Elements; 679 680 /* Scan the IrqTableElements for the Source Name String */ 681 682 NameFound = FALSE; 683 684 for (TableIndex = 0; 685 TableIndex < PackageElement->Package.Count && !NameFound; 686 TableIndex++) 687 { 688 if (*SubObjectList && /* Null object allowed */ 689 690 ((ACPI_TYPE_STRING == 691 (*SubObjectList)->Common.Type) || 692 693 ((ACPI_TYPE_LOCAL_REFERENCE == 694 (*SubObjectList)->Common.Type) && 695 696 ((*SubObjectList)->Reference.Class == 697 ACPI_REFCLASS_NAME)))) 698 { 699 NameFound = TRUE; 700 } 701 else 702 { 703 /* Look at the next element */ 704 705 SubObjectList++; 706 } 707 } 708 709 TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 710 711 /* Was a String type found? */ 712 713 if (NameFound) 714 { 715 if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING) 716 { 717 /* 718 * The length String.Length field does not include the 719 * terminating NULL, add 1 720 */ 721 TempSizeNeeded += ((ACPI_SIZE) 722 (*SubObjectList)->String.Length + 1); 723 } 724 else 725 { 726 TempSizeNeeded += AcpiNsGetPathnameLength ( 727 (*SubObjectList)->Reference.Node); 728 } 729 } 730 else 731 { 732 /* 733 * If no name was found, then this is a NULL, which is 734 * translated as a UINT32 zero. 735 */ 736 TempSizeNeeded += sizeof (UINT32); 737 } 738 739 /* Round up the size since each element must be aligned */ 740 741 TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded); 742 743 /* Point to the next ACPI_OPERAND_OBJECT */ 744 745 TopObjectList++; 746 } 747 748 /* 749 * Add an extra element to the end of the list, essentially a 750 * NULL terminator 751 */ 752 *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 753 return_ACPI_STATUS (AE_OK); 754 }