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