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