Sync ACPICA with Intel's version 20180508 (from previously 20170831).
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / aslrestype2s.c
1 /******************************************************************************
2  *
3  * Module Name: aslrestype2s - Serial Large resource descriptors
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151
152 #include "aslcompiler.h"
153 #include "aslcompiler.y.h"
154 #include "amlcode.h"
155
156 #define _COMPONENT          ACPI_COMPILER
157         ACPI_MODULE_NAME    ("aslrestype2s")
158
159
160 static UINT16
161 RsGetBufferDataLength (
162     ACPI_PARSE_OBJECT       *InitializerOp);
163
164 static UINT16
165 RsGetInterruptDataLength (
166     ACPI_PARSE_OBJECT       *InitializerOp,
167     UINT32                  StartIndex);
168
169 static BOOLEAN
170 RsGetVendorData (
171     ACPI_PARSE_OBJECT       *InitializerOp,
172     UINT8                   *VendorData,
173     ACPI_SIZE               DescriptorOffset);
174
175 static UINT16
176 RsGetStringDataLengthAt (
177     ACPI_PARSE_OBJECT       *InitializerOp,
178     UINT32                  StartIndex);
179
180 /*
181  * This module contains descriptors for serial buses and GPIO:
182  *
183  * GpioInt
184  * GpioIo
185  * I2cSerialBus
186  * SpiSerialBus
187  * UartSerialBus
188  * PinFunction
189  * PinConfig
190  * PinGroup
191  * PinGroupFunction
192  * PinGroupConfig
193  */
194
195
196 /*******************************************************************************
197  *
198  * FUNCTION:    RsGetBufferDataLength
199  *
200  * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
201  *                                    descriptor
202  *
203  * RETURN:      Length of the data buffer
204  *
205  * DESCRIPTION: Get the length of a RawDataBuffer, used for vendor data.
206  *
207  ******************************************************************************/
208
209 static UINT16
210 RsGetBufferDataLength (
211     ACPI_PARSE_OBJECT       *InitializerOp)
212 {
213     UINT16                  ExtraDataSize = 0;
214     ACPI_PARSE_OBJECT       *DataList;
215
216
217     /* Find the byte-initializer list */
218
219     while (InitializerOp)
220     {
221         if (InitializerOp->Asl.ParseOpcode == PARSEOP_DATABUFFER)
222         {
223             /* First child is the optional length (ignore it here) */
224
225             DataList = InitializerOp->Asl.Child;
226             DataList = ASL_GET_PEER_NODE (DataList);
227
228             /* Count the data items (each one is a byte of data) */
229
230             while (DataList)
231             {
232                 ExtraDataSize++;
233                 DataList = ASL_GET_PEER_NODE (DataList);
234             }
235
236             return (ExtraDataSize);
237         }
238
239         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
240     }
241
242     return (ExtraDataSize);
243 }
244
245
246 /*******************************************************************************
247  *
248  * FUNCTION:    RsGetInterruptDataLength
249  *
250  * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
251  *                                    descriptor
252  *              StartIndex          - Start index of interrupt/pin list
253  *
254  * RETURN:      Length of the interrupt data list
255  *
256  * DESCRIPTION: Get the length of a list of interrupt DWORDs for the GPIO
257  *              descriptors.
258  *
259  ******************************************************************************/
260
261 static UINT16
262 RsGetInterruptDataLength (
263     ACPI_PARSE_OBJECT       *InitializerOp,
264     UINT32                  StartIndex)
265 {
266     UINT16                  InterruptLength;
267     UINT32                  i;
268
269
270     /* Count the interrupt numbers */
271
272     InterruptLength = 0;
273     for (i = 0; InitializerOp; i++)
274     {
275         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
276
277         /* Interrupt list starts at offset StartIndex (Gpio descriptors) */
278
279         if (i >= StartIndex)
280         {
281             InterruptLength += 2;
282         }
283     }
284
285     return (InterruptLength);
286 }
287
288
289 /*******************************************************************************
290  *
291  * FUNCTION:    RsGetVendorData
292  *
293  * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
294  *                                    descriptor.
295  *              VendorData          - Where the vendor data is returned
296  *              DescriptorOffset    - Where vendor data begins in descriptor
297  *
298  * RETURN:      TRUE if valid vendor data was returned, FALSE otherwise.
299  *
300  * DESCRIPTION: Extract the vendor data and construct a vendor data buffer.
301  *
302  ******************************************************************************/
303
304 static BOOLEAN
305 RsGetVendorData (
306     ACPI_PARSE_OBJECT       *InitializerOp,
307     UINT8                   *VendorData,
308     ACPI_SIZE               DescriptorOffset)
309 {
310     ACPI_PARSE_OBJECT       *BufferOp;
311     UINT32                  SpecifiedLength = ACPI_UINT32_MAX;
312     UINT16                  ActualLength = 0;
313
314
315     /* Vendor Data field is always optional */
316
317     if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
318     {
319         return (FALSE);
320     }
321
322     BufferOp = InitializerOp->Asl.Child;
323     if (!BufferOp)
324     {
325         AslError (ASL_ERROR, ASL_MSG_SYNTAX, InitializerOp, "");
326         return (FALSE);
327     }
328
329     /* First child is the optional buffer length (WORD) */
330
331     if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
332     {
333         SpecifiedLength = (UINT16) BufferOp->Asl.Value.Integer;
334     }
335
336     /* Insert field tag _VEN */
337
338     RsCreateByteField (InitializerOp, ACPI_RESTAG_VENDORDATA,
339         (UINT16) DescriptorOffset);
340
341     /* Walk the list of buffer initializers (each is one byte) */
342
343     BufferOp = RsCompleteNodeAndGetNext (BufferOp);
344     if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
345     {
346         while (BufferOp)
347         {
348             *VendorData = (UINT8) BufferOp->Asl.Value.Integer;
349             VendorData++;
350             ActualLength++;
351             BufferOp = RsCompleteNodeAndGetNext (BufferOp);
352         }
353     }
354
355     /* Length validation. Buffer cannot be of zero length */
356
357     if ((SpecifiedLength == 0) ||
358         ((SpecifiedLength == ACPI_UINT32_MAX) && (ActualLength == 0)))
359     {
360         AslError (ASL_ERROR, ASL_MSG_BUFFER_LENGTH, InitializerOp, NULL);
361         return (FALSE);
362     }
363
364     if (SpecifiedLength != ACPI_UINT32_MAX)
365     {
366         /* ActualLength > SpecifiedLength -> error */
367
368         if (ActualLength > SpecifiedLength)
369         {
370             AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, InitializerOp, NULL);
371             return (FALSE);
372         }
373
374         /* ActualLength < SpecifiedLength -> remark */
375
376         else if (ActualLength < SpecifiedLength)
377         {
378             AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, InitializerOp, NULL);
379             return (FALSE);
380         }
381     }
382
383     return (TRUE);
384 }
385
386
387 /*******************************************************************************
388  *
389  * FUNCTION:    RsGetStringDataLengthAt
390  *
391  * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
392  *              StartIndex        - Starting index of the string node
393  *
394  * RETURN:      Valid string length if a string node is found at given
395  *               StartIndex or 0 otherwise.
396  *
397  * DESCRIPTION: In a list of peer nodes, find the first one at given index
398  *              that contains a string and return length.
399  *
400  ******************************************************************************/
401
402 static UINT16
403 RsGetStringDataLengthAt (
404     ACPI_PARSE_OBJECT       *InitializerOp,
405     UINT32                  StartIndex)
406 {
407     UINT32 i;
408
409     for (i = 0; InitializerOp; i++)
410     {
411         if (i == StartIndex &&
412             InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
413         {
414             return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
415         }
416
417         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
418     }
419
420     return (0);
421 }
422
423
424 /*******************************************************************************
425  *
426  * FUNCTION:    RsDoGpioIntDescriptor
427  *
428  * PARAMETERS:  Info                - Parse Op and resource template offset
429  *
430  * RETURN:      Completed resource node
431  *
432  * DESCRIPTION: Construct a long "GpioInt" descriptor
433  *
434  ******************************************************************************/
435
436 ASL_RESOURCE_NODE *
437 RsDoGpioIntDescriptor (
438     ASL_RESOURCE_INFO       *Info)
439 {
440     AML_RESOURCE            *Descriptor;
441     ACPI_PARSE_OBJECT       *InitializerOp;
442     ASL_RESOURCE_NODE       *Rnode;
443     char                    *ResourceSource = NULL;
444     UINT8                   *VendorData = NULL;
445     UINT16                  *InterruptList = NULL;
446     UINT16                  *PinList = NULL;
447     UINT16                  ResSourceLength;
448     UINT16                  VendorLength;
449     UINT16                  InterruptLength;
450     UINT16                  DescriptorSize;
451     UINT32                  CurrentByteOffset;
452     UINT32                  PinCount = 0;
453     UINT32                  i;
454
455
456     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
457     CurrentByteOffset = Info->CurrentByteOffset;
458
459     /*
460      * Calculate lengths for fields that have variable length:
461      * 1) Resource Source string
462      * 2) Vendor Data buffer
463      * 3) PIN (interrupt) list
464      */
465     ResSourceLength = RsGetStringDataLength (InitializerOp);
466     VendorLength = RsGetBufferDataLength (InitializerOp);
467     InterruptLength = RsGetInterruptDataLength (InitializerOp, 10);
468
469     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
470         ResSourceLength + VendorLength + InterruptLength;
471
472     /* Allocate the local resource node and initialize */
473
474     Rnode = RsAllocateResourceNode (DescriptorSize +
475         sizeof (AML_RESOURCE_LARGE_HEADER));
476
477     Descriptor = Rnode->Buffer;
478     Descriptor->Gpio.ResourceLength = DescriptorSize;
479     Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
480     Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
481     Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_INT;
482
483     /* Build pointers to optional areas */
484
485     InterruptList = ACPI_ADD_PTR (UINT16, Descriptor,
486         sizeof (AML_RESOURCE_GPIO));
487     PinList = InterruptList;
488     ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
489     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
490
491     /* Setup offsets within the descriptor */
492
493     Descriptor->Gpio.PinTableOffset = (UINT16)
494         ACPI_PTR_DIFF (InterruptList, Descriptor);
495
496     Descriptor->Gpio.ResSourceOffset = (UINT16)
497         ACPI_PTR_DIFF (ResourceSource, Descriptor);
498
499     /* Process all child initialization nodes */
500
501     for (i = 0; InitializerOp; i++)
502     {
503         switch (i)
504         {
505         case 0: /* Interrupt Mode - edge/level [Flag] (_MOD) */
506
507             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
508             RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
509                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0);
510             break;
511
512         case 1: /* Interrupt Polarity - Active high/low [Flags] (_POL) */
513
514             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 1, 0);
515             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_POLARITY,
516                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 1, 2);
517             break;
518
519         case 2: /* Share Type - Default: exclusive (0) [Flags] (_SHR) */
520
521             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
522             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
523                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3, 2);
524             break;
525
526         case 3: /* Pin Config [BYTE] (_PPI) */
527
528             Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
529             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
530                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
531             break;
532
533         case 4: /* Debounce Timeout [WORD] (_DBT) */
534
535             Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
536             RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
537                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
538             break;
539
540         case 5: /* ResSource [Optional Field - STRING] */
541
542             if (ResSourceLength)
543             {
544                 /* Copy string to the descriptor */
545
546                 strcpy (ResourceSource,
547                     InitializerOp->Asl.Value.String);
548             }
549             break;
550
551         case 6: /* Resource Index */
552
553             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
554             {
555                 Descriptor->Gpio.ResSourceIndex =
556                     (UINT8) InitializerOp->Asl.Value.Integer;
557             }
558             break;
559
560         case 7: /* Resource Usage (consumer/producer) */
561
562             RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
563             break;
564
565         case 8: /* Resource Tag (Descriptor Name) */
566
567             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
568             break;
569
570         case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
571
572             /*
573              * Always set the VendorOffset even if there is no Vendor Data.
574              * This field is required in order to calculate the length
575              * of the ResourceSource at runtime.
576              */
577             Descriptor->Gpio.VendorOffset = (UINT16)
578                 ACPI_PTR_DIFF (VendorData, Descriptor);
579
580             if (RsGetVendorData (InitializerOp, VendorData,
581                 (CurrentByteOffset +  Descriptor->Gpio.VendorOffset)))
582             {
583                 Descriptor->Gpio.VendorLength = VendorLength;
584             }
585             break;
586
587         default:
588             /*
589              * PINs come through here, repeatedly. Each PIN must be a WORD.
590              * NOTE: there is no "length" field for this, so from ACPI spec:
591              *  The number of pins in the table can be calculated from:
592              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
593              *  (implies resource source must immediately follow the pin list.)
594              *  Name: _PIN
595              */
596             *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
597             InterruptList++;
598             PinCount++;
599
600             /* Case 10: First interrupt number in list */
601
602             if (i == 10)
603             {
604                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
605                 {
606                     /* Must be at least one interrupt */
607
608                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
609                         InitializerOp, NULL);
610                 }
611
612                 /* Check now for duplicates in list */
613
614                 RsCheckListForDuplicates (InitializerOp);
615
616                 /* Create a named field at the start of the list */
617
618                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
619                     CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
620             }
621             break;
622         }
623
624         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
625     }
626
627     MpSaveGpioInfo (Info->MappingOp, Descriptor,
628         PinCount, PinList, ResourceSource);
629     return (Rnode);
630 }
631
632
633 /*******************************************************************************
634  *
635  * FUNCTION:    RsDoGpioIoDescriptor
636  *
637  * PARAMETERS:  Info                - Parse Op and resource template offset
638  *
639  * RETURN:      Completed resource node
640  *
641  * DESCRIPTION: Construct a long "GpioIo" descriptor
642  *
643  ******************************************************************************/
644
645 ASL_RESOURCE_NODE *
646 RsDoGpioIoDescriptor (
647     ASL_RESOURCE_INFO       *Info)
648 {
649     AML_RESOURCE            *Descriptor;
650     ACPI_PARSE_OBJECT       *InitializerOp;
651     ASL_RESOURCE_NODE       *Rnode;
652     char                    *ResourceSource = NULL;
653     UINT8                   *VendorData = NULL;
654     UINT16                  *InterruptList = NULL;
655     UINT16                  *PinList = NULL;
656     UINT16                  ResSourceLength;
657     UINT16                  VendorLength;
658     UINT16                  InterruptLength;
659     UINT16                  DescriptorSize;
660     UINT32                  CurrentByteOffset;
661     UINT32                  PinCount = 0;
662     UINT32                  i;
663
664
665     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
666     CurrentByteOffset = Info->CurrentByteOffset;
667
668     /*
669      * Calculate lengths for fields that have variable length:
670      * 1) Resource Source string
671      * 2) Vendor Data buffer
672      * 3) PIN (interrupt) list
673      */
674     ResSourceLength = RsGetStringDataLength (InitializerOp);
675     VendorLength = RsGetBufferDataLength (InitializerOp);
676     InterruptLength = RsGetInterruptDataLength (InitializerOp, 10);
677     PinList = InterruptList;
678
679     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
680         ResSourceLength + VendorLength + InterruptLength;
681
682     /* Allocate the local resource node and initialize */
683
684     Rnode = RsAllocateResourceNode (DescriptorSize +
685         sizeof (AML_RESOURCE_LARGE_HEADER));
686
687     Descriptor = Rnode->Buffer;
688     Descriptor->Gpio.ResourceLength = DescriptorSize;
689     Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
690     Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
691     Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO;
692
693     /* Build pointers to optional areas */
694
695     InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO));
696     PinList = InterruptList;
697     ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
698     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
699
700     /* Setup offsets within the descriptor */
701
702     Descriptor->Gpio.PinTableOffset = (UINT16)
703         ACPI_PTR_DIFF (InterruptList, Descriptor);
704
705     Descriptor->Gpio.ResSourceOffset = (UINT16)
706         ACPI_PTR_DIFF (ResourceSource, Descriptor);
707
708     /* Process all child initialization nodes */
709
710     for (i = 0; InitializerOp; i++)
711     {
712         switch (i)
713         {
714         case 0: /* Share Type [Flags] (_SHR) */
715
716             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
717             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
718                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3);
719             break;
720
721         case 1: /* Pin Config [BYTE] (_PPI) */
722
723             Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
724             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
725                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
726             break;
727
728         case 2: /* Debounce Timeout [WORD] (_DBT) */
729
730             Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
731             RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
732                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
733             break;
734
735         case 3: /* Drive Strength [WORD] (_DRS) */
736
737             Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer;
738             RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH,
739                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength));
740             break;
741
742         case 4: /* I/O Restriction [Flag] (_IOR) */
743
744             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
745             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION,
746                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2);
747             break;
748
749         case 5: /* ResSource [Optional Field - STRING] */
750
751             if (ResSourceLength)
752             {
753                 /* Copy string to the descriptor */
754
755                 strcpy (ResourceSource,
756                     InitializerOp->Asl.Value.String);
757             }
758             break;
759
760         case 6: /* Resource Index */
761
762             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
763             {
764                 Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
765             }
766             break;
767
768         case 7: /* Resource Usage (consumer/producer) */
769
770             RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
771             break;
772
773         case 8: /* Resource Tag (Descriptor Name) */
774
775             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
776             break;
777
778         case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
779             /*
780              * Always set the VendorOffset even if there is no Vendor Data.
781              * This field is required in order to calculate the length
782              * of the ResourceSource at runtime.
783              */
784             Descriptor->Gpio.VendorOffset = (UINT16)
785                 ACPI_PTR_DIFF (VendorData, Descriptor);
786
787             if (RsGetVendorData (InitializerOp, VendorData,
788                 (CurrentByteOffset + Descriptor->Gpio.VendorOffset)))
789             {
790                 Descriptor->Gpio.VendorLength = VendorLength;
791             }
792             break;
793
794         default:
795             /*
796              * PINs come through here, repeatedly. Each PIN must be a WORD.
797              * NOTE: there is no "length" field for this, so from ACPI spec:
798              *  The number of pins in the table can be calculated from:
799              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
800              *  (implies resource source must immediately follow the pin list.)
801              *  Name: _PIN
802              */
803             *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
804             InterruptList++;
805             PinCount++;
806
807             /* Case 10: First interrupt number in list */
808
809             if (i == 10)
810             {
811                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
812                 {
813                     /* Must be at least one interrupt */
814
815                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
816                         InitializerOp, NULL);
817                 }
818
819                 /* Check now for duplicates in list */
820
821                 RsCheckListForDuplicates (InitializerOp);
822
823                 /* Create a named field at the start of the list */
824
825                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
826                     CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
827             }
828             break;
829         }
830
831         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
832     }
833
834     MpSaveGpioInfo (Info->MappingOp, Descriptor,
835         PinCount, PinList, ResourceSource);
836     return (Rnode);
837 }
838
839
840 /*******************************************************************************
841  *
842  * FUNCTION:    RsDoI2cSerialBusDescriptor
843  *
844  * PARAMETERS:  Info                - Parse Op and resource template offset
845  *
846  * RETURN:      Completed resource node
847  *
848  * DESCRIPTION: Construct a long "I2cSerialBus" descriptor
849  *
850  ******************************************************************************/
851
852 ASL_RESOURCE_NODE *
853 RsDoI2cSerialBusDescriptor (
854     ASL_RESOURCE_INFO       *Info)
855 {
856     AML_RESOURCE            *Descriptor;
857     ACPI_PARSE_OBJECT       *InitializerOp;
858     ASL_RESOURCE_NODE       *Rnode;
859     char                    *ResourceSource = NULL;
860     UINT8                   *VendorData = NULL;
861     UINT16                  ResSourceLength;
862     UINT16                  VendorLength;
863     UINT16                  DescriptorSize;
864     UINT32                  CurrentByteOffset;
865     UINT32                  i;
866
867
868     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
869     CurrentByteOffset = Info->CurrentByteOffset;
870
871     /*
872      * Calculate lengths for fields that have variable length:
873      * 1) Resource Source string
874      * 2) Vendor Data buffer
875      */
876     ResSourceLength = RsGetStringDataLength (InitializerOp);
877     VendorLength = RsGetBufferDataLength (InitializerOp);
878
879     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) +
880         ResSourceLength + VendorLength;
881
882     /* Allocate the local resource node and initialize */
883
884     Rnode = RsAllocateResourceNode (DescriptorSize +
885         sizeof (AML_RESOURCE_LARGE_HEADER));
886
887     Descriptor = Rnode->Buffer;
888     Descriptor->I2cSerialBus.ResourceLength = DescriptorSize;
889     Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
890     Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION;
891     Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION;
892     Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE;
893     Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength;
894
895     if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_I2C_SERIALBUS_V2)
896     {
897         Descriptor->I2cSerialBus.RevisionId = 2;
898     }
899
900     /* Build pointers to optional areas */
901
902     VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS));
903     ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
904
905     /* Process all child initialization nodes */
906
907     for (i = 0; InitializerOp; i++)
908     {
909         switch (i)
910         {
911         case 0: /* Slave Address [WORD] (_ADR) */
912
913             Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer;
914             RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
915                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress));
916             break;
917
918         case 1: /* Slave Mode [Flag] (_SLV) */
919
920             RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0);
921             RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
922                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0);
923             break;
924
925         case 2: /* Connection Speed [DWORD] (_SPE) */
926
927             Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
928             RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
929                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed));
930             break;
931
932         case 3: /* Addressing Mode [Flag] (_MOD) */
933
934             RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
935             RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
936                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0);
937             break;
938
939         case 4: /* ResSource [Optional Field - STRING] */
940
941             if (ResSourceLength)
942             {
943                 /* Copy string to the descriptor */
944
945                 strcpy (ResourceSource,
946                     InitializerOp->Asl.Value.String);
947             }
948             break;
949
950         case 5: /* Resource Index */
951
952             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
953             {
954                 Descriptor->I2cSerialBus.ResSourceIndex =
955                     (UINT8) InitializerOp->Asl.Value.Integer;
956             }
957             break;
958
959         case 6: /* Resource Usage (consumer/producer) */
960
961             RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1);
962             break;
963
964         case 7: /* Resource Tag (Descriptor Name) */
965
966             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
967             break;
968
969         case 8:
970             /*
971              * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
972              * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
973              * the ASL parser)
974              */
975             RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 2, 0);
976             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
977                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 2);
978             break;
979
980         case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
981
982             RsGetVendorData (InitializerOp, VendorData,
983                 CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS));
984             break;
985
986         default:    /* Ignore any extra nodes */
987
988             break;
989         }
990
991         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
992     }
993
994     MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
995     return (Rnode);
996 }
997
998
999 /*******************************************************************************
1000  *
1001  * FUNCTION:    RsDoSpiSerialBusDescriptor
1002  *
1003  * PARAMETERS:  Info                - Parse Op and resource template offset
1004  *
1005  * RETURN:      Completed resource node
1006  *
1007  * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor
1008  *
1009  ******************************************************************************/
1010
1011 ASL_RESOURCE_NODE *
1012 RsDoSpiSerialBusDescriptor (
1013     ASL_RESOURCE_INFO       *Info)
1014 {
1015     AML_RESOURCE            *Descriptor;
1016     ACPI_PARSE_OBJECT       *InitializerOp;
1017     ASL_RESOURCE_NODE       *Rnode;
1018     char                    *ResourceSource = NULL;
1019     UINT8                   *VendorData = NULL;
1020     UINT16                  ResSourceLength;
1021     UINT16                  VendorLength;
1022     UINT16                  DescriptorSize;
1023     UINT32                  CurrentByteOffset;
1024     UINT32                  i;
1025
1026
1027     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1028     CurrentByteOffset = Info->CurrentByteOffset;
1029
1030     /*
1031      * Calculate lengths for fields that have variable length:
1032      * 1) Resource Source string
1033      * 2) Vendor Data buffer
1034      */
1035     ResSourceLength = RsGetStringDataLength (InitializerOp);
1036     VendorLength = RsGetBufferDataLength (InitializerOp);
1037
1038     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) +
1039         ResSourceLength + VendorLength;
1040
1041     /* Allocate the local resource node and initialize */
1042
1043     Rnode = RsAllocateResourceNode (DescriptorSize +
1044         sizeof (AML_RESOURCE_LARGE_HEADER));
1045
1046     Descriptor = Rnode->Buffer;
1047     Descriptor->SpiSerialBus.ResourceLength = DescriptorSize;
1048     Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1049     Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION;
1050     Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION;
1051     Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE;
1052     Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength;
1053
1054     if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_SPI_SERIALBUS_V2)
1055     {
1056         Descriptor->I2cSerialBus.RevisionId = 2;
1057     }
1058
1059     /* Build pointers to optional areas */
1060
1061     VendorData = ACPI_ADD_PTR (UINT8, Descriptor,
1062         sizeof (AML_RESOURCE_SPI_SERIALBUS));
1063     ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1064
1065     /* Process all child initialization nodes */
1066
1067     for (i = 0; InitializerOp; i++)
1068     {
1069         switch (i)
1070         {
1071         case 0: /* Device Selection [WORD] (_ADR) */
1072
1073             Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer;
1074             RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
1075                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection));
1076             break;
1077
1078         case 1: /* Device Polarity [Flag] (_DPL) */
1079
1080             RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0);
1081             RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY,
1082                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1);
1083             break;
1084
1085         case 2: /* Wire Mode [Flag] (_MOD) */
1086
1087             RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1088             RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
1089                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0);
1090             break;
1091
1092         case 3: /* Device Bit Length [BYTE] (_LEN) */
1093
1094             Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer;
1095             RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
1096                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength));
1097             break;
1098
1099         case 4: /* Slave Mode [Flag] (_SLV) */
1100
1101             RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0);
1102             RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1103                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0);
1104             break;
1105
1106         case 5: /* Connection Speed [DWORD] (_SPE) */
1107
1108             Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
1109             RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1110                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed));
1111             break;
1112
1113         case 6: /* Clock Polarity [BYTE] (_POL) */
1114
1115             Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer;
1116             RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY,
1117                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity));
1118             break;
1119
1120         case 7: /* Clock Phase [BYTE] (_PHA) */
1121
1122             Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer;
1123             RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE,
1124                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase));
1125             break;
1126
1127         case 8: /* ResSource [Optional Field - STRING] */
1128
1129             if (ResSourceLength)
1130             {
1131                 /* Copy string to the descriptor */
1132
1133                 strcpy (ResourceSource,
1134                     InitializerOp->Asl.Value.String);
1135             }
1136             break;
1137
1138         case 9: /* Resource Index */
1139
1140             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1141             {
1142                 Descriptor->SpiSerialBus.ResSourceIndex =
1143                     (UINT8) InitializerOp->Asl.Value.Integer;
1144             }
1145             break;
1146
1147         case 10: /* Resource Usage (consumer/producer) */
1148
1149             RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1);
1150             break;
1151
1152         case 11: /* Resource Tag (Descriptor Name) */
1153
1154             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1155             break;
1156
1157         case 12:
1158             /*
1159              * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1160              * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1161              * the ASL parser)
1162              */
1163             RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 2, 0);
1164             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1165                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 2);
1166             break;
1167
1168         case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1169
1170             RsGetVendorData (InitializerOp, VendorData,
1171                 CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS));
1172             break;
1173
1174         default:    /* Ignore any extra nodes */
1175
1176             break;
1177         }
1178
1179         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1180     }
1181
1182     MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1183     return (Rnode);
1184 }
1185
1186
1187 /*******************************************************************************
1188  *
1189  * FUNCTION:    RsDoUartSerialBusDescriptor
1190  *
1191  * PARAMETERS:  Info                - Parse Op and resource template offset
1192  *
1193  * RETURN:      Completed resource node
1194  *
1195  * DESCRIPTION: Construct a long "UART Serial Bus" descriptor
1196  *
1197  ******************************************************************************/
1198
1199 ASL_RESOURCE_NODE *
1200 RsDoUartSerialBusDescriptor (
1201     ASL_RESOURCE_INFO       *Info)
1202 {
1203     AML_RESOURCE            *Descriptor;
1204     ACPI_PARSE_OBJECT       *InitializerOp;
1205     ASL_RESOURCE_NODE       *Rnode;
1206     char                    *ResourceSource = NULL;
1207     UINT8                   *VendorData = NULL;
1208     UINT16                  ResSourceLength;
1209     UINT16                  VendorLength;
1210     UINT16                  DescriptorSize;
1211     UINT32                  CurrentByteOffset;
1212     UINT32                  i;
1213
1214
1215     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1216     CurrentByteOffset = Info->CurrentByteOffset;
1217
1218     /*
1219      * Calculate lengths for fields that have variable length:
1220      * 1) Resource Source string
1221      * 2) Vendor Data buffer
1222      */
1223     ResSourceLength = RsGetStringDataLength (InitializerOp);
1224     VendorLength = RsGetBufferDataLength (InitializerOp);
1225
1226     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) +
1227         ResSourceLength + VendorLength;
1228
1229     /* Allocate the local resource node and initialize */
1230
1231     Rnode = RsAllocateResourceNode (DescriptorSize +
1232         sizeof (AML_RESOURCE_LARGE_HEADER));
1233
1234     Descriptor = Rnode->Buffer;
1235     Descriptor->UartSerialBus.ResourceLength = DescriptorSize;
1236     Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1237     Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION;
1238     Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION;
1239     Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE;
1240     Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength;
1241
1242     if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_UART_SERIALBUS_V2)
1243     {
1244         Descriptor->I2cSerialBus.RevisionId = 2;
1245     }
1246
1247     /* Build pointers to optional areas */
1248
1249     VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS));
1250     ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1251
1252     /* Process all child initialization nodes */
1253
1254     for (i = 0; InitializerOp; i++)
1255     {
1256         switch (i)
1257         {
1258         case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */
1259
1260             Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer;
1261             RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1262                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate));
1263             break;
1264
1265         case 1: /* Bits Per Byte [Flags] (_LEN) */
1266
1267             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3);
1268             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH,
1269                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3);
1270             break;
1271
1272         case 2: /* Stop Bits [Flags] (_STB) */
1273
1274             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1);
1275             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS,
1276                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2);
1277             break;
1278
1279         case 3: /* Lines In Use [BYTE] (_LIN) */
1280
1281             Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer;
1282             RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE,
1283                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled));
1284             break;
1285
1286         case 4: /* Endianness [Flag] (_END) */
1287
1288             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0);
1289             RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS,
1290                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7);
1291             break;
1292
1293         case 5: /* Parity [BYTE] (_PAR) */
1294
1295             Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer;
1296             RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY,
1297                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity));
1298             break;
1299
1300         case 6: /* Flow Control [Flags] (_FLC) */
1301
1302             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1303             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL,
1304                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2);
1305             break;
1306
1307         case 7: /* Rx Buffer Size [WORD] (_RXL) */
1308
1309             Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1310             RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX,
1311                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize));
1312             break;
1313
1314         case 8: /* Tx Buffer Size [WORD] (_TXL) */
1315
1316             Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1317             RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX,
1318                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize));
1319             break;
1320
1321         case 9: /* ResSource [Optional Field - STRING] */
1322
1323             if (ResSourceLength)
1324             {
1325                 /* Copy string to the descriptor */
1326
1327                 strcpy (ResourceSource,
1328                     InitializerOp->Asl.Value.String);
1329             }
1330             break;
1331
1332         case 10: /* Resource Index */
1333
1334             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1335             {
1336                 Descriptor->UartSerialBus.ResSourceIndex =
1337                     (UINT8) InitializerOp->Asl.Value.Integer;
1338             }
1339             break;
1340
1341         case 11: /* Resource Usage (consumer/producer) */
1342
1343             RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1);
1344
1345             /*
1346              * Slave Mode [Flag] (_SLV)
1347              *
1348              * Note: There is no SlaveMode argument to the UartSerialBus macro, but
1349              * we add this name anyway to allow the flag to be set by ASL in the
1350              * rare case where there is a slave mode associated with the UART.
1351              */
1352             RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1353                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0);
1354             break;
1355
1356         case 12: /* Resource Tag (Descriptor Name) */
1357
1358             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1359             break;
1360
1361         case 13:
1362             /*
1363              * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1364              * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1365              * the ASL parser)
1366              */
1367             RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 2, 0);
1368             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1369                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 2);
1370             break;
1371
1372         case 14: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1373
1374             RsGetVendorData (InitializerOp, VendorData,
1375                 CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS));
1376             break;
1377
1378         default:    /* Ignore any extra nodes */
1379
1380             break;
1381         }
1382
1383         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1384     }
1385
1386     MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1387     return (Rnode);
1388 }
1389
1390
1391 /*******************************************************************************
1392  *
1393  * FUNCTION:    RsDoPinFunctionDescriptor
1394  *
1395  * PARAMETERS:  Info                - Parse Op and resource template offset
1396  *
1397  * RETURN:      Completed resource node
1398  *
1399  * DESCRIPTION: Construct a long "PinFunction" descriptor
1400  *
1401  ******************************************************************************/
1402
1403 ASL_RESOURCE_NODE *
1404 RsDoPinFunctionDescriptor (
1405     ASL_RESOURCE_INFO       *Info)
1406 {
1407     AML_RESOURCE            *Descriptor;
1408     ACPI_PARSE_OBJECT       *InitializerOp;
1409     ASL_RESOURCE_NODE       *Rnode;
1410     char                    *ResourceSource = NULL;
1411     UINT8                   *VendorData = NULL;
1412     UINT16                  *PinList = NULL;
1413     UINT16                  ResSourceLength;
1414     UINT16                  VendorLength;
1415     UINT16                  PinListLength;
1416     UINT16                  DescriptorSize;
1417     UINT32                  CurrentByteOffset;
1418     UINT32                  PinCount = 0;
1419     UINT32                  i;
1420
1421     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1422     CurrentByteOffset = Info->CurrentByteOffset;
1423
1424     /*
1425      * Calculate lengths for fields that have variable length:
1426      * 1) Resource Source string
1427      * 2) Vendor Data buffer
1428      * 3) PIN (interrupt) list
1429      */
1430     ResSourceLength = RsGetStringDataLength (InitializerOp);
1431     VendorLength = RsGetBufferDataLength (InitializerOp);
1432     PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1433
1434     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION) +
1435         ResSourceLength + VendorLength + PinListLength;
1436
1437     /* Allocate the local resource node and initialize */
1438
1439     Rnode = RsAllocateResourceNode (DescriptorSize +
1440         sizeof (AML_RESOURCE_LARGE_HEADER));
1441
1442     Descriptor = Rnode->Buffer;
1443     Descriptor->PinFunction.ResourceLength = DescriptorSize;
1444     Descriptor->PinFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_FUNCTION;
1445     Descriptor->PinFunction.RevisionId = AML_RESOURCE_PIN_FUNCTION_REVISION;
1446
1447     /* Build pointers to optional areas */
1448
1449     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_FUNCTION));
1450     ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1451     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1452
1453     /* Setup offsets within the descriptor */
1454
1455     Descriptor->PinFunction.PinTableOffset = (UINT16)
1456         ACPI_PTR_DIFF (PinList, Descriptor);
1457
1458     Descriptor->PinFunction.ResSourceOffset = (UINT16)
1459         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1460
1461     /* Process all child initialization nodes */
1462
1463     for (i = 0; InitializerOp; i++)
1464     {
1465         switch (i)
1466         {
1467         case 0: /* Share Type [Flags] (_SHR) */
1468
1469             RsSetFlagBits16 (&Descriptor->PinFunction.Flags, InitializerOp, 0, 0);
1470             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1471                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.Flags), 0);
1472             break;
1473
1474         case 1: /* Pin Config [BYTE] (_PPI) */
1475
1476             Descriptor->PinFunction.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
1477             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
1478                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.PinConfig));
1479             break;
1480
1481         case 2: /* Function Number [WORD] (_FUN) */
1482
1483             Descriptor->PinFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
1484             RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
1485                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.FunctionNumber));
1486             break;
1487
1488         case 3: /* ResSource [Optional Field - STRING] */
1489
1490             if (ResSourceLength)
1491             {
1492                 /* Copy string to the descriptor */
1493
1494                 strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1495             }
1496             break;
1497
1498         case 4: /* Resource Index */
1499
1500             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1501             {
1502                 Descriptor->PinFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1503             }
1504             break;
1505
1506         case 5: /* Resource Usage (consumer/producer) */
1507
1508             /* Assumed to be consumer */
1509
1510             break;
1511
1512         case 6: /* Resource Tag (Descriptor Name) */
1513
1514             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1515             break;
1516
1517         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1518             /*
1519              * Always set the VendorOffset even if there is no Vendor Data.
1520              * This field is required in order to calculate the length
1521              * of the ResourceSource at runtime.
1522              */
1523             Descriptor->PinFunction.VendorOffset = (UINT16)
1524                 ACPI_PTR_DIFF (VendorData, Descriptor);
1525
1526             if (RsGetVendorData (InitializerOp, VendorData,
1527                 (CurrentByteOffset + Descriptor->PinFunction.VendorOffset)))
1528             {
1529                 Descriptor->PinFunction.VendorLength = VendorLength;
1530             }
1531             break;
1532
1533         default:
1534             /*
1535              * PINs come through here, repeatedly. Each PIN must be a WORD.
1536              * NOTE: there is no "length" field for this, so from ACPI spec:
1537              *  The number of pins in the table can be calculated from:
1538              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1539              *  (implies resource source must immediately follow the pin list.)
1540              *  Name: _PIN
1541              */
1542             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1543             PinList++;
1544             PinCount++;
1545
1546             /* Case 8: First pin number in list */
1547
1548             if (i == 8)
1549             {
1550                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1551                 {
1552                     /* Must be at least one interrupt */
1553
1554                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1555                         InitializerOp, NULL);
1556                 }
1557
1558                 /* Check now for duplicates in list */
1559
1560                 RsCheckListForDuplicates (InitializerOp);
1561
1562                 /* Create a named field at the start of the list */
1563
1564                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1565                     CurrentByteOffset + Descriptor->PinFunction.PinTableOffset);
1566             }
1567             break;
1568         }
1569
1570         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1571     }
1572
1573     return (Rnode);
1574 }
1575
1576
1577 /*******************************************************************************
1578  *
1579  * FUNCTION:    RsDoPinConfigDescriptor
1580  *
1581  * PARAMETERS:  Info                - Parse Op and resource template offset
1582  *
1583  * RETURN:      Completed resource node
1584  *
1585  * DESCRIPTION: Construct a long "PinConfig" descriptor
1586  *
1587  ******************************************************************************/
1588
1589 ASL_RESOURCE_NODE *
1590 RsDoPinConfigDescriptor (
1591     ASL_RESOURCE_INFO       *Info)
1592 {
1593     AML_RESOURCE            *Descriptor;
1594     ACPI_PARSE_OBJECT       *InitializerOp;
1595     ASL_RESOURCE_NODE       *Rnode;
1596     char                    *ResourceSource = NULL;
1597     UINT8                   *VendorData = NULL;
1598     UINT16                  *PinList = NULL;
1599     UINT16                  ResSourceLength;
1600     UINT16                  VendorLength;
1601     UINT16                  PinListLength;
1602     UINT16                  DescriptorSize;
1603     UINT32                  CurrentByteOffset;
1604     UINT32                  PinCount = 0;
1605     UINT32                  i;
1606
1607     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1608     CurrentByteOffset = Info->CurrentByteOffset;
1609
1610     /*
1611      * Calculate lengths for fields that have variable length:
1612      * 1) Resource Source string
1613      * 2) Vendor Data buffer
1614      * 3) PIN (interrupt) list
1615      */
1616     ResSourceLength = RsGetStringDataLength (InitializerOp);
1617     VendorLength = RsGetBufferDataLength (InitializerOp);
1618     PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1619
1620     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG) +
1621         ResSourceLength + VendorLength + PinListLength;
1622
1623     /* Allocate the local resource node and initialize */
1624
1625     Rnode = RsAllocateResourceNode (DescriptorSize +
1626         sizeof (AML_RESOURCE_LARGE_HEADER));
1627
1628     Descriptor = Rnode->Buffer;
1629     Descriptor->PinConfig.ResourceLength = DescriptorSize;
1630     Descriptor->PinConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_CONFIG;
1631     Descriptor->PinConfig.RevisionId = AML_RESOURCE_PIN_CONFIG_REVISION;
1632
1633     /* Build pointers to optional areas */
1634
1635     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_CONFIG));
1636     ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1637     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1638
1639     /* Setup offsets within the descriptor */
1640
1641     Descriptor->PinConfig.PinTableOffset = (UINT16)
1642         ACPI_PTR_DIFF (PinList, Descriptor);
1643
1644     Descriptor->PinConfig.ResSourceOffset = (UINT16)
1645         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1646
1647     /* Process all child initialization nodes */
1648
1649     for (i = 0; InitializerOp; i++)
1650     {
1651         BOOLEAN isValid;
1652
1653         switch (i)
1654         {
1655         case 0: /* Share Type [Flags] (_SHR) */
1656
1657             RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 0, 0);
1658             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1659                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.Flags), 0);
1660             break;
1661
1662         case 1: /* Pin Config Type [BYTE] (_TYP) */
1663
1664             isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
1665             if (!isValid)
1666             {
1667                 isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
1668                           InitializerOp->Asl.Value.Integer <= 0xff;
1669             }
1670             if (!isValid)
1671             {
1672                     AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
1673             }
1674
1675             Descriptor->PinConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
1676             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
1677                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigType));
1678
1679             break;
1680
1681         case 2: /* Pin Config Value [DWORD] (_VAL) */
1682
1683             Descriptor->PinConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
1684             RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
1685                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigValue));
1686             break;
1687
1688         case 3: /* ResSource [Optional Field - STRING] */
1689
1690             if (ResSourceLength)
1691             {
1692                 /* Copy string to the descriptor */
1693
1694                 strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1695             }
1696             break;
1697
1698         case 4: /* Resource Index */
1699
1700             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1701             {
1702                 Descriptor->PinConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1703             }
1704             break;
1705
1706         case 5: /* Resource Usage (consumer/producer) */
1707
1708             RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 1, 1);
1709
1710             break;
1711
1712         case 6: /* Resource Tag (Descriptor Name) */
1713
1714             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1715             break;
1716
1717         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1718             /*
1719              * Always set the VendorOffset even if there is no Vendor Data.
1720              * This field is required in order to calculate the length
1721              * of the ResourceSource at runtime.
1722              */
1723             Descriptor->PinConfig.VendorOffset = (UINT16)
1724                 ACPI_PTR_DIFF (VendorData, Descriptor);
1725
1726             if (RsGetVendorData (InitializerOp, VendorData,
1727                 (CurrentByteOffset + Descriptor->PinConfig.VendorOffset)))
1728             {
1729                 Descriptor->PinConfig.VendorLength = VendorLength;
1730             }
1731             break;
1732
1733         default:
1734             /*
1735              * PINs come through here, repeatedly. Each PIN must be a WORD.
1736              * NOTE: there is no "length" field for this, so from ACPI spec:
1737              *  The number of pins in the table can be calculated from:
1738              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1739              *  (implies resource source must immediately follow the pin list.)
1740              *  Name: _PIN
1741              */
1742             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1743             PinList++;
1744             PinCount++;
1745
1746             /* Case 8: First pin number in list */
1747
1748             if (i == 8)
1749             {
1750                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1751                 {
1752                     /* Must be at least one interrupt */
1753
1754                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1755                         InitializerOp, NULL);
1756                 }
1757
1758                 /* Check now for duplicates in list */
1759
1760                 RsCheckListForDuplicates (InitializerOp);
1761
1762                 /* Create a named field at the start of the list */
1763
1764                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1765                     CurrentByteOffset + Descriptor->PinConfig.PinTableOffset);
1766             }
1767             break;
1768         }
1769
1770         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1771     }
1772
1773     return (Rnode);
1774 }
1775
1776
1777 /*******************************************************************************
1778  *
1779  * FUNCTION:    RsDoPinGroupDescriptor
1780  *
1781  * PARAMETERS:  Info                - Parse Op and resource template offset
1782  *
1783  * RETURN:      Completed resource node
1784  *
1785  * DESCRIPTION: Construct a long "PinGroup" descriptor
1786  *
1787  ******************************************************************************/
1788
1789 ASL_RESOURCE_NODE *
1790 RsDoPinGroupDescriptor (
1791     ASL_RESOURCE_INFO       *Info)
1792 {
1793     AML_RESOURCE            *Descriptor;
1794     ACPI_PARSE_OBJECT       *InitializerOp;
1795     ASL_RESOURCE_NODE       *Rnode;
1796     UINT8                   *VendorData = NULL;
1797     UINT16                  *PinList = NULL;
1798     char                    *Label = NULL;
1799     UINT16                  LabelLength;
1800     UINT16                  VendorLength;
1801     UINT16                  PinListLength;
1802     UINT16                  DescriptorSize;
1803     UINT32                  CurrentByteOffset;
1804     UINT32                  PinCount = 0;
1805     UINT32                  i;
1806
1807     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1808     CurrentByteOffset = Info->CurrentByteOffset;
1809
1810     /*
1811      * Calculate lengths for fields that have variable length:
1812      * 1) Label
1813      * 2) Vendor Data buffer
1814      * 3) PIN (interrupt) list
1815      */
1816     LabelLength = RsGetStringDataLength (InitializerOp);
1817     VendorLength = RsGetBufferDataLength (InitializerOp);
1818     PinListLength = RsGetInterruptDataLength (InitializerOp, 4);
1819
1820     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP) +
1821         LabelLength + VendorLength + PinListLength;
1822
1823     /* Allocate the local resource node and initialize */
1824
1825     Rnode = RsAllocateResourceNode (DescriptorSize +
1826         sizeof (AML_RESOURCE_LARGE_HEADER));
1827
1828     Descriptor = Rnode->Buffer;
1829     Descriptor->PinGroup.ResourceLength = DescriptorSize;
1830     Descriptor->PinGroup.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP;
1831     Descriptor->PinGroup.RevisionId = AML_RESOURCE_PIN_GROUP_REVISION;
1832
1833     /* Build pointers to optional areas */
1834
1835     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP));
1836     Label = ACPI_ADD_PTR (char, PinList, PinListLength);
1837     VendorData = ACPI_ADD_PTR (UINT8, Label, LabelLength);
1838
1839     /* Setup offsets within the descriptor */
1840
1841     Descriptor->PinGroup.PinTableOffset = (UINT16) ACPI_PTR_DIFF (PinList, Descriptor);
1842     Descriptor->PinGroup.LabelOffset = (UINT16) ACPI_PTR_DIFF (Label, Descriptor);
1843
1844     /* Process all child initialization nodes */
1845
1846     for (i = 0; InitializerOp; i++)
1847     {
1848         switch (i)
1849         {
1850         case 0: /* Resource Label */
1851
1852             if (LabelLength < 2)
1853             {
1854                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
1855             }
1856             strcpy (Label, InitializerOp->Asl.Value.String);
1857
1858             break;
1859
1860         case 1: /* Resource Usage (consumer/producer) */
1861
1862             RsSetFlagBits16 (&Descriptor->PinGroup.Flags, InitializerOp, 0, 0);
1863
1864             break;
1865
1866         case 2: /* Resource Tag (Descriptor Name) */
1867
1868             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1869             break;
1870
1871         case 3: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1872             /*
1873              * Always set the VendorOffset even if there is no Vendor Data.
1874              * This field is required in order to calculate the length
1875              * of the ResourceSource at runtime.
1876              */
1877             Descriptor->PinGroup.VendorOffset = (UINT16)
1878                 ACPI_PTR_DIFF (VendorData, Descriptor);
1879
1880             if (RsGetVendorData (InitializerOp, VendorData,
1881                 (CurrentByteOffset + Descriptor->PinGroup.VendorOffset)))
1882             {
1883                 Descriptor->PinGroup.VendorLength = VendorLength;
1884             }
1885             break;
1886
1887         default:
1888             /*
1889              * PINs come through here, repeatedly. Each PIN must be a WORD.
1890              * NOTE: there is no "length" field for this, so from ACPI spec:
1891              *  The number of pins in the table can be calculated from:
1892              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1893              *  (implies resource source must immediately follow the pin list.)
1894              *  Name: _PIN
1895              */
1896             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1897             PinList++;
1898             PinCount++;
1899
1900             /* Case 3: First pin number in list */
1901
1902             if (i == 4)
1903             {
1904                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1905                 {
1906                     /* Must be at least one interrupt */
1907
1908                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1909                         InitializerOp, NULL);
1910                 }
1911
1912                 /* Check now for duplicates in list */
1913
1914                 RsCheckListForDuplicates (InitializerOp);
1915
1916                 /* Create a named field at the start of the list */
1917
1918                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1919                     CurrentByteOffset + Descriptor->PinGroup.PinTableOffset);
1920             }
1921             break;
1922         }
1923
1924         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1925     }
1926
1927     return (Rnode);
1928 }
1929
1930
1931 /*******************************************************************************
1932  *
1933  * FUNCTION:    RsDoPinGroupFunctionDescriptor
1934  *
1935  * PARAMETERS:  Info                - Parse Op and resource template offset
1936  *
1937  * RETURN:      Completed resource node
1938  *
1939  * DESCRIPTION: Construct a long "PinGroupFunction" descriptor
1940  *
1941  ******************************************************************************/
1942
1943 ASL_RESOURCE_NODE *
1944 RsDoPinGroupFunctionDescriptor (
1945     ASL_RESOURCE_INFO       *Info)
1946 {
1947     AML_RESOURCE            *Descriptor;
1948     ACPI_PARSE_OBJECT       *InitializerOp;
1949     ASL_RESOURCE_NODE       *Rnode;
1950     char                    *ResourceSource = NULL;
1951     char                    *ResourceSourceLabel = NULL;
1952     UINT8                   *VendorData = NULL;
1953     UINT16                  ResSourceLength;
1954     UINT16                  ResSourceLabelLength;
1955     UINT16                  VendorLength;
1956     UINT16                  DescriptorSize;
1957     UINT32                  CurrentByteOffset;
1958     UINT32                  i;
1959
1960     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1961     CurrentByteOffset = Info->CurrentByteOffset;
1962
1963     /*
1964      * Calculate lengths for fields that have variable length:
1965      * 1) Resource Source string
1966      * 2) Resource Source Label string
1967      * 3) Vendor Data buffer
1968      */
1969     ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 2);
1970     ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 4);
1971     VendorLength = RsGetBufferDataLength (InitializerOp);
1972
1973     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION) +
1974         ResSourceLength + ResSourceLabelLength + VendorLength;
1975
1976     /* Allocate the local resource node and initialize */
1977
1978     Rnode = RsAllocateResourceNode (DescriptorSize +
1979         sizeof (AML_RESOURCE_LARGE_HEADER));
1980
1981     Descriptor = Rnode->Buffer;
1982     Descriptor->PinGroupFunction.ResourceLength = DescriptorSize;
1983     Descriptor->PinGroupFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION;
1984     Descriptor->PinGroupFunction.RevisionId = AML_RESOURCE_PIN_GROUP_FUNCTION_REVISION;
1985
1986     /* Build pointers to optional areas */
1987
1988     ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_FUNCTION));
1989     ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
1990     VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
1991
1992     /* Setup offsets within the descriptor */
1993
1994     Descriptor->PinGroupFunction.ResSourceOffset = (UINT16)
1995         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1996     Descriptor->PinGroupFunction.ResSourceLabelOffset = (UINT16)
1997         ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
1998
1999     /* Process all child initialization nodes */
2000
2001     for (i = 0; InitializerOp; i++)
2002     {
2003         switch (i)
2004         {
2005         case 0: /* Share Type [Flags] (_SHR) */
2006
2007             RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 0, 0);
2008             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2009                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.Flags), 0);
2010             break;
2011
2012         case 1: /* Function Number [WORD] */
2013
2014             Descriptor->PinGroupFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
2015             RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
2016                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.FunctionNumber));
2017             break;
2018
2019         case 2: /* ResourceSource [STRING] */
2020
2021             strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2022             break;
2023
2024         case 3: /* Resource Index */
2025
2026             Descriptor->PinGroupFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2027             break;
2028
2029         case 4: /* ResourceSourceLabel [STRING] */
2030
2031             if (ResSourceLabelLength < 2)
2032             {
2033                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2034             }
2035
2036             strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2037             break;
2038
2039         case 5: /* Resource Usage (consumer/producer) */
2040
2041             RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 1, 1);
2042
2043             break;
2044
2045         case 6: /* Resource Tag (Descriptor Name) */
2046
2047             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2048             break;
2049
2050         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2051             /*
2052              * Always set the VendorOffset even if there is no Vendor Data.
2053              * This field is required in order to calculate the length
2054              * of the ResourceSource at runtime.
2055              */
2056             Descriptor->PinGroupFunction.VendorOffset = (UINT16)
2057                 ACPI_PTR_DIFF (VendorData, Descriptor);
2058
2059             if (RsGetVendorData (InitializerOp, VendorData,
2060                 (CurrentByteOffset + Descriptor->PinGroupFunction.VendorOffset)))
2061             {
2062                 Descriptor->PinGroupFunction.VendorLength = VendorLength;
2063             }
2064             break;
2065
2066         default:
2067             break;
2068         }
2069
2070         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2071     }
2072
2073     return (Rnode);
2074 }
2075
2076
2077 /*******************************************************************************
2078  *
2079  * FUNCTION:    RsDoPinGroupConfigDescriptor
2080  *
2081  * PARAMETERS:  Info                - Parse Op and resource template offset
2082  *
2083  * RETURN:      Completed resource node
2084  *
2085  * DESCRIPTION: Construct a long "PinGroupConfig" descriptor
2086  *
2087  ******************************************************************************/
2088
2089 ASL_RESOURCE_NODE *
2090 RsDoPinGroupConfigDescriptor (
2091     ASL_RESOURCE_INFO       *Info)
2092 {
2093     AML_RESOURCE            *Descriptor;
2094     ACPI_PARSE_OBJECT       *InitializerOp;
2095     ASL_RESOURCE_NODE       *Rnode;
2096     char                    *ResourceSource = NULL;
2097     char                    *ResourceSourceLabel = NULL;
2098     UINT8                   *VendorData = NULL;
2099     UINT16                  ResSourceLength;
2100     UINT16                  ResSourceLabelLength;
2101     UINT16                  VendorLength;
2102     UINT16                  DescriptorSize;
2103     UINT32                  CurrentByteOffset;
2104     UINT32                  i;
2105
2106     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
2107     CurrentByteOffset = Info->CurrentByteOffset;
2108
2109     /*
2110      * Calculate lengths for fields that have variable length:
2111      * 1) Resource Source string
2112      * 2) Resource Source Label string
2113      * 3) Vendor Data buffer
2114      */
2115     ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 3);
2116     ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 5);
2117     VendorLength = RsGetBufferDataLength (InitializerOp);
2118
2119     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG) +
2120         ResSourceLength + ResSourceLabelLength + VendorLength;
2121
2122     /* Allocate the local resource node and initialize */
2123
2124     Rnode = RsAllocateResourceNode (DescriptorSize +
2125         sizeof (AML_RESOURCE_LARGE_HEADER));
2126
2127     Descriptor = Rnode->Buffer;
2128     Descriptor->PinGroupConfig.ResourceLength = DescriptorSize;
2129     Descriptor->PinGroupConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG;
2130     Descriptor->PinGroupConfig.RevisionId = AML_RESOURCE_PIN_GROUP_CONFIG_REVISION;
2131
2132     /* Build pointers to optional areas */
2133
2134     ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_CONFIG));
2135     ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
2136     VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
2137
2138     /* Setup offsets within the descriptor */
2139
2140     Descriptor->PinGroupConfig.ResSourceOffset = (UINT16)
2141         ACPI_PTR_DIFF (ResourceSource, Descriptor);
2142     Descriptor->PinGroupConfig.ResSourceLabelOffset = (UINT16)
2143         ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
2144
2145     /* Process all child initialization nodes */
2146
2147     for (i = 0; InitializerOp; i++)
2148     {
2149         BOOLEAN isValid;
2150
2151         switch (i)
2152         {
2153         case 0: /* Share Type [Flags] (_SHR) */
2154
2155             RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 0, 0);
2156             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2157                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.Flags), 0);
2158             break;
2159
2160         case 1: /* Pin Config Type [BYTE] (_TYP) */
2161
2162             isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
2163             if (!isValid)
2164             {
2165                 isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
2166                           InitializerOp->Asl.Value.Integer <= 0xff;
2167             }
2168             if (!isValid)
2169             {
2170                     AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
2171             }
2172
2173             Descriptor->PinGroupConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
2174             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
2175                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigType));
2176
2177             break;
2178
2179         case 2: /* Pin Config Value [DWORD] (_VAL) */
2180
2181             Descriptor->PinGroupConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
2182             RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
2183                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigValue));
2184             break;
2185
2186         case 3: /* ResourceSource [STRING] */
2187
2188             /* Copy string to the descriptor */
2189
2190             strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2191             break;
2192
2193         case 4: /* Resource Index */
2194
2195             Descriptor->PinGroupConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2196             break;
2197
2198         case 5: /* ResourceSourceLabel [STRING] */
2199
2200             if (ResSourceLabelLength < 2)
2201             {
2202                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2203             }
2204
2205             strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2206             break;
2207
2208         case 6: /* Resource Usage (consumer/producer) */
2209
2210             RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 1, 1);
2211
2212             break;
2213
2214         case 7: /* Resource Tag (Descriptor Name) */
2215
2216             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2217             break;
2218
2219         case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2220             /*
2221              * Always set the VendorOffset even if there is no Vendor Data.
2222              * This field is required in order to calculate the length
2223              * of the ResourceSource at runtime.
2224              */
2225             Descriptor->PinGroupConfig.VendorOffset = (UINT16)
2226                 ACPI_PTR_DIFF (VendorData, Descriptor);
2227
2228             if (RsGetVendorData (InitializerOp, VendorData,
2229                 (CurrentByteOffset + Descriptor->PinGroupConfig.VendorOffset)))
2230             {
2231                 Descriptor->PinGroupConfig.VendorLength = VendorLength;
2232             }
2233             break;
2234
2235         default:
2236             break;
2237         }
2238
2239         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2240     }
2241
2242     return (Rnode);
2243 }