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