1 2 /****************************************************************************** 3 * 4 * Module Name: aslresource - Resource template/descriptor utilities 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 118 #include <contrib/dev/acpica/compiler/aslcompiler.h> 119 #include "aslcompiler.y.h" 120 #include <contrib/dev/acpica/include/amlcode.h> 121 122 123 #define _COMPONENT ACPI_COMPILER 124 ACPI_MODULE_NAME ("aslresource") 125 126 127 /******************************************************************************* 128 * 129 * FUNCTION: RsSmallAddressCheck 130 * 131 * PARAMETERS: Minimum - Address Min value 132 * Maximum - Address Max value 133 * Length - Address range value 134 * Alignment - Address alignment value 135 * MinOp - Original Op for Address Min 136 * MaxOp - Original Op for Address Max 137 * LengthOp - Original Op for address range 138 * AlignOp - Original Op for address alignment. If 139 * NULL, means "zero value for alignment is 140 * OK, and means 64K alignment" (for 141 * Memory24 descriptor) 142 * 143 * RETURN: None. Adds error messages to error log if necessary 144 * 145 * DESCRIPTION: Perform common value checks for "small" address descriptors. 146 * Currently: 147 * Io, Memory24, Memory32 148 * 149 ******************************************************************************/ 150 151 void 152 RsSmallAddressCheck ( 153 UINT8 Type, 154 UINT32 Minimum, 155 UINT32 Maximum, 156 UINT32 Length, 157 UINT32 Alignment, 158 ACPI_PARSE_OBJECT *MinOp, 159 ACPI_PARSE_OBJECT *MaxOp, 160 ACPI_PARSE_OBJECT *LengthOp, 161 ACPI_PARSE_OBJECT *AlignOp) 162 { 163 164 if (Gbl_NoResourceChecking) 165 { 166 return; 167 } 168 169 /* Special case for Memory24, values are compressed */ 170 171 if (Type == ACPI_RESOURCE_NAME_MEMORY24) 172 { 173 if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */ 174 { 175 Alignment = ACPI_UINT16_MAX + 1; 176 } 177 178 Minimum <<= 8; 179 Maximum <<= 8; 180 Length *= 256; 181 } 182 183 /* IO descriptor has different definition of min/max, don't check */ 184 185 if (Type != ACPI_RESOURCE_NAME_IO) 186 { 187 /* Basic checks on Min/Max/Length */ 188 189 if (Minimum > Maximum) 190 { 191 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 192 } 193 else if (Length > (Maximum - Minimum + 1)) 194 { 195 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 196 } 197 } 198 199 /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */ 200 201 if (!Alignment) 202 { 203 Alignment = 1; 204 } 205 206 /* Addresses must be an exact multiple of the alignment value */ 207 208 if (Minimum % Alignment) 209 { 210 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 211 } 212 if (Maximum % Alignment) 213 { 214 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL); 215 } 216 } 217 218 219 /******************************************************************************* 220 * 221 * FUNCTION: RsLargeAddressCheck 222 * 223 * PARAMETERS: Minimum - Address Min value 224 * Maximum - Address Max value 225 * Length - Address range value 226 * Granularity - Address granularity value 227 * Flags - General flags for address descriptors: 228 * _MIF, _MAF, _DEC 229 * MinOp - Original Op for Address Min 230 * MaxOp - Original Op for Address Max 231 * LengthOp - Original Op for address range 232 * GranOp - Original Op for address granularity 233 * 234 * RETURN: None. Adds error messages to error log if necessary 235 * 236 * DESCRIPTION: Perform common value checks for "large" address descriptors. 237 * Currently: 238 * WordIo, WordBusNumber, WordSpace 239 * DWordIo, DWordMemory, DWordSpace 240 * QWordIo, QWordMemory, QWordSpace 241 * ExtendedIo, ExtendedMemory, ExtendedSpace 242 * 243 * _MIF flag set means that the minimum address is fixed and is not relocatable 244 * _MAF flag set means that the maximum address is fixed and is not relocatable 245 * Length of zero means that the record size is variable 246 * 247 * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40 248 * of the ACPI 4.0a specification. Added 04/2010. 249 * 250 ******************************************************************************/ 251 252 void 253 RsLargeAddressCheck ( 254 UINT64 Minimum, 255 UINT64 Maximum, 256 UINT64 Length, 257 UINT64 Granularity, 258 UINT8 Flags, 259 ACPI_PARSE_OBJECT *MinOp, 260 ACPI_PARSE_OBJECT *MaxOp, 261 ACPI_PARSE_OBJECT *LengthOp, 262 ACPI_PARSE_OBJECT *GranOp) 263 { 264 265 if (Gbl_NoResourceChecking) 266 { 267 return; 268 } 269 270 /* Basic checks on Min/Max/Length */ 271 272 if (Minimum > Maximum) 273 { 274 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 275 return; 276 } 277 else if (Length > (Maximum - Minimum + 1)) 278 { 279 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 280 return; 281 } 282 283 /* If specified (non-zero), ensure granularity is a power-of-two minus one */ 284 285 if (Granularity) 286 { 287 if ((Granularity + 1) & 288 Granularity) 289 { 290 AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL); 291 return; 292 } 293 } 294 295 /* 296 * Check the various combinations of Length, MinFixed, and MaxFixed 297 */ 298 if (Length) 299 { 300 /* Fixed non-zero length */ 301 302 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 303 { 304 case 0: 305 /* 306 * Fixed length, variable locations (both _MIN and _MAX). 307 * Length must be a multiple of granularity 308 */ 309 if (Granularity & Length) 310 { 311 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL); 312 } 313 break; 314 315 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 316 317 /* Fixed length, fixed location. Granularity must be zero */ 318 319 if (Granularity != 0) 320 { 321 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL); 322 } 323 324 /* Length must be exactly the size of the min/max window */ 325 326 if (Length != (Maximum - Minimum + 1)) 327 { 328 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL); 329 } 330 break; 331 332 /* All other combinations are invalid */ 333 334 case ACPI_RESOURCE_FLAG_MIF: 335 case ACPI_RESOURCE_FLAG_MAF: 336 default: 337 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 338 } 339 } 340 else 341 { 342 /* Variable length (length==0) */ 343 344 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 345 { 346 case 0: 347 /* 348 * Both _MIN and _MAX are variable. 349 * No additional requirements, just exit 350 */ 351 break; 352 353 case ACPI_RESOURCE_FLAG_MIF: 354 355 /* _MIN is fixed. _MIN must be multiple of _GRA */ 356 357 /* 358 * The granularity is defined by the ACPI specification to be a 359 * power-of-two minus one, therefore the granularity is a 360 * bitmask which can be used to easily validate the addresses. 361 */ 362 if (Granularity & Minimum) 363 { 364 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 365 } 366 break; 367 368 case ACPI_RESOURCE_FLAG_MAF: 369 370 /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */ 371 372 if (Granularity & (Maximum + 1)) 373 { 374 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1"); 375 } 376 break; 377 378 /* Both MIF/MAF set is invalid if length is zero */ 379 380 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 381 default: 382 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 383 } 384 } 385 } 386 387 388 /******************************************************************************* 389 * 390 * FUNCTION: RsGetStringDataLength 391 * 392 * PARAMETERS: InitializerOp - Start of a subtree of init nodes 393 * 394 * RETURN: Valid string length if a string node is found (otherwise 0) 395 * 396 * DESCRIPTION: In a list of peer nodes, find the first one that contains a 397 * string and return the length of the string. 398 * 399 ******************************************************************************/ 400 401 UINT16 402 RsGetStringDataLength ( 403 ACPI_PARSE_OBJECT *InitializerOp) 404 { 405 406 while (InitializerOp) 407 { 408 if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 409 { 410 return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1)); 411 } 412 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 413 } 414 415 return 0; 416 } 417 418 419 /******************************************************************************* 420 * 421 * FUNCTION: RsAllocateResourceNode 422 * 423 * PARAMETERS: Size - Size of node in bytes 424 * 425 * RETURN: The allocated node - aborts on allocation failure 426 * 427 * DESCRIPTION: Allocate a resource description node and the resource 428 * descriptor itself (the nodes are used to link descriptors). 429 * 430 ******************************************************************************/ 431 432 ASL_RESOURCE_NODE * 433 RsAllocateResourceNode ( 434 UINT32 Size) 435 { 436 ASL_RESOURCE_NODE *Rnode; 437 438 439 /* Allocate the node */ 440 441 Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE)); 442 443 /* Allocate the resource descriptor itself */ 444 445 Rnode->Buffer = UtLocalCalloc (Size); 446 Rnode->BufferLength = Size; 447 448 return (Rnode); 449 } 450 451 452 /******************************************************************************* 453 * 454 * FUNCTION: RsCreateBitField 455 * 456 * PARAMETERS: Op - Resource field node 457 * Name - Name of the field (Used only to reference 458 * the field in the ASL, not in the AML) 459 * ByteOffset - Offset from the field start 460 * BitOffset - Additional bit offset 461 * 462 * RETURN: None, sets fields within the input node 463 * 464 * DESCRIPTION: Utility function to generate a named bit field within a 465 * resource descriptor. Mark a node as 1) a field in a resource 466 * descriptor, and 2) set the value to be a BIT offset 467 * 468 ******************************************************************************/ 469 470 void 471 RsCreateBitField ( 472 ACPI_PARSE_OBJECT *Op, 473 char *Name, 474 UINT32 ByteOffset, 475 UINT32 BitOffset) 476 { 477 478 Op->Asl.ExternalName = Name; 479 Op->Asl.Value.Integer = ((UINT64) ByteOffset * 8) + BitOffset; 480 Op->Asl.CompileFlags |= (NODE_IS_RESOURCE_FIELD | NODE_IS_BIT_OFFSET); 481 } 482 483 484 /******************************************************************************* 485 * 486 * FUNCTION: RsCreateByteField 487 * 488 * PARAMETERS: Op - Resource field node 489 * Name - Name of the field (Used only to reference 490 * the field in the ASL, not in the AML) 491 * ByteOffset - Offset from the field start 492 * 493 * RETURN: None, sets fields within the input node 494 * 495 * DESCRIPTION: Utility function to generate a named byte field within a 496 * resource descriptor. Mark a node as 1) a field in a resource 497 * descriptor, and 2) set the value to be a BYTE offset 498 * 499 ******************************************************************************/ 500 501 void 502 RsCreateByteField ( 503 ACPI_PARSE_OBJECT *Op, 504 char *Name, 505 UINT32 ByteOffset) 506 { 507 508 Op->Asl.ExternalName = Name; 509 Op->Asl.Value.Integer = ByteOffset; 510 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 511 } 512 513 514 /******************************************************************************* 515 * 516 * FUNCTION: RsSetFlagBits 517 * 518 * PARAMETERS: *Flags - Pointer to the flag byte 519 * Op - Flag initialization node 520 * Position - Bit position within the flag byte 521 * Default - Used if the node is DEFAULT. 522 * 523 * RETURN: Sets bits within the *Flags output byte. 524 * 525 * DESCRIPTION: Set a bit in a cumulative flags word from an initialization 526 * node. Will use a default value if the node is DEFAULT, meaning 527 * that no value was specified in the ASL. Used to merge multiple 528 * keywords into a single flags byte. 529 * 530 ******************************************************************************/ 531 532 void 533 RsSetFlagBits ( 534 UINT8 *Flags, 535 ACPI_PARSE_OBJECT *Op, 536 UINT8 Position, 537 UINT8 DefaultBit) 538 { 539 540 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 541 { 542 /* Use the default bit */ 543 544 *Flags |= (DefaultBit << Position); 545 } 546 else 547 { 548 /* Use the bit specified in the initialization node */ 549 550 *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position); 551 } 552 } 553 554 555 /******************************************************************************* 556 * 557 * FUNCTION: RsCompleteNodeAndGetNext 558 * 559 * PARAMETERS: Op - Resource node to be completed 560 * 561 * RETURN: The next peer to the input node. 562 * 563 * DESCRIPTION: Mark the current node completed and return the next peer. 564 * The node ParseOpcode is set to DEFAULT_ARG, meaning that 565 * this node is to be ignored from now on. 566 * 567 ******************************************************************************/ 568 569 ACPI_PARSE_OBJECT * 570 RsCompleteNodeAndGetNext ( 571 ACPI_PARSE_OBJECT *Op) 572 { 573 574 /* Mark this node unused */ 575 576 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 577 578 /* Move on to the next peer node in the initializer list */ 579 580 return (ASL_GET_PEER_NODE (Op)); 581 } 582 583 584 /******************************************************************************* 585 * 586 * FUNCTION: RsCheckListForDuplicates 587 * 588 * PARAMETERS: Op - First op in the initializer list 589 * 590 * RETURN: None 591 * 592 * DESCRIPTION: Check an initializer list for duplicate values. Emits an error 593 * if any duplicates are found. 594 * 595 ******************************************************************************/ 596 597 void 598 RsCheckListForDuplicates ( 599 ACPI_PARSE_OBJECT *Op) 600 { 601 ACPI_PARSE_OBJECT *NextValueOp = Op; 602 ACPI_PARSE_OBJECT *NextOp; 603 UINT32 Value; 604 605 606 if (!Op) 607 { 608 return; 609 } 610 611 /* Search list once for each value in the list */ 612 613 while (NextValueOp) 614 { 615 Value = (UINT32) NextValueOp->Asl.Value.Integer; 616 617 /* Compare this value to all remaining values in the list */ 618 619 NextOp = ASL_GET_PEER_NODE (NextValueOp); 620 while (NextOp) 621 { 622 if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 623 { 624 /* Compare values */ 625 626 if (Value == (UINT32) NextOp->Asl.Value.Integer) 627 { 628 /* Emit error only once per duplicate node */ 629 630 if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE)) 631 { 632 NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE; 633 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM, 634 NextOp, NULL); 635 } 636 } 637 } 638 639 NextOp = ASL_GET_PEER_NODE (NextOp); 640 } 641 642 NextValueOp = ASL_GET_PEER_NODE (NextValueOp); 643 } 644 } 645 646 647 /******************************************************************************* 648 * 649 * FUNCTION: RsDoOneResourceDescriptor 650 * 651 * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor 652 * CurrentByteOffset - Offset in the resource descriptor 653 * buffer. 654 * 655 * RETURN: A valid resource node for the descriptor 656 * 657 * DESCRIPTION: Dispatches the processing of one resource descriptor 658 * 659 ******************************************************************************/ 660 661 ASL_RESOURCE_NODE * 662 RsDoOneResourceDescriptor ( 663 ACPI_PARSE_OBJECT *DescriptorTypeOp, 664 UINT32 CurrentByteOffset, 665 UINT8 *State) 666 { 667 ASL_RESOURCE_NODE *Rnode = NULL; 668 669 670 /* Construct the resource */ 671 672 switch (DescriptorTypeOp->Asl.ParseOpcode) 673 { 674 case PARSEOP_DMA: 675 Rnode = RsDoDmaDescriptor (DescriptorTypeOp, 676 CurrentByteOffset); 677 break; 678 679 case PARSEOP_DWORDIO: 680 Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp, 681 CurrentByteOffset); 682 break; 683 684 case PARSEOP_DWORDMEMORY: 685 Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp, 686 CurrentByteOffset); 687 break; 688 689 case PARSEOP_DWORDSPACE: 690 Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp, 691 CurrentByteOffset); 692 break; 693 694 case PARSEOP_ENDDEPENDENTFN: 695 switch (*State) 696 { 697 case ACPI_RSTATE_NORMAL: 698 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT, 699 DescriptorTypeOp, NULL); 700 break; 701 702 case ACPI_RSTATE_START_DEPENDENT: 703 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 704 DescriptorTypeOp, NULL); 705 break; 706 707 case ACPI_RSTATE_DEPENDENT_LIST: 708 default: 709 break; 710 } 711 712 *State = ACPI_RSTATE_NORMAL; 713 Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp, 714 CurrentByteOffset); 715 break; 716 717 case PARSEOP_ENDTAG: 718 Rnode = RsDoEndTagDescriptor (DescriptorTypeOp, 719 CurrentByteOffset); 720 break; 721 722 case PARSEOP_EXTENDEDIO: 723 Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp, 724 CurrentByteOffset); 725 break; 726 727 case PARSEOP_EXTENDEDMEMORY: 728 Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp, 729 CurrentByteOffset); 730 break; 731 732 case PARSEOP_EXTENDEDSPACE: 733 Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp, 734 CurrentByteOffset); 735 break; 736 737 case PARSEOP_FIXEDIO: 738 Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp, 739 CurrentByteOffset); 740 break; 741 742 case PARSEOP_INTERRUPT: 743 Rnode = RsDoInterruptDescriptor (DescriptorTypeOp, 744 CurrentByteOffset); 745 break; 746 747 case PARSEOP_IO: 748 Rnode = RsDoIoDescriptor (DescriptorTypeOp, 749 CurrentByteOffset); 750 break; 751 752 case PARSEOP_IRQ: 753 Rnode = RsDoIrqDescriptor (DescriptorTypeOp, 754 CurrentByteOffset); 755 break; 756 757 case PARSEOP_IRQNOFLAGS: 758 Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp, 759 CurrentByteOffset); 760 break; 761 762 case PARSEOP_MEMORY24: 763 Rnode = RsDoMemory24Descriptor (DescriptorTypeOp, 764 CurrentByteOffset); 765 break; 766 767 case PARSEOP_MEMORY32: 768 Rnode = RsDoMemory32Descriptor (DescriptorTypeOp, 769 CurrentByteOffset); 770 break; 771 772 case PARSEOP_MEMORY32FIXED: 773 Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp, 774 CurrentByteOffset); 775 break; 776 777 case PARSEOP_QWORDIO: 778 Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp, 779 CurrentByteOffset); 780 break; 781 782 case PARSEOP_QWORDMEMORY: 783 Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp, 784 CurrentByteOffset); 785 break; 786 787 case PARSEOP_QWORDSPACE: 788 Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp, 789 CurrentByteOffset); 790 break; 791 792 case PARSEOP_REGISTER: 793 Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp, 794 CurrentByteOffset); 795 break; 796 797 case PARSEOP_STARTDEPENDENTFN: 798 switch (*State) 799 { 800 case ACPI_RSTATE_START_DEPENDENT: 801 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 802 DescriptorTypeOp, NULL); 803 break; 804 805 case ACPI_RSTATE_NORMAL: 806 case ACPI_RSTATE_DEPENDENT_LIST: 807 default: 808 break; 809 } 810 811 *State = ACPI_RSTATE_START_DEPENDENT; 812 Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp, 813 CurrentByteOffset); 814 *State = ACPI_RSTATE_DEPENDENT_LIST; 815 break; 816 817 case PARSEOP_STARTDEPENDENTFN_NOPRI: 818 switch (*State) 819 { 820 case ACPI_RSTATE_START_DEPENDENT: 821 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 822 DescriptorTypeOp, NULL); 823 break; 824 825 case ACPI_RSTATE_NORMAL: 826 case ACPI_RSTATE_DEPENDENT_LIST: 827 default: 828 break; 829 } 830 831 *State = ACPI_RSTATE_START_DEPENDENT; 832 Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp, 833 CurrentByteOffset); 834 *State = ACPI_RSTATE_DEPENDENT_LIST; 835 break; 836 837 case PARSEOP_VENDORLONG: 838 Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp, 839 CurrentByteOffset); 840 break; 841 842 case PARSEOP_VENDORSHORT: 843 Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp, 844 CurrentByteOffset); 845 break; 846 847 case PARSEOP_WORDBUSNUMBER: 848 Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp, 849 CurrentByteOffset); 850 break; 851 852 case PARSEOP_WORDIO: 853 Rnode = RsDoWordIoDescriptor (DescriptorTypeOp, 854 CurrentByteOffset); 855 break; 856 857 case PARSEOP_WORDSPACE: 858 Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp, 859 CurrentByteOffset); 860 break; 861 862 case PARSEOP_DEFAULT_ARG: 863 /* Just ignore any of these, they are used as fillers/placeholders */ 864 break; 865 866 default: 867 printf ("Unknown resource descriptor type [%s]\n", 868 DescriptorTypeOp->Asl.ParseOpName); 869 break; 870 } 871 872 /* 873 * Mark original node as unused, but head of a resource descriptor. 874 * This allows the resource to be installed in the namespace so that 875 * references to the descriptor can be resolved. 876 */ 877 DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 878 DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC; 879 DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset; 880 881 if (Rnode) 882 { 883 DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength; 884 } 885 886 return (Rnode); 887 } 888 889 890 /******************************************************************************* 891 * 892 * FUNCTION: RsLinkDescriptorChain 893 * 894 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous 895 * to the linked node, At exit, set to the 896 * last node in the new chain. 897 * Rnode - Resource node to link into the list 898 * 899 * RETURN: Cumulative buffer byte offset of the new segment of chain 900 * 901 * DESCRIPTION: Link a descriptor chain at the end of an existing chain. 902 * 903 ******************************************************************************/ 904 905 UINT32 906 RsLinkDescriptorChain ( 907 ASL_RESOURCE_NODE **PreviousRnode, 908 ASL_RESOURCE_NODE *Rnode) 909 { 910 ASL_RESOURCE_NODE *LastRnode; 911 UINT32 CurrentByteOffset; 912 913 914 /* Anything to do? */ 915 916 if (!Rnode) 917 { 918 return 0; 919 } 920 921 /* Point the previous node to the new node */ 922 923 (*PreviousRnode)->Next = Rnode; 924 CurrentByteOffset = Rnode->BufferLength; 925 926 /* Walk to the end of the chain headed by Rnode */ 927 928 LastRnode = Rnode; 929 while (LastRnode->Next) 930 { 931 LastRnode = LastRnode->Next; 932 CurrentByteOffset += LastRnode->BufferLength; 933 } 934 935 /* Previous node becomes the last node in the chain */ 936 937 *PreviousRnode = LastRnode; 938 return CurrentByteOffset; 939 } 940 941 942 /******************************************************************************* 943 * 944 * FUNCTION: RsDoResourceTemplate 945 * 946 * PARAMETERS: Op - Parent of a resource template list 947 * 948 * RETURN: None. Sets input node to point to a list of AML code 949 * 950 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer, 951 * in preparation for output to the AML output file. 952 * 953 ******************************************************************************/ 954 955 void 956 RsDoResourceTemplate ( 957 ACPI_PARSE_OBJECT *Op) 958 { 959 ACPI_PARSE_OBJECT *BufferLengthOp; 960 ACPI_PARSE_OBJECT *BufferOp; 961 ACPI_PARSE_OBJECT *DescriptorTypeOp; 962 ACPI_PARSE_OBJECT *LastOp = NULL; 963 UINT32 CurrentByteOffset = 0; 964 ASL_RESOURCE_NODE HeadRnode; 965 ASL_RESOURCE_NODE *PreviousRnode; 966 ASL_RESOURCE_NODE *Rnode; 967 UINT8 State; 968 969 970 /* Mark parent as containing a resource template */ 971 972 if (Op->Asl.Parent) 973 { 974 Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 975 } 976 977 /* ResourceTemplate Opcode is first (Op) */ 978 /* Buffer Length node is first child */ 979 980 BufferLengthOp = ASL_GET_CHILD_NODE (Op); 981 982 /* Buffer Op is first peer */ 983 984 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp); 985 986 /* First Descriptor type is next */ 987 988 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp); 989 990 /* 991 * Process all resource descriptors in the list 992 * Note: It is assumed that the EndTag node has been automatically 993 * inserted at the end of the template by the parser. 994 */ 995 State = ACPI_RSTATE_NORMAL; 996 PreviousRnode = &HeadRnode; 997 while (DescriptorTypeOp) 998 { 999 DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 1000 Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset, 1001 &State); 1002 1003 /* 1004 * Update current byte offset to indicate the number of bytes from the 1005 * start of the buffer. Buffer can include multiple descriptors, we 1006 * must keep track of the offset of not only each descriptor, but each 1007 * element (field) within each descriptor as well. 1008 */ 1009 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 1010 1011 /* Get the next descriptor in the list */ 1012 1013 LastOp = DescriptorTypeOp; 1014 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp); 1015 } 1016 1017 if (State == ACPI_RSTATE_DEPENDENT_LIST) 1018 { 1019 if (LastOp) 1020 { 1021 LastOp = LastOp->Asl.Parent; 1022 } 1023 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL); 1024 } 1025 1026 /* 1027 * Transform the nodes into the following 1028 * 1029 * Op -> AML_BUFFER_OP 1030 * First Child -> BufferLength 1031 * Second Child -> Descriptor Buffer (raw byte data) 1032 */ 1033 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1034 Op->Asl.AmlOpcode = AML_BUFFER_OP; 1035 Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC; 1036 1037 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 1038 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset; 1039 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 1040 1041 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 1042 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 1043 BufferOp->Asl.AmlOpcodeLength = 0; 1044 BufferOp->Asl.AmlLength = CurrentByteOffset; 1045 BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next; 1046 BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA; 1047 1048 return; 1049 } 1050 1051 1052