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 - 2018, 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 * AmlStart - Address of the starting point of the AML. 234 * AmlLength - Length of the AML file. 235 * 236 * RETURN: None 237 * 238 * DESCRIPTION: Initialize the file dependency tree by scanning the AML. 239 * This is referred as ASL_CV_INIT_FILETREE. 240 * 241 ******************************************************************************/ 242 243 void 244 CvInitFileTree ( 245 ACPI_TABLE_HEADER *Table, 246 UINT8 *AmlStart, 247 UINT32 AmlLength) 248 { 249 UINT8 *TreeAml; 250 UINT8 *FileEnd; 251 char *Filename = NULL; 252 char *PreviousFilename = NULL; 253 char *ParentFilename = NULL; 254 char *ChildFilename = NULL; 255 256 257 if (!AcpiGbl_CaptureComments) 258 { 259 return; 260 } 261 262 CvDbgPrint ("AmlLength: %x\n", AmlLength); 263 CvDbgPrint ("AmlStart: %p\n", AmlStart); 264 CvDbgPrint ("AmlEnd?: %p\n", AmlStart+AmlLength); 265 266 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache); 267 268 AcpiGbl_FileTreeRoot->FileStart = (char *)(AmlStart); 269 AcpiGbl_FileTreeRoot->FileEnd = (char *)(AmlStart + Table->Length); 270 AcpiGbl_FileTreeRoot->Next = NULL; 271 AcpiGbl_FileTreeRoot->Parent = NULL; 272 AcpiGbl_FileTreeRoot->Filename = (char *)(AmlStart+2); 273 274 /* Set the root file to the current open file */ 275 276 AcpiGbl_FileTreeRoot->File = AcpiGbl_OutputFile; 277 278 /* 279 * Set this to true because we dont need to output 280 * an include statement for the topmost file 281 */ 282 AcpiGbl_FileTreeRoot->IncludeWritten = TRUE; 283 Filename = NULL; 284 AcpiGbl_CurrentFilename = (char *)(AmlStart+2); 285 AcpiGbl_RootFilename = (char *)(AmlStart+2); 286 287 TreeAml = AmlStart; 288 FileEnd = AmlStart + AmlLength; 289 290 while (TreeAml <= FileEnd) 291 { 292 /* 293 * Make sure that this filename contains all printable characters 294 * and a .dsl extension at the end. If not, then it must be some 295 * raw data that doesn't outline a filename. 296 */ 297 if ((*TreeAml == AML_COMMENT_OP) && 298 (*(TreeAml +1) == FILENAME_COMMENT) && 299 (CvIsFilename ((char *)(TreeAml +2)))) 300 { 301 CvDbgPrint ("A9 and a 08 file\n"); 302 PreviousFilename = Filename; 303 Filename = (char *) (TreeAml +2); 304 305 CvAddToFileTree (Filename, PreviousFilename); 306 ChildFilename = Filename; 307 CvDbgPrint ("%s\n", Filename); 308 } 309 else if ((*TreeAml == AML_COMMENT_OP) && 310 (*(TreeAml +1) == PARENTFILENAME_COMMENT) && 311 (CvIsFilename ((char *)(TreeAml +2)))) 312 { 313 CvDbgPrint ("A9 and a 09 file\n"); 314 ParentFilename = (char *)(TreeAml +2); 315 CvSetFileParent (ChildFilename, ParentFilename); 316 CvDbgPrint ("%s\n", ParentFilename); 317 } 318 319 ++TreeAml; 320 } 321 } 322 323 324 /******************************************************************************* 325 * 326 * FUNCTION: CvClearOpComments 327 * 328 * PARAMETERS: Op -- clear all comments within this Op 329 * 330 * RETURN: None 331 * 332 * DESCRIPTION: Clear all converter-related fields of the given Op. 333 * This is referred as ASL_CV_CLEAR_OP_COMMENTS. 334 * 335 ******************************************************************************/ 336 337 void 338 CvClearOpComments ( 339 ACPI_PARSE_OBJECT *Op) 340 { 341 342 Op->Common.InlineComment = NULL; 343 Op->Common.EndNodeComment = NULL; 344 Op->Common.NameComment = NULL; 345 Op->Common.CommentList = NULL; 346 Op->Common.EndBlkComment = NULL; 347 Op->Common.CloseBraceComment = NULL; 348 Op->Common.CvFilename = NULL; 349 Op->Common.CvParentFilename = NULL; 350 } 351 352 353 /******************************************************************************* 354 * 355 * FUNCTION: CvCommentExists 356 * 357 * PARAMETERS: Address - check if this address appears in the list 358 * 359 * RETURN: BOOLEAN - TRUE if the address exists. 360 * 361 * DESCRIPTION: Look at the pointer address and check if this appears in the 362 * list of all addresses. If it exists in the list, return TRUE 363 * if it exists. Otherwise add to the list and return FALSE. 364 * 365 ******************************************************************************/ 366 367 static BOOLEAN 368 CvCommentExists ( 369 UINT8 *Address) 370 { 371 ACPI_COMMENT_ADDR_NODE *Current = AcpiGbl_CommentAddrListHead; 372 UINT8 Option; 373 374 375 if (!Address) 376 { 377 return (FALSE); 378 } 379 380 Option = *(Address + 1); 381 382 /* 383 * FILENAME_COMMENT and PARENTFILENAME_COMMENT are not treated as 384 * comments. They serve as markers for where the file starts and ends. 385 */ 386 if ((Option == FILENAME_COMMENT) || 387 (Option == PARENTFILENAME_COMMENT)) 388 { 389 return (FALSE); 390 } 391 392 if (!Current) 393 { 394 AcpiGbl_CommentAddrListHead = 395 AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 396 AcpiGbl_CommentAddrListHead->Addr = Address; 397 AcpiGbl_CommentAddrListHead->Next = NULL; 398 return (FALSE); 399 } 400 else 401 { 402 while (Current) 403 { 404 if (Current->Addr != Address) 405 { 406 Current = Current->Next; 407 } 408 else 409 { 410 return (TRUE); 411 } 412 } 413 414 /* 415 * If the execution gets to this point, it means that this 416 * address does not exists in the list. Add this address to the 417 * beginning of the list. 418 */ 419 Current = AcpiGbl_CommentAddrListHead; 420 AcpiGbl_CommentAddrListHead = 421 AcpiOsAcquireObject (AcpiGbl_RegCommentCache); 422 423 AcpiGbl_CommentAddrListHead->Addr = Address; 424 AcpiGbl_CommentAddrListHead->Next = Current; 425 return (FALSE); 426 } 427 } 428 429 430 /******************************************************************************* 431 * 432 * FUNCTION: CvFilenameExists 433 * 434 * PARAMETERS: Filename - filename to search 435 * 436 * RETURN: ACPI_FILE_NODE - a pointer to a file node 437 * 438 * DESCRIPTION: Look for the given filename in the file dependency tree. 439 * Returns the file node if it exists, returns NULL if it does not. 440 * 441 ******************************************************************************/ 442 443 ACPI_FILE_NODE* 444 CvFilenameExists( 445 char *Filename, 446 ACPI_FILE_NODE *Head) 447 { 448 ACPI_FILE_NODE *Current = Head; 449 450 451 if (!Filename) 452 { 453 return (NULL); 454 } 455 456 while (Current) 457 { 458 if (!AcpiUtStricmp (Current->Filename, Filename)) 459 { 460 return (Current); 461 } 462 463 Current = Current->Next; 464 } 465 return (NULL); 466 } 467 468 469 /******************************************************************************* 470 * 471 * FUNCTION: CvFileAddressLookup 472 * 473 * PARAMETERS: Address - address to look up 474 * Head - file dependency tree 475 * 476 * RETURN: ACPI_FILE_NODE - pointer to a file node containing the address 477 * 478 * DESCRIPTION: Look for the given address in the file dependency tree. 479 * Returns the first file node where the given address is within 480 * the file node's starting and ending address. 481 * 482 ******************************************************************************/ 483 484 static ACPI_FILE_NODE * 485 CvFileAddressLookup( 486 char *Address, 487 ACPI_FILE_NODE *Head) 488 { 489 ACPI_FILE_NODE *Current = Head; 490 491 492 while (Current) 493 { 494 if ((Address >= Current->FileStart) && 495 (Address < Current->FileEnd || 496 !Current->FileEnd)) 497 { 498 return (Current); 499 } 500 501 Current = Current->Next; 502 } 503 504 return (NULL); 505 } 506 507 508 /******************************************************************************* 509 * 510 * FUNCTION: CvLabelFileNode 511 * 512 * PARAMETERS: Op 513 * 514 * RETURN: None 515 * 516 * DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field 517 * within the file tree and fills in approperiate file information 518 * from a matching node within the tree. 519 * This is referred as ASL_CV_LABEL_FILENODE. 520 * 521 ******************************************************************************/ 522 523 void 524 CvLabelFileNode( 525 ACPI_PARSE_OBJECT *Op) 526 { 527 ACPI_FILE_NODE *Node; 528 529 530 if (!Op) 531 { 532 return; 533 } 534 535 Node = CvFileAddressLookup ((char *) 536 Op->Common.Aml, AcpiGbl_FileTreeRoot); 537 if (!Node) 538 { 539 return; 540 } 541 542 Op->Common.CvFilename = Node->Filename; 543 if (Node->Parent) 544 { 545 Op->Common.CvParentFilename = Node->Parent->Filename; 546 } 547 else 548 { 549 Op->Common.CvParentFilename = Node->Filename; 550 } 551 } 552 553 554 /******************************************************************************* 555 * 556 * FUNCTION: CvAddToFileTree 557 * 558 * PARAMETERS: Filename - Address containing the name of the current 559 * filename 560 * PreviousFilename - Address containing the name of the previous 561 * filename 562 * 563 * RETURN: None 564 * 565 * DESCRIPTION: Add this filename to the AcpiGbl_FileTree if it does not exist. 566 * 567 ******************************************************************************/ 568 569 static void 570 CvAddToFileTree ( 571 char *Filename, 572 char *PreviousFilename) 573 { 574 ACPI_FILE_NODE *Node; 575 576 577 if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 578 PreviousFilename) 579 { 580 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 581 if (Node) 582 { 583 /* 584 * Set the end point of the PreviousFilename to the address 585 * of Filename. 586 */ 587 Node->FileEnd = Filename; 588 } 589 } 590 else if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) && 591 !PreviousFilename) 592 { 593 return; 594 } 595 596 Node = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot); 597 if (Node && PreviousFilename) 598 { 599 /* 600 * Update the end of the previous file and all of their parents' 601 * ending addresses. This is done to ensure that parent file 602 * ranges extend to the end of their childrens' files. 603 */ 604 Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot); 605 if (Node && (Node->FileEnd < Filename)) 606 { 607 Node->FileEnd = Filename; 608 Node = Node->Parent; 609 while (Node) 610 { 611 if (Node->FileEnd < Filename) 612 { 613 Node->FileEnd = Filename; 614 } 615 616 Node = Node->Parent; 617 } 618 } 619 } 620 else 621 { 622 Node = AcpiGbl_FileTreeRoot; 623 AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache); 624 625 AcpiGbl_FileTreeRoot->Next = Node; 626 AcpiGbl_FileTreeRoot->Parent = NULL; 627 AcpiGbl_FileTreeRoot->Filename = Filename; 628 AcpiGbl_FileTreeRoot->FileStart = Filename; 629 AcpiGbl_FileTreeRoot->IncludeWritten = FALSE; 630 AcpiGbl_FileTreeRoot->File = fopen(Filename, "w+"); 631 632 /* 633 * If we can't open the file, we need to abort here before we 634 * accidentally write to a NULL file. 635 */ 636 if (!AcpiGbl_FileTreeRoot->File) 637 { 638 /* delete the .xxx file */ 639 640 FlDeleteFile (ASL_FILE_AML_OUTPUT); 641 sprintf (MsgBuffer, "\"%s\" - %s", Filename, strerror (errno)); 642 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, 643 NULL, MsgBuffer); 644 AslAbort (); 645 } 646 } 647 } 648 649 650 /******************************************************************************* 651 * 652 * FUNCTION: CvSetFileParent 653 * 654 * PARAMETERS: ChildFile - contains the filename of the child file 655 * ParentFile - contains the filename of the parent file. 656 * 657 * RETURN: None 658 * 659 * DESCRIPTION: Point the parent pointer of the Child to the node that 660 * corresponds with the parent file node. 661 * 662 ******************************************************************************/ 663 664 static void 665 CvSetFileParent ( 666 char *ChildFile, 667 char *ParentFile) 668 { 669 ACPI_FILE_NODE *Child; 670 ACPI_FILE_NODE *Parent; 671 672 673 Child = CvFilenameExists (ChildFile, AcpiGbl_FileTreeRoot); 674 Parent = CvFilenameExists (ParentFile, AcpiGbl_FileTreeRoot); 675 676 if (Child && Parent) 677 { 678 Child->Parent = Parent; 679 680 while (Child->Parent) 681 { 682 if (Child->Parent->FileEnd < Child->FileStart) 683 { 684 Child->Parent->FileEnd = Child->FileStart; 685 } 686 687 Child = Child->Parent; 688 } 689 } 690 } 691 692 693 /******************************************************************************* 694 * 695 * FUNCTION: CvCaptureCommentsOnly 696 * 697 * PARAMETERS: ParserState - A parser state object 698 * 699 * RETURN: None 700 * 701 * DESCRIPTION: Look at the aml that the parser state is pointing to, 702 * capture any AML_COMMENT_OP and it's arguments and increment the 703 * aml pointer past the comment. Comments are transferred to parse 704 * nodes through CvTransferComments() as well as 705 * AcpiPsBuildNamedOp(). 706 * This is referred as ASL_CV_CAPTURE_COMMENTS_ONLY. 707 * 708 ******************************************************************************/ 709 710 void 711 CvCaptureCommentsOnly ( 712 ACPI_PARSE_STATE *ParserState) 713 { 714 UINT8 *Aml = ParserState->Aml; 715 UINT16 Opcode = (UINT16) ACPI_GET8 (Aml); 716 UINT32 Length = 0; 717 UINT8 CommentOption; 718 BOOLEAN StdDefBlockFlag = FALSE; 719 ACPI_COMMENT_NODE *CommentNode; 720 ACPI_FILE_NODE *FileNode; 721 722 723 if (!AcpiGbl_CaptureComments || 724 Opcode != AML_COMMENT_OP) 725 { 726 return; 727 } 728 729 while (Opcode == AML_COMMENT_OP) 730 { 731 CvDbgPrint ("comment aml address: %p\n", Aml); 732 733 if (CvCommentExists(ParserState->Aml)) 734 { 735 CvDbgPrint ("Avoiding capturing an existing comment.\n"); 736 } 737 else 738 { 739 CommentOption = *(Aml +1); 740 741 /* 742 * Increment past the comment option and point the 743 * appropriate char pointers 744 */ 745 Aml += 2; 746 747 /* Found a comment. Now, set pointers to these comments. */ 748 749 switch (CommentOption) 750 { 751 case STD_DEFBLK_COMMENT: 752 753 StdDefBlockFlag = TRUE; 754 755 /* 756 * Add to a linked list of nodes. This list will be 757 * taken by the parse node created next. 758 */ 759 CommentNode = AcpiOsAcquireObject ( 760 AcpiGbl_RegCommentCache); 761 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 762 CommentNode->Next = NULL; 763 764 if (!AcpiGbl_DefBlkCommentListHead) 765 { 766 AcpiGbl_DefBlkCommentListHead = CommentNode; 767 AcpiGbl_DefBlkCommentListTail = CommentNode; 768 } 769 else 770 { 771 AcpiGbl_DefBlkCommentListTail->Next = CommentNode; 772 AcpiGbl_DefBlkCommentListTail = 773 AcpiGbl_DefBlkCommentListTail->Next; 774 } 775 break; 776 777 case STANDARD_COMMENT: 778 779 CvDbgPrint ("found regular comment.\n"); 780 781 /* 782 * Add to a linked list of nodes. This list will be 783 * taken by the parse node created next. 784 */ 785 CommentNode = AcpiOsAcquireObject ( 786 AcpiGbl_RegCommentCache); 787 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 788 CommentNode->Next = NULL; 789 790 if (!AcpiGbl_RegCommentListHead) 791 { 792 AcpiGbl_RegCommentListHead = CommentNode; 793 AcpiGbl_RegCommentListTail = CommentNode; 794 } 795 else 796 { 797 AcpiGbl_RegCommentListTail->Next = CommentNode; 798 AcpiGbl_RegCommentListTail = 799 AcpiGbl_RegCommentListTail->Next; 800 } 801 break; 802 803 case ENDBLK_COMMENT: 804 805 CvDbgPrint ("found endblk comment.\n"); 806 807 /* Add to a linked list of nodes. This will be 808 * taken by the next created parse node. 809 */ 810 CommentNode = AcpiOsAcquireObject ( 811 AcpiGbl_RegCommentCache); 812 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 813 CommentNode->Next = NULL; 814 815 if (!AcpiGbl_EndBlkCommentListHead) 816 { 817 AcpiGbl_EndBlkCommentListHead = CommentNode; 818 AcpiGbl_EndBlkCommentListTail = CommentNode; 819 } 820 else 821 { 822 AcpiGbl_EndBlkCommentListTail->Next = CommentNode; 823 AcpiGbl_EndBlkCommentListTail = 824 AcpiGbl_EndBlkCommentListTail->Next; 825 } 826 break; 827 828 case INLINE_COMMENT: 829 830 CvDbgPrint ("found inline comment.\n"); 831 AcpiGbl_CurrentInlineComment = 832 ACPI_CAST_PTR (char, Aml); 833 break; 834 835 case ENDNODE_COMMENT: 836 837 CvDbgPrint ("found EndNode comment.\n"); 838 AcpiGbl_CurrentEndNodeComment = 839 ACPI_CAST_PTR (char, Aml); 840 break; 841 842 case CLOSE_BRACE_COMMENT: 843 844 CvDbgPrint ("found close brace comment.\n"); 845 AcpiGbl_CurrentCloseBraceComment = 846 ACPI_CAST_PTR (char, Aml); 847 break; 848 849 case END_DEFBLK_COMMENT: 850 851 CvDbgPrint ("Found comment that belongs after" 852 " the } for a definition block.\n"); 853 AcpiGbl_CurrentScope->Common.CloseBraceComment = 854 ACPI_CAST_PTR (char, Aml); 855 break; 856 857 case FILENAME_COMMENT: 858 859 CvDbgPrint ("Found a filename: %s\n", 860 ACPI_CAST_PTR (char, Aml)); 861 FileNode = CvFilenameExists ( 862 ACPI_CAST_PTR (char, Aml), AcpiGbl_FileTreeRoot); 863 864 /* 865 * If there is an INCLUDE_COMMENT followed by a 866 * FILENAME_COMMENT, then the INCLUDE_COMMENT is a comment 867 * that is emitted before the #include for the file. 868 * We will save the IncludeComment within the FileNode 869 * associated with this FILENAME_COMMENT. 870 */ 871 if (FileNode && AcpiGbl_IncCommentListHead) 872 { 873 FileNode->IncludeComment = AcpiGbl_IncCommentListHead; 874 AcpiGbl_IncCommentListHead = NULL; 875 AcpiGbl_IncCommentListTail = NULL; 876 } 877 break; 878 879 case PARENTFILENAME_COMMENT: 880 CvDbgPrint (" Found a parent filename.\n"); 881 break; 882 883 case INCLUDE_COMMENT: 884 885 /* 886 * Add to a linked list. This list will be taken by the 887 * parse node created next. See the FILENAME_COMMENT case 888 * for more details 889 */ 890 CommentNode = AcpiOsAcquireObject ( 891 AcpiGbl_RegCommentCache); 892 CommentNode->Comment = ACPI_CAST_PTR (char, Aml); 893 CommentNode->Next = NULL; 894 895 if (!AcpiGbl_IncCommentListHead) 896 { 897 AcpiGbl_IncCommentListHead = CommentNode; 898 AcpiGbl_IncCommentListTail = CommentNode; 899 } 900 else 901 { 902 AcpiGbl_IncCommentListTail->Next = CommentNode; 903 AcpiGbl_IncCommentListTail = 904 AcpiGbl_IncCommentListTail->Next; 905 } 906 907 CvDbgPrint ("Found a include comment: %s\n", 908 CommentNode->Comment); 909 break; 910 911 default: 912 913 /* Not a valid comment option. Revert the AML */ 914 915 Aml -= 2; 916 goto DefBlock; 917 918 } /* End switch statement */ 919 920 } /* End else */ 921 922 /* Determine the length and move forward that amount */ 923 924 Length = 0; 925 while (ParserState->Aml[Length]) 926 { 927 Length++; 928 } 929 930 ParserState->Aml += Length + 1; 931 932 /* Peek at the next Opcode. */ 933 934 Aml = ParserState->Aml; 935 Opcode = (UINT16) ACPI_GET8 (Aml); 936 } 937 938 DefBlock: 939 if (StdDefBlockFlag) 940 { 941 /* 942 * Give all of its comments to the current scope, which is known as 943 * the definition block, since STD_DEFBLK_COMMENT only appears after 944 * definition block headers. 945 */ 946 AcpiGbl_CurrentScope->Common.CommentList 947 = AcpiGbl_DefBlkCommentListHead; 948 AcpiGbl_DefBlkCommentListHead = NULL; 949 AcpiGbl_DefBlkCommentListTail = NULL; 950 } 951 } 952 953 954 /******************************************************************************* 955 * 956 * FUNCTION: CvCaptureComments 957 * 958 * PARAMETERS: ParserState - A parser state object 959 * 960 * RETURN: None 961 * 962 * DESCRIPTION: Wrapper function for CvCaptureCommentsOnly 963 * This is referred as ASL_CV_CAPTURE_COMMENTS. 964 * 965 ******************************************************************************/ 966 967 void 968 CvCaptureComments ( 969 ACPI_WALK_STATE *WalkState) 970 { 971 UINT8 *Aml; 972 UINT16 Opcode; 973 const ACPI_OPCODE_INFO *OpInfo; 974 975 976 if (!AcpiGbl_CaptureComments) 977 { 978 return; 979 } 980 981 /* 982 * Before parsing, check to see that comments that come directly 983 * after deferred opcodes aren't being processed. 984 */ 985 Aml = WalkState->ParserState.Aml; 986 Opcode = (UINT16) ACPI_GET8 (Aml); 987 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 988 989 if (!(OpInfo->Flags & AML_DEFER) || 990 ((OpInfo->Flags & AML_DEFER) && 991 (WalkState->PassNumber != ACPI_IMODE_LOAD_PASS1))) 992 { 993 CvCaptureCommentsOnly (&WalkState->ParserState); 994 WalkState->Aml = WalkState->ParserState.Aml; 995 } 996 997 } 998 999 1000 /******************************************************************************* 1001 * 1002 * FUNCTION: CvTransferComments 1003 * 1004 * PARAMETERS: Op - Transfer comments to this Op 1005 * 1006 * RETURN: None 1007 * 1008 * DESCRIPTION: Transfer all of the commments stored in global containers to the 1009 * given Op. This will be invoked shortly after the parser creates 1010 * a ParseOp. 1011 * This is referred as ASL_CV_TRANSFER_COMMENTS. 1012 * 1013 ******************************************************************************/ 1014 1015 void 1016 CvTransferComments ( 1017 ACPI_PARSE_OBJECT *Op) 1018 { 1019 1020 Op->Common.InlineComment = AcpiGbl_CurrentInlineComment; 1021 AcpiGbl_CurrentInlineComment = NULL; 1022 1023 Op->Common.EndNodeComment = AcpiGbl_CurrentEndNodeComment; 1024 AcpiGbl_CurrentEndNodeComment = NULL; 1025 1026 Op->Common.CloseBraceComment = AcpiGbl_CurrentCloseBraceComment; 1027 AcpiGbl_CurrentCloseBraceComment = NULL; 1028 1029 Op->Common.CommentList = AcpiGbl_RegCommentListHead; 1030 AcpiGbl_RegCommentListHead = NULL; 1031 AcpiGbl_RegCommentListTail = NULL; 1032 1033 Op->Common.EndBlkComment = AcpiGbl_EndBlkCommentListHead; 1034 AcpiGbl_EndBlkCommentListHead = NULL; 1035 AcpiGbl_EndBlkCommentListTail = NULL; 1036 } 1037