1 /****************************************************************************** 2 * 3 * Module Name: dtutils.c - Utility routines for the data table compiler 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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: DtGetFieldValue 201 * 202 * PARAMETERS: Field - Current field list pointer 203 * 204 * RETURN: Field value 205 * 206 * DESCRIPTION: Get field value 207 * 208 *****************************************************************************/ 209 210 char * 211 DtGetFieldValue ( 212 DT_FIELD *Field) 213 { 214 if (!Field) 215 { 216 return (NULL); 217 } 218 219 return (Field->Value); 220 } 221 222 223 /****************************************************************************** 224 * 225 * FUNCTION: DtGetFieldType 226 * 227 * PARAMETERS: Info - Data table info 228 * 229 * RETURN: Field type 230 * 231 * DESCRIPTION: Get field type 232 * 233 *****************************************************************************/ 234 235 UINT8 236 DtGetFieldType ( 237 ACPI_DMTABLE_INFO *Info) 238 { 239 UINT8 Type; 240 241 242 /* DT_FLAG means that this is the start of a block of flag bits */ 243 /* TBD - we can make these a separate opcode later */ 244 245 if (Info->Flags & DT_FLAG) 246 { 247 return (DT_FIELD_TYPE_FLAGS_INTEGER); 248 } 249 250 /* Type is based upon the opcode for this field in the info table */ 251 252 switch (Info->Opcode) 253 { 254 case ACPI_DMT_FLAG0: 255 case ACPI_DMT_FLAG1: 256 case ACPI_DMT_FLAG2: 257 case ACPI_DMT_FLAG3: 258 case ACPI_DMT_FLAG4: 259 case ACPI_DMT_FLAG5: 260 case ACPI_DMT_FLAG6: 261 case ACPI_DMT_FLAG7: 262 case ACPI_DMT_FLAGS0: 263 case ACPI_DMT_FLAGS1: 264 case ACPI_DMT_FLAGS2: 265 case ACPI_DMT_FLAGS4: 266 267 Type = DT_FIELD_TYPE_FLAG; 268 break; 269 270 case ACPI_DMT_NAME4: 271 case ACPI_DMT_SIG: 272 case ACPI_DMT_NAME6: 273 case ACPI_DMT_NAME8: 274 case ACPI_DMT_STRING: 275 276 Type = DT_FIELD_TYPE_STRING; 277 break; 278 279 case ACPI_DMT_BUFFER: 280 case ACPI_DMT_RAW_BUFFER: 281 case ACPI_DMT_BUF7: 282 case ACPI_DMT_BUF10: 283 case ACPI_DMT_BUF12: 284 case ACPI_DMT_BUF16: 285 case ACPI_DMT_BUF128: 286 case ACPI_DMT_PCI_PATH: 287 288 Type = DT_FIELD_TYPE_BUFFER; 289 break; 290 291 case ACPI_DMT_GAS: 292 case ACPI_DMT_HESTNTFY: 293 case ACPI_DMT_IORTMEM: 294 295 Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 296 break; 297 298 case ACPI_DMT_UNICODE: 299 300 Type = DT_FIELD_TYPE_UNICODE; 301 break; 302 303 case ACPI_DMT_UUID: 304 305 Type = DT_FIELD_TYPE_UUID; 306 break; 307 308 case ACPI_DMT_DEVICE_PATH: 309 310 Type = DT_FIELD_TYPE_DEVICE_PATH; 311 break; 312 313 case ACPI_DMT_LABEL: 314 315 Type = DT_FIELD_TYPE_LABEL; 316 break; 317 318 default: 319 320 Type = DT_FIELD_TYPE_INTEGER; 321 break; 322 } 323 324 return (Type); 325 } 326 327 328 /****************************************************************************** 329 * 330 * FUNCTION: DtGetBufferLength 331 * 332 * PARAMETERS: Buffer - List of integers, 333 * for example "10 3A 4F 2E" 334 * 335 * RETURN: Count of integer 336 * 337 * DESCRIPTION: Get length of bytes needed to store the integers 338 * 339 *****************************************************************************/ 340 341 UINT32 342 DtGetBufferLength ( 343 char *Buffer) 344 { 345 UINT32 ByteLength = 0; 346 347 348 while (*Buffer) 349 { 350 if (*Buffer == ' ') 351 { 352 ByteLength++; 353 354 while (*Buffer == ' ') 355 { 356 Buffer++; 357 } 358 } 359 360 Buffer++; 361 } 362 363 return (++ByteLength); 364 } 365 366 367 /****************************************************************************** 368 * 369 * FUNCTION: DtGetFieldLength 370 * 371 * PARAMETERS: Field - Current field 372 * Info - Data table info 373 * 374 * RETURN: Field length 375 * 376 * DESCRIPTION: Get length of bytes needed to compile the field 377 * 378 * Note: This function must remain in sync with AcpiDmDumpTable. 379 * 380 *****************************************************************************/ 381 382 UINT32 383 DtGetFieldLength ( 384 DT_FIELD *Field, 385 ACPI_DMTABLE_INFO *Info) 386 { 387 UINT32 ByteLength = 0; 388 char *Value; 389 390 391 /* Length is based upon the opcode for this field in the info table */ 392 393 switch (Info->Opcode) 394 { 395 case ACPI_DMT_FLAG0: 396 case ACPI_DMT_FLAG1: 397 case ACPI_DMT_FLAG2: 398 case ACPI_DMT_FLAG3: 399 case ACPI_DMT_FLAG4: 400 case ACPI_DMT_FLAG5: 401 case ACPI_DMT_FLAG6: 402 case ACPI_DMT_FLAG7: 403 case ACPI_DMT_FLAGS0: 404 case ACPI_DMT_FLAGS1: 405 case ACPI_DMT_FLAGS2: 406 case ACPI_DMT_FLAGS4: 407 case ACPI_DMT_LABEL: 408 case ACPI_DMT_EXTRA_TEXT: 409 410 ByteLength = 0; 411 break; 412 413 case ACPI_DMT_UINT8: 414 case ACPI_DMT_CHKSUM: 415 case ACPI_DMT_SPACEID: 416 case ACPI_DMT_ACCWIDTH: 417 case ACPI_DMT_IVRS: 418 case ACPI_DMT_GTDT: 419 case ACPI_DMT_MADT: 420 case ACPI_DMT_PCCT: 421 case ACPI_DMT_PMTT: 422 case ACPI_DMT_SRAT: 423 case ACPI_DMT_ASF: 424 case ACPI_DMT_HESTNTYP: 425 case ACPI_DMT_FADTPM: 426 case ACPI_DMT_EINJACT: 427 case ACPI_DMT_EINJINST: 428 case ACPI_DMT_ERSTACT: 429 case ACPI_DMT_ERSTINST: 430 case ACPI_DMT_DMAR_SCOPE: 431 432 ByteLength = 1; 433 break; 434 435 case ACPI_DMT_UINT16: 436 case ACPI_DMT_DMAR: 437 case ACPI_DMT_HEST: 438 case ACPI_DMT_NFIT: 439 case ACPI_DMT_PCI_PATH: 440 441 ByteLength = 2; 442 break; 443 444 case ACPI_DMT_UINT24: 445 446 ByteLength = 3; 447 break; 448 449 case ACPI_DMT_UINT32: 450 case ACPI_DMT_NAME4: 451 case ACPI_DMT_SIG: 452 case ACPI_DMT_LPIT: 453 454 ByteLength = 4; 455 break; 456 457 case ACPI_DMT_UINT40: 458 459 ByteLength = 5; 460 break; 461 462 case ACPI_DMT_UINT48: 463 case ACPI_DMT_NAME6: 464 465 ByteLength = 6; 466 break; 467 468 case ACPI_DMT_UINT56: 469 case ACPI_DMT_BUF7: 470 471 ByteLength = 7; 472 break; 473 474 case ACPI_DMT_UINT64: 475 case ACPI_DMT_NAME8: 476 477 ByteLength = 8; 478 break; 479 480 case ACPI_DMT_STRING: 481 482 Value = DtGetFieldValue (Field); 483 if (Value) 484 { 485 ByteLength = strlen (Value) + 1; 486 } 487 else 488 { /* At this point, this is a fatal error */ 489 490 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 491 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 492 return (0); 493 } 494 break; 495 496 case ACPI_DMT_GAS: 497 498 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 499 break; 500 501 case ACPI_DMT_HESTNTFY: 502 503 ByteLength = sizeof (ACPI_HEST_NOTIFY); 504 break; 505 506 case ACPI_DMT_IORTMEM: 507 508 ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS); 509 break; 510 511 case ACPI_DMT_BUFFER: 512 case ACPI_DMT_RAW_BUFFER: 513 514 Value = DtGetFieldValue (Field); 515 if (Value) 516 { 517 ByteLength = DtGetBufferLength (Value); 518 } 519 else 520 { /* At this point, this is a fatal error */ 521 522 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 523 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 524 return (0); 525 } 526 break; 527 528 case ACPI_DMT_BUF10: 529 530 ByteLength = 10; 531 break; 532 533 case ACPI_DMT_BUF12: 534 535 ByteLength = 12; 536 break; 537 538 case ACPI_DMT_BUF16: 539 case ACPI_DMT_UUID: 540 541 ByteLength = 16; 542 break; 543 544 case ACPI_DMT_BUF128: 545 546 ByteLength = 128; 547 break; 548 549 case ACPI_DMT_UNICODE: 550 551 Value = DtGetFieldValue (Field); 552 553 /* TBD: error if Value is NULL? (as below?) */ 554 555 ByteLength = (strlen (Value) + 1) * sizeof(UINT16); 556 break; 557 558 default: 559 560 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 561 return (0); 562 } 563 564 return (ByteLength); 565 } 566 567 568 /****************************************************************************** 569 * 570 * FUNCTION: DtSum 571 * 572 * PARAMETERS: DT_WALK_CALLBACK: 573 * Subtable - Subtable 574 * Context - Unused 575 * ReturnValue - Store the checksum of subtable 576 * 577 * RETURN: Status 578 * 579 * DESCRIPTION: Get the checksum of subtable 580 * 581 *****************************************************************************/ 582 583 static void 584 DtSum ( 585 DT_SUBTABLE *Subtable, 586 void *Context, 587 void *ReturnValue) 588 { 589 UINT8 Checksum; 590 UINT8 *Sum = ReturnValue; 591 592 593 Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 594 *Sum = (UINT8) (*Sum + Checksum); 595 } 596 597 598 /****************************************************************************** 599 * 600 * FUNCTION: DtSetTableChecksum 601 * 602 * PARAMETERS: ChecksumPointer - Where to return the checksum 603 * 604 * RETURN: None 605 * 606 * DESCRIPTION: Set checksum of the whole data table into the checksum field 607 * 608 *****************************************************************************/ 609 610 void 611 DtSetTableChecksum ( 612 UINT8 *ChecksumPointer) 613 { 614 UINT8 Checksum = 0; 615 UINT8 OldSum; 616 617 618 DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 619 620 OldSum = *ChecksumPointer; 621 Checksum = (UINT8) (Checksum - OldSum); 622 623 /* Compute the final checksum */ 624 625 Checksum = (UINT8) (0 - Checksum); 626 *ChecksumPointer = Checksum; 627 } 628 629 630 /****************************************************************************** 631 * 632 * FUNCTION: DtSetTableLength 633 * 634 * PARAMETERS: None 635 * 636 * RETURN: None 637 * 638 * DESCRIPTION: Walk the subtables and set all the length fields 639 * 640 *****************************************************************************/ 641 642 void 643 DtSetTableLength ( 644 void) 645 { 646 DT_SUBTABLE *ParentTable; 647 DT_SUBTABLE *ChildTable; 648 649 650 ParentTable = Gbl_RootTable; 651 ChildTable = NULL; 652 653 if (!ParentTable) 654 { 655 return; 656 } 657 658 DtSetSubtableLength (ParentTable); 659 660 while (1) 661 { 662 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 663 if (ChildTable) 664 { 665 if (ChildTable->LengthField) 666 { 667 DtSetSubtableLength (ChildTable); 668 } 669 670 if (ChildTable->Child) 671 { 672 ParentTable = ChildTable; 673 ChildTable = NULL; 674 } 675 else 676 { 677 ParentTable->TotalLength += ChildTable->TotalLength; 678 if (ParentTable->LengthField) 679 { 680 DtSetSubtableLength (ParentTable); 681 } 682 } 683 } 684 else 685 { 686 ChildTable = ParentTable; 687 688 if (ChildTable == Gbl_RootTable) 689 { 690 break; 691 } 692 693 ParentTable = DtGetParentSubtable (ParentTable); 694 695 ParentTable->TotalLength += ChildTable->TotalLength; 696 if (ParentTable->LengthField) 697 { 698 DtSetSubtableLength (ParentTable); 699 } 700 } 701 } 702 } 703 704 705 /****************************************************************************** 706 * 707 * FUNCTION: DtWalkTableTree 708 * 709 * PARAMETERS: StartTable - Subtable in the tree where walking begins 710 * UserFunction - Called during the walk 711 * Context - Passed to user function 712 * ReturnValue - The return value of UserFunction 713 * 714 * RETURN: None 715 * 716 * DESCRIPTION: Performs a depth-first walk of the subtable tree 717 * 718 *****************************************************************************/ 719 720 void 721 DtWalkTableTree ( 722 DT_SUBTABLE *StartTable, 723 DT_WALK_CALLBACK UserFunction, 724 void *Context, 725 void *ReturnValue) 726 { 727 DT_SUBTABLE *ParentTable; 728 DT_SUBTABLE *ChildTable; 729 730 731 ParentTable = StartTable; 732 ChildTable = NULL; 733 734 if (!ParentTable) 735 { 736 return; 737 } 738 739 UserFunction (ParentTable, Context, ReturnValue); 740 741 while (1) 742 { 743 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 744 if (ChildTable) 745 { 746 UserFunction (ChildTable, Context, ReturnValue); 747 748 if (ChildTable->Child) 749 { 750 ParentTable = ChildTable; 751 ChildTable = NULL; 752 } 753 } 754 else 755 { 756 ChildTable = ParentTable; 757 if (ChildTable == Gbl_RootTable) 758 { 759 break; 760 } 761 762 ParentTable = DtGetParentSubtable (ParentTable); 763 764 if (ChildTable->Peer == StartTable) 765 { 766 break; 767 } 768 } 769 } 770 } 771 772 773 /******************************************************************************* 774 * 775 * FUNCTION: UtSubtableCacheCalloc 776 * 777 * PARAMETERS: None 778 * 779 * RETURN: Pointer to the buffer. Aborts on allocation failure 780 * 781 * DESCRIPTION: Allocate a subtable object buffer. Bypass the local 782 * dynamic memory manager for performance reasons (This has a 783 * major impact on the speed of the compiler.) 784 * 785 ******************************************************************************/ 786 787 DT_SUBTABLE * 788 UtSubtableCacheCalloc ( 789 void) 790 { 791 ASL_CACHE_INFO *Cache; 792 793 794 if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast) 795 { 796 /* Allocate a new buffer */ 797 798 Cache = UtLocalCalloc (sizeof (Cache->Next) + 799 (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); 800 801 /* Link new cache buffer to head of list */ 802 803 Cache->Next = Gbl_SubtableCacheList; 804 Gbl_SubtableCacheList = Cache; 805 806 /* Setup cache management pointers */ 807 808 Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); 809 Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; 810 } 811 812 Gbl_SubtableCount++; 813 return (Gbl_SubtableCacheNext++); 814 } 815 816 817 /******************************************************************************* 818 * 819 * FUNCTION: UtFieldCacheCalloc 820 * 821 * PARAMETERS: None 822 * 823 * RETURN: Pointer to the buffer. Aborts on allocation failure 824 * 825 * DESCRIPTION: Allocate a field object buffer. Bypass the local 826 * dynamic memory manager for performance reasons (This has a 827 * major impact on the speed of the compiler.) 828 * 829 ******************************************************************************/ 830 831 DT_FIELD * 832 UtFieldCacheCalloc ( 833 void) 834 { 835 ASL_CACHE_INFO *Cache; 836 837 838 if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast) 839 { 840 /* Allocate a new buffer */ 841 842 Cache = UtLocalCalloc (sizeof (Cache->Next) + 843 (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); 844 845 /* Link new cache buffer to head of list */ 846 847 Cache->Next = Gbl_FieldCacheList; 848 Gbl_FieldCacheList = Cache; 849 850 /* Setup cache management pointers */ 851 852 Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); 853 Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; 854 } 855 856 Gbl_FieldCount++; 857 return (Gbl_FieldCacheNext++); 858 } 859 860 861 /******************************************************************************* 862 * 863 * FUNCTION: DtDeleteCaches 864 * 865 * PARAMETERS: None 866 * 867 * RETURN: None 868 * 869 * DESCRIPTION: Delete all local cache buffer blocks 870 * 871 ******************************************************************************/ 872 873 void 874 DtDeleteCaches ( 875 void) 876 { 877 UINT32 BufferCount; 878 ASL_CACHE_INFO *Next; 879 880 881 /* Field cache */ 882 883 BufferCount = 0; 884 while (Gbl_FieldCacheList) 885 { 886 Next = Gbl_FieldCacheList->Next; 887 ACPI_FREE (Gbl_FieldCacheList); 888 Gbl_FieldCacheList = Next; 889 BufferCount++; 890 } 891 892 DbgPrint (ASL_DEBUG_OUTPUT, 893 "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", 894 Gbl_FieldCount, ASL_FIELD_CACHE_SIZE, 895 (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); 896 897 Gbl_FieldCount = 0; 898 Gbl_FieldCacheNext = NULL; 899 Gbl_FieldCacheLast = NULL; 900 901 /* Subtable cache */ 902 903 BufferCount = 0; 904 while (Gbl_SubtableCacheList) 905 { 906 Next = Gbl_SubtableCacheList->Next; 907 ACPI_FREE (Gbl_SubtableCacheList); 908 Gbl_SubtableCacheList = Next; 909 BufferCount++; 910 } 911 912 DbgPrint (ASL_DEBUG_OUTPUT, 913 "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", 914 Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, 915 (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); 916 917 Gbl_SubtableCount = 0; 918 Gbl_SubtableCacheNext = NULL; 919 Gbl_SubtableCacheLast = NULL; 920 } 921