]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - compiler/dtutils.c
Import ACPICA 20120111.
[FreeBSD/FreeBSD.git] / 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 - 2012, 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 #define __DTUTILS_C__
45
46 #include "aslcompiler.h"
47 #include "dtcompiler.h"
48 #include "actables.h"
49
50 #define _COMPONENT          DT_COMPILER
51         ACPI_MODULE_NAME    ("dtutils")
52
53 /* Local prototypes */
54
55 static void
56 DtSum (
57     DT_SUBTABLE             *Subtable,
58     void                    *Context,
59     void                    *ReturnValue);
60
61
62 /******************************************************************************
63  *
64  * FUNCTION:    DtError
65  *
66  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
67  *              MessageId           - Index into global message buffer
68  *              Op                  - Parse node where error happened
69  *              ExtraMessage        - additional error message
70  *
71  * RETURN:      None
72  *
73  * DESCRIPTION: Common error interface for data table compiler
74  *
75  *****************************************************************************/
76
77 void
78 DtError (
79     UINT8                   Level,
80     UINT8                   MessageId,
81     DT_FIELD                *FieldObject,
82     char                    *ExtraMessage)
83 {
84
85     switch (Level)
86     {
87     case ASL_WARNING2:
88     case ASL_WARNING3:
89         if (Gbl_WarningLevel < Level)
90         {
91             return;
92         }
93         break;
94
95     default:
96         break;
97     }
98
99     if (FieldObject)
100     {
101         AslCommonError (Level, MessageId,
102             FieldObject->Line,
103             FieldObject->Line,
104             FieldObject->ByteOffset,
105             FieldObject->Column,
106             Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
107     }
108     else
109     {
110         AslCommonError (Level, MessageId, 0,
111             0, 0, 0, 0, ExtraMessage);
112     }
113 }
114
115
116 /******************************************************************************
117  *
118  * FUNCTION:    DtNameError
119  *
120  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
121  *              MessageId           - Index into global message buffer
122  *              Op                  - Parse node where error happened
123  *              ExtraMessage        - additional error message
124  *
125  * RETURN:      None
126  *
127  * DESCRIPTION: Error interface for named objects
128  *
129  *****************************************************************************/
130
131 void
132 DtNameError (
133     UINT8                   Level,
134     UINT8                   MessageId,
135     DT_FIELD                *FieldObject,
136     char                    *ExtraMessage)
137 {
138
139     switch (Level)
140     {
141     case ASL_WARNING2:
142     case ASL_WARNING3:
143         if (Gbl_WarningLevel < Level)
144         {
145             return;
146         }
147         break;
148
149     default:
150         break;
151     }
152
153     if (FieldObject)
154     {
155         AslCommonError (Level, MessageId,
156             FieldObject->Line,
157             FieldObject->Line,
158             FieldObject->ByteOffset,
159             FieldObject->NameColumn,
160             Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
161     }
162     else
163     {
164         AslCommonError (Level, MessageId, 0,
165             0, 0, 0, 0, ExtraMessage);
166     }
167 }
168
169
170 /*******************************************************************************
171  *
172  * FUNCTION:    DtFatal
173  *
174  * PARAMETERS:  None
175  *
176  * RETURN:      None
177  *
178  * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
179  *              compile or I/O errors
180  *
181  ******************************************************************************/
182
183 void
184 DtFatal (
185     UINT8                   MessageId,
186     DT_FIELD                *FieldObject,
187     char                    *ExtraMessage)
188 {
189
190     DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
191
192 /*
193  * TBD: remove this entire function, DtFatal
194  *
195  * We cannot abort the compiler on error, because we may be compiling a
196  * list of files. We must move on to the next file.
197  */
198 #ifdef __OBSOLETE
199     CmCleanupAndExit ();
200     exit (1);
201 #endif
202 }
203
204
205 /******************************************************************************
206  *
207  * FUNCTION:    DtStrtoul64
208  *
209  * PARAMETERS:  String              - Null terminated string
210  *              ReturnInteger       - Where the converted integer is returned
211  *
212  * RETURN:      Status
213  *
214  * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
215  *              value. Assumes no leading "0x" for the constant.
216  *
217  * Portability note: The reason this function exists is because a 64-bit
218  * sscanf is not available in all environments.
219  *
220  *****************************************************************************/
221
222 ACPI_STATUS
223 DtStrtoul64 (
224     char                    *String,
225     UINT64                  *ReturnInteger)
226 {
227     char                    *ThisChar = String;
228     UINT32                  ThisDigit;
229     UINT64                  ReturnValue = 0;
230     int                     DigitCount = 0;
231
232
233     /* Skip over any white space in the buffer */
234
235     while ((*ThisChar == ' ') || (*ThisChar == '\t'))
236     {
237         ThisChar++;
238     }
239
240     /* Skip leading zeros */
241
242     while ((*ThisChar) == '0')
243     {
244         ThisChar++;
245     }
246
247     /* Convert character-by-character */
248
249     while (*ThisChar)
250     {
251         if (ACPI_IS_DIGIT (*ThisChar))
252         {
253             /* Convert ASCII 0-9 to Decimal value */
254
255             ThisDigit = ((UINT8) *ThisChar) - '0';
256         }
257         else /* Letter */
258         {
259             ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
260             if (!ACPI_IS_XDIGIT ((char) ThisDigit))
261             {
262                 /* Not A-F */
263
264                 return (AE_BAD_CHARACTER);
265             }
266
267             /* Convert ASCII Hex char (A-F) to value */
268
269             ThisDigit = (ThisDigit - 'A') + 10;
270         }
271
272         /* Insert the 4-bit hex digit */
273
274         ReturnValue <<= 4;
275         ReturnValue += ThisDigit;
276
277         ThisChar++;
278         DigitCount++;
279         if (DigitCount > 16)
280         {
281             /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
282
283             return (AE_LIMIT);
284         }
285     }
286
287     *ReturnInteger = ReturnValue;
288     return (AE_OK);
289 }
290
291
292 /******************************************************************************
293  *
294  * FUNCTION:    DtGetFileSize
295  *
296  * PARAMETERS:  Handle              - Open file handler
297  *
298  * RETURN:      Current file size
299  *
300  * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the
301  *              offset. Seek back to the original location.
302  *
303  *****************************************************************************/
304
305 UINT32
306 DtGetFileSize (
307     FILE                    *Handle)
308 {
309     int                     CurrentOffset;
310     int                     LastOffset;
311
312
313     CurrentOffset = ftell (Handle);
314     fseek (Handle, 0, SEEK_END);
315     LastOffset = ftell (Handle);
316     fseek (Handle, CurrentOffset, SEEK_SET);
317
318     return ((UINT32) LastOffset);
319 }
320
321
322 /******************************************************************************
323  *
324  * FUNCTION:    DtGetFieldValue
325  *
326  * PARAMETERS:  Field               - Current field list pointer
327  *
328  * RETURN:      Field value
329  *
330  * DESCRIPTION: Get field value
331  *
332  *****************************************************************************/
333
334 char *
335 DtGetFieldValue (
336     DT_FIELD                *Field)
337 {
338     if (!Field)
339     {
340         return (NULL);
341     }
342
343     return (Field->Value);
344 }
345
346
347 /******************************************************************************
348  *
349  * FUNCTION:    DtGetFieldType
350  *
351  * PARAMETERS:  Info                - Data table info
352  *
353  * RETURN:      Field type
354  *
355  * DESCRIPTION: Get field type
356  *
357  *****************************************************************************/
358
359 UINT8
360 DtGetFieldType (
361     ACPI_DMTABLE_INFO       *Info)
362 {
363     UINT8                   Type;
364
365
366     /* DT_FLAG means that this is the start of a block of flag bits */
367     /* TBD - we can make these a separate opcode later */
368
369     if (Info->Flags & DT_FLAG)
370     {
371         return (DT_FIELD_TYPE_FLAGS_INTEGER);
372     }
373
374     /* Type is based upon the opcode for this field in the info table */
375
376     switch (Info->Opcode)
377     {
378     case ACPI_DMT_FLAG0:
379     case ACPI_DMT_FLAG1:
380     case ACPI_DMT_FLAG2:
381     case ACPI_DMT_FLAG3:
382     case ACPI_DMT_FLAG4:
383     case ACPI_DMT_FLAG5:
384     case ACPI_DMT_FLAG6:
385     case ACPI_DMT_FLAG7:
386     case ACPI_DMT_FLAGS0:
387     case ACPI_DMT_FLAGS1:
388     case ACPI_DMT_FLAGS2:
389     case ACPI_DMT_FLAGS4:
390         Type = DT_FIELD_TYPE_FLAG;
391         break;
392
393     case ACPI_DMT_NAME4:
394     case ACPI_DMT_SIG:
395     case ACPI_DMT_NAME6:
396     case ACPI_DMT_NAME8:
397     case ACPI_DMT_STRING:
398         Type = DT_FIELD_TYPE_STRING;
399         break;
400
401     case ACPI_DMT_BUFFER:
402     case ACPI_DMT_BUF7:
403     case ACPI_DMT_BUF16:
404     case ACPI_DMT_BUF128:
405     case ACPI_DMT_PCI_PATH:
406         Type = DT_FIELD_TYPE_BUFFER;
407         break;
408
409     case ACPI_DMT_GAS:
410     case ACPI_DMT_HESTNTFY:
411         Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
412         break;
413
414     case ACPI_DMT_UNICODE:
415         Type = DT_FIELD_TYPE_UNICODE;
416         break;
417
418     case ACPI_DMT_UUID:
419         Type = DT_FIELD_TYPE_UUID;
420         break;
421
422     case ACPI_DMT_DEVICE_PATH:
423         Type = DT_FIELD_TYPE_DEVICE_PATH;
424         break;
425
426     case ACPI_DMT_LABEL:
427         Type = DT_FIELD_TYPE_LABEL;
428         break;
429
430     default:
431         Type = DT_FIELD_TYPE_INTEGER;
432         break;
433     }
434
435     return (Type);
436 }
437
438
439 /******************************************************************************
440  *
441  * FUNCTION:    DtGetBufferLength
442  *
443  * PARAMETERS:  Buffer              - List of integers,
444  *                                    for example "10 3A 4F 2E"
445  *
446  * RETURN:      Count of integer
447  *
448  * DESCRIPTION: Get length of bytes needed to store the integers
449  *
450  *****************************************************************************/
451
452 UINT32
453 DtGetBufferLength (
454     char                    *Buffer)
455 {
456     UINT32                  ByteLength = 0;
457
458
459     while (*Buffer)
460     {
461         if (*Buffer == ' ')
462         {
463             ByteLength++;
464
465             while (*Buffer == ' ')
466             {
467                 Buffer++;
468             }
469         }
470
471         Buffer++;
472     }
473
474     return (++ByteLength);
475 }
476
477
478 /******************************************************************************
479  *
480  * FUNCTION:    DtGetFieldLength
481  *
482  * PARAMETERS:  Field               - Current field
483  *              Info                - Data table info
484  *
485  * RETURN:      Field length
486  *
487  * DESCRIPTION: Get length of bytes needed to compile the field
488  *
489  * Note: This function must remain in sync with AcpiDmDumpTable.
490  *
491  *****************************************************************************/
492
493 UINT32
494 DtGetFieldLength (
495     DT_FIELD                *Field,
496     ACPI_DMTABLE_INFO       *Info)
497 {
498     UINT32                  ByteLength = 0;
499     char                    *Value;
500
501
502     /* Length is based upon the opcode for this field in the info table */
503
504     switch (Info->Opcode)
505     {
506     case ACPI_DMT_FLAG0:
507     case ACPI_DMT_FLAG1:
508     case ACPI_DMT_FLAG2:
509     case ACPI_DMT_FLAG3:
510     case ACPI_DMT_FLAG4:
511     case ACPI_DMT_FLAG5:
512     case ACPI_DMT_FLAG6:
513     case ACPI_DMT_FLAG7:
514     case ACPI_DMT_FLAGS0:
515     case ACPI_DMT_FLAGS1:
516     case ACPI_DMT_FLAGS2:
517     case ACPI_DMT_FLAGS4:
518     case ACPI_DMT_LABEL:
519     case ACPI_DMT_EXTRA_TEXT:
520         ByteLength = 0;
521         break;
522
523     case ACPI_DMT_UINT8:
524     case ACPI_DMT_CHKSUM:
525     case ACPI_DMT_SPACEID:
526     case ACPI_DMT_ACCWIDTH:
527     case ACPI_DMT_IVRS:
528     case ACPI_DMT_MADT:
529     case ACPI_DMT_PMTT:
530     case ACPI_DMT_SRAT:
531     case ACPI_DMT_ASF:
532     case ACPI_DMT_HESTNTYP:
533     case ACPI_DMT_FADTPM:
534     case ACPI_DMT_EINJACT:
535     case ACPI_DMT_EINJINST:
536     case ACPI_DMT_ERSTACT:
537     case ACPI_DMT_ERSTINST:
538         ByteLength = 1;
539         break;
540
541     case ACPI_DMT_UINT16:
542     case ACPI_DMT_DMAR:
543     case ACPI_DMT_HEST:
544     case ACPI_DMT_PCI_PATH:
545         ByteLength = 2;
546         break;
547
548     case ACPI_DMT_UINT24:
549         ByteLength = 3;
550         break;
551
552     case ACPI_DMT_UINT32:
553     case ACPI_DMT_NAME4:
554     case ACPI_DMT_SLIC:
555     case ACPI_DMT_SIG:
556         ByteLength = 4;
557         break;
558
559     case ACPI_DMT_UINT40:
560         ByteLength = 5;
561         break;
562
563     case ACPI_DMT_UINT48:
564     case ACPI_DMT_NAME6:
565         ByteLength = 6;
566         break;
567
568     case ACPI_DMT_UINT56:
569     case ACPI_DMT_BUF7:
570         ByteLength = 7;
571         break;
572
573     case ACPI_DMT_UINT64:
574     case ACPI_DMT_NAME8:
575         ByteLength = 8;
576         break;
577
578     case ACPI_DMT_STRING:
579         Value = DtGetFieldValue (Field);
580         if (Value)
581         {
582             ByteLength = ACPI_STRLEN (Value) + 1;
583         }
584         else
585         {   /* At this point, this is a fatal error */
586
587             sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
588             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
589             return (0);
590         }
591         break;
592
593     case ACPI_DMT_GAS:
594         ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
595         break;
596
597     case ACPI_DMT_HESTNTFY:
598         ByteLength = sizeof (ACPI_HEST_NOTIFY);
599         break;
600
601     case ACPI_DMT_BUFFER:
602         Value = DtGetFieldValue (Field);
603         if (Value)
604         {
605             ByteLength = DtGetBufferLength (Value);
606         }
607         else
608         {   /* At this point, this is a fatal error */
609
610             sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
611             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
612             return (0);
613         }
614         break;
615
616     case ACPI_DMT_BUF16:
617     case ACPI_DMT_UUID:
618         ByteLength = 16;
619         break;
620
621     case ACPI_DMT_BUF128:
622         ByteLength = 128;
623         break;
624
625     case ACPI_DMT_UNICODE:
626         Value = DtGetFieldValue (Field);
627
628         /* TBD: error if Value is NULL? (as below?) */
629
630         ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16);
631         break;
632
633     default:
634         DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
635         return (0);
636     }
637
638     return (ByteLength);
639 }
640
641
642 /******************************************************************************
643  *
644  * FUNCTION:    DtSum
645  *
646  * PARAMETERS:  DT_WALK_CALLBACK:
647  *              Subtable            - Subtable
648  *              Context             - Unused
649  *              ReturnValue         - Store the checksum of subtable
650  *
651  * RETURN:      Status
652  *
653  * DESCRIPTION: Get the checksum of subtable
654  *
655  *****************************************************************************/
656
657 static void
658 DtSum (
659     DT_SUBTABLE             *Subtable,
660     void                    *Context,
661     void                    *ReturnValue)
662 {
663     UINT8                   Checksum;
664     UINT8                   *Sum = ReturnValue;
665
666
667     Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
668     *Sum = (UINT8) (*Sum + Checksum);
669 }
670
671
672 /******************************************************************************
673  *
674  * FUNCTION:    DtSetTableChecksum
675  *
676  * PARAMETERS:  ChecksumPointer     - Where to return the checksum
677  *
678  * RETURN:      None
679  *
680  * DESCRIPTION: Set checksum of the whole data table into the checksum field
681  *
682  *****************************************************************************/
683
684 void
685 DtSetTableChecksum (
686     UINT8                   *ChecksumPointer)
687 {
688     UINT8                   Checksum = 0;
689     UINT8                   OldSum;
690
691
692     DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
693
694     OldSum = *ChecksumPointer;
695     Checksum = (UINT8) (Checksum - OldSum);
696
697     /* Compute the final checksum */
698
699     Checksum = (UINT8) (0 - Checksum);
700     *ChecksumPointer = Checksum;
701 }
702
703
704 /******************************************************************************
705  *
706  * FUNCTION:    DtSetTableLength
707  *
708  * PARAMETERS:  None
709  *
710  * RETURN:      None
711  *
712  * DESCRIPTION: Walk the subtables and set all the length fields
713  *
714  *****************************************************************************/
715
716 void
717 DtSetTableLength (
718     void)
719 {
720     DT_SUBTABLE             *ParentTable;
721     DT_SUBTABLE             *ChildTable;
722
723
724     ParentTable = Gbl_RootTable;
725     ChildTable = NULL;
726
727     if (!ParentTable)
728     {
729         return;
730     }
731
732     DtSetSubtableLength (ParentTable);
733
734     while (1)
735     {
736         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
737         if (ChildTable)
738         {
739             if (ChildTable->LengthField)
740             {
741                 DtSetSubtableLength (ChildTable);
742             }
743
744             if (ChildTable->Child)
745             {
746                 ParentTable = ChildTable;
747                 ChildTable = NULL;
748             }
749             else
750             {
751                 ParentTable->TotalLength += ChildTable->TotalLength;
752                 if (ParentTable->LengthField)
753                 {
754                     DtSetSubtableLength (ParentTable);
755                 }
756             }
757         }
758         else
759         {
760             ChildTable = ParentTable;
761
762             if (ChildTable == Gbl_RootTable)
763             {
764                 break;
765             }
766
767             ParentTable = DtGetParentSubtable (ParentTable);
768
769             ParentTable->TotalLength += ChildTable->TotalLength;
770             if (ParentTable->LengthField)
771             {
772                 DtSetSubtableLength (ParentTable);
773             }
774         }
775     }
776 }
777
778
779 /******************************************************************************
780  *
781  * FUNCTION:    DtWalkTableTree
782  *
783  * PARAMETERS:  StartTable          - Subtable in the tree where walking begins
784  *              UserFunction        - Called during the walk
785  *              Context             - Passed to user function
786  *              ReturnValue         - The return value of UserFunction
787  *
788  * RETURN:      None
789  *
790  * DESCRIPTION: Performs a depth-first walk of the subtable tree
791  *
792  *****************************************************************************/
793
794 void
795 DtWalkTableTree (
796     DT_SUBTABLE             *StartTable,
797     DT_WALK_CALLBACK        UserFunction,
798     void                    *Context,
799     void                    *ReturnValue)
800 {
801     DT_SUBTABLE             *ParentTable;
802     DT_SUBTABLE             *ChildTable;
803
804
805     ParentTable = StartTable;
806     ChildTable = NULL;
807
808     if (!ParentTable)
809     {
810         return;
811     }
812
813     UserFunction (ParentTable, Context, ReturnValue);
814
815     while (1)
816     {
817         ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
818         if (ChildTable)
819         {
820             UserFunction (ChildTable, Context, ReturnValue);
821
822             if (ChildTable->Child)
823             {
824                 ParentTable = ChildTable;
825                 ChildTable = NULL;
826             }
827         }
828         else
829         {
830             ChildTable = ParentTable;
831             if (ChildTable == Gbl_RootTable)
832             {
833                 break;
834             }
835
836             ParentTable = DtGetParentSubtable (ParentTable);
837
838             if (ChildTable->Peer == StartTable)
839             {
840                 break;
841             }
842         }
843     }
844 }
845
846
847 /******************************************************************************
848  *
849  * FUNCTION:    DtFreeFieldList
850  *
851  * PARAMETERS:  None
852  *
853  * RETURN:      None
854  *
855  * DESCRIPTION: Free the field list
856  *
857  *****************************************************************************/
858
859 void
860 DtFreeFieldList (
861     void)
862 {
863     DT_FIELD                *Field = Gbl_FieldList;
864     DT_FIELD                *NextField;
865
866
867     /* Walk and free entire field list */
868
869     while (Field)
870     {
871         NextField = Field->Next; /* Save link */
872
873         if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED))
874         {
875             ACPI_FREE (Field->Name);
876             ACPI_FREE (Field->Value);
877         }
878
879         ACPI_FREE (Field);
880         Field = NextField;
881     }
882 }