xref: /illumos-gate/usr/src/cmd/acpi/iasl/aslrestype2s.c (revision 35786f6866ae52207d0f1a25fe7ca5f652f32ce0)
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
RsGetBufferDataLength(ACPI_PARSE_OBJECT * InitializerOp)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
RsGetInterruptDataLength(ACPI_PARSE_OBJECT * InitializerOp,UINT32 StartIndex)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
RsGetVendorData(ACPI_PARSE_OBJECT * InitializerOp,UINT8 * VendorData,ACPI_SIZE DescriptorOffset)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
RsGetStringDataLengthAt(ACPI_PARSE_OBJECT * InitializerOp,UINT32 StartIndex)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 *
RsDoGpioIntDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoGpioIoDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoI2cSerialBusDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoSpiSerialBusDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoUartSerialBusDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoPinFunctionDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoPinConfigDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoPinGroupDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoPinGroupFunctionDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoPinGroupConfigDescriptor(ASL_RESOURCE_INFO * Info)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 }
2244