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 - 2022, 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 case PARSEOP_DMA: 766 767 Rnode = RsDoDmaDescriptor (Info); 768 break; 769 770 case PARSEOP_FIXEDDMA: 771 772 Rnode = RsDoFixedDmaDescriptor (Info); 773 break; 774 775 case PARSEOP_DWORDIO: 776 777 Rnode = RsDoDwordIoDescriptor (Info); 778 break; 779 780 case PARSEOP_DWORDMEMORY: 781 782 Rnode = RsDoDwordMemoryDescriptor (Info); 783 break; 784 785 case PARSEOP_DWORDSPACE: 786 787 Rnode = RsDoDwordSpaceDescriptor (Info); 788 break; 789 790 case PARSEOP_ENDDEPENDENTFN: 791 792 switch (*State) 793 { 794 case ACPI_RSTATE_NORMAL: 795 796 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT, 797 Info->DescriptorTypeOp, NULL); 798 break; 799 800 case ACPI_RSTATE_START_DEPENDENT: 801 802 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 803 Info->DescriptorTypeOp, NULL); 804 break; 805 806 case ACPI_RSTATE_DEPENDENT_LIST: 807 default: 808 809 break; 810 } 811 812 *State = ACPI_RSTATE_NORMAL; 813 Rnode = RsDoEndDependentDescriptor (Info); 814 break; 815 816 case PARSEOP_ENDTAG: 817 818 Rnode = RsDoEndTagDescriptor (Info); 819 break; 820 821 case PARSEOP_EXTENDEDIO: 822 823 Rnode = RsDoExtendedIoDescriptor (Info); 824 break; 825 826 case PARSEOP_EXTENDEDMEMORY: 827 828 Rnode = RsDoExtendedMemoryDescriptor (Info); 829 break; 830 831 case PARSEOP_EXTENDEDSPACE: 832 833 Rnode = RsDoExtendedSpaceDescriptor (Info); 834 break; 835 836 case PARSEOP_FIXEDIO: 837 838 Rnode = RsDoFixedIoDescriptor (Info); 839 break; 840 841 case PARSEOP_INTERRUPT: 842 843 Rnode = RsDoInterruptDescriptor (Info); 844 break; 845 846 case PARSEOP_IO: 847 848 Rnode = RsDoIoDescriptor (Info); 849 break; 850 851 case PARSEOP_IRQ: 852 853 Rnode = RsDoIrqDescriptor (Info); 854 break; 855 856 case PARSEOP_IRQNOFLAGS: 857 858 Rnode = RsDoIrqNoFlagsDescriptor (Info); 859 break; 860 861 case PARSEOP_MEMORY24: 862 863 Rnode = RsDoMemory24Descriptor (Info); 864 break; 865 866 case PARSEOP_MEMORY32: 867 868 Rnode = RsDoMemory32Descriptor (Info); 869 break; 870 871 case PARSEOP_MEMORY32FIXED: 872 873 Rnode = RsDoMemory32FixedDescriptor (Info); 874 break; 875 876 case PARSEOP_QWORDIO: 877 878 Rnode = RsDoQwordIoDescriptor (Info); 879 break; 880 881 case PARSEOP_QWORDMEMORY: 882 883 Rnode = RsDoQwordMemoryDescriptor (Info); 884 break; 885 886 case PARSEOP_QWORDSPACE: 887 888 Rnode = RsDoQwordSpaceDescriptor (Info); 889 break; 890 891 case PARSEOP_REGISTER: 892 893 Rnode = RsDoGeneralRegisterDescriptor (Info); 894 break; 895 896 case PARSEOP_STARTDEPENDENTFN: 897 898 switch (*State) 899 { 900 case ACPI_RSTATE_START_DEPENDENT: 901 902 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 903 Info->DescriptorTypeOp, NULL); 904 break; 905 906 case ACPI_RSTATE_NORMAL: 907 case ACPI_RSTATE_DEPENDENT_LIST: 908 default: 909 910 break; 911 } 912 913 *State = ACPI_RSTATE_START_DEPENDENT; 914 Rnode = RsDoStartDependentDescriptor (Info); 915 *State = ACPI_RSTATE_DEPENDENT_LIST; 916 break; 917 918 case PARSEOP_STARTDEPENDENTFN_NOPRI: 919 920 switch (*State) 921 { 922 case ACPI_RSTATE_START_DEPENDENT: 923 924 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 925 Info->DescriptorTypeOp, NULL); 926 break; 927 928 case ACPI_RSTATE_NORMAL: 929 case ACPI_RSTATE_DEPENDENT_LIST: 930 default: 931 932 break; 933 } 934 935 *State = ACPI_RSTATE_START_DEPENDENT; 936 Rnode = RsDoStartDependentNoPriDescriptor (Info); 937 *State = ACPI_RSTATE_DEPENDENT_LIST; 938 break; 939 940 case PARSEOP_VENDORLONG: 941 942 Rnode = RsDoVendorLargeDescriptor (Info); 943 break; 944 945 case PARSEOP_VENDORSHORT: 946 947 Rnode = RsDoVendorSmallDescriptor (Info); 948 break; 949 950 case PARSEOP_WORDBUSNUMBER: 951 952 Rnode = RsDoWordBusNumberDescriptor (Info); 953 break; 954 955 case PARSEOP_WORDIO: 956 957 Rnode = RsDoWordIoDescriptor (Info); 958 break; 959 960 case PARSEOP_WORDSPACE: 961 962 Rnode = RsDoWordSpaceDescriptor (Info); 963 break; 964 965 case PARSEOP_GPIO_INT: 966 967 Rnode = RsDoGpioIntDescriptor (Info); 968 break; 969 970 case PARSEOP_GPIO_IO: 971 972 Rnode = RsDoGpioIoDescriptor (Info); 973 break; 974 975 case PARSEOP_I2C_SERIALBUS: 976 case PARSEOP_I2C_SERIALBUS_V2: 977 978 Rnode = RsDoI2cSerialBusDescriptor (Info); 979 break; 980 981 case PARSEOP_SPI_SERIALBUS: 982 case PARSEOP_SPI_SERIALBUS_V2: 983 984 Rnode = RsDoSpiSerialBusDescriptor (Info); 985 break; 986 987 case PARSEOP_UART_SERIALBUS: 988 case PARSEOP_UART_SERIALBUS_V2: 989 990 Rnode = RsDoUartSerialBusDescriptor (Info); 991 break; 992 993 case PARSEOP_CSI2_SERIALBUS: 994 995 Rnode = RsDoCsi2SerialBusDescriptor (Info); 996 break; 997 998 case PARSEOP_PINCONFIG: 999 1000 Rnode = RsDoPinConfigDescriptor (Info); 1001 break; 1002 1003 case PARSEOP_PINFUNCTION: 1004 1005 Rnode = RsDoPinFunctionDescriptor (Info); 1006 break; 1007 1008 case PARSEOP_PINGROUP: 1009 1010 Rnode = RsDoPinGroupDescriptor (Info); 1011 break; 1012 1013 case PARSEOP_PINGROUPFUNCTION: 1014 1015 Rnode = RsDoPinGroupFunctionDescriptor (Info); 1016 break; 1017 1018 case PARSEOP_PINGROUPCONFIG: 1019 1020 Rnode = RsDoPinGroupConfigDescriptor (Info); 1021 break; 1022 1023 case PARSEOP_DEFAULT_ARG: 1024 1025 /* Just ignore any of these, they are used as fillers/placeholders */ 1026 break; 1027 1028 default: 1029 1030 printf ("Unknown resource descriptor type [%s]\n", 1031 Info->DescriptorTypeOp->Asl.ParseOpName); 1032 break; 1033 } 1034 1035 /* 1036 * Mark original node as unused, but head of a resource descriptor. 1037 * This allows the resource to be installed in the namespace so that 1038 * references to the descriptor can be resolved. 1039 */ 1040 Info->DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1041 Info->DescriptorTypeOp->Asl.CompileFlags = OP_IS_RESOURCE_DESC; 1042 Info->DescriptorTypeOp->Asl.Value.Integer = Info->CurrentByteOffset; 1043 1044 if (Rnode) 1045 { 1046 Info->DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength; 1047 Info->DescriptorTypeOp->Asl.Extra = 1048 ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType; 1049 } 1050 1051 return (Rnode); 1052 } 1053 1054 1055 /******************************************************************************* 1056 * 1057 * FUNCTION: RsLinkDescriptorChain 1058 * 1059 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous 1060 * to the linked node, At exit, set to the 1061 * last node in the new chain. 1062 * Rnode - Resource node to link into the list 1063 * 1064 * RETURN: Cumulative buffer byte offset of the new segment of chain 1065 * 1066 * DESCRIPTION: Link a descriptor chain at the end of an existing chain. 1067 * 1068 ******************************************************************************/ 1069 1070 UINT32 1071 RsLinkDescriptorChain ( 1072 ASL_RESOURCE_NODE **PreviousRnode, 1073 ASL_RESOURCE_NODE *Rnode) 1074 { 1075 ASL_RESOURCE_NODE *LastRnode; 1076 UINT32 CurrentByteOffset; 1077 1078 1079 /* Anything to do? */ 1080 1081 if (!Rnode) 1082 { 1083 return (0); 1084 } 1085 1086 /* Point the previous node to the new node */ 1087 1088 (*PreviousRnode)->Next = Rnode; 1089 CurrentByteOffset = Rnode->BufferLength; 1090 1091 /* Walk to the end of the chain headed by Rnode */ 1092 1093 LastRnode = Rnode; 1094 while (LastRnode->Next) 1095 { 1096 LastRnode = LastRnode->Next; 1097 CurrentByteOffset += LastRnode->BufferLength; 1098 } 1099 1100 /* Previous node becomes the last node in the chain */ 1101 1102 *PreviousRnode = LastRnode; 1103 return (CurrentByteOffset); 1104 } 1105 1106 1107 /******************************************************************************* 1108 * 1109 * FUNCTION: RsDoResourceTemplate 1110 * 1111 * PARAMETERS: Op - Parent of a resource template list 1112 * 1113 * RETURN: None. Sets input node to point to a list of AML code 1114 * 1115 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer, 1116 * in preparation for output to the AML output file. 1117 * 1118 ******************************************************************************/ 1119 1120 void 1121 RsDoResourceTemplate ( 1122 ACPI_PARSE_OBJECT *Op) 1123 { 1124 ACPI_PARSE_OBJECT *BufferLengthOp; 1125 ACPI_PARSE_OBJECT *BufferOp; 1126 ACPI_PARSE_OBJECT *DescriptorTypeOp; 1127 ACPI_PARSE_OBJECT *LastOp = NULL; 1128 UINT32 CurrentByteOffset = 0; 1129 ASL_RESOURCE_NODE HeadRnode; 1130 ASL_RESOURCE_NODE *PreviousRnode; 1131 ASL_RESOURCE_NODE *Rnode; 1132 ASL_RESOURCE_INFO Info; 1133 UINT8 State; 1134 1135 1136 /* Mark parent as containing a resource template */ 1137 1138 if (Op->Asl.Parent) 1139 { 1140 Op->Asl.Parent->Asl.CompileFlags |= OP_IS_RESOURCE_DESC; 1141 } 1142 1143 /* ResourceTemplate Opcode is first (Op) */ 1144 /* Buffer Length node is first child */ 1145 1146 BufferLengthOp = ASL_GET_CHILD_NODE (Op); 1147 1148 /* Buffer Op is first peer */ 1149 1150 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp); 1151 1152 /* First Descriptor type is next */ 1153 1154 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp); 1155 1156 /* DEFAULT_ARG indicates null template - ResourceTemplate(){} */ 1157 1158 if (DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1159 { 1160 AslError (ASL_WARNING, ASL_MSG_NULL_RESOURCE_TEMPLATE, 1161 DescriptorTypeOp, DescriptorTypeOp->Asl.Value.String); 1162 } 1163 1164 /* 1165 * Process all resource descriptors in the list 1166 * Note: It is assumed that the EndTag node has been automatically 1167 * inserted at the end of the template by the parser. 1168 */ 1169 State = ACPI_RSTATE_NORMAL; 1170 PreviousRnode = &HeadRnode; 1171 while (DescriptorTypeOp) 1172 { 1173 /* Save information for optional mapfile */ 1174 1175 if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION) 1176 { 1177 Info.MappingOp = Op->Asl.Parent; 1178 } 1179 else 1180 { 1181 Info.MappingOp = DescriptorTypeOp; 1182 } 1183 1184 Info.DescriptorTypeOp = DescriptorTypeOp; 1185 Info.CurrentByteOffset = CurrentByteOffset; 1186 1187 DescriptorTypeOp->Asl.CompileFlags |= OP_IS_RESOURCE_DESC; 1188 Rnode = RsDoOneResourceDescriptor (&Info, &State); 1189 1190 /* 1191 * Update current byte offset to indicate the number of bytes from the 1192 * start of the buffer. Buffer can include multiple descriptors, we 1193 * must keep track of the offset of not only each descriptor, but each 1194 * element (field) within each descriptor as well. 1195 */ 1196 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 1197 1198 /* Get the next descriptor in the list */ 1199 1200 LastOp = DescriptorTypeOp; 1201 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp); 1202 } 1203 1204 if (State == ACPI_RSTATE_DEPENDENT_LIST) 1205 { 1206 if (LastOp) 1207 { 1208 LastOp = LastOp->Asl.Parent; 1209 } 1210 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL); 1211 } 1212 1213 /* 1214 * Transform the nodes into the following 1215 * 1216 * Op -> AML_BUFFER_OP 1217 * First Child -> BufferLength 1218 * Second Child -> Descriptor Buffer (raw byte data) 1219 */ 1220 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1221 Op->Asl.AmlOpcode = AML_BUFFER_OP; 1222 Op->Asl.CompileFlags = OP_AML_PACKAGE | OP_IS_RESOURCE_DESC; 1223 UtSetParseOpName (Op); 1224 1225 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 1226 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset; 1227 (void) OpcSetOptimalIntegerSize (BufferLengthOp); 1228 UtSetParseOpName (BufferLengthOp); 1229 1230 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 1231 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 1232 BufferOp->Asl.AmlOpcodeLength = 0; 1233 BufferOp->Asl.AmlLength = CurrentByteOffset; 1234 BufferOp->Asl.Value.Buffer = ACPI_CAST_PTR (UINT8, HeadRnode.Next); 1235 BufferOp->Asl.CompileFlags |= OP_IS_RESOURCE_DATA; 1236 UtSetParseOpName (BufferOp); 1237 1238 return; 1239 } 1240