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