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