Sync ACPICA with Intel's version 20140724.
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / dttable.c
1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, 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 __DTTABLE_C__
45
46 /* Compile all complex data tables */
47
48 #include "aslcompiler.h"
49 #include "dtcompiler.h"
50
51 #define _COMPONENT          DT_COMPILER
52         ACPI_MODULE_NAME    ("dttable")
53
54
55 /* TBD: merge these into dmtbinfo.c? */
56
57 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
58 {
59     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
60     {ACPI_DMT_EXIT,     0,               NULL, 0}
61 };
62
63 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
64 {
65     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
66     {ACPI_DMT_EXIT,     0,               NULL, 0}
67 };
68
69
70 /* TBD: move to acmacros.h */
71
72 #define ACPI_SUB_PTR(t, a, b) \
73     ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
74
75
76 /* Local prototypes */
77
78 static ACPI_STATUS
79 DtCompileTwoSubtables (
80     void                    **List,
81     ACPI_DMTABLE_INFO       *TableInfo1,
82     ACPI_DMTABLE_INFO       *TableInfo2);
83
84
85 /******************************************************************************
86  *
87  * FUNCTION:    DtCompileTwoSubtables
88  *
89  * PARAMETERS:  List                - Current field list pointer
90  *              TableInfo1          - Info table 1
91  *              TableInfo1          - Info table 2
92  *
93  * RETURN:      Status
94  *
95  * DESCRIPTION: Compile tables with a header and one or more same subtables.
96  *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
97  *
98  *****************************************************************************/
99
100 static ACPI_STATUS
101 DtCompileTwoSubtables (
102     void                    **List,
103     ACPI_DMTABLE_INFO       *TableInfo1,
104     ACPI_DMTABLE_INFO       *TableInfo2)
105 {
106     ACPI_STATUS             Status;
107     DT_SUBTABLE             *Subtable;
108     DT_SUBTABLE             *ParentTable;
109     DT_FIELD                **PFieldList = (DT_FIELD **) List;
110
111
112     Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
113     if (ACPI_FAILURE (Status))
114     {
115         return (Status);
116     }
117
118     ParentTable = DtPeekSubtable ();
119     DtInsertSubtable (ParentTable, Subtable);
120
121     while (*PFieldList)
122     {
123         Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
124         if (ACPI_FAILURE (Status))
125         {
126             return (Status);
127         }
128
129         DtInsertSubtable (ParentTable, Subtable);
130     }
131
132     return (AE_OK);
133 }
134
135
136 /******************************************************************************
137  *
138  * FUNCTION:    DtCompileFacs
139  *
140  * PARAMETERS:  PFieldList          - Current field list pointer
141  *
142  * RETURN:      Status
143  *
144  * DESCRIPTION: Compile FACS.
145  *
146  *****************************************************************************/
147
148 ACPI_STATUS
149 DtCompileFacs (
150     DT_FIELD                **PFieldList)
151 {
152     DT_SUBTABLE             *Subtable;
153     UINT8                   *ReservedBuffer;
154     ACPI_STATUS             Status;
155     UINT32                  ReservedSize;
156
157
158     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
159                 &Gbl_RootTable, TRUE);
160     if (ACPI_FAILURE (Status))
161     {
162         return (Status);
163     }
164
165     /* Large FACS reserved area at the end of the table */
166
167     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
168     ReservedBuffer = UtLocalCalloc (ReservedSize);
169
170     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
171
172     ACPI_FREE (ReservedBuffer);
173     DtInsertSubtable (Gbl_RootTable, Subtable);
174     return (AE_OK);
175 }
176
177
178 /******************************************************************************
179  *
180  * FUNCTION:    DtCompileRsdp
181  *
182  * PARAMETERS:  PFieldList          - Current field list pointer
183  *
184  * RETURN:      Status
185  *
186  * DESCRIPTION: Compile RSDP.
187  *
188  *****************************************************************************/
189
190 ACPI_STATUS
191 DtCompileRsdp (
192     DT_FIELD                **PFieldList)
193 {
194     DT_SUBTABLE             *Subtable;
195     ACPI_TABLE_RSDP         *Rsdp;
196     ACPI_RSDP_EXTENSION     *RsdpExtension;
197     ACPI_STATUS             Status;
198
199
200     /* Compile the "common" RSDP (ACPI 1.0) */
201
202     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
203                 &Gbl_RootTable, TRUE);
204     if (ACPI_FAILURE (Status))
205     {
206         return (Status);
207     }
208
209     Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
210     DtSetTableChecksum (&Rsdp->Checksum);
211
212     if (Rsdp->Revision > 0)
213     {
214         /* Compile the "extended" part of the RSDP as a subtable */
215
216         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
217                     &Subtable, TRUE);
218         if (ACPI_FAILURE (Status))
219         {
220             return (Status);
221         }
222
223         DtInsertSubtable (Gbl_RootTable, Subtable);
224
225         /* Set length and extended checksum for entire RSDP */
226
227         RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
228         RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
229         DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
230     }
231
232     return (AE_OK);
233 }
234
235
236 /******************************************************************************
237  *
238  * FUNCTION:    DtCompileAsf
239  *
240  * PARAMETERS:  List                - Current field list pointer
241  *
242  * RETURN:      Status
243  *
244  * DESCRIPTION: Compile ASF!.
245  *
246  *****************************************************************************/
247
248 ACPI_STATUS
249 DtCompileAsf (
250     void                    **List)
251 {
252     ACPI_ASF_INFO           *AsfTable;
253     DT_SUBTABLE             *Subtable;
254     DT_SUBTABLE             *ParentTable;
255     ACPI_DMTABLE_INFO       *InfoTable;
256     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
257     UINT32                  DataCount = 0;
258     ACPI_STATUS             Status;
259     UINT32                  i;
260     DT_FIELD                **PFieldList = (DT_FIELD **) List;
261     DT_FIELD                *SubtableStart;
262
263
264     while (*PFieldList)
265     {
266         SubtableStart = *PFieldList;
267         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
268                     &Subtable, TRUE);
269         if (ACPI_FAILURE (Status))
270         {
271             return (Status);
272         }
273
274         ParentTable = DtPeekSubtable ();
275         DtInsertSubtable (ParentTable, Subtable);
276         DtPushSubtable (Subtable);
277
278         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
279
280         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
281         {
282         case ACPI_ASF_TYPE_INFO:
283
284             InfoTable = AcpiDmTableInfoAsf0;
285             break;
286
287         case ACPI_ASF_TYPE_ALERT:
288
289             InfoTable = AcpiDmTableInfoAsf1;
290             break;
291
292         case ACPI_ASF_TYPE_CONTROL:
293
294             InfoTable = AcpiDmTableInfoAsf2;
295             break;
296
297         case ACPI_ASF_TYPE_BOOT:
298
299             InfoTable = AcpiDmTableInfoAsf3;
300             break;
301
302         case ACPI_ASF_TYPE_ADDRESS:
303
304             InfoTable = AcpiDmTableInfoAsf4;
305             break;
306
307         default:
308
309             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
310             return (AE_ERROR);
311         }
312
313         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
314         if (ACPI_FAILURE (Status))
315         {
316             return (Status);
317         }
318
319         ParentTable = DtPeekSubtable ();
320         DtInsertSubtable (ParentTable, Subtable);
321
322         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
323         {
324         case ACPI_ASF_TYPE_INFO:
325
326             DataInfoTable = NULL;
327             break;
328
329         case ACPI_ASF_TYPE_ALERT:
330
331             DataInfoTable = AcpiDmTableInfoAsf1a;
332             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
333                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
334                             sizeof (ACPI_ASF_HEADER)))->Alerts;
335             break;
336
337         case ACPI_ASF_TYPE_CONTROL:
338
339             DataInfoTable = AcpiDmTableInfoAsf2a;
340             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
341                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
342                             sizeof (ACPI_ASF_HEADER)))->Controls;
343             break;
344
345         case ACPI_ASF_TYPE_BOOT:
346
347             DataInfoTable = NULL;
348             break;
349
350         case ACPI_ASF_TYPE_ADDRESS:
351
352             DataInfoTable = TableInfoAsfAddress;
353             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
354                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
355                             sizeof (ACPI_ASF_HEADER)))->Devices;
356             break;
357
358         default:
359
360             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
361             return (AE_ERROR);
362         }
363
364         if (DataInfoTable)
365         {
366             switch (AsfTable->Header.Type & 0x7F)
367             {
368             case ACPI_ASF_TYPE_ADDRESS:
369
370                 while (DataCount > 0)
371                 {
372                     Status = DtCompileTable (PFieldList, DataInfoTable,
373                                 &Subtable, TRUE);
374                     if (ACPI_FAILURE (Status))
375                     {
376                         return (Status);
377                     }
378
379                     DtInsertSubtable (ParentTable, Subtable);
380                     DataCount = DataCount - Subtable->Length;
381                 }
382                 break;
383
384             default:
385
386                 for (i = 0; i < DataCount; i++)
387                 {
388                     Status = DtCompileTable (PFieldList, DataInfoTable,
389                                 &Subtable, TRUE);
390                     if (ACPI_FAILURE (Status))
391                     {
392                         return (Status);
393                     }
394
395                     DtInsertSubtable (ParentTable, Subtable);
396                 }
397                 break;
398             }
399         }
400
401         DtPopSubtable ();
402     }
403
404     return (AE_OK);
405 }
406
407
408 /******************************************************************************
409  *
410  * FUNCTION:    DtCompileCpep
411  *
412  * PARAMETERS:  List                - Current field list pointer
413  *
414  * RETURN:      Status
415  *
416  * DESCRIPTION: Compile CPEP.
417  *
418  *****************************************************************************/
419
420 ACPI_STATUS
421 DtCompileCpep (
422     void                    **List)
423 {
424     ACPI_STATUS             Status;
425
426
427     Status = DtCompileTwoSubtables (List,
428                  AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
429     return (Status);
430 }
431
432
433 /******************************************************************************
434  *
435  * FUNCTION:    DtCompileCsrt
436  *
437  * PARAMETERS:  List                - Current field list pointer
438  *
439  * RETURN:      Status
440  *
441  * DESCRIPTION: Compile CSRT.
442  *
443  *****************************************************************************/
444
445 ACPI_STATUS
446 DtCompileCsrt (
447     void                    **List)
448 {
449     ACPI_STATUS             Status = AE_OK;
450     DT_SUBTABLE             *Subtable;
451     DT_SUBTABLE             *ParentTable;
452     DT_FIELD                **PFieldList = (DT_FIELD **) List;
453     UINT32                  DescriptorCount;
454     UINT32                  GroupLength;
455
456
457     /* Subtables (Resource Groups) */
458
459     while (*PFieldList)
460     {
461         /* Resource group subtable */
462
463         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
464                     &Subtable, TRUE);
465         if (ACPI_FAILURE (Status))
466         {
467             return (Status);
468         }
469
470         /* Compute the number of resource descriptors */
471
472         GroupLength =
473             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
474                 Subtable->Buffer))->Length -
475             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
476                 Subtable->Buffer))->SharedInfoLength -
477             sizeof (ACPI_CSRT_GROUP);
478
479         DescriptorCount = (GroupLength  /
480             sizeof (ACPI_CSRT_DESCRIPTOR));
481
482         ParentTable = DtPeekSubtable ();
483         DtInsertSubtable (ParentTable, Subtable);
484         DtPushSubtable (Subtable);
485
486         /* Shared info subtable (One per resource group) */
487
488         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
489                     &Subtable, TRUE);
490         if (ACPI_FAILURE (Status))
491         {
492             return (Status);
493         }
494
495         ParentTable = DtPeekSubtable ();
496         DtInsertSubtable (ParentTable, Subtable);
497
498         /* Sub-Subtables (Resource Descriptors) */
499
500         while (*PFieldList && DescriptorCount)
501         {
502             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
503                         &Subtable, TRUE);
504             if (ACPI_FAILURE (Status))
505             {
506                 return (Status);
507             }
508
509             ParentTable = DtPeekSubtable ();
510             DtInsertSubtable (ParentTable, Subtable);
511             DescriptorCount--;
512         }
513
514         DtPopSubtable ();
515     }
516
517     return (Status);
518 }
519
520
521 /******************************************************************************
522  *
523  * FUNCTION:    DtCompileDbg2
524  *
525  * PARAMETERS:  List                - Current field list pointer
526  *
527  * RETURN:      Status
528  *
529  * DESCRIPTION: Compile DBG2.
530  *
531  *****************************************************************************/
532
533 ACPI_STATUS
534 DtCompileDbg2 (
535     void                    **List)
536 {
537     ACPI_STATUS             Status;
538     DT_SUBTABLE             *Subtable;
539     DT_SUBTABLE             *ParentTable;
540     DT_FIELD                **PFieldList = (DT_FIELD **) List;
541     UINT32                  SubtableCount;
542     ACPI_DBG2_HEADER        *Dbg2Header;
543     ACPI_DBG2_DEVICE        *DeviceInfo;
544     UINT16                  CurrentOffset;
545     UINT32                  i;
546
547
548     /* Main table */
549
550     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
551     if (ACPI_FAILURE (Status))
552     {
553         return (Status);
554     }
555
556     ParentTable = DtPeekSubtable ();
557     DtInsertSubtable (ParentTable, Subtable);
558
559     /* Main table fields */
560
561     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
562     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
563         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
564
565     SubtableCount = Dbg2Header->InfoCount;
566     DtPushSubtable (Subtable);
567
568     /* Process all Device Information subtables (Count = InfoCount) */
569
570     while (*PFieldList && SubtableCount)
571     {
572         /* Subtable: Debug Device Information */
573
574         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
575                     &Subtable, TRUE);
576         if (ACPI_FAILURE (Status))
577         {
578             return (Status);
579         }
580
581         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
582         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
583
584         ParentTable = DtPeekSubtable ();
585         DtInsertSubtable (ParentTable, Subtable);
586         DtPushSubtable (Subtable);
587
588         ParentTable = DtPeekSubtable ();
589
590         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
591
592         DeviceInfo->BaseAddressOffset = CurrentOffset;
593         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
594         {
595             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
596                         &Subtable, TRUE);
597             if (ACPI_FAILURE (Status))
598             {
599                 return (Status);
600             }
601
602             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
603             DtInsertSubtable (ParentTable, Subtable);
604         }
605
606         /* AddressSize array (Required, size = RegisterCount) */
607
608         DeviceInfo->AddressSizeOffset = CurrentOffset;
609         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
610         {
611             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
612                         &Subtable, TRUE);
613             if (ACPI_FAILURE (Status))
614             {
615                 return (Status);
616             }
617
618             CurrentOffset += (UINT16) sizeof (UINT32);
619             DtInsertSubtable (ParentTable, Subtable);
620         }
621
622         /* NamespaceString device identifier (Required, size = NamePathLength) */
623
624         DeviceInfo->NamepathOffset = CurrentOffset;
625         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
626                     &Subtable, TRUE);
627         if (ACPI_FAILURE (Status))
628         {
629             return (Status);
630         }
631
632         /* Update the device info header */
633
634         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
635         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
636         DtInsertSubtable (ParentTable, Subtable);
637
638         /* OemData - Variable-length data (Optional, size = OemDataLength) */
639
640         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
641                     &Subtable, TRUE);
642         if (ACPI_FAILURE (Status))
643         {
644             return (Status);
645         }
646
647         /* Update the device info header (zeros if no OEM data present) */
648
649         DeviceInfo->OemDataOffset = 0;
650         DeviceInfo->OemDataLength = 0;
651
652         /* Optional subtable (OemData) */
653
654         if (Subtable && Subtable->Length)
655         {
656             DeviceInfo->OemDataOffset = CurrentOffset;
657             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
658
659             DtInsertSubtable (ParentTable, Subtable);
660         }
661
662         SubtableCount--;
663         DtPopSubtable (); /* Get next Device Information subtable */
664     }
665
666     DtPopSubtable ();
667     return (AE_OK);
668 }
669
670
671 /******************************************************************************
672  *
673  * FUNCTION:    DtCompileDmar
674  *
675  * PARAMETERS:  List                - Current field list pointer
676  *
677  * RETURN:      Status
678  *
679  * DESCRIPTION: Compile DMAR.
680  *
681  *****************************************************************************/
682
683 ACPI_STATUS
684 DtCompileDmar (
685     void                    **List)
686 {
687     ACPI_STATUS             Status;
688     DT_SUBTABLE             *Subtable;
689     DT_SUBTABLE             *ParentTable;
690     DT_FIELD                **PFieldList = (DT_FIELD **) List;
691     DT_FIELD                *SubtableStart;
692     ACPI_DMTABLE_INFO       *InfoTable;
693     ACPI_DMAR_HEADER        *DmarHeader;
694     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
695     UINT32                  DeviceScopeLength;
696     UINT32                  PciPathLength;
697
698
699     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
700     if (ACPI_FAILURE (Status))
701     {
702         return (Status);
703     }
704
705     ParentTable = DtPeekSubtable ();
706     DtInsertSubtable (ParentTable, Subtable);
707     DtPushSubtable (Subtable);
708
709     while (*PFieldList)
710     {
711         /* DMAR Header */
712
713         SubtableStart = *PFieldList;
714         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
715                     &Subtable, TRUE);
716         if (ACPI_FAILURE (Status))
717         {
718             return (Status);
719         }
720
721         ParentTable = DtPeekSubtable ();
722         DtInsertSubtable (ParentTable, Subtable);
723         DtPushSubtable (Subtable);
724
725         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
726
727         switch (DmarHeader->Type)
728         {
729         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
730
731             InfoTable = AcpiDmTableInfoDmar0;
732             break;
733
734         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
735
736             InfoTable = AcpiDmTableInfoDmar1;
737             break;
738
739         case ACPI_DMAR_TYPE_ROOT_ATS:
740
741             InfoTable = AcpiDmTableInfoDmar2;
742             break;
743
744         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
745
746             InfoTable = AcpiDmTableInfoDmar3;
747             break;
748
749         case ACPI_DMAR_TYPE_NAMESPACE:
750
751             InfoTable = AcpiDmTableInfoDmar4;
752             break;
753
754         default:
755
756             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
757             return (AE_ERROR);
758         }
759
760         /* DMAR Subtable */
761
762         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
763         if (ACPI_FAILURE (Status))
764         {
765             return (Status);
766         }
767
768         ParentTable = DtPeekSubtable ();
769         DtInsertSubtable (ParentTable, Subtable);
770
771         /*
772          * Optional Device Scope subtables
773          */
774         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
775             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
776         {
777             /* These types do not support device scopes */
778
779             DtPopSubtable ();
780             continue;
781         }
782
783         DtPushSubtable (Subtable);
784         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
785             ParentTable->Length;
786         while (DeviceScopeLength)
787         {
788             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
789                         &Subtable, FALSE);
790             if (Status == AE_NOT_FOUND)
791             {
792                 break;
793             }
794
795             ParentTable = DtPeekSubtable ();
796             DtInsertSubtable (ParentTable, Subtable);
797             DtPushSubtable (Subtable);
798
799             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
800
801             /* Optional PCI Paths */
802
803             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
804             while (PciPathLength)
805             {
806                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
807                             &Subtable, FALSE);
808                 if (Status == AE_NOT_FOUND)
809                 {
810                     DtPopSubtable ();
811                     break;
812                 }
813
814                 ParentTable = DtPeekSubtable ();
815                 DtInsertSubtable (ParentTable, Subtable);
816                 PciPathLength -= Subtable->Length;
817             }
818
819             DtPopSubtable ();
820             DeviceScopeLength -= DmarDeviceScope->Length;
821         }
822
823         DtPopSubtable ();
824         DtPopSubtable ();
825     }
826
827     return (AE_OK);
828 }
829
830
831 /******************************************************************************
832  *
833  * FUNCTION:    DtCompileEinj
834  *
835  * PARAMETERS:  List                - Current field list pointer
836  *
837  * RETURN:      Status
838  *
839  * DESCRIPTION: Compile EINJ.
840  *
841  *****************************************************************************/
842
843 ACPI_STATUS
844 DtCompileEinj (
845     void                    **List)
846 {
847     ACPI_STATUS             Status;
848
849
850     Status = DtCompileTwoSubtables (List,
851                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
852     return (Status);
853 }
854
855
856 /******************************************************************************
857  *
858  * FUNCTION:    DtCompileErst
859  *
860  * PARAMETERS:  List                - Current field list pointer
861  *
862  * RETURN:      Status
863  *
864  * DESCRIPTION: Compile ERST.
865  *
866  *****************************************************************************/
867
868 ACPI_STATUS
869 DtCompileErst (
870     void                    **List)
871 {
872     ACPI_STATUS             Status;
873
874
875     Status = DtCompileTwoSubtables (List,
876                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
877     return (Status);
878 }
879
880
881 /******************************************************************************
882  *
883  * FUNCTION:    DtCompileFadt
884  *
885  * PARAMETERS:  List                - Current field list pointer
886  *
887  * RETURN:      Status
888  *
889  * DESCRIPTION: Compile FADT.
890  *
891  *****************************************************************************/
892
893 ACPI_STATUS
894 DtCompileFadt (
895     void                    **List)
896 {
897     ACPI_STATUS             Status;
898     DT_SUBTABLE             *Subtable;
899     DT_SUBTABLE             *ParentTable;
900     DT_FIELD                **PFieldList = (DT_FIELD **) List;
901     ACPI_TABLE_HEADER       *Table;
902     UINT8                   Revision;
903
904
905     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
906                 &Subtable, TRUE);
907     if (ACPI_FAILURE (Status))
908     {
909         return (Status);
910     }
911
912     ParentTable = DtPeekSubtable ();
913     DtInsertSubtable (ParentTable, Subtable);
914
915     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
916     Revision = Table->Revision;
917
918     if (Revision == 2)
919     {
920         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
921                     &Subtable, TRUE);
922         if (ACPI_FAILURE (Status))
923         {
924             return (Status);
925         }
926
927         DtInsertSubtable (ParentTable, Subtable);
928     }
929     else if (Revision >= 2)
930     {
931         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
932                     &Subtable, TRUE);
933         if (ACPI_FAILURE (Status))
934         {
935             return (Status);
936         }
937
938         DtInsertSubtable (ParentTable, Subtable);
939
940         if (Revision >= 5)
941         {
942             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
943                         &Subtable, TRUE);
944             if (ACPI_FAILURE (Status))
945             {
946                 return (Status);
947             }
948
949             DtInsertSubtable (ParentTable, Subtable);
950         }
951     }
952
953     return (AE_OK);
954 }
955
956 /******************************************************************************
957  *
958  * FUNCTION:    DtCompileGtdt
959  *
960  * PARAMETERS:  List                - Current field list pointer
961  *
962  * RETURN:      Status
963  *
964  * DESCRIPTION: Compile GTDT.
965  *
966  *****************************************************************************/
967
968 ACPI_STATUS
969 DtCompileGtdt (
970     void                    **List)
971 {
972     ACPI_STATUS             Status;
973     DT_SUBTABLE             *Subtable;
974     DT_SUBTABLE             *ParentTable;
975     DT_FIELD                **PFieldList = (DT_FIELD **) List;
976     DT_FIELD                *SubtableStart;
977     ACPI_SUBTABLE_HEADER    *GtdtHeader;
978     ACPI_DMTABLE_INFO       *InfoTable;
979     UINT32                  GtCount;
980
981
982     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
983                 &Subtable, TRUE);
984     if (ACPI_FAILURE (Status))
985     {
986         return (Status);
987     }
988
989     ParentTable = DtPeekSubtable ();
990     DtInsertSubtable (ParentTable, Subtable);
991
992     while (*PFieldList)
993     {
994         SubtableStart = *PFieldList;
995         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
996                     &Subtable, TRUE);
997         if (ACPI_FAILURE (Status))
998         {
999             return (Status);
1000         }
1001
1002         ParentTable = DtPeekSubtable ();
1003         DtInsertSubtable (ParentTable, Subtable);
1004         DtPushSubtable (Subtable);
1005
1006         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1007
1008         switch (GtdtHeader->Type)
1009         {
1010         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1011
1012             InfoTable = AcpiDmTableInfoGtdt0;
1013             break;
1014
1015         case ACPI_GTDT_TYPE_WATCHDOG:
1016
1017             InfoTable = AcpiDmTableInfoGtdt1;
1018             break;
1019
1020         default:
1021
1022             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1023             return (AE_ERROR);
1024         }
1025
1026         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1027         if (ACPI_FAILURE (Status))
1028         {
1029             return (Status);
1030         }
1031
1032         ParentTable = DtPeekSubtable ();
1033         DtInsertSubtable (ParentTable, Subtable);
1034
1035         /*
1036          * Additional GT block subtable data
1037          */
1038
1039         switch (GtdtHeader->Type)
1040         {
1041         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1042
1043             DtPushSubtable (Subtable);
1044             ParentTable = DtPeekSubtable ();
1045
1046             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1047                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1048             while (GtCount)
1049             {
1050                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1051                             &Subtable, TRUE);
1052                 if (ACPI_FAILURE (Status))
1053                 {
1054                     return (Status);
1055                 }
1056
1057
1058                 DtInsertSubtable (ParentTable, Subtable);
1059                 GtCount--;
1060             }
1061             DtPopSubtable ();
1062             break;
1063
1064         default:
1065
1066             break;
1067         }
1068
1069         DtPopSubtable ();
1070     }
1071
1072     return (AE_OK);
1073 }
1074
1075
1076 /******************************************************************************
1077  *
1078  * FUNCTION:    DtCompileFpdt
1079  *
1080  * PARAMETERS:  List                - Current field list pointer
1081  *
1082  * RETURN:      Status
1083  *
1084  * DESCRIPTION: Compile FPDT.
1085  *
1086  *****************************************************************************/
1087
1088 ACPI_STATUS
1089 DtCompileFpdt (
1090     void                    **List)
1091 {
1092     ACPI_STATUS             Status;
1093     ACPI_FPDT_HEADER        *FpdtHeader;
1094     DT_SUBTABLE             *Subtable;
1095     DT_SUBTABLE             *ParentTable;
1096     ACPI_DMTABLE_INFO       *InfoTable;
1097     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1098     DT_FIELD                *SubtableStart;
1099
1100
1101     while (*PFieldList)
1102     {
1103         SubtableStart = *PFieldList;
1104         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1105                     &Subtable, TRUE);
1106         if (ACPI_FAILURE (Status))
1107         {
1108             return (Status);
1109         }
1110
1111         ParentTable = DtPeekSubtable ();
1112         DtInsertSubtable (ParentTable, Subtable);
1113         DtPushSubtable (Subtable);
1114
1115         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1116
1117         switch (FpdtHeader->Type)
1118         {
1119         case ACPI_FPDT_TYPE_BOOT:
1120
1121             InfoTable = AcpiDmTableInfoFpdt0;
1122             break;
1123
1124         case ACPI_FPDT_TYPE_S3PERF:
1125
1126             InfoTable = AcpiDmTableInfoFpdt1;
1127             break;
1128
1129         default:
1130
1131             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1132             return (AE_ERROR);
1133             break;
1134         }
1135
1136         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1137         if (ACPI_FAILURE (Status))
1138         {
1139             return (Status);
1140         }
1141
1142         ParentTable = DtPeekSubtable ();
1143         DtInsertSubtable (ParentTable, Subtable);
1144         DtPopSubtable ();
1145     }
1146
1147     return (AE_OK);
1148 }
1149
1150
1151 /******************************************************************************
1152  *
1153  * FUNCTION:    DtCompileHest
1154  *
1155  * PARAMETERS:  List                - Current field list pointer
1156  *
1157  * RETURN:      Status
1158  *
1159  * DESCRIPTION: Compile HEST.
1160  *
1161  *****************************************************************************/
1162
1163 ACPI_STATUS
1164 DtCompileHest (
1165     void                    **List)
1166 {
1167     ACPI_STATUS             Status;
1168     DT_SUBTABLE             *Subtable;
1169     DT_SUBTABLE             *ParentTable;
1170     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1171     DT_FIELD                *SubtableStart;
1172     ACPI_DMTABLE_INFO       *InfoTable;
1173     UINT16                  Type;
1174     UINT32                  BankCount;
1175
1176
1177     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1178                 &Subtable, TRUE);
1179     if (ACPI_FAILURE (Status))
1180     {
1181         return (Status);
1182     }
1183
1184     ParentTable = DtPeekSubtable ();
1185     DtInsertSubtable (ParentTable, Subtable);
1186
1187     while (*PFieldList)
1188     {
1189         /* Get subtable type */
1190
1191         SubtableStart = *PFieldList;
1192         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1193
1194         switch (Type)
1195         {
1196         case ACPI_HEST_TYPE_IA32_CHECK:
1197
1198             InfoTable = AcpiDmTableInfoHest0;
1199             break;
1200
1201         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1202
1203             InfoTable = AcpiDmTableInfoHest1;
1204             break;
1205
1206         case ACPI_HEST_TYPE_IA32_NMI:
1207
1208             InfoTable = AcpiDmTableInfoHest2;
1209             break;
1210
1211         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1212
1213             InfoTable = AcpiDmTableInfoHest6;
1214             break;
1215
1216         case ACPI_HEST_TYPE_AER_ENDPOINT:
1217
1218             InfoTable = AcpiDmTableInfoHest7;
1219             break;
1220
1221         case ACPI_HEST_TYPE_AER_BRIDGE:
1222
1223             InfoTable = AcpiDmTableInfoHest8;
1224             break;
1225
1226         case ACPI_HEST_TYPE_GENERIC_ERROR:
1227
1228             InfoTable = AcpiDmTableInfoHest9;
1229             break;
1230
1231         default:
1232
1233             /* Cannot continue on unknown type */
1234
1235             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1236             return (AE_ERROR);
1237         }
1238
1239         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1240         if (ACPI_FAILURE (Status))
1241         {
1242             return (Status);
1243         }
1244
1245         DtInsertSubtable (ParentTable, Subtable);
1246
1247         /*
1248          * Additional subtable data - IA32 Error Bank(s)
1249          */
1250         BankCount = 0;
1251         switch (Type)
1252         {
1253         case ACPI_HEST_TYPE_IA32_CHECK:
1254
1255             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1256                             Subtable->Buffer))->NumHardwareBanks;
1257             break;
1258
1259         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1260
1261             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1262                             Subtable->Buffer))->NumHardwareBanks;
1263             break;
1264
1265         default:
1266
1267             break;
1268         }
1269
1270         while (BankCount)
1271         {
1272             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1273                         &Subtable, TRUE);
1274             if (ACPI_FAILURE (Status))
1275             {
1276                 return (Status);
1277             }
1278
1279             DtInsertSubtable (ParentTable, Subtable);
1280             BankCount--;
1281         }
1282     }
1283
1284     return (AE_OK);
1285 }
1286
1287
1288 /******************************************************************************
1289  *
1290  * FUNCTION:    DtCompileIvrs
1291  *
1292  * PARAMETERS:  List                - Current field list pointer
1293  *
1294  * RETURN:      Status
1295  *
1296  * DESCRIPTION: Compile IVRS.
1297  *
1298  *****************************************************************************/
1299
1300 ACPI_STATUS
1301 DtCompileIvrs (
1302     void                    **List)
1303 {
1304     ACPI_STATUS             Status;
1305     DT_SUBTABLE             *Subtable;
1306     DT_SUBTABLE             *ParentTable;
1307     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1308     DT_FIELD                *SubtableStart;
1309     ACPI_DMTABLE_INFO       *InfoTable;
1310     ACPI_IVRS_HEADER        *IvrsHeader;
1311     UINT8                   EntryType;
1312
1313
1314     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1315                 &Subtable, TRUE);
1316     if (ACPI_FAILURE (Status))
1317     {
1318         return (Status);
1319     }
1320
1321     ParentTable = DtPeekSubtable ();
1322     DtInsertSubtable (ParentTable, Subtable);
1323
1324     while (*PFieldList)
1325     {
1326         SubtableStart = *PFieldList;
1327         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1328                     &Subtable, TRUE);
1329         if (ACPI_FAILURE (Status))
1330         {
1331             return (Status);
1332         }
1333
1334         ParentTable = DtPeekSubtable ();
1335         DtInsertSubtable (ParentTable, Subtable);
1336         DtPushSubtable (Subtable);
1337
1338         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1339
1340         switch (IvrsHeader->Type)
1341         {
1342         case ACPI_IVRS_TYPE_HARDWARE:
1343
1344             InfoTable = AcpiDmTableInfoIvrs0;
1345             break;
1346
1347         case ACPI_IVRS_TYPE_MEMORY1:
1348         case ACPI_IVRS_TYPE_MEMORY2:
1349         case ACPI_IVRS_TYPE_MEMORY3:
1350
1351             InfoTable = AcpiDmTableInfoIvrs1;
1352             break;
1353
1354         default:
1355
1356             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1357             return (AE_ERROR);
1358         }
1359
1360         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1361         if (ACPI_FAILURE (Status))
1362         {
1363             return (Status);
1364         }
1365
1366         ParentTable = DtPeekSubtable ();
1367         DtInsertSubtable (ParentTable, Subtable);
1368
1369         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1370         {
1371             while (*PFieldList &&
1372                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1373             {
1374                 SubtableStart = *PFieldList;
1375                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1376
1377                 switch (EntryType)
1378                 {
1379                 /* 4-byte device entries */
1380
1381                 case ACPI_IVRS_TYPE_PAD4:
1382                 case ACPI_IVRS_TYPE_ALL:
1383                 case ACPI_IVRS_TYPE_SELECT:
1384                 case ACPI_IVRS_TYPE_START:
1385                 case ACPI_IVRS_TYPE_END:
1386
1387                     InfoTable = AcpiDmTableInfoIvrs4;
1388                     break;
1389
1390                 /* 8-byte entries, type A */
1391
1392                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1393                 case ACPI_IVRS_TYPE_ALIAS_START:
1394
1395                     InfoTable = AcpiDmTableInfoIvrs8a;
1396                     break;
1397
1398                 /* 8-byte entries, type B */
1399
1400                 case ACPI_IVRS_TYPE_PAD8:
1401                 case ACPI_IVRS_TYPE_EXT_SELECT:
1402                 case ACPI_IVRS_TYPE_EXT_START:
1403
1404                     InfoTable = AcpiDmTableInfoIvrs8b;
1405                     break;
1406
1407                 /* 8-byte entries, type C */
1408
1409                 case ACPI_IVRS_TYPE_SPECIAL:
1410
1411                     InfoTable = AcpiDmTableInfoIvrs8c;
1412                     break;
1413
1414                 default:
1415
1416                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1417                         "IVRS Device Entry");
1418                     return (AE_ERROR);
1419                 }
1420
1421                 Status = DtCompileTable (PFieldList, InfoTable,
1422                             &Subtable, TRUE);
1423                 if (ACPI_FAILURE (Status))
1424                 {
1425                     return (Status);
1426                 }
1427
1428                 DtInsertSubtable (ParentTable, Subtable);
1429             }
1430         }
1431
1432         DtPopSubtable ();
1433     }
1434
1435     return (AE_OK);
1436 }
1437
1438
1439 /******************************************************************************
1440  *
1441  * FUNCTION:    DtCompileLpit
1442  *
1443  * PARAMETERS:  List                - Current field list pointer
1444  *
1445  * RETURN:      Status
1446  *
1447  * DESCRIPTION: Compile LPIT.
1448  *
1449  *****************************************************************************/
1450
1451 ACPI_STATUS
1452 DtCompileLpit (
1453     void                    **List)
1454 {
1455     ACPI_STATUS             Status;
1456     DT_SUBTABLE             *Subtable;
1457     DT_SUBTABLE             *ParentTable;
1458     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1459     DT_FIELD                *SubtableStart;
1460     ACPI_DMTABLE_INFO       *InfoTable;
1461     ACPI_LPIT_HEADER        *LpitHeader;
1462
1463
1464     /* Note: Main table consists only of the standard ACPI table header */
1465
1466     while (*PFieldList)
1467     {
1468         SubtableStart = *PFieldList;
1469
1470         /* LPIT Subtable header */
1471
1472         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1473                     &Subtable, TRUE);
1474         if (ACPI_FAILURE (Status))
1475         {
1476             return (Status);
1477         }
1478
1479         ParentTable = DtPeekSubtable ();
1480         DtInsertSubtable (ParentTable, Subtable);
1481         DtPushSubtable (Subtable);
1482
1483         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1484
1485         switch (LpitHeader->Type)
1486         {
1487         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1488
1489             InfoTable = AcpiDmTableInfoLpit0;
1490             break;
1491
1492         case ACPI_LPIT_TYPE_SIMPLE_IO:
1493
1494             InfoTable = AcpiDmTableInfoLpit1;
1495             break;
1496
1497         default:
1498
1499             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1500             return (AE_ERROR);
1501         }
1502
1503         /* LPIT Subtable */
1504
1505         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1506         if (ACPI_FAILURE (Status))
1507         {
1508             return (Status);
1509         }
1510
1511         ParentTable = DtPeekSubtable ();
1512         DtInsertSubtable (ParentTable, Subtable);
1513         DtPopSubtable ();
1514     }
1515
1516     return (AE_OK);
1517 }
1518
1519
1520 /******************************************************************************
1521  *
1522  * FUNCTION:    DtCompileMadt
1523  *
1524  * PARAMETERS:  List                - Current field list pointer
1525  *
1526  * RETURN:      Status
1527  *
1528  * DESCRIPTION: Compile MADT.
1529  *
1530  *****************************************************************************/
1531
1532 ACPI_STATUS
1533 DtCompileMadt (
1534     void                    **List)
1535 {
1536     ACPI_STATUS             Status;
1537     DT_SUBTABLE             *Subtable;
1538     DT_SUBTABLE             *ParentTable;
1539     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1540     DT_FIELD                *SubtableStart;
1541     ACPI_SUBTABLE_HEADER    *MadtHeader;
1542     ACPI_DMTABLE_INFO       *InfoTable;
1543
1544
1545     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1546                 &Subtable, TRUE);
1547     if (ACPI_FAILURE (Status))
1548     {
1549         return (Status);
1550     }
1551
1552     ParentTable = DtPeekSubtable ();
1553     DtInsertSubtable (ParentTable, Subtable);
1554
1555     while (*PFieldList)
1556     {
1557         SubtableStart = *PFieldList;
1558         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1559                     &Subtable, TRUE);
1560         if (ACPI_FAILURE (Status))
1561         {
1562             return (Status);
1563         }
1564
1565         ParentTable = DtPeekSubtable ();
1566         DtInsertSubtable (ParentTable, Subtable);
1567         DtPushSubtable (Subtable);
1568
1569         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1570
1571         switch (MadtHeader->Type)
1572         {
1573         case ACPI_MADT_TYPE_LOCAL_APIC:
1574
1575             InfoTable = AcpiDmTableInfoMadt0;
1576             break;
1577
1578         case ACPI_MADT_TYPE_IO_APIC:
1579
1580             InfoTable = AcpiDmTableInfoMadt1;
1581             break;
1582
1583         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1584
1585             InfoTable = AcpiDmTableInfoMadt2;
1586             break;
1587
1588         case ACPI_MADT_TYPE_NMI_SOURCE:
1589
1590             InfoTable = AcpiDmTableInfoMadt3;
1591             break;
1592
1593         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1594
1595             InfoTable = AcpiDmTableInfoMadt4;
1596             break;
1597
1598         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1599
1600             InfoTable = AcpiDmTableInfoMadt5;
1601             break;
1602
1603         case ACPI_MADT_TYPE_IO_SAPIC:
1604
1605             InfoTable = AcpiDmTableInfoMadt6;
1606             break;
1607
1608         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1609
1610             InfoTable = AcpiDmTableInfoMadt7;
1611             break;
1612
1613         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1614
1615             InfoTable = AcpiDmTableInfoMadt8;
1616             break;
1617
1618         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1619
1620             InfoTable = AcpiDmTableInfoMadt9;
1621             break;
1622
1623         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1624
1625             InfoTable = AcpiDmTableInfoMadt10;
1626             break;
1627
1628         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1629
1630             InfoTable = AcpiDmTableInfoMadt11;
1631             break;
1632
1633         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1634
1635             InfoTable = AcpiDmTableInfoMadt12;
1636             break;
1637
1638         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1639
1640             InfoTable = AcpiDmTableInfoMadt13;
1641             break;
1642
1643         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1644
1645             InfoTable = AcpiDmTableInfoMadt14;
1646             break;
1647
1648         default:
1649
1650             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1651             return (AE_ERROR);
1652         }
1653
1654         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1655         if (ACPI_FAILURE (Status))
1656         {
1657             return (Status);
1658         }
1659
1660         ParentTable = DtPeekSubtable ();
1661         DtInsertSubtable (ParentTable, Subtable);
1662         DtPopSubtable ();
1663     }
1664
1665     return (AE_OK);
1666 }
1667
1668
1669 /******************************************************************************
1670  *
1671  * FUNCTION:    DtCompileMcfg
1672  *
1673  * PARAMETERS:  List                - Current field list pointer
1674  *
1675  * RETURN:      Status
1676  *
1677  * DESCRIPTION: Compile MCFG.
1678  *
1679  *****************************************************************************/
1680
1681 ACPI_STATUS
1682 DtCompileMcfg (
1683     void                    **List)
1684 {
1685     ACPI_STATUS             Status;
1686
1687
1688     Status = DtCompileTwoSubtables (List,
1689                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1690     return (Status);
1691 }
1692
1693
1694 /******************************************************************************
1695  *
1696  * FUNCTION:    DtCompileMpst
1697  *
1698  * PARAMETERS:  List                - Current field list pointer
1699  *
1700  * RETURN:      Status
1701  *
1702  * DESCRIPTION: Compile MPST.
1703  *
1704  *****************************************************************************/
1705
1706 ACPI_STATUS
1707 DtCompileMpst (
1708     void                    **List)
1709 {
1710     ACPI_STATUS             Status;
1711     DT_SUBTABLE             *Subtable;
1712     DT_SUBTABLE             *ParentTable;
1713     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1714     ACPI_MPST_CHANNEL       *MpstChannelInfo;
1715     ACPI_MPST_POWER_NODE    *MpstPowerNode;
1716     ACPI_MPST_DATA_HDR      *MpstDataHeader;
1717     UINT16                  SubtableCount;
1718     UINT32                  PowerStateCount;
1719     UINT32                  ComponentCount;
1720
1721
1722     /* Main table */
1723
1724     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1725     if (ACPI_FAILURE (Status))
1726     {
1727         return (Status);
1728     }
1729
1730     ParentTable = DtPeekSubtable ();
1731     DtInsertSubtable (ParentTable, Subtable);
1732     DtPushSubtable (Subtable);
1733
1734     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1735     SubtableCount = MpstChannelInfo->PowerNodeCount;
1736
1737     while (*PFieldList && SubtableCount)
1738     {
1739         /* Subtable: Memory Power Node(s) */
1740
1741         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1742                     &Subtable, TRUE);
1743         if (ACPI_FAILURE (Status))
1744         {
1745             return (Status);
1746         }
1747
1748         ParentTable = DtPeekSubtable ();
1749         DtInsertSubtable (ParentTable, Subtable);
1750         DtPushSubtable (Subtable);
1751
1752         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1753         PowerStateCount = MpstPowerNode->NumPowerStates;
1754         ComponentCount = MpstPowerNode->NumPhysicalComponents;
1755
1756         ParentTable = DtPeekSubtable ();
1757
1758         /* Sub-subtables - Memory Power State Structure(s) */
1759
1760         while (*PFieldList && PowerStateCount)
1761         {
1762             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1763                         &Subtable, TRUE);
1764             if (ACPI_FAILURE (Status))
1765             {
1766                 return (Status);
1767             }
1768
1769             DtInsertSubtable (ParentTable, Subtable);
1770             PowerStateCount--;
1771         }
1772
1773         /* Sub-subtables - Physical Component ID Structure(s) */
1774
1775         while (*PFieldList && ComponentCount)
1776         {
1777             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1778                         &Subtable, TRUE);
1779             if (ACPI_FAILURE (Status))
1780             {
1781                 return (Status);
1782             }
1783
1784             DtInsertSubtable (ParentTable, Subtable);
1785             ComponentCount--;
1786         }
1787
1788         SubtableCount--;
1789         DtPopSubtable ();
1790     }
1791
1792     /* Subtable: Count of Memory Power State Characteristic structures */
1793
1794     DtPopSubtable ();
1795
1796     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1797     if (ACPI_FAILURE (Status))
1798     {
1799         return (Status);
1800     }
1801
1802     ParentTable = DtPeekSubtable ();
1803     DtInsertSubtable (ParentTable, Subtable);
1804     DtPushSubtable (Subtable);
1805
1806     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1807     SubtableCount = MpstDataHeader->CharacteristicsCount;
1808
1809     ParentTable = DtPeekSubtable ();
1810
1811     /* Subtable: Memory Power State Characteristics structure(s) */
1812
1813     while (*PFieldList && SubtableCount)
1814     {
1815         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1816                     &Subtable, TRUE);
1817         if (ACPI_FAILURE (Status))
1818         {
1819             return (Status);
1820         }
1821
1822         DtInsertSubtable (ParentTable, Subtable);
1823         SubtableCount--;
1824     }
1825
1826     DtPopSubtable ();
1827     return (AE_OK);
1828 }
1829
1830
1831 /******************************************************************************
1832  *
1833  * FUNCTION:    DtCompileMsct
1834  *
1835  * PARAMETERS:  List                - Current field list pointer
1836  *
1837  * RETURN:      Status
1838  *
1839  * DESCRIPTION: Compile MSCT.
1840  *
1841  *****************************************************************************/
1842
1843 ACPI_STATUS
1844 DtCompileMsct (
1845     void                    **List)
1846 {
1847     ACPI_STATUS             Status;
1848
1849
1850     Status = DtCompileTwoSubtables (List,
1851                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1852     return (Status);
1853 }
1854
1855
1856 /******************************************************************************
1857  *
1858  * FUNCTION:    DtCompileMtmr
1859  *
1860  * PARAMETERS:  List                - Current field list pointer
1861  *
1862  * RETURN:      Status
1863  *
1864  * DESCRIPTION: Compile MTMR.
1865  *
1866  *****************************************************************************/
1867
1868 ACPI_STATUS
1869 DtCompileMtmr (
1870     void                    **List)
1871 {
1872     ACPI_STATUS             Status;
1873
1874
1875     Status = DtCompileTwoSubtables (List,
1876                  AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1877     return (Status);
1878 }
1879
1880
1881 /******************************************************************************
1882  *
1883  * FUNCTION:    DtCompilePcct
1884  *
1885  * PARAMETERS:  List                - Current field list pointer
1886  *
1887  * RETURN:      Status
1888  *
1889  * DESCRIPTION: Compile PCCT.
1890  *
1891  *****************************************************************************/
1892
1893 ACPI_STATUS
1894 DtCompilePcct (
1895     void                    **List)
1896 {
1897     ACPI_STATUS             Status;
1898     DT_SUBTABLE             *Subtable;
1899     DT_SUBTABLE             *ParentTable;
1900     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1901     DT_FIELD                *SubtableStart;
1902     ACPI_SUBTABLE_HEADER    *PcctHeader;
1903     ACPI_DMTABLE_INFO       *InfoTable;
1904
1905
1906     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1907                 &Subtable, TRUE);
1908     if (ACPI_FAILURE (Status))
1909     {
1910         return (Status);
1911     }
1912
1913     ParentTable = DtPeekSubtable ();
1914     DtInsertSubtable (ParentTable, Subtable);
1915
1916     while (*PFieldList)
1917     {
1918         SubtableStart = *PFieldList;
1919         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1920                     &Subtable, TRUE);
1921         if (ACPI_FAILURE (Status))
1922         {
1923             return (Status);
1924         }
1925
1926         ParentTable = DtPeekSubtable ();
1927         DtInsertSubtable (ParentTable, Subtable);
1928         DtPushSubtable (Subtable);
1929
1930         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1931
1932         switch (PcctHeader->Type)
1933         {
1934         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1935
1936             InfoTable = AcpiDmTableInfoPcct0;
1937             break;
1938
1939         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1940
1941             InfoTable = AcpiDmTableInfoPcct1;
1942             break;
1943
1944         default:
1945
1946             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1947             return (AE_ERROR);
1948         }
1949
1950         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1951         if (ACPI_FAILURE (Status))
1952         {
1953             return (Status);
1954         }
1955
1956         ParentTable = DtPeekSubtable ();
1957         DtInsertSubtable (ParentTable, Subtable);
1958         DtPopSubtable ();
1959     }
1960
1961     return (AE_OK);
1962 }
1963
1964
1965 /******************************************************************************
1966  *
1967  * FUNCTION:    DtCompilePmtt
1968  *
1969  * PARAMETERS:  List                - Current field list pointer
1970  *
1971  * RETURN:      Status
1972  *
1973  * DESCRIPTION: Compile PMTT.
1974  *
1975  *****************************************************************************/
1976
1977 ACPI_STATUS
1978 DtCompilePmtt (
1979     void                    **List)
1980 {
1981     ACPI_STATUS             Status;
1982     DT_SUBTABLE             *Subtable;
1983     DT_SUBTABLE             *ParentTable;
1984     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1985     DT_FIELD                *SubtableStart;
1986     ACPI_PMTT_HEADER        *PmttHeader;
1987     ACPI_PMTT_CONTROLLER    *PmttController;
1988     UINT16                  DomainCount;
1989     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1990
1991
1992     /* Main table */
1993
1994     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1995     if (ACPI_FAILURE (Status))
1996     {
1997         return (Status);
1998     }
1999
2000     ParentTable = DtPeekSubtable ();
2001     DtInsertSubtable (ParentTable, Subtable);
2002     DtPushSubtable (Subtable);
2003
2004     while (*PFieldList)
2005     {
2006         SubtableStart = *PFieldList;
2007         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
2008                     &Subtable, TRUE);
2009         if (ACPI_FAILURE (Status))
2010         {
2011             return (Status);
2012         }
2013
2014         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
2015         while (PrevType >= PmttHeader->Type)
2016         {
2017             DtPopSubtable ();
2018
2019             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
2020             {
2021                 break;
2022             }
2023             PrevType--;
2024         }
2025         PrevType = PmttHeader->Type;
2026
2027         ParentTable = DtPeekSubtable ();
2028         DtInsertSubtable (ParentTable, Subtable);
2029         DtPushSubtable (Subtable);
2030
2031         switch (PmttHeader->Type)
2032         {
2033         case ACPI_PMTT_TYPE_SOCKET:
2034
2035             /* Subtable: Socket Structure */
2036
2037             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
2038                     &Subtable, TRUE);
2039             if (ACPI_FAILURE (Status))
2040             {
2041                 return (Status);
2042             }
2043
2044             ParentTable = DtPeekSubtable ();
2045             DtInsertSubtable (ParentTable, Subtable);
2046             break;
2047
2048         case ACPI_PMTT_TYPE_CONTROLLER:
2049
2050             /* Subtable: Memory Controller Structure */
2051
2052             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
2053                     &Subtable, TRUE);
2054             if (ACPI_FAILURE (Status))
2055             {
2056                 return (Status);
2057             }
2058
2059             ParentTable = DtPeekSubtable ();
2060             DtInsertSubtable (ParentTable, Subtable);
2061
2062             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
2063                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
2064             DomainCount = PmttController->DomainCount;
2065
2066             while (DomainCount)
2067             {
2068                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
2069                     &Subtable, TRUE);
2070                 if (ACPI_FAILURE (Status))
2071                 {
2072                     return (Status);
2073                 }
2074
2075                 DtInsertSubtable (ParentTable, Subtable);
2076                 DomainCount--;
2077             }
2078             break;
2079
2080         case ACPI_PMTT_TYPE_DIMM:
2081
2082             /* Subtable: Physical Component Structure */
2083
2084             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
2085                     &Subtable, TRUE);
2086             if (ACPI_FAILURE (Status))
2087             {
2088                 return (Status);
2089             }
2090
2091             ParentTable = DtPeekSubtable ();
2092             DtInsertSubtable (ParentTable, Subtable);
2093             break;
2094
2095         default:
2096
2097             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
2098             return (AE_ERROR);
2099         }
2100     }
2101
2102     return (Status);
2103 }
2104
2105
2106 /******************************************************************************
2107  *
2108  * FUNCTION:    DtCompileRsdt
2109  *
2110  * PARAMETERS:  List                - Current field list pointer
2111  *
2112  * RETURN:      Status
2113  *
2114  * DESCRIPTION: Compile RSDT.
2115  *
2116  *****************************************************************************/
2117
2118 ACPI_STATUS
2119 DtCompileRsdt (
2120     void                    **List)
2121 {
2122     DT_SUBTABLE             *Subtable;
2123     DT_SUBTABLE             *ParentTable;
2124     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2125     UINT32                  Address;
2126
2127
2128     ParentTable = DtPeekSubtable ();
2129
2130     while (FieldList)
2131     {
2132         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2133
2134         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2135         DtInsertSubtable (ParentTable, Subtable);
2136         FieldList = FieldList->Next;
2137     }
2138
2139     return (AE_OK);
2140 }
2141
2142
2143 /******************************************************************************
2144  *
2145  * FUNCTION:    DtCompileS3pt
2146  *
2147  * PARAMETERS:  PFieldList          - Current field list pointer
2148  *
2149  * RETURN:      Status
2150  *
2151  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2152  *
2153  *****************************************************************************/
2154
2155 ACPI_STATUS
2156 DtCompileS3pt (
2157     DT_FIELD                **PFieldList)
2158 {
2159     ACPI_STATUS             Status;
2160     ACPI_S3PT_HEADER        *S3ptHeader;
2161     DT_SUBTABLE             *Subtable;
2162     DT_SUBTABLE             *ParentTable;
2163     ACPI_DMTABLE_INFO       *InfoTable;
2164     DT_FIELD                *SubtableStart;
2165
2166
2167     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2168                 &Gbl_RootTable, TRUE);
2169     if (ACPI_FAILURE (Status))
2170     {
2171         return (Status);
2172     }
2173
2174     DtPushSubtable (Gbl_RootTable);
2175
2176     while (*PFieldList)
2177     {
2178         SubtableStart = *PFieldList;
2179         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2180                     &Subtable, TRUE);
2181         if (ACPI_FAILURE (Status))
2182         {
2183             return (Status);
2184         }
2185
2186         ParentTable = DtPeekSubtable ();
2187         DtInsertSubtable (ParentTable, Subtable);
2188         DtPushSubtable (Subtable);
2189
2190         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2191
2192         switch (S3ptHeader->Type)
2193         {
2194         case ACPI_S3PT_TYPE_RESUME:
2195
2196             InfoTable = AcpiDmTableInfoS3pt0;
2197             break;
2198
2199         case ACPI_S3PT_TYPE_SUSPEND:
2200
2201             InfoTable = AcpiDmTableInfoS3pt1;
2202             break;
2203
2204         default:
2205
2206             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2207             return (AE_ERROR);
2208         }
2209
2210         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2211         if (ACPI_FAILURE (Status))
2212         {
2213             return (Status);
2214         }
2215
2216         ParentTable = DtPeekSubtable ();
2217         DtInsertSubtable (ParentTable, Subtable);
2218         DtPopSubtable ();
2219     }
2220
2221     return (AE_OK);
2222 }
2223
2224
2225 /******************************************************************************
2226  *
2227  * FUNCTION:    DtCompileSlic
2228  *
2229  * PARAMETERS:  List                - Current field list pointer
2230  *
2231  * RETURN:      Status
2232  *
2233  * DESCRIPTION: Compile SLIC.
2234  *
2235  *****************************************************************************/
2236
2237 ACPI_STATUS
2238 DtCompileSlic (
2239     void                    **List)
2240 {
2241     ACPI_STATUS             Status;
2242     DT_SUBTABLE             *Subtable;
2243     DT_SUBTABLE             *ParentTable;
2244     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2245     DT_FIELD                *SubtableStart;
2246     ACPI_SLIC_HEADER        *SlicHeader;
2247     ACPI_DMTABLE_INFO       *InfoTable;
2248
2249
2250     while (*PFieldList)
2251     {
2252         SubtableStart = *PFieldList;
2253         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
2254                     &Subtable, TRUE);
2255         if (ACPI_FAILURE (Status))
2256         {
2257             return (Status);
2258         }
2259
2260         ParentTable = DtPeekSubtable ();
2261         DtInsertSubtable (ParentTable, Subtable);
2262         DtPushSubtable (Subtable);
2263
2264         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
2265
2266         switch (SlicHeader->Type)
2267         {
2268         case ACPI_SLIC_TYPE_PUBLIC_KEY:
2269
2270             InfoTable = AcpiDmTableInfoSlic0;
2271             break;
2272
2273         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
2274
2275             InfoTable = AcpiDmTableInfoSlic1;
2276             break;
2277
2278         default:
2279
2280             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
2281             return (AE_ERROR);
2282         }
2283
2284         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2285         if (ACPI_FAILURE (Status))
2286         {
2287             return (Status);
2288         }
2289
2290         ParentTable = DtPeekSubtable ();
2291         DtInsertSubtable (ParentTable, Subtable);
2292         DtPopSubtable ();
2293     }
2294
2295     return (AE_OK);
2296 }
2297
2298
2299 /******************************************************************************
2300  *
2301  * FUNCTION:    DtCompileSlit
2302  *
2303  * PARAMETERS:  List                - Current field list pointer
2304  *
2305  * RETURN:      Status
2306  *
2307  * DESCRIPTION: Compile SLIT.
2308  *
2309  *****************************************************************************/
2310
2311 ACPI_STATUS
2312 DtCompileSlit (
2313     void                    **List)
2314 {
2315     ACPI_STATUS             Status;
2316     DT_SUBTABLE             *Subtable;
2317     DT_SUBTABLE             *ParentTable;
2318     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2319     DT_FIELD                *FieldList;
2320     UINT32                  Localities;
2321     UINT8                   *LocalityBuffer;
2322
2323
2324     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2325                 &Subtable, TRUE);
2326     if (ACPI_FAILURE (Status))
2327     {
2328         return (Status);
2329     }
2330
2331     ParentTable = DtPeekSubtable ();
2332     DtInsertSubtable (ParentTable, Subtable);
2333
2334     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2335     LocalityBuffer = UtLocalCalloc (Localities);
2336
2337     /* Compile each locality buffer */
2338
2339     FieldList = *PFieldList;
2340     while (FieldList)
2341     {
2342         DtCompileBuffer (LocalityBuffer,
2343             FieldList->Value, FieldList, Localities);
2344
2345         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2346         DtInsertSubtable (ParentTable, Subtable);
2347         FieldList = FieldList->Next;
2348     }
2349
2350     ACPI_FREE (LocalityBuffer);
2351     return (AE_OK);
2352 }
2353
2354
2355 /******************************************************************************
2356  *
2357  * FUNCTION:    DtCompileSrat
2358  *
2359  * PARAMETERS:  List                - Current field list pointer
2360  *
2361  * RETURN:      Status
2362  *
2363  * DESCRIPTION: Compile SRAT.
2364  *
2365  *****************************************************************************/
2366
2367 ACPI_STATUS
2368 DtCompileSrat (
2369     void                    **List)
2370 {
2371     ACPI_STATUS             Status;
2372     DT_SUBTABLE             *Subtable;
2373     DT_SUBTABLE             *ParentTable;
2374     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2375     DT_FIELD                *SubtableStart;
2376     ACPI_SUBTABLE_HEADER    *SratHeader;
2377     ACPI_DMTABLE_INFO       *InfoTable;
2378
2379
2380     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2381                 &Subtable, TRUE);
2382     if (ACPI_FAILURE (Status))
2383     {
2384         return (Status);
2385     }
2386
2387     ParentTable = DtPeekSubtable ();
2388     DtInsertSubtable (ParentTable, Subtable);
2389
2390     while (*PFieldList)
2391     {
2392         SubtableStart = *PFieldList;
2393         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2394                     &Subtable, TRUE);
2395         if (ACPI_FAILURE (Status))
2396         {
2397             return (Status);
2398         }
2399
2400         ParentTable = DtPeekSubtable ();
2401         DtInsertSubtable (ParentTable, Subtable);
2402         DtPushSubtable (Subtable);
2403
2404         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2405
2406         switch (SratHeader->Type)
2407         {
2408         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2409
2410             InfoTable = AcpiDmTableInfoSrat0;
2411             break;
2412
2413         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2414
2415             InfoTable = AcpiDmTableInfoSrat1;
2416             break;
2417
2418         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2419
2420             InfoTable = AcpiDmTableInfoSrat2;
2421             break;
2422
2423         default:
2424
2425             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2426             return (AE_ERROR);
2427         }
2428
2429         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2430         if (ACPI_FAILURE (Status))
2431         {
2432             return (Status);
2433         }
2434
2435         ParentTable = DtPeekSubtable ();
2436         DtInsertSubtable (ParentTable, Subtable);
2437         DtPopSubtable ();
2438     }
2439
2440     return (AE_OK);
2441 }
2442
2443
2444 /******************************************************************************
2445  *
2446  * FUNCTION:    DtGetGenericTableInfo
2447  *
2448  * PARAMETERS:  Name                - Generic type name
2449  *
2450  * RETURN:      Info entry
2451  *
2452  * DESCRIPTION: Obtain table info for a generic name entry
2453  *
2454  *****************************************************************************/
2455
2456 ACPI_DMTABLE_INFO *
2457 DtGetGenericTableInfo (
2458     char                    *Name)
2459 {
2460     ACPI_DMTABLE_INFO       *Info;
2461     UINT32                  i;
2462
2463
2464     if (!Name)
2465     {
2466         return (NULL);
2467     }
2468
2469     /* Search info table for name match */
2470
2471     for (i = 0; ; i++)
2472     {
2473         Info = AcpiDmTableInfoGeneric[i];
2474         if (Info->Opcode == ACPI_DMT_EXIT)
2475         {
2476             Info = NULL;
2477             break;
2478         }
2479
2480         /* Use caseless compare for generic keywords */
2481
2482         if (!AcpiUtStricmp (Name, Info->Name))
2483         {
2484             break;
2485         }
2486     }
2487
2488     return (Info);
2489 }
2490
2491
2492 /******************************************************************************
2493  *
2494  * FUNCTION:    DtCompileUefi
2495  *
2496  * PARAMETERS:  List                - Current field list pointer
2497  *
2498  * RETURN:      Status
2499  *
2500  * DESCRIPTION: Compile UEFI.
2501  *
2502  *****************************************************************************/
2503
2504 ACPI_STATUS
2505 DtCompileUefi (
2506     void                    **List)
2507 {
2508     ACPI_STATUS             Status;
2509     DT_SUBTABLE             *Subtable;
2510     DT_SUBTABLE             *ParentTable;
2511     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2512     UINT16                  *DataOffset;
2513
2514
2515     /* Compile the predefined portion of the UEFI table */
2516
2517     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2518                 &Subtable, TRUE);
2519     if (ACPI_FAILURE (Status))
2520     {
2521         return (Status);
2522     }
2523
2524     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2525     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2526
2527     ParentTable = DtPeekSubtable ();
2528     DtInsertSubtable (ParentTable, Subtable);
2529
2530     /*
2531      * Compile the "generic" portion of the UEFI table. This
2532      * part of the table is not predefined and any of the generic
2533      * operators may be used.
2534      */
2535
2536     DtCompileGeneric ((void **) PFieldList);
2537
2538     return (AE_OK);
2539 }
2540
2541
2542 /******************************************************************************
2543  *
2544  * FUNCTION:    DtCompileVrtc
2545  *
2546  * PARAMETERS:  List                - Current field list pointer
2547  *
2548  * RETURN:      Status
2549  *
2550  * DESCRIPTION: Compile VRTC.
2551  *
2552  *****************************************************************************/
2553
2554 ACPI_STATUS
2555 DtCompileVrtc (
2556     void                    **List)
2557 {
2558     ACPI_STATUS             Status;
2559
2560
2561     Status = DtCompileTwoSubtables (List,
2562                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2563     return (Status);
2564 }
2565
2566
2567 /******************************************************************************
2568  *
2569  * FUNCTION:    DtCompileWdat
2570  *
2571  * PARAMETERS:  List                - Current field list pointer
2572  *
2573  * RETURN:      Status
2574  *
2575  * DESCRIPTION: Compile WDAT.
2576  *
2577  *****************************************************************************/
2578
2579 ACPI_STATUS
2580 DtCompileWdat (
2581     void                    **List)
2582 {
2583     ACPI_STATUS             Status;
2584
2585
2586     Status = DtCompileTwoSubtables (List,
2587                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2588     return (Status);
2589 }
2590
2591
2592 /******************************************************************************
2593  *
2594  * FUNCTION:    DtCompileXsdt
2595  *
2596  * PARAMETERS:  List                - Current field list pointer
2597  *
2598  * RETURN:      Status
2599  *
2600  * DESCRIPTION: Compile XSDT.
2601  *
2602  *****************************************************************************/
2603
2604 ACPI_STATUS
2605 DtCompileXsdt (
2606     void                    **List)
2607 {
2608     DT_SUBTABLE             *Subtable;
2609     DT_SUBTABLE             *ParentTable;
2610     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2611     UINT64                  Address;
2612
2613     ParentTable = DtPeekSubtable ();
2614
2615     while (FieldList)
2616     {
2617         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2618
2619         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2620         DtInsertSubtable (ParentTable, Subtable);
2621         FieldList = FieldList->Next;
2622     }
2623
2624     return (AE_OK);
2625 }
2626
2627
2628 /******************************************************************************
2629  *
2630  * FUNCTION:    DtCompileGeneric
2631  *
2632  * PARAMETERS:  List                - Current field list pointer
2633  *
2634  * RETURN:      Status
2635  *
2636  * DESCRIPTION: Compile generic unknown table.
2637  *
2638  *****************************************************************************/
2639
2640 ACPI_STATUS
2641 DtCompileGeneric (
2642     void                    **List)
2643 {
2644     ACPI_STATUS             Status;
2645     DT_SUBTABLE             *Subtable;
2646     DT_SUBTABLE             *ParentTable;
2647     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2648     ACPI_DMTABLE_INFO       *Info;
2649
2650
2651     ParentTable = DtPeekSubtable ();
2652
2653     /*
2654      * Compile the "generic" portion of the table. This
2655      * part of the table is not predefined and any of the generic
2656      * operators may be used.
2657      */
2658
2659     /* Find any and all labels in the entire generic portion */
2660
2661     DtDetectAllLabels (*PFieldList);
2662
2663     /* Now we can actually compile the parse tree */
2664
2665     while (*PFieldList)
2666     {
2667         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2668         if (!Info)
2669         {
2670             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2671                 (*PFieldList)->Name);
2672             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2673                 (*PFieldList), MsgBuffer);
2674
2675             *PFieldList = (*PFieldList)->Next;
2676             continue;
2677         }
2678
2679         Status = DtCompileTable (PFieldList, Info,
2680                     &Subtable, TRUE);
2681         if (ACPI_SUCCESS (Status))
2682         {
2683             DtInsertSubtable (ParentTable, Subtable);
2684         }
2685         else
2686         {
2687             *PFieldList = (*PFieldList)->Next;
2688
2689             if (Status == AE_NOT_FOUND)
2690             {
2691                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2692                     (*PFieldList)->Name);
2693                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2694                     (*PFieldList), MsgBuffer);
2695             }
2696         }
2697     }
2698
2699     return (AE_OK);
2700 }