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