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