1/****************************************************************************** 2 * 3 * Module Name: dtutils.c - Utility routines for the data table compiler 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116#include "aslcompiler.h" 117#include "dtcompiler.h" 118#include "actables.h" 119 120#define _COMPONENT DT_COMPILER 121 ACPI_MODULE_NAME ("dtutils") 122 123/* Local prototypes */ 124 125static void 126DtSum ( 127 DT_SUBTABLE *Subtable, 128 void *Context, 129 void *ReturnValue); 130 131 132/****************************************************************************** 133 * 134 * FUNCTION: DtError 135 * 136 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 137 * MessageId - Index into global message buffer 138 * Op - Parse node where error happened 139 * ExtraMessage - additional error message 140 * 141 * RETURN: None 142 * 143 * DESCRIPTION: Common error interface for data table compiler 144 * 145 *****************************************************************************/ 146 147void 148DtError ( 149 UINT8 Level, 150 UINT16 MessageId, 151 DT_FIELD *FieldObject, 152 char *ExtraMessage) 153{ 154 155 /* Check if user wants to ignore this exception */ 156 157 if (AslIsExceptionDisabled (Level, MessageId)) 158 { 159 return; 160 } 161 162 if (FieldObject) 163 { 164 AslCommonError (Level, MessageId, 165 FieldObject->Line, 166 FieldObject->Line, 167 FieldObject->ByteOffset, 168 FieldObject->Column, 169 Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 170 } 171 else 172 { 173 AslCommonError (Level, MessageId, 0, 174 0, 0, 0, 0, ExtraMessage); 175 } 176} 177 178 179/****************************************************************************** 180 * 181 * FUNCTION: DtNameError 182 * 183 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 184 * MessageId - Index into global message buffer 185 * Op - Parse node where error happened 186 * ExtraMessage - additional error message 187 * 188 * RETURN: None 189 * 190 * DESCRIPTION: Error interface for named objects 191 * 192 *****************************************************************************/ 193 194void 195DtNameError ( 196 UINT8 Level, 197 UINT16 MessageId, 198 DT_FIELD *FieldObject, 199 char *ExtraMessage) 200{ 201 202 switch (Level) 203 { 204 case ASL_WARNING2: 205 case ASL_WARNING3: 206 207 if (Gbl_WarningLevel < Level) 208 { 209 return; 210 } 211 break; 212 213 default: 214 215 break; 216 } 217 218 if (FieldObject) 219 { 220 AslCommonError (Level, MessageId, 221 FieldObject->Line, 222 FieldObject->Line, 223 FieldObject->ByteOffset, 224 FieldObject->NameColumn, 225 Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 226 } 227 else 228 { 229 AslCommonError (Level, MessageId, 0, 230 0, 0, 0, 0, ExtraMessage); 231 } 232} 233 234 235/******************************************************************************* 236 * 237 * FUNCTION: DtFatal 238 * 239 * PARAMETERS: None 240 * 241 * RETURN: None 242 * 243 * DESCRIPTION: Dump the error log and abort the compiler. Used for serious 244 * compile or I/O errors 245 * 246 ******************************************************************************/ 247 248void 249DtFatal ( 250 UINT16 MessageId, 251 DT_FIELD *FieldObject, 252 char *ExtraMessage) 253{ 254 255 DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage); 256 257/* 258 * TBD: remove this entire function, DtFatal 259 * 260 * We cannot abort the compiler on error, because we may be compiling a 261 * list of files. We must move on to the next file. 262 */ 263#ifdef __OBSOLETE 264 CmCleanupAndExit (); 265 exit (1); 266#endif 267} 268 269 270/****************************************************************************** 271 * 272 * FUNCTION: DtStrtoul64 273 * 274 * PARAMETERS: String - Null terminated string 275 * ReturnInteger - Where the converted integer is returned 276 * 277 * RETURN: Status 278 * 279 * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned 280 * value. Assumes no leading "0x" for the constant. 281 * 282 * Portability note: The reason this function exists is because a 64-bit 283 * sscanf is not available in all environments. 284 * 285 *****************************************************************************/ 286 287ACPI_STATUS 288DtStrtoul64 ( 289 char *String, 290 UINT64 *ReturnInteger) 291{ 292 char *ThisChar = String; 293 UINT32 ThisDigit; 294 UINT64 ReturnValue = 0; 295 int DigitCount = 0; 296 297 298 /* Skip over any white space in the buffer */ 299 300 while ((*ThisChar == ' ') || (*ThisChar == '\t')) 301 { 302 ThisChar++; 303 } 304 305 /* Skip leading zeros */ 306 307 while ((*ThisChar) == '0') 308 { 309 ThisChar++; 310 } 311 312 /* Convert character-by-character */ 313 314 while (*ThisChar) 315 { 316 if (isdigit ((int) *ThisChar)) 317 { 318 /* Convert ASCII 0-9 to Decimal value */ 319 320 ThisDigit = ((UINT8) *ThisChar) - '0'; 321 } 322 else /* Letter */ 323 { 324 ThisDigit = (UINT32) toupper ((int) *ThisChar); 325 if (!isxdigit ((int) ThisDigit)) 326 { 327 /* Not A-F */ 328 329 return (AE_BAD_CHARACTER); 330 } 331 332 /* Convert ASCII Hex char (A-F) to value */ 333 334 ThisDigit = (ThisDigit - 'A') + 10; 335 } 336 337 /* Insert the 4-bit hex digit */ 338 339 ReturnValue <<= 4; 340 ReturnValue += ThisDigit; 341 342 ThisChar++; 343 DigitCount++; 344 if (DigitCount > 16) 345 { 346 /* Value is too large (> 64 bits/8 bytes/16 hex digits) */ 347 348 return (AE_LIMIT); 349 } 350 } 351 352 *ReturnInteger = ReturnValue; 353 return (AE_OK); 354} 355 356 357/****************************************************************************** 358 * 359 * FUNCTION: DtGetFieldValue 360 * 361 * PARAMETERS: Field - Current field list pointer 362 * 363 * RETURN: Field value 364 * 365 * DESCRIPTION: Get field value 366 * 367 *****************************************************************************/ 368 369char * 370DtGetFieldValue ( 371 DT_FIELD *Field) 372{ 373 if (!Field) 374 { 375 return (NULL); 376 } 377 378 return (Field->Value); 379} 380 381 382/****************************************************************************** 383 * 384 * FUNCTION: DtGetFieldType 385 * 386 * PARAMETERS: Info - Data table info 387 * 388 * RETURN: Field type 389 * 390 * DESCRIPTION: Get field type 391 * 392 *****************************************************************************/ 393 394UINT8 395DtGetFieldType ( 396 ACPI_DMTABLE_INFO *Info) 397{ 398 UINT8 Type; 399 400 401 /* DT_FLAG means that this is the start of a block of flag bits */ 402 /* TBD - we can make these a separate opcode later */ 403 404 if (Info->Flags & DT_FLAG) 405 { 406 return (DT_FIELD_TYPE_FLAGS_INTEGER); 407 } 408 409 /* Type is based upon the opcode for this field in the info table */ 410 411 switch (Info->Opcode) 412 { 413 case ACPI_DMT_FLAG0: 414 case ACPI_DMT_FLAG1: 415 case ACPI_DMT_FLAG2: 416 case ACPI_DMT_FLAG3: 417 case ACPI_DMT_FLAG4: 418 case ACPI_DMT_FLAG5: 419 case ACPI_DMT_FLAG6: 420 case ACPI_DMT_FLAG7: 421 case ACPI_DMT_FLAGS0: 422 case ACPI_DMT_FLAGS1: 423 case ACPI_DMT_FLAGS2: 424 case ACPI_DMT_FLAGS4: 425 426 Type = DT_FIELD_TYPE_FLAG; 427 break; 428 429 case ACPI_DMT_NAME4: 430 case ACPI_DMT_SIG: 431 case ACPI_DMT_NAME6: 432 case ACPI_DMT_NAME8: 433 case ACPI_DMT_STRING: 434 435 Type = DT_FIELD_TYPE_STRING; 436 break; 437 438 case ACPI_DMT_BUFFER: 439 case ACPI_DMT_RAW_BUFFER: 440 case ACPI_DMT_BUF7: 441 case ACPI_DMT_BUF10: 442 case ACPI_DMT_BUF12: 443 case ACPI_DMT_BUF16: 444 case ACPI_DMT_BUF128: 445 case ACPI_DMT_PCI_PATH: 446 447 Type = DT_FIELD_TYPE_BUFFER; 448 break; 449 450 case ACPI_DMT_GAS: 451 case ACPI_DMT_HESTNTFY: 452 case ACPI_DMT_IORTMEM: 453 454 Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 455 break; 456 457 case ACPI_DMT_UNICODE: 458 459 Type = DT_FIELD_TYPE_UNICODE; 460 break; 461 462 case ACPI_DMT_UUID: 463 464 Type = DT_FIELD_TYPE_UUID; 465 break; 466 467 case ACPI_DMT_DEVICE_PATH: 468 469 Type = DT_FIELD_TYPE_DEVICE_PATH; 470 break; 471 472 case ACPI_DMT_LABEL: 473 474 Type = DT_FIELD_TYPE_LABEL; 475 break; 476 477 default: 478 479 Type = DT_FIELD_TYPE_INTEGER; 480 break; 481 } 482 483 return (Type); 484} 485 486 487/****************************************************************************** 488 * 489 * FUNCTION: DtGetBufferLength 490 * 491 * PARAMETERS: Buffer - List of integers, 492 * for example "10 3A 4F 2E" 493 * 494 * RETURN: Count of integer 495 * 496 * DESCRIPTION: Get length of bytes needed to store the integers 497 * 498 *****************************************************************************/ 499 500UINT32 501DtGetBufferLength ( 502 char *Buffer) 503{ 504 UINT32 ByteLength = 0; 505 506 507 while (*Buffer) 508 { 509 if (*Buffer == ' ') 510 { 511 ByteLength++; 512 513 while (*Buffer == ' ') 514 { 515 Buffer++; 516 } 517 } 518 519 Buffer++; 520 } 521 522 return (++ByteLength); 523} 524 525 526/****************************************************************************** 527 * 528 * FUNCTION: DtGetFieldLength 529 * 530 * PARAMETERS: Field - Current field 531 * Info - Data table info 532 * 533 * RETURN: Field length 534 * 535 * DESCRIPTION: Get length of bytes needed to compile the field 536 * 537 * Note: This function must remain in sync with AcpiDmDumpTable. 538 * 539 *****************************************************************************/ 540 541UINT32 542DtGetFieldLength ( 543 DT_FIELD *Field, 544 ACPI_DMTABLE_INFO *Info) 545{ 546 UINT32 ByteLength = 0; 547 char *Value; 548 549 550 /* Length is based upon the opcode for this field in the info table */ 551 552 switch (Info->Opcode) 553 { 554 case ACPI_DMT_FLAG0: 555 case ACPI_DMT_FLAG1: 556 case ACPI_DMT_FLAG2: 557 case ACPI_DMT_FLAG3: 558 case ACPI_DMT_FLAG4: 559 case ACPI_DMT_FLAG5: 560 case ACPI_DMT_FLAG6: 561 case ACPI_DMT_FLAG7: 562 case ACPI_DMT_FLAGS0: 563 case ACPI_DMT_FLAGS1: 564 case ACPI_DMT_FLAGS2: 565 case ACPI_DMT_FLAGS4: 566 case ACPI_DMT_LABEL: 567 case ACPI_DMT_EXTRA_TEXT: 568 569 ByteLength = 0; 570 break; 571 572 case ACPI_DMT_UINT8: 573 case ACPI_DMT_CHKSUM: 574 case ACPI_DMT_SPACEID: 575 case ACPI_DMT_ACCWIDTH: 576 case ACPI_DMT_IVRS: 577 case ACPI_DMT_GTDT: 578 case ACPI_DMT_MADT: 579 case ACPI_DMT_PCCT: 580 case ACPI_DMT_PMTT: 581 case ACPI_DMT_SRAT: 582 case ACPI_DMT_ASF: 583 case ACPI_DMT_HESTNTYP: 584 case ACPI_DMT_FADTPM: 585 case ACPI_DMT_EINJACT: 586 case ACPI_DMT_EINJINST: 587 case ACPI_DMT_ERSTACT: 588 case ACPI_DMT_ERSTINST: 589 case ACPI_DMT_DMAR_SCOPE: 590 591 ByteLength = 1; 592 break; 593 594 case ACPI_DMT_UINT16: 595 case ACPI_DMT_DMAR: 596 case ACPI_DMT_HEST: 597 case ACPI_DMT_NFIT: 598 case ACPI_DMT_PCI_PATH: 599 600 ByteLength = 2; 601 break; 602 603 case ACPI_DMT_UINT24: 604 605 ByteLength = 3; 606 break; 607 608 case ACPI_DMT_UINT32: 609 case ACPI_DMT_NAME4: 610 case ACPI_DMT_SIG: 611 case ACPI_DMT_LPIT: 612 613 ByteLength = 4; 614 break; 615 616 case ACPI_DMT_UINT40: 617 618 ByteLength = 5; 619 break; 620 621 case ACPI_DMT_UINT48: 622 case ACPI_DMT_NAME6: 623 624 ByteLength = 6; 625 break; 626 627 case ACPI_DMT_UINT56: 628 case ACPI_DMT_BUF7: 629 630 ByteLength = 7; 631 break; 632 633 case ACPI_DMT_UINT64: 634 case ACPI_DMT_NAME8: 635 636 ByteLength = 8; 637 break; 638 639 case ACPI_DMT_STRING: 640 641 Value = DtGetFieldValue (Field); 642 if (Value) 643 { 644 ByteLength = strlen (Value) + 1; 645 } 646 else 647 { /* At this point, this is a fatal error */ 648 649 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 650 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 651 return (0); 652 } 653 break; 654 655 case ACPI_DMT_GAS: 656 657 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 658 break; 659 660 case ACPI_DMT_HESTNTFY: 661 662 ByteLength = sizeof (ACPI_HEST_NOTIFY); 663 break; 664 665 case ACPI_DMT_IORTMEM: 666 667 ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS); 668 break; 669 670 case ACPI_DMT_BUFFER: 671 case ACPI_DMT_RAW_BUFFER: 672 673 Value = DtGetFieldValue (Field); 674 if (Value) 675 { 676 ByteLength = DtGetBufferLength (Value); 677 } 678 else 679 { /* At this point, this is a fatal error */ 680 681 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 682 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 683 return (0); 684 } 685 break; 686 687 case ACPI_DMT_BUF10: 688 689 ByteLength = 10; 690 break; 691 692 case ACPI_DMT_BUF12: 693 694 ByteLength = 12; 695 break; 696 697 case ACPI_DMT_BUF16: 698 case ACPI_DMT_UUID: 699 700 ByteLength = 16; 701 break; 702 703 case ACPI_DMT_BUF128: 704 705 ByteLength = 128; 706 break; 707 708 case ACPI_DMT_UNICODE: 709 710 Value = DtGetFieldValue (Field); 711 712 /* TBD: error if Value is NULL? (as below?) */ 713 714 ByteLength = (strlen (Value) + 1) * sizeof(UINT16); 715 break; 716 717 default: 718 719 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 720 return (0); 721 } 722 723 return (ByteLength); 724} 725 726 727/****************************************************************************** 728 * 729 * FUNCTION: DtSum 730 * 731 * PARAMETERS: DT_WALK_CALLBACK: 732 * Subtable - Subtable 733 * Context - Unused 734 * ReturnValue - Store the checksum of subtable 735 * 736 * RETURN: Status 737 * 738 * DESCRIPTION: Get the checksum of subtable 739 * 740 *****************************************************************************/ 741 742static void 743DtSum ( 744 DT_SUBTABLE *Subtable, 745 void *Context, 746 void *ReturnValue) 747{ 748 UINT8 Checksum; 749 UINT8 *Sum = ReturnValue; 750 751 752 Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 753 *Sum = (UINT8) (*Sum + Checksum); 754} 755 756 757/****************************************************************************** 758 * 759 * FUNCTION: DtSetTableChecksum 760 * 761 * PARAMETERS: ChecksumPointer - Where to return the checksum 762 * 763 * RETURN: None 764 * 765 * DESCRIPTION: Set checksum of the whole data table into the checksum field 766 * 767 *****************************************************************************/ 768 769void 770DtSetTableChecksum ( 771 UINT8 *ChecksumPointer) 772{ 773 UINT8 Checksum = 0; 774 UINT8 OldSum; 775 776 777 DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 778 779 OldSum = *ChecksumPointer; 780 Checksum = (UINT8) (Checksum - OldSum); 781 782 /* Compute the final checksum */ 783 784 Checksum = (UINT8) (0 - Checksum); 785 *ChecksumPointer = Checksum; 786} 787 788 789/****************************************************************************** 790 * 791 * FUNCTION: DtSetTableLength 792 * 793 * PARAMETERS: None 794 * 795 * RETURN: None 796 * 797 * DESCRIPTION: Walk the subtables and set all the length fields 798 * 799 *****************************************************************************/ 800 801void 802DtSetTableLength ( 803 void) 804{ 805 DT_SUBTABLE *ParentTable; 806 DT_SUBTABLE *ChildTable; 807 808 809 ParentTable = Gbl_RootTable; 810 ChildTable = NULL; 811 812 if (!ParentTable) 813 { 814 return; 815 } 816 817 DtSetSubtableLength (ParentTable); 818 819 while (1) 820 { 821 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 822 if (ChildTable) 823 { 824 if (ChildTable->LengthField) 825 { 826 DtSetSubtableLength (ChildTable); 827 } 828 829 if (ChildTable->Child) 830 { 831 ParentTable = ChildTable; 832 ChildTable = NULL; 833 } 834 else 835 { 836 ParentTable->TotalLength += ChildTable->TotalLength; 837 if (ParentTable->LengthField) 838 { 839 DtSetSubtableLength (ParentTable); 840 } 841 } 842 } 843 else 844 { 845 ChildTable = ParentTable; 846 847 if (ChildTable == Gbl_RootTable) 848 { 849 break; 850 } 851 852 ParentTable = DtGetParentSubtable (ParentTable); 853 854 ParentTable->TotalLength += ChildTable->TotalLength; 855 if (ParentTable->LengthField) 856 { 857 DtSetSubtableLength (ParentTable); 858 } 859 } 860 } 861} 862 863 864/****************************************************************************** 865 * 866 * FUNCTION: DtWalkTableTree 867 * 868 * PARAMETERS: StartTable - Subtable in the tree where walking begins 869 * UserFunction - Called during the walk 870 * Context - Passed to user function 871 * ReturnValue - The return value of UserFunction 872 * 873 * RETURN: None 874 * 875 * DESCRIPTION: Performs a depth-first walk of the subtable tree 876 * 877 *****************************************************************************/ 878 879void 880DtWalkTableTree ( 881 DT_SUBTABLE *StartTable, 882 DT_WALK_CALLBACK UserFunction, 883 void *Context, 884 void *ReturnValue) 885{ 886 DT_SUBTABLE *ParentTable; 887 DT_SUBTABLE *ChildTable; 888 889 890 ParentTable = StartTable; 891 ChildTable = NULL; 892 893 if (!ParentTable) 894 { 895 return; 896 } 897 898 UserFunction (ParentTable, Context, ReturnValue); 899 900 while (1) 901 { 902 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 903 if (ChildTable) 904 { 905 UserFunction (ChildTable, Context, ReturnValue); 906 907 if (ChildTable->Child) 908 { 909 ParentTable = ChildTable; 910 ChildTable = NULL; 911 } 912 } 913 else 914 { 915 ChildTable = ParentTable; 916 if (ChildTable == Gbl_RootTable) 917 { 918 break; 919 } 920 921 ParentTable = DtGetParentSubtable (ParentTable); 922 923 if (ChildTable->Peer == StartTable) 924 { 925 break; 926 } 927 } 928 } 929} 930 931 932/******************************************************************************* 933 * 934 * FUNCTION: UtSubtableCacheCalloc 935 * 936 * PARAMETERS: None 937 * 938 * RETURN: Pointer to the buffer. Aborts on allocation failure 939 * 940 * DESCRIPTION: Allocate a subtable object buffer. Bypass the local 941 * dynamic memory manager for performance reasons (This has a 942 * major impact on the speed of the compiler.) 943 * 944 ******************************************************************************/ 945 946DT_SUBTABLE * 947UtSubtableCacheCalloc ( 948 void) 949{ 950 ASL_CACHE_INFO *Cache; 951 952 953 if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast) 954 { 955 /* Allocate a new buffer */ 956 957 Cache = UtLocalCalloc (sizeof (Cache->Next) + 958 (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); 959 960 /* Link new cache buffer to head of list */ 961 962 Cache->Next = Gbl_SubtableCacheList; 963 Gbl_SubtableCacheList = Cache; 964 965 /* Setup cache management pointers */ 966 967 Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); 968 Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; 969 } 970 971 Gbl_SubtableCount++; 972 return (Gbl_SubtableCacheNext++); 973} 974 975 976/******************************************************************************* 977 * 978 * FUNCTION: UtFieldCacheCalloc 979 * 980 * PARAMETERS: None 981 * 982 * RETURN: Pointer to the buffer. Aborts on allocation failure 983 * 984 * DESCRIPTION: Allocate a field object buffer. Bypass the local 985 * dynamic memory manager for performance reasons (This has a 986 * major impact on the speed of the compiler.) 987 * 988 ******************************************************************************/ 989 990DT_FIELD * 991UtFieldCacheCalloc ( 992 void) 993{ 994 ASL_CACHE_INFO *Cache; 995 996 997 if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast) 998 { 999 /* Allocate a new buffer */ 1000 1001 Cache = UtLocalCalloc (sizeof (Cache->Next) + 1002 (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); 1003 1004 /* Link new cache buffer to head of list */ 1005 1006 Cache->Next = Gbl_FieldCacheList; 1007 Gbl_FieldCacheList = Cache; 1008 1009 /* Setup cache management pointers */ 1010 1011 Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); 1012 Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; 1013 } 1014 1015 Gbl_FieldCount++; 1016 return (Gbl_FieldCacheNext++); 1017} 1018 1019 1020/******************************************************************************* 1021 * 1022 * FUNCTION: DtDeleteCaches 1023 * 1024 * PARAMETERS: None 1025 * 1026 * RETURN: None 1027 * 1028 * DESCRIPTION: Delete all local cache buffer blocks 1029 * 1030 ******************************************************************************/ 1031 1032void 1033DtDeleteCaches ( 1034 void) 1035{ 1036 UINT32 BufferCount; 1037 ASL_CACHE_INFO *Next; 1038 1039 1040 /* Field cache */ 1041 1042 BufferCount = 0; 1043 while (Gbl_FieldCacheList) 1044 { 1045 Next = Gbl_FieldCacheList->Next; 1046 ACPI_FREE (Gbl_FieldCacheList); 1047 Gbl_FieldCacheList = Next; 1048 BufferCount++; 1049 } 1050 1051 DbgPrint (ASL_DEBUG_OUTPUT, 1052 "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", 1053 Gbl_FieldCount, ASL_FIELD_CACHE_SIZE, 1054 (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); 1055 1056 Gbl_FieldCount = 0; 1057 Gbl_FieldCacheNext = NULL; 1058 Gbl_FieldCacheLast = NULL; 1059 1060 /* Subtable cache */ 1061 1062 BufferCount = 0; 1063 while (Gbl_SubtableCacheList) 1064 { 1065 Next = Gbl_SubtableCacheList->Next; 1066 ACPI_FREE (Gbl_SubtableCacheList); 1067 Gbl_SubtableCacheList = Next; 1068 BufferCount++; 1069 } 1070 1071 DbgPrint (ASL_DEBUG_OUTPUT, 1072 "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", 1073 Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, 1074 (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); 1075 1076 Gbl_SubtableCount = 0; 1077 Gbl_SubtableCacheNext = NULL; 1078 Gbl_SubtableCacheLast = NULL; 1079} 1080