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:
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 RsCreateBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
106 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5);
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 RsCreateBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
120 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0);
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: RsDoFixedIoDescriptor
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 "FixedIO" descriptor
195 ******************************************************************************/
198 RsDoFixedIoDescriptor (
199 ACPI_PARSE_OBJECT *Op,
200 UINT32 CurrentByteOffset)
202 AML_RESOURCE *Descriptor;
203 ACPI_PARSE_OBJECT *InitializerOp;
204 ACPI_PARSE_OBJECT *AddressOp = NULL;
205 ASL_RESOURCE_NODE *Rnode;
209 InitializerOp = Op->Asl.Child;
210 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
212 Descriptor = Rnode->Buffer;
213 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_FIXED_IO |
214 ASL_RDESC_FIXED_IO_SIZE;
216 /* Process all child initialization nodes */
218 for (i = 0; InitializerOp; i++)
222 case 0: /* Base Address */
224 Descriptor->FixedIo.Address =
225 (UINT16) InitializerOp->Asl.Value.Integer;
226 RsCreateByteField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
227 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
228 AddressOp = InitializerOp;
233 Descriptor->FixedIo.AddressLength =
234 (UINT8) InitializerOp->Asl.Value.Integer;
235 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
236 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
241 UtAttachNamepathToOwner (Op, InitializerOp);
246 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
250 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
255 if (Descriptor->FixedIo.Address > 0x03FF)
257 AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
264 /*******************************************************************************
266 * FUNCTION: RsDoIoDescriptor
268 * PARAMETERS: Op - Parent resource descriptor parse node
269 * CurrentByteOffset - Offset into the resource template AML
270 * buffer (to track references to the desc)
272 * RETURN: Completed resource node
274 * DESCRIPTION: Construct a short "IO" descriptor
276 ******************************************************************************/
280 ACPI_PARSE_OBJECT *Op,
281 UINT32 CurrentByteOffset)
283 AML_RESOURCE *Descriptor;
284 ACPI_PARSE_OBJECT *InitializerOp;
285 ACPI_PARSE_OBJECT *MinOp = NULL;
286 ACPI_PARSE_OBJECT *MaxOp = NULL;
287 ACPI_PARSE_OBJECT *LengthOp = NULL;
288 ACPI_PARSE_OBJECT *AlignOp = NULL;
289 ASL_RESOURCE_NODE *Rnode;
293 InitializerOp = Op->Asl.Child;
294 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
296 Descriptor = Rnode->Buffer;
297 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_IO |
300 /* Process all child initialization nodes */
302 for (i = 0; InitializerOp; i++)
306 case 0: /* Decode size */
308 RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
309 RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
310 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
313 case 1: /* Min Address */
315 Descriptor->Io.Minimum =
316 (UINT16) InitializerOp->Asl.Value.Integer;
317 RsCreateByteField (InitializerOp, ACPI_RESTAG_MINADDR,
318 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
319 MinOp = InitializerOp;
322 case 2: /* Max Address */
324 Descriptor->Io.Maximum =
325 (UINT16) InitializerOp->Asl.Value.Integer;
326 RsCreateByteField (InitializerOp, ACPI_RESTAG_MAXADDR,
327 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
328 MaxOp = InitializerOp;
331 case 3: /* Alignment */
333 Descriptor->Io.Alignment =
334 (UINT8) InitializerOp->Asl.Value.Integer;
335 RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
336 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
337 AlignOp = InitializerOp;
342 Descriptor->Io.AddressLength =
343 (UINT8) InitializerOp->Asl.Value.Integer;
344 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
345 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
346 LengthOp = InitializerOp;
351 UtAttachNamepathToOwner (Op, InitializerOp);
356 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
360 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
363 /* Validate the Min/Max/Len/Align values */
365 RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
366 Descriptor->Io.Minimum,
367 Descriptor->Io.Maximum,
368 Descriptor->Io.AddressLength,
369 Descriptor->Io.Alignment,
370 MinOp, MaxOp, LengthOp, AlignOp, Op);
376 /*******************************************************************************
378 * FUNCTION: RsDoIrqDescriptor
380 * PARAMETERS: Op - Parent resource descriptor parse node
381 * CurrentByteOffset - Offset into the resource template AML
382 * buffer (to track references to the desc)
384 * RETURN: Completed resource node
386 * DESCRIPTION: Construct a short "IRQ" descriptor
388 ******************************************************************************/
392 ACPI_PARSE_OBJECT *Op,
393 UINT32 CurrentByteOffset)
395 AML_RESOURCE *Descriptor;
396 ACPI_PARSE_OBJECT *InitializerOp;
397 ASL_RESOURCE_NODE *Rnode;
398 UINT32 Interrupts = 0;
403 InitializerOp = Op->Asl.Child;
404 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
406 /* Length = 3 (with flag byte) */
408 Descriptor = Rnode->Buffer;
409 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
410 (ASL_RDESC_IRQ_SIZE + 0x01);
412 /* Process all child initialization nodes */
414 for (i = 0; InitializerOp; i++)
418 case 0: /* Interrupt Type (or Mode - edge/level) */
420 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
421 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
422 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
425 case 1: /* Interrupt Level (or Polarity - Active high/low) */
427 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
428 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
429 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
432 case 2: /* Share Type - Default: exclusive (0) */
434 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
435 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
436 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
441 UtAttachNamepathToOwner (Op, InitializerOp);
446 /* All IRQ bytes are handled here, after the flags and name */
448 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
450 /* Up to 16 interrupts can be specified in the list */
455 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
456 InitializerOp, NULL);
460 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
462 if (InitializerOp->Asl.Value.Integer > 15)
464 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
465 InitializerOp, NULL);
469 IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
473 /* Case 4: First IRQ value in list */
477 /* Check now for duplicates in list */
479 RsCheckListForDuplicates (InitializerOp);
481 /* Create a named field at the start of the list */
483 RsCreateByteField (InitializerOp, ACPI_RESTAG_INTERRUPT,
484 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
489 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
492 /* Now we can set the channel mask */
494 Descriptor->Irq.IrqMask = IrqMask;
499 /*******************************************************************************
501 * FUNCTION: RsDoIrqNoFlagsDescriptor
503 * PARAMETERS: Op - Parent resource descriptor parse node
504 * CurrentByteOffset - Offset into the resource template AML
505 * buffer (to track references to the desc)
507 * RETURN: Completed resource node
509 * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
511 ******************************************************************************/
514 RsDoIrqNoFlagsDescriptor (
515 ACPI_PARSE_OBJECT *Op,
516 UINT32 CurrentByteOffset)
518 AML_RESOURCE *Descriptor;
519 ACPI_PARSE_OBJECT *InitializerOp;
520 ASL_RESOURCE_NODE *Rnode;
522 UINT32 Interrupts = 0;
526 InitializerOp = Op->Asl.Child;
527 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
529 Descriptor = Rnode->Buffer;
530 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
533 /* Process all child initialization nodes */
535 for (i = 0; InitializerOp; i++)
541 UtAttachNamepathToOwner (Op, InitializerOp);
546 /* IRQ bytes are handled here, after the flags and name */
548 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
550 /* Up to 16 interrupts can be specified in the list */
555 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
556 InitializerOp, NULL);
560 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
562 if (InitializerOp->Asl.Value.Integer > 15)
564 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
565 InitializerOp, NULL);
569 IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
573 /* Case 1: First IRQ value in list */
577 /* Check now for duplicates in list */
579 RsCheckListForDuplicates (InitializerOp);
581 /* Create a named field at the start of the list */
583 RsCreateByteField (InitializerOp, ACPI_RESTAG_INTERRUPT,
584 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
589 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
592 /* Now we can set the interrupt mask */
594 Descriptor->Irq.IrqMask = IrqMask;