1 /****************************************************************************** 2 * 3 * Module Name: aslresource - Resource template/descriptor utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/compiler/aslcompiler.h> 46 #include "aslcompiler.y.h" 47 #include <contrib/dev/acpica/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 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 323 } 324 } 325 else 326 { 327 /* Variable length (length==0) */ 328 329 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 330 { 331 case 0: 332 /* 333 * Both _MIN and _MAX are variable. 334 * No additional requirements, just exit 335 */ 336 break; 337 338 case ACPI_RESOURCE_FLAG_MIF: 339 340 /* _MIN is fixed. _MIN must be multiple of _GRA */ 341 342 /* 343 * The granularity is defined by the ACPI specification to be a 344 * power-of-two minus one, therefore the granularity is a 345 * bitmask which can be used to easily validate the addresses. 346 */ 347 if (Granularity & Minimum) 348 { 349 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 350 } 351 break; 352 353 case ACPI_RESOURCE_FLAG_MAF: 354 355 /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */ 356 357 if (Granularity & (Maximum + 1)) 358 { 359 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1"); 360 } 361 break; 362 363 /* Both MIF/MAF set is invalid if length is zero */ 364 365 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 366 default: 367 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 368 } 369 } 370 } 371 372 373 /******************************************************************************* 374 * 375 * FUNCTION: RsGetStringDataLength 376 * 377 * PARAMETERS: InitializerOp - Start of a subtree of init nodes 378 * 379 * RETURN: Valid string length if a string node is found (otherwise 0) 380 * 381 * DESCRIPTION: In a list of peer nodes, find the first one that contains a 382 * string and return the length of the string. 383 * 384 ******************************************************************************/ 385 386 UINT16 387 RsGetStringDataLength ( 388 ACPI_PARSE_OBJECT *InitializerOp) 389 { 390 391 while (InitializerOp) 392 { 393 if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 394 { 395 return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1)); 396 } 397 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 398 } 399 400 return (0); 401 } 402 403 404 /******************************************************************************* 405 * 406 * FUNCTION: RsAllocateResourceNode 407 * 408 * PARAMETERS: Size - Size of node in bytes 409 * 410 * RETURN: The allocated node - aborts on allocation failure 411 * 412 * DESCRIPTION: Allocate a resource description node and the resource 413 * descriptor itself (the nodes are used to link descriptors). 414 * 415 ******************************************************************************/ 416 417 ASL_RESOURCE_NODE * 418 RsAllocateResourceNode ( 419 UINT32 Size) 420 { 421 ASL_RESOURCE_NODE *Rnode; 422 423 424 /* Allocate the node */ 425 426 Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE)); 427 428 /* Allocate the resource descriptor itself */ 429 430 Rnode->Buffer = UtLocalCalloc (Size); 431 Rnode->BufferLength = Size; 432 433 return (Rnode); 434 } 435 436 437 /******************************************************************************* 438 * 439 * FUNCTION: RsCreateResourceField 440 * 441 * PARAMETERS: Op - Resource field node 442 * Name - Name of the field (Used only to reference 443 * the field in the ASL, not in the AML) 444 * ByteOffset - Offset from the field start 445 * BitOffset - Additional bit offset 446 * BitLength - Number of bits in the field 447 * 448 * RETURN: None, sets fields within the input node 449 * 450 * DESCRIPTION: Utility function to generate a named bit field within a 451 * resource descriptor. Mark a node as 1) a field in a resource 452 * descriptor, and 2) set the value to be a BIT offset 453 * 454 ******************************************************************************/ 455 456 void 457 RsCreateResourceField ( 458 ACPI_PARSE_OBJECT *Op, 459 char *Name, 460 UINT32 ByteOffset, 461 UINT32 BitOffset, 462 UINT32 BitLength) 463 { 464 465 Op->Asl.ExternalName = Name; 466 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 467 468 469 Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset; 470 Op->Asl.Value.Tag.BitLength = BitLength; 471 } 472 473 474 /******************************************************************************* 475 * 476 * FUNCTION: RsSetFlagBits 477 * 478 * PARAMETERS: *Flags - Pointer to the flag byte 479 * Op - Flag initialization node 480 * Position - Bit position within the flag byte 481 * Default - Used if the node is DEFAULT. 482 * 483 * RETURN: Sets bits within the *Flags output byte. 484 * 485 * DESCRIPTION: Set a bit in a cumulative flags word from an initialization 486 * node. Will use a default value if the node is DEFAULT, meaning 487 * that no value was specified in the ASL. Used to merge multiple 488 * keywords into a single flags byte. 489 * 490 ******************************************************************************/ 491 492 void 493 RsSetFlagBits ( 494 UINT8 *Flags, 495 ACPI_PARSE_OBJECT *Op, 496 UINT8 Position, 497 UINT8 DefaultBit) 498 { 499 500 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 501 { 502 /* Use the default bit */ 503 504 *Flags |= (DefaultBit << Position); 505 } 506 else 507 { 508 /* Use the bit specified in the initialization node */ 509 510 *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position); 511 } 512 } 513 514 515 void 516 RsSetFlagBits16 ( 517 UINT16 *Flags, 518 ACPI_PARSE_OBJECT *Op, 519 UINT8 Position, 520 UINT8 DefaultBit) 521 { 522 523 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 524 { 525 /* Use the default bit */ 526 527 *Flags |= (DefaultBit << Position); 528 } 529 else 530 { 531 /* Use the bit specified in the initialization node */ 532 533 *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position); 534 } 535 } 536 537 538 /******************************************************************************* 539 * 540 * FUNCTION: RsCompleteNodeAndGetNext 541 * 542 * PARAMETERS: Op - Resource node to be completed 543 * 544 * RETURN: The next peer to the input node. 545 * 546 * DESCRIPTION: Mark the current node completed and return the next peer. 547 * The node ParseOpcode is set to DEFAULT_ARG, meaning that 548 * this node is to be ignored from now on. 549 * 550 ******************************************************************************/ 551 552 ACPI_PARSE_OBJECT * 553 RsCompleteNodeAndGetNext ( 554 ACPI_PARSE_OBJECT *Op) 555 { 556 557 /* Mark this node unused */ 558 559 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 560 561 /* Move on to the next peer node in the initializer list */ 562 563 return (ASL_GET_PEER_NODE (Op)); 564 } 565 566 567 /******************************************************************************* 568 * 569 * FUNCTION: RsCheckListForDuplicates 570 * 571 * PARAMETERS: Op - First op in the initializer list 572 * 573 * RETURN: None 574 * 575 * DESCRIPTION: Check an initializer list for duplicate values. Emits an error 576 * if any duplicates are found. 577 * 578 ******************************************************************************/ 579 580 void 581 RsCheckListForDuplicates ( 582 ACPI_PARSE_OBJECT *Op) 583 { 584 ACPI_PARSE_OBJECT *NextValueOp = Op; 585 ACPI_PARSE_OBJECT *NextOp; 586 UINT32 Value; 587 588 589 if (!Op) 590 { 591 return; 592 } 593 594 /* Search list once for each value in the list */ 595 596 while (NextValueOp) 597 { 598 Value = (UINT32) NextValueOp->Asl.Value.Integer; 599 600 /* Compare this value to all remaining values in the list */ 601 602 NextOp = ASL_GET_PEER_NODE (NextValueOp); 603 while (NextOp) 604 { 605 if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 606 { 607 /* Compare values */ 608 609 if (Value == (UINT32) NextOp->Asl.Value.Integer) 610 { 611 /* Emit error only once per duplicate node */ 612 613 if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE)) 614 { 615 NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE; 616 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM, 617 NextOp, NULL); 618 } 619 } 620 } 621 622 NextOp = ASL_GET_PEER_NODE (NextOp); 623 } 624 625 NextValueOp = ASL_GET_PEER_NODE (NextValueOp); 626 } 627 } 628 629 630 /******************************************************************************* 631 * 632 * FUNCTION: RsDoOneResourceDescriptor 633 * 634 * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor 635 * CurrentByteOffset - Offset in the resource descriptor 636 * buffer. 637 * 638 * RETURN: A valid resource node for the descriptor 639 * 640 * DESCRIPTION: Dispatches the processing of one resource descriptor 641 * 642 ******************************************************************************/ 643 644 ASL_RESOURCE_NODE * 645 RsDoOneResourceDescriptor ( 646 ACPI_PARSE_OBJECT *DescriptorTypeOp, 647 UINT32 CurrentByteOffset, 648 UINT8 *State) 649 { 650 ASL_RESOURCE_NODE *Rnode = NULL; 651 652 653 /* Construct the resource */ 654 655 switch (DescriptorTypeOp->Asl.ParseOpcode) 656 { 657 case PARSEOP_DMA: 658 Rnode = RsDoDmaDescriptor (DescriptorTypeOp, 659 CurrentByteOffset); 660 break; 661 662 case PARSEOP_FIXEDDMA: 663 Rnode = RsDoFixedDmaDescriptor (DescriptorTypeOp, 664 CurrentByteOffset); 665 break; 666 667 case PARSEOP_DWORDIO: 668 Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp, 669 CurrentByteOffset); 670 break; 671 672 case PARSEOP_DWORDMEMORY: 673 Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp, 674 CurrentByteOffset); 675 break; 676 677 case PARSEOP_DWORDSPACE: 678 Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp, 679 CurrentByteOffset); 680 break; 681 682 case PARSEOP_ENDDEPENDENTFN: 683 switch (*State) 684 { 685 case ACPI_RSTATE_NORMAL: 686 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT, 687 DescriptorTypeOp, NULL); 688 break; 689 690 case ACPI_RSTATE_START_DEPENDENT: 691 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 692 DescriptorTypeOp, NULL); 693 break; 694 695 case ACPI_RSTATE_DEPENDENT_LIST: 696 default: 697 break; 698 } 699 700 *State = ACPI_RSTATE_NORMAL; 701 Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp, 702 CurrentByteOffset); 703 break; 704 705 case PARSEOP_ENDTAG: 706 Rnode = RsDoEndTagDescriptor (DescriptorTypeOp, 707 CurrentByteOffset); 708 break; 709 710 case PARSEOP_EXTENDEDIO: 711 Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp, 712 CurrentByteOffset); 713 break; 714 715 case PARSEOP_EXTENDEDMEMORY: 716 Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp, 717 CurrentByteOffset); 718 break; 719 720 case PARSEOP_EXTENDEDSPACE: 721 Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp, 722 CurrentByteOffset); 723 break; 724 725 case PARSEOP_FIXEDIO: 726 Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp, 727 CurrentByteOffset); 728 break; 729 730 case PARSEOP_INTERRUPT: 731 Rnode = RsDoInterruptDescriptor (DescriptorTypeOp, 732 CurrentByteOffset); 733 break; 734 735 case PARSEOP_IO: 736 Rnode = RsDoIoDescriptor (DescriptorTypeOp, 737 CurrentByteOffset); 738 break; 739 740 case PARSEOP_IRQ: 741 Rnode = RsDoIrqDescriptor (DescriptorTypeOp, 742 CurrentByteOffset); 743 break; 744 745 case PARSEOP_IRQNOFLAGS: 746 Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp, 747 CurrentByteOffset); 748 break; 749 750 case PARSEOP_MEMORY24: 751 Rnode = RsDoMemory24Descriptor (DescriptorTypeOp, 752 CurrentByteOffset); 753 break; 754 755 case PARSEOP_MEMORY32: 756 Rnode = RsDoMemory32Descriptor (DescriptorTypeOp, 757 CurrentByteOffset); 758 break; 759 760 case PARSEOP_MEMORY32FIXED: 761 Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp, 762 CurrentByteOffset); 763 break; 764 765 case PARSEOP_QWORDIO: 766 Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp, 767 CurrentByteOffset); 768 break; 769 770 case PARSEOP_QWORDMEMORY: 771 Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp, 772 CurrentByteOffset); 773 break; 774 775 case PARSEOP_QWORDSPACE: 776 Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp, 777 CurrentByteOffset); 778 break; 779 780 case PARSEOP_REGISTER: 781 Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp, 782 CurrentByteOffset); 783 break; 784 785 case PARSEOP_STARTDEPENDENTFN: 786 switch (*State) 787 { 788 case ACPI_RSTATE_START_DEPENDENT: 789 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 790 DescriptorTypeOp, NULL); 791 break; 792 793 case ACPI_RSTATE_NORMAL: 794 case ACPI_RSTATE_DEPENDENT_LIST: 795 default: 796 break; 797 } 798 799 *State = ACPI_RSTATE_START_DEPENDENT; 800 Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp, 801 CurrentByteOffset); 802 *State = ACPI_RSTATE_DEPENDENT_LIST; 803 break; 804 805 case PARSEOP_STARTDEPENDENTFN_NOPRI: 806 switch (*State) 807 { 808 case ACPI_RSTATE_START_DEPENDENT: 809 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 810 DescriptorTypeOp, NULL); 811 break; 812 813 case ACPI_RSTATE_NORMAL: 814 case ACPI_RSTATE_DEPENDENT_LIST: 815 default: 816 break; 817 } 818 819 *State = ACPI_RSTATE_START_DEPENDENT; 820 Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp, 821 CurrentByteOffset); 822 *State = ACPI_RSTATE_DEPENDENT_LIST; 823 break; 824 825 case PARSEOP_VENDORLONG: 826 Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp, 827 CurrentByteOffset); 828 break; 829 830 case PARSEOP_VENDORSHORT: 831 Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp, 832 CurrentByteOffset); 833 break; 834 835 case PARSEOP_WORDBUSNUMBER: 836 Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp, 837 CurrentByteOffset); 838 break; 839 840 case PARSEOP_WORDIO: 841 Rnode = RsDoWordIoDescriptor (DescriptorTypeOp, 842 CurrentByteOffset); 843 break; 844 845 case PARSEOP_WORDSPACE: 846 Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp, 847 CurrentByteOffset); 848 break; 849 850 case PARSEOP_GPIO_INT: 851 Rnode = RsDoGpioIntDescriptor (DescriptorTypeOp, 852 CurrentByteOffset); 853 break; 854 855 case PARSEOP_GPIO_IO: 856 Rnode = RsDoGpioIoDescriptor (DescriptorTypeOp, 857 CurrentByteOffset); 858 break; 859 860 case PARSEOP_I2C_SERIALBUS: 861 Rnode = RsDoI2cSerialBusDescriptor (DescriptorTypeOp, 862 CurrentByteOffset); 863 break; 864 865 case PARSEOP_SPI_SERIALBUS: 866 Rnode = RsDoSpiSerialBusDescriptor (DescriptorTypeOp, 867 CurrentByteOffset); 868 break; 869 870 case PARSEOP_UART_SERIALBUS: 871 Rnode = RsDoUartSerialBusDescriptor (DescriptorTypeOp, 872 CurrentByteOffset); 873 break; 874 875 case PARSEOP_DEFAULT_ARG: 876 /* Just ignore any of these, they are used as fillers/placeholders */ 877 break; 878 879 default: 880 printf ("Unknown resource descriptor type [%s]\n", 881 DescriptorTypeOp->Asl.ParseOpName); 882 break; 883 } 884 885 /* 886 * Mark original node as unused, but head of a resource descriptor. 887 * This allows the resource to be installed in the namespace so that 888 * references to the descriptor can be resolved. 889 */ 890 DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 891 DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC; 892 DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset; 893 894 if (Rnode) 895 { 896 DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength; 897 } 898 899 return (Rnode); 900 } 901 902 903 /******************************************************************************* 904 * 905 * FUNCTION: RsLinkDescriptorChain 906 * 907 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous 908 * to the linked node, At exit, set to the 909 * last node in the new chain. 910 * Rnode - Resource node to link into the list 911 * 912 * RETURN: Cumulative buffer byte offset of the new segment of chain 913 * 914 * DESCRIPTION: Link a descriptor chain at the end of an existing chain. 915 * 916 ******************************************************************************/ 917 918 UINT32 919 RsLinkDescriptorChain ( 920 ASL_RESOURCE_NODE **PreviousRnode, 921 ASL_RESOURCE_NODE *Rnode) 922 { 923 ASL_RESOURCE_NODE *LastRnode; 924 UINT32 CurrentByteOffset; 925 926 927 /* Anything to do? */ 928 929 if (!Rnode) 930 { 931 return (0); 932 } 933 934 /* Point the previous node to the new node */ 935 936 (*PreviousRnode)->Next = Rnode; 937 CurrentByteOffset = Rnode->BufferLength; 938 939 /* Walk to the end of the chain headed by Rnode */ 940 941 LastRnode = Rnode; 942 while (LastRnode->Next) 943 { 944 LastRnode = LastRnode->Next; 945 CurrentByteOffset += LastRnode->BufferLength; 946 } 947 948 /* Previous node becomes the last node in the chain */ 949 950 *PreviousRnode = LastRnode; 951 return (CurrentByteOffset); 952 } 953 954 955 /******************************************************************************* 956 * 957 * FUNCTION: RsDoResourceTemplate 958 * 959 * PARAMETERS: Op - Parent of a resource template list 960 * 961 * RETURN: None. Sets input node to point to a list of AML code 962 * 963 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer, 964 * in preparation for output to the AML output file. 965 * 966 ******************************************************************************/ 967 968 void 969 RsDoResourceTemplate ( 970 ACPI_PARSE_OBJECT *Op) 971 { 972 ACPI_PARSE_OBJECT *BufferLengthOp; 973 ACPI_PARSE_OBJECT *BufferOp; 974 ACPI_PARSE_OBJECT *DescriptorTypeOp; 975 ACPI_PARSE_OBJECT *LastOp = NULL; 976 UINT32 CurrentByteOffset = 0; 977 ASL_RESOURCE_NODE HeadRnode; 978 ASL_RESOURCE_NODE *PreviousRnode; 979 ASL_RESOURCE_NODE *Rnode; 980 UINT8 State; 981 982 983 /* Mark parent as containing a resource template */ 984 985 if (Op->Asl.Parent) 986 { 987 Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 988 } 989 990 /* ResourceTemplate Opcode is first (Op) */ 991 /* Buffer Length node is first child */ 992 993 BufferLengthOp = ASL_GET_CHILD_NODE (Op); 994 995 /* Buffer Op is first peer */ 996 997 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp); 998 999 /* First Descriptor type is next */ 1000 1001 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp); 1002 1003 /* 1004 * Process all resource descriptors in the list 1005 * Note: It is assumed that the EndTag node has been automatically 1006 * inserted at the end of the template by the parser. 1007 */ 1008 State = ACPI_RSTATE_NORMAL; 1009 PreviousRnode = &HeadRnode; 1010 while (DescriptorTypeOp) 1011 { 1012 DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 1013 Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset, 1014 &State); 1015 1016 /* 1017 * Update current byte offset to indicate the number of bytes from the 1018 * start of the buffer. Buffer can include multiple descriptors, we 1019 * must keep track of the offset of not only each descriptor, but each 1020 * element (field) within each descriptor as well. 1021 */ 1022 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 1023 1024 /* Get the next descriptor in the list */ 1025 1026 LastOp = DescriptorTypeOp; 1027 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp); 1028 } 1029 1030 if (State == ACPI_RSTATE_DEPENDENT_LIST) 1031 { 1032 if (LastOp) 1033 { 1034 LastOp = LastOp->Asl.Parent; 1035 } 1036 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL); 1037 } 1038 1039 /* 1040 * Transform the nodes into the following 1041 * 1042 * Op -> AML_BUFFER_OP 1043 * First Child -> BufferLength 1044 * Second Child -> Descriptor Buffer (raw byte data) 1045 */ 1046 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1047 Op->Asl.AmlOpcode = AML_BUFFER_OP; 1048 Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC; 1049 UtSetParseOpName (Op); 1050 1051 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 1052 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset; 1053 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 1054 UtSetParseOpName (BufferLengthOp); 1055 1056 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 1057 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 1058 BufferOp->Asl.AmlOpcodeLength = 0; 1059 BufferOp->Asl.AmlLength = CurrentByteOffset; 1060 BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next; 1061 BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA; 1062 UtSetParseOpName (BufferOp); 1063 1064 return; 1065 } 1066