Home | History | Annotate | Line # | Download | only in utilities
utresrc.c revision 1.1.1.3
      1 /*******************************************************************************
      2  *
      3  * Module Name: utresrc - Resource management utilities
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, 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_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 }
    926