1 /******************************************************************************* 2 * 3 * Module Name: utresrc - Resource management utilities 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #define __UTRESRC_C__ 45 46 #include "acpi.h" 47 #include "accommon.h" 48 #include "acresrc.h" 49 50 51 #define _COMPONENT ACPI_UTILITIES 52 ACPI_MODULE_NAME ("utresrc") 53 54 55 #if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) 56 57 /* 58 * Strings used to decode resource descriptors. 59 * Used by both the disassembler and the debugger resource dump routines 60 */ 61 const char *AcpiGbl_BmDecode[] = 62 { 63 "NotBusMaster", 64 "BusMaster" 65 }; 66 67 const char *AcpiGbl_ConfigDecode[] = 68 { 69 "0 - Good Configuration", 70 "1 - Acceptable Configuration", 71 "2 - Suboptimal Configuration", 72 "3 - ***Invalid Configuration***", 73 }; 74 75 const char *AcpiGbl_ConsumeDecode[] = 76 { 77 "ResourceProducer", 78 "ResourceConsumer" 79 }; 80 81 const char *AcpiGbl_DecDecode[] = 82 { 83 "PosDecode", 84 "SubDecode" 85 }; 86 87 const char *AcpiGbl_HeDecode[] = 88 { 89 "Level", 90 "Edge" 91 }; 92 93 const char *AcpiGbl_IoDecode[] = 94 { 95 "Decode10", 96 "Decode16" 97 }; 98 99 const char *AcpiGbl_LlDecode[] = 100 { 101 "ActiveHigh", 102 "ActiveLow", 103 "ActiveBoth", 104 "Reserved" 105 }; 106 107 const char *AcpiGbl_MaxDecode[] = 108 { 109 "MaxNotFixed", 110 "MaxFixed" 111 }; 112 113 const char *AcpiGbl_MemDecode[] = 114 { 115 "NonCacheable", 116 "Cacheable", 117 "WriteCombining", 118 "Prefetchable" 119 }; 120 121 const char *AcpiGbl_MinDecode[] = 122 { 123 "MinNotFixed", 124 "MinFixed" 125 }; 126 127 const char *AcpiGbl_MtpDecode[] = 128 { 129 "AddressRangeMemory", 130 "AddressRangeReserved", 131 "AddressRangeACPI", 132 "AddressRangeNVS" 133 }; 134 135 const char *AcpiGbl_RngDecode[] = 136 { 137 "InvalidRanges", 138 "NonISAOnlyRanges", 139 "ISAOnlyRanges", 140 "EntireRange" 141 }; 142 143 const char *AcpiGbl_RwDecode[] = 144 { 145 "ReadOnly", 146 "ReadWrite" 147 }; 148 149 const char *AcpiGbl_ShrDecode[] = 150 { 151 "Exclusive", 152 "Shared", 153 "ExclusiveAndWake", /* ACPI 5.0 */ 154 "SharedAndWake" /* ACPI 5.0 */ 155 }; 156 157 const char *AcpiGbl_SizDecode[] = 158 { 159 "Transfer8", 160 "Transfer8_16", 161 "Transfer16", 162 "InvalidSize" 163 }; 164 165 const char *AcpiGbl_TrsDecode[] = 166 { 167 "DenseTranslation", 168 "SparseTranslation" 169 }; 170 171 const char *AcpiGbl_TtpDecode[] = 172 { 173 "TypeStatic", 174 "TypeTranslation" 175 }; 176 177 const char *AcpiGbl_TypDecode[] = 178 { 179 "Compatibility", 180 "TypeA", 181 "TypeB", 182 "TypeF" 183 }; 184 185 const char *AcpiGbl_PpcDecode[] = 186 { 187 "PullDefault", 188 "PullUp", 189 "PullDown", 190 "PullNone" 191 }; 192 193 const char *AcpiGbl_IorDecode[] = 194 { 195 "IoRestrictionNone", 196 "IoRestrictionInputOnly", 197 "IoRestrictionOutputOnly", 198 "IoRestrictionNoneAndPreserve" 199 }; 200 201 const char *AcpiGbl_DtsDecode[] = 202 { 203 "Width8bit", 204 "Width16bit", 205 "Width32bit", 206 "Width64bit", 207 "Width128bit", 208 "Width256bit", 209 }; 210 211 /* GPIO connection type */ 212 213 const char *AcpiGbl_CtDecode[] = 214 { 215 "Interrupt", 216 "I/O" 217 }; 218 219 /* Serial bus type */ 220 221 const char *AcpiGbl_SbtDecode[] = 222 { 223 "/* UNKNOWN serial bus type */", 224 "I2C", 225 "SPI", 226 "UART" 227 }; 228 229 /* I2C serial bus access mode */ 230 231 const char *AcpiGbl_AmDecode[] = 232 { 233 "AddressingMode7Bit", 234 "AddressingMode10Bit" 235 }; 236 237 /* I2C serial bus slave mode */ 238 239 const char *AcpiGbl_SmDecode[] = 240 { 241 "ControllerInitiated", 242 "DeviceInitiated" 243 }; 244 245 /* SPI serial bus wire mode */ 246 247 const char *AcpiGbl_WmDecode[] = 248 { 249 "FourWireMode", 250 "ThreeWireMode" 251 }; 252 253 /* SPI serial clock phase */ 254 255 const char *AcpiGbl_CphDecode[] = 256 { 257 "ClockPhaseFirst", 258 "ClockPhaseSecond" 259 }; 260 261 /* SPI serial bus clock polarity */ 262 263 const char *AcpiGbl_CpoDecode[] = 264 { 265 "ClockPolarityLow", 266 "ClockPolarityHigh" 267 }; 268 269 /* SPI serial bus device polarity */ 270 271 const char *AcpiGbl_DpDecode[] = 272 { 273 "PolarityLow", 274 "PolarityHigh" 275 }; 276 277 /* UART serial bus endian */ 278 279 const char *AcpiGbl_EdDecode[] = 280 { 281 "LittleEndian", 282 "BigEndian" 283 }; 284 285 /* UART serial bus bits per byte */ 286 287 const char *AcpiGbl_BpbDecode[] = 288 { 289 "DataBitsFive", 290 "DataBitsSix", 291 "DataBitsSeven", 292 "DataBitsEight", 293 "DataBitsNine", 294 "/* UNKNOWN Bits per byte */", 295 "/* UNKNOWN Bits per byte */", 296 "/* UNKNOWN Bits per byte */" 297 }; 298 299 /* UART serial bus stop bits */ 300 301 const char *AcpiGbl_SbDecode[] = 302 { 303 "StopBitsNone", 304 "StopBitsOne", 305 "StopBitsOnePlusHalf", 306 "StopBitsTwo" 307 }; 308 309 /* UART serial bus flow control */ 310 311 const char *AcpiGbl_FcDecode[] = 312 { 313 "FlowControlNone", 314 "FlowControlHardware", 315 "FlowControlXON", 316 "/* UNKNOWN flow control keyword */" 317 }; 318 319 /* UART serial bus parity type */ 320 321 const char *AcpiGbl_PtDecode[] = 322 { 323 "ParityTypeNone", 324 "ParityTypeEven", 325 "ParityTypeOdd", 326 "ParityTypeMark", 327 "ParityTypeSpace", 328 "/* UNKNOWN parity keyword */", 329 "/* UNKNOWN parity keyword */", 330 "/* UNKNOWN parity keyword */" 331 }; 332 333 #endif 334 335 336 /* 337 * Base sizes of the raw AML resource descriptors, indexed by resource type. 338 * Zero indicates a reserved (and therefore invalid) resource type. 339 */ 340 const UINT8 AcpiGbl_ResourceAmlSizes[] = 341 { 342 /* Small descriptors */ 343 344 0, 345 0, 346 0, 347 0, 348 ACPI_AML_SIZE_SMALL (AML_RESOURCE_IRQ), 349 ACPI_AML_SIZE_SMALL (AML_RESOURCE_DMA), 350 ACPI_AML_SIZE_SMALL (AML_RESOURCE_START_DEPENDENT), 351 ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_DEPENDENT), 352 ACPI_AML_SIZE_SMALL (AML_RESOURCE_IO), 353 ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_IO), 354 ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_DMA), 355 0, 356 0, 357 0, 358 ACPI_AML_SIZE_SMALL (AML_RESOURCE_VENDOR_SMALL), 359 ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_TAG), 360 361 /* Large descriptors */ 362 363 0, 364 ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY24), 365 ACPI_AML_SIZE_LARGE (AML_RESOURCE_GENERIC_REGISTER), 366 0, 367 ACPI_AML_SIZE_LARGE (AML_RESOURCE_VENDOR_LARGE), 368 ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY32), 369 ACPI_AML_SIZE_LARGE (AML_RESOURCE_FIXED_MEMORY32), 370 ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS32), 371 ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS16), 372 ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_IRQ), 373 ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS64), 374 ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_ADDRESS64), 375 ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO), 376 0, 377 ACPI_AML_SIZE_LARGE (AML_RESOURCE_COMMON_SERIALBUS), 378 }; 379 380 const UINT8 AcpiGbl_ResourceAmlSerialBusSizes[] = 381 { 382 0, 383 ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS), 384 ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS), 385 ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS), 386 }; 387 388 389 /* 390 * Resource types, used to validate the resource length field. 391 * The length of fixed-length types must match exactly, variable 392 * lengths must meet the minimum required length, etc. 393 * Zero indicates a reserved (and therefore invalid) resource type. 394 */ 395 static const UINT8 AcpiGbl_ResourceTypes[] = 396 { 397 /* Small descriptors */ 398 399 0, 400 0, 401 0, 402 0, 403 ACPI_SMALL_VARIABLE_LENGTH, /* 04 IRQ */ 404 ACPI_FIXED_LENGTH, /* 05 DMA */ 405 ACPI_SMALL_VARIABLE_LENGTH, /* 06 StartDependentFunctions */ 406 ACPI_FIXED_LENGTH, /* 07 EndDependentFunctions */ 407 ACPI_FIXED_LENGTH, /* 08 IO */ 408 ACPI_FIXED_LENGTH, /* 09 FixedIO */ 409 ACPI_FIXED_LENGTH, /* 0A FixedDMA */ 410 0, 411 0, 412 0, 413 ACPI_VARIABLE_LENGTH, /* 0E VendorShort */ 414 ACPI_FIXED_LENGTH, /* 0F EndTag */ 415 416 /* Large descriptors */ 417 418 0, 419 ACPI_FIXED_LENGTH, /* 01 Memory24 */ 420 ACPI_FIXED_LENGTH, /* 02 GenericRegister */ 421 0, 422 ACPI_VARIABLE_LENGTH, /* 04 VendorLong */ 423 ACPI_FIXED_LENGTH, /* 05 Memory32 */ 424 ACPI_FIXED_LENGTH, /* 06 Memory32Fixed */ 425 ACPI_VARIABLE_LENGTH, /* 07 Dword* address */ 426 ACPI_VARIABLE_LENGTH, /* 08 Word* address */ 427 ACPI_VARIABLE_LENGTH, /* 09 ExtendedIRQ */ 428 ACPI_VARIABLE_LENGTH, /* 0A Qword* address */ 429 ACPI_FIXED_LENGTH, /* 0B Extended* address */ 430 ACPI_VARIABLE_LENGTH, /* 0C Gpio* */ 431 0, 432 ACPI_VARIABLE_LENGTH /* 0E *SerialBus */ 433 }; 434 435 436 /******************************************************************************* 437 * 438 * FUNCTION: AcpiUtWalkAmlResources 439 * 440 * PARAMETERS: WalkState - Current walk info 441 * PARAMETERS: Aml - Pointer to the raw AML resource template 442 * AmlLength - Length of the entire template 443 * UserFunction - Called once for each descriptor found. If 444 * NULL, a pointer to the EndTag is returned 445 * Context - Passed to UserFunction 446 * 447 * RETURN: Status 448 * 449 * DESCRIPTION: Walk a raw AML resource list(buffer). User function called 450 * once for each resource found. 451 * 452 ******************************************************************************/ 453 454 ACPI_STATUS 455 AcpiUtWalkAmlResources ( 456 ACPI_WALK_STATE *WalkState, 457 UINT8 *Aml, 458 ACPI_SIZE AmlLength, 459 ACPI_WALK_AML_CALLBACK UserFunction, 460 void **Context) 461 { 462 ACPI_STATUS Status; 463 UINT8 *EndAml; 464 UINT8 ResourceIndex; 465 UINT32 Length; 466 UINT32 Offset = 0; 467 UINT8 EndTag[2] = {0x79, 0x00}; 468 469 470 ACPI_FUNCTION_TRACE (UtWalkAmlResources); 471 472 473 /* The absolute minimum resource template is one EndTag descriptor */ 474 475 if (AmlLength < sizeof (AML_RESOURCE_END_TAG)) 476 { 477 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 478 } 479 480 /* Point to the end of the resource template buffer */ 481 482 EndAml = Aml + AmlLength; 483 484 /* Walk the byte list, abort on any invalid descriptor type or length */ 485 486 while (Aml < EndAml) 487 { 488 /* Validate the Resource Type and Resource Length */ 489 490 Status = AcpiUtValidateResource (WalkState, Aml, &ResourceIndex); 491 if (ACPI_FAILURE (Status)) 492 { 493 /* 494 * Exit on failure. Cannot continue because the descriptor length 495 * may be bogus also. 496 */ 497 return_ACPI_STATUS (Status); 498 } 499 500 /* Get the length of this descriptor */ 501 502 Length = AcpiUtGetDescriptorLength (Aml); 503 504 /* Invoke the user function */ 505 506 if (UserFunction) 507 { 508 Status = UserFunction (Aml, Length, Offset, ResourceIndex, Context); 509 if (ACPI_FAILURE (Status)) 510 { 511 return_ACPI_STATUS (Status); 512 } 513 } 514 515 /* An EndTag descriptor terminates this resource template */ 516 517 if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_END_TAG) 518 { 519 /* 520 * There must be at least one more byte in the buffer for 521 * the 2nd byte of the EndTag 522 */ 523 if ((Aml + 1) >= EndAml) 524 { 525 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 526 } 527 528 /* Return the pointer to the EndTag if requested */ 529 530 if (!UserFunction) 531 { 532 *Context = Aml; 533 } 534 535 /* Normal exit */ 536 537 return_ACPI_STATUS (AE_OK); 538 } 539 540 Aml += Length; 541 Offset += Length; 542 } 543 544 /* Did not find an EndTag descriptor */ 545 546 if (UserFunction) 547 { 548 /* Insert an EndTag anyway. AcpiRsGetListLength always leaves room */ 549 550 (void) AcpiUtValidateResource (WalkState, EndTag, &ResourceIndex); 551 Status = UserFunction (EndTag, 2, Offset, ResourceIndex, Context); 552 if (ACPI_FAILURE (Status)) 553 { 554 return_ACPI_STATUS (Status); 555 } 556 } 557 558 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 559 } 560 561 562 /******************************************************************************* 563 * 564 * FUNCTION: AcpiUtValidateResource 565 * 566 * PARAMETERS: WalkState - Current walk info 567 * Aml - Pointer to the raw AML resource descriptor 568 * ReturnIndex - Where the resource index is returned. NULL 569 * if the index is not required. 570 * 571 * RETURN: Status, and optionally the Index into the global resource tables 572 * 573 * DESCRIPTION: Validate an AML resource descriptor by checking the Resource 574 * Type and Resource Length. Returns an index into the global 575 * resource information/dispatch tables for later use. 576 * 577 ******************************************************************************/ 578 579 ACPI_STATUS 580 AcpiUtValidateResource ( 581 ACPI_WALK_STATE *WalkState, 582 void *Aml, 583 UINT8 *ReturnIndex) 584 { 585 AML_RESOURCE *AmlResource; 586 UINT8 ResourceType; 587 UINT8 ResourceIndex; 588 ACPI_RS_LENGTH ResourceLength; 589 ACPI_RS_LENGTH MinimumResourceLength; 590 591 592 ACPI_FUNCTION_ENTRY (); 593 594 595 /* 596 * 1) Validate the ResourceType field (Byte 0) 597 */ 598 ResourceType = ACPI_GET8 (Aml); 599 600 /* 601 * Byte 0 contains the descriptor name (Resource Type) 602 * Examine the large/small bit in the resource header 603 */ 604 if (ResourceType & ACPI_RESOURCE_NAME_LARGE) 605 { 606 /* Verify the large resource type (name) against the max */ 607 608 if (ResourceType > ACPI_RESOURCE_NAME_LARGE_MAX) 609 { 610 goto InvalidResource; 611 } 612 613 /* 614 * Large Resource Type -- bits 6:0 contain the name 615 * Translate range 0x80-0x8B to index range 0x10-0x1B 616 */ 617 ResourceIndex = (UINT8) (ResourceType - 0x70); 618 } 619 else 620 { 621 /* 622 * Small Resource Type -- bits 6:3 contain the name 623 * Shift range to index range 0x00-0x0F 624 */ 625 ResourceIndex = (UINT8) 626 ((ResourceType & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); 627 } 628 629 /* 630 * Check validity of the resource type, via AcpiGbl_ResourceTypes. Zero 631 * indicates an invalid resource. 632 */ 633 if (!AcpiGbl_ResourceTypes[ResourceIndex]) 634 { 635 goto InvalidResource; 636 } 637 638 /* 639 * Validate the ResourceLength field. This ensures that the length 640 * is at least reasonable, and guarantees that it is non-zero. 641 */ 642 ResourceLength = AcpiUtGetResourceLength (Aml); 643 MinimumResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 644 645 /* Validate based upon the type of resource - fixed length or variable */ 646 647 switch (AcpiGbl_ResourceTypes[ResourceIndex]) 648 { 649 case ACPI_FIXED_LENGTH: 650 651 /* Fixed length resource, length must match exactly */ 652 653 if (ResourceLength != MinimumResourceLength) 654 { 655 goto BadResourceLength; 656 } 657 break; 658 659 case ACPI_VARIABLE_LENGTH: 660 661 /* Variable length resource, length must be at least the minimum */ 662 663 if (ResourceLength < MinimumResourceLength) 664 { 665 goto BadResourceLength; 666 } 667 break; 668 669 case ACPI_SMALL_VARIABLE_LENGTH: 670 671 /* Small variable length resource, length can be (Min) or (Min-1) */ 672 673 if ((ResourceLength > MinimumResourceLength) || 674 (ResourceLength < (MinimumResourceLength - 1))) 675 { 676 goto BadResourceLength; 677 } 678 break; 679 680 default: 681 682 /* Shouldn't happen (because of validation earlier), but be sure */ 683 684 goto InvalidResource; 685 } 686 687 AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml); 688 if (ResourceType == ACPI_RESOURCE_NAME_SERIAL_BUS) 689 { 690 /* Validate the BusType field */ 691 692 if ((AmlResource->CommonSerialBus.Type == 0) || 693 (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)) 694 { 695 if (WalkState) 696 { 697 ACPI_ERROR ((AE_INFO, 698 "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X", 699 AmlResource->CommonSerialBus.Type)); 700 } 701 return (AE_AML_INVALID_RESOURCE_TYPE); 702 } 703 } 704 705 /* Optionally return the resource table index */ 706 707 if (ReturnIndex) 708 { 709 *ReturnIndex = ResourceIndex; 710 } 711 712 return (AE_OK); 713 714 715 InvalidResource: 716 717 if (WalkState) 718 { 719 ACPI_ERROR ((AE_INFO, 720 "Invalid/unsupported resource descriptor: Type 0x%2.2X", 721 ResourceType)); 722 } 723 return (AE_AML_INVALID_RESOURCE_TYPE); 724 725 BadResourceLength: 726 727 if (WalkState) 728 { 729 ACPI_ERROR ((AE_INFO, 730 "Invalid resource descriptor length: Type " 731 "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X", 732 ResourceType, ResourceLength, MinimumResourceLength)); 733 } 734 return (AE_AML_BAD_RESOURCE_LENGTH); 735 } 736 737 738 /******************************************************************************* 739 * 740 * FUNCTION: AcpiUtGetResourceType 741 * 742 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 743 * 744 * RETURN: The Resource Type with no extraneous bits (except the 745 * Large/Small descriptor bit -- this is left alone) 746 * 747 * DESCRIPTION: Extract the Resource Type/Name from the first byte of 748 * a resource descriptor. 749 * 750 ******************************************************************************/ 751 752 UINT8 753 AcpiUtGetResourceType ( 754 void *Aml) 755 { 756 ACPI_FUNCTION_ENTRY (); 757 758 759 /* 760 * Byte 0 contains the descriptor name (Resource Type) 761 * Examine the large/small bit in the resource header 762 */ 763 if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE) 764 { 765 /* Large Resource Type -- bits 6:0 contain the name */ 766 767 return (ACPI_GET8 (Aml)); 768 } 769 else 770 { 771 /* Small Resource Type -- bits 6:3 contain the name */ 772 773 return ((UINT8) (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); 774 } 775 } 776 777 778 /******************************************************************************* 779 * 780 * FUNCTION: AcpiUtGetResourceLength 781 * 782 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 783 * 784 * RETURN: Byte Length 785 * 786 * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By 787 * definition, this does not include the size of the descriptor 788 * header or the length field itself. 789 * 790 ******************************************************************************/ 791 792 UINT16 793 AcpiUtGetResourceLength ( 794 void *Aml) 795 { 796 ACPI_RS_LENGTH ResourceLength; 797 798 799 ACPI_FUNCTION_ENTRY (); 800 801 802 /* 803 * Byte 0 contains the descriptor name (Resource Type) 804 * Examine the large/small bit in the resource header 805 */ 806 if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE) 807 { 808 /* Large Resource type -- bytes 1-2 contain the 16-bit length */ 809 810 ACPI_MOVE_16_TO_16 (&ResourceLength, ACPI_ADD_PTR (UINT8, Aml, 1)); 811 812 } 813 else 814 { 815 /* Small Resource type -- bits 2:0 of byte 0 contain the length */ 816 817 ResourceLength = (UINT16) (ACPI_GET8 (Aml) & 818 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); 819 } 820 821 return (ResourceLength); 822 } 823 824 825 /******************************************************************************* 826 * 827 * FUNCTION: AcpiUtGetResourceHeaderLength 828 * 829 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 830 * 831 * RETURN: Length of the AML header (depends on large/small descriptor) 832 * 833 * DESCRIPTION: Get the length of the header for this resource. 834 * 835 ******************************************************************************/ 836 837 UINT8 838 AcpiUtGetResourceHeaderLength ( 839 void *Aml) 840 { 841 ACPI_FUNCTION_ENTRY (); 842 843 844 /* Examine the large/small bit in the resource header */ 845 846 if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE) 847 { 848 return (sizeof (AML_RESOURCE_LARGE_HEADER)); 849 } 850 else 851 { 852 return (sizeof (AML_RESOURCE_SMALL_HEADER)); 853 } 854 } 855 856 857 /******************************************************************************* 858 * 859 * FUNCTION: AcpiUtGetDescriptorLength 860 * 861 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 862 * 863 * RETURN: Byte length 864 * 865 * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the 866 * length of the descriptor header and the length field itself. 867 * Used to walk descriptor lists. 868 * 869 ******************************************************************************/ 870 871 UINT32 872 AcpiUtGetDescriptorLength ( 873 void *Aml) 874 { 875 ACPI_FUNCTION_ENTRY (); 876 877 878 /* 879 * Get the Resource Length (does not include header length) and add 880 * the header length (depends on if this is a small or large resource) 881 */ 882 return (AcpiUtGetResourceLength (Aml) + 883 AcpiUtGetResourceHeaderLength (Aml)); 884 } 885 886 887 /******************************************************************************* 888 * 889 * FUNCTION: AcpiUtGetResourceEndTag 890 * 891 * PARAMETERS: ObjDesc - The resource template buffer object 892 * EndTag - Where the pointer to the EndTag is returned 893 * 894 * RETURN: Status, pointer to the end tag 895 * 896 * DESCRIPTION: Find the EndTag resource descriptor in an AML resource template 897 * Note: allows a buffer length of zero. 898 * 899 ******************************************************************************/ 900 901 ACPI_STATUS 902 AcpiUtGetResourceEndTag ( 903 ACPI_OPERAND_OBJECT *ObjDesc, 904 UINT8 **EndTag) 905 { 906 ACPI_STATUS Status; 907 908 909 ACPI_FUNCTION_TRACE (UtGetResourceEndTag); 910 911 912 /* Allow a buffer length of zero */ 913 914 if (!ObjDesc->Buffer.Length) 915 { 916 *EndTag = ObjDesc->Buffer.Pointer; 917 return_ACPI_STATUS (AE_OK); 918 } 919 920 /* Validate the template and get a pointer to the EndTag */ 921 922 Status = AcpiUtWalkAmlResources (NULL, ObjDesc->Buffer.Pointer, 923 ObjDesc->Buffer.Length, NULL, (void **) EndTag); 924 925 return_ACPI_STATUS (Status); 926 } 927