1 /******************************************************************************
3 * Module Name: aslrestype1i - Small I/O-related resource descriptors
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, 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.
44 #include <contrib/dev/acpica/compiler/aslcompiler.h>
45 #include "aslcompiler.y.h"
47 #define _COMPONENT ACPI_COMPILER
48 ACPI_MODULE_NAME ("aslrestype1i")
51 * This module contains the I/O-related small resource descriptors:
61 /*******************************************************************************
63 * FUNCTION: RsDoDmaDescriptor
65 * PARAMETERS: Info - Parse Op and resource template offset
67 * RETURN: Completed resource node
69 * DESCRIPTION: Construct a short "DMA" descriptor
71 ******************************************************************************/
75 ASL_RESOURCE_INFO *Info)
77 AML_RESOURCE *Descriptor;
78 ACPI_PARSE_OBJECT *InitializerOp;
79 ASL_RESOURCE_NODE *Rnode;
80 UINT32 CurrentByteOffset;
82 UINT8 DmaChannelMask = 0;
83 UINT8 DmaChannels = 0;
86 InitializerOp = Info->DescriptorTypeOp->Asl.Child;
87 CurrentByteOffset = Info->CurrentByteOffset;
88 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
90 Descriptor = Rnode->Buffer;
91 Descriptor->Dma.DescriptorType =
92 ACPI_RESOURCE_NAME_DMA | ASL_RDESC_DMA_SIZE;
94 /* Process all child initialization nodes */
96 for (i = 0; InitializerOp; i++)
100 case 0: /* DMA type */
102 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
103 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
104 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
107 case 1: /* Bus Master */
109 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
110 RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
111 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
114 case 2: /* Xfer Type (transfer width) */
116 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
117 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
118 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
123 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
128 /* All DMA channel bytes are handled here, after flags and name */
130 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
132 /* Up to 8 channels can be specified in the list */
137 AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
138 InitializerOp, NULL);
142 /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
144 if (InitializerOp->Asl.Value.Integer > 7)
146 AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
147 InitializerOp, NULL);
153 (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
156 if (i == 4) /* case 4: First DMA byte */
158 /* Check now for duplicates in list */
160 RsCheckListForDuplicates (InitializerOp);
162 /* Create a named field at the start of the list */
164 RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
166 ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
171 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
174 /* Now we can set the channel mask */
176 Descriptor->Dma.DmaChannelMask = DmaChannelMask;
181 /*******************************************************************************
183 * FUNCTION: RsDoFixedDmaDescriptor
185 * PARAMETERS: Info - Parse Op and resource template offset
187 * RETURN: Completed resource node
189 * DESCRIPTION: Construct a short "FixedDMA" descriptor
191 ******************************************************************************/
194 RsDoFixedDmaDescriptor (
195 ASL_RESOURCE_INFO *Info)
197 AML_RESOURCE *Descriptor;
198 ACPI_PARSE_OBJECT *InitializerOp;
199 ASL_RESOURCE_NODE *Rnode;
200 UINT32 CurrentByteOffset;
204 InitializerOp = Info->DescriptorTypeOp->Asl.Child;
205 CurrentByteOffset = Info->CurrentByteOffset;
206 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
208 Descriptor = Rnode->Buffer;
209 Descriptor->FixedDma.DescriptorType =
210 ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
212 /* Process all child initialization nodes */
214 for (i = 0; InitializerOp; i++)
218 case 0: /* DMA Request Lines [WORD] (_DMA) */
220 Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
221 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
222 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
225 case 1: /* DMA Channel [WORD] (_TYP) */
227 Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
228 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
229 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
232 case 2: /* Transfer Width [BYTE] (_SIZ) */
234 Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
235 RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
236 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
239 case 3: /* Descriptor Name (optional) */
241 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
244 default: /* Ignore any extra nodes */
249 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
256 /*******************************************************************************
258 * FUNCTION: RsDoFixedIoDescriptor
260 * PARAMETERS: Info - Parse Op and resource template offset
262 * RETURN: Completed resource node
264 * DESCRIPTION: Construct a short "FixedIO" descriptor
266 ******************************************************************************/
269 RsDoFixedIoDescriptor (
270 ASL_RESOURCE_INFO *Info)
272 AML_RESOURCE *Descriptor;
273 ACPI_PARSE_OBJECT *InitializerOp;
274 ACPI_PARSE_OBJECT *AddressOp = NULL;
275 ASL_RESOURCE_NODE *Rnode;
276 UINT32 CurrentByteOffset;
280 InitializerOp = Info->DescriptorTypeOp->Asl.Child;
281 CurrentByteOffset = Info->CurrentByteOffset;
282 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
284 Descriptor = Rnode->Buffer;
285 Descriptor->Io.DescriptorType =
286 ACPI_RESOURCE_NAME_FIXED_IO | ASL_RDESC_FIXED_IO_SIZE;
288 /* Process all child initialization nodes */
290 for (i = 0; InitializerOp; i++)
294 case 0: /* Base Address */
296 Descriptor->FixedIo.Address =
297 (UINT16) InitializerOp->Asl.Value.Integer;
298 RsCreateWordField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
299 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
300 AddressOp = InitializerOp;
305 Descriptor->FixedIo.AddressLength =
306 (UINT8) InitializerOp->Asl.Value.Integer;
307 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
308 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
313 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
318 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
322 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
327 if (Descriptor->FixedIo.Address > 0x03FF)
329 AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
336 /*******************************************************************************
338 * FUNCTION: RsDoIoDescriptor
340 * PARAMETERS: Info - Parse Op and resource template offset
342 * RETURN: Completed resource node
344 * DESCRIPTION: Construct a short "IO" descriptor
346 ******************************************************************************/
350 ASL_RESOURCE_INFO *Info)
352 AML_RESOURCE *Descriptor;
353 ACPI_PARSE_OBJECT *InitializerOp;
354 ACPI_PARSE_OBJECT *MinOp = NULL;
355 ACPI_PARSE_OBJECT *MaxOp = NULL;
356 ACPI_PARSE_OBJECT *LengthOp = NULL;
357 ACPI_PARSE_OBJECT *AlignOp = NULL;
358 ASL_RESOURCE_NODE *Rnode;
359 UINT32 CurrentByteOffset;
363 InitializerOp = Info->DescriptorTypeOp->Asl.Child;
364 CurrentByteOffset = Info->CurrentByteOffset;
365 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
367 Descriptor = Rnode->Buffer;
368 Descriptor->Io.DescriptorType =
369 ACPI_RESOURCE_NAME_IO | ASL_RDESC_IO_SIZE;
371 /* Process all child initialization nodes */
373 for (i = 0; InitializerOp; i++)
377 case 0: /* Decode size */
379 RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
380 RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
381 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
384 case 1: /* Min Address */
386 Descriptor->Io.Minimum =
387 (UINT16) InitializerOp->Asl.Value.Integer;
388 RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
389 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
390 MinOp = InitializerOp;
393 case 2: /* Max Address */
395 Descriptor->Io.Maximum =
396 (UINT16) InitializerOp->Asl.Value.Integer;
397 RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
398 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
399 MaxOp = InitializerOp;
402 case 3: /* Alignment */
404 Descriptor->Io.Alignment =
405 (UINT8) InitializerOp->Asl.Value.Integer;
406 RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
407 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
408 AlignOp = InitializerOp;
413 Descriptor->Io.AddressLength =
414 (UINT8) InitializerOp->Asl.Value.Integer;
415 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
416 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
417 LengthOp = InitializerOp;
422 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
427 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
431 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
434 /* Validate the Min/Max/Len/Align values */
436 RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
437 Descriptor->Io.Minimum,
438 Descriptor->Io.Maximum,
439 Descriptor->Io.AddressLength,
440 Descriptor->Io.Alignment,
441 MinOp, MaxOp, LengthOp, AlignOp, Info->DescriptorTypeOp);
447 /*******************************************************************************
449 * FUNCTION: RsDoIrqDescriptor
451 * PARAMETERS: Info - Parse Op and resource template offset
453 * RETURN: Completed resource node
455 * DESCRIPTION: Construct a short "IRQ" descriptor
457 ******************************************************************************/
461 ASL_RESOURCE_INFO *Info)
463 AML_RESOURCE *Descriptor;
464 ACPI_PARSE_OBJECT *InitializerOp;
465 ASL_RESOURCE_NODE *Rnode;
466 UINT32 Interrupts = 0;
468 UINT32 CurrentByteOffset;
472 InitializerOp = Info->DescriptorTypeOp->Asl.Child;
473 CurrentByteOffset = Info->CurrentByteOffset;
474 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
476 /* Length = 3 (with flag byte) */
478 Descriptor = Rnode->Buffer;
479 Descriptor->Irq.DescriptorType =
480 ACPI_RESOURCE_NAME_IRQ | (ASL_RDESC_IRQ_SIZE + 0x01);
482 /* Process all child initialization nodes */
484 for (i = 0; InitializerOp; i++)
488 case 0: /* Interrupt Type (or Mode - edge/level) */
490 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
491 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
492 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
495 case 1: /* Interrupt Level (or Polarity - Active high/low) */
497 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
498 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
499 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
502 case 2: /* Share Type - Default: exclusive (0) */
504 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
505 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
506 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
511 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
516 /* All IRQ bytes are handled here, after the flags and name */
518 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
520 /* Up to 16 interrupts can be specified in the list */
525 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
526 InitializerOp, NULL);
530 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
532 if (InitializerOp->Asl.Value.Integer > 15)
534 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
535 InitializerOp, NULL);
539 IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
543 /* Case 4: First IRQ value in list */
547 /* Check now for duplicates in list */
549 RsCheckListForDuplicates (InitializerOp);
551 /* Create a named field at the start of the list */
553 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
554 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
559 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
562 /* Now we can set the channel mask */
564 Descriptor->Irq.IrqMask = IrqMask;
569 /*******************************************************************************
571 * FUNCTION: RsDoIrqNoFlagsDescriptor
573 * PARAMETERS: Info - Parse Op and resource template offset
575 * RETURN: Completed resource node
577 * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
579 ******************************************************************************/
582 RsDoIrqNoFlagsDescriptor (
583 ASL_RESOURCE_INFO *Info)
585 AML_RESOURCE *Descriptor;
586 ACPI_PARSE_OBJECT *InitializerOp;
587 ASL_RESOURCE_NODE *Rnode;
589 UINT32 Interrupts = 0;
590 UINT32 CurrentByteOffset;
594 InitializerOp = Info->DescriptorTypeOp->Asl.Child;
595 CurrentByteOffset = Info->CurrentByteOffset;
596 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
598 Descriptor = Rnode->Buffer;
599 Descriptor->Irq.DescriptorType =
600 ACPI_RESOURCE_NAME_IRQ | ASL_RDESC_IRQ_SIZE;
602 /* Process all child initialization nodes */
604 for (i = 0; InitializerOp; i++)
610 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
615 /* IRQ bytes are handled here, after the flags and name */
617 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
619 /* Up to 16 interrupts can be specified in the list */
624 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
625 InitializerOp, NULL);
629 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
631 if (InitializerOp->Asl.Value.Integer > 15)
633 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
634 InitializerOp, NULL);
638 IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
642 /* Case 1: First IRQ value in list */
646 /* Check now for duplicates in list */
648 RsCheckListForDuplicates (InitializerOp);
650 /* Create a named field at the start of the list */
652 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
653 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
658 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
661 /* Now we can set the interrupt mask */
663 Descriptor->Irq.IrqMask = IrqMask;