dtutils.c revision 1.6.2.1 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 "aslcompiler.h"
45 #include "dtcompiler.h"
46 #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 snprintf (MsgBuffer, sizeof(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 snprintf (MsgBuffer, sizeof(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