1 /******************************************************************************
   2  *
   3  * Module Name: aslrestype1i - Small I/O-related resource descriptors
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  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.
  25  *
  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.
  29  *
  30  * NO WARRANTY
  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.
  42  */
  43 
  44 
  45 #include "aslcompiler.h"
  46 #include "aslcompiler.y.h"
  47 
  48 #define _COMPONENT          ACPI_COMPILER
  49         ACPI_MODULE_NAME    ("aslrestype1i")
  50 
  51 /*
  52  * This module contains the I/O-related small resource descriptors:
  53  *
  54  * DMA
  55  * FixedDMA
  56  * FixedIO
  57  * IO
  58  * IRQ
  59  * IRQNoFlags
  60  */
  61 
  62 /*******************************************************************************
  63  *
  64  * FUNCTION:    RsDoDmaDescriptor
  65  *
  66  * PARAMETERS:  Op                  - Parent resource descriptor parse node
  67  *              CurrentByteOffset   - Offset into the resource template AML
  68  *                                    buffer (to track references to the desc)
  69  *
  70  * RETURN:      Completed resource node
  71  *
  72  * DESCRIPTION: Construct a short "DMA" descriptor
  73  *
  74  ******************************************************************************/
  75 
  76 ASL_RESOURCE_NODE *
  77 RsDoDmaDescriptor (
  78     ACPI_PARSE_OBJECT       *Op,
  79     UINT32                  CurrentByteOffset)
  80 {
  81     AML_RESOURCE            *Descriptor;
  82     ACPI_PARSE_OBJECT       *InitializerOp;
  83     ASL_RESOURCE_NODE       *Rnode;
  84     UINT32                  i;
  85     UINT8                   DmaChannelMask = 0;
  86     UINT8                   DmaChannels = 0;
  87 
  88 
  89     InitializerOp = Op->Asl.Child;
  90     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
  91 
  92     Descriptor = Rnode->Buffer;
  93     Descriptor->Dma.DescriptorType  = ACPI_RESOURCE_NAME_DMA |
  94                                         ASL_RDESC_DMA_SIZE;
  95 
  96     /* Process all child initialization nodes */
  97 
  98     for (i = 0; InitializerOp; i++)
  99     {
 100         switch (i)
 101         {
 102         case 0: /* DMA type */
 103 
 104             RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
 105             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
 106                 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2);
 107             break;
 108 
 109         case 1: /* Bus Master */
 110 
 111             RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
 112             RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
 113                 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
 114             break;
 115 
 116         case 2: /* Xfer Type (transfer width) */
 117 
 118             RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
 119             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
 120                 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2);
 121             break;
 122 
 123         case 3: /* Name */
 124 
 125             UtAttachNamepathToOwner (Op, InitializerOp);
 126             break;
 127 
 128         default:
 129 
 130             /* All DMA channel bytes are handled here, after flags and name */
 131 
 132             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
 133             {
 134                 /* Up to 8 channels can be specified in the list */
 135 
 136                 DmaChannels++;
 137                 if (DmaChannels > 8)
 138                 {
 139                     AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
 140                         InitializerOp, NULL);
 141                     return (Rnode);
 142                 }
 143 
 144                 /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
 145 
 146                 if (InitializerOp->Asl.Value.Integer > 7)
 147                 {
 148                     AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
 149                         InitializerOp, NULL);
 150                 }
 151 
 152                 /* Build the mask */
 153 
 154                 DmaChannelMask |=
 155                     (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
 156             }
 157 
 158             if (i == 4) /* case 4: First DMA byte */
 159             {
 160                 /* Check now for duplicates in list */
 161 
 162                 RsCheckListForDuplicates (InitializerOp);
 163 
 164                 /* Create a named field at the start of the list */
 165 
 166                 RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
 167                     CurrentByteOffset +
 168                     ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
 169             }
 170             break;
 171         }
 172 
 173         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
 174     }
 175 
 176     /* Now we can set the channel mask */
 177 
 178     Descriptor->Dma.DmaChannelMask = DmaChannelMask;
 179     return (Rnode);
 180 }
 181 
 182 
 183 /*******************************************************************************
 184  *
 185  * FUNCTION:    RsDoFixedDmaDescriptor
 186  *
 187  * PARAMETERS:  Op                  - Parent resource descriptor parse node
 188  *              CurrentByteOffset   - Offset into the resource template AML
 189  *                                    buffer (to track references to the desc)
 190  *
 191  * RETURN:      Completed resource node
 192  *
 193  * DESCRIPTION: Construct a short "FixedDMA" descriptor
 194  *
 195  ******************************************************************************/
 196 
 197 ASL_RESOURCE_NODE *
 198 RsDoFixedDmaDescriptor (
 199     ACPI_PARSE_OBJECT       *Op,
 200     UINT32                  CurrentByteOffset)
 201 {
 202     AML_RESOURCE            *Descriptor;
 203     ACPI_PARSE_OBJECT       *InitializerOp;
 204     ASL_RESOURCE_NODE       *Rnode;
 205     UINT32                  i;
 206 
 207 
 208     InitializerOp = Op->Asl.Child;
 209     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA));
 210 
 211     Descriptor = Rnode->Buffer;
 212     Descriptor->FixedDma.DescriptorType =
 213         ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE;
 214 
 215     /* Process all child initialization nodes */
 216 
 217     for (i = 0; InitializerOp; i++)
 218     {
 219         switch (i)
 220         {
 221         case 0: /* DMA Request Lines [WORD] (_DMA) */
 222 
 223             Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer;
 224             RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA,
 225                 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines));
 226             break;
 227 
 228         case 1: /* DMA Channel [WORD] (_TYP) */
 229 
 230             Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer;
 231             RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE,
 232                 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels));
 233             break;
 234 
 235         case 2: /* Transfer Width [BYTE] (_SIZ) */
 236 
 237             Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer;
 238             RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE,
 239                 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width));
 240             break;
 241 
 242         case 3: /* Descriptor Name (optional) */
 243 
 244             UtAttachNamepathToOwner (Op, InitializerOp);
 245             break;
 246 
 247         default:    /* Ignore any extra nodes */
 248 
 249             break;
 250         }
 251 
 252         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
 253     }
 254 
 255     return (Rnode);
 256 }
 257 
 258 
 259 /*******************************************************************************
 260  *
 261  * FUNCTION:    RsDoFixedIoDescriptor
 262  *
 263  * PARAMETERS:  Op                  - Parent resource descriptor parse node
 264  *              CurrentByteOffset   - Offset into the resource template AML
 265  *                                    buffer (to track references to the desc)
 266  *
 267  * RETURN:      Completed resource node
 268  *
 269  * DESCRIPTION: Construct a short "FixedIO" descriptor
 270  *
 271  ******************************************************************************/
 272 
 273 ASL_RESOURCE_NODE *
 274 RsDoFixedIoDescriptor (
 275     ACPI_PARSE_OBJECT       *Op,
 276     UINT32                  CurrentByteOffset)
 277 {
 278     AML_RESOURCE            *Descriptor;
 279     ACPI_PARSE_OBJECT       *InitializerOp;
 280     ACPI_PARSE_OBJECT       *AddressOp = NULL;
 281     ASL_RESOURCE_NODE       *Rnode;
 282     UINT32                  i;
 283 
 284 
 285     InitializerOp = Op->Asl.Child;
 286     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
 287 
 288     Descriptor = Rnode->Buffer;
 289     Descriptor->Io.DescriptorType  = ACPI_RESOURCE_NAME_FIXED_IO |
 290                                       ASL_RDESC_FIXED_IO_SIZE;
 291 
 292     /* Process all child initialization nodes */
 293 
 294     for (i = 0; InitializerOp; i++)
 295     {
 296         switch (i)
 297         {
 298         case 0: /* Base Address */
 299 
 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;
 305             break;
 306 
 307         case 1: /* Length */
 308 
 309             Descriptor->FixedIo.AddressLength =
 310                 (UINT8) InitializerOp->Asl.Value.Integer;
 311             RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
 312                 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
 313             break;
 314 
 315         case 2: /* Name */
 316 
 317             UtAttachNamepathToOwner (Op, InitializerOp);
 318             break;
 319 
 320         default:
 321 
 322             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
 323             break;
 324         }
 325 
 326         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
 327     }
 328 
 329     /* Error checks */
 330 
 331     if (Descriptor->FixedIo.Address > 0x03FF)
 332     {
 333         AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
 334     }
 335 
 336     return (Rnode);
 337 }
 338 
 339 
 340 /*******************************************************************************
 341  *
 342  * FUNCTION:    RsDoIoDescriptor
 343  *
 344  * PARAMETERS:  Op                  - Parent resource descriptor parse node
 345  *              CurrentByteOffset   - Offset into the resource template AML
 346  *                                    buffer (to track references to the desc)
 347  *
 348  * RETURN:      Completed resource node
 349  *
 350  * DESCRIPTION: Construct a short "IO" descriptor
 351  *
 352  ******************************************************************************/
 353 
 354 ASL_RESOURCE_NODE *
 355 RsDoIoDescriptor (
 356     ACPI_PARSE_OBJECT       *Op,
 357     UINT32                  CurrentByteOffset)
 358 {
 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;
 366     UINT32                  i;
 367 
 368 
 369     InitializerOp = Op->Asl.Child;
 370     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
 371 
 372     Descriptor = Rnode->Buffer;
 373     Descriptor->Io.DescriptorType  = ACPI_RESOURCE_NAME_IO |
 374                                       ASL_RDESC_IO_SIZE;
 375 
 376     /* Process all child initialization nodes */
 377 
 378     for (i = 0; InitializerOp; i++)
 379     {
 380         switch (i)
 381         {
 382         case 0: /* Decode size */
 383 
 384             RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
 385             RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
 386                 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
 387             break;
 388 
 389         case 1:  /* Min Address */
 390 
 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;
 396             break;
 397 
 398         case 2: /* Max Address */
 399 
 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;
 405             break;
 406 
 407         case 3: /* Alignment */
 408 
 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;
 414             break;
 415 
 416         case 4: /* Length */
 417 
 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;
 423             break;
 424 
 425         case 5: /* Name */
 426 
 427             UtAttachNamepathToOwner (Op, InitializerOp);
 428             break;
 429 
 430         default:
 431 
 432             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
 433             break;
 434         }
 435 
 436         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
 437     }
 438 
 439     /* Validate the Min/Max/Len/Align values */
 440 
 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);
 447 
 448     return (Rnode);
 449 }
 450 
 451 
 452 /*******************************************************************************
 453  *
 454  * FUNCTION:    RsDoIrqDescriptor
 455  *
 456  * PARAMETERS:  Op                  - Parent resource descriptor parse node
 457  *              CurrentByteOffset   - Offset into the resource template AML
 458  *                                    buffer (to track references to the desc)
 459  *
 460  * RETURN:      Completed resource node
 461  *
 462  * DESCRIPTION: Construct a short "IRQ" descriptor
 463  *
 464  ******************************************************************************/
 465 
 466 ASL_RESOURCE_NODE *
 467 RsDoIrqDescriptor (
 468     ACPI_PARSE_OBJECT       *Op,
 469     UINT32                  CurrentByteOffset)
 470 {
 471     AML_RESOURCE            *Descriptor;
 472     ACPI_PARSE_OBJECT       *InitializerOp;
 473     ASL_RESOURCE_NODE       *Rnode;
 474     UINT32                  Interrupts = 0;
 475     UINT16                  IrqMask = 0;
 476     UINT32                  i;
 477 
 478 
 479     InitializerOp = Op->Asl.Child;
 480     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
 481 
 482     /* Length = 3 (with flag byte) */
 483 
 484     Descriptor = Rnode->Buffer;
 485     Descriptor->Irq.DescriptorType  = ACPI_RESOURCE_NAME_IRQ |
 486                                       (ASL_RDESC_IRQ_SIZE + 0x01);
 487 
 488     /* Process all child initialization nodes */
 489 
 490     for (i = 0; InitializerOp; i++)
 491     {
 492         switch (i)
 493         {
 494         case 0: /* Interrupt Type (or Mode - edge/level) */
 495 
 496             RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
 497             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
 498                 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
 499             break;
 500 
 501         case 1: /* Interrupt Level (or Polarity - Active high/low) */
 502 
 503             RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
 504             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
 505                 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
 506             break;
 507 
 508         case 2: /* Share Type - Default: exclusive (0) */
 509 
 510             RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
 511             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
 512                 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
 513             break;
 514 
 515         case 3: /* Name */
 516 
 517             UtAttachNamepathToOwner (Op, InitializerOp);
 518             break;
 519 
 520         default:
 521 
 522             /* All IRQ bytes are handled here, after the flags and name */
 523 
 524             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
 525             {
 526                 /* Up to 16 interrupts can be specified in the list */
 527 
 528                 Interrupts++;
 529                 if (Interrupts > 16)
 530                 {
 531                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
 532                         InitializerOp, NULL);
 533                     return (Rnode);
 534                 }
 535 
 536                 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
 537 
 538                 if (InitializerOp->Asl.Value.Integer > 15)
 539                 {
 540                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
 541                         InitializerOp, NULL);
 542                 }
 543                 else
 544                 {
 545                     IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
 546                 }
 547             }
 548 
 549             /* Case 4: First IRQ value in list */
 550 
 551             if (i == 4)
 552             {
 553                 /* Check now for duplicates in list */
 554 
 555                 RsCheckListForDuplicates (InitializerOp);
 556 
 557                 /* Create a named field at the start of the list */
 558 
 559                 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
 560                     CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
 561             }
 562             break;
 563         }
 564 
 565         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
 566     }
 567 
 568     /* Now we can set the channel mask */
 569 
 570     Descriptor->Irq.IrqMask = IrqMask;
 571     return (Rnode);
 572 }
 573 
 574 
 575 /*******************************************************************************
 576  *
 577  * FUNCTION:    RsDoIrqNoFlagsDescriptor
 578  *
 579  * PARAMETERS:  Op                  - Parent resource descriptor parse node
 580  *              CurrentByteOffset   - Offset into the resource template AML
 581  *                                    buffer (to track references to the desc)
 582  *
 583  * RETURN:      Completed resource node
 584  *
 585  * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
 586  *
 587  ******************************************************************************/
 588 
 589 ASL_RESOURCE_NODE *
 590 RsDoIrqNoFlagsDescriptor (
 591     ACPI_PARSE_OBJECT       *Op,
 592     UINT32                  CurrentByteOffset)
 593 {
 594     AML_RESOURCE            *Descriptor;
 595     ACPI_PARSE_OBJECT       *InitializerOp;
 596     ASL_RESOURCE_NODE       *Rnode;
 597     UINT16                  IrqMask = 0;
 598     UINT32                  Interrupts = 0;
 599     UINT32                  i;
 600 
 601 
 602     InitializerOp = Op->Asl.Child;
 603     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
 604 
 605     Descriptor = Rnode->Buffer;
 606     Descriptor->Irq.DescriptorType  = ACPI_RESOURCE_NAME_IRQ |
 607                                       ASL_RDESC_IRQ_SIZE;
 608 
 609     /* Process all child initialization nodes */
 610 
 611     for (i = 0; InitializerOp; i++)
 612     {
 613         switch (i)
 614         {
 615         case 0: /* Name */
 616 
 617             UtAttachNamepathToOwner (Op, InitializerOp);
 618             break;
 619 
 620         default:
 621 
 622             /* IRQ bytes are handled here, after the flags and name */
 623 
 624             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
 625             {
 626                 /* Up to 16 interrupts can be specified in the list */
 627 
 628                 Interrupts++;
 629                 if (Interrupts > 16)
 630                 {
 631                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
 632                         InitializerOp, NULL);
 633                     return (Rnode);
 634                 }
 635 
 636                 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
 637 
 638                 if (InitializerOp->Asl.Value.Integer > 15)
 639                 {
 640                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
 641                         InitializerOp, NULL);
 642                 }
 643                 else
 644                 {
 645                     IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
 646                 }
 647             }
 648 
 649             /* Case 1: First IRQ value in list */
 650 
 651             if (i == 1)
 652             {
 653                 /* Check now for duplicates in list */
 654 
 655                 RsCheckListForDuplicates (InitializerOp);
 656 
 657                 /* Create a named field at the start of the list */
 658 
 659                 RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
 660                     CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
 661             }
 662             break;
 663         }
 664 
 665         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
 666     }
 667 
 668     /* Now we can set the interrupt mask */
 669 
 670     Descriptor->Irq.IrqMask = IrqMask;
 671     return (Rnode);
 672 }