1207340Sjkim/******************************************************************************
2207340Sjkim *
3207340Sjkim * Module Name: aslrestype1i - Small I/O-related resource descriptors
4207340Sjkim *
5207340Sjkim *****************************************************************************/
6207340Sjkim
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9207340Sjkim * All rights reserved.
10207340Sjkim *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25207340Sjkim *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29207340Sjkim *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43207340Sjkim
44207344Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45207340Sjkim#include "aslcompiler.y.h"
46207340Sjkim
47207340Sjkim#define _COMPONENT          ACPI_COMPILER
48207340Sjkim        ACPI_MODULE_NAME    ("aslrestype1i")
49207340Sjkim
50207340Sjkim/*
51207340Sjkim * This module contains the I/O-related small resource descriptors:
52207340Sjkim *
53207340Sjkim * DMA
54228110Sjkim * FixedDMA
55207340Sjkim * FixedIO
56207340Sjkim * IO
57207340Sjkim * IRQ
58207340Sjkim * IRQNoFlags
59207340Sjkim */
60207340Sjkim
61207340Sjkim/*******************************************************************************
62207340Sjkim *
63207340Sjkim * FUNCTION:    RsDoDmaDescriptor
64207340Sjkim *
65281075Sdim * PARAMETERS:  Info                - Parse Op and resource template offset
66207340Sjkim *
67207340Sjkim * RETURN:      Completed resource node
68207340Sjkim *
69207340Sjkim * DESCRIPTION: Construct a short "DMA" descriptor
70207340Sjkim *
71207340Sjkim ******************************************************************************/
72207340Sjkim
73207340SjkimASL_RESOURCE_NODE *
74207340SjkimRsDoDmaDescriptor (
75281075Sdim    ASL_RESOURCE_INFO       *Info)
76207340Sjkim{
77207340Sjkim    AML_RESOURCE            *Descriptor;
78207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
79207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
80281075Sdim    UINT32                  CurrentByteOffset;
81207340Sjkim    UINT32                  i;
82207340Sjkim    UINT8                   DmaChannelMask = 0;
83207340Sjkim    UINT8                   DmaChannels = 0;
84207340Sjkim
85207340Sjkim
86281075Sdim    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
87281075Sdim    CurrentByteOffset = Info->CurrentByteOffset;
88207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
89207340Sjkim
90207340Sjkim    Descriptor = Rnode->Buffer;
91306536Sjkim    Descriptor->Dma.DescriptorType =
92306536Sjkim        ACPI_RESOURCE_NAME_DMA | ASL_RDESC_DMA_SIZE;
93207340Sjkim
94207340Sjkim    /* Process all child initialization nodes */
95207340Sjkim
96207340Sjkim    for (i = 0; InitializerOp; i++)
97207340Sjkim    {
98207340Sjkim        switch (i)
99207340Sjkim        {
100207340Sjkim        case 0: /* DMA type */
101207340Sjkim
102207340Sjkim            RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
103228110Sjkim            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
104228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
105207340Sjkim            break;
106207340Sjkim
107207340Sjkim        case 1: /* Bus Master */
108207340Sjkim
109207340Sjkim            RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
110207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
111207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
112207340Sjkim            break;
113207340Sjkim
114207340Sjkim        case 2: /* Xfer Type (transfer width) */
115207340Sjkim
116207340Sjkim            RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
117228110Sjkim            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
118228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
119207340Sjkim            break;
120207340Sjkim
121207340Sjkim        case 3: /* Name */
122207340Sjkim
123281075Sdim            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
124207340Sjkim            break;
125207340Sjkim
126207340Sjkim        default:
127207340Sjkim
128207340Sjkim            /* All DMA channel bytes are handled here, after flags and name */
129207340Sjkim
130207340Sjkim            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
131207340Sjkim            {
132207340Sjkim                /* Up to 8 channels can be specified in the list */
133207340Sjkim
134207340Sjkim                DmaChannels++;
135207340Sjkim                if (DmaChannels > 8)
136207340Sjkim                {
137207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
138207340Sjkim                        InitializerOp, NULL);
139207340Sjkim                    return (Rnode);
140207340Sjkim                }
141207340Sjkim
142207340Sjkim                /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
143207340Sjkim
144207340Sjkim                if (InitializerOp->Asl.Value.Integer > 7)
145207340Sjkim                {
146207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
147207340Sjkim                        InitializerOp, NULL);
148207340Sjkim                }
149207340Sjkim
150207340Sjkim                /* Build the mask */
151207340Sjkim
152207340Sjkim                DmaChannelMask |=
153207340Sjkim                    (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
154207340Sjkim            }
155207340Sjkim
156207340Sjkim            if (i == 4) /* case 4: First DMA byte */
157207340Sjkim            {
158207340Sjkim                /* Check now for duplicates in list */
159207340Sjkim
160207340Sjkim                RsCheckListForDuplicates (InitializerOp);
161207340Sjkim
162207340Sjkim                /* Create a named field at the start of the list */
163207340Sjkim
164207340Sjkim                RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
165207340Sjkim                    CurrentByteOffset +
166207340Sjkim                    ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
167207340Sjkim            }
168207340Sjkim            break;
169207340Sjkim        }
170207340Sjkim
171207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
172207340Sjkim    }
173207340Sjkim
174207340Sjkim    /* Now we can set the channel mask */
175207340Sjkim
176207340Sjkim    Descriptor->Dma.DmaChannelMask = DmaChannelMask;
177207340Sjkim    return (Rnode);
178207340Sjkim}
179207340Sjkim
180207340Sjkim
181207340Sjkim/*******************************************************************************
182207340Sjkim *
183228110Sjkim * FUNCTION:    RsDoFixedDmaDescriptor
184228110Sjkim *
185281075Sdim * PARAMETERS:  Info                - Parse Op and resource template offset
186228110Sjkim *
187228110Sjkim * RETURN:      Completed resource node
188228110Sjkim *
189228110Sjkim * DESCRIPTION: Construct a short "FixedDMA" descriptor
190228110Sjkim *
191228110Sjkim ******************************************************************************/
192228110Sjkim
193228110SjkimASL_RESOURCE_NODE *
194228110SjkimRsDoFixedDmaDescriptor (
195281075Sdim    ASL_RESOURCE_INFO       *Info)
196228110Sjkim{
197228110Sjkim    AML_RESOURCE            *Descriptor;
198228110Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
199228110Sjkim    ASL_RESOURCE_NODE       *Rnode;
200281075Sdim    UINT32                  CurrentByteOffset;
201228110Sjkim    UINT32                  i;
202228110Sjkim
203228110Sjkim
204281075Sdim    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
205281075Sdim    CurrentByteOffset = Info->CurrentByteOffset;
206228110Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
207228110Sjkim
208228110Sjkim    Descriptor = Rnode->Buffer;
209228110Sjkim    Descriptor->FixedDma.DescriptorType =
210228110Sjkim        ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
211228110Sjkim
212228110Sjkim    /* Process all child initialization nodes */
213228110Sjkim
214228110Sjkim    for (i = 0; InitializerOp; i++)
215228110Sjkim    {
216228110Sjkim        switch (i)
217228110Sjkim        {
218228110Sjkim        case 0: /* DMA Request Lines [WORD] (_DMA) */
219228110Sjkim
220228110Sjkim            Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
221228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
222228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
223228110Sjkim            break;
224228110Sjkim
225228110Sjkim        case 1: /* DMA Channel [WORD] (_TYP) */
226228110Sjkim
227228110Sjkim            Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
228228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
229228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
230228110Sjkim            break;
231228110Sjkim
232228110Sjkim        case 2: /* Transfer Width [BYTE] (_SIZ) */
233228110Sjkim
234228110Sjkim            Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
235228110Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
236228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
237228110Sjkim            break;
238228110Sjkim
239228110Sjkim        case 3: /* Descriptor Name (optional) */
240228110Sjkim
241281075Sdim            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
242228110Sjkim            break;
243228110Sjkim
244228110Sjkim        default:    /* Ignore any extra nodes */
245250838Sjkim
246228110Sjkim            break;
247228110Sjkim        }
248228110Sjkim
249228110Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
250228110Sjkim    }
251228110Sjkim
252228110Sjkim    return (Rnode);
253228110Sjkim}
254228110Sjkim
255228110Sjkim
256228110Sjkim/*******************************************************************************
257228110Sjkim *
258207340Sjkim * FUNCTION:    RsDoFixedIoDescriptor
259207340Sjkim *
260281075Sdim * PARAMETERS:  Info                - Parse Op and resource template offset
261207340Sjkim *
262207340Sjkim * RETURN:      Completed resource node
263207340Sjkim *
264207340Sjkim * DESCRIPTION: Construct a short "FixedIO" descriptor
265207340Sjkim *
266207340Sjkim ******************************************************************************/
267207340Sjkim
268207340SjkimASL_RESOURCE_NODE *
269207340SjkimRsDoFixedIoDescriptor (
270281075Sdim    ASL_RESOURCE_INFO       *Info)
271207340Sjkim{
272207340Sjkim    AML_RESOURCE            *Descriptor;
273207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
274207340Sjkim    ACPI_PARSE_OBJECT       *AddressOp = NULL;
275207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
276281075Sdim    UINT32                  CurrentByteOffset;
277207340Sjkim    UINT32                  i;
278207340Sjkim
279207340Sjkim
280281075Sdim    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
281281075Sdim    CurrentByteOffset = Info->CurrentByteOffset;
282207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
283207340Sjkim
284207340Sjkim    Descriptor = Rnode->Buffer;
285306536Sjkim    Descriptor->Io.DescriptorType =
286306536Sjkim        ACPI_RESOURCE_NAME_FIXED_IO | ASL_RDESC_FIXED_IO_SIZE;
287207340Sjkim
288207340Sjkim    /* Process all child initialization nodes */
289207340Sjkim
290207340Sjkim    for (i = 0; InitializerOp; i++)
291207340Sjkim    {
292207340Sjkim        switch (i)
293207340Sjkim        {
294207340Sjkim        case 0: /* Base Address */
295207340Sjkim
296207340Sjkim            Descriptor->FixedIo.Address =
297207340Sjkim                (UINT16) InitializerOp->Asl.Value.Integer;
298228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
299207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
300207340Sjkim            AddressOp = InitializerOp;
301207340Sjkim            break;
302207340Sjkim
303207340Sjkim        case 1: /* Length */
304207340Sjkim
305207340Sjkim            Descriptor->FixedIo.AddressLength =
306207340Sjkim                (UINT8) InitializerOp->Asl.Value.Integer;
307207340Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
308207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
309207340Sjkim            break;
310207340Sjkim
311207340Sjkim        case 2: /* Name */
312207340Sjkim
313281075Sdim            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
314207340Sjkim            break;
315207340Sjkim
316207340Sjkim        default:
317207340Sjkim
318207340Sjkim            AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
319207340Sjkim            break;
320207340Sjkim        }
321207340Sjkim
322207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
323207340Sjkim    }
324207340Sjkim
325207340Sjkim    /* Error checks */
326207340Sjkim
327207340Sjkim    if (Descriptor->FixedIo.Address > 0x03FF)
328207340Sjkim    {
329207340Sjkim        AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
330207340Sjkim    }
331207340Sjkim
332207340Sjkim    return (Rnode);
333207340Sjkim}
334207340Sjkim
335207340Sjkim
336207340Sjkim/*******************************************************************************
337207340Sjkim *
338207340Sjkim * FUNCTION:    RsDoIoDescriptor
339207340Sjkim *
340281075Sdim * PARAMETERS:  Info                - Parse Op and resource template offset
341207340Sjkim *
342207340Sjkim * RETURN:      Completed resource node
343207340Sjkim *
344207340Sjkim * DESCRIPTION: Construct a short "IO" descriptor
345207340Sjkim *
346207340Sjkim ******************************************************************************/
347207340Sjkim
348207340SjkimASL_RESOURCE_NODE *
349207340SjkimRsDoIoDescriptor (
350281075Sdim    ASL_RESOURCE_INFO       *Info)
351207340Sjkim{
352207340Sjkim    AML_RESOURCE            *Descriptor;
353207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
354207340Sjkim    ACPI_PARSE_OBJECT       *MinOp = NULL;
355207340Sjkim    ACPI_PARSE_OBJECT       *MaxOp = NULL;
356207340Sjkim    ACPI_PARSE_OBJECT       *LengthOp = NULL;
357207340Sjkim    ACPI_PARSE_OBJECT       *AlignOp = NULL;
358207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
359281075Sdim    UINT32                  CurrentByteOffset;
360207340Sjkim    UINT32                  i;
361207340Sjkim
362207340Sjkim
363281075Sdim    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
364281075Sdim    CurrentByteOffset = Info->CurrentByteOffset;
365207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
366207340Sjkim
367207340Sjkim    Descriptor = Rnode->Buffer;
368306536Sjkim    Descriptor->Io.DescriptorType =
369306536Sjkim        ACPI_RESOURCE_NAME_IO | ASL_RDESC_IO_SIZE;
370207340Sjkim
371207340Sjkim    /* Process all child initialization nodes */
372207340Sjkim
373207340Sjkim    for (i = 0; InitializerOp; i++)
374207340Sjkim    {
375207340Sjkim        switch (i)
376207340Sjkim        {
377207340Sjkim        case 0: /* Decode size */
378207340Sjkim
379207340Sjkim            RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
380207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
381207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
382207340Sjkim            break;
383207340Sjkim
384207340Sjkim        case 1:  /* Min Address */
385207340Sjkim
386207340Sjkim            Descriptor->Io.Minimum =
387207340Sjkim                (UINT16) InitializerOp->Asl.Value.Integer;
388228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
389207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
390207340Sjkim            MinOp = InitializerOp;
391207340Sjkim            break;
392207340Sjkim
393207340Sjkim        case 2: /* Max Address */
394207340Sjkim
395207340Sjkim            Descriptor->Io.Maximum =
396207340Sjkim                (UINT16) InitializerOp->Asl.Value.Integer;
397228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
398207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
399207340Sjkim            MaxOp = InitializerOp;
400207340Sjkim            break;
401207340Sjkim
402207340Sjkim        case 3: /* Alignment */
403207340Sjkim
404207340Sjkim            Descriptor->Io.Alignment =
405207340Sjkim                (UINT8) InitializerOp->Asl.Value.Integer;
406207340Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
407207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
408207340Sjkim            AlignOp = InitializerOp;
409207340Sjkim            break;
410207340Sjkim
411207340Sjkim        case 4: /* Length */
412207340Sjkim
413207340Sjkim            Descriptor->Io.AddressLength =
414207340Sjkim                (UINT8) InitializerOp->Asl.Value.Integer;
415207340Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
416207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
417207340Sjkim            LengthOp = InitializerOp;
418207340Sjkim            break;
419207340Sjkim
420207340Sjkim        case 5: /* Name */
421207340Sjkim
422281075Sdim            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
423207340Sjkim            break;
424207340Sjkim
425207340Sjkim        default:
426207340Sjkim
427207340Sjkim            AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
428207340Sjkim            break;
429207340Sjkim        }
430207340Sjkim
431207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
432207340Sjkim    }
433207340Sjkim
434207340Sjkim    /* Validate the Min/Max/Len/Align values */
435207340Sjkim
436207340Sjkim    RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
437207340Sjkim        Descriptor->Io.Minimum,
438207340Sjkim        Descriptor->Io.Maximum,
439207340Sjkim        Descriptor->Io.AddressLength,
440207340Sjkim        Descriptor->Io.Alignment,
441281075Sdim        MinOp, MaxOp, LengthOp, AlignOp, Info->DescriptorTypeOp);
442207340Sjkim
443207340Sjkim    return (Rnode);
444207340Sjkim}
445207340Sjkim
446207340Sjkim
447207340Sjkim/*******************************************************************************
448207340Sjkim *
449207340Sjkim * FUNCTION:    RsDoIrqDescriptor
450207340Sjkim *
451281075Sdim * PARAMETERS:  Info                - Parse Op and resource template offset
452207340Sjkim *
453207340Sjkim * RETURN:      Completed resource node
454207340Sjkim *
455207340Sjkim * DESCRIPTION: Construct a short "IRQ" descriptor
456207340Sjkim *
457207340Sjkim ******************************************************************************/
458207340Sjkim
459207340SjkimASL_RESOURCE_NODE *
460207340SjkimRsDoIrqDescriptor (
461281075Sdim    ASL_RESOURCE_INFO       *Info)
462207340Sjkim{
463207340Sjkim    AML_RESOURCE            *Descriptor;
464207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
465207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
466207340Sjkim    UINT32                  Interrupts = 0;
467207340Sjkim    UINT16                  IrqMask = 0;
468281075Sdim    UINT32                  CurrentByteOffset;
469207340Sjkim    UINT32                  i;
470207340Sjkim
471207340Sjkim
472281075Sdim    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
473281075Sdim    CurrentByteOffset = Info->CurrentByteOffset;
474207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
475207340Sjkim
476207340Sjkim    /* Length = 3 (with flag byte) */
477207340Sjkim
478207340Sjkim    Descriptor = Rnode->Buffer;
479306536Sjkim    Descriptor->Irq.DescriptorType =
480306536Sjkim        ACPI_RESOURCE_NAME_IRQ | (ASL_RDESC_IRQ_SIZE + 0x01);
481207340Sjkim
482207340Sjkim    /* Process all child initialization nodes */
483207340Sjkim
484207340Sjkim    for (i = 0; InitializerOp; i++)
485207340Sjkim    {
486207340Sjkim        switch (i)
487207340Sjkim        {
488207340Sjkim        case 0: /* Interrupt Type (or Mode - edge/level) */
489207340Sjkim
490207340Sjkim            RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
491207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
492207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
493207340Sjkim            break;
494207340Sjkim
495207340Sjkim        case 1: /* Interrupt Level (or Polarity - Active high/low) */
496207340Sjkim
497207340Sjkim            RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
498207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
499207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
500207340Sjkim            break;
501207340Sjkim
502207340Sjkim        case 2: /* Share Type - Default: exclusive (0) */
503207340Sjkim
504207340Sjkim            RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
505207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
506207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
507207340Sjkim            break;
508207340Sjkim
509207340Sjkim        case 3: /* Name */
510207340Sjkim
511281075Sdim            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
512207340Sjkim            break;
513207340Sjkim
514207340Sjkim        default:
515207340Sjkim
516207340Sjkim            /* All IRQ bytes are handled here, after the flags and name */
517207340Sjkim
518207340Sjkim            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
519207340Sjkim            {
520207340Sjkim                /* Up to 16 interrupts can be specified in the list */
521207340Sjkim
522207340Sjkim                Interrupts++;
523207340Sjkim                if (Interrupts > 16)
524207340Sjkim                {
525207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
526207340Sjkim                        InitializerOp, NULL);
527207340Sjkim                    return (Rnode);
528207340Sjkim                }
529207340Sjkim
530207340Sjkim                /* Only interrupts 0-15 are allowed (mask is 16 bits) */
531207340Sjkim
532207340Sjkim                if (InitializerOp->Asl.Value.Integer > 15)
533207340Sjkim                {
534207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
535207340Sjkim                        InitializerOp, NULL);
536207340Sjkim                }
537207340Sjkim                else
538207340Sjkim                {
539207340Sjkim                    IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
540207340Sjkim                }
541207340Sjkim            }
542207340Sjkim
543207340Sjkim            /* Case 4: First IRQ value in list */
544207340Sjkim
545207340Sjkim            if (i == 4)
546207340Sjkim            {
547207340Sjkim                /* Check now for duplicates in list */
548207340Sjkim
549207340Sjkim                RsCheckListForDuplicates (InitializerOp);
550207340Sjkim
551207340Sjkim                /* Create a named field at the start of the list */
552207340Sjkim
553228110Sjkim                RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
554207340Sjkim                    CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
555207340Sjkim            }
556207340Sjkim            break;
557207340Sjkim        }
558207340Sjkim
559207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
560207340Sjkim    }
561207340Sjkim
562207340Sjkim    /* Now we can set the channel mask */
563207340Sjkim
564207340Sjkim    Descriptor->Irq.IrqMask = IrqMask;
565207340Sjkim    return (Rnode);
566207340Sjkim}
567207340Sjkim
568207340Sjkim
569207340Sjkim/*******************************************************************************
570207340Sjkim *
571207340Sjkim * FUNCTION:    RsDoIrqNoFlagsDescriptor
572207340Sjkim *
573281075Sdim * PARAMETERS:  Info                - Parse Op and resource template offset
574207340Sjkim *
575207340Sjkim * RETURN:      Completed resource node
576207340Sjkim *
577207340Sjkim * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
578207340Sjkim *
579207340Sjkim ******************************************************************************/
580207340Sjkim
581207340SjkimASL_RESOURCE_NODE *
582207340SjkimRsDoIrqNoFlagsDescriptor (
583281075Sdim    ASL_RESOURCE_INFO       *Info)
584207340Sjkim{
585207340Sjkim    AML_RESOURCE            *Descriptor;
586207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
587207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
588207340Sjkim    UINT16                  IrqMask = 0;
589207340Sjkim    UINT32                  Interrupts = 0;
590281075Sdim    UINT32                  CurrentByteOffset;
591207340Sjkim    UINT32                  i;
592207340Sjkim
593207340Sjkim
594281075Sdim    InitializerOp = Info->DescriptorTypeOp->Asl.Child;
595281075Sdim    CurrentByteOffset = Info->CurrentByteOffset;
596207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
597207340Sjkim
598207340Sjkim    Descriptor = Rnode->Buffer;
599306536Sjkim    Descriptor->Irq.DescriptorType =
600306536Sjkim        ACPI_RESOURCE_NAME_IRQ | ASL_RDESC_IRQ_SIZE;
601207340Sjkim
602207340Sjkim    /* Process all child initialization nodes */
603207340Sjkim
604207340Sjkim    for (i = 0; InitializerOp; i++)
605207340Sjkim    {
606207340Sjkim        switch (i)
607207340Sjkim        {
608207340Sjkim        case 0: /* Name */
609207340Sjkim
610281075Sdim            UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
611207340Sjkim            break;
612207340Sjkim
613207340Sjkim        default:
614207340Sjkim
615207340Sjkim            /* IRQ bytes are handled here, after the flags and name */
616207340Sjkim
617207340Sjkim            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
618207340Sjkim            {
619207340Sjkim                /* Up to 16 interrupts can be specified in the list */
620207340Sjkim
621207340Sjkim                Interrupts++;
622207340Sjkim                if (Interrupts > 16)
623207340Sjkim                {
624207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
625207340Sjkim                        InitializerOp, NULL);
626207340Sjkim                    return (Rnode);
627207340Sjkim                }
628207340Sjkim
629207340Sjkim                /* Only interrupts 0-15 are allowed (mask is 16 bits) */
630207340Sjkim
631207340Sjkim                if (InitializerOp->Asl.Value.Integer > 15)
632207340Sjkim                {
633207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
634207340Sjkim                        InitializerOp, NULL);
635207340Sjkim                }
636207340Sjkim                else
637207340Sjkim                {
638207340Sjkim                    IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
639207340Sjkim                }
640207340Sjkim            }
641207340Sjkim
642207340Sjkim            /* Case 1: First IRQ value in list */
643207340Sjkim
644207340Sjkim            if (i == 1)
645207340Sjkim            {
646207340Sjkim                /* Check now for duplicates in list */
647207340Sjkim
648207340Sjkim                RsCheckListForDuplicates (InitializerOp);
649207340Sjkim
650207340Sjkim                /* Create a named field at the start of the list */
651207340Sjkim
652228110Sjkim                RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
653207340Sjkim                    CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
654207340Sjkim            }
655207340Sjkim            break;
656207340Sjkim        }
657207340Sjkim
658207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
659207340Sjkim    }
660207340Sjkim
661207340Sjkim    /* Now we can set the interrupt mask */
662207340Sjkim
663207340Sjkim    Descriptor->Irq.IrqMask = IrqMask;
664207340Sjkim    return (Rnode);
665207340Sjkim}
666