1 /******************************************************************************
3 * Module Name: aslrestype1i - Small I/O-related resource descriptors
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2014, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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 MERCHANTIBILITY 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.
45 #include "aslcompiler.h"
46 #include "aslcompiler.y.h"
48 #define _COMPONENT ACPI_COMPILER
49 ACPI_MODULE_NAME ("aslrestype1i")
52 * This module contains the I/O-related small resource descriptors:
62 /*******************************************************************************
64 * FUNCTION: RsDoDmaDescriptor
66 * PARAMETERS: Op - Parent resource descriptor parse node
67 * CurrentByteOffset - Offset into the resource template AML
68 * buffer (to track references to the desc)
70 * RETURN: Completed resource node
72 * DESCRIPTION: Construct a short "DMA" descriptor
74 ******************************************************************************/
78 ACPI_PARSE_OBJECT *Op,
79 UINT32 CurrentByteOffset)
81 AML_RESOURCE *Descriptor;
82 ACPI_PARSE_OBJECT *InitializerOp;
83 ASL_RESOURCE_NODE *Rnode;
85 UINT8 DmaChannelMask = 0;
86 UINT8 DmaChannels = 0;
89 InitializerOp = Op->Asl.Child;
90 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
92 Descriptor = Rnode->Buffer;
93 Descriptor->Dma.DescriptorType = ACPI_RESOURCE_NAME_DMA |
96 /* Process all child initialization nodes */
98 for (i = 0; InitializerOp; i++)
102 case 0: /* DMA type */
104 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
105 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
106 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
109 case 1: /* Bus Master */
111 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
112 RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
113 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
116 case 2: /* Xfer Type (transfer width) */
118 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
119 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
120 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
125 UtAttachNamepathToOwner (Op, InitializerOp);
130 /* All DMA channel bytes are handled here, after flags and name */
132 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
134 /* Up to 8 channels can be specified in the list */
139 AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
140 InitializerOp, NULL);
144 /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
146 if (InitializerOp->Asl.Value.Integer > 7)
148 AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
149 InitializerOp, NULL);
155 (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
158 if (i == 4) /* case 4: First DMA byte */
160 /* Check now for duplicates in list */
162 RsCheckListForDuplicates (InitializerOp);
164 /* Create a named field at the start of the list */
166 RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
168 ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
173 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
176 /* Now we can set the channel mask */
178 Descriptor->Dma.DmaChannelMask = DmaChannelMask;
183 /*******************************************************************************
185 * FUNCTION: RsDoFixedDmaDescriptor
187 * PARAMETERS: Op - Parent resource descriptor parse node
188 * CurrentByteOffset - Offset into the resource template AML
189 * buffer (to track references to the desc)
191 * RETURN: Completed resource node
193 * DESCRIPTION: Construct a short "FixedDMA" descriptor
195 ******************************************************************************/
198 RsDoFixedDmaDescriptor (
199 ACPI_PARSE_OBJECT *Op,
200 UINT32 CurrentByteOffset)
202 AML_RESOURCE *Descriptor;
203 ACPI_PARSE_OBJECT *InitializerOp;
204 ASL_RESOURCE_NODE *Rnode;
208 InitializerOp = Op->Asl.Child;
209 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
211 Descriptor = Rnode->Buffer;
212 Descriptor->FixedDma.DescriptorType =
213 ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
215 /* Process all child initialization nodes */
217 for (i = 0; InitializerOp; i++)
221 case 0: /* DMA Request Lines [WORD] (_DMA) */
223 Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
224 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
225 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
228 case 1: /* DMA Channel [WORD] (_TYP) */
230 Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
231 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
232 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
235 case 2: /* Transfer Width [BYTE] (_SIZ) */
237 Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
238 RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
239 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
242 case 3: /* Descriptor Name (optional) */
244 UtAttachNamepathToOwner (Op, InitializerOp);
247 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;