1207340Sjkim/******************************************************************************
2207340Sjkim *
3207340Sjkim * Module Name: aslrestype1i - Small I/O-related resource descriptors
4207340Sjkim *
5207340Sjkim *****************************************************************************/
6207340Sjkim
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, 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
44207340Sjkim
45207344Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
46207340Sjkim#include "aslcompiler.y.h"
47207340Sjkim
48207340Sjkim#define _COMPONENT          ACPI_COMPILER
49207340Sjkim        ACPI_MODULE_NAME    ("aslrestype1i")
50207340Sjkim
51207340Sjkim/*
52207340Sjkim * This module contains the I/O-related small resource descriptors:
53207340Sjkim *
54207340Sjkim * DMA
55228110Sjkim * FixedDMA
56207340Sjkim * FixedIO
57207340Sjkim * IO
58207340Sjkim * IRQ
59207340Sjkim * IRQNoFlags
60207340Sjkim */
61207340Sjkim
62207340Sjkim/*******************************************************************************
63207340Sjkim *
64207340Sjkim * FUNCTION:    RsDoDmaDescriptor
65207340Sjkim *
66207340Sjkim * PARAMETERS:  Op                  - Parent resource descriptor parse node
67207340Sjkim *              CurrentByteOffset   - Offset into the resource template AML
68207340Sjkim *                                    buffer (to track references to the desc)
69207340Sjkim *
70207340Sjkim * RETURN:      Completed resource node
71207340Sjkim *
72207340Sjkim * DESCRIPTION: Construct a short "DMA" descriptor
73207340Sjkim *
74207340Sjkim ******************************************************************************/
75207340Sjkim
76207340SjkimASL_RESOURCE_NODE *
77207340SjkimRsDoDmaDescriptor (
78207340Sjkim    ACPI_PARSE_OBJECT       *Op,
79207340Sjkim    UINT32                  CurrentByteOffset)
80207340Sjkim{
81207340Sjkim    AML_RESOURCE            *Descriptor;
82207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
83207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
84207340Sjkim    UINT32                  i;
85207340Sjkim    UINT8                   DmaChannelMask = 0;
86207340Sjkim    UINT8                   DmaChannels = 0;
87207340Sjkim
88207340Sjkim
89207340Sjkim    InitializerOp = Op->Asl.Child;
90207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
91207340Sjkim
92207340Sjkim    Descriptor = Rnode->Buffer;
93207340Sjkim    Descriptor->Dma.DescriptorType  = ACPI_RESOURCE_NAME_DMA |
94207340Sjkim                                        ASL_RDESC_DMA_SIZE;
95207340Sjkim
96207340Sjkim    /* Process all child initialization nodes */
97207340Sjkim
98207340Sjkim    for (i = 0; InitializerOp; i++)
99207340Sjkim    {
100207340Sjkim        switch (i)
101207340Sjkim        {
102207340Sjkim        case 0: /* DMA type */
103207340Sjkim
104207340Sjkim            RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
105228110Sjkim            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
106228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
107207340Sjkim            break;
108207340Sjkim
109207340Sjkim        case 1: /* Bus Master */
110207340Sjkim
111207340Sjkim            RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
112207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
113207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
114207340Sjkim            break;
115207340Sjkim
116207340Sjkim        case 2: /* Xfer Type (transfer width) */
117207340Sjkim
118207340Sjkim            RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
119228110Sjkim            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
120228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
121207340Sjkim            break;
122207340Sjkim
123207340Sjkim        case 3: /* Name */
124207340Sjkim
125207340Sjkim            UtAttachNamepathToOwner (Op, InitializerOp);
126207340Sjkim            break;
127207340Sjkim
128207340Sjkim        default:
129207340Sjkim
130207340Sjkim            /* All DMA channel bytes are handled here, after flags and name */
131207340Sjkim
132207340Sjkim            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
133207340Sjkim            {
134207340Sjkim                /* Up to 8 channels can be specified in the list */
135207340Sjkim
136207340Sjkim                DmaChannels++;
137207340Sjkim                if (DmaChannels > 8)
138207340Sjkim                {
139207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
140207340Sjkim                        InitializerOp, NULL);
141207340Sjkim                    return (Rnode);
142207340Sjkim                }
143207340Sjkim
144207340Sjkim                /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
145207340Sjkim
146207340Sjkim                if (InitializerOp->Asl.Value.Integer > 7)
147207340Sjkim                {
148207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
149207340Sjkim                        InitializerOp, NULL);
150207340Sjkim                }
151207340Sjkim
152207340Sjkim                /* Build the mask */
153207340Sjkim
154207340Sjkim                DmaChannelMask |=
155207340Sjkim                    (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
156207340Sjkim            }
157207340Sjkim
158207340Sjkim            if (i == 4) /* case 4: First DMA byte */
159207340Sjkim            {
160207340Sjkim                /* Check now for duplicates in list */
161207340Sjkim
162207340Sjkim                RsCheckListForDuplicates (InitializerOp);
163207340Sjkim
164207340Sjkim                /* Create a named field at the start of the list */
165207340Sjkim
166207340Sjkim                RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
167207340Sjkim                    CurrentByteOffset +
168207340Sjkim                    ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
169207340Sjkim            }
170207340Sjkim            break;
171207340Sjkim        }
172207340Sjkim
173207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
174207340Sjkim    }
175207340Sjkim
176207340Sjkim    /* Now we can set the channel mask */
177207340Sjkim
178207340Sjkim    Descriptor->Dma.DmaChannelMask = DmaChannelMask;
179207340Sjkim    return (Rnode);
180207340Sjkim}
181207340Sjkim
182207340Sjkim
183207340Sjkim/*******************************************************************************
184207340Sjkim *
185228110Sjkim * FUNCTION:    RsDoFixedDmaDescriptor
186228110Sjkim *
187228110Sjkim * PARAMETERS:  Op                  - Parent resource descriptor parse node
188228110Sjkim *              CurrentByteOffset   - Offset into the resource template AML
189228110Sjkim *                                    buffer (to track references to the desc)
190228110Sjkim *
191228110Sjkim * RETURN:      Completed resource node
192228110Sjkim *
193228110Sjkim * DESCRIPTION: Construct a short "FixedDMA" descriptor
194228110Sjkim *
195228110Sjkim ******************************************************************************/
196228110Sjkim
197228110SjkimASL_RESOURCE_NODE *
198228110SjkimRsDoFixedDmaDescriptor (
199228110Sjkim    ACPI_PARSE_OBJECT       *Op,
200228110Sjkim    UINT32                  CurrentByteOffset)
201228110Sjkim{
202228110Sjkim    AML_RESOURCE            *Descriptor;
203228110Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
204228110Sjkim    ASL_RESOURCE_NODE       *Rnode;
205228110Sjkim    UINT32                  i;
206228110Sjkim
207228110Sjkim
208228110Sjkim    InitializerOp = Op->Asl.Child;
209228110Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
210228110Sjkim
211228110Sjkim    Descriptor = Rnode->Buffer;
212228110Sjkim    Descriptor->FixedDma.DescriptorType =
213228110Sjkim        ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
214228110Sjkim
215228110Sjkim    /* Process all child initialization nodes */
216228110Sjkim
217228110Sjkim    for (i = 0; InitializerOp; i++)
218228110Sjkim    {
219228110Sjkim        switch (i)
220228110Sjkim        {
221228110Sjkim        case 0: /* DMA Request Lines [WORD] (_DMA) */
222228110Sjkim
223228110Sjkim            Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
224228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
225228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
226228110Sjkim            break;
227228110Sjkim
228228110Sjkim        case 1: /* DMA Channel [WORD] (_TYP) */
229228110Sjkim
230228110Sjkim            Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
231228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
232228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
233228110Sjkim            break;
234228110Sjkim
235228110Sjkim        case 2: /* Transfer Width [BYTE] (_SIZ) */
236228110Sjkim
237228110Sjkim            Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
238228110Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
239228110Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
240228110Sjkim            break;
241228110Sjkim
242228110Sjkim        case 3: /* Descriptor Name (optional) */
243228110Sjkim
244228110Sjkim            UtAttachNamepathToOwner (Op, InitializerOp);
245228110Sjkim            break;
246228110Sjkim
247228110Sjkim        default:    /* Ignore any extra nodes */
248250838Sjkim
249228110Sjkim            break;
250228110Sjkim        }
251228110Sjkim
252228110Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
253228110Sjkim    }
254228110Sjkim
255228110Sjkim    return (Rnode);
256228110Sjkim}
257228110Sjkim
258228110Sjkim
259228110Sjkim/*******************************************************************************
260228110Sjkim *
261207340Sjkim * FUNCTION:    RsDoFixedIoDescriptor
262207340Sjkim *
263207340Sjkim * PARAMETERS:  Op                  - Parent resource descriptor parse node
264207340Sjkim *              CurrentByteOffset   - Offset into the resource template AML
265207340Sjkim *                                    buffer (to track references to the desc)
266207340Sjkim *
267207340Sjkim * RETURN:      Completed resource node
268207340Sjkim *
269207340Sjkim * DESCRIPTION: Construct a short "FixedIO" descriptor
270207340Sjkim *
271207340Sjkim ******************************************************************************/
272207340Sjkim
273207340SjkimASL_RESOURCE_NODE *
274207340SjkimRsDoFixedIoDescriptor (
275207340Sjkim    ACPI_PARSE_OBJECT       *Op,
276207340Sjkim    UINT32                  CurrentByteOffset)
277207340Sjkim{
278207340Sjkim    AML_RESOURCE            *Descriptor;
279207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
280207340Sjkim    ACPI_PARSE_OBJECT       *AddressOp = NULL;
281207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
282207340Sjkim    UINT32                  i;
283207340Sjkim
284207340Sjkim
285207340Sjkim    InitializerOp = Op->Asl.Child;
286207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
287207340Sjkim
288207340Sjkim    Descriptor = Rnode->Buffer;
289207340Sjkim    Descriptor->Io.DescriptorType  = ACPI_RESOURCE_NAME_FIXED_IO |
290207340Sjkim                                      ASL_RDESC_FIXED_IO_SIZE;
291207340Sjkim
292207340Sjkim    /* Process all child initialization nodes */
293207340Sjkim
294207340Sjkim    for (i = 0; InitializerOp; i++)
295207340Sjkim    {
296207340Sjkim        switch (i)
297207340Sjkim        {
298207340Sjkim        case 0: /* Base Address */
299207340Sjkim
300207340Sjkim            Descriptor->FixedIo.Address =
301207340Sjkim                (UINT16) InitializerOp->Asl.Value.Integer;
302228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
303207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
304207340Sjkim            AddressOp = InitializerOp;
305207340Sjkim            break;
306207340Sjkim
307207340Sjkim        case 1: /* Length */
308207340Sjkim
309207340Sjkim            Descriptor->FixedIo.AddressLength =
310207340Sjkim                (UINT8) InitializerOp->Asl.Value.Integer;
311207340Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
312207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
313207340Sjkim            break;
314207340Sjkim
315207340Sjkim        case 2: /* Name */
316207340Sjkim
317207340Sjkim            UtAttachNamepathToOwner (Op, InitializerOp);
318207340Sjkim            break;
319207340Sjkim
320207340Sjkim        default:
321207340Sjkim
322207340Sjkim            AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
323207340Sjkim            break;
324207340Sjkim        }
325207340Sjkim
326207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
327207340Sjkim    }
328207340Sjkim
329207340Sjkim    /* Error checks */
330207340Sjkim
331207340Sjkim    if (Descriptor->FixedIo.Address > 0x03FF)
332207340Sjkim    {
333207340Sjkim        AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
334207340Sjkim    }
335207340Sjkim
336207340Sjkim    return (Rnode);
337207340Sjkim}
338207340Sjkim
339207340Sjkim
340207340Sjkim/*******************************************************************************
341207340Sjkim *
342207340Sjkim * FUNCTION:    RsDoIoDescriptor
343207340Sjkim *
344207340Sjkim * PARAMETERS:  Op                  - Parent resource descriptor parse node
345207340Sjkim *              CurrentByteOffset   - Offset into the resource template AML
346207340Sjkim *                                    buffer (to track references to the desc)
347207340Sjkim *
348207340Sjkim * RETURN:      Completed resource node
349207340Sjkim *
350207340Sjkim * DESCRIPTION: Construct a short "IO" descriptor
351207340Sjkim *
352207340Sjkim ******************************************************************************/
353207340Sjkim
354207340SjkimASL_RESOURCE_NODE *
355207340SjkimRsDoIoDescriptor (
356207340Sjkim    ACPI_PARSE_OBJECT       *Op,
357207340Sjkim    UINT32                  CurrentByteOffset)
358207340Sjkim{
359207340Sjkim    AML_RESOURCE            *Descriptor;
360207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
361207340Sjkim    ACPI_PARSE_OBJECT       *MinOp = NULL;
362207340Sjkim    ACPI_PARSE_OBJECT       *MaxOp = NULL;
363207340Sjkim    ACPI_PARSE_OBJECT       *LengthOp = NULL;
364207340Sjkim    ACPI_PARSE_OBJECT       *AlignOp = NULL;
365207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
366207340Sjkim    UINT32                  i;
367207340Sjkim
368207340Sjkim
369207340Sjkim    InitializerOp = Op->Asl.Child;
370207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
371207340Sjkim
372207340Sjkim    Descriptor = Rnode->Buffer;
373207340Sjkim    Descriptor->Io.DescriptorType  = ACPI_RESOURCE_NAME_IO |
374207340Sjkim                                      ASL_RDESC_IO_SIZE;
375207340Sjkim
376207340Sjkim    /* Process all child initialization nodes */
377207340Sjkim
378207340Sjkim    for (i = 0; InitializerOp; i++)
379207340Sjkim    {
380207340Sjkim        switch (i)
381207340Sjkim        {
382207340Sjkim        case 0: /* Decode size */
383207340Sjkim
384207340Sjkim            RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
385207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
386207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
387207340Sjkim            break;
388207340Sjkim
389207340Sjkim        case 1:  /* Min Address */
390207340Sjkim
391207340Sjkim            Descriptor->Io.Minimum =
392207340Sjkim                (UINT16) InitializerOp->Asl.Value.Integer;
393228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
394207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
395207340Sjkim            MinOp = InitializerOp;
396207340Sjkim            break;
397207340Sjkim
398207340Sjkim        case 2: /* Max Address */
399207340Sjkim
400207340Sjkim            Descriptor->Io.Maximum =
401207340Sjkim                (UINT16) InitializerOp->Asl.Value.Integer;
402228110Sjkim            RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
403207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
404207340Sjkim            MaxOp = InitializerOp;
405207340Sjkim            break;
406207340Sjkim
407207340Sjkim        case 3: /* Alignment */
408207340Sjkim
409207340Sjkim            Descriptor->Io.Alignment =
410207340Sjkim                (UINT8) InitializerOp->Asl.Value.Integer;
411207340Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
412207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
413207340Sjkim            AlignOp = InitializerOp;
414207340Sjkim            break;
415207340Sjkim
416207340Sjkim        case 4: /* Length */
417207340Sjkim
418207340Sjkim            Descriptor->Io.AddressLength =
419207340Sjkim                (UINT8) InitializerOp->Asl.Value.Integer;
420207340Sjkim            RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
421207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
422207340Sjkim            LengthOp = InitializerOp;
423207340Sjkim            break;
424207340Sjkim
425207340Sjkim        case 5: /* Name */
426207340Sjkim
427207340Sjkim            UtAttachNamepathToOwner (Op, InitializerOp);
428207340Sjkim            break;
429207340Sjkim
430207340Sjkim        default:
431207340Sjkim
432207340Sjkim            AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
433207340Sjkim            break;
434207340Sjkim        }
435207340Sjkim
436207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
437207340Sjkim    }
438207340Sjkim
439207340Sjkim    /* Validate the Min/Max/Len/Align values */
440207340Sjkim
441207340Sjkim    RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
442207340Sjkim        Descriptor->Io.Minimum,
443207340Sjkim        Descriptor->Io.Maximum,
444207340Sjkim        Descriptor->Io.AddressLength,
445207340Sjkim        Descriptor->Io.Alignment,
446213806Sjkim        MinOp, MaxOp, LengthOp, AlignOp, Op);
447207340Sjkim
448207340Sjkim    return (Rnode);
449207340Sjkim}
450207340Sjkim
451207340Sjkim
452207340Sjkim/*******************************************************************************
453207340Sjkim *
454207340Sjkim * FUNCTION:    RsDoIrqDescriptor
455207340Sjkim *
456207340Sjkim * PARAMETERS:  Op                  - Parent resource descriptor parse node
457207340Sjkim *              CurrentByteOffset   - Offset into the resource template AML
458207340Sjkim *                                    buffer (to track references to the desc)
459207340Sjkim *
460207340Sjkim * RETURN:      Completed resource node
461207340Sjkim *
462207340Sjkim * DESCRIPTION: Construct a short "IRQ" descriptor
463207340Sjkim *
464207340Sjkim ******************************************************************************/
465207340Sjkim
466207340SjkimASL_RESOURCE_NODE *
467207340SjkimRsDoIrqDescriptor (
468207340Sjkim    ACPI_PARSE_OBJECT       *Op,
469207340Sjkim    UINT32                  CurrentByteOffset)
470207340Sjkim{
471207340Sjkim    AML_RESOURCE            *Descriptor;
472207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
473207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
474207340Sjkim    UINT32                  Interrupts = 0;
475207340Sjkim    UINT16                  IrqMask = 0;
476207340Sjkim    UINT32                  i;
477207340Sjkim
478207340Sjkim
479207340Sjkim    InitializerOp = Op->Asl.Child;
480207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
481207340Sjkim
482207340Sjkim    /* Length = 3 (with flag byte) */
483207340Sjkim
484207340Sjkim    Descriptor = Rnode->Buffer;
485207340Sjkim    Descriptor->Irq.DescriptorType  = ACPI_RESOURCE_NAME_IRQ |
486207340Sjkim                                      (ASL_RDESC_IRQ_SIZE + 0x01);
487207340Sjkim
488207340Sjkim    /* Process all child initialization nodes */
489207340Sjkim
490207340Sjkim    for (i = 0; InitializerOp; i++)
491207340Sjkim    {
492207340Sjkim        switch (i)
493207340Sjkim        {
494207340Sjkim        case 0: /* Interrupt Type (or Mode - edge/level) */
495207340Sjkim
496207340Sjkim            RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
497207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
498207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
499207340Sjkim            break;
500207340Sjkim
501207340Sjkim        case 1: /* Interrupt Level (or Polarity - Active high/low) */
502207340Sjkim
503207340Sjkim            RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
504207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
505207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
506207340Sjkim            break;
507207340Sjkim
508207340Sjkim        case 2: /* Share Type - Default: exclusive (0) */
509207340Sjkim
510207340Sjkim            RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
511207340Sjkim            RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
512207340Sjkim                CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
513207340Sjkim            break;
514207340Sjkim
515207340Sjkim        case 3: /* Name */
516207340Sjkim
517207340Sjkim            UtAttachNamepathToOwner (Op, InitializerOp);
518207340Sjkim            break;
519207340Sjkim
520207340Sjkim        default:
521207340Sjkim
522207340Sjkim            /* All IRQ bytes are handled here, after the flags and name */
523207340Sjkim
524207340Sjkim            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
525207340Sjkim            {
526207340Sjkim                /* Up to 16 interrupts can be specified in the list */
527207340Sjkim
528207340Sjkim                Interrupts++;
529207340Sjkim                if (Interrupts > 16)
530207340Sjkim                {
531207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
532207340Sjkim                        InitializerOp, NULL);
533207340Sjkim                    return (Rnode);
534207340Sjkim                }
535207340Sjkim
536207340Sjkim                /* Only interrupts 0-15 are allowed (mask is 16 bits) */
537207340Sjkim
538207340Sjkim                if (InitializerOp->Asl.Value.Integer > 15)
539207340Sjkim                {
540207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
541207340Sjkim                        InitializerOp, NULL);
542207340Sjkim                }
543207340Sjkim                else
544207340Sjkim                {
545207340Sjkim                    IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
546207340Sjkim                }
547207340Sjkim            }
548207340Sjkim
549207340Sjkim            /* Case 4: First IRQ value in list */
550207340Sjkim
551207340Sjkim            if (i == 4)
552207340Sjkim            {
553207340Sjkim                /* Check now for duplicates in list */
554207340Sjkim
555207340Sjkim                RsCheckListForDuplicates (InitializerOp);
556207340Sjkim
557207340Sjkim                /* Create a named field at the start of the list */
558207340Sjkim
559228110Sjkim                RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
560207340Sjkim                    CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
561207340Sjkim            }
562207340Sjkim            break;
563207340Sjkim        }
564207340Sjkim
565207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
566207340Sjkim    }
567207340Sjkim
568207340Sjkim    /* Now we can set the channel mask */
569207340Sjkim
570207340Sjkim    Descriptor->Irq.IrqMask = IrqMask;
571207340Sjkim    return (Rnode);
572207340Sjkim}
573207340Sjkim
574207340Sjkim
575207340Sjkim/*******************************************************************************
576207340Sjkim *
577207340Sjkim * FUNCTION:    RsDoIrqNoFlagsDescriptor
578207340Sjkim *
579207340Sjkim * PARAMETERS:  Op                  - Parent resource descriptor parse node
580207340Sjkim *              CurrentByteOffset   - Offset into the resource template AML
581207340Sjkim *                                    buffer (to track references to the desc)
582207340Sjkim *
583207340Sjkim * RETURN:      Completed resource node
584207340Sjkim *
585207340Sjkim * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
586207340Sjkim *
587207340Sjkim ******************************************************************************/
588207340Sjkim
589207340SjkimASL_RESOURCE_NODE *
590207340SjkimRsDoIrqNoFlagsDescriptor (
591207340Sjkim    ACPI_PARSE_OBJECT       *Op,
592207340Sjkim    UINT32                  CurrentByteOffset)
593207340Sjkim{
594207340Sjkim    AML_RESOURCE            *Descriptor;
595207340Sjkim    ACPI_PARSE_OBJECT       *InitializerOp;
596207340Sjkim    ASL_RESOURCE_NODE       *Rnode;
597207340Sjkim    UINT16                  IrqMask = 0;
598207340Sjkim    UINT32                  Interrupts = 0;
599207340Sjkim    UINT32                  i;
600207340Sjkim
601207340Sjkim
602207340Sjkim    InitializerOp = Op->Asl.Child;
603207340Sjkim    Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
604207340Sjkim
605207340Sjkim    Descriptor = Rnode->Buffer;
606207340Sjkim    Descriptor->Irq.DescriptorType  = ACPI_RESOURCE_NAME_IRQ |
607207340Sjkim                                      ASL_RDESC_IRQ_SIZE;
608207340Sjkim
609207340Sjkim    /* Process all child initialization nodes */
610207340Sjkim
611207340Sjkim    for (i = 0; InitializerOp; i++)
612207340Sjkim    {
613207340Sjkim        switch (i)
614207340Sjkim        {
615207340Sjkim        case 0: /* Name */
616207340Sjkim
617207340Sjkim            UtAttachNamepathToOwner (Op, InitializerOp);
618207340Sjkim            break;
619207340Sjkim
620207340Sjkim        default:
621207340Sjkim
622207340Sjkim            /* IRQ bytes are handled here, after the flags and name */
623207340Sjkim
624207340Sjkim            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
625207340Sjkim            {
626207340Sjkim                /* Up to 16 interrupts can be specified in the list */
627207340Sjkim
628207340Sjkim                Interrupts++;
629207340Sjkim                if (Interrupts > 16)
630207340Sjkim                {
631207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
632207340Sjkim                        InitializerOp, NULL);
633207340Sjkim                    return (Rnode);
634207340Sjkim                }
635207340Sjkim
636207340Sjkim                /* Only interrupts 0-15 are allowed (mask is 16 bits) */
637207340Sjkim
638207340Sjkim                if (InitializerOp->Asl.Value.Integer > 15)
639207340Sjkim                {
640207340Sjkim                    AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
641207340Sjkim                        InitializerOp, NULL);
642207340Sjkim                }
643207340Sjkim                else
644207340Sjkim                {
645207340Sjkim                    IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
646207340Sjkim                }
647207340Sjkim            }
648207340Sjkim
649207340Sjkim            /* Case 1: First IRQ value in list */
650207340Sjkim
651207340Sjkim            if (i == 1)
652207340Sjkim            {
653207340Sjkim                /* Check now for duplicates in list */
654207340Sjkim
655207340Sjkim                RsCheckListForDuplicates (InitializerOp);
656207340Sjkim
657207340Sjkim                /* Create a named field at the start of the list */
658207340Sjkim
659228110Sjkim                RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
660207340Sjkim                    CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
661207340Sjkim            }
662207340Sjkim            break;
663207340Sjkim        }
664207340Sjkim
665207340Sjkim        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
666207340Sjkim    }
667207340Sjkim
668207340Sjkim    /* Now we can set the interrupt mask */
669207340Sjkim
670207340Sjkim    Descriptor->Irq.IrqMask = IrqMask;
671207340Sjkim    return (Rnode);
672207340Sjkim}
673