2 /******************************************************************************
4 * Module Name: aslrestype1i - Small I/O-related resource descriptors
6 *****************************************************************************/
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include "aslcompiler.y.h"
49 #define _COMPONENT ACPI_COMPILER
50 ACPI_MODULE_NAME ("aslrestype1i")
53 * This module contains the I/O-related small resource descriptors:
63 /*******************************************************************************
65 * FUNCTION: RsDoDmaDescriptor
67 * PARAMETERS: Op - Parent resource descriptor parse node
68 * CurrentByteOffset - Offset into the resource template AML
69 * buffer (to track references to the desc)
71 * RETURN: Completed resource node
73 * DESCRIPTION: Construct a short "DMA" descriptor
75 ******************************************************************************/
79 ACPI_PARSE_OBJECT *Op,
80 UINT32 CurrentByteOffset)
82 AML_RESOURCE *Descriptor;
83 ACPI_PARSE_OBJECT *InitializerOp;
84 ASL_RESOURCE_NODE *Rnode;
86 UINT8 DmaChannelMask = 0;
87 UINT8 DmaChannels = 0;
90 InitializerOp = Op->Asl.Child;
91 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
93 Descriptor = Rnode->Buffer;
94 Descriptor->Dma.DescriptorType = ACPI_RESOURCE_NAME_DMA |
97 /* Process all child initialization nodes */
99 for (i = 0; InitializerOp; i++)
103 case 0: /* DMA type */
105 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
106 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
107 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
110 case 1: /* Bus Master */
112 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
113 RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
114 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
117 case 2: /* Xfer Type (transfer width) */
119 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
120 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
121 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
126 UtAttachNamepathToOwner (Op, InitializerOp);
131 /* All DMA channel bytes are handled here, after flags and name */
133 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
135 /* Up to 8 channels can be specified in the list */
140 AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
141 InitializerOp, NULL);
145 /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
147 if (InitializerOp->Asl.Value.Integer > 7)
149 AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
150 InitializerOp, NULL);
156 (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
159 if (i == 4) /* case 4: First DMA byte */
161 /* Check now for duplicates in list */
163 RsCheckListForDuplicates (InitializerOp);
165 /* Create a named field at the start of the list */
167 RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
169 ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
174 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
177 /* Now we can set the channel mask */
179 Descriptor->Dma.DmaChannelMask = DmaChannelMask;
184 /*******************************************************************************
186 * FUNCTION: RsDoFixedDmaDescriptor
188 * PARAMETERS: Op - Parent resource descriptor parse node
189 * CurrentByteOffset - Offset into the resource template AML
190 * buffer (to track references to the desc)
192 * RETURN: Completed resource node
194 * DESCRIPTION: Construct a short "FixedDMA" descriptor
196 ******************************************************************************/
199 RsDoFixedDmaDescriptor (
200 ACPI_PARSE_OBJECT *Op,
201 UINT32 CurrentByteOffset)
203 AML_RESOURCE *Descriptor;
204 ACPI_PARSE_OBJECT *InitializerOp;
205 ASL_RESOURCE_NODE *Rnode;
209 InitializerOp = Op->Asl.Child;
210 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
212 Descriptor = Rnode->Buffer;
213 Descriptor->FixedDma.DescriptorType =
214 ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
216 /* Process all child initialization nodes */
218 for (i = 0; InitializerOp; i++)
222 case 0: /* DMA Request Lines [WORD] (_DMA) */
224 Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
225 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
226 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
229 case 1: /* DMA Channel [WORD] (_TYP) */
231 Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
232 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
233 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
236 case 2: /* Transfer Width [BYTE] (_SIZ) */
238 Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
239 RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
240 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
243 case 3: /* Descriptor Name (optional) */
245 UtAttachNamepathToOwner (Op, InitializerOp);
248 default: /* Ignore any extra nodes */
252 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
259 /*******************************************************************************
261 * FUNCTION: RsDoFixedIoDescriptor
263 * PARAMETERS: Op - Parent resource descriptor parse node
264 * CurrentByteOffset - Offset into the resource template AML
265 * buffer (to track references to the desc)
267 * RETURN: Completed resource node
269 * DESCRIPTION: Construct a short "FixedIO" descriptor
271 ******************************************************************************/
274 RsDoFixedIoDescriptor (
275 ACPI_PARSE_OBJECT *Op,
276 UINT32 CurrentByteOffset)
278 AML_RESOURCE *Descriptor;
279 ACPI_PARSE_OBJECT *InitializerOp;
280 ACPI_PARSE_OBJECT *AddressOp = NULL;
281 ASL_RESOURCE_NODE *Rnode;
285 InitializerOp = Op->Asl.Child;
286 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
288 Descriptor = Rnode->Buffer;
289 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_FIXED_IO |
290 ASL_RDESC_FIXED_IO_SIZE;
292 /* Process all child initialization nodes */
294 for (i = 0; InitializerOp; i++)
298 case 0: /* Base Address */
300 Descriptor->FixedIo.Address =
301 (UINT16) InitializerOp->Asl.Value.Integer;
302 RsCreateWordField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
303 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
304 AddressOp = InitializerOp;
309 Descriptor->FixedIo.AddressLength =
310 (UINT8) InitializerOp->Asl.Value.Integer;
311 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
312 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
317 UtAttachNamepathToOwner (Op, InitializerOp);
322 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
326 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
331 if (Descriptor->FixedIo.Address > 0x03FF)
333 AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
340 /*******************************************************************************
342 * FUNCTION: RsDoIoDescriptor
344 * PARAMETERS: Op - Parent resource descriptor parse node
345 * CurrentByteOffset - Offset into the resource template AML
346 * buffer (to track references to the desc)
348 * RETURN: Completed resource node
350 * DESCRIPTION: Construct a short "IO" descriptor
352 ******************************************************************************/
356 ACPI_PARSE_OBJECT *Op,
357 UINT32 CurrentByteOffset)
359 AML_RESOURCE *Descriptor;
360 ACPI_PARSE_OBJECT *InitializerOp;
361 ACPI_PARSE_OBJECT *MinOp = NULL;
362 ACPI_PARSE_OBJECT *MaxOp = NULL;
363 ACPI_PARSE_OBJECT *LengthOp = NULL;
364 ACPI_PARSE_OBJECT *AlignOp = NULL;
365 ASL_RESOURCE_NODE *Rnode;
369 InitializerOp = Op->Asl.Child;
370 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
372 Descriptor = Rnode->Buffer;
373 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_IO |
376 /* Process all child initialization nodes */
378 for (i = 0; InitializerOp; i++)
382 case 0: /* Decode size */
384 RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
385 RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
386 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
389 case 1: /* Min Address */
391 Descriptor->Io.Minimum =
392 (UINT16) InitializerOp->Asl.Value.Integer;
393 RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
394 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
395 MinOp = InitializerOp;
398 case 2: /* Max Address */
400 Descriptor->Io.Maximum =
401 (UINT16) InitializerOp->Asl.Value.Integer;
402 RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
403 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
404 MaxOp = InitializerOp;
407 case 3: /* Alignment */
409 Descriptor->Io.Alignment =
410 (UINT8) InitializerOp->Asl.Value.Integer;
411 RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
412 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
413 AlignOp = InitializerOp;
418 Descriptor->Io.AddressLength =
419 (UINT8) InitializerOp->Asl.Value.Integer;
420 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
421 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
422 LengthOp = InitializerOp;
427 UtAttachNamepathToOwner (Op, InitializerOp);
432 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
436 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
439 /* Validate the Min/Max/Len/Align values */
441 RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
442 Descriptor->Io.Minimum,
443 Descriptor->Io.Maximum,
444 Descriptor->Io.AddressLength,
445 Descriptor->Io.Alignment,
446 MinOp, MaxOp, LengthOp, AlignOp, Op);
452 /*******************************************************************************
454 * FUNCTION: RsDoIrqDescriptor
456 * PARAMETERS: Op - Parent resource descriptor parse node
457 * CurrentByteOffset - Offset into the resource template AML
458 * buffer (to track references to the desc)
460 * RETURN: Completed resource node
462 * DESCRIPTION: Construct a short "IRQ" descriptor
464 ******************************************************************************/
468 ACPI_PARSE_OBJECT *Op,
469 UINT32 CurrentByteOffset)
471 AML_RESOURCE *Descriptor;
472 ACPI_PARSE_OBJECT *InitializerOp;
473 ASL_RESOURCE_NODE *Rnode;
474 UINT32 Interrupts = 0;
479 InitializerOp = Op->Asl.Child;
480 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
482 /* Length = 3 (with flag byte) */
484 Descriptor = Rnode->Buffer;
485 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
486 (ASL_RDESC_IRQ_SIZE + 0x01);
488 /* Process all child initialization nodes */
490 for (i = 0; InitializerOp; i++)
494 case 0: /* Interrupt Type (or Mode - edge/level) */
496 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
497 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
498 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
501 case 1: /* Interrupt Level (or Polarity - Active high/low) */
503 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
504 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
505 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
508 case 2: /* Share Type - Default: exclusive (0) */
510 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
511 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
512 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
517 UtAttachNamepathToOwner (Op, InitializerOp);
522 /* All IRQ bytes are handled here, after the flags and name */
524 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
526 /* Up to 16 interrupts can be specified in the list */
531 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
532 InitializerOp, NULL);
536 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
538 if (InitializerOp->Asl.Value.Integer > 15)
540 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
541 InitializerOp, NULL);
545 IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
549 /* Case 4: First IRQ value in list */
553 /* Check now for duplicates in list */
555 RsCheckListForDuplicates (InitializerOp);
557 /* Create a named field at the start of the list */
559 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
560 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
565 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
568 /* Now we can set the channel mask */
570 Descriptor->Irq.IrqMask = IrqMask;
575 /*******************************************************************************
577 * FUNCTION: RsDoIrqNoFlagsDescriptor
579 * PARAMETERS: Op - Parent resource descriptor parse node
580 * CurrentByteOffset - Offset into the resource template AML
581 * buffer (to track references to the desc)
583 * RETURN: Completed resource node
585 * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
587 ******************************************************************************/
590 RsDoIrqNoFlagsDescriptor (
591 ACPI_PARSE_OBJECT *Op,
592 UINT32 CurrentByteOffset)
594 AML_RESOURCE *Descriptor;
595 ACPI_PARSE_OBJECT *InitializerOp;
596 ASL_RESOURCE_NODE *Rnode;
598 UINT32 Interrupts = 0;
602 InitializerOp = Op->Asl.Child;
603 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
605 Descriptor = Rnode->Buffer;
606 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
609 /* Process all child initialization nodes */
611 for (i = 0; InitializerOp; i++)
617 UtAttachNamepathToOwner (Op, InitializerOp);
622 /* IRQ bytes are handled here, after the flags and name */
624 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
626 /* Up to 16 interrupts can be specified in the list */
631 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
632 InitializerOp, NULL);
636 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
638 if (InitializerOp->Asl.Value.Integer > 15)
640 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
641 InitializerOp, NULL);
645 IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
649 /* Case 1: First IRQ value in list */
653 /* Check now for duplicates in list */
655 RsCheckListForDuplicates (InitializerOp);
657 /* Create a named field at the start of the list */
659 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
660 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
665 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
668 /* Now we can set the interrupt mask */
670 Descriptor->Irq.IrqMask = IrqMask;