1 /****************************************************************************** 2 * 3 * Module Name: dtutils.c - Utility routines for the data table compiler 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 (isdigit ((int) *ThisChar)) 245 { 246 /* Convert ASCII 0-9 to Decimal value */ 247 248 ThisDigit = ((UINT8) *ThisChar) - '0'; 249 } 250 else /* Letter */ 251 { 252 ThisDigit = (UINT32) toupper ((int) *ThisChar); 253 if (!isxdigit ((int) 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 case ACPI_DMT_IORTMEM: 380 381 Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 382 break; 383 384 case ACPI_DMT_UNICODE: 385 386 Type = DT_FIELD_TYPE_UNICODE; 387 break; 388 389 case ACPI_DMT_UUID: 390 391 Type = DT_FIELD_TYPE_UUID; 392 break; 393 394 case ACPI_DMT_DEVICE_PATH: 395 396 Type = DT_FIELD_TYPE_DEVICE_PATH; 397 break; 398 399 case ACPI_DMT_LABEL: 400 401 Type = DT_FIELD_TYPE_LABEL; 402 break; 403 404 default: 405 406 Type = DT_FIELD_TYPE_INTEGER; 407 break; 408 } 409 410 return (Type); 411 } 412 413 414 /****************************************************************************** 415 * 416 * FUNCTION: DtGetBufferLength 417 * 418 * PARAMETERS: Buffer - List of integers, 419 * for example "10 3A 4F 2E" 420 * 421 * RETURN: Count of integer 422 * 423 * DESCRIPTION: Get length of bytes needed to store the integers 424 * 425 *****************************************************************************/ 426 427 UINT32 428 DtGetBufferLength ( 429 char *Buffer) 430 { 431 UINT32 ByteLength = 0; 432 433 434 while (*Buffer) 435 { 436 if (*Buffer == ' ') 437 { 438 ByteLength++; 439 440 while (*Buffer == ' ') 441 { 442 Buffer++; 443 } 444 } 445 446 Buffer++; 447 } 448 449 return (++ByteLength); 450 } 451 452 453 /****************************************************************************** 454 * 455 * FUNCTION: DtGetFieldLength 456 * 457 * PARAMETERS: Field - Current field 458 * Info - Data table info 459 * 460 * RETURN: Field length 461 * 462 * DESCRIPTION: Get length of bytes needed to compile the field 463 * 464 * Note: This function must remain in sync with AcpiDmDumpTable. 465 * 466 *****************************************************************************/ 467 468 UINT32 469 DtGetFieldLength ( 470 DT_FIELD *Field, 471 ACPI_DMTABLE_INFO *Info) 472 { 473 UINT32 ByteLength = 0; 474 char *Value; 475 476 477 /* Length is based upon the opcode for this field in the info table */ 478 479 switch (Info->Opcode) 480 { 481 case ACPI_DMT_FLAG0: 482 case ACPI_DMT_FLAG1: 483 case ACPI_DMT_FLAG2: 484 case ACPI_DMT_FLAG3: 485 case ACPI_DMT_FLAG4: 486 case ACPI_DMT_FLAG5: 487 case ACPI_DMT_FLAG6: 488 case ACPI_DMT_FLAG7: 489 case ACPI_DMT_FLAGS0: 490 case ACPI_DMT_FLAGS1: 491 case ACPI_DMT_FLAGS2: 492 case ACPI_DMT_FLAGS4: 493 case ACPI_DMT_LABEL: 494 case ACPI_DMT_EXTRA_TEXT: 495 496 ByteLength = 0; 497 break; 498 499 case ACPI_DMT_UINT8: 500 case ACPI_DMT_CHKSUM: 501 case ACPI_DMT_SPACEID: 502 case ACPI_DMT_ACCWIDTH: 503 case ACPI_DMT_IVRS: 504 case ACPI_DMT_GTDT: 505 case ACPI_DMT_MADT: 506 case ACPI_DMT_PCCT: 507 case ACPI_DMT_PMTT: 508 case ACPI_DMT_SRAT: 509 case ACPI_DMT_ASF: 510 case ACPI_DMT_HESTNTYP: 511 case ACPI_DMT_FADTPM: 512 case ACPI_DMT_EINJACT: 513 case ACPI_DMT_EINJINST: 514 case ACPI_DMT_ERSTACT: 515 case ACPI_DMT_ERSTINST: 516 case ACPI_DMT_DMAR_SCOPE: 517 518 ByteLength = 1; 519 break; 520 521 case ACPI_DMT_UINT16: 522 case ACPI_DMT_DMAR: 523 case ACPI_DMT_HEST: 524 case ACPI_DMT_NFIT: 525 case ACPI_DMT_PCI_PATH: 526 527 ByteLength = 2; 528 break; 529 530 case ACPI_DMT_UINT24: 531 532 ByteLength = 3; 533 break; 534 535 case ACPI_DMT_UINT32: 536 case ACPI_DMT_NAME4: 537 case ACPI_DMT_SIG: 538 case ACPI_DMT_LPIT: 539 540 ByteLength = 4; 541 break; 542 543 case ACPI_DMT_UINT40: 544 545 ByteLength = 5; 546 break; 547 548 case ACPI_DMT_UINT48: 549 case ACPI_DMT_NAME6: 550 551 ByteLength = 6; 552 break; 553 554 case ACPI_DMT_UINT56: 555 case ACPI_DMT_BUF7: 556 557 ByteLength = 7; 558 break; 559 560 case ACPI_DMT_UINT64: 561 case ACPI_DMT_NAME8: 562 563 ByteLength = 8; 564 break; 565 566 case ACPI_DMT_STRING: 567 568 Value = DtGetFieldValue (Field); 569 if (Value) 570 { 571 ByteLength = strlen (Value) + 1; 572 } 573 else 574 { /* At this point, this is a fatal error */ 575 576 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 577 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 578 return (0); 579 } 580 break; 581 582 case ACPI_DMT_GAS: 583 584 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 585 break; 586 587 case ACPI_DMT_HESTNTFY: 588 589 ByteLength = sizeof (ACPI_HEST_NOTIFY); 590 break; 591 592 case ACPI_DMT_IORTMEM: 593 594 ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS); 595 break; 596 597 case ACPI_DMT_BUFFER: 598 case ACPI_DMT_RAW_BUFFER: 599 600 Value = DtGetFieldValue (Field); 601 if (Value) 602 { 603 ByteLength = DtGetBufferLength (Value); 604 } 605 else 606 { /* At this point, this is a fatal error */ 607 608 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 609 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 610 return (0); 611 } 612 break; 613 614 case ACPI_DMT_BUF10: 615 616 ByteLength = 10; 617 break; 618 619 case ACPI_DMT_BUF16: 620 case ACPI_DMT_UUID: 621 622 ByteLength = 16; 623 break; 624 625 case ACPI_DMT_BUF128: 626 627 ByteLength = 128; 628 break; 629 630 case ACPI_DMT_UNICODE: 631 632 Value = DtGetFieldValue (Field); 633 634 /* TBD: error if Value is NULL? (as below?) */ 635 636 ByteLength = (strlen (Value) + 1) * sizeof(UINT16); 637 break; 638 639 default: 640 641 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 642 return (0); 643 } 644 645 return (ByteLength); 646 } 647 648 649 /****************************************************************************** 650 * 651 * FUNCTION: DtSum 652 * 653 * PARAMETERS: DT_WALK_CALLBACK: 654 * Subtable - Subtable 655 * Context - Unused 656 * ReturnValue - Store the checksum of subtable 657 * 658 * RETURN: Status 659 * 660 * DESCRIPTION: Get the checksum of subtable 661 * 662 *****************************************************************************/ 663 664 static void 665 DtSum ( 666 DT_SUBTABLE *Subtable, 667 void *Context, 668 void *ReturnValue) 669 { 670 UINT8 Checksum; 671 UINT8 *Sum = ReturnValue; 672 673 674 Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 675 *Sum = (UINT8) (*Sum + Checksum); 676 } 677 678 679 /****************************************************************************** 680 * 681 * FUNCTION: DtSetTableChecksum 682 * 683 * PARAMETERS: ChecksumPointer - Where to return the checksum 684 * 685 * RETURN: None 686 * 687 * DESCRIPTION: Set checksum of the whole data table into the checksum field 688 * 689 *****************************************************************************/ 690 691 void 692 DtSetTableChecksum ( 693 UINT8 *ChecksumPointer) 694 { 695 UINT8 Checksum = 0; 696 UINT8 OldSum; 697 698 699 DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 700 701 OldSum = *ChecksumPointer; 702 Checksum = (UINT8) (Checksum - OldSum); 703 704 /* Compute the final checksum */ 705 706 Checksum = (UINT8) (0 - Checksum); 707 *ChecksumPointer = Checksum; 708 } 709 710 711 /****************************************************************************** 712 * 713 * FUNCTION: DtSetTableLength 714 * 715 * PARAMETERS: None 716 * 717 * RETURN: None 718 * 719 * DESCRIPTION: Walk the subtables and set all the length fields 720 * 721 *****************************************************************************/ 722 723 void 724 DtSetTableLength ( 725 void) 726 { 727 DT_SUBTABLE *ParentTable; 728 DT_SUBTABLE *ChildTable; 729 730 731 ParentTable = Gbl_RootTable; 732 ChildTable = NULL; 733 734 if (!ParentTable) 735 { 736 return; 737 } 738 739 DtSetSubtableLength (ParentTable); 740 741 while (1) 742 { 743 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 744 if (ChildTable) 745 { 746 if (ChildTable->LengthField) 747 { 748 DtSetSubtableLength (ChildTable); 749 } 750 751 if (ChildTable->Child) 752 { 753 ParentTable = ChildTable; 754 ChildTable = NULL; 755 } 756 else 757 { 758 ParentTable->TotalLength += ChildTable->TotalLength; 759 if (ParentTable->LengthField) 760 { 761 DtSetSubtableLength (ParentTable); 762 } 763 } 764 } 765 else 766 { 767 ChildTable = ParentTable; 768 769 if (ChildTable == Gbl_RootTable) 770 { 771 break; 772 } 773 774 ParentTable = DtGetParentSubtable (ParentTable); 775 776 ParentTable->TotalLength += ChildTable->TotalLength; 777 if (ParentTable->LengthField) 778 { 779 DtSetSubtableLength (ParentTable); 780 } 781 } 782 } 783 } 784 785 786 /****************************************************************************** 787 * 788 * FUNCTION: DtWalkTableTree 789 * 790 * PARAMETERS: StartTable - Subtable in the tree where walking begins 791 * UserFunction - Called during the walk 792 * Context - Passed to user function 793 * ReturnValue - The return value of UserFunction 794 * 795 * RETURN: None 796 * 797 * DESCRIPTION: Performs a depth-first walk of the subtable tree 798 * 799 *****************************************************************************/ 800 801 void 802 DtWalkTableTree ( 803 DT_SUBTABLE *StartTable, 804 DT_WALK_CALLBACK UserFunction, 805 void *Context, 806 void *ReturnValue) 807 { 808 DT_SUBTABLE *ParentTable; 809 DT_SUBTABLE *ChildTable; 810 811 812 ParentTable = StartTable; 813 ChildTable = NULL; 814 815 if (!ParentTable) 816 { 817 return; 818 } 819 820 UserFunction (ParentTable, Context, ReturnValue); 821 822 while (1) 823 { 824 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 825 if (ChildTable) 826 { 827 UserFunction (ChildTable, Context, ReturnValue); 828 829 if (ChildTable->Child) 830 { 831 ParentTable = ChildTable; 832 ChildTable = NULL; 833 } 834 } 835 else 836 { 837 ChildTable = ParentTable; 838 if (ChildTable == Gbl_RootTable) 839 { 840 break; 841 } 842 843 ParentTable = DtGetParentSubtable (ParentTable); 844 845 if (ChildTable->Peer == StartTable) 846 { 847 break; 848 } 849 } 850 } 851 } 852 853 854 /******************************************************************************* 855 * 856 * FUNCTION: UtSubtableCacheCalloc 857 * 858 * PARAMETERS: None 859 * 860 * RETURN: Pointer to the buffer. Aborts on allocation failure 861 * 862 * DESCRIPTION: Allocate a subtable object buffer. Bypass the local 863 * dynamic memory manager for performance reasons (This has a 864 * major impact on the speed of the compiler.) 865 * 866 ******************************************************************************/ 867 868 DT_SUBTABLE * 869 UtSubtableCacheCalloc ( 870 void) 871 { 872 ASL_CACHE_INFO *Cache; 873 874 875 if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast) 876 { 877 /* Allocate a new buffer */ 878 879 Cache = UtLocalCalloc (sizeof (Cache->Next) + 880 (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); 881 882 /* Link new cache buffer to head of list */ 883 884 Cache->Next = Gbl_SubtableCacheList; 885 Gbl_SubtableCacheList = Cache; 886 887 /* Setup cache management pointers */ 888 889 Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); 890 Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; 891 } 892 893 Gbl_SubtableCount++; 894 return (Gbl_SubtableCacheNext++); 895 } 896 897 898 /******************************************************************************* 899 * 900 * FUNCTION: UtFieldCacheCalloc 901 * 902 * PARAMETERS: None 903 * 904 * RETURN: Pointer to the buffer. Aborts on allocation failure 905 * 906 * DESCRIPTION: Allocate a field object buffer. Bypass the local 907 * dynamic memory manager for performance reasons (This has a 908 * major impact on the speed of the compiler.) 909 * 910 ******************************************************************************/ 911 912 DT_FIELD * 913 UtFieldCacheCalloc ( 914 void) 915 { 916 ASL_CACHE_INFO *Cache; 917 918 919 if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast) 920 { 921 /* Allocate a new buffer */ 922 923 Cache = UtLocalCalloc (sizeof (Cache->Next) + 924 (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); 925 926 /* Link new cache buffer to head of list */ 927 928 Cache->Next = Gbl_FieldCacheList; 929 Gbl_FieldCacheList = Cache; 930 931 /* Setup cache management pointers */ 932 933 Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); 934 Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; 935 } 936 937 Gbl_FieldCount++; 938 return (Gbl_FieldCacheNext++); 939 } 940 941 942 /******************************************************************************* 943 * 944 * FUNCTION: DtDeleteCaches 945 * 946 * PARAMETERS: None 947 * 948 * RETURN: None 949 * 950 * DESCRIPTION: Delete all local cache buffer blocks 951 * 952 ******************************************************************************/ 953 954 void 955 DtDeleteCaches ( 956 void) 957 { 958 UINT32 BufferCount; 959 ASL_CACHE_INFO *Next; 960 961 962 /* Field cache */ 963 964 BufferCount = 0; 965 while (Gbl_FieldCacheList) 966 { 967 Next = Gbl_FieldCacheList->Next; 968 ACPI_FREE (Gbl_FieldCacheList); 969 Gbl_FieldCacheList = Next; 970 BufferCount++; 971 } 972 973 DbgPrint (ASL_DEBUG_OUTPUT, 974 "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", 975 Gbl_FieldCount, ASL_FIELD_CACHE_SIZE, 976 (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); 977 978 Gbl_FieldCount = 0; 979 Gbl_FieldCacheNext = NULL; 980 Gbl_FieldCacheLast = NULL; 981 982 /* Subtable cache */ 983 984 BufferCount = 0; 985 while (Gbl_SubtableCacheList) 986 { 987 Next = Gbl_SubtableCacheList->Next; 988 ACPI_FREE (Gbl_SubtableCacheList); 989 Gbl_SubtableCacheList = Next; 990 BufferCount++; 991 } 992 993 DbgPrint (ASL_DEBUG_OUTPUT, 994 "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", 995 Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, 996 (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); 997 998 Gbl_SubtableCount = 0; 999 Gbl_SubtableCacheNext = NULL; 1000 Gbl_SubtableCacheLast = NULL; 1001 } 1002