1 /****************************************************************************** 2 * 3 * Module Name: cvparser - Converter functions that are called from the AML 4 * parser. 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2023, 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 * Alternatively, you may choose to be licensed under the terms of the 118 * following license: 119 * 120 * Redistribution and use in source and binary forms, with or without 121 * modification, are permitted provided that the following conditions 122 * are met: 123 * 1. Redistributions of source code must retain the above copyright 124 * notice, this list of conditions, and the following disclaimer, 125 * without modification. 126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 127 * substantially similar to the "NO WARRANTY" disclaimer below 128 * ("Disclaimer") and any redistribution must be conditioned upon 129 * including a substantially similar Disclaimer requirement for further 130 * binary redistribution. 131 * 3. Neither the names of the above-listed copyright holders nor the names 132 * of any contributors may be used to endorse or promote products derived 133 * from this software without specific prior written permission. 134 * 135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 146 * 147 * Alternatively, you may choose to be licensed under the terms of the 148 * GNU General Public License ("GPL") version 2 as published by the Free 149 * Software Foundation. 150 * 151 *****************************************************************************/ 152 153 #include <contrib/dev/acpica/compiler/aslcompiler.h> 154 #include <contrib/dev/acpica/include/acparser.h> 155 #include <contrib/dev/acpica/include/acdispat.h> 156 #include <contrib/dev/acpica/include/amlcode.h> 157 #include <contrib/dev/acpica/include/acinterp.h> 158 #include <contrib/dev/acpica/include/acdisasm.h> 159 #include <contrib/dev/acpica/include/acconvert.h> 160 161 162 /* local prototypes */ 163 164 static BOOLEAN 165 CvCommentExists ( 166 UINT8 *Address); 167 168 static BOOLEAN 169 CvIsFilename ( 170 char *Filename); 171 172 static ACPI_FILE_NODE* 173 CvFileAddressLookup( 174 char *Address, 175 ACPI_FILE_NODE *Head); 176 177 static void 178 CvAddToFileTree ( 179 char *Filename, 180 char *PreviousFilename); 181 182 static void 183 CvSetFileParent ( 184 char *ChildFile, 185 char *ParentFile); 186 187 188 /******************************************************************************* 189 * 190 * FUNCTION: CvIsFilename 191 * 192 * PARAMETERS: filename - input filename 193 * 194 * RETURN: BOOLEAN - TRUE if all characters are between 0x20 and 0x7f 195 * 196 * DESCRIPTION: Take a given char * and see if it contains all printable 197 * characters. If all characters have hexvalues 20-7f and ends with 198 * .dsl, we will assume that it is a proper filename. 199 * 200 ******************************************************************************/ 201 202 static BOOLEAN 203 CvIsFilename ( 204 char *Filename) 205 { 206 UINT64 Length = strlen(Filename); 207 char *FileExt = Filename + Length - 4; 208 UINT64 i; 209 210 211 if ((Length > 4) && AcpiUtStricmp (FileExt, ".dsl")) 212 { 213 return (FALSE); 214 } 215 216 for(i = 0; i<Length; ++i) 217 { 218 if (!isprint ((int) Filename[i])) 219 { 220 return (FALSE); 221 } 222 } 223 224 return (TRUE); 225 } 226 227 228 /******************************************************************************* 229 * 230 * FUNCTION: CvInitFileTree 231 * 232 * PARAMETERS: Table - input table 233 * RootFile - Output file that defines the DefinitionBlock 234 * 235 * RETURN: None 236 * 237 * DESCRIPTION: Initialize the file dependency tree by scanning the AML. 238 * This is referred as ASL_CV_INIT_FILETREE. 239 * 240 ******************************************************************************/ 241 242 void 243 CvInitFileTree ( 244 ACPI_TABLE_HEADER *Table, 245 FILE *RootFile) 246 { 247 UINT8 *TreeAml; 248 UINT8 *FileEnd; 249 char *Filename = NULL; 250 char *PreviousFilename = NULL; 251 char *ParentFilename = NULL; 252 char *ChildFilename = NULL; 253 UINT8 *AmlStart; 254 UINT32 AmlLength; 255 256 257 if (!AcpiGbl_CaptureComments) 258 { 259 return; 260 } 261 262 263 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 264 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 265 266 CvDbgPrint ("AmlLength: %x\n", AmlLength); 267 CvDbgPrint ("AmlStart: %p\n", AmlStart); 268 CvDbgPrint ("AmlEnd: %p\n", AmlStart+AmlLength); 269 270 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache); 271 272 AcpiGbl_FileTreeRoot->FileStart = (char *)(AmlStart); 273 AcpiGbl_FileTreeRoot->FileEnd = (char *)(AmlStart + Table->Length); 274 AcpiGbl_FileTreeRoot->Next = NULL; 275 AcpiGbl_FileTreeRoot->Parent = NULL; 276 AcpiGbl_FileTreeRoot->Filename = (char *)(AmlStart+2); 277 278 /* Set the root file to the current open file */ 279 280 AcpiGbl_FileTreeRoot->File = RootFile; 281 282 /* 283 * Set this to true because we don't need to output 284 * an include statement for the topmost file 285 */ 286 AcpiGbl_FileTreeRoot->IncludeWritten = TRUE; 287 Filename = NULL; 288 AcpiGbl_CurrentFilename = (char *)(AmlStart+2); 289 AcpiGbl_RootFilename = (char *)(AmlStart+2); 290 291 TreeAml = AmlStart; 292 FileEnd = AmlStart + AmlLength; 293 294 while (TreeAml <= FileEnd) 295 { 296 /* 297 * Make sure that this filename contains all printable characters 298 * and a .dsl extension at the end. If not, then it must be some 299 * raw data that doesn't outline a filename. 300 */ 301 if ((*TreeAml == AML_COMMENT_OP) && 302 (*(TreeAml +1) == FILENAME_COMMENT) && 303 (CvIsFilename ((char *)(TreeAml +2)))) 304 { 305 CvDbgPrint ("A9 and a 08 file\n"); 306 PreviousFilename = Filename; 307 Filename = (char *) (TreeAml +2); 308 309 CvAddToFileTree (Filename, PreviousFilename); 310 ChildFilename = Filename; 311 CvDbgPrint ("%s\n", Filename); 312 } 313 else if ((*TreeAml == AML_COMMENT_OP) && 314 (*(TreeAml +1) == PARENTFILENAME_COMMENT) && 315 (CvIsFilename ((char *)(TreeAml +2)))) 316 { 317 CvDbgPrint ("A9 and a 09 file\n"); 318 ParentFilename = (char *)(TreeAml +2); 319 CvSetFileParent (ChildFilename, ParentFilename); 320 CvDbgPrint ("%s\n", ParentFilename); 321 } 322 323 ++TreeAml; 324 } 325 } 326 327 328 /******************************************************************************* 329 * 330 * FUNCTION: CvClearOpComments 331 * 332 * PARAMETERS: Op -- clear all comments within this Op 333 * 334 * RETURN: None 335 * 336 * DESCRIPTION: Clear all converter-related fields of the given Op. 337 * This is referred as ASL_CV_CLEAR_OP_COMMENTS. 338 * 339 ******************************************************************************/ 340 341 void 342 CvClearOpComments ( 343 ACPI_PARSE_OBJECT *Op) 344 { 345 346 Op->Common.InlineComment = NULL; 347 Op->Common.EndNodeComment = NULL; 348 Op->Common.NameComment = NULL; 349 Op->Common.CommentList = NULL; 350 Op->Common.EndBlkComment = NULL; 351 Op->Common.CloseBraceComment = NULL; 352 Op->Common.CvFilename = NULL; 353 Op->Common.CvParentFilename = NULL; 354 } 355 356 357 /******************************************************************************* 358 * 359 * FUNCTION: CvCommentExists 360 * 361 * PARAMETERS: Address - check if this address appears in the list 362 * 363 * RETURN: BOOLEAN - TRUE if the address exists. 364 * 365 * DESCRIPTION: Look at the pointer address and check if this appears in the 366 * list of all addresses. If it exists in the list, return TRUE 367 * if it exists. Otherwise add to the list and return FALSE. 368 * 369 ******************************************************************************/ 370 371 static BOOLEAN 372 CvCommentExists ( 373 UINT8 *Address) 374 { 375 ACPI_COMMENT_ADDR_NODE *Current = AcpiGbl_CommentAddrListHead; 376 UINT8 Option; 377 378 379 if (!Address) 380 { 381 return (FALSE); 382 } 383 384 Option = *(Address + 1); 385 386 /* 387 * FILENAME_COMMENT and PARENTFILENAME_COMMENT are not treated as 388 * comments. They serve as markers for where the file starts and ends. 389 */ 390 if ((Option == FILENAME_COMMENT) || 391 (Option == PARENTFILENAME_COMMENT)) 392 { 393 return (FALSE); 394 } 395 396 if (!Current) 397 { 398 AcpiGbl_CommentAddrListHead = 399 AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 400 AcpiGbl_CommentAddrListHead->Addr = Address; 401 AcpiGbl_CommentAddrListHead->Next = NULL; 402 return (FALSE); 403 } 404 else 405 { 406 while (Current) 407 { 408 if (Current->Addr != Address) 409 { 410 Current = Current->Next; 411 } 412 else 413 { 414 return (TRUE); 415 } 416 } 417 418 /* 419 * If the execution gets to this point, it means that this 420 * address does not exists in the list. Add this address to the 421 * beginning of the list. 422 */ 423 Current = AcpiGbl_CommentAddrListHead; 424 AcpiGbl_CommentAddrListHead = 425 AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 426 427 AcpiGbl_CommentAddrListHead->Addr = Address; 428 AcpiGbl_CommentAddrListHead->Next = Current; 429 return (FALSE); 430 } 431 } 432 433 434 /******************************************************************************* 435 * 436 * FUNCTION: CvFilenameExists 437 * 438 * PARAMETERS: Filename - filename to search 439 * 440 * RETURN: ACPI_FILE_NODE - a pointer to a file node 441 * 442 * DESCRIPTION: Look for the given filename in the file dependency tree. 443 * Returns the file node if it exists, returns NULL if it does not. 444 * 445 ******************************************************************************/ 446 447 ACPI_FILE_NODE* 448 CvFilenameExists( 449 char *Filename, 450 ACPI_FILE_NODE *Head) 451 { 452 ACPI_FILE_NODE *Current = Head; 453 454 455 if (!Filename) 456 { 457 return (NULL); 458 } 459 460 while (Current) 461 { 462 if (!AcpiUtStricmp (Current->Filename, Filename)) 463 { 464 return (Current); 465 } 466 467 Current = Current->Next; 468 } 469 return (NULL); 470 } 471 472 473 /******************************************************************************* 474 * 475 * FUNCTION: CvFileAddressLookup 476 * 477 * PARAMETERS: Address - address to look up 478 * Head - file dependency tree 479 * 480 * RETURN: ACPI_FILE_NODE - pointer to a file node containing the address 481 * 482 * DESCRIPTION: Look for the given address in the file dependency tree. 483 * Returns the first file node where the given address is within 484 * the file node's starting and ending address. 485 * 486 ******************************************************************************/ 487 488 static ACPI_FILE_NODE * 489 CvFileAddressLookup( 490 char *Address, 491 ACPI_FILE_NODE *Head) 492 { 493 ACPI_FILE_NODE *Current = Head; 494 495 496 while (Current) 497 { 498 if ((Address >= Current->FileStart) && 499 (Address < Current->FileEnd || 500 !Current->FileEnd)) 501 { 502 return (Current); 503 } 504 505 Current = Current->Next; 506 } 507 508 return (NULL); 509 } 510 511 512 /******************************************************************************* 513 * 514 * FUNCTION: CvLabelFileNode 515 * 516 * PARAMETERS: Op 517 * 518 * RETURN: None 519 * 520 * DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field 521 * within the file tree and fills in appropriate file information 522 * from a matching node within the tree. 523 * This is referred as ASL_CV_LABEL_FILENODE. 524 * 525 ******************************************************************************/ 526 527 void 528 CvLabelFileNode( 529 ACPI_PARSE_OBJECT *Op) 530 { 531 ACPI_FILE_NODE *Node; 532 533 534 if (!Op) 535 { 536 return; 537 } 538 539 Node = CvFileAddressLookup ((char *) 540 Op->Common.Aml, AcpiGbl_FileTreeRoot); 541 if (!Node) 542 { 543 return; 544 } 545 546 Op->Common.CvFilename = Node->Filename; 547 if (Node->Parent) 548 { 549 Op->Common.CvParentFilename = Node->Parent->Filename; 550 } 551 else 552 { 553 Op->Common.CvParentFilename = Node->Filename; 554 } 555 } 556 557 558 /******************************************************************************* 559 * 560 * FUNCTION: CvAddToFileTree 561 * 562 * PARAMETERS: Filename - Address containing the name of the current 563 * filename 564 * PreviousFilename - Address containing the name of the previous 565 * filename 566 * 567 * RETURN: None 568 * 569 * DESCRIPTION: Add this filename to the AcpiGbl_FileTree if it does not exist. 570 * 571 ******************************************************************************/ 572 573 static void 574 CvAddToFileTree ( 575 char *Filename, 576 char *PreviousFilename) 577 { 578 ACPI_FILE_NODE *Node; 579 580 581 if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 582 PreviousFilename) 583 { 584 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 585 if (Node) 586 { 587 /* 588 * Set the end point of the PreviousFilename to the address 589 * of Filename. 590 */ 591 Node->FileEnd = Filename; 592 } 593 } 594 else if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 595 !PreviousFilename) 596 { 597 return; 598 } 599 600 Node = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot); 601 if (Node && PreviousFilename) 602 { 603 /* 604 * Update the end of the previous file and all of their parents' 605 * ending addresses. This is done to ensure that parent file 606 * ranges extend to the end of their childrens' files. 607 */ 608 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 609 if (Node && (Node->FileEnd < Filename)) 610 { 611 Node->FileEnd = Filename; 612 Node = Node->Parent; 613 while (Node) 614 { 615 if (Node->FileEnd < Filename) 616 { 617 Node->FileEnd = Filename; 618 } 619 620 Node = Node->Parent; 621 } 622 } 623 } 624 else 625 { 626 Node = AcpiGbl_FileTreeRoot; 627 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache); 628 629 AcpiGbl_FileTreeRoot->Next = Node; 630 AcpiGbl_FileTreeRoot->Parent = NULL; 631 AcpiGbl_FileTreeRoot->Filename = Filename; 632 AcpiGbl_FileTreeRoot->FileStart = Filename; 633 AcpiGbl_FileTreeRoot->IncludeWritten = FALSE; 634 AcpiGbl_FileTreeRoot->File = fopen(Filename, "w+"); 635 636 /* 637 * If we can't open the file, we need to abort here before we 638 * accidentally write to a NULL file. 639 */ 640 if (!AcpiGbl_FileTreeRoot->File) 641 { 642 /* delete the .xxx file */ 643 644 FlDeleteFile (ASL_FILE_AML_OUTPUT); 645 sprintf (AslGbl_MsgBuffer, "\"%s\" - %s", Filename, strerror (errno)); 646 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, 647 NULL, AslGbl_MsgBuffer); 648 AslAbort (); 649 } 650 } 651 } 652 653 654 /******************************************************************************* 655 * 656 * FUNCTION: CvSetFileParent 657 * 658 * PARAMETERS: ChildFile - contains the filename of the child file 659 * ParentFile - contains the filename of the parent file. 660 * 661 * RETURN: None 662 * 663 * DESCRIPTION: Point the parent pointer of the Child to the node that 664 * corresponds with the parent file node. 665 * 666 ******************************************************************************/ 667 668 static void 669 CvSetFileParent ( 670 char *ChildFile, 671 char *ParentFile) 672 { 673 ACPI_FILE_NODE *Child; 674 ACPI_FILE_NODE *Parent; 675 676 677 Child = CvFilenameExists (ChildFile, AcpiGbl_FileTreeRoot); 678 Parent = CvFilenameExists (ParentFile, AcpiGbl_FileTreeRoot); 679 680 if (Child && Parent) 681 { 682 Child->Parent = Parent; 683 684 while (Child->Parent) 685 { 686 if (Child->Parent->FileEnd < Child->FileStart) 687 { 688 Child->Parent->FileEnd = Child->FileStart; 689 } 690 691 Child = Child->Parent; 692 } 693 } 694 } 695 696 697 /******************************************************************************* 698 * 699 * FUNCTION: CvCaptureCommentsOnly 700 * 701 * PARAMETERS: ParserState - A parser state object 702 * 703 * RETURN: None 704 * 705 * DESCRIPTION: Look at the aml that the parser state is pointing to, 706 * capture any AML_COMMENT_OP and it's arguments and increment the 707 * aml pointer past the comment. Comments are transferred to parse 708 * nodes through CvTransferComments() as well as 709 * AcpiPsBuildNamedOp(). 710 * This is referred as ASL_CV_CAPTURE_COMMENTS_ONLY. 711 * 712 ******************************************************************************/ 713 714 void 715 CvCaptureCommentsOnly ( 716 ACPI_PARSE_STATE *ParserState) 717 { 718 UINT8 *Aml = ParserState->Aml; 719 UINT16 Opcode = (UINT16) ACPI_GET8 (Aml); 720 UINT32 Length = 0; 721 UINT8 CommentOption; 722 BOOLEAN StdDefBlockFlag = FALSE; 723 ACPI_COMMENT_NODE *CommentNode; 724 ACPI_FILE_NODE *FileNode; 725 726 727 if (!AcpiGbl_CaptureComments || 728 Opcode != AML_COMMENT_OP) 729 { 730 return; 731 } 732 733 while (Opcode == AML_COMMENT_OP) 734 { 735 CvDbgPrint ("comment aml address: %p\n", Aml); 736 737 if (CvCommentExists(ParserState->Aml)) 738 { 739 CvDbgPrint ("Avoiding capturing an existing comment.\n"); 740 } 741 else 742 { 743 CommentOption = *(Aml +1); 744 745 /* 746 * Increment past the comment option and point the 747 * appropriate char pointers 748 */ 749 Aml += 2; 750 751 /* Found a comment. Now, set pointers to these comments. */ 752 753 switch (CommentOption) 754 { 755 case STD_DEFBLK_COMMENT: 756 757 StdDefBlockFlag = TRUE; 758 759 /* 760 * Add to a linked list of nodes. This list will be 761 * taken by the parse node created next. 762 */ 763 CommentNode = AcpiOsAcquireObject ( 764 AcpiGbl_RegCommentCache); 765 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 766 CommentNode->Next = NULL; 767 768 if (!AcpiGbl_DefBlkCommentListHead) 769 { 770 AcpiGbl_DefBlkCommentListHead = CommentNode; 771 AcpiGbl_DefBlkCommentListTail = CommentNode; 772 } 773 else 774 { 775 AcpiGbl_DefBlkCommentListTail->Next = CommentNode; 776 AcpiGbl_DefBlkCommentListTail = 777 AcpiGbl_DefBlkCommentListTail->Next; 778 } 779 break; 780 781 case STANDARD_COMMENT: 782 783 CvDbgPrint ("found regular comment.\n"); 784 785 /* 786 * Add to a linked list of nodes. This list will be 787 * taken by the parse node created next. 788 */ 789 CommentNode = AcpiOsAcquireObject ( 790 AcpiGbl_RegCommentCache); 791 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 792 CommentNode->Next = NULL; 793 794 if (!AcpiGbl_RegCommentListHead) 795 { 796 AcpiGbl_RegCommentListHead = CommentNode; 797 AcpiGbl_RegCommentListTail = CommentNode; 798 } 799 else 800 { 801 AcpiGbl_RegCommentListTail->Next = CommentNode; 802 AcpiGbl_RegCommentListTail = 803 AcpiGbl_RegCommentListTail->Next; 804 } 805 break; 806 807 case ENDBLK_COMMENT: 808 809 CvDbgPrint ("found endblk comment.\n"); 810 811 /* Add to a linked list of nodes. This will be 812 * taken by the next created parse node. 813 */ 814 CommentNode = AcpiOsAcquireObject ( 815 AcpiGbl_RegCommentCache); 816 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 817 CommentNode->Next = NULL; 818 819 if (!AcpiGbl_EndBlkCommentListHead) 820 { 821 AcpiGbl_EndBlkCommentListHead = CommentNode; 822 AcpiGbl_EndBlkCommentListTail = CommentNode; 823 } 824 else 825 { 826 AcpiGbl_EndBlkCommentListTail->Next = CommentNode; 827 AcpiGbl_EndBlkCommentListTail = 828 AcpiGbl_EndBlkCommentListTail->Next; 829 } 830 break; 831 832 case INLINE_COMMENT: 833 834 CvDbgPrint ("found inline comment.\n"); 835 AcpiGbl_CurrentInlineComment = 836 ACPI_CAST_PTR (char, Aml); 837 break; 838 839 case ENDNODE_COMMENT: 840 841 CvDbgPrint ("found EndNode comment.\n"); 842 AcpiGbl_CurrentEndNodeComment = 843 ACPI_CAST_PTR (char, Aml); 844 break; 845 846 case CLOSE_BRACE_COMMENT: 847 848 CvDbgPrint ("found close brace comment.\n"); 849 AcpiGbl_CurrentCloseBraceComment = 850 ACPI_CAST_PTR (char, Aml); 851 break; 852 853 case END_DEFBLK_COMMENT: 854 855 CvDbgPrint ("Found comment that belongs after" 856 " the } for a definition block.\n"); 857 AcpiGbl_CurrentScope->Common.CloseBraceComment = 858 ACPI_CAST_PTR (char, Aml); 859 break; 860 861 case FILENAME_COMMENT: 862 863 CvDbgPrint ("Found a filename: %s\n", 864 ACPI_CAST_PTR (char, Aml)); 865 FileNode = CvFilenameExists ( 866 ACPI_CAST_PTR (char, Aml), AcpiGbl_FileTreeRoot); 867 868 /* 869 * If there is an INCLUDE_COMMENT followed by a 870 * FILENAME_COMMENT, then the INCLUDE_COMMENT is a comment 871 * that is emitted before the #include for the file. 872 * We will save the IncludeComment within the FileNode 873 * associated with this FILENAME_COMMENT. 874 */ 875 if (FileNode && AcpiGbl_IncCommentListHead) 876 { 877 FileNode->IncludeComment = AcpiGbl_IncCommentListHead; 878 AcpiGbl_IncCommentListHead = NULL; 879 AcpiGbl_IncCommentListTail = NULL; 880 } 881 break; 882 883 case PARENTFILENAME_COMMENT: 884 CvDbgPrint (" Found a parent filename.\n"); 885 break; 886 887 case INCLUDE_COMMENT: 888 889 /* 890 * Add to a linked list. This list will be taken by the 891 * parse node created next. See the FILENAME_COMMENT case 892 * for more details 893 */ 894 CommentNode = AcpiOsAcquireObject ( 895 AcpiGbl_RegCommentCache); 896 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 897 CommentNode->Next = NULL; 898 899 if (!AcpiGbl_IncCommentListHead) 900 { 901 AcpiGbl_IncCommentListHead = CommentNode; 902 AcpiGbl_IncCommentListTail = CommentNode; 903 } 904 else 905 { 906 AcpiGbl_IncCommentListTail->Next = CommentNode; 907 AcpiGbl_IncCommentListTail = 908 AcpiGbl_IncCommentListTail->Next; 909 } 910 911 CvDbgPrint ("Found a include comment: %s\n", 912 CommentNode->Comment); 913 break; 914 915 default: 916 917 /* Not a valid comment option. Revert the AML */ 918 919 goto DefBlock; 920 921 } /* End switch statement */ 922 923 } /* End else */ 924 925 /* Determine the length and move forward that amount */ 926 927 Length = 0; 928 while (ParserState->Aml[Length]) 929 { 930 Length++; 931 } 932 933 ParserState->Aml += Length + 1; 934 935 /* Peek at the next Opcode. */ 936 937 Aml = ParserState->Aml; 938 Opcode = (UINT16) ACPI_GET8 (Aml); 939 } 940 941 DefBlock: 942 if (StdDefBlockFlag) 943 { 944 /* 945 * Give all of its comments to the current scope, which is known as 946 * the definition block, since STD_DEFBLK_COMMENT only appears after 947 * definition block headers. 948 */ 949 AcpiGbl_CurrentScope->Common.CommentList 950 = AcpiGbl_DefBlkCommentListHead; 951 AcpiGbl_DefBlkCommentListHead = NULL; 952 AcpiGbl_DefBlkCommentListTail = NULL; 953 } 954 } 955 956 957 /******************************************************************************* 958 * 959 * FUNCTION: CvCaptureComments 960 * 961 * PARAMETERS: ParserState - A parser state object 962 * 963 * RETURN: None 964 * 965 * DESCRIPTION: Wrapper function for CvCaptureCommentsOnly 966 * This is referred as ASL_CV_CAPTURE_COMMENTS. 967 * 968 ******************************************************************************/ 969 970 void 971 CvCaptureComments ( 972 ACPI_WALK_STATE *WalkState) 973 { 974 UINT8 *Aml; 975 UINT16 Opcode; 976 const ACPI_OPCODE_INFO *OpInfo; 977 978 979 if (!AcpiGbl_CaptureComments) 980 { 981 return; 982 } 983 984 /* 985 * Before parsing, check to see that comments that come directly 986 * after deferred opcodes aren't being processed. 987 */ 988 Aml = WalkState->ParserState.Aml; 989 Opcode = (UINT16) ACPI_GET8 (Aml); 990 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 991 992 if (!(OpInfo->Flags & AML_DEFER) || 993 ((OpInfo->Flags & AML_DEFER) && 994 (WalkState->PassNumber != ACPI_IMODE_LOAD_PASS1))) 995 { 996 CvCaptureCommentsOnly (&WalkState->ParserState); 997 WalkState->Aml = WalkState->ParserState.Aml; 998 } 999 1000 } 1001 1002 1003 /******************************************************************************* 1004 * 1005 * FUNCTION: CvTransferComments 1006 * 1007 * PARAMETERS: Op - Transfer comments to this Op 1008 * 1009 * RETURN: None 1010 * 1011 * DESCRIPTION: Transfer all of the comments stored in global containers to the 1012 * given Op. This will be invoked shortly after the parser creates 1013 * a ParseOp. 1014 * This is referred as ASL_CV_TRANSFER_COMMENTS. 1015 * 1016 ******************************************************************************/ 1017 1018 void 1019 CvTransferComments ( 1020 ACPI_PARSE_OBJECT *Op) 1021 { 1022 1023 Op->Common.InlineComment = AcpiGbl_CurrentInlineComment; 1024 AcpiGbl_CurrentInlineComment = NULL; 1025 1026 Op->Common.EndNodeComment = AcpiGbl_CurrentEndNodeComment; 1027 AcpiGbl_CurrentEndNodeComment = NULL; 1028 1029 Op->Common.CloseBraceComment = AcpiGbl_CurrentCloseBraceComment; 1030 AcpiGbl_CurrentCloseBraceComment = NULL; 1031 1032 Op->Common.CommentList = AcpiGbl_RegCommentListHead; 1033 AcpiGbl_RegCommentListHead = NULL; 1034 AcpiGbl_RegCommentListTail = NULL; 1035 1036 Op->Common.EndBlkComment = AcpiGbl_EndBlkCommentListHead; 1037 AcpiGbl_EndBlkCommentListHead = NULL; 1038 AcpiGbl_EndBlkCommentListTail = NULL; 1039 } 1040