utresrc.c revision 7851:e828bbb1689c
1/*******************************************************************************
2 *
3 * Module Name: utresrc - Resource managment utilities
4 *              $Revision: 1.15 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#define __UTRESRC_C__
119
120#include "acpi.h"
121#include "amlresrc.h"
122
123
124#define _COMPONENT          ACPI_UTILITIES
125        ACPI_MODULE_NAME    ("utresrc")
126
127
128#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
129
130/*
131 * Strings used to decode resource descriptors.
132 * Used by both the disasssembler and the debugger resource dump routines
133 */
134const char                      *AcpiGbl_BmDecode[] =
135{
136    "NotBusMaster",
137    "BusMaster"
138};
139
140const char                      *AcpiGbl_ConfigDecode[] =
141{
142    "0 - Good Configuration",
143    "1 - Acceptable Configuration",
144    "2 - Suboptimal Configuration",
145    "3 - ***Invalid Configuration***",
146};
147
148const char                      *AcpiGbl_ConsumeDecode[] =
149{
150    "ResourceProducer",
151    "ResourceConsumer"
152};
153
154const char                      *AcpiGbl_DecDecode[] =
155{
156    "PosDecode",
157    "SubDecode"
158};
159
160const char                      *AcpiGbl_HeDecode[] =
161{
162    "Level",
163    "Edge"
164};
165
166const char                      *AcpiGbl_IoDecode[] =
167{
168    "Decode10",
169    "Decode16"
170};
171
172const char                      *AcpiGbl_LlDecode[] =
173{
174    "ActiveHigh",
175    "ActiveLow"
176};
177
178const char                      *AcpiGbl_MaxDecode[] =
179{
180    "MaxNotFixed",
181    "MaxFixed"
182};
183
184const char                      *AcpiGbl_MemDecode[] =
185{
186    "NonCacheable",
187    "Cacheable",
188    "WriteCombining",
189    "Prefetchable"
190};
191
192const char                      *AcpiGbl_MinDecode[] =
193{
194    "MinNotFixed",
195    "MinFixed"
196};
197
198const char                      *AcpiGbl_MtpDecode[] =
199{
200    "AddressRangeMemory",
201    "AddressRangeReserved",
202    "AddressRangeACPI",
203    "AddressRangeNVS"
204};
205
206const char                      *AcpiGbl_RngDecode[] =
207{
208    "InvalidRanges",
209    "NonISAOnlyRanges",
210    "ISAOnlyRanges",
211    "EntireRange"
212};
213
214const char                      *AcpiGbl_RwDecode[] =
215{
216    "ReadOnly",
217    "ReadWrite"
218};
219
220const char                      *AcpiGbl_ShrDecode[] =
221{
222    "Exclusive",
223    "Shared"
224};
225
226const char                      *AcpiGbl_SizDecode[] =
227{
228    "Transfer8",
229    "Transfer8_16",
230    "Transfer16",
231    "InvalidSize"
232};
233
234const char                      *AcpiGbl_TrsDecode[] =
235{
236    "DenseTranslation",
237    "SparseTranslation"
238};
239
240const char                      *AcpiGbl_TtpDecode[] =
241{
242    "TypeStatic",
243    "TypeTranslation"
244};
245
246const char                      *AcpiGbl_TypDecode[] =
247{
248    "Compatibility",
249    "TypeA",
250    "TypeB",
251    "TypeF"
252};
253
254#endif
255
256
257/*
258 * Base sizes of the raw AML resource descriptors, indexed by resource type.
259 * Zero indicates a reserved (and therefore invalid) resource type.
260 */
261const UINT8                 AcpiGbl_ResourceAmlSizes[] =
262{
263    /* Small descriptors */
264
265    0,
266    0,
267    0,
268    0,
269    ACPI_AML_SIZE_SMALL (AML_RESOURCE_IRQ),
270    ACPI_AML_SIZE_SMALL (AML_RESOURCE_DMA),
271    ACPI_AML_SIZE_SMALL (AML_RESOURCE_START_DEPENDENT),
272    ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_DEPENDENT),
273    ACPI_AML_SIZE_SMALL (AML_RESOURCE_IO),
274    ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_IO),
275    0,
276    0,
277    0,
278    0,
279    ACPI_AML_SIZE_SMALL (AML_RESOURCE_VENDOR_SMALL),
280    ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_TAG),
281
282    /* Large descriptors */
283
284    0,
285    ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY24),
286    ACPI_AML_SIZE_LARGE (AML_RESOURCE_GENERIC_REGISTER),
287    0,
288    ACPI_AML_SIZE_LARGE (AML_RESOURCE_VENDOR_LARGE),
289    ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY32),
290    ACPI_AML_SIZE_LARGE (AML_RESOURCE_FIXED_MEMORY32),
291    ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS32),
292    ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS16),
293    ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_IRQ),
294    ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS64),
295    ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_ADDRESS64)
296};
297
298
299/*
300 * Resource types, used to validate the resource length field.
301 * The length of fixed-length types must match exactly, variable
302 * lengths must meet the minimum required length, etc.
303 * Zero indicates a reserved (and therefore invalid) resource type.
304 */
305static const UINT8          AcpiGbl_ResourceTypes[] =
306{
307    /* Small descriptors */
308
309    0,
310    0,
311    0,
312    0,
313    ACPI_SMALL_VARIABLE_LENGTH,
314    ACPI_FIXED_LENGTH,
315    ACPI_SMALL_VARIABLE_LENGTH,
316    ACPI_FIXED_LENGTH,
317    ACPI_FIXED_LENGTH,
318    ACPI_FIXED_LENGTH,
319    0,
320    0,
321    0,
322    0,
323    ACPI_VARIABLE_LENGTH,
324    ACPI_FIXED_LENGTH,
325
326    /* Large descriptors */
327
328    0,
329    ACPI_FIXED_LENGTH,
330    ACPI_FIXED_LENGTH,
331    0,
332    ACPI_VARIABLE_LENGTH,
333    ACPI_FIXED_LENGTH,
334    ACPI_FIXED_LENGTH,
335    ACPI_VARIABLE_LENGTH,
336    ACPI_VARIABLE_LENGTH,
337    ACPI_VARIABLE_LENGTH,
338    ACPI_VARIABLE_LENGTH,
339    ACPI_FIXED_LENGTH
340};
341
342
343/*******************************************************************************
344 *
345 * FUNCTION:    AcpiUtWalkAmlResources
346 *
347 * PARAMETERS:  Aml             - Pointer to the raw AML resource template
348 *              AmlLength       - Length of the entire template
349 *              UserFunction    - Called once for each descriptor found. If
350 *                                NULL, a pointer to the EndTag is returned
351 *              Context         - Passed to UserFunction
352 *
353 * RETURN:      Status
354 *
355 * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
356 *              once for each resource found.
357 *
358 ******************************************************************************/
359
360ACPI_STATUS
361AcpiUtWalkAmlResources (
362    UINT8                   *Aml,
363    ACPI_SIZE               AmlLength,
364    ACPI_WALK_AML_CALLBACK  UserFunction,
365    void                    *Context)
366{
367    ACPI_STATUS             Status;
368    UINT8                   *EndAml;
369    UINT8                   ResourceIndex;
370    UINT32                  Length;
371    UINT32                  Offset = 0;
372
373
374    ACPI_FUNCTION_TRACE (UtWalkAmlResources);
375
376
377    /* The absolute minimum resource template is one EndTag descriptor */
378
379    if (AmlLength < sizeof (AML_RESOURCE_END_TAG))
380    {
381        return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
382    }
383
384    /* Point to the end of the resource template buffer */
385
386    EndAml = Aml + AmlLength;
387
388    /* Walk the byte list, abort on any invalid descriptor type or length */
389
390    while (Aml < EndAml)
391    {
392        /* Validate the Resource Type and Resource Length */
393
394        Status = AcpiUtValidateResource (Aml, &ResourceIndex);
395        if (ACPI_FAILURE (Status))
396        {
397            return_ACPI_STATUS (Status);
398        }
399
400        /* Get the length of this descriptor */
401
402        Length = AcpiUtGetDescriptorLength (Aml);
403
404        /* Invoke the user function */
405
406        if (UserFunction)
407        {
408            Status = UserFunction (Aml, Length, Offset, ResourceIndex, Context);
409            if (ACPI_FAILURE (Status))
410            {
411                return (Status);
412            }
413        }
414
415        /* An EndTag descriptor terminates this resource template */
416
417        if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_END_TAG)
418        {
419            /*
420             * There must be at least one more byte in the buffer for
421             * the 2nd byte of the EndTag
422             */
423            if ((Aml + 1) >= EndAml)
424            {
425                return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
426            }
427
428            /* Return the pointer to the EndTag if requested */
429
430            if (!UserFunction)
431            {
432                *(void **) Context = Aml;
433            }
434
435            /* Normal exit */
436
437            return_ACPI_STATUS (AE_OK);
438        }
439
440        Aml += Length;
441        Offset += Length;
442    }
443
444    /* Did not find an EndTag descriptor */
445
446    return (AE_AML_NO_RESOURCE_END_TAG);
447}
448
449
450/*******************************************************************************
451 *
452 * FUNCTION:    AcpiUtValidateResource
453 *
454 * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
455 *              ReturnIndex     - Where the resource index is returned. NULL
456 *                                if the index is not required.
457 *
458 * RETURN:      Status, and optionally the Index into the global resource tables
459 *
460 * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
461 *              Type and Resource Length. Returns an index into the global
462 *              resource information/dispatch tables for later use.
463 *
464 ******************************************************************************/
465
466ACPI_STATUS
467AcpiUtValidateResource (
468    void                    *Aml,
469    UINT8                   *ReturnIndex)
470{
471    UINT8                   ResourceType;
472    UINT8                   ResourceIndex;
473    ACPI_RS_LENGTH          ResourceLength;
474    ACPI_RS_LENGTH          MinimumResourceLength;
475
476
477    ACPI_FUNCTION_ENTRY ();
478
479
480    /*
481     * 1) Validate the ResourceType field (Byte 0)
482     */
483    ResourceType = ACPI_GET8 (Aml);
484
485    /*
486     * Byte 0 contains the descriptor name (Resource Type)
487     * Examine the large/small bit in the resource header
488     */
489    if (ResourceType & ACPI_RESOURCE_NAME_LARGE)
490    {
491        /* Verify the large resource type (name) against the max */
492
493        if (ResourceType > ACPI_RESOURCE_NAME_LARGE_MAX)
494        {
495            return (AE_AML_INVALID_RESOURCE_TYPE);
496        }
497
498        /*
499         * Large Resource Type -- bits 6:0 contain the name
500         * Translate range 0x80-0x8B to index range 0x10-0x1B
501         */
502        ResourceIndex = (UINT8) (ResourceType - 0x70);
503    }
504    else
505    {
506        /*
507         * Small Resource Type -- bits 6:3 contain the name
508         * Shift range to index range 0x00-0x0F
509         */
510        ResourceIndex = (UINT8)
511            ((ResourceType & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
512    }
513
514    /* Check validity of the resource type, zero indicates name is invalid */
515
516    if (!AcpiGbl_ResourceTypes[ResourceIndex])
517    {
518        return (AE_AML_INVALID_RESOURCE_TYPE);
519    }
520
521
522    /*
523     * 2) Validate the ResourceLength field. This ensures that the length
524     *    is at least reasonable, and guarantees that it is non-zero.
525     */
526    ResourceLength = AcpiUtGetResourceLength (Aml);
527    MinimumResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
528
529    /* Validate based upon the type of resource - fixed length or variable */
530
531    switch (AcpiGbl_ResourceTypes[ResourceIndex])
532    {
533    case ACPI_FIXED_LENGTH:
534
535        /* Fixed length resource, length must match exactly */
536
537        if (ResourceLength != MinimumResourceLength)
538        {
539            return (AE_AML_BAD_RESOURCE_LENGTH);
540        }
541        break;
542
543    case ACPI_VARIABLE_LENGTH:
544
545        /* Variable length resource, length must be at least the minimum */
546
547        if (ResourceLength < MinimumResourceLength)
548        {
549            return (AE_AML_BAD_RESOURCE_LENGTH);
550        }
551        break;
552
553    case ACPI_SMALL_VARIABLE_LENGTH:
554
555        /* Small variable length resource, length can be (Min) or (Min-1) */
556
557        if ((ResourceLength > MinimumResourceLength) ||
558            (ResourceLength < (MinimumResourceLength - 1)))
559        {
560            return (AE_AML_BAD_RESOURCE_LENGTH);
561        }
562        break;
563
564    default:
565
566        /* Shouldn't happen (because of validation earlier), but be sure */
567
568        return (AE_AML_INVALID_RESOURCE_TYPE);
569    }
570
571    /* Optionally return the resource table index */
572
573    if (ReturnIndex)
574    {
575        *ReturnIndex = ResourceIndex;
576    }
577
578    return (AE_OK);
579}
580
581
582/*******************************************************************************
583 *
584 * FUNCTION:    AcpiUtGetResourceType
585 *
586 * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
587 *
588 * RETURN:      The Resource Type with no extraneous bits (except the
589 *              Large/Small descriptor bit -- this is left alone)
590 *
591 * DESCRIPTION: Extract the Resource Type/Name from the first byte of
592 *              a resource descriptor.
593 *
594 ******************************************************************************/
595
596UINT8
597AcpiUtGetResourceType (
598    void                    *Aml)
599{
600    ACPI_FUNCTION_ENTRY ();
601
602
603    /*
604     * Byte 0 contains the descriptor name (Resource Type)
605     * Examine the large/small bit in the resource header
606     */
607    if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
608    {
609        /* Large Resource Type -- bits 6:0 contain the name */
610
611        return (ACPI_GET8 (Aml));
612    }
613    else
614    {
615        /* Small Resource Type -- bits 6:3 contain the name */
616
617        return ((UINT8) (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
618    }
619}
620
621
622/*******************************************************************************
623 *
624 * FUNCTION:    AcpiUtGetResourceLength
625 *
626 * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
627 *
628 * RETURN:      Byte Length
629 *
630 * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
631 *              definition, this does not include the size of the descriptor
632 *              header or the length field itself.
633 *
634 ******************************************************************************/
635
636UINT16
637AcpiUtGetResourceLength (
638    void                    *Aml)
639{
640    ACPI_RS_LENGTH          ResourceLength;
641
642
643    ACPI_FUNCTION_ENTRY ();
644
645
646    /*
647     * Byte 0 contains the descriptor name (Resource Type)
648     * Examine the large/small bit in the resource header
649     */
650    if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
651    {
652        /* Large Resource type -- bytes 1-2 contain the 16-bit length */
653
654        ACPI_MOVE_16_TO_16 (&ResourceLength, ACPI_ADD_PTR (UINT8, Aml, 1));
655
656    }
657    else
658    {
659        /* Small Resource type -- bits 2:0 of byte 0 contain the length */
660
661        ResourceLength = (UINT16) (ACPI_GET8 (Aml) &
662                                    ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
663    }
664
665    return (ResourceLength);
666}
667
668
669/*******************************************************************************
670 *
671 * FUNCTION:    AcpiUtGetResourceHeaderLength
672 *
673 * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
674 *
675 * RETURN:      Length of the AML header (depends on large/small descriptor)
676 *
677 * DESCRIPTION: Get the length of the header for this resource.
678 *
679 ******************************************************************************/
680
681UINT8
682AcpiUtGetResourceHeaderLength (
683    void                    *Aml)
684{
685    ACPI_FUNCTION_ENTRY ();
686
687
688    /* Examine the large/small bit in the resource header */
689
690    if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE)
691    {
692        return (sizeof (AML_RESOURCE_LARGE_HEADER));
693    }
694    else
695    {
696        return (sizeof (AML_RESOURCE_SMALL_HEADER));
697    }
698}
699
700
701/*******************************************************************************
702 *
703 * FUNCTION:    AcpiUtGetDescriptorLength
704 *
705 * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
706 *
707 * RETURN:      Byte length
708 *
709 * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
710 *              length of the descriptor header and the length field itself.
711 *              Used to walk descriptor lists.
712 *
713 ******************************************************************************/
714
715UINT32
716AcpiUtGetDescriptorLength (
717    void                    *Aml)
718{
719    ACPI_FUNCTION_ENTRY ();
720
721
722    /*
723     * Get the Resource Length (does not include header length) and add
724     * the header length (depends on if this is a small or large resource)
725     */
726    return (AcpiUtGetResourceLength (Aml) +
727            AcpiUtGetResourceHeaderLength (Aml));
728}
729
730
731/*******************************************************************************
732 *
733 * FUNCTION:    AcpiUtGetResourceEndTag
734 *
735 * PARAMETERS:  ObjDesc         - The resource template buffer object
736 *              EndTag          - Where the pointer to the EndTag is returned
737 *
738 * RETURN:      Status, pointer to the end tag
739 *
740 * DESCRIPTION: Find the EndTag resource descriptor in an AML resource template
741 *              Note: allows a buffer length of zero.
742 *
743 ******************************************************************************/
744
745ACPI_STATUS
746AcpiUtGetResourceEndTag (
747    ACPI_OPERAND_OBJECT     *ObjDesc,
748    UINT8                   **EndTag)
749{
750    ACPI_STATUS             Status;
751
752
753    ACPI_FUNCTION_TRACE (UtGetResourceEndTag);
754
755
756    /* Allow a buffer length of zero */
757
758    if (!ObjDesc->Buffer.Length)
759    {
760        *EndTag = ObjDesc->Buffer.Pointer;
761        return_ACPI_STATUS (AE_OK);
762    }
763
764    /* Validate the template and get a pointer to the EndTag */
765
766    Status = AcpiUtWalkAmlResources (ObjDesc->Buffer.Pointer,
767                ObjDesc->Buffer.Length, NULL, EndTag);
768
769    return_ACPI_STATUS (Status);
770}
771
772
773