1 /****************************************************************************** 2 * 3 * Module Name: aslresource - Resource template/descriptor utilities 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 #include "amlcode.h" 48 49 50 #define _COMPONENT ACPI_COMPILER 51 ACPI_MODULE_NAME ("aslresource") 52 53 54 /******************************************************************************* 55 * 56 * FUNCTION: RsSmallAddressCheck 57 * 58 * PARAMETERS: Minimum - Address Min value 59 * Maximum - Address Max value 60 * Length - Address range value 61 * Alignment - Address alignment value 62 * MinOp - Original Op for Address Min 63 * MaxOp - Original Op for Address Max 64 * LengthOp - Original Op for address range 65 * AlignOp - Original Op for address alignment. If 66 * NULL, means "zero value for alignment is 67 * OK, and means 64K alignment" (for 68 * Memory24 descriptor) 69 * Op - Parent Op for entire construct 70 * 71 * RETURN: None. Adds error messages to error log if necessary 72 * 73 * DESCRIPTION: Perform common value checks for "small" address descriptors. 74 * Currently: 75 * Io, Memory24, Memory32 76 * 77 ******************************************************************************/ 78 79 void 80 RsSmallAddressCheck ( 81 UINT8 Type, 82 UINT32 Minimum, 83 UINT32 Maximum, 84 UINT32 Length, 85 UINT32 Alignment, 86 ACPI_PARSE_OBJECT *MinOp, 87 ACPI_PARSE_OBJECT *MaxOp, 88 ACPI_PARSE_OBJECT *LengthOp, 89 ACPI_PARSE_OBJECT *AlignOp, 90 ACPI_PARSE_OBJECT *Op) 91 { 92 93 if (Gbl_NoResourceChecking) 94 { 95 return; 96 } 97 98 /* 99 * Check for a so-called "null descriptor". These are descriptors that are 100 * created with most fields set to zero. The intent is that the descriptor 101 * will be updated/completed at runtime via a BufferField. 102 * 103 * If the descriptor does NOT have a resource tag, it cannot be referenced 104 * by a BufferField and we will flag this as an error. Conversely, if 105 * the descriptor has a resource tag, we will assume that a BufferField 106 * will be used to dynamically update it, so no error. 107 * 108 * A possible enhancement to this check would be to verify that in fact 109 * a BufferField is created using the resource tag, and perhaps even 110 * verify that a Store is performed to the BufferField. 111 * 112 * Note: for these descriptors, Alignment is allowed to be zero 113 */ 114 if (!Minimum && !Maximum && !Length) 115 { 116 if (!Op->Asl.ExternalName) 117 { 118 /* No resource tag. Descriptor is fixed and is also illegal */ 119 120 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL); 121 } 122 123 return; 124 } 125 126 /* Special case for Memory24, values are compressed */ 127 128 if (Type == ACPI_RESOURCE_NAME_MEMORY24) 129 { 130 if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */ 131 { 132 Alignment = ACPI_UINT16_MAX + 1; 133 } 134 135 Minimum <<= 8; 136 Maximum <<= 8; 137 Length *= 256; 138 } 139 140 /* IO descriptor has different definition of min/max, don't check */ 141 142 if (Type != ACPI_RESOURCE_NAME_IO) 143 { 144 /* Basic checks on Min/Max/Length */ 145 146 if (Minimum > Maximum) 147 { 148 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 149 } 150 else if (Length > (Maximum - Minimum + 1)) 151 { 152 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 153 } 154 } 155 156 /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */ 157 158 if (!Alignment) 159 { 160 Alignment = 1; 161 } 162 163 /* Addresses must be an exact multiple of the alignment value */ 164 165 if (Minimum % Alignment) 166 { 167 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 168 } 169 if (Maximum % Alignment) 170 { 171 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL); 172 } 173 } 174 175 176 /******************************************************************************* 177 * 178 * FUNCTION: RsLargeAddressCheck 179 * 180 * PARAMETERS: Minimum - Address Min value 181 * Maximum - Address Max value 182 * Length - Address range value 183 * Granularity - Address granularity value 184 * Flags - General flags for address descriptors: 185 * _MIF, _MAF, _DEC 186 * MinOp - Original Op for Address Min 187 * MaxOp - Original Op for Address Max 188 * LengthOp - Original Op for address range 189 * GranOp - Original Op for address granularity 190 * Op - Parent Op for entire construct 191 * 192 * RETURN: None. Adds error messages to error log if necessary 193 * 194 * DESCRIPTION: Perform common value checks for "large" address descriptors. 195 * Currently: 196 * WordIo, WordBusNumber, WordSpace 197 * DWordIo, DWordMemory, DWordSpace 198 * QWordIo, QWordMemory, QWordSpace 199 * ExtendedIo, ExtendedMemory, ExtendedSpace 200 * 201 * _MIF flag set means that the minimum address is fixed and is not relocatable 202 * _MAF flag set means that the maximum address is fixed and is not relocatable 203 * Length of zero means that the record size is variable 204 * 205 * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40 206 * of the ACPI 4.0a specification. Added 04/2010. 207 * 208 ******************************************************************************/ 209 210 void 211 RsLargeAddressCheck ( 212 UINT64 Minimum, 213 UINT64 Maximum, 214 UINT64 Length, 215 UINT64 Granularity, 216 UINT8 Flags, 217 ACPI_PARSE_OBJECT *MinOp, 218 ACPI_PARSE_OBJECT *MaxOp, 219 ACPI_PARSE_OBJECT *LengthOp, 220 ACPI_PARSE_OBJECT *GranOp, 221 ACPI_PARSE_OBJECT *Op) 222 { 223 224 if (Gbl_NoResourceChecking) 225 { 226 return; 227 } 228 229 /* 230 * Check for a so-called "null descriptor". These are descriptors that are 231 * created with most fields set to zero. The intent is that the descriptor 232 * will be updated/completed at runtime via a BufferField. 233 * 234 * If the descriptor does NOT have a resource tag, it cannot be referenced 235 * by a BufferField and we will flag this as an error. Conversely, if 236 * the descriptor has a resource tag, we will assume that a BufferField 237 * will be used to dynamically update it, so no error. 238 * 239 * A possible enhancement to this check would be to verify that in fact 240 * a BufferField is created using the resource tag, and perhaps even 241 * verify that a Store is performed to the BufferField. 242 */ 243 if (!Minimum && !Maximum && !Length && !Granularity) 244 { 245 if (!Op->Asl.ExternalName) 246 { 247 /* No resource tag. Descriptor is fixed and is also illegal */ 248 249 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL); 250 } 251 252 return; 253 } 254 255 /* Basic checks on Min/Max/Length */ 256 257 if (Minimum > Maximum) 258 { 259 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 260 return; 261 } 262 else if (Length > (Maximum - Minimum + 1)) 263 { 264 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 265 return; 266 } 267 268 /* If specified (non-zero), ensure granularity is a power-of-two minus one */ 269 270 if (Granularity) 271 { 272 if ((Granularity + 1) & 273 Granularity) 274 { 275 AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL); 276 return; 277 } 278 } 279 280 /* 281 * Check the various combinations of Length, MinFixed, and MaxFixed 282 */ 283 if (Length) 284 { 285 /* Fixed non-zero length */ 286 287 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 288 { 289 case 0: 290 /* 291 * Fixed length, variable locations (both _MIN and _MAX). 292 * Length must be a multiple of granularity 293 */ 294 if (Granularity & Length) 295 { 296 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL); 297 } 298 break; 299 300 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 301 302 /* Fixed length, fixed location. Granularity must be zero */ 303 304 if (Granularity != 0) 305 { 306 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL); 307 } 308 309 /* Length must be exactly the size of the min/max window */ 310 311 if (Length != (Maximum - Minimum + 1)) 312 { 313 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL); 314 } 315 break; 316 317 /* All other combinations are invalid */ 318 319 case ACPI_RESOURCE_FLAG_MIF: 320 case ACPI_RESOURCE_FLAG_MAF: 321 default: 322 323 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 324 } 325 } 326 else 327 { 328 /* Variable length (length==0) */ 329 330 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 331 { 332 case 0: 333 /* 334 * Both _MIN and _MAX are variable. 335 * No additional requirements, just exit 336 */ 337 break; 338 339 case ACPI_RESOURCE_FLAG_MIF: 340 341 /* _MIN is fixed. _MIN must be multiple of _GRA */ 342 343 /* 344 * The granularity is defined by the ACPI specification to be a 345 * power-of-two minus one, therefore the granularity is a 346 * bitmask which can be used to easily validate the addresses. 347 */ 348 if (Granularity & Minimum) 349 { 350 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 351 } 352 break; 353 354 case ACPI_RESOURCE_FLAG_MAF: 355 356 /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */ 357 358 if (Granularity & (Maximum + 1)) 359 { 360 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1"); 361 } 362 break; 363 364 /* Both MIF/MAF set is invalid if length is zero */ 365 366 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 367 default: 368 369 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 370 } 371 } 372 } 373 374 375 /******************************************************************************* 376 * 377 * FUNCTION: RsGetStringDataLength 378 * 379 * PARAMETERS: InitializerOp - Start of a subtree of init nodes 380 * 381 * RETURN: Valid string length if a string node is found (otherwise 0) 382 * 383 * DESCRIPTION: In a list of peer nodes, find the first one that contains a 384 * string and return the length of the string. 385 * 386 ******************************************************************************/ 387 388 UINT16 389 RsGetStringDataLength ( 390 ACPI_PARSE_OBJECT *InitializerOp) 391 { 392 393 while (InitializerOp) 394 { 395 if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 396 { 397 return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1)); 398 } 399 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 400 } 401 402 return (0); 403 } 404 405 406 /******************************************************************************* 407 * 408 * FUNCTION: RsAllocateResourceNode 409 * 410 * PARAMETERS: Size - Size of node in bytes 411 * 412 * RETURN: The allocated node - aborts on allocation failure 413 * 414 * DESCRIPTION: Allocate a resource description node and the resource 415 * descriptor itself (the nodes are used to link descriptors). 416 * 417 ******************************************************************************/ 418 419 ASL_RESOURCE_NODE * 420 RsAllocateResourceNode ( 421 UINT32 Size) 422 { 423 ASL_RESOURCE_NODE *Rnode; 424 425 426 /* Allocate the node */ 427 428 Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE)); 429 430 /* Allocate the resource descriptor itself */ 431 432 Rnode->Buffer = UtLocalCalloc (Size); 433 Rnode->BufferLength = Size; 434 435 return (Rnode); 436 } 437 438 439 /******************************************************************************* 440 * 441 * FUNCTION: RsCreateResourceField 442 * 443 * PARAMETERS: Op - Resource field node 444 * Name - Name of the field (Used only to reference 445 * the field in the ASL, not in the AML) 446 * ByteOffset - Offset from the field start 447 * BitOffset - Additional bit offset 448 * BitLength - Number of bits in the field 449 * 450 * RETURN: None, sets fields within the input node 451 * 452 * DESCRIPTION: Utility function to generate a named bit field within a 453 * resource descriptor. Mark a node as 1) a field in a resource 454 * descriptor, and 2) set the value to be a BIT offset 455 * 456 ******************************************************************************/ 457 458 void 459 RsCreateResourceField ( 460 ACPI_PARSE_OBJECT *Op, 461 char *Name, 462 UINT32 ByteOffset, 463 UINT32 BitOffset, 464 UINT32 BitLength) 465 { 466 467 Op->Asl.ExternalName = Name; 468 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 469 470 471 Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset; 472 Op->Asl.Value.Tag.BitLength = BitLength; 473 } 474 475 476 /******************************************************************************* 477 * 478 * FUNCTION: RsSetFlagBits 479 * 480 * PARAMETERS: *Flags - Pointer to the flag byte 481 * Op - Flag initialization node 482 * Position - Bit position within the flag byte 483 * Default - Used if the node is DEFAULT. 484 * 485 * RETURN: Sets bits within the *Flags output byte. 486 * 487 * DESCRIPTION: Set a bit in a cumulative flags word from an initialization 488 * node. Will use a default value if the node is DEFAULT, meaning 489 * that no value was specified in the ASL. Used to merge multiple 490 * keywords into a single flags byte. 491 * 492 ******************************************************************************/ 493 494 void 495 RsSetFlagBits ( 496 UINT8 *Flags, 497 ACPI_PARSE_OBJECT *Op, 498 UINT8 Position, 499 UINT8 DefaultBit) 500 { 501 502 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 503 { 504 /* Use the default bit */ 505 506 *Flags |= (DefaultBit << Position); 507 } 508 else 509 { 510 /* Use the bit specified in the initialization node */ 511 512 *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position); 513 } 514 } 515 516 517 void 518 RsSetFlagBits16 ( 519 UINT16 *Flags, 520 ACPI_PARSE_OBJECT *Op, 521 UINT8 Position, 522 UINT8 DefaultBit) 523 { 524 525 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 526 { 527 /* Use the default bit */ 528 529 *Flags |= (DefaultBit << Position); 530 } 531 else 532 { 533 /* Use the bit specified in the initialization node */ 534 535 *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position); 536 } 537 } 538 539 540 /******************************************************************************* 541 * 542 * FUNCTION: RsCompleteNodeAndGetNext 543 * 544 * PARAMETERS: Op - Resource node to be completed 545 * 546 * RETURN: The next peer to the input node. 547 * 548 * DESCRIPTION: Mark the current node completed and return the next peer. 549 * The node ParseOpcode is set to DEFAULT_ARG, meaning that 550 * this node is to be ignored from now on. 551 * 552 ******************************************************************************/ 553 554 ACPI_PARSE_OBJECT * 555 RsCompleteNodeAndGetNext ( 556 ACPI_PARSE_OBJECT *Op) 557 { 558 559 /* Mark this node unused */ 560 561 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 562 563 /* Move on to the next peer node in the initializer list */ 564 565 return (ASL_GET_PEER_NODE (Op)); 566 } 567 568 569 /******************************************************************************* 570 * 571 * FUNCTION: RsCheckListForDuplicates 572 * 573 * PARAMETERS: Op - First op in the initializer list 574 * 575 * RETURN: None 576 * 577 * DESCRIPTION: Check an initializer list for duplicate values. Emits an error 578 * if any duplicates are found. 579 * 580 ******************************************************************************/ 581 582 void 583 RsCheckListForDuplicates ( 584 ACPI_PARSE_OBJECT *Op) 585 { 586 ACPI_PARSE_OBJECT *NextValueOp = Op; 587 ACPI_PARSE_OBJECT *NextOp; 588 UINT32 Value; 589 590 591 if (!Op) 592 { 593 return; 594 } 595 596 /* Search list once for each value in the list */ 597 598 while (NextValueOp) 599 { 600 Value = (UINT32) NextValueOp->Asl.Value.Integer; 601 602 /* Compare this value to all remaining values in the list */ 603 604 NextOp = ASL_GET_PEER_NODE (NextValueOp); 605 while (NextOp) 606 { 607 if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 608 { 609 /* Compare values */ 610 611 if (Value == (UINT32) NextOp->Asl.Value.Integer) 612 { 613 /* Emit error only once per duplicate node */ 614 615 if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE)) 616 { 617 NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE; 618 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM, 619 NextOp, NULL); 620 } 621 } 622 } 623 624 NextOp = ASL_GET_PEER_NODE (NextOp); 625 } 626 627 NextValueOp = ASL_GET_PEER_NODE (NextValueOp); 628 } 629 } 630 631 632 /******************************************************************************* 633 * 634 * FUNCTION: RsDoOneResourceDescriptor 635 * 636 * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor 637 * CurrentByteOffset - Offset in the resource descriptor 638 * buffer. 639 * 640 * RETURN: A valid resource node for the descriptor 641 * 642 * DESCRIPTION: Dispatches the processing of one resource descriptor 643 * 644 ******************************************************************************/ 645 646 ASL_RESOURCE_NODE * 647 RsDoOneResourceDescriptor ( 648 ACPI_PARSE_OBJECT *DescriptorTypeOp, 649 UINT32 CurrentByteOffset, 650 UINT8 *State) 651 { 652 ASL_RESOURCE_NODE *Rnode = NULL; 653 654 655 /* Construct the resource */ 656 657 switch (DescriptorTypeOp->Asl.ParseOpcode) 658 { 659 case PARSEOP_DMA: 660 661 Rnode = RsDoDmaDescriptor (DescriptorTypeOp, 662 CurrentByteOffset); 663 break; 664 665 case PARSEOP_FIXEDDMA: 666 667 Rnode = RsDoFixedDmaDescriptor (DescriptorTypeOp, 668 CurrentByteOffset); 669 break; 670 671 case PARSEOP_DWORDIO: 672 673 Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp, 674 CurrentByteOffset); 675 break; 676 677 case PARSEOP_DWORDMEMORY: 678 679 Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp, 680 CurrentByteOffset); 681 break; 682 683 case PARSEOP_DWORDSPACE: 684 685 Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp, 686 CurrentByteOffset); 687 break; 688 689 case PARSEOP_ENDDEPENDENTFN: 690 691 switch (*State) 692 { 693 case ACPI_RSTATE_NORMAL: 694 695 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT, 696 DescriptorTypeOp, NULL); 697 break; 698 699 case ACPI_RSTATE_START_DEPENDENT: 700 701 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 702 DescriptorTypeOp, NULL); 703 break; 704 705 case ACPI_RSTATE_DEPENDENT_LIST: 706 default: 707 708 break; 709 } 710 711 *State = ACPI_RSTATE_NORMAL; 712 Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp, 713 CurrentByteOffset); 714 break; 715 716 case PARSEOP_ENDTAG: 717 718 Rnode = RsDoEndTagDescriptor (DescriptorTypeOp, 719 CurrentByteOffset); 720 break; 721 722 case PARSEOP_EXTENDEDIO: 723 724 Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp, 725 CurrentByteOffset); 726 break; 727 728 case PARSEOP_EXTENDEDMEMORY: 729 730 Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp, 731 CurrentByteOffset); 732 break; 733 734 case PARSEOP_EXTENDEDSPACE: 735 736 Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp, 737 CurrentByteOffset); 738 break; 739 740 case PARSEOP_FIXEDIO: 741 742 Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp, 743 CurrentByteOffset); 744 break; 745 746 case PARSEOP_INTERRUPT: 747 748 Rnode = RsDoInterruptDescriptor (DescriptorTypeOp, 749 CurrentByteOffset); 750 break; 751 752 case PARSEOP_IO: 753 754 Rnode = RsDoIoDescriptor (DescriptorTypeOp, 755 CurrentByteOffset); 756 break; 757 758 case PARSEOP_IRQ: 759 760 Rnode = RsDoIrqDescriptor (DescriptorTypeOp, 761 CurrentByteOffset); 762 break; 763 764 case PARSEOP_IRQNOFLAGS: 765 766 Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp, 767 CurrentByteOffset); 768 break; 769 770 case PARSEOP_MEMORY24: 771 772 Rnode = RsDoMemory24Descriptor (DescriptorTypeOp, 773 CurrentByteOffset); 774 break; 775 776 case PARSEOP_MEMORY32: 777 778 Rnode = RsDoMemory32Descriptor (DescriptorTypeOp, 779 CurrentByteOffset); 780 break; 781 782 case PARSEOP_MEMORY32FIXED: 783 784 Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp, 785 CurrentByteOffset); 786 break; 787 788 case PARSEOP_QWORDIO: 789 790 Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp, 791 CurrentByteOffset); 792 break; 793 794 case PARSEOP_QWORDMEMORY: 795 796 Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp, 797 CurrentByteOffset); 798 break; 799 800 case PARSEOP_QWORDSPACE: 801 802 Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp, 803 CurrentByteOffset); 804 break; 805 806 case PARSEOP_REGISTER: 807 808 Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp, 809 CurrentByteOffset); 810 break; 811 812 case PARSEOP_STARTDEPENDENTFN: 813 814 switch (*State) 815 { 816 case ACPI_RSTATE_START_DEPENDENT: 817 818 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 819 DescriptorTypeOp, NULL); 820 break; 821 822 case ACPI_RSTATE_NORMAL: 823 case ACPI_RSTATE_DEPENDENT_LIST: 824 default: 825 826 break; 827 } 828 829 *State = ACPI_RSTATE_START_DEPENDENT; 830 Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp, 831 CurrentByteOffset); 832 *State = ACPI_RSTATE_DEPENDENT_LIST; 833 break; 834 835 case PARSEOP_STARTDEPENDENTFN_NOPRI: 836 837 switch (*State) 838 { 839 case ACPI_RSTATE_START_DEPENDENT: 840 841 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 842 DescriptorTypeOp, NULL); 843 break; 844 845 case ACPI_RSTATE_NORMAL: 846 case ACPI_RSTATE_DEPENDENT_LIST: 847 default: 848 849 break; 850 } 851 852 *State = ACPI_RSTATE_START_DEPENDENT; 853 Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp, 854 CurrentByteOffset); 855 *State = ACPI_RSTATE_DEPENDENT_LIST; 856 break; 857 858 case PARSEOP_VENDORLONG: 859 860 Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp, 861 CurrentByteOffset); 862 break; 863 864 case PARSEOP_VENDORSHORT: 865 866 Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp, 867 CurrentByteOffset); 868 break; 869 870 case PARSEOP_WORDBUSNUMBER: 871 872 Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp, 873 CurrentByteOffset); 874 break; 875 876 case PARSEOP_WORDIO: 877 878 Rnode = RsDoWordIoDescriptor (DescriptorTypeOp, 879 CurrentByteOffset); 880 break; 881 882 case PARSEOP_WORDSPACE: 883 884 Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp, 885 CurrentByteOffset); 886 break; 887 888 case PARSEOP_GPIO_INT: 889 890 Rnode = RsDoGpioIntDescriptor (DescriptorTypeOp, 891 CurrentByteOffset); 892 break; 893 894 case PARSEOP_GPIO_IO: 895 896 Rnode = RsDoGpioIoDescriptor (DescriptorTypeOp, 897 CurrentByteOffset); 898 break; 899 900 case PARSEOP_I2C_SERIALBUS: 901 902 Rnode = RsDoI2cSerialBusDescriptor (DescriptorTypeOp, 903 CurrentByteOffset); 904 break; 905 906 case PARSEOP_SPI_SERIALBUS: 907 908 Rnode = RsDoSpiSerialBusDescriptor (DescriptorTypeOp, 909 CurrentByteOffset); 910 break; 911 912 case PARSEOP_UART_SERIALBUS: 913 914 Rnode = RsDoUartSerialBusDescriptor (DescriptorTypeOp, 915 CurrentByteOffset); 916 break; 917 918 case PARSEOP_DEFAULT_ARG: 919 920 /* Just ignore any of these, they are used as fillers/placeholders */ 921 break; 922 923 default: 924 925 printf ("Unknown resource descriptor type [%s]\n", 926 DescriptorTypeOp->Asl.ParseOpName); 927 break; 928 } 929 930 /* 931 * Mark original node as unused, but head of a resource descriptor. 932 * This allows the resource to be installed in the namespace so that 933 * references to the descriptor can be resolved. 934 */ 935 DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 936 DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC; 937 DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset; 938 939 if (Rnode) 940 { 941 DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength; 942 DescriptorTypeOp->Asl.Extra = ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType; 943 } 944 945 return (Rnode); 946 } 947 948 949 /******************************************************************************* 950 * 951 * FUNCTION: RsLinkDescriptorChain 952 * 953 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous 954 * to the linked node, At exit, set to the 955 * last node in the new chain. 956 * Rnode - Resource node to link into the list 957 * 958 * RETURN: Cumulative buffer byte offset of the new segment of chain 959 * 960 * DESCRIPTION: Link a descriptor chain at the end of an existing chain. 961 * 962 ******************************************************************************/ 963 964 UINT32 965 RsLinkDescriptorChain ( 966 ASL_RESOURCE_NODE **PreviousRnode, 967 ASL_RESOURCE_NODE *Rnode) 968 { 969 ASL_RESOURCE_NODE *LastRnode; 970 UINT32 CurrentByteOffset; 971 972 973 /* Anything to do? */ 974 975 if (!Rnode) 976 { 977 return (0); 978 } 979 980 /* Point the previous node to the new node */ 981 982 (*PreviousRnode)->Next = Rnode; 983 CurrentByteOffset = Rnode->BufferLength; 984 985 /* Walk to the end of the chain headed by Rnode */ 986 987 LastRnode = Rnode; 988 while (LastRnode->Next) 989 { 990 LastRnode = LastRnode->Next; 991 CurrentByteOffset += LastRnode->BufferLength; 992 } 993 994 /* Previous node becomes the last node in the chain */ 995 996 *PreviousRnode = LastRnode; 997 return (CurrentByteOffset); 998 } 999 1000 1001 /******************************************************************************* 1002 * 1003 * FUNCTION: RsDoResourceTemplate 1004 * 1005 * PARAMETERS: Op - Parent of a resource template list 1006 * 1007 * RETURN: None. Sets input node to point to a list of AML code 1008 * 1009 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer, 1010 * in preparation for output to the AML output file. 1011 * 1012 ******************************************************************************/ 1013 1014 void 1015 RsDoResourceTemplate ( 1016 ACPI_PARSE_OBJECT *Op) 1017 { 1018 ACPI_PARSE_OBJECT *BufferLengthOp; 1019 ACPI_PARSE_OBJECT *BufferOp; 1020 ACPI_PARSE_OBJECT *DescriptorTypeOp; 1021 ACPI_PARSE_OBJECT *LastOp = NULL; 1022 UINT32 CurrentByteOffset = 0; 1023 ASL_RESOURCE_NODE HeadRnode; 1024 ASL_RESOURCE_NODE *PreviousRnode; 1025 ASL_RESOURCE_NODE *Rnode; 1026 UINT8 State; 1027 1028 1029 /* Mark parent as containing a resource template */ 1030 1031 if (Op->Asl.Parent) 1032 { 1033 Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 1034 } 1035 1036 /* ResourceTemplate Opcode is first (Op) */ 1037 /* Buffer Length node is first child */ 1038 1039 BufferLengthOp = ASL_GET_CHILD_NODE (Op); 1040 1041 /* Buffer Op is first peer */ 1042 1043 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp); 1044 1045 /* First Descriptor type is next */ 1046 1047 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp); 1048 1049 /* 1050 * Process all resource descriptors in the list 1051 * Note: It is assumed that the EndTag node has been automatically 1052 * inserted at the end of the template by the parser. 1053 */ 1054 State = ACPI_RSTATE_NORMAL; 1055 PreviousRnode = &HeadRnode; 1056 while (DescriptorTypeOp) 1057 { 1058 DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 1059 Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset, 1060 &State); 1061 1062 /* 1063 * Update current byte offset to indicate the number of bytes from the 1064 * start of the buffer. Buffer can include multiple descriptors, we 1065 * must keep track of the offset of not only each descriptor, but each 1066 * element (field) within each descriptor as well. 1067 */ 1068 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 1069 1070 /* Get the next descriptor in the list */ 1071 1072 LastOp = DescriptorTypeOp; 1073 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp); 1074 } 1075 1076 if (State == ACPI_RSTATE_DEPENDENT_LIST) 1077 { 1078 if (LastOp) 1079 { 1080 LastOp = LastOp->Asl.Parent; 1081 } 1082 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL); 1083 } 1084 1085 /* 1086 * Transform the nodes into the following 1087 * 1088 * Op -> AML_BUFFER_OP 1089 * First Child -> BufferLength 1090 * Second Child -> Descriptor Buffer (raw byte data) 1091 */ 1092 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1093 Op->Asl.AmlOpcode = AML_BUFFER_OP; 1094 Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC; 1095 UtSetParseOpName (Op); 1096 1097 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 1098 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset; 1099 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 1100 UtSetParseOpName (BufferLengthOp); 1101 1102 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 1103 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 1104 BufferOp->Asl.AmlOpcodeLength = 0; 1105 BufferOp->Asl.AmlLength = CurrentByteOffset; 1106 BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next; 1107 BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA; 1108 UtSetParseOpName (BufferOp); 1109 1110 return; 1111 }