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