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 ACPI_RESOURCE_EXT_IRQ *ExIrq = NULL; 152 BOOLEAN Done = FALSE; 153 154 155 ACPI_FUNCTION_TRACE ("RsGetByteStreamLength"); 156 157 158 while (!Done) 159 { 160 /* 161 * Init the variable that will hold the size to add to the total. 162 */ 163 SegmentSize = 0; 164 165 switch (LinkedList->Id) 166 { 167 case ACPI_RSTYPE_IRQ: 168 /* 169 * IRQ Resource 170 * For an IRQ Resource, Byte 3, although optional, will 171 * always be created - it holds IRQ information. 172 */ 173 SegmentSize = 4; 174 break; 175 176 case ACPI_RSTYPE_DMA: 177 /* 178 * DMA Resource 179 * For this resource the size is static 180 */ 181 SegmentSize = 3; 182 break; 183 184 case ACPI_RSTYPE_START_DPF: 185 /* 186 * Start Dependent Functions Resource 187 * For a StartDependentFunctions Resource, Byte 1, 188 * although optional, will always be created. 189 */ 190 SegmentSize = 2; 191 break; 192 193 case ACPI_RSTYPE_END_DPF: 194 /* 195 * End Dependent Functions Resource 196 * For this resource the size is static 197 */ 198 SegmentSize = 1; 199 break; 200 201 case ACPI_RSTYPE_IO: 202 /* 203 * IO Port Resource 204 * For this resource the size is static 205 */ 206 SegmentSize = 8; 207 break; 208 209 case ACPI_RSTYPE_FIXED_IO: 210 /* 211 * Fixed IO Port Resource 212 * For this resource the size is static 213 */ 214 SegmentSize = 4; 215 break; 216 217 case ACPI_RSTYPE_VENDOR: 218 /* 219 * Vendor Defined Resource 220 * For a Vendor Specific resource, if the Length is 221 * between 1 and 7 it will be created as a Small 222 * Resource data type, otherwise it is a Large 223 * Resource data type. 224 */ 225 if (LinkedList->Data.VendorSpecific.Length > 7) 226 { 227 SegmentSize = 3; 228 } 229 else 230 { 231 SegmentSize = 1; 232 } 233 SegmentSize += LinkedList->Data.VendorSpecific.Length; 234 break; 235 236 case ACPI_RSTYPE_END_TAG: 237 /* 238 * End Tag 239 * For this resource the size is static 240 */ 241 SegmentSize = 2; 242 Done = TRUE; 243 break; 244 245 case ACPI_RSTYPE_MEM24: 246 /* 247 * 24-Bit Memory Resource 248 * For this resource the size is static 249 */ 250 SegmentSize = 12; 251 break; 252 253 case ACPI_RSTYPE_MEM32: 254 /* 255 * 32-Bit Memory Range Resource 256 * For this resource the size is static 257 */ 258 SegmentSize = 20; 259 break; 260 261 case ACPI_RSTYPE_FIXED_MEM32: 262 /* 263 * 32-Bit Fixed Memory Resource 264 * For this resource the size is static 265 */ 266 SegmentSize = 12; 267 break; 268 269 case ACPI_RSTYPE_ADDRESS16: 270 /* 271 * 16-Bit Address Resource 272 * The base size of this byte stream is 16. If a 273 * Resource Source string is not NULL, add 1 for 274 * the Index + the length of the null terminated 275 * string Resource Source + 1 for the null. 276 */ 277 SegmentSize = 16; 278 279 if (LinkedList->Data.Address16.ResourceSource.StringPtr) 280 { 281 SegmentSize += LinkedList->Data.Address16.ResourceSource.StringLength; 282 SegmentSize++; 283 } 284 break; 285 286 case ACPI_RSTYPE_ADDRESS32: 287 /* 288 * 32-Bit Address Resource 289 * The base size of this byte stream is 26. If a Resource 290 * Source string is not NULL, add 1 for the Index + the 291 * length of the null terminated string Resource Source + 292 * 1 for the null. 293 */ 294 SegmentSize = 26; 295 296 if (LinkedList->Data.Address32.ResourceSource.StringPtr) 297 { 298 SegmentSize += LinkedList->Data.Address32.ResourceSource.StringLength; 299 SegmentSize++; 300 } 301 break; 302 303 case ACPI_RSTYPE_ADDRESS64: 304 /* 305 * 64-Bit Address Resource 306 * The base size of this byte stream is 46. If a Resource 307 * Source string is not NULL, add 1 for the Index + the 308 * length of the null terminated string Resource Source + 309 * 1 for the null. 310 */ 311 SegmentSize = 46; 312 313 if (LinkedList->Data.Address64.ResourceSource.StringPtr) 314 { 315 SegmentSize += LinkedList->Data.Address64.ResourceSource.StringLength; 316 SegmentSize++; 317 } 318 break; 319 320 case ACPI_RSTYPE_EXT_IRQ: 321 /* 322 * Extended IRQ Resource 323 * The base size of this byte stream is 9. This is for an 324 * Interrupt table length of 1. For each additional 325 * interrupt, add 4. 326 * If a Resource Source string is not NULL, add 1 for the 327 * Index + the length of the null terminated string 328 * Resource Source + 1 for the null. 329 */ 330 SegmentSize = 9 + 331 (((ACPI_SIZE) LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4); 332 333 if (ExIrq && ExIrq->ResourceSource.StringPtr) 334 { 335 SegmentSize += LinkedList->Data.ExtendedIrq.ResourceSource.StringLength; 336 SegmentSize++; 337 } 338 break; 339 340 default: 341 /* 342 * If we get here, everything is out of sync, 343 * so exit with an error 344 */ 345 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 346 347 } /* switch (LinkedList->Id) */ 348 349 /* 350 * Update the total 351 */ 352 ByteStreamSizeNeeded += SegmentSize; 353 354 /* 355 * Point to the next object 356 */ 357 LinkedList = ACPI_PTR_ADD (ACPI_RESOURCE, 358 LinkedList, LinkedList->Length); 359 } 360 361 /* 362 * This is the data the caller needs 363 */ 364 *SizeNeeded = ByteStreamSizeNeeded; 365 return_ACPI_STATUS (AE_OK); 366} 367 368 369/******************************************************************************* 370 * 371 * FUNCTION: AcpiRsGetListLength 372 * 373 * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream 374 * ByteStreamBufferLength - Size of ByteStreamBuffer 375 * SizeNeeded - UINT32 pointer of the size buffer 376 * needed to properly return the 377 * parsed data 378 * 379 * RETURN: Status 380 * 381 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 382 * the size buffer needed to hold the linked list that conveys 383 * the resource data. 384 * 385 ******************************************************************************/ 386 387ACPI_STATUS 388AcpiRsGetListLength ( 389 UINT8 *ByteStreamBuffer, 390 UINT32 ByteStreamBufferLength, 391 ACPI_SIZE *SizeNeeded) 392{ 393 UINT32 BufferSize = 0; 394 UINT32 BytesParsed = 0; 395 UINT8 NumberOfInterrupts = 0; 396 UINT8 NumberOfChannels = 0; 397 UINT8 ResourceType; 398 UINT32 StructureSize; 399 UINT32 BytesConsumed; 400 UINT8 *Buffer; 401 UINT8 Temp8; 402 UINT16 Temp16; 403 UINT8 Index; 404 UINT8 AdditionalBytes; 405 406 407 ACPI_FUNCTION_TRACE ("RsGetListLength"); 408 409 410 while (BytesParsed < ByteStreamBufferLength) 411 { 412 /* 413 * The next byte in the stream is the resource type 414 */ 415 ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer); 416 417 switch (ResourceType) 418 { 419 case ACPI_RDESC_TYPE_MEMORY_24: 420 /* 421 * 24-Bit Memory Resource 422 */ 423 BytesConsumed = 12; 424 425 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24); 426 break; 427 428 429 case ACPI_RDESC_TYPE_LARGE_VENDOR: 430 /* 431 * Vendor Defined Resource 432 */ 433 Buffer = ByteStreamBuffer; 434 ++Buffer; 435 436 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 437 BytesConsumed = Temp16 + 3; 438 439 /* 440 * Ensure a 32-bit boundary for the structure 441 */ 442 Temp16 = (UINT16) ACPI_ROUND_UP_TO_32BITS (Temp16); 443 444 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 445 (Temp16 * sizeof (UINT8)); 446 break; 447 448 449 case ACPI_RDESC_TYPE_MEMORY_32: 450 /* 451 * 32-Bit Memory Range Resource 452 */ 453 454 BytesConsumed = 20; 455 456 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32); 457 break; 458 459 460 case ACPI_RDESC_TYPE_FIXED_MEMORY_32: 461 /* 462 * 32-Bit Fixed Memory Resource 463 */ 464 BytesConsumed = 12; 465 466 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32); 467 break; 468 469 470 case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: 471 /* 472 * 64-Bit Address Resource 473 */ 474 Buffer = ByteStreamBuffer; 475 476 ++Buffer; 477 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 478 479 BytesConsumed = Temp16 + 3; 480 481 /* 482 * Resource Source Index and Resource Source are 483 * optional elements. Check the length of the 484 * Bytestream. If it is greater than 43, that 485 * means that an Index exists and is followed by 486 * a null termininated string. Therefore, set 487 * the temp variable to the length minus the minimum 488 * byte stream length plus the byte for the Index to 489 * determine the size of the NULL terminiated string. 490 */ 491 if (43 < Temp16) 492 { 493 Temp8 = (UINT8) (Temp16 - 44); 494 } 495 else 496 { 497 Temp8 = 0; 498 } 499 500 /* 501 * Ensure a 64-bit boundary for the structure 502 */ 503 Temp8 = (UINT8) ACPI_ROUND_UP_TO_64BITS (Temp8); 504 505 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) + 506 (Temp8 * sizeof (UINT8)); 507 break; 508 509 510 case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: 511 /* 512 * 32-Bit Address Resource 513 */ 514 Buffer = ByteStreamBuffer; 515 516 ++Buffer; 517 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 518 519 BytesConsumed = Temp16 + 3; 520 521 /* 522 * Resource Source Index and Resource Source are 523 * optional elements. Check the length of the 524 * Bytestream. If it is greater than 23, that 525 * means that an Index exists and is followed by 526 * a null termininated string. Therefore, set 527 * the temp variable to the length minus the minimum 528 * byte stream length plus the byte for the Index to 529 * determine the size of the NULL terminiated string. 530 */ 531 if (23 < Temp16) 532 { 533 Temp8 = (UINT8) (Temp16 - 24); 534 } 535 else 536 { 537 Temp8 = 0; 538 } 539 540 /* 541 * Ensure a 32-bit boundary for the structure 542 */ 543 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 544 545 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) + 546 (Temp8 * sizeof (UINT8)); 547 break; 548 549 550 case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: 551 /* 552 * 16-Bit Address Resource 553 */ 554 Buffer = ByteStreamBuffer; 555 556 ++Buffer; 557 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 558 559 BytesConsumed = Temp16 + 3; 560 561 /* 562 * Resource Source Index and Resource Source are 563 * optional elements. Check the length of the 564 * Bytestream. If it is greater than 13, that 565 * means that an Index exists and is followed by 566 * a null termininated string. Therefore, set 567 * the temp variable to the length minus the minimum 568 * byte stream length plus the byte for the Index to 569 * determine the size of the NULL terminiated string. 570 */ 571 if (13 < Temp16) 572 { 573 Temp8 = (UINT8) (Temp16 - 14); 574 } 575 else 576 { 577 Temp8 = 0; 578 } 579 580 /* 581 * Ensure a 32-bit boundary for the structure 582 */ 583 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 584 585 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) + 586 (Temp8 * sizeof (UINT8)); 587 break; 588 589 590 case ACPI_RDESC_TYPE_EXTENDED_XRUPT: 591 /* 592 * Extended IRQ 593 */ 594 Buffer = ByteStreamBuffer; 595 596 ++Buffer; 597 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 598 599 BytesConsumed = Temp16 + 3; 600 601 /* 602 * Point past the length field and the 603 * Interrupt vector flags to save off the 604 * Interrupt table length to the Temp8 variable. 605 */ 606 Buffer += 3; 607 Temp8 = *Buffer; 608 609 /* 610 * To compensate for multiple interrupt numbers, add 4 bytes for 611 * each additional interrupts greater than 1 612 */ 613 AdditionalBytes = (UINT8) ((Temp8 - 1) * 4); 614 615 /* 616 * Resource Source Index and Resource Source are 617 * optional elements. Check the length of the 618 * Bytestream. If it is greater than 9, that 619 * means that an Index exists and is followed by 620 * a null termininated string. Therefore, set 621 * the temp variable to the length minus the minimum 622 * byte stream length plus the byte for the Index to 623 * determine the size of the NULL terminiated string. 624 */ 625 if (9 + AdditionalBytes < Temp16) 626 { 627 Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes)); 628 } 629 else 630 { 631 Temp8 = 0; 632 } 633 634 /* 635 * Ensure a 32-bit boundary for the structure 636 */ 637 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 638 639 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) + 640 (AdditionalBytes * sizeof (UINT8)) + 641 (Temp8 * sizeof (UINT8)); 642 break; 643 644 645 case ACPI_RDESC_TYPE_IRQ_FORMAT: 646 /* 647 * IRQ Resource. 648 * Determine if it there are two or three trailing bytes 649 */ 650 Buffer = ByteStreamBuffer; 651 Temp8 = *Buffer; 652 653 if(Temp8 & 0x01) 654 { 655 BytesConsumed = 4; 656 } 657 else 658 { 659 BytesConsumed = 3; 660 } 661 662 /* 663 * Point past the descriptor 664 */ 665 ++Buffer; 666 667 /* 668 * Look at the number of bits set 669 */ 670 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 671 672 for (Index = 0; Index < 16; Index++) 673 { 674 if (Temp16 & 0x1) 675 { 676 ++NumberOfInterrupts; 677 } 678 679 Temp16 >>= 1; 680 } 681 682 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO) + 683 (NumberOfInterrupts * sizeof (UINT32)); 684 break; 685 686 687 case ACPI_RDESC_TYPE_DMA_FORMAT: 688 /* 689 * DMA Resource 690 */ 691 Buffer = ByteStreamBuffer; 692 BytesConsumed = 3; 693 694 /* 695 * Point past the descriptor 696 */ 697 ++Buffer; 698 699 /* 700 * Look at the number of bits set 701 */ 702 Temp8 = *Buffer; 703 704 for(Index = 0; Index < 8; Index++) 705 { 706 if(Temp8 & 0x1) 707 { 708 ++NumberOfChannels; 709 } 710 711 Temp8 >>= 1; 712 } 713 714 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) + 715 (NumberOfChannels * sizeof (UINT32)); 716 break; 717 718 719 case ACPI_RDESC_TYPE_START_DEPENDENT: 720 /* 721 * Start Dependent Functions Resource 722 * Determine if it there are two or three trailing bytes 723 */ 724 Buffer = ByteStreamBuffer; 725 Temp8 = *Buffer; 726 727 if(Temp8 & 0x01) 728 { 729 BytesConsumed = 2; 730 } 731 else 732 { 733 BytesConsumed = 1; 734 } 735 736 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF); 737 break; 738 739 740 case ACPI_RDESC_TYPE_END_DEPENDENT: 741 /* 742 * End Dependent Functions Resource 743 */ 744 BytesConsumed = 1; 745 StructureSize = ACPI_RESOURCE_LENGTH; 746 break; 747 748 749 case ACPI_RDESC_TYPE_IO_PORT: 750 /* 751 * IO Port Resource 752 */ 753 BytesConsumed = 8; 754 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO); 755 break; 756 757 758 case ACPI_RDESC_TYPE_FIXED_IO_PORT: 759 /* 760 * Fixed IO Port Resource 761 */ 762 BytesConsumed = 4; 763 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO); 764 break; 765 766 767 case ACPI_RDESC_TYPE_SMALL_VENDOR: 768 /* 769 * Vendor Specific Resource 770 */ 771 Buffer = ByteStreamBuffer; 772 773 Temp8 = *Buffer; 774 Temp8 = (UINT8) (Temp8 & 0x7); 775 BytesConsumed = Temp8 + 1; 776 777 /* 778 * Ensure a 32-bit boundary for the structure 779 */ 780 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 781 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 782 (Temp8 * sizeof (UINT8)); 783 break; 784 785 786 case ACPI_RDESC_TYPE_END_TAG: 787 /* 788 * End Tag 789 */ 790 BytesConsumed = 2; 791 StructureSize = ACPI_RESOURCE_LENGTH; 792 ByteStreamBufferLength = BytesParsed; 793 break; 794 795 796 default: 797 /* 798 * If we get here, everything is out of sync, 799 * exit with an error 800 */ 801 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 802 } 803 804 /* 805 * Update the return value and counter 806 */ 807 BufferSize += (UINT32) ACPI_ALIGN_RESOURCE_SIZE (StructureSize); 808 BytesParsed += BytesConsumed; 809 810 /* 811 * Set the byte stream to point to the next resource 812 */ 813 ByteStreamBuffer += BytesConsumed; 814 } 815 816 /* 817 * This is the data the caller needs 818 */ 819 *SizeNeeded = BufferSize; 820 return_ACPI_STATUS (AE_OK); 821} 822 823 824/******************************************************************************* 825 * 826 * FUNCTION: AcpiRsGetPciRoutingTableLength 827 * 828 * PARAMETERS: PackageObject - Pointer to the package object 829 * BufferSizeNeeded - UINT32 pointer of the size buffer 830 * needed to properly return the 831 * parsed data 832 * 833 * RETURN: Status 834 * 835 * DESCRIPTION: Given a package representing a PCI routing table, this 836 * calculates the size of the corresponding linked list of 837 * descriptions. 838 * 839 ******************************************************************************/ 840 841ACPI_STATUS 842AcpiRsGetPciRoutingTableLength ( 843 ACPI_OPERAND_OBJECT *PackageObject, 844 ACPI_SIZE *BufferSizeNeeded) 845{ 846 UINT32 NumberOfElements; 847 ACPI_SIZE TempSizeNeeded = 0; 848 ACPI_OPERAND_OBJECT **TopObjectList; 849 UINT32 Index; 850 ACPI_OPERAND_OBJECT *PackageElement; 851 ACPI_OPERAND_OBJECT **SubObjectList; 852 BOOLEAN NameFound; 853 UINT32 TableIndex; 854 855 856 ACPI_FUNCTION_TRACE ("RsGetPciRoutingTableLength"); 857 858 859 NumberOfElements = PackageObject->Package.Count; 860 861 /* 862 * Calculate the size of the return buffer. 863 * The base size is the number of elements * the sizes of the 864 * structures. Additional space for the strings is added below. 865 * The minus one is to subtract the size of the UINT8 Source[1] 866 * member because it is added below. 867 * 868 * But each PRT_ENTRY structure has a pointer to a string and 869 * the size of that string must be found. 870 */ 871 TopObjectList = PackageObject->Package.Elements; 872 873 for (Index = 0; Index < NumberOfElements; Index++) 874 { 875 /* 876 * Dereference the sub-package 877 */ 878 PackageElement = *TopObjectList; 879 880 /* 881 * The SubObjectList will now point to an array of the 882 * four IRQ elements: Address, Pin, Source and SourceIndex 883 */ 884 SubObjectList = PackageElement->Package.Elements; 885 886 /* 887 * Scan the IrqTableElements for the Source Name String 888 */ 889 NameFound = FALSE; 890 891 for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 892 { 893 if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*SubObjectList)) || 894 ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*SubObjectList)) && 895 ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP))) 896 { 897 NameFound = TRUE; 898 } 899 else 900 { 901 /* 902 * Look at the next element 903 */ 904 SubObjectList++; 905 } 906 } 907 908 TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 909 910 /* 911 * Was a String type found? 912 */ 913 if (NameFound) 914 { 915 if (ACPI_GET_OBJECT_TYPE (*SubObjectList) == ACPI_TYPE_STRING) 916 { 917 /* 918 * The length String.Length field does not include the 919 * terminating NULL, add 1 920 */ 921 TempSizeNeeded += ((ACPI_SIZE) (*SubObjectList)->String.Length + 1); 922 } 923 else 924 { 925 TempSizeNeeded += AcpiNsGetPathnameLength ( 926 (*SubObjectList)->Reference.Node); 927 } 928 } 929 else 930 { 931 /* 932 * If no name was found, then this is a NULL, which is 933 * translated as a UINT32 zero. 934 */ 935 TempSizeNeeded += sizeof (UINT32); 936 } 937 938 /* Round up the size since each element must be aligned */ 939 940 TempSizeNeeded = ACPI_ROUND_UP_TO_64BITS (TempSizeNeeded); 941 942 /* 943 * Point to the next ACPI_OPERAND_OBJECT 944 */ 945 TopObjectList++; 946 } 947 948 /* 949 * Adding an extra element to the end of the list, essentially a NULL terminator 950 */ 951 *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 952 return_ACPI_STATUS (AE_OK); 953}
| 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 ACPI_RESOURCE_EXT_IRQ *ExIrq = NULL; 152 BOOLEAN Done = FALSE; 153 154 155 ACPI_FUNCTION_TRACE ("RsGetByteStreamLength"); 156 157 158 while (!Done) 159 { 160 /* 161 * Init the variable that will hold the size to add to the total. 162 */ 163 SegmentSize = 0; 164 165 switch (LinkedList->Id) 166 { 167 case ACPI_RSTYPE_IRQ: 168 /* 169 * IRQ Resource 170 * For an IRQ Resource, Byte 3, although optional, will 171 * always be created - it holds IRQ information. 172 */ 173 SegmentSize = 4; 174 break; 175 176 case ACPI_RSTYPE_DMA: 177 /* 178 * DMA Resource 179 * For this resource the size is static 180 */ 181 SegmentSize = 3; 182 break; 183 184 case ACPI_RSTYPE_START_DPF: 185 /* 186 * Start Dependent Functions Resource 187 * For a StartDependentFunctions Resource, Byte 1, 188 * although optional, will always be created. 189 */ 190 SegmentSize = 2; 191 break; 192 193 case ACPI_RSTYPE_END_DPF: 194 /* 195 * End Dependent Functions Resource 196 * For this resource the size is static 197 */ 198 SegmentSize = 1; 199 break; 200 201 case ACPI_RSTYPE_IO: 202 /* 203 * IO Port Resource 204 * For this resource the size is static 205 */ 206 SegmentSize = 8; 207 break; 208 209 case ACPI_RSTYPE_FIXED_IO: 210 /* 211 * Fixed IO Port Resource 212 * For this resource the size is static 213 */ 214 SegmentSize = 4; 215 break; 216 217 case ACPI_RSTYPE_VENDOR: 218 /* 219 * Vendor Defined Resource 220 * For a Vendor Specific resource, if the Length is 221 * between 1 and 7 it will be created as a Small 222 * Resource data type, otherwise it is a Large 223 * Resource data type. 224 */ 225 if (LinkedList->Data.VendorSpecific.Length > 7) 226 { 227 SegmentSize = 3; 228 } 229 else 230 { 231 SegmentSize = 1; 232 } 233 SegmentSize += LinkedList->Data.VendorSpecific.Length; 234 break; 235 236 case ACPI_RSTYPE_END_TAG: 237 /* 238 * End Tag 239 * For this resource the size is static 240 */ 241 SegmentSize = 2; 242 Done = TRUE; 243 break; 244 245 case ACPI_RSTYPE_MEM24: 246 /* 247 * 24-Bit Memory Resource 248 * For this resource the size is static 249 */ 250 SegmentSize = 12; 251 break; 252 253 case ACPI_RSTYPE_MEM32: 254 /* 255 * 32-Bit Memory Range Resource 256 * For this resource the size is static 257 */ 258 SegmentSize = 20; 259 break; 260 261 case ACPI_RSTYPE_FIXED_MEM32: 262 /* 263 * 32-Bit Fixed Memory Resource 264 * For this resource the size is static 265 */ 266 SegmentSize = 12; 267 break; 268 269 case ACPI_RSTYPE_ADDRESS16: 270 /* 271 * 16-Bit Address Resource 272 * The base size of this byte stream is 16. If a 273 * Resource Source string is not NULL, add 1 for 274 * the Index + the length of the null terminated 275 * string Resource Source + 1 for the null. 276 */ 277 SegmentSize = 16; 278 279 if (LinkedList->Data.Address16.ResourceSource.StringPtr) 280 { 281 SegmentSize += LinkedList->Data.Address16.ResourceSource.StringLength; 282 SegmentSize++; 283 } 284 break; 285 286 case ACPI_RSTYPE_ADDRESS32: 287 /* 288 * 32-Bit Address Resource 289 * The base size of this byte stream is 26. If a Resource 290 * Source string is not NULL, add 1 for the Index + the 291 * length of the null terminated string Resource Source + 292 * 1 for the null. 293 */ 294 SegmentSize = 26; 295 296 if (LinkedList->Data.Address32.ResourceSource.StringPtr) 297 { 298 SegmentSize += LinkedList->Data.Address32.ResourceSource.StringLength; 299 SegmentSize++; 300 } 301 break; 302 303 case ACPI_RSTYPE_ADDRESS64: 304 /* 305 * 64-Bit Address Resource 306 * The base size of this byte stream is 46. If a Resource 307 * Source string is not NULL, add 1 for the Index + the 308 * length of the null terminated string Resource Source + 309 * 1 for the null. 310 */ 311 SegmentSize = 46; 312 313 if (LinkedList->Data.Address64.ResourceSource.StringPtr) 314 { 315 SegmentSize += LinkedList->Data.Address64.ResourceSource.StringLength; 316 SegmentSize++; 317 } 318 break; 319 320 case ACPI_RSTYPE_EXT_IRQ: 321 /* 322 * Extended IRQ Resource 323 * The base size of this byte stream is 9. This is for an 324 * Interrupt table length of 1. For each additional 325 * interrupt, add 4. 326 * If a Resource Source string is not NULL, add 1 for the 327 * Index + the length of the null terminated string 328 * Resource Source + 1 for the null. 329 */ 330 SegmentSize = 9 + 331 (((ACPI_SIZE) LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4); 332 333 if (ExIrq && ExIrq->ResourceSource.StringPtr) 334 { 335 SegmentSize += LinkedList->Data.ExtendedIrq.ResourceSource.StringLength; 336 SegmentSize++; 337 } 338 break; 339 340 default: 341 /* 342 * If we get here, everything is out of sync, 343 * so exit with an error 344 */ 345 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 346 347 } /* switch (LinkedList->Id) */ 348 349 /* 350 * Update the total 351 */ 352 ByteStreamSizeNeeded += SegmentSize; 353 354 /* 355 * Point to the next object 356 */ 357 LinkedList = ACPI_PTR_ADD (ACPI_RESOURCE, 358 LinkedList, LinkedList->Length); 359 } 360 361 /* 362 * This is the data the caller needs 363 */ 364 *SizeNeeded = ByteStreamSizeNeeded; 365 return_ACPI_STATUS (AE_OK); 366} 367 368 369/******************************************************************************* 370 * 371 * FUNCTION: AcpiRsGetListLength 372 * 373 * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream 374 * ByteStreamBufferLength - Size of ByteStreamBuffer 375 * SizeNeeded - UINT32 pointer of the size buffer 376 * needed to properly return the 377 * parsed data 378 * 379 * RETURN: Status 380 * 381 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 382 * the size buffer needed to hold the linked list that conveys 383 * the resource data. 384 * 385 ******************************************************************************/ 386 387ACPI_STATUS 388AcpiRsGetListLength ( 389 UINT8 *ByteStreamBuffer, 390 UINT32 ByteStreamBufferLength, 391 ACPI_SIZE *SizeNeeded) 392{ 393 UINT32 BufferSize = 0; 394 UINT32 BytesParsed = 0; 395 UINT8 NumberOfInterrupts = 0; 396 UINT8 NumberOfChannels = 0; 397 UINT8 ResourceType; 398 UINT32 StructureSize; 399 UINT32 BytesConsumed; 400 UINT8 *Buffer; 401 UINT8 Temp8; 402 UINT16 Temp16; 403 UINT8 Index; 404 UINT8 AdditionalBytes; 405 406 407 ACPI_FUNCTION_TRACE ("RsGetListLength"); 408 409 410 while (BytesParsed < ByteStreamBufferLength) 411 { 412 /* 413 * The next byte in the stream is the resource type 414 */ 415 ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer); 416 417 switch (ResourceType) 418 { 419 case ACPI_RDESC_TYPE_MEMORY_24: 420 /* 421 * 24-Bit Memory Resource 422 */ 423 BytesConsumed = 12; 424 425 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24); 426 break; 427 428 429 case ACPI_RDESC_TYPE_LARGE_VENDOR: 430 /* 431 * Vendor Defined Resource 432 */ 433 Buffer = ByteStreamBuffer; 434 ++Buffer; 435 436 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 437 BytesConsumed = Temp16 + 3; 438 439 /* 440 * Ensure a 32-bit boundary for the structure 441 */ 442 Temp16 = (UINT16) ACPI_ROUND_UP_TO_32BITS (Temp16); 443 444 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 445 (Temp16 * sizeof (UINT8)); 446 break; 447 448 449 case ACPI_RDESC_TYPE_MEMORY_32: 450 /* 451 * 32-Bit Memory Range Resource 452 */ 453 454 BytesConsumed = 20; 455 456 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32); 457 break; 458 459 460 case ACPI_RDESC_TYPE_FIXED_MEMORY_32: 461 /* 462 * 32-Bit Fixed Memory Resource 463 */ 464 BytesConsumed = 12; 465 466 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32); 467 break; 468 469 470 case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: 471 /* 472 * 64-Bit Address Resource 473 */ 474 Buffer = ByteStreamBuffer; 475 476 ++Buffer; 477 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 478 479 BytesConsumed = Temp16 + 3; 480 481 /* 482 * Resource Source Index and Resource Source are 483 * optional elements. Check the length of the 484 * Bytestream. If it is greater than 43, that 485 * means that an Index exists and is followed by 486 * a null termininated string. Therefore, set 487 * the temp variable to the length minus the minimum 488 * byte stream length plus the byte for the Index to 489 * determine the size of the NULL terminiated string. 490 */ 491 if (43 < Temp16) 492 { 493 Temp8 = (UINT8) (Temp16 - 44); 494 } 495 else 496 { 497 Temp8 = 0; 498 } 499 500 /* 501 * Ensure a 64-bit boundary for the structure 502 */ 503 Temp8 = (UINT8) ACPI_ROUND_UP_TO_64BITS (Temp8); 504 505 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) + 506 (Temp8 * sizeof (UINT8)); 507 break; 508 509 510 case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: 511 /* 512 * 32-Bit Address Resource 513 */ 514 Buffer = ByteStreamBuffer; 515 516 ++Buffer; 517 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 518 519 BytesConsumed = Temp16 + 3; 520 521 /* 522 * Resource Source Index and Resource Source are 523 * optional elements. Check the length of the 524 * Bytestream. If it is greater than 23, that 525 * means that an Index exists and is followed by 526 * a null termininated string. Therefore, set 527 * the temp variable to the length minus the minimum 528 * byte stream length plus the byte for the Index to 529 * determine the size of the NULL terminiated string. 530 */ 531 if (23 < Temp16) 532 { 533 Temp8 = (UINT8) (Temp16 - 24); 534 } 535 else 536 { 537 Temp8 = 0; 538 } 539 540 /* 541 * Ensure a 32-bit boundary for the structure 542 */ 543 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 544 545 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) + 546 (Temp8 * sizeof (UINT8)); 547 break; 548 549 550 case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: 551 /* 552 * 16-Bit Address Resource 553 */ 554 Buffer = ByteStreamBuffer; 555 556 ++Buffer; 557 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 558 559 BytesConsumed = Temp16 + 3; 560 561 /* 562 * Resource Source Index and Resource Source are 563 * optional elements. Check the length of the 564 * Bytestream. If it is greater than 13, that 565 * means that an Index exists and is followed by 566 * a null termininated string. Therefore, set 567 * the temp variable to the length minus the minimum 568 * byte stream length plus the byte for the Index to 569 * determine the size of the NULL terminiated string. 570 */ 571 if (13 < Temp16) 572 { 573 Temp8 = (UINT8) (Temp16 - 14); 574 } 575 else 576 { 577 Temp8 = 0; 578 } 579 580 /* 581 * Ensure a 32-bit boundary for the structure 582 */ 583 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 584 585 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) + 586 (Temp8 * sizeof (UINT8)); 587 break; 588 589 590 case ACPI_RDESC_TYPE_EXTENDED_XRUPT: 591 /* 592 * Extended IRQ 593 */ 594 Buffer = ByteStreamBuffer; 595 596 ++Buffer; 597 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 598 599 BytesConsumed = Temp16 + 3; 600 601 /* 602 * Point past the length field and the 603 * Interrupt vector flags to save off the 604 * Interrupt table length to the Temp8 variable. 605 */ 606 Buffer += 3; 607 Temp8 = *Buffer; 608 609 /* 610 * To compensate for multiple interrupt numbers, add 4 bytes for 611 * each additional interrupts greater than 1 612 */ 613 AdditionalBytes = (UINT8) ((Temp8 - 1) * 4); 614 615 /* 616 * Resource Source Index and Resource Source are 617 * optional elements. Check the length of the 618 * Bytestream. If it is greater than 9, that 619 * means that an Index exists and is followed by 620 * a null termininated string. Therefore, set 621 * the temp variable to the length minus the minimum 622 * byte stream length plus the byte for the Index to 623 * determine the size of the NULL terminiated string. 624 */ 625 if (9 + AdditionalBytes < Temp16) 626 { 627 Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes)); 628 } 629 else 630 { 631 Temp8 = 0; 632 } 633 634 /* 635 * Ensure a 32-bit boundary for the structure 636 */ 637 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 638 639 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) + 640 (AdditionalBytes * sizeof (UINT8)) + 641 (Temp8 * sizeof (UINT8)); 642 break; 643 644 645 case ACPI_RDESC_TYPE_IRQ_FORMAT: 646 /* 647 * IRQ Resource. 648 * Determine if it there are two or three trailing bytes 649 */ 650 Buffer = ByteStreamBuffer; 651 Temp8 = *Buffer; 652 653 if(Temp8 & 0x01) 654 { 655 BytesConsumed = 4; 656 } 657 else 658 { 659 BytesConsumed = 3; 660 } 661 662 /* 663 * Point past the descriptor 664 */ 665 ++Buffer; 666 667 /* 668 * Look at the number of bits set 669 */ 670 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 671 672 for (Index = 0; Index < 16; Index++) 673 { 674 if (Temp16 & 0x1) 675 { 676 ++NumberOfInterrupts; 677 } 678 679 Temp16 >>= 1; 680 } 681 682 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO) + 683 (NumberOfInterrupts * sizeof (UINT32)); 684 break; 685 686 687 case ACPI_RDESC_TYPE_DMA_FORMAT: 688 /* 689 * DMA Resource 690 */ 691 Buffer = ByteStreamBuffer; 692 BytesConsumed = 3; 693 694 /* 695 * Point past the descriptor 696 */ 697 ++Buffer; 698 699 /* 700 * Look at the number of bits set 701 */ 702 Temp8 = *Buffer; 703 704 for(Index = 0; Index < 8; Index++) 705 { 706 if(Temp8 & 0x1) 707 { 708 ++NumberOfChannels; 709 } 710 711 Temp8 >>= 1; 712 } 713 714 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) + 715 (NumberOfChannels * sizeof (UINT32)); 716 break; 717 718 719 case ACPI_RDESC_TYPE_START_DEPENDENT: 720 /* 721 * Start Dependent Functions Resource 722 * Determine if it there are two or three trailing bytes 723 */ 724 Buffer = ByteStreamBuffer; 725 Temp8 = *Buffer; 726 727 if(Temp8 & 0x01) 728 { 729 BytesConsumed = 2; 730 } 731 else 732 { 733 BytesConsumed = 1; 734 } 735 736 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF); 737 break; 738 739 740 case ACPI_RDESC_TYPE_END_DEPENDENT: 741 /* 742 * End Dependent Functions Resource 743 */ 744 BytesConsumed = 1; 745 StructureSize = ACPI_RESOURCE_LENGTH; 746 break; 747 748 749 case ACPI_RDESC_TYPE_IO_PORT: 750 /* 751 * IO Port Resource 752 */ 753 BytesConsumed = 8; 754 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO); 755 break; 756 757 758 case ACPI_RDESC_TYPE_FIXED_IO_PORT: 759 /* 760 * Fixed IO Port Resource 761 */ 762 BytesConsumed = 4; 763 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO); 764 break; 765 766 767 case ACPI_RDESC_TYPE_SMALL_VENDOR: 768 /* 769 * Vendor Specific Resource 770 */ 771 Buffer = ByteStreamBuffer; 772 773 Temp8 = *Buffer; 774 Temp8 = (UINT8) (Temp8 & 0x7); 775 BytesConsumed = Temp8 + 1; 776 777 /* 778 * Ensure a 32-bit boundary for the structure 779 */ 780 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8); 781 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 782 (Temp8 * sizeof (UINT8)); 783 break; 784 785 786 case ACPI_RDESC_TYPE_END_TAG: 787 /* 788 * End Tag 789 */ 790 BytesConsumed = 2; 791 StructureSize = ACPI_RESOURCE_LENGTH; 792 ByteStreamBufferLength = BytesParsed; 793 break; 794 795 796 default: 797 /* 798 * If we get here, everything is out of sync, 799 * exit with an error 800 */ 801 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 802 } 803 804 /* 805 * Update the return value and counter 806 */ 807 BufferSize += (UINT32) ACPI_ALIGN_RESOURCE_SIZE (StructureSize); 808 BytesParsed += BytesConsumed; 809 810 /* 811 * Set the byte stream to point to the next resource 812 */ 813 ByteStreamBuffer += BytesConsumed; 814 } 815 816 /* 817 * This is the data the caller needs 818 */ 819 *SizeNeeded = BufferSize; 820 return_ACPI_STATUS (AE_OK); 821} 822 823 824/******************************************************************************* 825 * 826 * FUNCTION: AcpiRsGetPciRoutingTableLength 827 * 828 * PARAMETERS: PackageObject - Pointer to the package object 829 * BufferSizeNeeded - UINT32 pointer of the size buffer 830 * needed to properly return the 831 * parsed data 832 * 833 * RETURN: Status 834 * 835 * DESCRIPTION: Given a package representing a PCI routing table, this 836 * calculates the size of the corresponding linked list of 837 * descriptions. 838 * 839 ******************************************************************************/ 840 841ACPI_STATUS 842AcpiRsGetPciRoutingTableLength ( 843 ACPI_OPERAND_OBJECT *PackageObject, 844 ACPI_SIZE *BufferSizeNeeded) 845{ 846 UINT32 NumberOfElements; 847 ACPI_SIZE TempSizeNeeded = 0; 848 ACPI_OPERAND_OBJECT **TopObjectList; 849 UINT32 Index; 850 ACPI_OPERAND_OBJECT *PackageElement; 851 ACPI_OPERAND_OBJECT **SubObjectList; 852 BOOLEAN NameFound; 853 UINT32 TableIndex; 854 855 856 ACPI_FUNCTION_TRACE ("RsGetPciRoutingTableLength"); 857 858 859 NumberOfElements = PackageObject->Package.Count; 860 861 /* 862 * Calculate the size of the return buffer. 863 * The base size is the number of elements * the sizes of the 864 * structures. Additional space for the strings is added below. 865 * The minus one is to subtract the size of the UINT8 Source[1] 866 * member because it is added below. 867 * 868 * But each PRT_ENTRY structure has a pointer to a string and 869 * the size of that string must be found. 870 */ 871 TopObjectList = PackageObject->Package.Elements; 872 873 for (Index = 0; Index < NumberOfElements; Index++) 874 { 875 /* 876 * Dereference the sub-package 877 */ 878 PackageElement = *TopObjectList; 879 880 /* 881 * The SubObjectList will now point to an array of the 882 * four IRQ elements: Address, Pin, Source and SourceIndex 883 */ 884 SubObjectList = PackageElement->Package.Elements; 885 886 /* 887 * Scan the IrqTableElements for the Source Name String 888 */ 889 NameFound = FALSE; 890 891 for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 892 { 893 if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*SubObjectList)) || 894 ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*SubObjectList)) && 895 ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP))) 896 { 897 NameFound = TRUE; 898 } 899 else 900 { 901 /* 902 * Look at the next element 903 */ 904 SubObjectList++; 905 } 906 } 907 908 TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 909 910 /* 911 * Was a String type found? 912 */ 913 if (NameFound) 914 { 915 if (ACPI_GET_OBJECT_TYPE (*SubObjectList) == ACPI_TYPE_STRING) 916 { 917 /* 918 * The length String.Length field does not include the 919 * terminating NULL, add 1 920 */ 921 TempSizeNeeded += ((ACPI_SIZE) (*SubObjectList)->String.Length + 1); 922 } 923 else 924 { 925 TempSizeNeeded += AcpiNsGetPathnameLength ( 926 (*SubObjectList)->Reference.Node); 927 } 928 } 929 else 930 { 931 /* 932 * If no name was found, then this is a NULL, which is 933 * translated as a UINT32 zero. 934 */ 935 TempSizeNeeded += sizeof (UINT32); 936 } 937 938 /* Round up the size since each element must be aligned */ 939 940 TempSizeNeeded = ACPI_ROUND_UP_TO_64BITS (TempSizeNeeded); 941 942 /* 943 * Point to the next ACPI_OPERAND_OBJECT 944 */ 945 TopObjectList++; 946 } 947 948 /* 949 * Adding an extra element to the end of the list, essentially a NULL terminator 950 */ 951 *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 952 return_ACPI_STATUS (AE_OK); 953}
|