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