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