Home | History | Annotate | Line # | Download | only in utilities
utresrc.c revision 1.1.1.13
      1 /*******************************************************************************
      2  *
      3  * Module Name: utresrc - Resource management utilities
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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 /*
     54  * Base sizes of the raw AML resource descriptors, indexed by resource type.
     55  * Zero indicates a reserved (and therefore invalid) resource type.
     56  */
     57 const UINT8                 AcpiGbl_ResourceAmlSizes[] =
     58 {
     59     /* Small descriptors */
     60 
     61     0,
     62     0,
     63     0,
     64     0,
     65     ACPI_AML_SIZE_SMALL (AML_RESOURCE_IRQ),
     66     ACPI_AML_SIZE_SMALL (AML_RESOURCE_DMA),
     67     ACPI_AML_SIZE_SMALL (AML_RESOURCE_START_DEPENDENT),
     68     ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_DEPENDENT),
     69     ACPI_AML_SIZE_SMALL (AML_RESOURCE_IO),
     70     ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_IO),
     71     ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_DMA),
     72     0,
     73     0,
     74     0,
     75     ACPI_AML_SIZE_SMALL (AML_RESOURCE_VENDOR_SMALL),
     76     ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_TAG),
     77 
     78     /* Large descriptors */
     79 
     80     0,
     81     ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY24),
     82     ACPI_AML_SIZE_LARGE (AML_RESOURCE_GENERIC_REGISTER),
     83     0,
     84     ACPI_AML_SIZE_LARGE (AML_RESOURCE_VENDOR_LARGE),
     85     ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY32),
     86     ACPI_AML_SIZE_LARGE (AML_RESOURCE_FIXED_MEMORY32),
     87     ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS32),
     88     ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS16),
     89     ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_IRQ),
     90     ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS64),
     91     ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_ADDRESS64),
     92     ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO),
     93     ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION),
     94     ACPI_AML_SIZE_LARGE (AML_RESOURCE_COMMON_SERIALBUS),
     95     ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG),
     96     ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP),
     97     ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION),
     98     ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG),
     99 };
    100 
    101 const UINT8                 AcpiGbl_ResourceAmlSerialBusSizes[] =
    102 {
    103     0,
    104     ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS),
    105     ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS),
    106     ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS),
    107     ACPI_AML_SIZE_LARGE (AML_RESOURCE_CSI2_SERIALBUS),
    108 };
    109 
    110 
    111 /*
    112  * Resource types, used to validate the resource length field.
    113  * The length of fixed-length types must match exactly, variable
    114  * lengths must meet the minimum required length, etc.
    115  * Zero indicates a reserved (and therefore invalid) resource type.
    116  */
    117 static const UINT8          AcpiGbl_ResourceTypes[] =
    118 {
    119     /* Small descriptors */
    120 
    121     0,
    122     0,
    123     0,
    124     0,
    125     ACPI_SMALL_VARIABLE_LENGTH,     /* 04 IRQ */
    126     ACPI_FIXED_LENGTH,              /* 05 DMA */
    127     ACPI_SMALL_VARIABLE_LENGTH,     /* 06 StartDependentFunctions */
    128     ACPI_FIXED_LENGTH,              /* 07 EndDependentFunctions */
    129     ACPI_FIXED_LENGTH,              /* 08 IO */
    130     ACPI_FIXED_LENGTH,              /* 09 FixedIO */
    131     ACPI_FIXED_LENGTH,              /* 0A FixedDMA */
    132     0,
    133     0,
    134     0,
    135     ACPI_VARIABLE_LENGTH,           /* 0E VendorShort */
    136     ACPI_FIXED_LENGTH,              /* 0F EndTag */
    137 
    138     /* Large descriptors */
    139 
    140     0,
    141     ACPI_FIXED_LENGTH,              /* 01 Memory24 */
    142     ACPI_FIXED_LENGTH,              /* 02 GenericRegister */
    143     0,
    144     ACPI_VARIABLE_LENGTH,           /* 04 VendorLong */
    145     ACPI_FIXED_LENGTH,              /* 05 Memory32 */
    146     ACPI_FIXED_LENGTH,              /* 06 Memory32Fixed */
    147     ACPI_VARIABLE_LENGTH,           /* 07 Dword* address */
    148     ACPI_VARIABLE_LENGTH,           /* 08 Word* address */
    149     ACPI_VARIABLE_LENGTH,           /* 09 ExtendedIRQ */
    150     ACPI_VARIABLE_LENGTH,           /* 0A Qword* address */
    151     ACPI_FIXED_LENGTH,              /* 0B Extended* address */
    152     ACPI_VARIABLE_LENGTH,           /* 0C Gpio* */
    153     ACPI_VARIABLE_LENGTH,           /* 0D PinFunction */
    154     ACPI_VARIABLE_LENGTH,           /* 0E *SerialBus */
    155     ACPI_VARIABLE_LENGTH,           /* 0F PinConfig */
    156     ACPI_VARIABLE_LENGTH,           /* 10 PinGroup */
    157     ACPI_VARIABLE_LENGTH,           /* 11 PinGroupFunction */
    158     ACPI_VARIABLE_LENGTH,           /* 12 PinGroupConfig */
    159 };
    160 
    161 
    162 /*******************************************************************************
    163  *
    164  * FUNCTION:    AcpiUtWalkAmlResources
    165  *
    166  * PARAMETERS:  WalkState           - Current walk info
    167  * PARAMETERS:  Aml                 - Pointer to the raw AML resource template
    168  *              AmlLength           - Length of the entire template
    169  *              UserFunction        - Called once for each descriptor found. If
    170  *                                    NULL, a pointer to the EndTag is returned
    171  *              Context             - Passed to UserFunction
    172  *
    173  * RETURN:      Status
    174  *
    175  * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
    176  *              once for each resource found.
    177  *
    178  ******************************************************************************/
    179 
    180 ACPI_STATUS
    181 AcpiUtWalkAmlResources (
    182     ACPI_WALK_STATE         *WalkState,
    183     UINT8                   *Aml,
    184     ACPI_SIZE               AmlLength,
    185     ACPI_WALK_AML_CALLBACK  UserFunction,
    186     void                    **Context)
    187 {
    188     ACPI_STATUS             Status;
    189     UINT8                   *EndAml;
    190     UINT8                   ResourceIndex;
    191     UINT32                  Length;
    192     UINT32                  Offset = 0;
    193     UINT8                   EndTag[2] = {0x79, 0x00};
    194 
    195 
    196     ACPI_FUNCTION_TRACE (UtWalkAmlResources);
    197 
    198 
    199     /* The absolute minimum resource template is one EndTag descriptor */
    200 
    201     if (AmlLength < sizeof (AML_RESOURCE_END_TAG))
    202     {
    203         return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
    204     }
    205 
    206     /* Point to the end of the resource template buffer */
    207 
    208     EndAml = Aml + AmlLength;
    209 
    210     /* Walk the byte list, abort on any invalid descriptor type or length */
    211 
    212     while (Aml < EndAml)
    213     {
    214         /* Validate the Resource Type and Resource Length */
    215 
    216         Status = AcpiUtValidateResource (WalkState, Aml, &ResourceIndex);
    217         if (ACPI_FAILURE (Status))
    218         {
    219             /*
    220              * Exit on failure. Cannot continue because the descriptor
    221              * length may be bogus also.
    222              */
    223             return_ACPI_STATUS (Status);
    224         }
    225 
    226         /* Get the length of this descriptor */
    227 
    228         Length = AcpiUtGetDescriptorLength (Aml);
    229 
    230         /* Invoke the user function */
    231 
    232         if (UserFunction)
    233         {
    234             Status = UserFunction (
    235                 Aml, Length, Offset, ResourceIndex, Context);
    236             if (ACPI_FAILURE (Status))
    237             {
    238                 return_ACPI_STATUS (Status);
    239             }
    240         }
    241 
    242         /* An EndTag descriptor terminates this resource template */
    243 
    244         if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_END_TAG)
    245         {
    246             /*
    247              * There must be at least one more byte in the buffer for
    248              * the 2nd byte of the EndTag
    249              */
    250             if ((Aml + 1) >= EndAml)
    251             {
    252                 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
    253             }
    254 
    255             /*
    256              * Don't attempt to perform any validation on the 2nd byte.
    257              * Although all known ASL compilers insert a zero for the 2nd
    258              * byte, it can also be a checksum (as per the ACPI spec),
    259              * and this is occasionally seen in the field. July 2017.
    260              */
    261 
    262             /* Return the pointer to the EndTag if requested */
    263 
    264             if (!UserFunction)
    265             {
    266                 *Context = Aml;
    267             }
    268 
    269             /* Normal exit */
    270 
    271             return_ACPI_STATUS (AE_OK);
    272         }
    273 
    274         Aml += Length;
    275         Offset += Length;
    276     }
    277 
    278     /* Did not find an EndTag descriptor */
    279 
    280     if (UserFunction)
    281     {
    282         /* Insert an EndTag anyway. AcpiRsGetListLength always leaves room */
    283 
    284         (void) AcpiUtValidateResource (WalkState, EndTag, &ResourceIndex);
    285         Status = UserFunction (EndTag, 2, Offset, ResourceIndex, Context);
    286         if (ACPI_FAILURE (Status))
    287         {
    288             return_ACPI_STATUS (Status);
    289         }
    290     }
    291 
    292     return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
    293 }
    294 
    295 
    296 /*******************************************************************************
    297  *
    298  * FUNCTION:    AcpiUtValidateResource
    299  *
    300  * PARAMETERS:  WalkState           - Current walk info
    301  *              Aml                 - Pointer to the raw AML resource descriptor
    302  *              ReturnIndex         - Where the resource index is returned. NULL
    303  *                                    if the index is not required.
    304  *
    305  * RETURN:      Status, and optionally the Index into the global resource tables
    306  *
    307  * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
    308  *              Type and Resource Length. Returns an index into the global
    309  *              resource information/dispatch tables for later use.
    310  *
    311  ******************************************************************************/
    312 
    313 ACPI_STATUS
    314 AcpiUtValidateResource (
    315     ACPI_WALK_STATE         *WalkState,
    316     void                    *Aml,
    317     UINT8                   *ReturnIndex)
    318 {
    319     AML_RESOURCE            *AmlResource;
    320     UINT8                   ResourceType;
    321     UINT8                   ResourceIndex;
    322     ACPI_RS_LENGTH          ResourceLength;
    323     ACPI_RS_LENGTH          MinimumResourceLength;
    324 
    325 
    326     ACPI_FUNCTION_ENTRY ();
    327 
    328 
    329     /*
    330      * 1) Validate the ResourceType field (Byte 0)
    331      */
    332     ResourceType = ACPI_GET8 (Aml);
    333 
    334     /*
    335      * Byte 0 contains the descriptor name (Resource Type)
    336      * Examine the large/small bit in the resource header
    337      */
    338     if (ResourceType & ACPI_RESOURCE_NAME_LARGE)
    339     {
    340         /* Verify the large resource type (name) against the max */
    341 
    342         if (ResourceType > ACPI_RESOURCE_NAME_LARGE_MAX)
    343         {
    344             goto InvalidResource;
    345         }
    346 
    347         /*
    348          * Large Resource Type -- bits 6:0 contain the name
    349          * Translate range 0x80-0x8B to index range 0x10-0x1B
    350          */
    351         ResourceIndex = (UINT8) (ResourceType - 0x70);
    352     }
    353     else
    354     {
    355         /*
    356          * Small Resource Type -- bits 6:3 contain the name
    357          * Shift range to index range 0x00-0x0F
    358          */
    359         ResourceIndex = (UINT8)
    360             ((ResourceType & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
    361     }
    362 
    363     /*
    364      * Check validity of the resource type, via AcpiGbl_ResourceTypes.
    365      * Zero indicates an invalid resource.
    366      */
    367     if (!AcpiGbl_ResourceTypes[ResourceIndex])
    368     {
    369         goto InvalidResource;
    370     }
    371 
    372     /*
    373      * Validate the ResourceLength field. This ensures that the length
    374      * is at least reasonable, and guarantees that it is non-zero.
    375      */
    376     ResourceLength = AcpiUtGetResourceLength (Aml);
    377     MinimumResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
    378 
    379     /* Validate based upon the type of resource - fixed length or variable */
    380 
    381     switch (AcpiGbl_ResourceTypes[ResourceIndex])
    382     {
    383     case ACPI_FIXED_LENGTH:
    384 
    385         /* Fixed length resource, length must match exactly */
    386 
    387         if (ResourceLength != MinimumResourceLength)
    388         {
    389             goto BadResourceLength;
    390         }
    391         break;
    392 
    393     case ACPI_VARIABLE_LENGTH:
    394 
    395         /* Variable length resource, length must be at least the minimum */
    396 
    397         if (ResourceLength < MinimumResourceLength)
    398         {
    399             goto BadResourceLength;
    400         }
    401         break;
    402 
    403     case ACPI_SMALL_VARIABLE_LENGTH:
    404 
    405         /* Small variable length resource, length can be (Min) or (Min-1) */
    406 
    407         if ((ResourceLength > MinimumResourceLength) ||
    408             (ResourceLength < (MinimumResourceLength - 1)))
    409         {
    410             goto BadResourceLength;
    411         }
    412         break;
    413 
    414     default:
    415 
    416         /* Shouldn't happen (because of validation earlier), but be sure */
    417 
    418         goto InvalidResource;
    419     }
    420 
    421     AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml);
    422     if (ResourceType == ACPI_RESOURCE_NAME_SERIAL_BUS)
    423     {
    424         /* Validate the BusType field */
    425 
    426         if ((AmlResource->CommonSerialBus.Type == 0) ||
    427             (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE))
    428         {
    429             if (WalkState)
    430             {
    431                 ACPI_ERROR ((AE_INFO,
    432                     "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
    433                     AmlResource->CommonSerialBus.Type));
    434             }
    435             return (AE_AML_INVALID_RESOURCE_TYPE);
    436         }
    437     }
    438 
    439     /* Optionally return the resource table index */
    440 
    441     if (ReturnIndex)
    442     {
    443         *ReturnIndex = ResourceIndex;
    444     }
    445 
    446     return (AE_OK);
    447 
    448 
    449 InvalidResource:
    450 
    451     if (WalkState)
    452     {
    453         ACPI_ERROR ((AE_INFO,
    454             "Invalid/unsupported resource descriptor: Type 0x%2.2X",
    455             ResourceType));
    456     }
    457     return (AE_AML_INVALID_RESOURCE_TYPE);
    458 
    459 BadResourceLength:
    460 
    461     if (WalkState)
    462     {
    463         ACPI_ERROR ((AE_INFO,
    464             "Invalid resource descriptor length: Type "
    465             "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
    466             ResourceType, ResourceLength, MinimumResourceLength));
    467     }
    468     return (AE_AML_BAD_RESOURCE_LENGTH);
    469 }
    470 
    471 
    472 /*******************************************************************************
    473  *
    474  * FUNCTION:    AcpiUtGetResourceType
    475  *
    476  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    477  *
    478  * RETURN:      The Resource Type with no extraneous bits (except the
    479  *              Large/Small descriptor bit -- this is left alone)
    480  *
    481  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
    482  *              a resource descriptor.
    483  *
    484  ******************************************************************************/
    485 
    486 UINT8
    487 AcpiUtGetResourceType (
    488     void                    *Aml)
    489 {
    490     ACPI_FUNCTION_ENTRY ();
    491 
    492 
    493     /*
    494      * Byte 0 contains the descriptor name (Resource Type)
    495      * Examine the large/small bit in the resource header
    496      */
    497     if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
    498     {
    499         /* Large Resource Type -- bits 6:0 contain the name */
    500 
    501         return (ACPI_GET8 (Aml));
    502     }
    503     else
    504     {
    505         /* Small Resource Type -- bits 6:3 contain the name */
    506 
    507         return ((UINT8) (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
    508     }
    509 }
    510 
    511 
    512 /*******************************************************************************
    513  *
    514  * FUNCTION:    AcpiUtGetResourceLength
    515  *
    516  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    517  *
    518  * RETURN:      Byte Length
    519  *
    520  * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
    521  *              definition, this does not include the size of the descriptor
    522  *              header or the length field itself.
    523  *
    524  ******************************************************************************/
    525 
    526 UINT16
    527 AcpiUtGetResourceLength (
    528     void                    *Aml)
    529 {
    530     ACPI_RS_LENGTH          ResourceLength;
    531 
    532 
    533     ACPI_FUNCTION_ENTRY ();
    534 
    535 
    536     /*
    537      * Byte 0 contains the descriptor name (Resource Type)
    538      * Examine the large/small bit in the resource header
    539      */
    540     if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
    541     {
    542         /* Large Resource type -- bytes 1-2 contain the 16-bit length */
    543 
    544         ACPI_MOVE_16_TO_16 (&ResourceLength, ACPI_ADD_PTR (UINT8, Aml, 1));
    545 
    546     }
    547     else
    548     {
    549         /* Small Resource type -- bits 2:0 of byte 0 contain the length */
    550 
    551         ResourceLength = (UINT16) (ACPI_GET8 (Aml) &
    552             ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
    553     }
    554 
    555     return (ResourceLength);
    556 }
    557 
    558 
    559 /*******************************************************************************
    560  *
    561  * FUNCTION:    AcpiUtGetResourceHeaderLength
    562  *
    563  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    564  *
    565  * RETURN:      Length of the AML header (depends on large/small descriptor)
    566  *
    567  * DESCRIPTION: Get the length of the header for this resource.
    568  *
    569  ******************************************************************************/
    570 
    571 UINT8
    572 AcpiUtGetResourceHeaderLength (
    573     void                    *Aml)
    574 {
    575     ACPI_FUNCTION_ENTRY ();
    576 
    577 
    578     /* Examine the large/small bit in the resource header */
    579 
    580     if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
    581     {
    582         return (sizeof (AML_RESOURCE_LARGE_HEADER));
    583     }
    584     else
    585     {
    586         return (sizeof (AML_RESOURCE_SMALL_HEADER));
    587     }
    588 }
    589 
    590 
    591 /*******************************************************************************
    592  *
    593  * FUNCTION:    AcpiUtGetDescriptorLength
    594  *
    595  * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
    596  *
    597  * RETURN:      Byte length
    598  *
    599  * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
    600  *              length of the descriptor header and the length field itself.
    601  *              Used to walk descriptor lists.
    602  *
    603  ******************************************************************************/
    604 
    605 UINT32
    606 AcpiUtGetDescriptorLength (
    607     void                    *Aml)
    608 {
    609     ACPI_FUNCTION_ENTRY ();
    610 
    611 
    612     /*
    613      * Get the Resource Length (does not include header length) and add
    614      * the header length (depends on if this is a small or large resource)
    615      */
    616     return (AcpiUtGetResourceLength (Aml) +
    617         AcpiUtGetResourceHeaderLength (Aml));
    618 }
    619 
    620 
    621 /*******************************************************************************
    622  *
    623  * FUNCTION:    AcpiUtGetResourceEndTag
    624  *
    625  * PARAMETERS:  ObjDesc         - The resource template buffer object
    626  *              EndTag          - Where the pointer to the EndTag is returned
    627  *
    628  * RETURN:      Status, pointer to the end tag
    629  *
    630  * DESCRIPTION: Find the EndTag resource descriptor in an AML resource template
    631  *              Note: allows a buffer length of zero.
    632  *
    633  ******************************************************************************/
    634 
    635 ACPI_STATUS
    636 AcpiUtGetResourceEndTag (
    637     ACPI_OPERAND_OBJECT     *ObjDesc,
    638     UINT8                   **EndTag)
    639 {
    640     ACPI_STATUS             Status;
    641 
    642 
    643     ACPI_FUNCTION_TRACE (UtGetResourceEndTag);
    644 
    645 
    646     /* Allow a buffer length of zero */
    647 
    648     if (!ObjDesc->Buffer.Length)
    649     {
    650         *EndTag = ObjDesc->Buffer.Pointer;
    651         return_ACPI_STATUS (AE_OK);
    652     }
    653 
    654     /* Validate the template and get a pointer to the EndTag */
    655 
    656     Status = AcpiUtWalkAmlResources (NULL, ObjDesc->Buffer.Pointer,
    657         ObjDesc->Buffer.Length, NULL, (void **) EndTag);
    658 
    659     return_ACPI_STATUS (Status);
    660 }
    661