aslrestype2s.c revision 316303
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 - 2017, 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
168static BOOLEAN
169RsGetVendorData (
170    ACPI_PARSE_OBJECT       *InitializerOp,
171    UINT8                   *VendorData,
172    ACPI_SIZE               DescriptorOffset);
173
174/*
175 * This module contains descriptors for serial buses and GPIO:
176 *
177 * GpioInt
178 * GpioIo
179 * I2cSerialBus
180 * SpiSerialBus
181 * UartSerialBus
182 */
183
184
185/*******************************************************************************
186 *
187 * FUNCTION:    RsGetBufferDataLength
188 *
189 * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
190 *                                    descriptor
191 *
192 * RETURN:      Length of the data buffer
193 *
194 * DESCRIPTION: Get the length of a RawDataBuffer, used for vendor data.
195 *
196 ******************************************************************************/
197
198static UINT16
199RsGetBufferDataLength (
200    ACPI_PARSE_OBJECT       *InitializerOp)
201{
202    UINT16                  ExtraDataSize = 0;
203    ACPI_PARSE_OBJECT       *DataList;
204
205
206    /* Find the byte-initializer list */
207
208    while (InitializerOp)
209    {
210        if (InitializerOp->Asl.ParseOpcode == PARSEOP_DATABUFFER)
211        {
212            /* First child is the optional length (ignore it here) */
213
214            DataList = InitializerOp->Asl.Child;
215            DataList = ASL_GET_PEER_NODE (DataList);
216
217            /* Count the data items (each one is a byte of data) */
218
219            while (DataList)
220            {
221                ExtraDataSize++;
222                DataList = ASL_GET_PEER_NODE (DataList);
223            }
224
225            return (ExtraDataSize);
226        }
227
228        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
229    }
230
231    return (ExtraDataSize);
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION:    RsGetInterruptDataLength
238 *
239 * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
240 *                                    descriptor
241 *
242 * RETURN:      Length of the interrupt data list
243 *
244 * DESCRIPTION: Get the length of a list of interrupt DWORDs for the GPIO
245 *              descriptors.
246 *
247 ******************************************************************************/
248
249static UINT16
250RsGetInterruptDataLength (
251    ACPI_PARSE_OBJECT       *InitializerOp)
252{
253    UINT16                  InterruptLength;
254    UINT32                  i;
255
256
257    /* Count the interrupt numbers */
258
259    InterruptLength = 0;
260    for (i = 0; InitializerOp; i++)
261    {
262        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
263
264        /* Interrupt list starts at offset 10 (Gpio descriptors) */
265
266        if (i >= 10)
267        {
268            InterruptLength += 2;
269        }
270    }
271
272    return (InterruptLength);
273}
274
275
276/*******************************************************************************
277 *
278 * FUNCTION:    RsGetVendorData
279 *
280 * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
281 *                                    descriptor.
282 *              VendorData          - Where the vendor data is returned
283 *              DescriptorOffset    - Where vendor data begins in descriptor
284 *
285 * RETURN:      TRUE if valid vendor data was returned, FALSE otherwise.
286 *
287 * DESCRIPTION: Extract the vendor data and construct a vendor data buffer.
288 *
289 ******************************************************************************/
290
291static BOOLEAN
292RsGetVendorData (
293    ACPI_PARSE_OBJECT       *InitializerOp,
294    UINT8                   *VendorData,
295    ACPI_SIZE               DescriptorOffset)
296{
297    ACPI_PARSE_OBJECT       *BufferOp;
298    UINT32                  SpecifiedLength = ACPI_UINT32_MAX;
299    UINT16                  ActualLength = 0;
300
301
302    /* Vendor Data field is always optional */
303
304    if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
305    {
306        return (FALSE);
307    }
308
309    BufferOp = InitializerOp->Asl.Child;
310    if (!BufferOp)
311    {
312        AslError (ASL_ERROR, ASL_MSG_SYNTAX, InitializerOp, "");
313        return (FALSE);
314    }
315
316    /* First child is the optional buffer length (WORD) */
317
318    if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
319    {
320        SpecifiedLength = (UINT16) BufferOp->Asl.Value.Integer;
321    }
322
323    /* Insert field tag _VEN */
324
325    RsCreateByteField (InitializerOp, ACPI_RESTAG_VENDORDATA,
326        (UINT16) DescriptorOffset);
327
328    /* Walk the list of buffer initializers (each is one byte) */
329
330    BufferOp = RsCompleteNodeAndGetNext (BufferOp);
331    if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
332    {
333        while (BufferOp)
334        {
335            *VendorData = (UINT8) BufferOp->Asl.Value.Integer;
336            VendorData++;
337            ActualLength++;
338            BufferOp = RsCompleteNodeAndGetNext (BufferOp);
339        }
340    }
341
342    /* Length validation. Buffer cannot be of zero length */
343
344    if ((SpecifiedLength == 0) ||
345        ((SpecifiedLength == ACPI_UINT32_MAX) && (ActualLength == 0)))
346    {
347        AslError (ASL_ERROR, ASL_MSG_BUFFER_LENGTH, InitializerOp, NULL);
348        return (FALSE);
349    }
350
351    if (SpecifiedLength != ACPI_UINT32_MAX)
352    {
353        /* ActualLength > SpecifiedLength -> error */
354
355        if (ActualLength > SpecifiedLength)
356        {
357            AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, InitializerOp, NULL);
358            return (FALSE);
359        }
360
361        /* ActualLength < SpecifiedLength -> remark */
362
363        else if (ActualLength < SpecifiedLength)
364        {
365            AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, InitializerOp, NULL);
366            return (FALSE);
367        }
368    }
369
370    return (TRUE);
371}
372
373
374/*******************************************************************************
375 *
376 * FUNCTION:    RsDoGpioIntDescriptor
377 *
378 * PARAMETERS:  Info                - Parse Op and resource template offset
379 *
380 * RETURN:      Completed resource node
381 *
382 * DESCRIPTION: Construct a long "GpioInt" descriptor
383 *
384 ******************************************************************************/
385
386ASL_RESOURCE_NODE *
387RsDoGpioIntDescriptor (
388    ASL_RESOURCE_INFO       *Info)
389{
390    AML_RESOURCE            *Descriptor;
391    ACPI_PARSE_OBJECT       *InitializerOp;
392    ASL_RESOURCE_NODE       *Rnode;
393    char                    *ResourceSource = NULL;
394    UINT8                   *VendorData = NULL;
395    UINT16                  *InterruptList = NULL;
396    UINT16                  *PinList = NULL;
397    UINT16                  ResSourceLength;
398    UINT16                  VendorLength;
399    UINT16                  InterruptLength;
400    UINT16                  DescriptorSize;
401    UINT32                  CurrentByteOffset;
402    UINT32                  PinCount = 0;
403    UINT32                  i;
404
405
406    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
407    CurrentByteOffset = Info->CurrentByteOffset;
408
409    /*
410     * Calculate lengths for fields that have variable length:
411     * 1) Resource Source string
412     * 2) Vendor Data buffer
413     * 3) PIN (interrupt) list
414     */
415    ResSourceLength = RsGetStringDataLength (InitializerOp);
416    VendorLength = RsGetBufferDataLength (InitializerOp);
417    InterruptLength = RsGetInterruptDataLength (InitializerOp);
418
419    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
420        ResSourceLength + VendorLength + InterruptLength;
421
422    /* Allocate the local resource node and initialize */
423
424    Rnode = RsAllocateResourceNode (DescriptorSize +
425        sizeof (AML_RESOURCE_LARGE_HEADER));
426
427    Descriptor = Rnode->Buffer;
428    Descriptor->Gpio.ResourceLength = DescriptorSize;
429    Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
430    Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
431    Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_INT;
432
433    /* Build pointers to optional areas */
434
435    InterruptList = ACPI_ADD_PTR (UINT16, Descriptor,
436        sizeof (AML_RESOURCE_GPIO));
437    PinList = InterruptList;
438    ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
439    VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
440
441    /* Setup offsets within the descriptor */
442
443    Descriptor->Gpio.PinTableOffset = (UINT16)
444        ACPI_PTR_DIFF (InterruptList, Descriptor);
445
446    Descriptor->Gpio.ResSourceOffset = (UINT16)
447        ACPI_PTR_DIFF (ResourceSource, Descriptor);
448
449    /* Process all child initialization nodes */
450
451    for (i = 0; InitializerOp; i++)
452    {
453        switch (i)
454        {
455        case 0: /* Interrupt Mode - edge/level [Flag] (_MOD) */
456
457            RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
458            RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
459                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0);
460            break;
461
462        case 1: /* Interrupt Polarity - Active high/low [Flags] (_POL) */
463
464            RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 1, 0);
465            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_POLARITY,
466                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 1, 2);
467            break;
468
469        case 2: /* Share Type - Default: exclusive (0) [Flags] (_SHR) */
470
471            RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
472            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
473                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3, 2);
474            break;
475
476        case 3: /* Pin Config [BYTE] (_PPI) */
477
478            Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
479            RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
480                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
481            break;
482
483        case 4: /* Debounce Timeout [WORD] (_DBT) */
484
485            Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
486            RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
487                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
488            break;
489
490        case 5: /* ResSource [Optional Field - STRING] */
491
492            if (ResSourceLength)
493            {
494                /* Copy string to the descriptor */
495
496                strcpy (ResourceSource,
497                    InitializerOp->Asl.Value.String);
498            }
499            break;
500
501        case 6: /* Resource Index */
502
503            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
504            {
505                Descriptor->Gpio.ResSourceIndex =
506                    (UINT8) InitializerOp->Asl.Value.Integer;
507            }
508            break;
509
510        case 7: /* Resource Usage (consumer/producer) */
511
512            RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
513            break;
514
515        case 8: /* Resource Tag (Descriptor Name) */
516
517            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
518            break;
519
520        case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
521
522            /*
523             * Always set the VendorOffset even if there is no Vendor Data.
524             * This field is required in order to calculate the length
525             * of the ResourceSource at runtime.
526             */
527            Descriptor->Gpio.VendorOffset = (UINT16)
528                ACPI_PTR_DIFF (VendorData, Descriptor);
529
530            if (RsGetVendorData (InitializerOp, VendorData,
531                (CurrentByteOffset +  Descriptor->Gpio.VendorOffset)))
532            {
533                Descriptor->Gpio.VendorLength = VendorLength;
534            }
535            break;
536
537        default:
538            /*
539             * PINs come through here, repeatedly. Each PIN must be a WORD.
540             * NOTE: there is no "length" field for this, so from ACPI spec:
541             *  The number of pins in the table can be calculated from:
542             *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
543             *  (implies resource source must immediately follow the pin list.)
544             *  Name: _PIN
545             */
546            *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
547            InterruptList++;
548            PinCount++;
549
550            /* Case 10: First interrupt number in list */
551
552            if (i == 10)
553            {
554                if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
555                {
556                    /* Must be at least one interrupt */
557
558                    AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
559                        InitializerOp, NULL);
560                }
561
562                /* Check now for duplicates in list */
563
564                RsCheckListForDuplicates (InitializerOp);
565
566                /* Create a named field at the start of the list */
567
568                RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
569                    CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
570            }
571            break;
572        }
573
574        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
575    }
576
577    MpSaveGpioInfo (Info->MappingOp, Descriptor,
578        PinCount, PinList, ResourceSource);
579    return (Rnode);
580}
581
582
583/*******************************************************************************
584 *
585 * FUNCTION:    RsDoGpioIoDescriptor
586 *
587 * PARAMETERS:  Info                - Parse Op and resource template offset
588 *
589 * RETURN:      Completed resource node
590 *
591 * DESCRIPTION: Construct a long "GpioIo" descriptor
592 *
593 ******************************************************************************/
594
595ASL_RESOURCE_NODE *
596RsDoGpioIoDescriptor (
597    ASL_RESOURCE_INFO       *Info)
598{
599    AML_RESOURCE            *Descriptor;
600    ACPI_PARSE_OBJECT       *InitializerOp;
601    ASL_RESOURCE_NODE       *Rnode;
602    char                    *ResourceSource = NULL;
603    UINT8                   *VendorData = NULL;
604    UINT16                  *InterruptList = NULL;
605    UINT16                  *PinList = NULL;
606    UINT16                  ResSourceLength;
607    UINT16                  VendorLength;
608    UINT16                  InterruptLength;
609    UINT16                  DescriptorSize;
610    UINT32                  CurrentByteOffset;
611    UINT32                  PinCount = 0;
612    UINT32                  i;
613
614
615    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
616    CurrentByteOffset = Info->CurrentByteOffset;
617
618    /*
619     * Calculate lengths for fields that have variable length:
620     * 1) Resource Source string
621     * 2) Vendor Data buffer
622     * 3) PIN (interrupt) list
623     */
624    ResSourceLength = RsGetStringDataLength (InitializerOp);
625    VendorLength = RsGetBufferDataLength (InitializerOp);
626    InterruptLength = RsGetInterruptDataLength (InitializerOp);
627    PinList = InterruptList;
628
629    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
630        ResSourceLength + VendorLength + InterruptLength;
631
632    /* Allocate the local resource node and initialize */
633
634    Rnode = RsAllocateResourceNode (DescriptorSize +
635        sizeof (AML_RESOURCE_LARGE_HEADER));
636
637    Descriptor = Rnode->Buffer;
638    Descriptor->Gpio.ResourceLength = DescriptorSize;
639    Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
640    Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
641    Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO;
642
643    /* Build pointers to optional areas */
644
645    InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO));
646    PinList = InterruptList;
647    ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
648    VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
649
650    /* Setup offsets within the descriptor */
651
652    Descriptor->Gpio.PinTableOffset = (UINT16)
653        ACPI_PTR_DIFF (InterruptList, Descriptor);
654
655    Descriptor->Gpio.ResSourceOffset = (UINT16)
656        ACPI_PTR_DIFF (ResourceSource, Descriptor);
657
658    /* Process all child initialization nodes */
659
660    for (i = 0; InitializerOp; i++)
661    {
662        switch (i)
663        {
664        case 0: /* Share Type [Flags] (_SHR) */
665
666            RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
667            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
668                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3);
669            break;
670
671        case 1: /* Pin Config [BYTE] (_PPI) */
672
673            Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
674            RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
675                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
676            break;
677
678        case 2: /* Debounce Timeout [WORD] (_DBT) */
679
680            Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
681            RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
682                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
683            break;
684
685        case 3: /* Drive Strength [WORD] (_DRS) */
686
687            Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer;
688            RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH,
689                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength));
690            break;
691
692        case 4: /* I/O Restriction [Flag] (_IOR) */
693
694            RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
695            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION,
696                CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2);
697            break;
698
699        case 5: /* ResSource [Optional Field - STRING] */
700
701            if (ResSourceLength)
702            {
703                /* Copy string to the descriptor */
704
705                strcpy (ResourceSource,
706                    InitializerOp->Asl.Value.String);
707            }
708            break;
709
710        case 6: /* Resource Index */
711
712            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
713            {
714                Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
715            }
716            break;
717
718        case 7: /* Resource Usage (consumer/producer) */
719
720            RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
721            break;
722
723        case 8: /* Resource Tag (Descriptor Name) */
724
725            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
726            break;
727
728        case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
729            /*
730             * Always set the VendorOffset even if there is no Vendor Data.
731             * This field is required in order to calculate the length
732             * of the ResourceSource at runtime.
733             */
734            Descriptor->Gpio.VendorOffset = (UINT16)
735                ACPI_PTR_DIFF (VendorData, Descriptor);
736
737            if (RsGetVendorData (InitializerOp, VendorData,
738                (CurrentByteOffset + Descriptor->Gpio.VendorOffset)))
739            {
740                Descriptor->Gpio.VendorLength = VendorLength;
741            }
742            break;
743
744        default:
745            /*
746             * PINs come through here, repeatedly. Each PIN must be a WORD.
747             * NOTE: there is no "length" field for this, so from ACPI spec:
748             *  The number of pins in the table can be calculated from:
749             *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
750             *  (implies resource source must immediately follow the pin list.)
751             *  Name: _PIN
752             */
753            *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
754            InterruptList++;
755            PinCount++;
756
757            /* Case 10: First interrupt number in list */
758
759            if (i == 10)
760            {
761                if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
762                {
763                    /* Must be at least one interrupt */
764
765                    AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
766                        InitializerOp, NULL);
767                }
768
769                /* Check now for duplicates in list */
770
771                RsCheckListForDuplicates (InitializerOp);
772
773                /* Create a named field at the start of the list */
774
775                RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
776                    CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
777            }
778            break;
779        }
780
781        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
782    }
783
784    MpSaveGpioInfo (Info->MappingOp, Descriptor,
785        PinCount, PinList, ResourceSource);
786    return (Rnode);
787}
788
789
790/*******************************************************************************
791 *
792 * FUNCTION:    RsDoI2cSerialBusDescriptor
793 *
794 * PARAMETERS:  Info                - Parse Op and resource template offset
795 *
796 * RETURN:      Completed resource node
797 *
798 * DESCRIPTION: Construct a long "I2cSerialBus" descriptor
799 *
800 ******************************************************************************/
801
802ASL_RESOURCE_NODE *
803RsDoI2cSerialBusDescriptor (
804    ASL_RESOURCE_INFO       *Info)
805{
806    AML_RESOURCE            *Descriptor;
807    ACPI_PARSE_OBJECT       *InitializerOp;
808    ASL_RESOURCE_NODE       *Rnode;
809    char                    *ResourceSource = NULL;
810    UINT8                   *VendorData = NULL;
811    UINT16                  ResSourceLength;
812    UINT16                  VendorLength;
813    UINT16                  DescriptorSize;
814    UINT32                  CurrentByteOffset;
815    UINT32                  i;
816
817
818    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
819    CurrentByteOffset = Info->CurrentByteOffset;
820
821    /*
822     * Calculate lengths for fields that have variable length:
823     * 1) Resource Source string
824     * 2) Vendor Data buffer
825     */
826    ResSourceLength = RsGetStringDataLength (InitializerOp);
827    VendorLength = RsGetBufferDataLength (InitializerOp);
828
829    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) +
830        ResSourceLength + VendorLength;
831
832    /* Allocate the local resource node and initialize */
833
834    Rnode = RsAllocateResourceNode (DescriptorSize +
835        sizeof (AML_RESOURCE_LARGE_HEADER));
836
837    Descriptor = Rnode->Buffer;
838    Descriptor->I2cSerialBus.ResourceLength = DescriptorSize;
839    Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
840    Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION;
841    Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION;
842    Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE;
843    Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength;
844
845    if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_I2C_SERIALBUS_V2)
846    {
847        Descriptor->I2cSerialBus.RevisionId = 2;
848    }
849
850    /* Build pointers to optional areas */
851
852    VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS));
853    ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
854
855    /* Process all child initialization nodes */
856
857    for (i = 0; InitializerOp; i++)
858    {
859        switch (i)
860        {
861        case 0: /* Slave Address [WORD] (_ADR) */
862
863            Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer;
864            RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
865                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress));
866            break;
867
868        case 1: /* Slave Mode [Flag] (_SLV) */
869
870            RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0);
871            RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
872                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0);
873            break;
874
875        case 2: /* Connection Speed [DWORD] (_SPE) */
876
877            Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
878            RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
879                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed));
880            break;
881
882        case 3: /* Addressing Mode [Flag] (_MOD) */
883
884            RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
885            RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
886                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0);
887            break;
888
889        case 4: /* ResSource [Optional Field - STRING] */
890
891            if (ResSourceLength)
892            {
893                /* Copy string to the descriptor */
894
895                strcpy (ResourceSource,
896                    InitializerOp->Asl.Value.String);
897            }
898            break;
899
900        case 5: /* Resource Index */
901
902            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
903            {
904                Descriptor->I2cSerialBus.ResSourceIndex =
905                    (UINT8) InitializerOp->Asl.Value.Integer;
906            }
907            break;
908
909        case 6: /* Resource Usage (consumer/producer) */
910
911            RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1);
912            break;
913
914        case 7: /* Resource Tag (Descriptor Name) */
915
916            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
917            break;
918
919        case 8:
920            /*
921             * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
922             * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
923             * the ASL parser)
924             */
925            RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 2, 0);
926            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
927                CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 2);
928            break;
929
930        case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
931
932            RsGetVendorData (InitializerOp, VendorData,
933                CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS));
934            break;
935
936        default:    /* Ignore any extra nodes */
937
938            break;
939        }
940
941        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
942    }
943
944    MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
945    return (Rnode);
946}
947
948
949/*******************************************************************************
950 *
951 * FUNCTION:    RsDoSpiSerialBusDescriptor
952 *
953 * PARAMETERS:  Info                - Parse Op and resource template offset
954 *
955 * RETURN:      Completed resource node
956 *
957 * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor
958 *
959 ******************************************************************************/
960
961ASL_RESOURCE_NODE *
962RsDoSpiSerialBusDescriptor (
963    ASL_RESOURCE_INFO       *Info)
964{
965    AML_RESOURCE            *Descriptor;
966    ACPI_PARSE_OBJECT       *InitializerOp;
967    ASL_RESOURCE_NODE       *Rnode;
968    char                    *ResourceSource = NULL;
969    UINT8                   *VendorData = NULL;
970    UINT16                  ResSourceLength;
971    UINT16                  VendorLength;
972    UINT16                  DescriptorSize;
973    UINT32                  CurrentByteOffset;
974    UINT32                  i;
975
976
977    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
978    CurrentByteOffset = Info->CurrentByteOffset;
979
980    /*
981     * Calculate lengths for fields that have variable length:
982     * 1) Resource Source string
983     * 2) Vendor Data buffer
984     */
985    ResSourceLength = RsGetStringDataLength (InitializerOp);
986    VendorLength = RsGetBufferDataLength (InitializerOp);
987
988    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) +
989        ResSourceLength + VendorLength;
990
991    /* Allocate the local resource node and initialize */
992
993    Rnode = RsAllocateResourceNode (DescriptorSize +
994        sizeof (AML_RESOURCE_LARGE_HEADER));
995
996    Descriptor = Rnode->Buffer;
997    Descriptor->SpiSerialBus.ResourceLength = DescriptorSize;
998    Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
999    Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION;
1000    Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION;
1001    Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE;
1002    Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength;
1003
1004    if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_SPI_SERIALBUS_V2)
1005    {
1006        Descriptor->I2cSerialBus.RevisionId = 2;
1007    }
1008
1009    /* Build pointers to optional areas */
1010
1011    VendorData = ACPI_ADD_PTR (UINT8, Descriptor,
1012        sizeof (AML_RESOURCE_SPI_SERIALBUS));
1013    ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1014
1015    /* Process all child initialization nodes */
1016
1017    for (i = 0; InitializerOp; i++)
1018    {
1019        switch (i)
1020        {
1021        case 0: /* Device Selection [WORD] (_ADR) */
1022
1023            Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer;
1024            RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
1025                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection));
1026            break;
1027
1028        case 1: /* Device Polarity [Flag] (_DPL) */
1029
1030            RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0);
1031            RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY,
1032                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1);
1033            break;
1034
1035        case 2: /* Wire Mode [Flag] (_MOD) */
1036
1037            RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1038            RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
1039                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0);
1040            break;
1041
1042        case 3: /* Device Bit Length [BYTE] (_LEN) */
1043
1044            Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer;
1045            RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
1046                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength));
1047            break;
1048
1049        case 4: /* Slave Mode [Flag] (_SLV) */
1050
1051            RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0);
1052            RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1053                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0);
1054            break;
1055
1056        case 5: /* Connection Speed [DWORD] (_SPE) */
1057
1058            Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
1059            RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1060                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed));
1061            break;
1062
1063        case 6: /* Clock Polarity [BYTE] (_POL) */
1064
1065            Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer;
1066            RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY,
1067                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity));
1068            break;
1069
1070        case 7: /* Clock Phase [BYTE] (_PHA) */
1071
1072            Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer;
1073            RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE,
1074                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase));
1075            break;
1076
1077        case 8: /* ResSource [Optional Field - STRING] */
1078
1079            if (ResSourceLength)
1080            {
1081                /* Copy string to the descriptor */
1082
1083                strcpy (ResourceSource,
1084                    InitializerOp->Asl.Value.String);
1085            }
1086            break;
1087
1088        case 9: /* Resource Index */
1089
1090            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1091            {
1092                Descriptor->SpiSerialBus.ResSourceIndex =
1093                    (UINT8) InitializerOp->Asl.Value.Integer;
1094            }
1095            break;
1096
1097        case 10: /* Resource Usage (consumer/producer) */
1098
1099            RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1);
1100            break;
1101
1102        case 11: /* Resource Tag (Descriptor Name) */
1103
1104            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1105            break;
1106
1107        case 12:
1108            /*
1109             * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1110             * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1111             * the ASL parser)
1112             */
1113            RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 2, 0);
1114            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1115                CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 2);
1116            break;
1117
1118        case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1119
1120            RsGetVendorData (InitializerOp, VendorData,
1121                CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS));
1122            break;
1123
1124        default:    /* Ignore any extra nodes */
1125
1126            break;
1127        }
1128
1129        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1130    }
1131
1132    MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1133    return (Rnode);
1134}
1135
1136
1137/*******************************************************************************
1138 *
1139 * FUNCTION:    RsDoUartSerialBusDescriptor
1140 *
1141 * PARAMETERS:  Info                - Parse Op and resource template offset
1142 *
1143 * RETURN:      Completed resource node
1144 *
1145 * DESCRIPTION: Construct a long "UART Serial Bus" descriptor
1146 *
1147 ******************************************************************************/
1148
1149ASL_RESOURCE_NODE *
1150RsDoUartSerialBusDescriptor (
1151    ASL_RESOURCE_INFO       *Info)
1152{
1153    AML_RESOURCE            *Descriptor;
1154    ACPI_PARSE_OBJECT       *InitializerOp;
1155    ASL_RESOURCE_NODE       *Rnode;
1156    char                    *ResourceSource = NULL;
1157    UINT8                   *VendorData = NULL;
1158    UINT16                  ResSourceLength;
1159    UINT16                  VendorLength;
1160    UINT16                  DescriptorSize;
1161    UINT32                  CurrentByteOffset;
1162    UINT32                  i;
1163
1164
1165    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1166    CurrentByteOffset = Info->CurrentByteOffset;
1167
1168    /*
1169     * Calculate lengths for fields that have variable length:
1170     * 1) Resource Source string
1171     * 2) Vendor Data buffer
1172     */
1173    ResSourceLength = RsGetStringDataLength (InitializerOp);
1174    VendorLength = RsGetBufferDataLength (InitializerOp);
1175
1176    DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) +
1177        ResSourceLength + VendorLength;
1178
1179    /* Allocate the local resource node and initialize */
1180
1181    Rnode = RsAllocateResourceNode (DescriptorSize +
1182        sizeof (AML_RESOURCE_LARGE_HEADER));
1183
1184    Descriptor = Rnode->Buffer;
1185    Descriptor->UartSerialBus.ResourceLength = DescriptorSize;
1186    Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1187    Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION;
1188    Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION;
1189    Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE;
1190    Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength;
1191
1192    if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_UART_SERIALBUS_V2)
1193    {
1194        Descriptor->I2cSerialBus.RevisionId = 2;
1195    }
1196
1197    /* Build pointers to optional areas */
1198
1199    VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS));
1200    ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1201
1202    /* Process all child initialization nodes */
1203
1204    for (i = 0; InitializerOp; i++)
1205    {
1206        switch (i)
1207        {
1208        case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */
1209
1210            Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer;
1211            RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1212                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate));
1213            break;
1214
1215        case 1: /* Bits Per Byte [Flags] (_LEN) */
1216
1217            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3);
1218            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH,
1219                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3);
1220            break;
1221
1222        case 2: /* Stop Bits [Flags] (_STB) */
1223
1224            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1);
1225            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS,
1226                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2);
1227            break;
1228
1229        case 3: /* Lines In Use [BYTE] (_LIN) */
1230
1231            Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer;
1232            RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE,
1233                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled));
1234            break;
1235
1236        case 4: /* Endianness [Flag] (_END) */
1237
1238            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0);
1239            RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS,
1240                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7);
1241            break;
1242
1243        case 5: /* Parity [BYTE] (_PAR) */
1244
1245            Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer;
1246            RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY,
1247                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity));
1248            break;
1249
1250        case 6: /* Flow Control [Flags] (_FLC) */
1251
1252            RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1253            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL,
1254                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2);
1255            break;
1256
1257        case 7: /* Rx Buffer Size [WORD] (_RXL) */
1258
1259            Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1260            RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX,
1261                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize));
1262            break;
1263
1264        case 8: /* Tx Buffer Size [WORD] (_TXL) */
1265
1266            Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1267            RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX,
1268                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize));
1269            break;
1270
1271        case 9: /* ResSource [Optional Field - STRING] */
1272
1273            if (ResSourceLength)
1274            {
1275                /* Copy string to the descriptor */
1276
1277                strcpy (ResourceSource,
1278                    InitializerOp->Asl.Value.String);
1279            }
1280            break;
1281
1282        case 10: /* Resource Index */
1283
1284            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1285            {
1286                Descriptor->UartSerialBus.ResSourceIndex =
1287                    (UINT8) InitializerOp->Asl.Value.Integer;
1288            }
1289            break;
1290
1291        case 11: /* Resource Usage (consumer/producer) */
1292
1293            RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1);
1294
1295            /*
1296             * Slave Mode [Flag] (_SLV)
1297             *
1298             * Note: There is no SlaveMode argument to the UartSerialBus macro, but
1299             * we add this name anyway to allow the flag to be set by ASL in the
1300             * rare case where there is a slave mode associated with the UART.
1301             */
1302            RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1303                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0);
1304            break;
1305
1306        case 12: /* Resource Tag (Descriptor Name) */
1307
1308            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1309            break;
1310
1311        case 13:
1312            /*
1313             * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1314             * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1315             * the ASL parser)
1316             */
1317            RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 2, 0);
1318            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1319                CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 2);
1320            break;
1321
1322        case 14: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1323
1324            RsGetVendorData (InitializerOp, VendorData,
1325                CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS));
1326            break;
1327
1328        default:    /* Ignore any extra nodes */
1329
1330            break;
1331        }
1332
1333        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1334    }
1335
1336    MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1337    return (Rnode);
1338}
1339