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_ATSR:
740 
741             InfoTable = AcpiDmTableInfoDmar2;
742             break;
743 
744         case ACPI_DMAR_HARDWARE_AFFINITY:
745 
746             InfoTable = AcpiDmTableInfoDmar3;
747             break;
748 
749         default:
750 
751             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
752             return (AE_ERROR);
753         }
754 
755         /* DMAR Subtable */
756 
757         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
758         if (ACPI_FAILURE (Status))
759         {
760             return (Status);
761         }
762 
763         ParentTable = DtPeekSubtable ();
764         DtInsertSubtable (ParentTable, Subtable);
765         DtPushSubtable (Subtable);
766 
767         /* Optional Device Scope subtables */
768 
769         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
770             ParentTable->Length;
771         while (DeviceScopeLength)
772         {
773             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
774                         &Subtable, FALSE);
775             if (Status == AE_NOT_FOUND)
776             {
777                 break;
778             }
779 
780             ParentTable = DtPeekSubtable ();
781             DtInsertSubtable (ParentTable, Subtable);
782             DtPushSubtable (Subtable);
783 
784             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
785 
786             /* Optional PCI Paths */
787 
788             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
789             while (PciPathLength)
790             {
791                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
792                             &Subtable, FALSE);
793                 if (Status == AE_NOT_FOUND)
794                 {
795                     DtPopSubtable ();
796                     break;
797                 }
798 
799                 ParentTable = DtPeekSubtable ();
800                 DtInsertSubtable (ParentTable, Subtable);
801                 PciPathLength -= Subtable->Length;
802             }
803 
804             DtPopSubtable ();
805             DeviceScopeLength -= DmarDeviceScope->Length;
806         }
807 
808         DtPopSubtable ();
809         DtPopSubtable ();
810     }
811 
812     return (AE_OK);
813 }
814 
815 
816 /******************************************************************************
817  *
818  * FUNCTION:    DtCompileEinj
819  *
820  * PARAMETERS:  List                - Current field list pointer
821  *
822  * RETURN:      Status
823  *
824  * DESCRIPTION: Compile EINJ.
825  *
826  *****************************************************************************/
827 
828 ACPI_STATUS
829 DtCompileEinj (
830     void                    **List)
831 {
832     ACPI_STATUS             Status;
833 
834 
835     Status = DtCompileTwoSubtables (List,
836                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
837     return (Status);
838 }
839 
840 
841 /******************************************************************************
842  *
843  * FUNCTION:    DtCompileErst
844  *
845  * PARAMETERS:  List                - Current field list pointer
846  *
847  * RETURN:      Status
848  *
849  * DESCRIPTION: Compile ERST.
850  *
851  *****************************************************************************/
852 
853 ACPI_STATUS
854 DtCompileErst (
855     void                    **List)
856 {
857     ACPI_STATUS             Status;
858 
859 
860     Status = DtCompileTwoSubtables (List,
861                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
862     return (Status);
863 }
864 
865 
866 /******************************************************************************
867  *
868  * FUNCTION:    DtCompileFadt
869  *
870  * PARAMETERS:  List                - Current field list pointer
871  *
872  * RETURN:      Status
873  *
874  * DESCRIPTION: Compile FADT.
875  *
876  *****************************************************************************/
877 
878 ACPI_STATUS
879 DtCompileFadt (
880     void                    **List)
881 {
882     ACPI_STATUS             Status;
883     DT_SUBTABLE             *Subtable;
884     DT_SUBTABLE             *ParentTable;
885     DT_FIELD                **PFieldList = (DT_FIELD **) List;
886     ACPI_TABLE_HEADER       *Table;
887     UINT8                   Revision;
888 
889 
890     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
891                 &Subtable, TRUE);
892     if (ACPI_FAILURE (Status))
893     {
894         return (Status);
895     }
896 
897     ParentTable = DtPeekSubtable ();
898     DtInsertSubtable (ParentTable, Subtable);
899 
900     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
901     Revision = Table->Revision;
902 
903     if (Revision == 2)
904     {
905         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
906                     &Subtable, TRUE);
907         if (ACPI_FAILURE (Status))
908         {
909             return (Status);
910         }
911 
912         DtInsertSubtable (ParentTable, Subtable);
913     }
914     else if (Revision >= 2)
915     {
916         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
917                     &Subtable, TRUE);
918         if (ACPI_FAILURE (Status))
919         {
920             return (Status);
921         }
922 
923         DtInsertSubtable (ParentTable, Subtable);
924 
925         if (Revision >= 5)
926         {
927             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
928                         &Subtable, TRUE);
929             if (ACPI_FAILURE (Status))
930             {
931                 return (Status);
932             }
933 
934             DtInsertSubtable (ParentTable, Subtable);
935         }
936     }
937 
938     return (AE_OK);
939 }
940 
941 
942 /******************************************************************************
943  *
944  * FUNCTION:    DtCompileFpdt
945  *
946  * PARAMETERS:  List                - Current field list pointer
947  *
948  * RETURN:      Status
949  *
950  * DESCRIPTION: Compile FPDT.
951  *
952  *****************************************************************************/
953 
954 ACPI_STATUS
955 DtCompileFpdt (
956     void                    **List)
957 {
958     ACPI_STATUS             Status;
959     ACPI_FPDT_HEADER        *FpdtHeader;
960     DT_SUBTABLE             *Subtable;
961     DT_SUBTABLE             *ParentTable;
962     ACPI_DMTABLE_INFO       *InfoTable;
963     DT_FIELD                **PFieldList = (DT_FIELD **) List;
964     DT_FIELD                *SubtableStart;
965 
966 
967     while (*PFieldList)
968     {
969         SubtableStart = *PFieldList;
970         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
971                     &Subtable, TRUE);
972         if (ACPI_FAILURE (Status))
973         {
974             return (Status);
975         }
976 
977         ParentTable = DtPeekSubtable ();
978         DtInsertSubtable (ParentTable, Subtable);
979         DtPushSubtable (Subtable);
980 
981         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
982 
983         switch (FpdtHeader->Type)
984         {
985         case ACPI_FPDT_TYPE_BOOT:
986 
987             InfoTable = AcpiDmTableInfoFpdt0;
988             break;
989 
990         case ACPI_FPDT_TYPE_S3PERF:
991 
992             InfoTable = AcpiDmTableInfoFpdt1;
993             break;
994 
995         default:
996 
997             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
998             return (AE_ERROR);
999             break;
1000         }
1001 
1002         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1003         if (ACPI_FAILURE (Status))
1004         {
1005             return (Status);
1006         }
1007 
1008         ParentTable = DtPeekSubtable ();
1009         DtInsertSubtable (ParentTable, Subtable);
1010         DtPopSubtable ();
1011     }
1012 
1013     return (AE_OK);
1014 }
1015 
1016 
1017 /******************************************************************************
1018  *
1019  * FUNCTION:    DtCompileHest
1020  *
1021  * PARAMETERS:  List                - Current field list pointer
1022  *
1023  * RETURN:      Status
1024  *
1025  * DESCRIPTION: Compile HEST.
1026  *
1027  *****************************************************************************/
1028 
1029 ACPI_STATUS
1030 DtCompileHest (
1031     void                    **List)
1032 {
1033     ACPI_STATUS             Status;
1034     DT_SUBTABLE             *Subtable;
1035     DT_SUBTABLE             *ParentTable;
1036     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1037     DT_FIELD                *SubtableStart;
1038     ACPI_DMTABLE_INFO       *InfoTable;
1039     UINT16                  Type;
1040     UINT32                  BankCount;
1041 
1042 
1043     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1044                 &Subtable, TRUE);
1045     if (ACPI_FAILURE (Status))
1046     {
1047         return (Status);
1048     }
1049 
1050     ParentTable = DtPeekSubtable ();
1051     DtInsertSubtable (ParentTable, Subtable);
1052 
1053     while (*PFieldList)
1054     {
1055         /* Get subtable type */
1056 
1057         SubtableStart = *PFieldList;
1058         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1059 
1060         switch (Type)
1061         {
1062         case ACPI_HEST_TYPE_IA32_CHECK:
1063 
1064             InfoTable = AcpiDmTableInfoHest0;
1065             break;
1066 
1067         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1068 
1069             InfoTable = AcpiDmTableInfoHest1;
1070             break;
1071 
1072         case ACPI_HEST_TYPE_IA32_NMI:
1073 
1074             InfoTable = AcpiDmTableInfoHest2;
1075             break;
1076 
1077         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1078 
1079             InfoTable = AcpiDmTableInfoHest6;
1080             break;
1081 
1082         case ACPI_HEST_TYPE_AER_ENDPOINT:
1083 
1084             InfoTable = AcpiDmTableInfoHest7;
1085             break;
1086 
1087         case ACPI_HEST_TYPE_AER_BRIDGE:
1088 
1089             InfoTable = AcpiDmTableInfoHest8;
1090             break;
1091 
1092         case ACPI_HEST_TYPE_GENERIC_ERROR:
1093 
1094             InfoTable = AcpiDmTableInfoHest9;
1095             break;
1096 
1097         default:
1098 
1099             /* Cannot continue on unknown type */
1100 
1101             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1102             return (AE_ERROR);
1103         }
1104 
1105         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1106         if (ACPI_FAILURE (Status))
1107         {
1108             return (Status);
1109         }
1110 
1111         DtInsertSubtable (ParentTable, Subtable);
1112 
1113         /*
1114          * Additional subtable data - IA32 Error Bank(s)
1115          */
1116         BankCount = 0;
1117         switch (Type)
1118         {
1119         case ACPI_HEST_TYPE_IA32_CHECK:
1120 
1121             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1122                             Subtable->Buffer))->NumHardwareBanks;
1123             break;
1124 
1125         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1126 
1127             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1128                             Subtable->Buffer))->NumHardwareBanks;
1129             break;
1130 
1131         default:
1132 
1133             break;
1134         }
1135 
1136         while (BankCount)
1137         {
1138             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1139                         &Subtable, TRUE);
1140             if (ACPI_FAILURE (Status))
1141             {
1142                 return (Status);
1143             }
1144 
1145             DtInsertSubtable (ParentTable, Subtable);
1146             BankCount--;
1147         }
1148     }
1149 
1150     return (AE_OK);
1151 }
1152 
1153 
1154 /******************************************************************************
1155  *
1156  * FUNCTION:    DtCompileIvrs
1157  *
1158  * PARAMETERS:  List                - Current field list pointer
1159  *
1160  * RETURN:      Status
1161  *
1162  * DESCRIPTION: Compile IVRS.
1163  *
1164  *****************************************************************************/
1165 
1166 ACPI_STATUS
1167 DtCompileIvrs (
1168     void                    **List)
1169 {
1170     ACPI_STATUS             Status;
1171     DT_SUBTABLE             *Subtable;
1172     DT_SUBTABLE             *ParentTable;
1173     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1174     DT_FIELD                *SubtableStart;
1175     ACPI_DMTABLE_INFO       *InfoTable;
1176     ACPI_IVRS_HEADER        *IvrsHeader;
1177     UINT8                   EntryType;
1178 
1179 
1180     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1181                 &Subtable, TRUE);
1182     if (ACPI_FAILURE (Status))
1183     {
1184         return (Status);
1185     }
1186 
1187     ParentTable = DtPeekSubtable ();
1188     DtInsertSubtable (ParentTable, Subtable);
1189 
1190     while (*PFieldList)
1191     {
1192         SubtableStart = *PFieldList;
1193         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1194                     &Subtable, TRUE);
1195         if (ACPI_FAILURE (Status))
1196         {
1197             return (Status);
1198         }
1199 
1200         ParentTable = DtPeekSubtable ();
1201         DtInsertSubtable (ParentTable, Subtable);
1202         DtPushSubtable (Subtable);
1203 
1204         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1205 
1206         switch (IvrsHeader->Type)
1207         {
1208         case ACPI_IVRS_TYPE_HARDWARE:
1209 
1210             InfoTable = AcpiDmTableInfoIvrs0;
1211             break;
1212 
1213         case ACPI_IVRS_TYPE_MEMORY1:
1214         case ACPI_IVRS_TYPE_MEMORY2:
1215         case ACPI_IVRS_TYPE_MEMORY3:
1216 
1217             InfoTable = AcpiDmTableInfoIvrs1;
1218             break;
1219 
1220         default:
1221 
1222             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1223             return (AE_ERROR);
1224         }
1225 
1226         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1227         if (ACPI_FAILURE (Status))
1228         {
1229             return (Status);
1230         }
1231 
1232         ParentTable = DtPeekSubtable ();
1233         DtInsertSubtable (ParentTable, Subtable);
1234 
1235         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1236         {
1237             while (*PFieldList &&
1238                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1239             {
1240                 SubtableStart = *PFieldList;
1241                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1242 
1243                 switch (EntryType)
1244                 {
1245                 /* 4-byte device entries */
1246 
1247                 case ACPI_IVRS_TYPE_PAD4:
1248                 case ACPI_IVRS_TYPE_ALL:
1249                 case ACPI_IVRS_TYPE_SELECT:
1250                 case ACPI_IVRS_TYPE_START:
1251                 case ACPI_IVRS_TYPE_END:
1252 
1253                     InfoTable = AcpiDmTableInfoIvrs4;
1254                     break;
1255 
1256                 /* 8-byte entries, type A */
1257 
1258                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1259                 case ACPI_IVRS_TYPE_ALIAS_START:
1260 
1261                     InfoTable = AcpiDmTableInfoIvrs8a;
1262                     break;
1263 
1264                 /* 8-byte entries, type B */
1265 
1266                 case ACPI_IVRS_TYPE_PAD8:
1267                 case ACPI_IVRS_TYPE_EXT_SELECT:
1268                 case ACPI_IVRS_TYPE_EXT_START:
1269 
1270                     InfoTable = AcpiDmTableInfoIvrs8b;
1271                     break;
1272 
1273                 /* 8-byte entries, type C */
1274 
1275                 case ACPI_IVRS_TYPE_SPECIAL:
1276 
1277                     InfoTable = AcpiDmTableInfoIvrs8c;
1278                     break;
1279 
1280                 default:
1281 
1282                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1283                         "IVRS Device Entry");
1284                     return (AE_ERROR);
1285                 }
1286 
1287                 Status = DtCompileTable (PFieldList, InfoTable,
1288                             &Subtable, TRUE);
1289                 if (ACPI_FAILURE (Status))
1290                 {
1291                     return (Status);
1292                 }
1293 
1294                 DtInsertSubtable (ParentTable, Subtable);
1295             }
1296         }
1297 
1298         DtPopSubtable ();
1299     }
1300 
1301     return (AE_OK);
1302 }
1303 
1304 
1305 /******************************************************************************
1306  *
1307  * FUNCTION:    DtCompileLpit
1308  *
1309  * PARAMETERS:  List                - Current field list pointer
1310  *
1311  * RETURN:      Status
1312  *
1313  * DESCRIPTION: Compile LPIT.
1314  *
1315  *****************************************************************************/
1316 
1317 ACPI_STATUS
1318 DtCompileLpit (
1319     void                    **List)
1320 {
1321     ACPI_STATUS             Status;
1322     DT_SUBTABLE             *Subtable;
1323     DT_SUBTABLE             *ParentTable;
1324     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1325     DT_FIELD                *SubtableStart;
1326     ACPI_DMTABLE_INFO       *InfoTable;
1327     ACPI_LPIT_HEADER        *LpitHeader;
1328 
1329 
1330     /* Note: Main table consists only of the standard ACPI table header */
1331 
1332     while (*PFieldList)
1333     {
1334         SubtableStart = *PFieldList;
1335 
1336         /* LPIT Subtable header */
1337 
1338         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1339                     &Subtable, TRUE);
1340         if (ACPI_FAILURE (Status))
1341         {
1342             return (Status);
1343         }
1344 
1345         ParentTable = DtPeekSubtable ();
1346         DtInsertSubtable (ParentTable, Subtable);
1347         DtPushSubtable (Subtable);
1348 
1349         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1350 
1351         switch (LpitHeader->Type)
1352         {
1353         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1354 
1355             InfoTable = AcpiDmTableInfoLpit0;
1356             break;
1357 
1358         case ACPI_LPIT_TYPE_SIMPLE_IO:
1359 
1360             InfoTable = AcpiDmTableInfoLpit1;
1361             break;
1362 
1363         default:
1364 
1365             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1366             return (AE_ERROR);
1367         }
1368 
1369         /* LPIT Subtable */
1370 
1371         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1372         if (ACPI_FAILURE (Status))
1373         {
1374             return (Status);
1375         }
1376 
1377         ParentTable = DtPeekSubtable ();
1378         DtInsertSubtable (ParentTable, Subtable);
1379         DtPopSubtable ();
1380     }
1381 
1382     return (AE_OK);
1383 }
1384 
1385 
1386 /******************************************************************************
1387  *
1388  * FUNCTION:    DtCompileMadt
1389  *
1390  * PARAMETERS:  List                - Current field list pointer
1391  *
1392  * RETURN:      Status
1393  *
1394  * DESCRIPTION: Compile MADT.
1395  *
1396  *****************************************************************************/
1397 
1398 ACPI_STATUS
1399 DtCompileMadt (
1400     void                    **List)
1401 {
1402     ACPI_STATUS             Status;
1403     DT_SUBTABLE             *Subtable;
1404     DT_SUBTABLE             *ParentTable;
1405     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1406     DT_FIELD                *SubtableStart;
1407     ACPI_SUBTABLE_HEADER    *MadtHeader;
1408     ACPI_DMTABLE_INFO       *InfoTable;
1409 
1410 
1411     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1412                 &Subtable, TRUE);
1413     if (ACPI_FAILURE (Status))
1414     {
1415         return (Status);
1416     }
1417 
1418     ParentTable = DtPeekSubtable ();
1419     DtInsertSubtable (ParentTable, Subtable);
1420 
1421     while (*PFieldList)
1422     {
1423         SubtableStart = *PFieldList;
1424         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1425                     &Subtable, TRUE);
1426         if (ACPI_FAILURE (Status))
1427         {
1428             return (Status);
1429         }
1430 
1431         ParentTable = DtPeekSubtable ();
1432         DtInsertSubtable (ParentTable, Subtable);
1433         DtPushSubtable (Subtable);
1434 
1435         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1436 
1437         switch (MadtHeader->Type)
1438         {
1439         case ACPI_MADT_TYPE_LOCAL_APIC:
1440 
1441             InfoTable = AcpiDmTableInfoMadt0;
1442             break;
1443 
1444         case ACPI_MADT_TYPE_IO_APIC:
1445 
1446             InfoTable = AcpiDmTableInfoMadt1;
1447             break;
1448 
1449         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1450 
1451             InfoTable = AcpiDmTableInfoMadt2;
1452             break;
1453 
1454         case ACPI_MADT_TYPE_NMI_SOURCE:
1455 
1456             InfoTable = AcpiDmTableInfoMadt3;
1457             break;
1458 
1459         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1460 
1461             InfoTable = AcpiDmTableInfoMadt4;
1462             break;
1463 
1464         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1465 
1466             InfoTable = AcpiDmTableInfoMadt5;
1467             break;
1468 
1469         case ACPI_MADT_TYPE_IO_SAPIC:
1470 
1471             InfoTable = AcpiDmTableInfoMadt6;
1472             break;
1473 
1474         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1475 
1476             InfoTable = AcpiDmTableInfoMadt7;
1477             break;
1478 
1479         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1480 
1481             InfoTable = AcpiDmTableInfoMadt8;
1482             break;
1483 
1484         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1485 
1486             InfoTable = AcpiDmTableInfoMadt9;
1487             break;
1488 
1489         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1490 
1491             InfoTable = AcpiDmTableInfoMadt10;
1492             break;
1493 
1494         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1495 
1496             InfoTable = AcpiDmTableInfoMadt11;
1497             break;
1498 
1499         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1500 
1501             InfoTable = AcpiDmTableInfoMadt12;
1502             break;
1503 
1504         default:
1505 
1506             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1507             return (AE_ERROR);
1508         }
1509 
1510         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1511         if (ACPI_FAILURE (Status))
1512         {
1513             return (Status);
1514         }
1515 
1516         ParentTable = DtPeekSubtable ();
1517         DtInsertSubtable (ParentTable, Subtable);
1518         DtPopSubtable ();
1519     }
1520 
1521     return (AE_OK);
1522 }
1523 
1524 
1525 /******************************************************************************
1526  *
1527  * FUNCTION:    DtCompileMcfg
1528  *
1529  * PARAMETERS:  List                - Current field list pointer
1530  *
1531  * RETURN:      Status
1532  *
1533  * DESCRIPTION: Compile MCFG.
1534  *
1535  *****************************************************************************/
1536 
1537 ACPI_STATUS
1538 DtCompileMcfg (
1539     void                    **List)
1540 {
1541     ACPI_STATUS             Status;
1542 
1543 
1544     Status = DtCompileTwoSubtables (List,
1545                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1546     return (Status);
1547 }
1548 
1549 
1550 /******************************************************************************
1551  *
1552  * FUNCTION:    DtCompileMpst
1553  *
1554  * PARAMETERS:  List                - Current field list pointer
1555  *
1556  * RETURN:      Status
1557  *
1558  * DESCRIPTION: Compile MPST.
1559  *
1560  *****************************************************************************/
1561 
1562 ACPI_STATUS
1563 DtCompileMpst (
1564     void                    **List)
1565 {
1566     ACPI_STATUS             Status;
1567     DT_SUBTABLE             *Subtable;
1568     DT_SUBTABLE             *ParentTable;
1569     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1570     ACPI_MPST_CHANNEL       *MpstChannelInfo;
1571     ACPI_MPST_POWER_NODE    *MpstPowerNode;
1572     ACPI_MPST_DATA_HDR      *MpstDataHeader;
1573     UINT16                  SubtableCount;
1574     UINT32                  PowerStateCount;
1575     UINT32                  ComponentCount;
1576 
1577 
1578     /* Main table */
1579 
1580     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1581     if (ACPI_FAILURE (Status))
1582     {
1583         return (Status);
1584     }
1585 
1586     ParentTable = DtPeekSubtable ();
1587     DtInsertSubtable (ParentTable, Subtable);
1588     DtPushSubtable (Subtable);
1589 
1590     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1591     SubtableCount = MpstChannelInfo->PowerNodeCount;
1592 
1593     while (*PFieldList && SubtableCount)
1594     {
1595         /* Subtable: Memory Power Node(s) */
1596 
1597         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1598                     &Subtable, TRUE);
1599         if (ACPI_FAILURE (Status))
1600         {
1601             return (Status);
1602         }
1603 
1604         ParentTable = DtPeekSubtable ();
1605         DtInsertSubtable (ParentTable, Subtable);
1606         DtPushSubtable (Subtable);
1607 
1608         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1609         PowerStateCount = MpstPowerNode->NumPowerStates;
1610         ComponentCount = MpstPowerNode->NumPhysicalComponents;
1611 
1612         ParentTable = DtPeekSubtable ();
1613 
1614         /* Sub-subtables - Memory Power State Structure(s) */
1615 
1616         while (*PFieldList && PowerStateCount)
1617         {
1618             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1619                         &Subtable, TRUE);
1620             if (ACPI_FAILURE (Status))
1621             {
1622                 return (Status);
1623             }
1624 
1625             DtInsertSubtable (ParentTable, Subtable);
1626             PowerStateCount--;
1627         }
1628 
1629         /* Sub-subtables - Physical Component ID Structure(s) */
1630 
1631         while (*PFieldList && ComponentCount)
1632         {
1633             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1634                         &Subtable, TRUE);
1635             if (ACPI_FAILURE (Status))
1636             {
1637                 return (Status);
1638             }
1639 
1640             DtInsertSubtable (ParentTable, Subtable);
1641             ComponentCount--;
1642         }
1643 
1644         SubtableCount--;
1645         DtPopSubtable ();
1646     }
1647 
1648     /* Subtable: Count of Memory Power State Characteristic structures */
1649 
1650     DtPopSubtable ();
1651 
1652     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1653     if (ACPI_FAILURE (Status))
1654     {
1655         return (Status);
1656     }
1657 
1658     ParentTable = DtPeekSubtable ();
1659     DtInsertSubtable (ParentTable, Subtable);
1660     DtPushSubtable (Subtable);
1661 
1662     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1663     SubtableCount = MpstDataHeader->CharacteristicsCount;
1664 
1665     ParentTable = DtPeekSubtable ();
1666 
1667     /* Subtable: Memory Power State Characteristics structure(s) */
1668 
1669     while (*PFieldList && SubtableCount)
1670     {
1671         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1672                     &Subtable, TRUE);
1673         if (ACPI_FAILURE (Status))
1674         {
1675             return (Status);
1676         }
1677 
1678         DtInsertSubtable (ParentTable, Subtable);
1679         SubtableCount--;
1680     }
1681 
1682     DtPopSubtable ();
1683     return (AE_OK);
1684 }
1685 
1686 
1687 /******************************************************************************
1688  *
1689  * FUNCTION:    DtCompileMsct
1690  *
1691  * PARAMETERS:  List                - Current field list pointer
1692  *
1693  * RETURN:      Status
1694  *
1695  * DESCRIPTION: Compile MSCT.
1696  *
1697  *****************************************************************************/
1698 
1699 ACPI_STATUS
1700 DtCompileMsct (
1701     void                    **List)
1702 {
1703     ACPI_STATUS             Status;
1704 
1705 
1706     Status = DtCompileTwoSubtables (List,
1707                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1708     return (Status);
1709 }
1710 
1711 
1712 /******************************************************************************
1713  *
1714  * FUNCTION:    DtCompileMtmr
1715  *
1716  * PARAMETERS:  List                - Current field list pointer
1717  *
1718  * RETURN:      Status
1719  *
1720  * DESCRIPTION: Compile MTMR.
1721  *
1722  *****************************************************************************/
1723 
1724 ACPI_STATUS
1725 DtCompileMtmr (
1726     void                    **List)
1727 {
1728     ACPI_STATUS             Status;
1729 
1730 
1731     Status = DtCompileTwoSubtables (List,
1732                  AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1733     return (Status);
1734 }
1735 
1736 
1737 /******************************************************************************
1738  *
1739  * FUNCTION:    DtCompilePcct
1740  *
1741  * PARAMETERS:  List                - Current field list pointer
1742  *
1743  * RETURN:      Status
1744  *
1745  * DESCRIPTION: Compile PCCT.
1746  *
1747  *****************************************************************************/
1748 
1749 ACPI_STATUS
1750 DtCompilePcct (
1751     void                    **List)
1752 {
1753     ACPI_STATUS             Status;
1754     DT_SUBTABLE             *Subtable;
1755     DT_SUBTABLE             *ParentTable;
1756     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1757     DT_FIELD                *SubtableStart;
1758     ACPI_SUBTABLE_HEADER    *PcctHeader;
1759     ACPI_DMTABLE_INFO       *InfoTable;
1760 
1761 
1762     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1763                 &Subtable, TRUE);
1764     if (ACPI_FAILURE (Status))
1765     {
1766         return (Status);
1767     }
1768 
1769     ParentTable = DtPeekSubtable ();
1770     DtInsertSubtable (ParentTable, Subtable);
1771 
1772     while (*PFieldList)
1773     {
1774         SubtableStart = *PFieldList;
1775         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1776                     &Subtable, TRUE);
1777         if (ACPI_FAILURE (Status))
1778         {
1779             return (Status);
1780         }
1781 
1782         ParentTable = DtPeekSubtable ();
1783         DtInsertSubtable (ParentTable, Subtable);
1784         DtPushSubtable (Subtable);
1785 
1786         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1787 
1788         switch (PcctHeader->Type)
1789         {
1790         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1791 
1792             InfoTable = AcpiDmTableInfoPcct0;
1793             break;
1794 
1795         default:
1796 
1797             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1798             return (AE_ERROR);
1799         }
1800 
1801         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1802         if (ACPI_FAILURE (Status))
1803         {
1804             return (Status);
1805         }
1806 
1807         ParentTable = DtPeekSubtable ();
1808         DtInsertSubtable (ParentTable, Subtable);
1809         DtPopSubtable ();
1810     }
1811 
1812     return (AE_OK);
1813 }
1814 
1815 
1816 /******************************************************************************
1817  *
1818  * FUNCTION:    DtCompilePmtt
1819  *
1820  * PARAMETERS:  List                - Current field list pointer
1821  *
1822  * RETURN:      Status
1823  *
1824  * DESCRIPTION: Compile PMTT.
1825  *
1826  *****************************************************************************/
1827 
1828 ACPI_STATUS
1829 DtCompilePmtt (
1830     void                    **List)
1831 {
1832     ACPI_STATUS             Status;
1833     DT_SUBTABLE             *Subtable;
1834     DT_SUBTABLE             *ParentTable;
1835     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1836     DT_FIELD                *SubtableStart;
1837     ACPI_PMTT_HEADER        *PmttHeader;
1838     ACPI_PMTT_CONTROLLER    *PmttController;
1839     UINT16                  DomainCount;
1840     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1841 
1842 
1843     /* Main table */
1844 
1845     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1846     if (ACPI_FAILURE (Status))
1847     {
1848         return (Status);
1849     }
1850 
1851     ParentTable = DtPeekSubtable ();
1852     DtInsertSubtable (ParentTable, Subtable);
1853     DtPushSubtable (Subtable);
1854 
1855     while (*PFieldList)
1856     {
1857         SubtableStart = *PFieldList;
1858         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
1859                     &Subtable, TRUE);
1860         if (ACPI_FAILURE (Status))
1861         {
1862             return (Status);
1863         }
1864 
1865         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
1866         while (PrevType >= PmttHeader->Type)
1867         {
1868             DtPopSubtable ();
1869 
1870             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
1871             {
1872                 break;
1873             }
1874             PrevType--;
1875         }
1876         PrevType = PmttHeader->Type;
1877 
1878         ParentTable = DtPeekSubtable ();
1879         DtInsertSubtable (ParentTable, Subtable);
1880         DtPushSubtable (Subtable);
1881 
1882         switch (PmttHeader->Type)
1883         {
1884         case ACPI_PMTT_TYPE_SOCKET:
1885 
1886             /* Subtable: Socket Structure */
1887 
1888             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1889                     &Subtable, TRUE);
1890             if (ACPI_FAILURE (Status))
1891             {
1892                 return (Status);
1893             }
1894 
1895             ParentTable = DtPeekSubtable ();
1896             DtInsertSubtable (ParentTable, Subtable);
1897             break;
1898 
1899         case ACPI_PMTT_TYPE_CONTROLLER:
1900 
1901             /* Subtable: Memory Controller Structure */
1902 
1903             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1904                     &Subtable, TRUE);
1905             if (ACPI_FAILURE (Status))
1906             {
1907                 return (Status);
1908             }
1909 
1910             ParentTable = DtPeekSubtable ();
1911             DtInsertSubtable (ParentTable, Subtable);
1912 
1913             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
1914                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
1915             DomainCount = PmttController->DomainCount;
1916 
1917             while (DomainCount)
1918             {
1919                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
1920                     &Subtable, TRUE);
1921                 if (ACPI_FAILURE (Status))
1922                 {
1923                     return (Status);
1924                 }
1925 
1926                 DtInsertSubtable (ParentTable, Subtable);
1927                 DomainCount--;
1928             }
1929             break;
1930 
1931         case ACPI_PMTT_TYPE_DIMM:
1932 
1933             /* Subtable: Physical Component Structure */
1934 
1935             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1936                     &Subtable, TRUE);
1937             if (ACPI_FAILURE (Status))
1938             {
1939                 return (Status);
1940             }
1941 
1942             ParentTable = DtPeekSubtable ();
1943             DtInsertSubtable (ParentTable, Subtable);
1944             break;
1945 
1946         default:
1947 
1948             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1949             return (AE_ERROR);
1950         }
1951     }
1952 
1953     return (Status);
1954 }
1955 
1956 
1957 /******************************************************************************
1958  *
1959  * FUNCTION:    DtCompileRsdt
1960  *
1961  * PARAMETERS:  List                - Current field list pointer
1962  *
1963  * RETURN:      Status
1964  *
1965  * DESCRIPTION: Compile RSDT.
1966  *
1967  *****************************************************************************/
1968 
1969 ACPI_STATUS
1970 DtCompileRsdt (
1971     void                    **List)
1972 {
1973     DT_SUBTABLE             *Subtable;
1974     DT_SUBTABLE             *ParentTable;
1975     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1976     UINT32                  Address;
1977 
1978 
1979     ParentTable = DtPeekSubtable ();
1980 
1981     while (FieldList)
1982     {
1983         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1984 
1985         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1986         DtInsertSubtable (ParentTable, Subtable);
1987         FieldList = FieldList->Next;
1988     }
1989 
1990     return (AE_OK);
1991 }
1992 
1993 
1994 /******************************************************************************
1995  *
1996  * FUNCTION:    DtCompileS3pt
1997  *
1998  * PARAMETERS:  PFieldList          - Current field list pointer
1999  *
2000  * RETURN:      Status
2001  *
2002  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2003  *
2004  *****************************************************************************/
2005 
2006 ACPI_STATUS
2007 DtCompileS3pt (
2008     DT_FIELD                **PFieldList)
2009 {
2010     ACPI_STATUS             Status;
2011     ACPI_S3PT_HEADER        *S3ptHeader;
2012     DT_SUBTABLE             *Subtable;
2013     DT_SUBTABLE             *ParentTable;
2014     ACPI_DMTABLE_INFO       *InfoTable;
2015     DT_FIELD                *SubtableStart;
2016 
2017 
2018     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2019                 &Gbl_RootTable, TRUE);
2020     if (ACPI_FAILURE (Status))
2021     {
2022         return (Status);
2023     }
2024 
2025     DtPushSubtable (Gbl_RootTable);
2026 
2027     while (*PFieldList)
2028     {
2029         SubtableStart = *PFieldList;
2030         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2031                     &Subtable, TRUE);
2032         if (ACPI_FAILURE (Status))
2033         {
2034             return (Status);
2035         }
2036 
2037         ParentTable = DtPeekSubtable ();
2038         DtInsertSubtable (ParentTable, Subtable);
2039         DtPushSubtable (Subtable);
2040 
2041         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2042 
2043         switch (S3ptHeader->Type)
2044         {
2045         case ACPI_S3PT_TYPE_RESUME:
2046 
2047             InfoTable = AcpiDmTableInfoS3pt0;
2048             break;
2049 
2050         case ACPI_S3PT_TYPE_SUSPEND:
2051 
2052             InfoTable = AcpiDmTableInfoS3pt1;
2053             break;
2054 
2055         default:
2056 
2057             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2058             return (AE_ERROR);
2059         }
2060 
2061         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2062         if (ACPI_FAILURE (Status))
2063         {
2064             return (Status);
2065         }
2066 
2067         ParentTable = DtPeekSubtable ();
2068         DtInsertSubtable (ParentTable, Subtable);
2069         DtPopSubtable ();
2070     }
2071 
2072     return (AE_OK);
2073 }
2074 
2075 
2076 /******************************************************************************
2077  *
2078  * FUNCTION:    DtCompileSlic
2079  *
2080  * PARAMETERS:  List                - Current field list pointer
2081  *
2082  * RETURN:      Status
2083  *
2084  * DESCRIPTION: Compile SLIC.
2085  *
2086  *****************************************************************************/
2087 
2088 ACPI_STATUS
2089 DtCompileSlic (
2090     void                    **List)
2091 {
2092     ACPI_STATUS             Status;
2093     DT_SUBTABLE             *Subtable;
2094     DT_SUBTABLE             *ParentTable;
2095     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2096     DT_FIELD                *SubtableStart;
2097     ACPI_SLIC_HEADER        *SlicHeader;
2098     ACPI_DMTABLE_INFO       *InfoTable;
2099 
2100 
2101     while (*PFieldList)
2102     {
2103         SubtableStart = *PFieldList;
2104         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
2105                     &Subtable, TRUE);
2106         if (ACPI_FAILURE (Status))
2107         {
2108             return (Status);
2109         }
2110 
2111         ParentTable = DtPeekSubtable ();
2112         DtInsertSubtable (ParentTable, Subtable);
2113         DtPushSubtable (Subtable);
2114 
2115         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
2116 
2117         switch (SlicHeader->Type)
2118         {
2119         case ACPI_SLIC_TYPE_PUBLIC_KEY:
2120 
2121             InfoTable = AcpiDmTableInfoSlic0;
2122             break;
2123 
2124         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
2125 
2126             InfoTable = AcpiDmTableInfoSlic1;
2127             break;
2128 
2129         default:
2130 
2131             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
2132             return (AE_ERROR);
2133         }
2134 
2135         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2136         if (ACPI_FAILURE (Status))
2137         {
2138             return (Status);
2139         }
2140 
2141         ParentTable = DtPeekSubtable ();
2142         DtInsertSubtable (ParentTable, Subtable);
2143         DtPopSubtable ();
2144     }
2145 
2146     return (AE_OK);
2147 }
2148 
2149 
2150 /******************************************************************************
2151  *
2152  * FUNCTION:    DtCompileSlit
2153  *
2154  * PARAMETERS:  List                - Current field list pointer
2155  *
2156  * RETURN:      Status
2157  *
2158  * DESCRIPTION: Compile SLIT.
2159  *
2160  *****************************************************************************/
2161 
2162 ACPI_STATUS
2163 DtCompileSlit (
2164     void                    **List)
2165 {
2166     ACPI_STATUS             Status;
2167     DT_SUBTABLE             *Subtable;
2168     DT_SUBTABLE             *ParentTable;
2169     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2170     DT_FIELD                *FieldList;
2171     UINT32                  Localities;
2172     UINT8                   *LocalityBuffer;
2173 
2174 
2175     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2176                 &Subtable, TRUE);
2177     if (ACPI_FAILURE (Status))
2178     {
2179         return (Status);
2180     }
2181 
2182     ParentTable = DtPeekSubtable ();
2183     DtInsertSubtable (ParentTable, Subtable);
2184 
2185     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2186     LocalityBuffer = UtLocalCalloc (Localities);
2187 
2188     /* Compile each locality buffer */
2189 
2190     FieldList = *PFieldList;
2191     while (FieldList)
2192     {
2193         DtCompileBuffer (LocalityBuffer,
2194             FieldList->Value, FieldList, Localities);
2195 
2196         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2197         DtInsertSubtable (ParentTable, Subtable);
2198         FieldList = FieldList->Next;
2199     }
2200 
2201     ACPI_FREE (LocalityBuffer);
2202     return (AE_OK);
2203 }
2204 
2205 
2206 /******************************************************************************
2207  *
2208  * FUNCTION:    DtCompileSrat
2209  *
2210  * PARAMETERS:  List                - Current field list pointer
2211  *
2212  * RETURN:      Status
2213  *
2214  * DESCRIPTION: Compile SRAT.
2215  *
2216  *****************************************************************************/
2217 
2218 ACPI_STATUS
2219 DtCompileSrat (
2220     void                    **List)
2221 {
2222     ACPI_STATUS             Status;
2223     DT_SUBTABLE             *Subtable;
2224     DT_SUBTABLE             *ParentTable;
2225     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2226     DT_FIELD                *SubtableStart;
2227     ACPI_SUBTABLE_HEADER    *SratHeader;
2228     ACPI_DMTABLE_INFO       *InfoTable;
2229 
2230 
2231     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2232                 &Subtable, TRUE);
2233     if (ACPI_FAILURE (Status))
2234     {
2235         return (Status);
2236     }
2237 
2238     ParentTable = DtPeekSubtable ();
2239     DtInsertSubtable (ParentTable, Subtable);
2240 
2241     while (*PFieldList)
2242     {
2243         SubtableStart = *PFieldList;
2244         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2245                     &Subtable, TRUE);
2246         if (ACPI_FAILURE (Status))
2247         {
2248             return (Status);
2249         }
2250 
2251         ParentTable = DtPeekSubtable ();
2252         DtInsertSubtable (ParentTable, Subtable);
2253         DtPushSubtable (Subtable);
2254 
2255         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2256 
2257         switch (SratHeader->Type)
2258         {
2259         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2260 
2261             InfoTable = AcpiDmTableInfoSrat0;
2262             break;
2263 
2264         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2265 
2266             InfoTable = AcpiDmTableInfoSrat1;
2267             break;
2268 
2269         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2270 
2271             InfoTable = AcpiDmTableInfoSrat2;
2272             break;
2273 
2274         default:
2275 
2276             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2277             return (AE_ERROR);
2278         }
2279 
2280         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2281         if (ACPI_FAILURE (Status))
2282         {
2283             return (Status);
2284         }
2285 
2286         ParentTable = DtPeekSubtable ();
2287         DtInsertSubtable (ParentTable, Subtable);
2288         DtPopSubtable ();
2289     }
2290 
2291     return (AE_OK);
2292 }
2293 
2294 
2295 /******************************************************************************
2296  *
2297  * FUNCTION:    DtGetGenericTableInfo
2298  *
2299  * PARAMETERS:  Name                - Generic type name
2300  *
2301  * RETURN:      Info entry
2302  *
2303  * DESCRIPTION: Obtain table info for a generic name entry
2304  *
2305  *****************************************************************************/
2306 
2307 ACPI_DMTABLE_INFO *
2308 DtGetGenericTableInfo (
2309     char                    *Name)
2310 {
2311     ACPI_DMTABLE_INFO       *Info;
2312     UINT32                  i;
2313 
2314 
2315     if (!Name)
2316     {
2317         return (NULL);
2318     }
2319 
2320     /* Search info table for name match */
2321 
2322     for (i = 0; ; i++)
2323     {
2324         Info = AcpiDmTableInfoGeneric[i];
2325         if (Info->Opcode == ACPI_DMT_EXIT)
2326         {
2327             Info = NULL;
2328             break;
2329         }
2330 
2331         /* Use caseless compare for generic keywords */
2332 
2333         if (!AcpiUtStricmp (Name, Info->Name))
2334         {
2335             break;
2336         }
2337     }
2338 
2339     return (Info);
2340 }
2341 
2342 
2343 /******************************************************************************
2344  *
2345  * FUNCTION:    DtCompileUefi
2346  *
2347  * PARAMETERS:  List                - Current field list pointer
2348  *
2349  * RETURN:      Status
2350  *
2351  * DESCRIPTION: Compile UEFI.
2352  *
2353  *****************************************************************************/
2354 
2355 ACPI_STATUS
2356 DtCompileUefi (
2357     void                    **List)
2358 {
2359     ACPI_STATUS             Status;
2360     DT_SUBTABLE             *Subtable;
2361     DT_SUBTABLE             *ParentTable;
2362     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2363     UINT16                  *DataOffset;
2364 
2365 
2366     /* Compile the predefined portion of the UEFI table */
2367 
2368     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2369                 &Subtable, TRUE);
2370     if (ACPI_FAILURE (Status))
2371     {
2372         return (Status);
2373     }
2374 
2375     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2376     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2377 
2378     ParentTable = DtPeekSubtable ();
2379     DtInsertSubtable (ParentTable, Subtable);
2380 
2381     /*
2382      * Compile the "generic" portion of the UEFI table. This
2383      * part of the table is not predefined and any of the generic
2384      * operators may be used.
2385      */
2386 
2387     DtCompileGeneric ((void **) PFieldList);
2388 
2389     return (AE_OK);
2390 }
2391 
2392 
2393 /******************************************************************************
2394  *
2395  * FUNCTION:    DtCompileVrtc
2396  *
2397  * PARAMETERS:  List                - Current field list pointer
2398  *
2399  * RETURN:      Status
2400  *
2401  * DESCRIPTION: Compile VRTC.
2402  *
2403  *****************************************************************************/
2404 
2405 ACPI_STATUS
2406 DtCompileVrtc (
2407     void                    **List)
2408 {
2409     ACPI_STATUS             Status;
2410 
2411 
2412     Status = DtCompileTwoSubtables (List,
2413                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2414     return (Status);
2415 }
2416 
2417 
2418 /******************************************************************************
2419  *
2420  * FUNCTION:    DtCompileWdat
2421  *
2422  * PARAMETERS:  List                - Current field list pointer
2423  *
2424  * RETURN:      Status
2425  *
2426  * DESCRIPTION: Compile WDAT.
2427  *
2428  *****************************************************************************/
2429 
2430 ACPI_STATUS
2431 DtCompileWdat (
2432     void                    **List)
2433 {
2434     ACPI_STATUS             Status;
2435 
2436 
2437     Status = DtCompileTwoSubtables (List,
2438                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2439     return (Status);
2440 }
2441 
2442 
2443 /******************************************************************************
2444  *
2445  * FUNCTION:    DtCompileXsdt
2446  *
2447  * PARAMETERS:  List                - Current field list pointer
2448  *
2449  * RETURN:      Status
2450  *
2451  * DESCRIPTION: Compile XSDT.
2452  *
2453  *****************************************************************************/
2454 
2455 ACPI_STATUS
2456 DtCompileXsdt (
2457     void                    **List)
2458 {
2459     DT_SUBTABLE             *Subtable;
2460     DT_SUBTABLE             *ParentTable;
2461     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2462     UINT64                  Address;
2463 
2464     ParentTable = DtPeekSubtable ();
2465 
2466     while (FieldList)
2467     {
2468         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2469 
2470         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2471         DtInsertSubtable (ParentTable, Subtable);
2472         FieldList = FieldList->Next;
2473     }
2474 
2475     return (AE_OK);
2476 }
2477 
2478 
2479 /******************************************************************************
2480  *
2481  * FUNCTION:    DtCompileGeneric
2482  *
2483  * PARAMETERS:  List                - Current field list pointer
2484  *
2485  * RETURN:      Status
2486  *
2487  * DESCRIPTION: Compile generic unknown table.
2488  *
2489  *****************************************************************************/
2490 
2491 ACPI_STATUS
2492 DtCompileGeneric (
2493     void                    **List)
2494 {
2495     ACPI_STATUS             Status;
2496     DT_SUBTABLE             *Subtable;
2497     DT_SUBTABLE             *ParentTable;
2498     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2499     ACPI_DMTABLE_INFO       *Info;
2500 
2501 
2502     ParentTable = DtPeekSubtable ();
2503 
2504     /*
2505      * Compile the "generic" portion of the table. This
2506      * part of the table is not predefined and any of the generic
2507      * operators may be used.
2508      */
2509 
2510     /* Find any and all labels in the entire generic portion */
2511 
2512     DtDetectAllLabels (*PFieldList);
2513 
2514     /* Now we can actually compile the parse tree */
2515 
2516     while (*PFieldList)
2517     {
2518         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2519         if (!Info)
2520         {
2521             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2522                 (*PFieldList)->Name);
2523             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2524                 (*PFieldList), MsgBuffer);
2525 
2526             *PFieldList = (*PFieldList)->Next;
2527             continue;
2528         }
2529 
2530         Status = DtCompileTable (PFieldList, Info,
2531                     &Subtable, TRUE);
2532         if (ACPI_SUCCESS (Status))
2533         {
2534             DtInsertSubtable (ParentTable, Subtable);
2535         }
2536         else
2537         {
2538             *PFieldList = (*PFieldList)->Next;
2539 
2540             if (Status == AE_NOT_FOUND)
2541             {
2542                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2543                     (*PFieldList)->Name);
2544                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2545                     (*PFieldList), MsgBuffer);
2546             }
2547         }
2548     }
2549 
2550     return (AE_OK);
2551 }
2552