aslrestype1i.c revision 217365
1 2/****************************************************************************** 3 * 4 * Module Name: aslrestype1i - Small I/O-related resource descriptors 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2011, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 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. 26 * 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. 30 * 31 * NO WARRANTY 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. 43 */ 44 45 46#include <contrib/dev/acpica/compiler/aslcompiler.h> 47#include "aslcompiler.y.h" 48 49#define _COMPONENT ACPI_COMPILER 50 ACPI_MODULE_NAME ("aslrestype1i") 51 52/* 53 * This module contains the I/O-related small resource descriptors: 54 * 55 * DMA 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 76ASL_RESOURCE_NODE * 77RsDoDmaDescriptor ( 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 RsCreateBitField (InitializerOp, ACPI_RESTAG_DMATYPE, 106 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5); 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 RsCreateBitField (InitializerOp, ACPI_RESTAG_XFERTYPE, 120 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0); 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: RsDoFixedIoDescriptor 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 "FixedIO" descriptor 194 * 195 ******************************************************************************/ 196 197ASL_RESOURCE_NODE * 198RsDoFixedIoDescriptor ( 199 ACPI_PARSE_OBJECT *Op, 200 UINT32 CurrentByteOffset) 201{ 202 AML_RESOURCE *Descriptor; 203 ACPI_PARSE_OBJECT *InitializerOp; 204 ACPI_PARSE_OBJECT *AddressOp = NULL; 205 ASL_RESOURCE_NODE *Rnode; 206 UINT32 i; 207 208 209 InitializerOp = Op->Asl.Child; 210 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO)); 211 212 Descriptor = Rnode->Buffer; 213 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_FIXED_IO | 214 ASL_RDESC_FIXED_IO_SIZE; 215 216 /* Process all child initialization nodes */ 217 218 for (i = 0; InitializerOp; i++) 219 { 220 switch (i) 221 { 222 case 0: /* Base Address */ 223 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; 229 break; 230 231 case 1: /* Length */ 232 233 Descriptor->FixedIo.AddressLength = 234 (UINT8) InitializerOp->Asl.Value.Integer; 235 RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, 236 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength)); 237 break; 238 239 case 2: /* Name */ 240 241 UtAttachNamepathToOwner (Op, InitializerOp); 242 break; 243 244 default: 245 246 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 247 break; 248 } 249 250 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 251 } 252 253 /* Error checks */ 254 255 if (Descriptor->FixedIo.Address > 0x03FF) 256 { 257 AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL); 258 } 259 260 return (Rnode); 261} 262 263 264/******************************************************************************* 265 * 266 * FUNCTION: RsDoIoDescriptor 267 * 268 * PARAMETERS: Op - Parent resource descriptor parse node 269 * CurrentByteOffset - Offset into the resource template AML 270 * buffer (to track references to the desc) 271 * 272 * RETURN: Completed resource node 273 * 274 * DESCRIPTION: Construct a short "IO" descriptor 275 * 276 ******************************************************************************/ 277 278ASL_RESOURCE_NODE * 279RsDoIoDescriptor ( 280 ACPI_PARSE_OBJECT *Op, 281 UINT32 CurrentByteOffset) 282{ 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; 290 UINT32 i; 291 292 293 InitializerOp = Op->Asl.Child; 294 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO)); 295 296 Descriptor = Rnode->Buffer; 297 Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_IO | 298 ASL_RDESC_IO_SIZE; 299 300 /* Process all child initialization nodes */ 301 302 for (i = 0; InitializerOp; i++) 303 { 304 switch (i) 305 { 306 case 0: /* Decode size */ 307 308 RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1); 309 RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE, 310 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0); 311 break; 312 313 case 1: /* Min Address */ 314 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; 320 break; 321 322 case 2: /* Max Address */ 323 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; 329 break; 330 331 case 3: /* Alignment */ 332 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; 338 break; 339 340 case 4: /* Length */ 341 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; 347 break; 348 349 case 5: /* Name */ 350 351 UtAttachNamepathToOwner (Op, InitializerOp); 352 break; 353 354 default: 355 356 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 357 break; 358 } 359 360 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 361 } 362 363 /* Validate the Min/Max/Len/Align values */ 364 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); 371 372 return (Rnode); 373} 374 375 376/******************************************************************************* 377 * 378 * FUNCTION: RsDoIrqDescriptor 379 * 380 * PARAMETERS: Op - Parent resource descriptor parse node 381 * CurrentByteOffset - Offset into the resource template AML 382 * buffer (to track references to the desc) 383 * 384 * RETURN: Completed resource node 385 * 386 * DESCRIPTION: Construct a short "IRQ" descriptor 387 * 388 ******************************************************************************/ 389 390ASL_RESOURCE_NODE * 391RsDoIrqDescriptor ( 392 ACPI_PARSE_OBJECT *Op, 393 UINT32 CurrentByteOffset) 394{ 395 AML_RESOURCE *Descriptor; 396 ACPI_PARSE_OBJECT *InitializerOp; 397 ASL_RESOURCE_NODE *Rnode; 398 UINT32 Interrupts = 0; 399 UINT16 IrqMask = 0; 400 UINT32 i; 401 402 403 InitializerOp = Op->Asl.Child; 404 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ)); 405 406 /* Length = 3 (with flag byte) */ 407 408 Descriptor = Rnode->Buffer; 409 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ | 410 (ASL_RDESC_IRQ_SIZE + 0x01); 411 412 /* Process all child initialization nodes */ 413 414 for (i = 0; InitializerOp; i++) 415 { 416 switch (i) 417 { 418 case 0: /* Interrupt Type (or Mode - edge/level) */ 419 420 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1); 421 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, 422 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0); 423 break; 424 425 case 1: /* Interrupt Level (or Polarity - Active high/low) */ 426 427 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0); 428 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, 429 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3); 430 break; 431 432 case 2: /* Share Type - Default: exclusive (0) */ 433 434 RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0); 435 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 436 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4); 437 break; 438 439 case 3: /* Name */ 440 441 UtAttachNamepathToOwner (Op, InitializerOp); 442 break; 443 444 default: 445 446 /* All IRQ bytes are handled here, after the flags and name */ 447 448 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 449 { 450 /* Up to 16 interrupts can be specified in the list */ 451 452 Interrupts++; 453 if (Interrupts > 16) 454 { 455 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST, 456 InitializerOp, NULL); 457 return (Rnode); 458 } 459 460 /* Only interrupts 0-15 are allowed (mask is 16 bits) */ 461 462 if (InitializerOp->Asl.Value.Integer > 15) 463 { 464 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER, 465 InitializerOp, NULL); 466 } 467 else 468 { 469 IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer); 470 } 471 } 472 473 /* Case 4: First IRQ value in list */ 474 475 if (i == 4) 476 { 477 /* Check now for duplicates in list */ 478 479 RsCheckListForDuplicates (InitializerOp); 480 481 /* Create a named field at the start of the list */ 482 483 RsCreateByteField (InitializerOp, ACPI_RESTAG_INTERRUPT, 484 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask)); 485 } 486 break; 487 } 488 489 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 490 } 491 492 /* Now we can set the channel mask */ 493 494 Descriptor->Irq.IrqMask = IrqMask; 495 return (Rnode); 496} 497 498 499/******************************************************************************* 500 * 501 * FUNCTION: RsDoIrqNoFlagsDescriptor 502 * 503 * PARAMETERS: Op - Parent resource descriptor parse node 504 * CurrentByteOffset - Offset into the resource template AML 505 * buffer (to track references to the desc) 506 * 507 * RETURN: Completed resource node 508 * 509 * DESCRIPTION: Construct a short "IRQNoFlags" descriptor 510 * 511 ******************************************************************************/ 512 513ASL_RESOURCE_NODE * 514RsDoIrqNoFlagsDescriptor ( 515 ACPI_PARSE_OBJECT *Op, 516 UINT32 CurrentByteOffset) 517{ 518 AML_RESOURCE *Descriptor; 519 ACPI_PARSE_OBJECT *InitializerOp; 520 ASL_RESOURCE_NODE *Rnode; 521 UINT16 IrqMask = 0; 522 UINT32 Interrupts = 0; 523 UINT32 i; 524 525 526 InitializerOp = Op->Asl.Child; 527 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS)); 528 529 Descriptor = Rnode->Buffer; 530 Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ | 531 ASL_RDESC_IRQ_SIZE; 532 533 /* Process all child initialization nodes */ 534 535 for (i = 0; InitializerOp; i++) 536 { 537 switch (i) 538 { 539 case 0: /* Name */ 540 541 UtAttachNamepathToOwner (Op, InitializerOp); 542 break; 543 544 default: 545 546 /* IRQ bytes are handled here, after the flags and name */ 547 548 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 549 { 550 /* Up to 16 interrupts can be specified in the list */ 551 552 Interrupts++; 553 if (Interrupts > 16) 554 { 555 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST, 556 InitializerOp, NULL); 557 return (Rnode); 558 } 559 560 /* Only interrupts 0-15 are allowed (mask is 16 bits) */ 561 562 if (InitializerOp->Asl.Value.Integer > 15) 563 { 564 AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER, 565 InitializerOp, NULL); 566 } 567 else 568 { 569 IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer)); 570 } 571 } 572 573 /* Case 1: First IRQ value in list */ 574 575 if (i == 1) 576 { 577 /* Check now for duplicates in list */ 578 579 RsCheckListForDuplicates (InitializerOp); 580 581 /* Create a named field at the start of the list */ 582 583 RsCreateByteField (InitializerOp, ACPI_RESTAG_INTERRUPT, 584 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask)); 585 } 586 break; 587 } 588 589 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 590 } 591 592 /* Now we can set the interrupt mask */ 593 594 Descriptor->Irq.IrqMask = IrqMask; 595 return (Rnode); 596} 597