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