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