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