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