xref: /freebsd/sys/contrib/dev/acpica/compiler/dtutils.c (revision 5dae51da3da0cc94d17bd67b308fad304ebec7e0)
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:    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