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.
44 #include "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: Op - Parent resource descriptor parse node
66 * CurrentByteOffset - Offset into the resource template AML
67 * buffer (to track references to the desc)
69 * RETURN: Completed resource node
71 * DESCRIPTION: Construct a short "DMA" descriptor
73 ******************************************************************************/
77 ACPI_PARSE_OBJECT *Op,
78 UINT32 CurrentByteOffset)
80 AML_RESOURCE *Descriptor;
81 ACPI_PARSE_OBJECT *InitializerOp;
82 ASL_RESOURCE_NODE *Rnode;
84 UINT8 DmaChannelMask = 0;
85 UINT8 DmaChannels = 0;
88 InitializerOp = Op->Asl.Child;
89 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
91 Descriptor = Rnode->Buffer;
92 Descriptor->Dma.DescriptorType = ACPI_RESOURCE_NAME_DMA |
95 /* Process all child initialization nodes */
97 for (i = 0; InitializerOp; i++)
101 case 0: /* DMA type */
103 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
104 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
105 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
108 case 1: /* Bus Master */
110 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
111 RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
112 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
115 case 2: /* Xfer Type (transfer width) */
117 RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
118 RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
119 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
124 UtAttachNamepathToOwner (Op, InitializerOp);
129 /* All DMA channel bytes are handled here, after flags and name */
131 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
133 /* Up to 8 channels can be specified in the list */
138 AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
139 InitializerOp, NULL);
143 /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
145 if (InitializerOp->Asl.Value.Integer > 7)
147 AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
148 InitializerOp, NULL);
154 (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
157 if (i == 4) /* case 4: First DMA byte */
159 /* Check now for duplicates in list */
161 RsCheckListForDuplicates (InitializerOp);
163 /* Create a named field at the start of the list */
165 RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
167 ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
172 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
175 /* Now we can set the channel mask */
177 Descriptor->Dma.DmaChannelMask = DmaChannelMask;
182 /*******************************************************************************
184 * FUNCTION: RsDoFixedDmaDescriptor
186 * PARAMETERS: Op - Parent resource descriptor parse node
187 * CurrentByteOffset - Offset into the resource template AML
188 * buffer (to track references to the desc)
190 * RETURN: Completed resource node
192 * DESCRIPTION: Construct a short "FixedDMA" descriptor
194 ******************************************************************************/
197 RsDoFixedDmaDescriptor (
198 ACPI_PARSE_OBJECT *Op,
199 UINT32 CurrentByteOffset)
201 AML_RESOURCE *Descriptor;
202 ACPI_PARSE_OBJECT *InitializerOp;
203 ASL_RESOURCE_NODE *Rnode;
207 InitializerOp = Op->Asl.Child;
208 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
210 Descriptor = Rnode->Buffer;
211 Descriptor->FixedDma.DescriptorType =
212 ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
214 /* Process all child initialization nodes */
216 for (i = 0; InitializerOp; i++)
220 case 0: /* DMA Request Lines [WORD] (_DMA) */
222 Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
223 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
224 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
227 case 1: /* DMA Channel [WORD] (_TYP) */
229 Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
230 RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
231 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
234 case 2: /* Transfer Width [BYTE] (_SIZ) */
236 Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
237 RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
238 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
241 case 3: /* Descriptor Name (optional) */
243 UtAttachNamepathToOwner (Op, InitializerOp);
246 default: /* Ignore any extra nodes */
251 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
258 /*******************************************************************************
260 * FUNCTION: RsDoFixedIoDescriptor
262 * PARAMETERS: Op - Parent resource descriptor parse node
263 * CurrentByteOffset - Offset into the resource template AML
264 * buffer (to track references to the desc)
266 * RETURN: Completed resource node
268 * DESCRIPTION: Construct a short "FixedIO" descriptor
270 ******************************************************************************/
273 RsDoFixedIoDescriptor (
274 ACPI_PARSE_OBJECT *Op,
275 UINT32 CurrentByteOffset)
277 AML_RESOURCE *Descriptor;
278 ACPI_PARSE_OBJECT *InitializerOp;
279 ACPI_PARSE_OBJECT *AddressOp = NULL;
280 ASL_RESOURCE_NODE *Rnode;
284 InitializerOp = Op->Asl.Child;
285 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
287 Descriptor = Rnode->Buffer;
288 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_FIXED_IO |
289 ASL_RDESC_FIXED_IO_SIZE;
291 /* Process all child initialization nodes */
293 for (i = 0; InitializerOp; i++)
297 case 0: /* Base Address */
299 Descriptor->FixedIo.Address =
300 (UINT16) InitializerOp->Asl.Value.Integer;
301 RsCreateWordField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
302 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
303 AddressOp = InitializerOp;
308 Descriptor->FixedIo.AddressLength =
309 (UINT8) InitializerOp->Asl.Value.Integer;
310 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
311 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
316 UtAttachNamepathToOwner (Op, InitializerOp);
321 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
325 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
330 if (Descriptor->FixedIo.Address > 0x03FF)
332 AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
339 /*******************************************************************************
341 * FUNCTION: RsDoIoDescriptor
343 * PARAMETERS: Op - Parent resource descriptor parse node
344 * CurrentByteOffset - Offset into the resource template AML
345 * buffer (to track references to the desc)
347 * RETURN: Completed resource node
349 * DESCRIPTION: Construct a short "IO" descriptor
351 ******************************************************************************/
355 ACPI_PARSE_OBJECT *Op,
356 UINT32 CurrentByteOffset)
358 AML_RESOURCE *Descriptor;
359 ACPI_PARSE_OBJECT *InitializerOp;
360 ACPI_PARSE_OBJECT *MinOp = NULL;
361 ACPI_PARSE_OBJECT *MaxOp = NULL;
362 ACPI_PARSE_OBJECT *LengthOp = NULL;
363 ACPI_PARSE_OBJECT *AlignOp = NULL;
364 ASL_RESOURCE_NODE *Rnode;
368 InitializerOp = Op->Asl.Child;
369 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
371 Descriptor = Rnode->Buffer;
372 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_IO |
375 /* Process all child initialization nodes */
377 for (i = 0; InitializerOp; i++)
381 case 0: /* Decode size */
383 RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
384 RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
385 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
388 case 1: /* Min Address */
390 Descriptor->Io.Minimum =
391 (UINT16) InitializerOp->Asl.Value.Integer;
392 RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
393 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
394 MinOp = InitializerOp;
397 case 2: /* Max Address */
399 Descriptor->Io.Maximum =
400 (UINT16) InitializerOp->Asl.Value.Integer;
401 RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
402 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
403 MaxOp = InitializerOp;
406 case 3: /* Alignment */
408 Descriptor->Io.Alignment =
409 (UINT8) InitializerOp->Asl.Value.Integer;
410 RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
411 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
412 AlignOp = InitializerOp;
417 Descriptor->Io.AddressLength =
418 (UINT8) InitializerOp->Asl.Value.Integer;
419 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
420 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
421 LengthOp = InitializerOp;
426 UtAttachNamepathToOwner (Op, InitializerOp);
431 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
435 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
438 /* Validate the Min/Max/Len/Align values */
440 RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
441 Descriptor->Io.Minimum,
442 Descriptor->Io.Maximum,
443 Descriptor->Io.AddressLength,
444 Descriptor->Io.Alignment,
445 MinOp, MaxOp, LengthOp, AlignOp, Op);
451 /*******************************************************************************
453 * FUNCTION: RsDoIrqDescriptor
455 * PARAMETERS: Op - Parent resource descriptor parse node
456 * CurrentByteOffset - Offset into the resource template AML
457 * buffer (to track references to the desc)
459 * RETURN: Completed resource node
461 * DESCRIPTION: Construct a short "IRQ" descriptor
463 ******************************************************************************/
467 ACPI_PARSE_OBJECT *Op,
468 UINT32 CurrentByteOffset)
470 AML_RESOURCE *Descriptor;
471 ACPI_PARSE_OBJECT *InitializerOp;
472 ASL_RESOURCE_NODE *Rnode;
473 UINT32 Interrupts = 0;
478 InitializerOp = Op->Asl.Child;
479 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
481 /* Length = 3 (with flag byte) */
483 Descriptor = Rnode->Buffer;
484 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
485 (ASL_RDESC_IRQ_SIZE + 0x01);
487 /* Process all child initialization nodes */
489 for (i = 0; InitializerOp; i++)
493 case 0: /* Interrupt Type (or Mode - edge/level) */
495 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
496 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
497 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
500 case 1: /* Interrupt Level (or Polarity - Active high/low) */
502 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
503 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
504 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
507 case 2: /* Share Type - Default: exclusive (0) */
509 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
510 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
511 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
516 UtAttachNamepathToOwner (Op, InitializerOp);
521 /* All IRQ bytes are handled here, after the flags and name */
523 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
525 /* Up to 16 interrupts can be specified in the list */
530 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
531 InitializerOp, NULL);
535 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
537 if (InitializerOp->Asl.Value.Integer > 15)
539 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
540 InitializerOp, NULL);
544 IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
548 /* Case 4: First IRQ value in list */
552 /* Check now for duplicates in list */
554 RsCheckListForDuplicates (InitializerOp);
556 /* Create a named field at the start of the list */
558 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
559 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
564 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
567 /* Now we can set the channel mask */
569 Descriptor->Irq.IrqMask = IrqMask;
574 /*******************************************************************************
576 * FUNCTION: RsDoIrqNoFlagsDescriptor
578 * PARAMETERS: Op - Parent resource descriptor parse node
579 * CurrentByteOffset - Offset into the resource template AML
580 * buffer (to track references to the desc)
582 * RETURN: Completed resource node
584 * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
586 ******************************************************************************/
589 RsDoIrqNoFlagsDescriptor (
590 ACPI_PARSE_OBJECT *Op,
591 UINT32 CurrentByteOffset)
593 AML_RESOURCE *Descriptor;
594 ACPI_PARSE_OBJECT *InitializerOp;
595 ASL_RESOURCE_NODE *Rnode;
597 UINT32 Interrupts = 0;
601 InitializerOp = Op->Asl.Child;
602 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
604 Descriptor = Rnode->Buffer;
605 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ |
608 /* Process all child initialization nodes */
610 for (i = 0; InitializerOp; i++)
616 UtAttachNamepathToOwner (Op, InitializerOp);
621 /* IRQ bytes are handled here, after the flags and name */
623 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
625 /* Up to 16 interrupts can be specified in the list */
630 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
631 InitializerOp, NULL);
635 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
637 if (InitializerOp->Asl.Value.Integer > 15)
639 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
640 InitializerOp, NULL);
644 IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
648 /* Case 1: First IRQ value in list */
652 /* Check now for duplicates in list */
654 RsCheckListForDuplicates (InitializerOp);
656 /* Create a named field at the start of the list */
658 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
659 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
664 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
667 /* Now we can set the interrupt mask */
669 Descriptor->Irq.IrqMask = IrqMask;