Home | History | Annotate | Line # | Download | only in utilities
utresrc.c revision 1.1.1.8
      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             /*
    530              * The EndTag opcode must be followed by a zero byte.
    531              * Although this byte is technically defined to be a checksum,
    532              * in practice, all ASL compilers set this byte to zero.
    533              */
    534             if (*(Aml + 1) != 0)
    535             {
    536                 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
    537             }
    538 
    539             /* Return the pointer to the EndTag if requested */
    540 
    541             if (!UserFunction)
    542             {
    543                 *Context = Aml;
    544             }
    545 
    546             /* Check if buffer is defined to be longer than the resource length */
    547 
    548             if (AmlLength > (Offset + Length))
    549             {
    550                 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
    551             }
    552 
    553             /* Normal exit */
    554 
    555             return_ACPI_STATUS (AE_OK);
    556         }
    557 
    558         Aml += Length;
    559         Offset += Length;
    560     }
    561 
    562     /* Did not find an EndTag descriptor */
    563 
    564     if (UserFunction)
    565     {
    566         /* Insert an EndTag anyway. AcpiRsGetListLength always leaves room */
    567 
    568         (void) AcpiUtValidateResource (WalkState, EndTag, &ResourceIndex);
    569         Status = UserFunction (EndTag, 2, Offset, ResourceIndex, Context);
    570         if (ACPI_FAILURE (Status))
    571         {
    572             return_ACPI_STATUS (Status);
    573         }
    574     }
    575 
    576     return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
    577 }
    578 
    579 
    580 /*******************************************************************************
    581  *
    582  * FUNCTION:    AcpiUtValidateResource
    583  *
    584  * PARAMETERS:  WalkState           - Current walk info
    585  *              Aml                 - Pointer to the raw AML resource descriptor
    586  *              ReturnIndex         - Where the resource index is returned. NULL
    587  *                                    if the index is not required.
    588  *
    589  * RETURN:      Status, and optionally the Index into the global resource tables
    590  *
    591  * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
    592  *              Type and Resource Length. Returns an index into the global
    593  *              resource information/dispatch tables for later use.
    594  *
    595  ******************************************************************************/
    596 
    597 ACPI_STATUS
    598 AcpiUtValidateResource (
    599     ACPI_WALK_STATE         *WalkState,
    600     void                    *Aml,
    601     UINT8                   *ReturnIndex)
    602 {
    603     AML_RESOURCE            *AmlResource;
    604     UINT8                   ResourceType;
    605     UINT8                   ResourceIndex;
    606     ACPI_RS_LENGTH          ResourceLength;
    607     ACPI_RS_LENGTH          MinimumResourceLength;
    608 
    609 
    610     ACPI_FUNCTION_ENTRY ();
    611 
    612 
    613     /*
    614      * 1) Validate the ResourceType field (Byte 0)
    615      */
    616     ResourceType = ACPI_GET8 (Aml);
    617 
    618     /*
    619      * Byte 0 contains the descriptor name (Resource Type)
    620      * Examine the large/small bit in the resource header
    621      */
    622     if (ResourceType & ACPI_RESOURCE_NAME_LARGE)
    623     {
    624         /* Verify the large resource type (name) against the max */
    625 
    626         if (ResourceType > ACPI_RESOURCE_NAME_LARGE_MAX)
    627         {
    628             goto InvalidResource;
    629         }
    630 
    631         /*
    632          * Large Resource Type -- bits 6:0 contain the name
    633          * Translate range 0x80-0x8B to index range 0x10-0x1B
    634          */
    635         ResourceIndex = (UINT8) (ResourceType - 0x70);
    636     }
    637     else
    638     {
    639         /*
    640          * Small Resource Type -- bits 6:3 contain the name
    641          * Shift range to index range 0x00-0x0F
    642          */
    643         ResourceIndex = (UINT8)
    644             ((ResourceType & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
    645     }
    646 
    647     /*
    648      * Check validity of the resource type, via AcpiGbl_ResourceTypes.
    649      * Zero indicates an invalid resource.
    650      */
    651     if (!AcpiGbl_ResourceTypes[ResourceIndex])
    652     {
    653         goto InvalidResource;
    654     }
    655 
    656     /*
    657      * Validate the ResourceLength field. This ensures that the length
    658      * is at least reasonable, and guarantees that it is non-zero.
    659      */
    660     ResourceLength = AcpiUtGetResourceLength (Aml);
    661     MinimumResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
    662 
    663     /* Validate based upon the type of resource - fixed length or variable */
    664 
    665     switch (AcpiGbl_ResourceTypes[ResourceIndex])
    666     {
    667     case ACPI_FIXED_LENGTH:
    668 
    669         /* Fixed length resource, length must match exactly */
    670 
    671         if (ResourceLength != MinimumResourceLength)
    672         {
    673             goto BadResourceLength;
    674         }
    675         break;
    676 
    677     case ACPI_VARIABLE_LENGTH:
    678 
    679         /* Variable length resource, length must be at least the minimum */
    680 
    681         if (ResourceLength < MinimumResourceLength)
    682         {
    683             goto BadResourceLength;
    684         }
    685         break;
    686 
    687     case ACPI_SMALL_VARIABLE_LENGTH:
    688 
    689         /* Small variable length resource, length can be (Min) or (Min-1) */
    690 
    691         if ((ResourceLength > MinimumResourceLength) ||
    692             (ResourceLength < (MinimumResourceLength - 1)))
    693         {
    694             goto BadResourceLength;
    695         }
    696         break;
    697 
    698     default:
    699 
    700         /* Shouldn't happen (because of validation earlier), but be sure */
    701 
    702         goto InvalidResource;
    703     }
    704 
    705     AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml);
    706     if (ResourceType == ACPI_RESOURCE_NAME_SERIAL_BUS)
    707     {
    708         /* Validate the BusType field */
    709 
    710         if ((AmlResource->CommonSerialBus.Type == 0) ||
    711             (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE))
    712         {
    713             if (WalkState)
    714             {
    715                 ACPI_ERROR ((AE_INFO,
    716                     "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
    717                     AmlResource->CommonSerialBus.Type));
    718             }
    719             return (AE_AML_INVALID_RESOURCE_TYPE);
    720         }
    721     }
    722 
    723     /* Optionally return the resource table index */
    724 
    725     if (ReturnIndex)
    726     {
    727         *ReturnIndex = ResourceIndex;
    728     }
    729 
    730     return (AE_OK);
    731 
    732 
    733 InvalidResource:
    734 
    735     if (WalkState)
    736     {
    737         ACPI_ERROR ((AE_INFO,
    738             "Invalid/unsupported resource descriptor: Type 0x%2.2X",
    739             ResourceType));
    740     }
    741     return (AE_AML_INVALID_RESOURCE_TYPE);
    742 
    743 BadResourceLength:
    744 
    745     if (WalkState)
    746     {
    747         ACPI_ERROR ((AE_INFO,
    748             "Invalid resource descriptor length: Type "
    749             "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
    750             ResourceType, ResourceLength, MinimumResourceLength));
    751     }
    752     return (AE_AML_BAD_RESOURCE_LENGTH);
    753 }
    754 
    755 
    756 /*******************************************************************************
    757  *
    758  * FUNCTION:    AcpiUtGetResourceType
    759  *
    760  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    761  *
    762  * RETURN:      The Resource Type with no extraneous bits (except the
    763  *              Large/Small descriptor bit -- this is left alone)
    764  *
    765  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
    766  *              a resource descriptor.
    767  *
    768  ******************************************************************************/
    769 
    770 UINT8
    771 AcpiUtGetResourceType (
    772     void                    *Aml)
    773 {
    774     ACPI_FUNCTION_ENTRY ();
    775 
    776 
    777     /*
    778      * Byte 0 contains the descriptor name (Resource Type)
    779      * Examine the large/small bit in the resource header
    780      */
    781     if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
    782     {
    783         /* Large Resource Type -- bits 6:0 contain the name */
    784 
    785         return (ACPI_GET8 (Aml));
    786     }
    787     else
    788     {
    789         /* Small Resource Type -- bits 6:3 contain the name */
    790 
    791         return ((UINT8) (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
    792     }
    793 }
    794 
    795 
    796 /*******************************************************************************
    797  *
    798  * FUNCTION:    AcpiUtGetResourceLength
    799  *
    800  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    801  *
    802  * RETURN:      Byte Length
    803  *
    804  * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
    805  *              definition, this does not include the size of the descriptor
    806  *              header or the length field itself.
    807  *
    808  ******************************************************************************/
    809 
    810 UINT16
    811 AcpiUtGetResourceLength (
    812     void                    *Aml)
    813 {
    814     ACPI_RS_LENGTH          ResourceLength;
    815 
    816 
    817     ACPI_FUNCTION_ENTRY ();
    818 
    819 
    820     /*
    821      * Byte 0 contains the descriptor name (Resource Type)
    822      * Examine the large/small bit in the resource header
    823      */
    824     if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
    825     {
    826         /* Large Resource type -- bytes 1-2 contain the 16-bit length */
    827 
    828         ACPI_MOVE_16_TO_16 (&ResourceLength, ACPI_ADD_PTR (UINT8, Aml, 1));
    829 
    830     }
    831     else
    832     {
    833         /* Small Resource type -- bits 2:0 of byte 0 contain the length */
    834 
    835         ResourceLength = (UINT16) (ACPI_GET8 (Aml) &
    836             ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
    837     }
    838 
    839     return (ResourceLength);
    840 }
    841 
    842 
    843 /*******************************************************************************
    844  *
    845  * FUNCTION:    AcpiUtGetResourceHeaderLength
    846  *
    847  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    848  *
    849  * RETURN:      Length of the AML header (depends on large/small descriptor)
    850  *
    851  * DESCRIPTION: Get the length of the header for this resource.
    852  *
    853  ******************************************************************************/
    854 
    855 UINT8
    856 AcpiUtGetResourceHeaderLength (
    857     void                    *Aml)
    858 {
    859     ACPI_FUNCTION_ENTRY ();
    860 
    861 
    862     /* Examine the large/small bit in the resource header */
    863 
    864     if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
    865     {
    866         return (sizeof (AML_RESOURCE_LARGE_HEADER));
    867     }
    868     else
    869     {
    870         return (sizeof (AML_RESOURCE_SMALL_HEADER));
    871     }
    872 }
    873 
    874 
    875 /*******************************************************************************
    876  *
    877  * FUNCTION:    AcpiUtGetDescriptorLength
    878  *
    879  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    880  *
    881  * RETURN:      Byte length
    882  *
    883  * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
    884  *              length of the descriptor header and the length field itself.
    885  *              Used to walk descriptor lists.
    886  *
    887  ******************************************************************************/
    888 
    889 UINT32
    890 AcpiUtGetDescriptorLength (
    891     void                    *Aml)
    892 {
    893     ACPI_FUNCTION_ENTRY ();
    894 
    895 
    896     /*
    897      * Get the Resource Length (does not include header length) and add
    898      * the header length (depends on if this is a small or large resource)
    899      */
    900     return (AcpiUtGetResourceLength (Aml) +
    901         AcpiUtGetResourceHeaderLength (Aml));
    902 }
    903 
    904 
    905 /*******************************************************************************
    906  *
    907  * FUNCTION:    AcpiUtGetResourceEndTag
    908  *
    909  * PARAMETERS:  ObjDesc         - The resource template buffer object
    910  *              EndTag          - Where the pointer to the EndTag is returned
    911  *
    912  * RETURN:      Status, pointer to the end tag
    913  *
    914  * DESCRIPTION: Find the EndTag resource descriptor in an AML resource template
    915  *              Note: allows a buffer length of zero.
    916  *
    917  ******************************************************************************/
    918 
    919 ACPI_STATUS
    920 AcpiUtGetResourceEndTag (
    921     ACPI_OPERAND_OBJECT     *ObjDesc,
    922     UINT8                   **EndTag)
    923 {
    924     ACPI_STATUS             Status;
    925 
    926 
    927     ACPI_FUNCTION_TRACE (UtGetResourceEndTag);
    928 
    929 
    930     /* Allow a buffer length of zero */
    931 
    932     if (!ObjDesc->Buffer.Length)
    933     {
    934         *EndTag = ObjDesc->Buffer.Pointer;
    935         return_ACPI_STATUS (AE_OK);
    936     }
    937 
    938     /* Validate the template and get a pointer to the EndTag */
    939 
    940     Status = AcpiUtWalkAmlResources (NULL, ObjDesc->Buffer.Pointer,
    941         ObjDesc->Buffer.Length, NULL, (void **) EndTag);
    942 
    943     return_ACPI_STATUS (Status);
    944 }
    945