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 - 2020, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
153#include "aslcompiler.y.h"
154#include <contrib/dev/acpica/include/amlcode.h>
155
156#define _COMPONENT          ACPI_COMPILER
157        ACPI_MODULE_NAME    ("aslrestype2s")
158
159
160static UINT16
161RsGetBufferDataLength (
162    ACPI_PARSE_OBJECT       *InitializerOp);
163
164static UINT16
165RsGetInterruptDataLength (
166    ACPI_PARSE_OBJECT       *InitializerOp,
167    UINT32                  StartIndex);
168
169static BOOLEAN
170RsGetVendorData (
171    ACPI_PARSE_OBJECT       *InitializerOp,
172    UINT8                   *VendorData,
173    ACPI_SIZE               DescriptorOffset);
174
175static UINT16
176RsGetStringDataLengthAt (
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
209static UINT16
210RsGetBufferDataLength (
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
261static UINT16
262RsGetInterruptDataLength (
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
304static BOOLEAN
305RsGetVendorData (
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
402static UINT16
403RsGetStringDataLengthAt (
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
436ASL_RESOURCE_NODE *
437RsDoGpioIntDescriptor (
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
645ASL_RESOURCE_NODE *
646RsDoGpioIoDescriptor (
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
678    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
679        ResSourceLength + VendorLength + InterruptLength;
680
681    /* Allocate the local resource node and initialize */
682
683    Rnode = RsAllocateResourceNode (DescriptorSize +
684        sizeof (AML_RESOURCE_LARGE_HEADER));
685
686    Descriptor = Rnode->Buffer;
687    Descriptor->Gpio.ResourceLength = DescriptorSize;
688    Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
689    Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
690    Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO;
691
692    /* Build pointers to optional areas */
693
694    InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO));
695    PinList = InterruptList;
696    ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
697    VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
698
699    /* Setup offsets within the descriptor */
700
701    Descriptor->Gpio.PinTableOffset = (UINT16)
702        ACPI_PTR_DIFF (InterruptList, Descriptor);
703
704    Descriptor->Gpio.ResSourceOffset = (UINT16)
705        ACPI_PTR_DIFF (ResourceSource, Descriptor);
706
707    /* Process all child initialization nodes */
708
709    for (i = 0; InitializerOp; i++)
710    {
711        switch (i)
712        {
713        case 0: /* Share Type [Flags] (_SHR) */
714
715            RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
716            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
717                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3);
718            break;
719
720        case 1: /* Pin Config [BYTE] (_PPI) */
721
722            Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
723            RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
724                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
725            break;
726
727        case 2: /* Debounce Timeout [WORD] (_DBT) */
728
729            Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
730            RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
731                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
732            break;
733
734        case 3: /* Drive Strength [WORD] (_DRS) */
735
736            Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer;
737            RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH,
738                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength));
739            break;
740
741        case 4: /* I/O Restriction [Flag] (_IOR) */
742
743            RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
744            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION,
745                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2);
746            break;
747
748        case 5: /* ResSource [Optional Field - STRING] */
749
750            if (ResSourceLength)
751            {
752                /* Copy string to the descriptor */
753
754                strcpy (ResourceSource,
755                    InitializerOp->Asl.Value.String);
756            }
757            break;
758
759        case 6: /* Resource Index */
760
761            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
762            {
763                Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
764            }
765            break;
766
767        case 7: /* Resource Usage (consumer/producer) */
768
769            RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
770            break;
771
772        case 8: /* Resource Tag (Descriptor Name) */
773
774            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
775            break;
776
777        case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
778            /*
779             * Always set the VendorOffset even if there is no Vendor Data.
780             * This field is required in order to calculate the length
781             * of the ResourceSource at runtime.
782             */
783            Descriptor->Gpio.VendorOffset = (UINT16)
784                ACPI_PTR_DIFF (VendorData, Descriptor);
785
786            if (RsGetVendorData (InitializerOp, VendorData,
787                (CurrentByteOffset + Descriptor->Gpio.VendorOffset)))
788            {
789                Descriptor->Gpio.VendorLength = VendorLength;
790            }
791            break;
792
793        default:
794            /*
795             * PINs come through here, repeatedly. Each PIN must be a WORD.
796             * NOTE: there is no "length" field for this, so from ACPI spec:
797             *  The number of pins in the table can be calculated from:
798             *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
799             *  (implies resource source must immediately follow the pin list.)
800             *  Name: _PIN
801             */
802            *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
803            InterruptList++;
804            PinCount++;
805
806            /* Case 10: First interrupt number in list */
807
808            if (i == 10)
809            {
810                if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
811                {
812                    /* Must be at least one interrupt */
813
814                    AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
815                        InitializerOp, NULL);
816                }
817
818                /* Check now for duplicates in list */
819
820                RsCheckListForDuplicates (InitializerOp);
821
822                /* Create a named field at the start of the list */
823
824                RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
825                    CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
826            }
827            break;
828        }
829
830        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
831    }
832
833    MpSaveGpioInfo (Info->MappingOp, Descriptor,
834        PinCount, PinList, ResourceSource);
835    return (Rnode);
836}
837
838
839/*******************************************************************************
840 *
841 * FUNCTION:    RsDoI2cSerialBusDescriptor
842 *
843 * PARAMETERS:  Info                - Parse Op and resource template offset
844 *
845 * RETURN:      Completed resource node
846 *
847 * DESCRIPTION: Construct a long "I2cSerialBus" descriptor
848 *
849 ******************************************************************************/
850
851ASL_RESOURCE_NODE *
852RsDoI2cSerialBusDescriptor (
853    ASL_RESOURCE_INFO       *Info)
854{
855    AML_RESOURCE            *Descriptor;
856    ACPI_PARSE_OBJECT       *InitializerOp;
857    ASL_RESOURCE_NODE       *Rnode;
858    char                    *ResourceSource = NULL;
859    UINT8                   *VendorData = NULL;
860    UINT16                  ResSourceLength;
861    UINT16                  VendorLength;
862    UINT16                  DescriptorSize;
863    UINT32                  CurrentByteOffset;
864    UINT32                  i;
865
866
867    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
868    CurrentByteOffset = Info->CurrentByteOffset;
869
870    /*
871     * Calculate lengths for fields that have variable length:
872     * 1) Resource Source string
873     * 2) Vendor Data buffer
874     */
875    ResSourceLength = RsGetStringDataLength (InitializerOp);
876    VendorLength = RsGetBufferDataLength (InitializerOp);
877
878    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) +
879        ResSourceLength + VendorLength;
880
881    /* Allocate the local resource node and initialize */
882
883    Rnode = RsAllocateResourceNode (DescriptorSize +
884        sizeof (AML_RESOURCE_LARGE_HEADER));
885
886    Descriptor = Rnode->Buffer;
887    Descriptor->I2cSerialBus.ResourceLength = DescriptorSize;
888    Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
889    Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION;
890    Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION;
891    Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE;
892    Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength;
893
894    if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_I2C_SERIALBUS_V2)
895    {
896        Descriptor->I2cSerialBus.RevisionId = 2;
897    }
898
899    /* Build pointers to optional areas */
900
901    VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS));
902    ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
903
904    /* Process all child initialization nodes */
905
906    for (i = 0; InitializerOp; i++)
907    {
908        switch (i)
909        {
910        case 0: /* Slave Address [WORD] (_ADR) */
911
912            Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer;
913            RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
914                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress));
915            break;
916
917        case 1: /* Slave Mode [Flag] (_SLV) */
918
919            RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0);
920            RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
921                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0);
922            break;
923
924        case 2: /* Connection Speed [DWORD] (_SPE) */
925
926            Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
927            RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
928                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed));
929            break;
930
931        case 3: /* Addressing Mode [Flag] (_MOD) */
932
933            RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
934            RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
935                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0);
936            break;
937
938        case 4: /* ResSource [Optional Field - STRING] */
939
940            if (ResSourceLength)
941            {
942                /* Copy string to the descriptor */
943
944                strcpy (ResourceSource,
945                    InitializerOp->Asl.Value.String);
946            }
947            break;
948
949        case 5: /* Resource Index */
950
951            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
952            {
953                Descriptor->I2cSerialBus.ResSourceIndex =
954                    (UINT8) InitializerOp->Asl.Value.Integer;
955            }
956            break;
957
958        case 6: /* Resource Usage (consumer/producer) */
959
960            RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1);
961            break;
962
963        case 7: /* Resource Tag (Descriptor Name) */
964
965            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
966            break;
967
968        case 8:
969            /*
970             * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
971             * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
972             * the ASL parser)
973             */
974            RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 2, 0);
975            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
976                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 2);
977            break;
978
979        case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
980
981            RsGetVendorData (InitializerOp, VendorData,
982                CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS));
983            break;
984
985        default:    /* Ignore any extra nodes */
986
987            break;
988        }
989
990        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
991    }
992
993    MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
994    return (Rnode);
995}
996
997
998/*******************************************************************************
999 *
1000 * FUNCTION:    RsDoSpiSerialBusDescriptor
1001 *
1002 * PARAMETERS:  Info                - Parse Op and resource template offset
1003 *
1004 * RETURN:      Completed resource node
1005 *
1006 * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor
1007 *
1008 ******************************************************************************/
1009
1010ASL_RESOURCE_NODE *
1011RsDoSpiSerialBusDescriptor (
1012    ASL_RESOURCE_INFO       *Info)
1013{
1014    AML_RESOURCE            *Descriptor;
1015    ACPI_PARSE_OBJECT       *InitializerOp;
1016    ASL_RESOURCE_NODE       *Rnode;
1017    char                    *ResourceSource = NULL;
1018    UINT8                   *VendorData = NULL;
1019    UINT16                  ResSourceLength;
1020    UINT16                  VendorLength;
1021    UINT16                  DescriptorSize;
1022    UINT32                  CurrentByteOffset;
1023    UINT32                  i;
1024
1025
1026    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1027    CurrentByteOffset = Info->CurrentByteOffset;
1028
1029    /*
1030     * Calculate lengths for fields that have variable length:
1031     * 1) Resource Source string
1032     * 2) Vendor Data buffer
1033     */
1034    ResSourceLength = RsGetStringDataLength (InitializerOp);
1035    VendorLength = RsGetBufferDataLength (InitializerOp);
1036
1037    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) +
1038        ResSourceLength + VendorLength;
1039
1040    /* Allocate the local resource node and initialize */
1041
1042    Rnode = RsAllocateResourceNode (DescriptorSize +
1043        sizeof (AML_RESOURCE_LARGE_HEADER));
1044
1045    Descriptor = Rnode->Buffer;
1046    Descriptor->SpiSerialBus.ResourceLength = DescriptorSize;
1047    Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1048    Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION;
1049    Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION;
1050    Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE;
1051    Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength;
1052
1053    if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_SPI_SERIALBUS_V2)
1054    {
1055        Descriptor->I2cSerialBus.RevisionId = 2;
1056    }
1057
1058    /* Build pointers to optional areas */
1059
1060    VendorData = ACPI_ADD_PTR (UINT8, Descriptor,
1061        sizeof (AML_RESOURCE_SPI_SERIALBUS));
1062    ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1063
1064    /* Process all child initialization nodes */
1065
1066    for (i = 0; InitializerOp; i++)
1067    {
1068        switch (i)
1069        {
1070        case 0: /* Device Selection [WORD] (_ADR) */
1071
1072            Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer;
1073            RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
1074                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection));
1075            break;
1076
1077        case 1: /* Device Polarity [Flag] (_DPL) */
1078
1079            RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0);
1080            RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY,
1081                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1);
1082            break;
1083
1084        case 2: /* Wire Mode [Flag] (_MOD) */
1085
1086            RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1087            RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
1088                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0);
1089            break;
1090
1091        case 3: /* Device Bit Length [BYTE] (_LEN) */
1092
1093            Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer;
1094            RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
1095                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength));
1096            break;
1097
1098        case 4: /* Slave Mode [Flag] (_SLV) */
1099
1100            RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0);
1101            RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1102                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0);
1103            break;
1104
1105        case 5: /* Connection Speed [DWORD] (_SPE) */
1106
1107            Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
1108            RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1109                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed));
1110            break;
1111
1112        case 6: /* Clock Polarity [BYTE] (_POL) */
1113
1114            Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer;
1115            RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY,
1116                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity));
1117            break;
1118
1119        case 7: /* Clock Phase [BYTE] (_PHA) */
1120
1121            Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer;
1122            RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE,
1123                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase));
1124            break;
1125
1126        case 8: /* ResSource [Optional Field - STRING] */
1127
1128            if (ResSourceLength)
1129            {
1130                /* Copy string to the descriptor */
1131
1132                strcpy (ResourceSource,
1133                    InitializerOp->Asl.Value.String);
1134            }
1135            break;
1136
1137        case 9: /* Resource Index */
1138
1139            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1140            {
1141                Descriptor->SpiSerialBus.ResSourceIndex =
1142                    (UINT8) InitializerOp->Asl.Value.Integer;
1143            }
1144            break;
1145
1146        case 10: /* Resource Usage (consumer/producer) */
1147
1148            RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1);
1149            break;
1150
1151        case 11: /* Resource Tag (Descriptor Name) */
1152
1153            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1154            break;
1155
1156        case 12:
1157            /*
1158             * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1159             * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1160             * the ASL parser)
1161             */
1162            RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 2, 0);
1163            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1164                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 2);
1165            break;
1166
1167        case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1168
1169            RsGetVendorData (InitializerOp, VendorData,
1170                CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS));
1171            break;
1172
1173        default:    /* Ignore any extra nodes */
1174
1175            break;
1176        }
1177
1178        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1179    }
1180
1181    MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1182    return (Rnode);
1183}
1184
1185
1186/*******************************************************************************
1187 *
1188 * FUNCTION:    RsDoUartSerialBusDescriptor
1189 *
1190 * PARAMETERS:  Info                - Parse Op and resource template offset
1191 *
1192 * RETURN:      Completed resource node
1193 *
1194 * DESCRIPTION: Construct a long "UART Serial Bus" descriptor
1195 *
1196 ******************************************************************************/
1197
1198ASL_RESOURCE_NODE *
1199RsDoUartSerialBusDescriptor (
1200    ASL_RESOURCE_INFO       *Info)
1201{
1202    AML_RESOURCE            *Descriptor;
1203    ACPI_PARSE_OBJECT       *InitializerOp;
1204    ASL_RESOURCE_NODE       *Rnode;
1205    char                    *ResourceSource = NULL;
1206    UINT8                   *VendorData = NULL;
1207    UINT16                  ResSourceLength;
1208    UINT16                  VendorLength;
1209    UINT16                  DescriptorSize;
1210    UINT32                  CurrentByteOffset;
1211    UINT32                  i;
1212
1213
1214    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1215    CurrentByteOffset = Info->CurrentByteOffset;
1216
1217    /*
1218     * Calculate lengths for fields that have variable length:
1219     * 1) Resource Source string
1220     * 2) Vendor Data buffer
1221     */
1222    ResSourceLength = RsGetStringDataLength (InitializerOp);
1223    VendorLength = RsGetBufferDataLength (InitializerOp);
1224
1225    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) +
1226        ResSourceLength + VendorLength;
1227
1228    /* Allocate the local resource node and initialize */
1229
1230    Rnode = RsAllocateResourceNode (DescriptorSize +
1231        sizeof (AML_RESOURCE_LARGE_HEADER));
1232
1233    Descriptor = Rnode->Buffer;
1234    Descriptor->UartSerialBus.ResourceLength = DescriptorSize;
1235    Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1236    Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION;
1237    Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION;
1238    Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE;
1239    Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength;
1240
1241    if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_UART_SERIALBUS_V2)
1242    {
1243        Descriptor->I2cSerialBus.RevisionId = 2;
1244    }
1245
1246    /* Build pointers to optional areas */
1247
1248    VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS));
1249    ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1250
1251    /* Process all child initialization nodes */
1252
1253    for (i = 0; InitializerOp; i++)
1254    {
1255        switch (i)
1256        {
1257        case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */
1258
1259            Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer;
1260            RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1261                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate));
1262            break;
1263
1264        case 1: /* Bits Per Byte [Flags] (_LEN) */
1265
1266            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3);
1267            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH,
1268                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3);
1269            break;
1270
1271        case 2: /* Stop Bits [Flags] (_STB) */
1272
1273            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1);
1274            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS,
1275                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2);
1276            break;
1277
1278        case 3: /* Lines In Use [BYTE] (_LIN) */
1279
1280            Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer;
1281            RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE,
1282                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled));
1283            break;
1284
1285        case 4: /* Endianness [Flag] (_END) */
1286
1287            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0);
1288            RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS,
1289                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7);
1290            break;
1291
1292        case 5: /* Parity [BYTE] (_PAR) */
1293
1294            Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer;
1295            RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY,
1296                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity));
1297            break;
1298
1299        case 6: /* Flow Control [Flags] (_FLC) */
1300
1301            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1302            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL,
1303                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2);
1304            break;
1305
1306        case 7: /* Rx Buffer Size [WORD] (_RXL) */
1307
1308            Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1309            RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX,
1310                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize));
1311            break;
1312
1313        case 8: /* Tx Buffer Size [WORD] (_TXL) */
1314
1315            Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1316            RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX,
1317                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize));
1318            break;
1319
1320        case 9: /* ResSource [Optional Field - STRING] */
1321
1322            if (ResSourceLength)
1323            {
1324                /* Copy string to the descriptor */
1325
1326                strcpy (ResourceSource,
1327                    InitializerOp->Asl.Value.String);
1328            }
1329            break;
1330
1331        case 10: /* Resource Index */
1332
1333            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1334            {
1335                Descriptor->UartSerialBus.ResSourceIndex =
1336                    (UINT8) InitializerOp->Asl.Value.Integer;
1337            }
1338            break;
1339
1340        case 11: /* Resource Usage (consumer/producer) */
1341
1342            RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1);
1343
1344            /*
1345             * Slave Mode [Flag] (_SLV)
1346             *
1347             * Note: There is no SlaveMode argument to the UartSerialBus macro, but
1348             * we add this name anyway to allow the flag to be set by ASL in the
1349             * rare case where there is a slave mode associated with the UART.
1350             */
1351            RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1352                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0);
1353            break;
1354
1355        case 12: /* Resource Tag (Descriptor Name) */
1356
1357            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1358            break;
1359
1360        case 13:
1361            /*
1362             * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1363             * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1364             * the ASL parser)
1365             */
1366            RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 2, 0);
1367            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1368                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 2);
1369            break;
1370
1371        case 14: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1372
1373            RsGetVendorData (InitializerOp, VendorData,
1374                CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS));
1375            break;
1376
1377        default:    /* Ignore any extra nodes */
1378
1379            break;
1380        }
1381
1382        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1383    }
1384
1385    MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1386    return (Rnode);
1387}
1388
1389
1390/*******************************************************************************
1391 *
1392 * FUNCTION:    RsDoPinFunctionDescriptor
1393 *
1394 * PARAMETERS:  Info                - Parse Op and resource template offset
1395 *
1396 * RETURN:      Completed resource node
1397 *
1398 * DESCRIPTION: Construct a long "PinFunction" descriptor
1399 *
1400 ******************************************************************************/
1401
1402ASL_RESOURCE_NODE *
1403RsDoPinFunctionDescriptor (
1404    ASL_RESOURCE_INFO       *Info)
1405{
1406    AML_RESOURCE            *Descriptor;
1407    ACPI_PARSE_OBJECT       *InitializerOp;
1408    ASL_RESOURCE_NODE       *Rnode;
1409    char                    *ResourceSource = NULL;
1410    UINT8                   *VendorData = NULL;
1411    UINT16                  *PinList = NULL;
1412    UINT16                  ResSourceLength;
1413    UINT16                  VendorLength;
1414    UINT16                  PinListLength;
1415    UINT16                  DescriptorSize;
1416    UINT32                  CurrentByteOffset;
1417    UINT32                  PinCount = 0;
1418    UINT32                  i;
1419
1420    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1421    CurrentByteOffset = Info->CurrentByteOffset;
1422
1423    /*
1424     * Calculate lengths for fields that have variable length:
1425     * 1) Resource Source string
1426     * 2) Vendor Data buffer
1427     * 3) PIN (interrupt) list
1428     */
1429    ResSourceLength = RsGetStringDataLength (InitializerOp);
1430    VendorLength = RsGetBufferDataLength (InitializerOp);
1431    PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1432
1433    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION) +
1434        ResSourceLength + VendorLength + PinListLength;
1435
1436    /* Allocate the local resource node and initialize */
1437
1438    Rnode = RsAllocateResourceNode (DescriptorSize +
1439        sizeof (AML_RESOURCE_LARGE_HEADER));
1440
1441    Descriptor = Rnode->Buffer;
1442    Descriptor->PinFunction.ResourceLength = DescriptorSize;
1443    Descriptor->PinFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_FUNCTION;
1444    Descriptor->PinFunction.RevisionId = AML_RESOURCE_PIN_FUNCTION_REVISION;
1445
1446    /* Build pointers to optional areas */
1447
1448    PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_FUNCTION));
1449    ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1450    VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1451
1452    /* Setup offsets within the descriptor */
1453
1454    Descriptor->PinFunction.PinTableOffset = (UINT16)
1455        ACPI_PTR_DIFF (PinList, Descriptor);
1456
1457    Descriptor->PinFunction.ResSourceOffset = (UINT16)
1458        ACPI_PTR_DIFF (ResourceSource, Descriptor);
1459
1460    /* Process all child initialization nodes */
1461
1462    for (i = 0; InitializerOp; i++)
1463    {
1464        switch (i)
1465        {
1466        case 0: /* Share Type [Flags] (_SHR) */
1467
1468            RsSetFlagBits16 (&Descriptor->PinFunction.Flags, InitializerOp, 0, 0);
1469            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1470                CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.Flags), 0);
1471            break;
1472
1473        case 1: /* Pin Config [BYTE] (_PPI) */
1474
1475            Descriptor->PinFunction.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
1476            RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
1477                CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.PinConfig));
1478            break;
1479
1480        case 2: /* Function Number [WORD] (_FUN) */
1481
1482            Descriptor->PinFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
1483            RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
1484                CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.FunctionNumber));
1485            break;
1486
1487        case 3: /* ResSource [Optional Field - STRING] */
1488
1489            if (ResSourceLength)
1490            {
1491                /* Copy string to the descriptor */
1492
1493                strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1494            }
1495            break;
1496
1497        case 4: /* Resource Index */
1498
1499            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1500            {
1501                Descriptor->PinFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1502            }
1503            break;
1504
1505        case 5: /* Resource Usage (consumer/producer) */
1506
1507            /* Assumed to be consumer */
1508
1509            break;
1510
1511        case 6: /* Resource Tag (Descriptor Name) */
1512
1513            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1514            break;
1515
1516        case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1517            /*
1518             * Always set the VendorOffset even if there is no Vendor Data.
1519             * This field is required in order to calculate the length
1520             * of the ResourceSource at runtime.
1521             */
1522            Descriptor->PinFunction.VendorOffset = (UINT16)
1523                ACPI_PTR_DIFF (VendorData, Descriptor);
1524
1525            if (RsGetVendorData (InitializerOp, VendorData,
1526                (CurrentByteOffset + Descriptor->PinFunction.VendorOffset)))
1527            {
1528                Descriptor->PinFunction.VendorLength = VendorLength;
1529            }
1530            break;
1531
1532        default:
1533            /*
1534             * PINs come through here, repeatedly. Each PIN must be a WORD.
1535             * NOTE: there is no "length" field for this, so from ACPI spec:
1536             *  The number of pins in the table can be calculated from:
1537             *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1538             *  (implies resource source must immediately follow the pin list.)
1539             *  Name: _PIN
1540             */
1541            *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1542            PinList++;
1543            PinCount++;
1544
1545            /* Case 8: First pin number in list */
1546
1547            if (i == 8)
1548            {
1549                if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1550                {
1551                    /* Must be at least one interrupt */
1552
1553                    AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1554                        InitializerOp, NULL);
1555                }
1556
1557                /* Check now for duplicates in list */
1558
1559                RsCheckListForDuplicates (InitializerOp);
1560
1561                /* Create a named field at the start of the list */
1562
1563                RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1564                    CurrentByteOffset + Descriptor->PinFunction.PinTableOffset);
1565            }
1566            break;
1567        }
1568
1569        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1570    }
1571
1572    return (Rnode);
1573}
1574
1575
1576/*******************************************************************************
1577 *
1578 * FUNCTION:    RsDoPinConfigDescriptor
1579 *
1580 * PARAMETERS:  Info                - Parse Op and resource template offset
1581 *
1582 * RETURN:      Completed resource node
1583 *
1584 * DESCRIPTION: Construct a long "PinConfig" descriptor
1585 *
1586 ******************************************************************************/
1587
1588ASL_RESOURCE_NODE *
1589RsDoPinConfigDescriptor (
1590    ASL_RESOURCE_INFO       *Info)
1591{
1592    AML_RESOURCE            *Descriptor;
1593    ACPI_PARSE_OBJECT       *InitializerOp;
1594    ASL_RESOURCE_NODE       *Rnode;
1595    char                    *ResourceSource = NULL;
1596    UINT8                   *VendorData = NULL;
1597    UINT16                  *PinList = NULL;
1598    UINT16                  ResSourceLength;
1599    UINT16                  VendorLength;
1600    UINT16                  PinListLength;
1601    UINT16                  DescriptorSize;
1602    UINT32                  CurrentByteOffset;
1603    UINT32                  PinCount = 0;
1604    UINT32                  i;
1605
1606    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1607    CurrentByteOffset = Info->CurrentByteOffset;
1608
1609    /*
1610     * Calculate lengths for fields that have variable length:
1611     * 1) Resource Source string
1612     * 2) Vendor Data buffer
1613     * 3) PIN (interrupt) list
1614     */
1615    ResSourceLength = RsGetStringDataLength (InitializerOp);
1616    VendorLength = RsGetBufferDataLength (InitializerOp);
1617    PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1618
1619    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG) +
1620        ResSourceLength + VendorLength + PinListLength;
1621
1622    /* Allocate the local resource node and initialize */
1623
1624    Rnode = RsAllocateResourceNode (DescriptorSize +
1625        sizeof (AML_RESOURCE_LARGE_HEADER));
1626
1627    Descriptor = Rnode->Buffer;
1628    Descriptor->PinConfig.ResourceLength = DescriptorSize;
1629    Descriptor->PinConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_CONFIG;
1630    Descriptor->PinConfig.RevisionId = AML_RESOURCE_PIN_CONFIG_REVISION;
1631
1632    /* Build pointers to optional areas */
1633
1634    PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_CONFIG));
1635    ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1636    VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1637
1638    /* Setup offsets within the descriptor */
1639
1640    Descriptor->PinConfig.PinTableOffset = (UINT16)
1641        ACPI_PTR_DIFF (PinList, Descriptor);
1642
1643    Descriptor->PinConfig.ResSourceOffset = (UINT16)
1644        ACPI_PTR_DIFF (ResourceSource, Descriptor);
1645
1646    /* Process all child initialization nodes */
1647
1648    for (i = 0; InitializerOp; i++)
1649    {
1650        BOOLEAN isValid;
1651
1652        switch (i)
1653        {
1654        case 0: /* Share Type [Flags] (_SHR) */
1655
1656            RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 0, 0);
1657            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1658                CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.Flags), 0);
1659            break;
1660
1661        case 1: /* Pin Config Type [BYTE] (_TYP) */
1662
1663            isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
1664            if (!isValid)
1665            {
1666                isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
1667                          InitializerOp->Asl.Value.Integer <= 0xff;
1668            }
1669            if (!isValid)
1670            {
1671                    AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
1672            }
1673
1674            Descriptor->PinConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
1675            RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
1676                CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigType));
1677
1678            break;
1679
1680        case 2: /* Pin Config Value [DWORD] (_VAL) */
1681
1682            Descriptor->PinConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
1683            RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
1684                CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigValue));
1685            break;
1686
1687        case 3: /* ResSource [Optional Field - STRING] */
1688
1689            if (ResSourceLength)
1690            {
1691                /* Copy string to the descriptor */
1692
1693                strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1694            }
1695            break;
1696
1697        case 4: /* Resource Index */
1698
1699            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1700            {
1701                Descriptor->PinConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1702            }
1703            break;
1704
1705        case 5: /* Resource Usage (consumer/producer) */
1706
1707            RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 1, 1);
1708
1709            break;
1710
1711        case 6: /* Resource Tag (Descriptor Name) */
1712
1713            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1714            break;
1715
1716        case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1717            /*
1718             * Always set the VendorOffset even if there is no Vendor Data.
1719             * This field is required in order to calculate the length
1720             * of the ResourceSource at runtime.
1721             */
1722            Descriptor->PinConfig.VendorOffset = (UINT16)
1723                ACPI_PTR_DIFF (VendorData, Descriptor);
1724
1725            if (RsGetVendorData (InitializerOp, VendorData,
1726                (CurrentByteOffset + Descriptor->PinConfig.VendorOffset)))
1727            {
1728                Descriptor->PinConfig.VendorLength = VendorLength;
1729            }
1730            break;
1731
1732        default:
1733            /*
1734             * PINs come through here, repeatedly. Each PIN must be a WORD.
1735             * NOTE: there is no "length" field for this, so from ACPI spec:
1736             *  The number of pins in the table can be calculated from:
1737             *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1738             *  (implies resource source must immediately follow the pin list.)
1739             *  Name: _PIN
1740             */
1741            *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1742            PinList++;
1743            PinCount++;
1744
1745            /* Case 8: First pin number in list */
1746
1747            if (i == 8)
1748            {
1749                if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1750                {
1751                    /* Must be at least one interrupt */
1752
1753                    AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1754                        InitializerOp, NULL);
1755                }
1756
1757                /* Check now for duplicates in list */
1758
1759                RsCheckListForDuplicates (InitializerOp);
1760
1761                /* Create a named field at the start of the list */
1762
1763                RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1764                    CurrentByteOffset + Descriptor->PinConfig.PinTableOffset);
1765            }
1766            break;
1767        }
1768
1769        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1770    }
1771
1772    return (Rnode);
1773}
1774
1775
1776/*******************************************************************************
1777 *
1778 * FUNCTION:    RsDoPinGroupDescriptor
1779 *
1780 * PARAMETERS:  Info                - Parse Op and resource template offset
1781 *
1782 * RETURN:      Completed resource node
1783 *
1784 * DESCRIPTION: Construct a long "PinGroup" descriptor
1785 *
1786 ******************************************************************************/
1787
1788ASL_RESOURCE_NODE *
1789RsDoPinGroupDescriptor (
1790    ASL_RESOURCE_INFO       *Info)
1791{
1792    AML_RESOURCE            *Descriptor;
1793    ACPI_PARSE_OBJECT       *InitializerOp;
1794    ASL_RESOURCE_NODE       *Rnode;
1795    UINT8                   *VendorData = NULL;
1796    UINT16                  *PinList = NULL;
1797    char                    *Label = NULL;
1798    UINT16                  LabelLength;
1799    UINT16                  VendorLength;
1800    UINT16                  PinListLength;
1801    UINT16                  DescriptorSize;
1802    UINT32                  CurrentByteOffset;
1803    UINT32                  PinCount = 0;
1804    UINT32                  i;
1805
1806    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1807    CurrentByteOffset = Info->CurrentByteOffset;
1808
1809    /*
1810     * Calculate lengths for fields that have variable length:
1811     * 1) Label
1812     * 2) Vendor Data buffer
1813     * 3) PIN (interrupt) list
1814     */
1815    LabelLength = RsGetStringDataLength (InitializerOp);
1816    VendorLength = RsGetBufferDataLength (InitializerOp);
1817    PinListLength = RsGetInterruptDataLength (InitializerOp, 4);
1818
1819    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP) +
1820        LabelLength + VendorLength + PinListLength;
1821
1822    /* Allocate the local resource node and initialize */
1823
1824    Rnode = RsAllocateResourceNode (DescriptorSize +
1825        sizeof (AML_RESOURCE_LARGE_HEADER));
1826
1827    Descriptor = Rnode->Buffer;
1828    Descriptor->PinGroup.ResourceLength = DescriptorSize;
1829    Descriptor->PinGroup.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP;
1830    Descriptor->PinGroup.RevisionId = AML_RESOURCE_PIN_GROUP_REVISION;
1831
1832    /* Build pointers to optional areas */
1833
1834    PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP));
1835    Label = ACPI_ADD_PTR (char, PinList, PinListLength);
1836    VendorData = ACPI_ADD_PTR (UINT8, Label, LabelLength);
1837
1838    /* Setup offsets within the descriptor */
1839
1840    Descriptor->PinGroup.PinTableOffset = (UINT16) ACPI_PTR_DIFF (PinList, Descriptor);
1841    Descriptor->PinGroup.LabelOffset = (UINT16) ACPI_PTR_DIFF (Label, Descriptor);
1842
1843    /* Process all child initialization nodes */
1844
1845    for (i = 0; InitializerOp; i++)
1846    {
1847        switch (i)
1848        {
1849        case 0: /* Resource Label */
1850
1851            if (LabelLength < 2)
1852            {
1853                AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
1854            }
1855            strcpy (Label, InitializerOp->Asl.Value.String);
1856
1857            break;
1858
1859        case 1: /* Resource Usage (consumer/producer) */
1860
1861            RsSetFlagBits16 (&Descriptor->PinGroup.Flags, InitializerOp, 0, 0);
1862
1863            break;
1864
1865        case 2: /* Resource Tag (Descriptor Name) */
1866
1867            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1868            break;
1869
1870        case 3: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1871            /*
1872             * Always set the VendorOffset even if there is no Vendor Data.
1873             * This field is required in order to calculate the length
1874             * of the ResourceSource at runtime.
1875             */
1876            Descriptor->PinGroup.VendorOffset = (UINT16)
1877                ACPI_PTR_DIFF (VendorData, Descriptor);
1878
1879            if (RsGetVendorData (InitializerOp, VendorData,
1880                (CurrentByteOffset + Descriptor->PinGroup.VendorOffset)))
1881            {
1882                Descriptor->PinGroup.VendorLength = VendorLength;
1883            }
1884            break;
1885
1886        default:
1887            /*
1888             * PINs come through here, repeatedly. Each PIN must be a WORD.
1889             * NOTE: there is no "length" field for this, so from ACPI spec:
1890             *  The number of pins in the table can be calculated from:
1891             *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1892             *  (implies resource source must immediately follow the pin list.)
1893             *  Name: _PIN
1894             */
1895            *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1896            PinList++;
1897            PinCount++;
1898
1899            /* Case 3: First pin number in list */
1900
1901            if (i == 4)
1902            {
1903                if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1904                {
1905                    /* Must be at least one interrupt */
1906
1907                    AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1908                        InitializerOp, NULL);
1909                }
1910
1911                /* Check now for duplicates in list */
1912
1913                RsCheckListForDuplicates (InitializerOp);
1914
1915                /* Create a named field at the start of the list */
1916
1917                RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1918                    CurrentByteOffset + Descriptor->PinGroup.PinTableOffset);
1919            }
1920            break;
1921        }
1922
1923        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1924    }
1925
1926    return (Rnode);
1927}
1928
1929
1930/*******************************************************************************
1931 *
1932 * FUNCTION:    RsDoPinGroupFunctionDescriptor
1933 *
1934 * PARAMETERS:  Info                - Parse Op and resource template offset
1935 *
1936 * RETURN:      Completed resource node
1937 *
1938 * DESCRIPTION: Construct a long "PinGroupFunction" descriptor
1939 *
1940 ******************************************************************************/
1941
1942ASL_RESOURCE_NODE *
1943RsDoPinGroupFunctionDescriptor (
1944    ASL_RESOURCE_INFO       *Info)
1945{
1946    AML_RESOURCE            *Descriptor;
1947    ACPI_PARSE_OBJECT       *InitializerOp;
1948    ASL_RESOURCE_NODE       *Rnode;
1949    char                    *ResourceSource = NULL;
1950    char                    *ResourceSourceLabel = NULL;
1951    UINT8                   *VendorData = NULL;
1952    UINT16                  ResSourceLength;
1953    UINT16                  ResSourceLabelLength;
1954    UINT16                  VendorLength;
1955    UINT16                  DescriptorSize;
1956    UINT32                  CurrentByteOffset;
1957    UINT32                  i;
1958
1959    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1960    CurrentByteOffset = Info->CurrentByteOffset;
1961
1962    /*
1963     * Calculate lengths for fields that have variable length:
1964     * 1) Resource Source string
1965     * 2) Resource Source Label string
1966     * 3) Vendor Data buffer
1967     */
1968    ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 2);
1969    ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 4);
1970    VendorLength = RsGetBufferDataLength (InitializerOp);
1971
1972    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION) +
1973        ResSourceLength + ResSourceLabelLength + VendorLength;
1974
1975    /* Allocate the local resource node and initialize */
1976
1977    Rnode = RsAllocateResourceNode (DescriptorSize +
1978        sizeof (AML_RESOURCE_LARGE_HEADER));
1979
1980    Descriptor = Rnode->Buffer;
1981    Descriptor->PinGroupFunction.ResourceLength = DescriptorSize;
1982    Descriptor->PinGroupFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION;
1983    Descriptor->PinGroupFunction.RevisionId = AML_RESOURCE_PIN_GROUP_FUNCTION_REVISION;
1984
1985    /* Build pointers to optional areas */
1986
1987    ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_FUNCTION));
1988    ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
1989    VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
1990
1991    /* Setup offsets within the descriptor */
1992
1993    Descriptor->PinGroupFunction.ResSourceOffset = (UINT16)
1994        ACPI_PTR_DIFF (ResourceSource, Descriptor);
1995    Descriptor->PinGroupFunction.ResSourceLabelOffset = (UINT16)
1996        ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
1997
1998    /* Process all child initialization nodes */
1999
2000    for (i = 0; InitializerOp; i++)
2001    {
2002        switch (i)
2003        {
2004        case 0: /* Share Type [Flags] (_SHR) */
2005
2006            RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 0, 0);
2007            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2008                CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.Flags), 0);
2009            break;
2010
2011        case 1: /* Function Number [WORD] */
2012
2013            Descriptor->PinGroupFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
2014            RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
2015                CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.FunctionNumber));
2016            break;
2017
2018        case 2: /* ResourceSource [STRING] */
2019
2020            strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2021            break;
2022
2023        case 3: /* Resource Index */
2024
2025            Descriptor->PinGroupFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2026            break;
2027
2028        case 4: /* ResourceSourceLabel [STRING] */
2029
2030            if (ResSourceLabelLength < 2)
2031            {
2032                AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2033            }
2034
2035            strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2036            break;
2037
2038        case 5: /* Resource Usage (consumer/producer) */
2039
2040            RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 1, 1);
2041
2042            break;
2043
2044        case 6: /* Resource Tag (Descriptor Name) */
2045
2046            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2047            break;
2048
2049        case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2050            /*
2051             * Always set the VendorOffset even if there is no Vendor Data.
2052             * This field is required in order to calculate the length
2053             * of the ResourceSource at runtime.
2054             */
2055            Descriptor->PinGroupFunction.VendorOffset = (UINT16)
2056                ACPI_PTR_DIFF (VendorData, Descriptor);
2057
2058            if (RsGetVendorData (InitializerOp, VendorData,
2059                (CurrentByteOffset + Descriptor->PinGroupFunction.VendorOffset)))
2060            {
2061                Descriptor->PinGroupFunction.VendorLength = VendorLength;
2062            }
2063            break;
2064
2065        default:
2066            break;
2067        }
2068
2069        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2070    }
2071
2072    return (Rnode);
2073}
2074
2075
2076/*******************************************************************************
2077 *
2078 * FUNCTION:    RsDoPinGroupConfigDescriptor
2079 *
2080 * PARAMETERS:  Info                - Parse Op and resource template offset
2081 *
2082 * RETURN:      Completed resource node
2083 *
2084 * DESCRIPTION: Construct a long "PinGroupConfig" descriptor
2085 *
2086 ******************************************************************************/
2087
2088ASL_RESOURCE_NODE *
2089RsDoPinGroupConfigDescriptor (
2090    ASL_RESOURCE_INFO       *Info)
2091{
2092    AML_RESOURCE            *Descriptor;
2093    ACPI_PARSE_OBJECT       *InitializerOp;
2094    ASL_RESOURCE_NODE       *Rnode;
2095    char                    *ResourceSource = NULL;
2096    char                    *ResourceSourceLabel = NULL;
2097    UINT8                   *VendorData = NULL;
2098    UINT16                  ResSourceLength;
2099    UINT16                  ResSourceLabelLength;
2100    UINT16                  VendorLength;
2101    UINT16                  DescriptorSize;
2102    UINT32                  CurrentByteOffset;
2103    UINT32                  i;
2104
2105    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
2106    CurrentByteOffset = Info->CurrentByteOffset;
2107
2108    /*
2109     * Calculate lengths for fields that have variable length:
2110     * 1) Resource Source string
2111     * 2) Resource Source Label string
2112     * 3) Vendor Data buffer
2113     */
2114    ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 3);
2115    ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 5);
2116    VendorLength = RsGetBufferDataLength (InitializerOp);
2117
2118    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG) +
2119        ResSourceLength + ResSourceLabelLength + VendorLength;
2120
2121    /* Allocate the local resource node and initialize */
2122
2123    Rnode = RsAllocateResourceNode (DescriptorSize +
2124        sizeof (AML_RESOURCE_LARGE_HEADER));
2125
2126    Descriptor = Rnode->Buffer;
2127    Descriptor->PinGroupConfig.ResourceLength = DescriptorSize;
2128    Descriptor->PinGroupConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG;
2129    Descriptor->PinGroupConfig.RevisionId = AML_RESOURCE_PIN_GROUP_CONFIG_REVISION;
2130
2131    /* Build pointers to optional areas */
2132
2133    ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_CONFIG));
2134    ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
2135    VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
2136
2137    /* Setup offsets within the descriptor */
2138
2139    Descriptor->PinGroupConfig.ResSourceOffset = (UINT16)
2140        ACPI_PTR_DIFF (ResourceSource, Descriptor);
2141    Descriptor->PinGroupConfig.ResSourceLabelOffset = (UINT16)
2142        ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
2143
2144    /* Process all child initialization nodes */
2145
2146    for (i = 0; InitializerOp; i++)
2147    {
2148        BOOLEAN isValid;
2149
2150        switch (i)
2151        {
2152        case 0: /* Share Type [Flags] (_SHR) */
2153
2154            RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 0, 0);
2155            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2156                CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.Flags), 0);
2157            break;
2158
2159        case 1: /* Pin Config Type [BYTE] (_TYP) */
2160
2161            isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
2162            if (!isValid)
2163            {
2164                isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
2165                          InitializerOp->Asl.Value.Integer <= 0xff;
2166            }
2167            if (!isValid)
2168            {
2169                    AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
2170            }
2171
2172            Descriptor->PinGroupConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
2173            RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
2174                CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigType));
2175
2176            break;
2177
2178        case 2: /* Pin Config Value [DWORD] (_VAL) */
2179
2180            Descriptor->PinGroupConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
2181            RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
2182                CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigValue));
2183            break;
2184
2185        case 3: /* ResourceSource [STRING] */
2186
2187            /* Copy string to the descriptor */
2188
2189            strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2190            break;
2191
2192        case 4: /* Resource Index */
2193
2194            Descriptor->PinGroupConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2195            break;
2196
2197        case 5: /* ResourceSourceLabel [STRING] */
2198
2199            if (ResSourceLabelLength < 2)
2200            {
2201                AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2202            }
2203
2204            strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2205            break;
2206
2207        case 6: /* Resource Usage (consumer/producer) */
2208
2209            RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 1, 1);
2210
2211            break;
2212
2213        case 7: /* Resource Tag (Descriptor Name) */
2214
2215            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2216            break;
2217
2218        case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2219            /*
2220             * Always set the VendorOffset even if there is no Vendor Data.
2221             * This field is required in order to calculate the length
2222             * of the ResourceSource at runtime.
2223             */
2224            Descriptor->PinGroupConfig.VendorOffset = (UINT16)
2225                ACPI_PTR_DIFF (VendorData, Descriptor);
2226
2227            if (RsGetVendorData (InitializerOp, VendorData,
2228                (CurrentByteOffset + Descriptor->PinGroupConfig.VendorOffset)))
2229            {
2230                Descriptor->PinGroupConfig.VendorLength = VendorLength;
2231            }
2232            break;
2233
2234        default:
2235            break;
2236        }
2237
2238        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2239    }
2240
2241    return (Rnode);
2242}
2243