rscalc.c revision 67754
1/******************************************************************************* 2 * 3 * Module Name: rscalc - AcpiRsCalculateByteStreamLength 4 * AcpiRsCalculateListLength 5 * $Revision: 11 $ 6 * 7 ******************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 14 * reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118#define __RSCALC_C__ 119 120#include "acpi.h" 121 122#define _COMPONENT RESOURCE_MANAGER 123 MODULE_NAME ("rscalc") 124 125 126/******************************************************************************* 127 * 128 * FUNCTION: AcpiRsCalculateByteStreamLength 129 * 130 * PARAMETERS: LinkedList - Pointer to the resource linked list 131 * SizeNeeded - UINT32 pointer of the size buffer needed 132 * to properly return the parsed data 133 * 134 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 135 * 136 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 137 * the size buffer needed to hold the linked list that conveys 138 * the resource data. 139 * 140 ******************************************************************************/ 141 142ACPI_STATUS 143AcpiRsCalculateByteStreamLength ( 144 RESOURCE *LinkedList, 145 UINT32 *SizeNeeded) 146{ 147 UINT32 ByteStreamSizeNeeded = 0; 148 UINT32 SegmentSize; 149 EXTENDED_IRQ_RESOURCE *ExIrq = NULL; 150 BOOLEAN Done = FALSE; 151 152 153 FUNCTION_TRACE ("RsCalculateByteStreamLength"); 154 155 156 while (!Done) 157 { 158 159 /* 160 * Init the variable that will hold the size to add to the 161 * total. 162 */ 163 SegmentSize = 0; 164 165 switch (LinkedList->Id) 166 { 167 case Irq: 168 /* 169 * IRQ Resource 170 */ 171 /* 172 * For an IRQ Resource, Byte 3, although optional, will 173 * always be created - it holds IRQ information. 174 */ 175 SegmentSize = 4; 176 break; 177 178 case Dma: 179 /* 180 * DMA Resource 181 */ 182 /* 183 * For this resource the size is static 184 */ 185 SegmentSize = 3; 186 break; 187 188 case StartDependentFunctions: 189 /* 190 * Start Dependent Functions Resource 191 */ 192 /* 193 * For a StartDependentFunctions Resource, Byte 1, 194 * although optional, will always be created. 195 */ 196 SegmentSize = 2; 197 break; 198 199 case EndDependentFunctions: 200 /* 201 * End Dependent Functions Resource 202 */ 203 /* 204 * For this resource the size is static 205 */ 206 SegmentSize = 1; 207 break; 208 209 case Io: 210 /* 211 * IO Port Resource 212 */ 213 /* 214 * For this resource the size is static 215 */ 216 SegmentSize = 8; 217 break; 218 219 case FixedIo: 220 /* 221 * Fixed IO Port Resource 222 */ 223 /* 224 * For this resource the size is static 225 */ 226 SegmentSize = 4; 227 break; 228 229 case VendorSpecific: 230 /* 231 * Vendor Defined Resource 232 */ 233 /* 234 * For a Vendor Specific resource, if the Length is 235 * between 1 and 7 it will be created as a Small 236 * Resource data type, otherwise it is a Large 237 * Resource data type. 238 */ 239 if(LinkedList->Data.VendorSpecific.Length > 7) 240 { 241 SegmentSize = 3; 242 } 243 else 244 { 245 SegmentSize = 1; 246 } 247 SegmentSize += 248 LinkedList->Data.VendorSpecific.Length; 249 break; 250 251 case EndTag: 252 /* 253 * End Tag 254 */ 255 /* 256 * For this resource the size is static 257 */ 258 SegmentSize = 2; 259 Done = TRUE; 260 break; 261 262 case Memory24: 263 /* 264 * 24-Bit Memory Resource 265 */ 266 /* 267 * For this resource the size is static 268 */ 269 SegmentSize = 12; 270 break; 271 272 case Memory32: 273 /* 274 * 32-Bit Memory Range Resource 275 */ 276 /* 277 * For this resource the size is static 278 */ 279 SegmentSize = 20; 280 break; 281 282 case FixedMemory32: 283 /* 284 * 32-Bit Fixed Memory Resource 285 */ 286 /* 287 * For this resource the size is static 288 */ 289 SegmentSize = 12; 290 break; 291 292 case Address16: 293 /* 294 * 16-Bit Address Resource 295 */ 296 /* 297 * The base size of this byte stream is 16. If a 298 * Resource Source string is not NULL, add 1 for 299 * the Index + the length of the null terminated 300 * string Resource Source + 1 for the null. 301 */ 302 SegmentSize = 16; 303 304 if(NULL != LinkedList->Data.Address16.ResourceSource) 305 { 306 SegmentSize += (1 + 307 LinkedList->Data.Address16.ResourceSourceStringLength); 308 } 309 break; 310 311 case Address32: 312 /* 313 * 32-Bit Address Resource 314 */ 315 /* 316 * The base size of this byte stream is 26. If a Resource 317 * Source string is not NULL, add 1 for the Index + the 318 * length of the null terminated string Resource Source + 319 * 1 for the null. 320 */ 321 SegmentSize = 26; 322 323 if(NULL != LinkedList->Data.Address16.ResourceSource) 324 { 325 SegmentSize += (1 + 326 LinkedList->Data.Address16.ResourceSourceStringLength); 327 } 328 break; 329 330 case ExtendedIrq: 331 /* 332 * Extended IRQ Resource 333 */ 334 /* 335 * The base size of this byte stream is 9. This is for an 336 * Interrupt table length of 1. For each additional 337 * interrupt, add 4. 338 * If a Resource Source string is not NULL, add 1 for the 339 * Index + the length of the null terminated string 340 * Resource Source + 1 for the null. 341 */ 342 SegmentSize = 9; 343 344 SegmentSize += 345 (LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 346 1) * 4; 347 348 if(NULL != ExIrq->ResourceSource) 349 { 350 SegmentSize += (1 + 351 LinkedList->Data.ExtendedIrq.ResourceSourceStringLength); 352 } 353 break; 354 355 default: 356 /* 357 * If we get here, everything is out of sync, 358 * so exit with an error 359 */ 360 return_ACPI_STATUS (AE_AML_ERROR); 361 break; 362 363 } /* switch (LinkedList->Id) */ 364 365 /* 366 * Update the total 367 */ 368 ByteStreamSizeNeeded += SegmentSize; 369 370 /* 371 * Point to the next object 372 */ 373 LinkedList = (RESOURCE *) ((NATIVE_UINT) LinkedList + 374 (NATIVE_UINT) LinkedList->Length); 375 } 376 377 /* 378 * This is the data the caller needs 379 */ 380 *SizeNeeded = ByteStreamSizeNeeded; 381 382 return_ACPI_STATUS (AE_OK); 383} 384 385 386/******************************************************************************* 387 * 388 * FUNCTION: AcpiRsCalculateListLength 389 * 390 * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream 391 * ByteStreamBufferLength - Size of ByteStreamBuffer 392 * SizeNeeded - UINT32 pointer of the size buffer 393 * needed to properly return the 394 * parsed data 395 * 396 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 397 * 398 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 399 * the size buffer needed to hold the linked list that conveys 400 * the resource data. 401 * 402 ******************************************************************************/ 403 404ACPI_STATUS 405AcpiRsCalculateListLength ( 406 UINT8 *ByteStreamBuffer, 407 UINT32 ByteStreamBufferLength, 408 UINT32 *SizeNeeded) 409{ 410 UINT32 BufferSize = 0; 411 UINT32 BytesParsed = 0; 412 UINT8 NumberOfInterrupts = 0; 413 UINT8 NumberOfChannels = 0; 414 UINT8 ResourceType; 415 UINT32 StructureSize; 416 UINT32 BytesConsumed; 417 UINT8 *Buffer; 418 UINT8 Temp8; 419 UINT16 Temp16; 420 UINT8 Index; 421 UINT8 AdditionalBytes; 422 423 424 FUNCTION_TRACE ("RsCalculateListLength"); 425 426 427 while (BytesParsed < ByteStreamBufferLength) 428 { 429 /* 430 * Look at the next byte in the stream 431 */ 432 ResourceType = *ByteStreamBuffer; 433 434 /* 435 * See if this is a small or large resource 436 */ 437 if(ResourceType & 0x80) 438 { 439 /* 440 * Large Resource Type 441 */ 442 switch (ResourceType) 443 { 444 case MEMORY_RANGE_24: 445 /* 446 * 24-Bit Memory Resource 447 */ 448 BytesConsumed = 12; 449 450 StructureSize = sizeof (MEMORY24_RESOURCE) + 451 RESOURCE_LENGTH_NO_DATA; 452 break; 453 454 case LARGE_VENDOR_DEFINED: 455 /* 456 * Vendor Defined Resource 457 */ 458 Buffer = ByteStreamBuffer; 459 ++Buffer; 460 461 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 462 BytesConsumed = Temp16 + 3; 463 464 /* 465 * Ensure a 32-bit boundary for the structure 466 */ 467 Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16); 468 469 StructureSize = sizeof (VENDOR_RESOURCE) + 470 RESOURCE_LENGTH_NO_DATA + 471 (Temp16 * sizeof (UINT8)); 472 break; 473 474 case MEMORY_RANGE_32: 475 /* 476 * 32-Bit Memory Range Resource 477 */ 478 479 BytesConsumed = 20; 480 481 StructureSize = sizeof (MEMORY32_RESOURCE) + 482 RESOURCE_LENGTH_NO_DATA; 483 break; 484 485 case FIXED_MEMORY_RANGE_32: 486 /* 487 * 32-Bit Fixed Memory Resource 488 */ 489 BytesConsumed = 12; 490 491 StructureSize = sizeof(FIXED_MEMORY32_RESOURCE) + 492 RESOURCE_LENGTH_NO_DATA; 493 break; 494 495 case DWORD_ADDRESS_SPACE: 496 /* 497 * 32-Bit Address Resource 498 */ 499 Buffer = ByteStreamBuffer; 500 501 ++Buffer; 502 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 503 504 BytesConsumed = Temp16 + 3; 505 506 /* 507 * Resource Source Index and Resource Source are 508 * optional elements. Check the length of the 509 * Bytestream. If it is greater than 23, that 510 * means that an Index exists and is followed by 511 * a null termininated string. Therefore, set 512 * the temp variable to the length minus the minimum 513 * byte stream length plus the byte for the Index to 514 * determine the size of the NULL terminiated string. 515 */ 516 if (23 < Temp16) 517 { 518 Temp8 = (UINT8) (Temp16 - 24); 519 } 520 else 521 { 522 Temp8 = 0; 523 } 524 525 /* 526 * Ensure a 32-bit boundary for the structure 527 */ 528 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 529 530 StructureSize = sizeof (ADDRESS32_RESOURCE) + 531 RESOURCE_LENGTH_NO_DATA + 532 (Temp8 * sizeof (UINT8)); 533 break; 534 535 case WORD_ADDRESS_SPACE: 536 /* 537 * 16-Bit Address Resource 538 */ 539 Buffer = ByteStreamBuffer; 540 541 ++Buffer; 542 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 543 544 BytesConsumed = Temp16 + 3; 545 546 /* 547 * Resource Source Index and Resource Source are 548 * optional elements. Check the length of the 549 * Bytestream. If it is greater than 13, that 550 * means that an Index exists and is followed by 551 * a null termininated string. Therefore, set 552 * the temp variable to the length minus the minimum 553 * byte stream length plus the byte for the Index to 554 * determine the size of the NULL terminiated string. 555 */ 556 if (13 < Temp16) 557 { 558 Temp8 = (UINT8) (Temp16 - 14); 559 } 560 else 561 { 562 Temp8 = 0; 563 } 564 565 /* 566 * Ensure a 32-bit boundry for the structure 567 */ 568 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 569 570 StructureSize = sizeof (ADDRESS16_RESOURCE) + 571 RESOURCE_LENGTH_NO_DATA + 572 (Temp8 * sizeof (UINT8)); 573 break; 574 575 case EXTENDED_IRQ: 576 /* 577 * Extended IRQ 578 */ 579 Buffer = ByteStreamBuffer; 580 581 ++Buffer; 582 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 583 584 BytesConsumed = Temp16 + 3; 585 586 /* 587 * Point past the length field and the 588 * Interrupt vector flags to save off the 589 * Interrupt table length to the Temp8 variable. 590 */ 591 Buffer += 3; 592 Temp8 = *Buffer; 593 594 /* 595 * To compensate for multiple interrupt numbers, 596 * Add 4 bytes for each additional interrupts 597 * greater than 1 598 */ 599 AdditionalBytes = (UINT8) ((Temp8 - 1) * 4); 600 601 /* 602 * Resource Source Index and Resource Source are 603 * optional elements. Check the length of the 604 * Bytestream. If it is greater than 9, that 605 * means that an Index exists and is followed by 606 * a null termininated string. Therefore, set 607 * the temp variable to the length minus the minimum 608 * byte stream length plus the byte for the Index to 609 * determine the size of the NULL terminiated string. 610 */ 611 if (9 + AdditionalBytes < Temp16) 612 { 613 Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes)); 614 } 615 616 else 617 { 618 Temp8 = 0; 619 } 620 621 /* 622 * Ensure a 32-bit boundry for the structure 623 */ 624 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 625 626 StructureSize = sizeof (EXTENDED_IRQ_RESOURCE) + 627 RESOURCE_LENGTH_NO_DATA + 628 (AdditionalBytes * sizeof (UINT8)) + 629 (Temp8 * sizeof (UINT8)); 630 631 break; 632 633/* TBD: [Future] 64-bit not currently supported */ 634/* 635 case 0x8A: 636 break; 637*/ 638 639 default: 640 /* 641 * If we get here, everything is out of sync, 642 * so exit with an error 643 */ 644 return_ACPI_STATUS (AE_AML_ERROR); 645 break; 646 } 647 } 648 649 else 650 { 651 /* 652 * Small Resource Type 653 * Only bits 7:3 are valid 654 */ 655 ResourceType >>= 3; 656 657 switch (ResourceType) 658 { 659 case IRQ_FORMAT: 660 /* 661 * IRQ Resource 662 */ 663 /* 664 * Determine if it there are two or three 665 * trailing bytes 666 */ 667 Buffer = ByteStreamBuffer; 668 Temp8 = *Buffer; 669 670 if(Temp8 & 0x01) 671 { 672 BytesConsumed = 4; 673 } 674 675 else 676 { 677 BytesConsumed = 3; 678 } 679 680 /* 681 * Point past the descriptor 682 */ 683 ++Buffer; 684 685 /* 686 * Look at the number of bits set 687 */ 688 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 689 690 for (Index = 0; Index < 16; Index++) 691 { 692 if (Temp16 & 0x1) 693 { 694 ++NumberOfInterrupts; 695 } 696 697 Temp16 >>= 1; 698 } 699 700 StructureSize = sizeof (IO_RESOURCE) + 701 RESOURCE_LENGTH_NO_DATA + 702 (NumberOfInterrupts * sizeof (UINT32)); 703 break; 704 705 706 case DMA_FORMAT: 707 708 /* 709 * DMA Resource 710 */ 711 Buffer = ByteStreamBuffer; 712 713 BytesConsumed = 3; 714 715 /* 716 * Point past the descriptor 717 */ 718 ++Buffer; 719 720 /* 721 * Look at the number of bits set 722 */ 723 Temp8 = *Buffer; 724 725 for(Index = 0; Index < 8; Index++) 726 { 727 if(Temp8 & 0x1) 728 { 729 ++NumberOfChannels; 730 } 731 732 Temp8 >>= 1; 733 } 734 735 StructureSize = sizeof (DMA_RESOURCE) + 736 RESOURCE_LENGTH_NO_DATA + 737 (NumberOfChannels * sizeof (UINT32)); 738 break; 739 740 741 case START_DEPENDENT_TAG: 742 743 /* 744 * Start Dependent Functions Resource 745 */ 746 /* 747 * Determine if it there are two or three trailing bytes 748 */ 749 Buffer = ByteStreamBuffer; 750 Temp8 = *Buffer; 751 752 if(Temp8 & 0x01) 753 { 754 BytesConsumed = 2; 755 } 756 else 757 { 758 BytesConsumed = 1; 759 } 760 761 762 StructureSize = 763 sizeof (START_DEPENDENT_FUNCTIONS_RESOURCE) + 764 RESOURCE_LENGTH_NO_DATA; 765 break; 766 767 768 case END_DEPENDENT_TAG: 769 770 /* 771 * End Dependent Functions Resource 772 */ 773 BytesConsumed = 1; 774 StructureSize = RESOURCE_LENGTH; 775 break; 776 777 778 case IO_PORT_DESCRIPTOR: 779 /* 780 * IO Port Resource 781 */ 782 BytesConsumed = 8; 783 StructureSize = sizeof (IO_RESOURCE) + 784 RESOURCE_LENGTH_NO_DATA; 785 break; 786 787 788 case FIXED_LOCATION_IO_DESCRIPTOR: 789 790 /* 791 * Fixed IO Port Resource 792 */ 793 BytesConsumed = 4; 794 StructureSize = sizeof (FIXED_IO_RESOURCE) + 795 RESOURCE_LENGTH_NO_DATA; 796 break; 797 798 799 case SMALL_VENDOR_DEFINED: 800 801 /* 802 * Vendor Specific Resource 803 */ 804 Buffer = ByteStreamBuffer; 805 806 Temp8 = *Buffer; 807 Temp8 = (UINT8) (Temp8 & 0x7); 808 BytesConsumed = Temp8 + 1; 809 810 /* 811 * Ensure a 32-bit boundry for the structure 812 */ 813 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 814 StructureSize = sizeof (VENDOR_RESOURCE) + 815 RESOURCE_LENGTH_NO_DATA + 816 (Temp8 * sizeof (UINT8)); 817 break; 818 819 820 case END_TAG: 821 822 /* 823 * End Tag 824 */ 825 BytesConsumed = 2; 826 StructureSize = RESOURCE_LENGTH; 827 break; 828 829 830 default: 831 /* 832 * If we get here, everything is out of sync, 833 * so exit with an error 834 */ 835 return_ACPI_STATUS (AE_AML_ERROR); 836 break; 837 838 } /* switch */ 839 840 } /* if(ResourceType & 0x80) */ 841 842 /* 843 * Update the return value and counter 844 */ 845 BufferSize += StructureSize; 846 BytesParsed += BytesConsumed; 847 848 /* 849 * Set the byte stream to point to the next resource 850 */ 851 ByteStreamBuffer += BytesConsumed; 852 853 } 854 855 /* 856 * This is the data the caller needs 857 */ 858 *SizeNeeded = BufferSize; 859 860 return_ACPI_STATUS (AE_OK); 861} 862 863 864/******************************************************************************* 865 * 866 * FUNCTION: AcpiRsCalculatePciRoutingTableLength 867 * 868 * PARAMETERS: PackageObject - Pointer to the package object 869 * BufferSizeNeeded - UINT32 pointer of the size buffer 870 * needed to properly return the 871 * parsed data 872 * 873 * RETURN: Status AE_OK 874 * 875 * DESCRIPTION: Given a package representing a PCI routing table, this 876 * calculates the size of the corresponding linked list of 877 * descriptions. 878 * 879 ******************************************************************************/ 880 881ACPI_STATUS 882AcpiRsCalculatePciRoutingTableLength ( 883 ACPI_OPERAND_OBJECT *PackageObject, 884 UINT32 *BufferSizeNeeded) 885{ 886 UINT32 NumberOfElements; 887 UINT32 TempSizeNeeded; 888 ACPI_OPERAND_OBJECT **TopObjectList; 889 UINT32 Index; 890 ACPI_OPERAND_OBJECT *PackageElement; 891 ACPI_OPERAND_OBJECT **SubObjectList; 892 BOOLEAN NameFound; 893 UINT32 TableIndex; 894 895 896 FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength"); 897 898 899 NumberOfElements = PackageObject->Package.Count; 900 901 /* 902 * Calculate the size of the return buffer. 903 * The base size is the number of elements * the sizes of the 904 * structures. Additional space for the strings is added below. 905 * The minus one is to subtract the size of the UINT8 Source[1] 906 * member because it is added below. 907 * 908 * NOTE: The NumberOfElements is incremented by one to add an end 909 * table structure that is essentially a structure of zeros. 910 */ 911 TempSizeNeeded = (NumberOfElements + 1) * 912 (sizeof (PCI_ROUTING_TABLE) - 1); 913 914 /* 915 * But each PRT_ENTRY structure has a pointer to a string and 916 * the size of that string must be found. 917 */ 918 TopObjectList = PackageObject->Package.Elements; 919 920 for (Index = 0; Index < NumberOfElements; Index++) 921 { 922 /* 923 * Dereference the sub-package 924 */ 925 PackageElement = *TopObjectList; 926 927 /* 928 * The SubObjectList will now point to an array of the 929 * four IRQ elements: Address, Pin, Source and SourceIndex 930 */ 931 SubObjectList = PackageElement->Package.Elements; 932 933 /* 934 * Scan the IrqTableElements for the Source Name String 935 */ 936 NameFound = FALSE; 937 938 for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 939 { 940 if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) 941 { 942 NameFound = TRUE; 943 } 944 945 else 946 { 947 /* 948 * Look at the next element 949 */ 950 SubObjectList++; 951 } 952 } 953 954 /* 955 * Was a String type found? 956 */ 957 if (TRUE == NameFound) 958 { 959 /* 960 * The length String.Length field includes the 961 * terminating NULL 962 */ 963 TempSizeNeeded += (*SubObjectList)->String.Length; 964 } 965 966 else 967 { 968 /* 969 * If no name was found, then this is a NULL, which is 970 * translated as a UINT32 zero. 971 */ 972 TempSizeNeeded += sizeof(UINT32); 973 } 974 975 /* 976 * Point to the next ACPI_OPERAND_OBJECT 977 */ 978 TopObjectList++; 979 } 980 981 /* Align the count before returning it */ 982 983 *BufferSizeNeeded = ROUND_UP_TO_32BITS (TempSizeNeeded); 984 985 return_ACPI_STATUS (AE_OK); 986}