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     /* Sub-tables (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:    DtCompileMadt
1308  *
1309  * PARAMETERS:  List                - Current field list pointer
1310  *
1311  * RETURN:      Status
1312  *
1313  * DESCRIPTION: Compile MADT.
1314  *
1315  *****************************************************************************/
1316 
1317 ACPI_STATUS
1318 DtCompileMadt (
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_SUBTABLE_HEADER    *MadtHeader;
1327     ACPI_DMTABLE_INFO       *InfoTable;
1328 
1329 
1330     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1331                 &Subtable, TRUE);
1332     if (ACPI_FAILURE (Status))
1333     {
1334         return (Status);
1335     }
1336 
1337     ParentTable = DtPeekSubtable ();
1338     DtInsertSubtable (ParentTable, Subtable);
1339 
1340     while (*PFieldList)
1341     {
1342         SubtableStart = *PFieldList;
1343         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1344                     &Subtable, TRUE);
1345         if (ACPI_FAILURE (Status))
1346         {
1347             return (Status);
1348         }
1349 
1350         ParentTable = DtPeekSubtable ();
1351         DtInsertSubtable (ParentTable, Subtable);
1352         DtPushSubtable (Subtable);
1353 
1354         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1355 
1356         switch (MadtHeader->Type)
1357         {
1358         case ACPI_MADT_TYPE_LOCAL_APIC:
1359 
1360             InfoTable = AcpiDmTableInfoMadt0;
1361             break;
1362 
1363         case ACPI_MADT_TYPE_IO_APIC:
1364 
1365             InfoTable = AcpiDmTableInfoMadt1;
1366             break;
1367 
1368         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1369 
1370             InfoTable = AcpiDmTableInfoMadt2;
1371             break;
1372 
1373         case ACPI_MADT_TYPE_NMI_SOURCE:
1374 
1375             InfoTable = AcpiDmTableInfoMadt3;
1376             break;
1377 
1378         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1379 
1380             InfoTable = AcpiDmTableInfoMadt4;
1381             break;
1382 
1383         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1384 
1385             InfoTable = AcpiDmTableInfoMadt5;
1386             break;
1387 
1388         case ACPI_MADT_TYPE_IO_SAPIC:
1389 
1390             InfoTable = AcpiDmTableInfoMadt6;
1391             break;
1392 
1393         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1394 
1395             InfoTable = AcpiDmTableInfoMadt7;
1396             break;
1397 
1398         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1399 
1400             InfoTable = AcpiDmTableInfoMadt8;
1401             break;
1402 
1403         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1404 
1405             InfoTable = AcpiDmTableInfoMadt9;
1406             break;
1407 
1408         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1409 
1410             InfoTable = AcpiDmTableInfoMadt10;
1411             break;
1412 
1413         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1414 
1415             InfoTable = AcpiDmTableInfoMadt11;
1416             break;
1417 
1418         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1419 
1420             InfoTable = AcpiDmTableInfoMadt12;
1421             break;
1422 
1423         default:
1424 
1425             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1426             return (AE_ERROR);
1427         }
1428 
1429         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1430         if (ACPI_FAILURE (Status))
1431         {
1432             return (Status);
1433         }
1434 
1435         ParentTable = DtPeekSubtable ();
1436         DtInsertSubtable (ParentTable, Subtable);
1437         DtPopSubtable ();
1438     }
1439 
1440     return (AE_OK);
1441 }
1442 
1443 
1444 /******************************************************************************
1445  *
1446  * FUNCTION:    DtCompileMcfg
1447  *
1448  * PARAMETERS:  List                - Current field list pointer
1449  *
1450  * RETURN:      Status
1451  *
1452  * DESCRIPTION: Compile MCFG.
1453  *
1454  *****************************************************************************/
1455 
1456 ACPI_STATUS
1457 DtCompileMcfg (
1458     void                    **List)
1459 {
1460     ACPI_STATUS             Status;
1461 
1462 
1463     Status = DtCompileTwoSubtables (List,
1464                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1465     return (Status);
1466 }
1467 
1468 
1469 /******************************************************************************
1470  *
1471  * FUNCTION:    DtCompileMpst
1472  *
1473  * PARAMETERS:  List                - Current field list pointer
1474  *
1475  * RETURN:      Status
1476  *
1477  * DESCRIPTION: Compile MPST.
1478  *
1479  *****************************************************************************/
1480 
1481 ACPI_STATUS
1482 DtCompileMpst (
1483     void                    **List)
1484 {
1485     ACPI_STATUS             Status;
1486     DT_SUBTABLE             *Subtable;
1487     DT_SUBTABLE             *ParentTable;
1488     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1489     ACPI_MPST_CHANNEL       *MpstChannelInfo;
1490     ACPI_MPST_POWER_NODE    *MpstPowerNode;
1491     ACPI_MPST_DATA_HDR      *MpstDataHeader;
1492     UINT16                  SubtableCount;
1493     UINT32                  PowerStateCount;
1494     UINT32                  ComponentCount;
1495 
1496 
1497     /* Main table */
1498 
1499     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1500     if (ACPI_FAILURE (Status))
1501     {
1502         return (Status);
1503     }
1504 
1505     ParentTable = DtPeekSubtable ();
1506     DtInsertSubtable (ParentTable, Subtable);
1507     DtPushSubtable (Subtable);
1508 
1509     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1510     SubtableCount = MpstChannelInfo->PowerNodeCount;
1511 
1512     while (*PFieldList && SubtableCount)
1513     {
1514         /* Subtable: Memory Power Node(s) */
1515 
1516         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1517                     &Subtable, TRUE);
1518         if (ACPI_FAILURE (Status))
1519         {
1520             return (Status);
1521         }
1522 
1523         ParentTable = DtPeekSubtable ();
1524         DtInsertSubtable (ParentTable, Subtable);
1525         DtPushSubtable (Subtable);
1526 
1527         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1528         PowerStateCount = MpstPowerNode->NumPowerStates;
1529         ComponentCount = MpstPowerNode->NumPhysicalComponents;
1530 
1531         ParentTable = DtPeekSubtable ();
1532 
1533         /* Sub-subtables - Memory Power State Structure(s) */
1534 
1535         while (*PFieldList && PowerStateCount)
1536         {
1537             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1538                         &Subtable, TRUE);
1539             if (ACPI_FAILURE (Status))
1540             {
1541                 return (Status);
1542             }
1543 
1544             DtInsertSubtable (ParentTable, Subtable);
1545             PowerStateCount--;
1546         }
1547 
1548         /* Sub-subtables - Physical Component ID Structure(s) */
1549 
1550         while (*PFieldList && ComponentCount)
1551         {
1552             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1553                         &Subtable, TRUE);
1554             if (ACPI_FAILURE (Status))
1555             {
1556                 return (Status);
1557             }
1558 
1559             DtInsertSubtable (ParentTable, Subtable);
1560             ComponentCount--;
1561         }
1562 
1563         SubtableCount--;
1564         DtPopSubtable ();
1565     }
1566 
1567     /* Subtable: Count of Memory Power State Characteristic structures */
1568 
1569     DtPopSubtable ();
1570 
1571     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1572     if (ACPI_FAILURE (Status))
1573     {
1574         return (Status);
1575     }
1576 
1577     ParentTable = DtPeekSubtable ();
1578     DtInsertSubtable (ParentTable, Subtable);
1579     DtPushSubtable (Subtable);
1580 
1581     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1582     SubtableCount = MpstDataHeader->CharacteristicsCount;
1583 
1584     ParentTable = DtPeekSubtable ();
1585 
1586     /* Subtable: Memory Power State Characteristics structure(s) */
1587 
1588     while (*PFieldList && SubtableCount)
1589     {
1590         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1591                     &Subtable, TRUE);
1592         if (ACPI_FAILURE (Status))
1593         {
1594             return (Status);
1595         }
1596 
1597         DtInsertSubtable (ParentTable, Subtable);
1598         SubtableCount--;
1599     }
1600 
1601     DtPopSubtable ();
1602     return (AE_OK);
1603 }
1604 
1605 
1606 /******************************************************************************
1607  *
1608  * FUNCTION:    DtCompileMsct
1609  *
1610  * PARAMETERS:  List                - Current field list pointer
1611  *
1612  * RETURN:      Status
1613  *
1614  * DESCRIPTION: Compile MSCT.
1615  *
1616  *****************************************************************************/
1617 
1618 ACPI_STATUS
1619 DtCompileMsct (
1620     void                    **List)
1621 {
1622     ACPI_STATUS             Status;
1623 
1624 
1625     Status = DtCompileTwoSubtables (List,
1626                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1627     return (Status);
1628 }
1629 
1630 
1631 /******************************************************************************
1632  *
1633  * FUNCTION:    DtCompileMtmr
1634  *
1635  * PARAMETERS:  List                - Current field list pointer
1636  *
1637  * RETURN:      Status
1638  *
1639  * DESCRIPTION: Compile MTMR.
1640  *
1641  *****************************************************************************/
1642 
1643 ACPI_STATUS
1644 DtCompileMtmr (
1645     void                    **List)
1646 {
1647     ACPI_STATUS             Status;
1648 
1649 
1650     Status = DtCompileTwoSubtables (List,
1651                  AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1652     return (Status);
1653 }
1654 
1655 
1656 /******************************************************************************
1657  *
1658  * FUNCTION:    DtCompilePcct
1659  *
1660  * PARAMETERS:  List                - Current field list pointer
1661  *
1662  * RETURN:      Status
1663  *
1664  * DESCRIPTION: Compile PCCT.
1665  *
1666  *****************************************************************************/
1667 
1668 ACPI_STATUS
1669 DtCompilePcct (
1670     void                    **List)
1671 {
1672     ACPI_STATUS             Status;
1673     DT_SUBTABLE             *Subtable;
1674     DT_SUBTABLE             *ParentTable;
1675     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1676     DT_FIELD                *SubtableStart;
1677     ACPI_SUBTABLE_HEADER    *PcctHeader;
1678     ACPI_DMTABLE_INFO       *InfoTable;
1679 
1680 
1681     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1682                 &Subtable, TRUE);
1683     if (ACPI_FAILURE (Status))
1684     {
1685         return (Status);
1686     }
1687 
1688     ParentTable = DtPeekSubtable ();
1689     DtInsertSubtable (ParentTable, Subtable);
1690 
1691     while (*PFieldList)
1692     {
1693         SubtableStart = *PFieldList;
1694         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1695                     &Subtable, TRUE);
1696         if (ACPI_FAILURE (Status))
1697         {
1698             return (Status);
1699         }
1700 
1701         ParentTable = DtPeekSubtable ();
1702         DtInsertSubtable (ParentTable, Subtable);
1703         DtPushSubtable (Subtable);
1704 
1705         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1706 
1707         switch (PcctHeader->Type)
1708         {
1709         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1710 
1711             InfoTable = AcpiDmTableInfoPcct0;
1712             break;
1713 
1714         default:
1715 
1716             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1717             return (AE_ERROR);
1718         }
1719 
1720         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1721         if (ACPI_FAILURE (Status))
1722         {
1723             return (Status);
1724         }
1725 
1726         ParentTable = DtPeekSubtable ();
1727         DtInsertSubtable (ParentTable, Subtable);
1728         DtPopSubtable ();
1729     }
1730 
1731     return (AE_OK);
1732 }
1733 
1734 
1735 /******************************************************************************
1736  *
1737  * FUNCTION:    DtCompilePmtt
1738  *
1739  * PARAMETERS:  List                - Current field list pointer
1740  *
1741  * RETURN:      Status
1742  *
1743  * DESCRIPTION: Compile PMTT.
1744  *
1745  *****************************************************************************/
1746 
1747 ACPI_STATUS
1748 DtCompilePmtt (
1749     void                    **List)
1750 {
1751     ACPI_STATUS             Status;
1752     DT_SUBTABLE             *Subtable;
1753     DT_SUBTABLE             *ParentTable;
1754     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1755     DT_FIELD                *SubtableStart;
1756     ACPI_PMTT_HEADER        *PmttHeader;
1757     ACPI_PMTT_CONTROLLER    *PmttController;
1758     UINT16                  DomainCount;
1759     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1760 
1761 
1762     /* Main table */
1763 
1764     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1765     if (ACPI_FAILURE (Status))
1766     {
1767         return (Status);
1768     }
1769 
1770     ParentTable = DtPeekSubtable ();
1771     DtInsertSubtable (ParentTable, Subtable);
1772     DtPushSubtable (Subtable);
1773 
1774     while (*PFieldList)
1775     {
1776         SubtableStart = *PFieldList;
1777         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
1778                     &Subtable, TRUE);
1779         if (ACPI_FAILURE (Status))
1780         {
1781             return (Status);
1782         }
1783 
1784         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
1785         while (PrevType >= PmttHeader->Type)
1786         {
1787             DtPopSubtable ();
1788 
1789             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
1790             {
1791                 break;
1792             }
1793             PrevType--;
1794         }
1795         PrevType = PmttHeader->Type;
1796 
1797         ParentTable = DtPeekSubtable ();
1798         DtInsertSubtable (ParentTable, Subtable);
1799         DtPushSubtable (Subtable);
1800 
1801         switch (PmttHeader->Type)
1802         {
1803         case ACPI_PMTT_TYPE_SOCKET:
1804 
1805             /* Subtable: Socket Structure */
1806 
1807             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1808                     &Subtable, TRUE);
1809             if (ACPI_FAILURE (Status))
1810             {
1811                 return (Status);
1812             }
1813 
1814             ParentTable = DtPeekSubtable ();
1815             DtInsertSubtable (ParentTable, Subtable);
1816             break;
1817 
1818         case ACPI_PMTT_TYPE_CONTROLLER:
1819 
1820             /* Subtable: Memory Controller Structure */
1821 
1822             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1823                     &Subtable, TRUE);
1824             if (ACPI_FAILURE (Status))
1825             {
1826                 return (Status);
1827             }
1828 
1829             ParentTable = DtPeekSubtable ();
1830             DtInsertSubtable (ParentTable, Subtable);
1831 
1832             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
1833                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
1834             DomainCount = PmttController->DomainCount;
1835 
1836             while (DomainCount)
1837             {
1838                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
1839                     &Subtable, TRUE);
1840                 if (ACPI_FAILURE (Status))
1841                 {
1842                     return (Status);
1843                 }
1844 
1845                 DtInsertSubtable (ParentTable, Subtable);
1846                 DomainCount--;
1847             }
1848             break;
1849 
1850         case ACPI_PMTT_TYPE_DIMM:
1851 
1852             /* Subtable: Physical Component Structure */
1853 
1854             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1855                     &Subtable, TRUE);
1856             if (ACPI_FAILURE (Status))
1857             {
1858                 return (Status);
1859             }
1860 
1861             ParentTable = DtPeekSubtable ();
1862             DtInsertSubtable (ParentTable, Subtable);
1863             break;
1864 
1865         default:
1866 
1867             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1868             return (AE_ERROR);
1869         }
1870     }
1871 
1872     return (Status);
1873 }
1874 
1875 
1876 /******************************************************************************
1877  *
1878  * FUNCTION:    DtCompileRsdt
1879  *
1880  * PARAMETERS:  List                - Current field list pointer
1881  *
1882  * RETURN:      Status
1883  *
1884  * DESCRIPTION: Compile RSDT.
1885  *
1886  *****************************************************************************/
1887 
1888 ACPI_STATUS
1889 DtCompileRsdt (
1890     void                    **List)
1891 {
1892     DT_SUBTABLE             *Subtable;
1893     DT_SUBTABLE             *ParentTable;
1894     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1895     UINT32                  Address;
1896 
1897 
1898     ParentTable = DtPeekSubtable ();
1899 
1900     while (FieldList)
1901     {
1902         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1903 
1904         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1905         DtInsertSubtable (ParentTable, Subtable);
1906         FieldList = FieldList->Next;
1907     }
1908 
1909     return (AE_OK);
1910 }
1911 
1912 
1913 /******************************************************************************
1914  *
1915  * FUNCTION:    DtCompileS3pt
1916  *
1917  * PARAMETERS:  PFieldList          - Current field list pointer
1918  *
1919  * RETURN:      Status
1920  *
1921  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1922  *
1923  *****************************************************************************/
1924 
1925 ACPI_STATUS
1926 DtCompileS3pt (
1927     DT_FIELD                **PFieldList)
1928 {
1929     ACPI_STATUS             Status;
1930     ACPI_S3PT_HEADER        *S3ptHeader;
1931     DT_SUBTABLE             *Subtable;
1932     DT_SUBTABLE             *ParentTable;
1933     ACPI_DMTABLE_INFO       *InfoTable;
1934     DT_FIELD                *SubtableStart;
1935 
1936 
1937     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1938                 &Gbl_RootTable, TRUE);
1939     if (ACPI_FAILURE (Status))
1940     {
1941         return (Status);
1942     }
1943 
1944     DtPushSubtable (Gbl_RootTable);
1945 
1946     while (*PFieldList)
1947     {
1948         SubtableStart = *PFieldList;
1949         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1950                     &Subtable, TRUE);
1951         if (ACPI_FAILURE (Status))
1952         {
1953             return (Status);
1954         }
1955 
1956         ParentTable = DtPeekSubtable ();
1957         DtInsertSubtable (ParentTable, Subtable);
1958         DtPushSubtable (Subtable);
1959 
1960         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
1961 
1962         switch (S3ptHeader->Type)
1963         {
1964         case ACPI_S3PT_TYPE_RESUME:
1965 
1966             InfoTable = AcpiDmTableInfoS3pt0;
1967             break;
1968 
1969         case ACPI_S3PT_TYPE_SUSPEND:
1970 
1971             InfoTable = AcpiDmTableInfoS3pt1;
1972             break;
1973 
1974         default:
1975 
1976             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1977             return (AE_ERROR);
1978         }
1979 
1980         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1981         if (ACPI_FAILURE (Status))
1982         {
1983             return (Status);
1984         }
1985 
1986         ParentTable = DtPeekSubtable ();
1987         DtInsertSubtable (ParentTable, Subtable);
1988         DtPopSubtable ();
1989     }
1990 
1991     return (AE_OK);
1992 }
1993 
1994 
1995 /******************************************************************************
1996  *
1997  * FUNCTION:    DtCompileSlic
1998  *
1999  * PARAMETERS:  List                - Current field list pointer
2000  *
2001  * RETURN:      Status
2002  *
2003  * DESCRIPTION: Compile SLIC.
2004  *
2005  *****************************************************************************/
2006 
2007 ACPI_STATUS
2008 DtCompileSlic (
2009     void                    **List)
2010 {
2011     ACPI_STATUS             Status;
2012     DT_SUBTABLE             *Subtable;
2013     DT_SUBTABLE             *ParentTable;
2014     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2015     DT_FIELD                *SubtableStart;
2016     ACPI_SLIC_HEADER        *SlicHeader;
2017     ACPI_DMTABLE_INFO       *InfoTable;
2018 
2019 
2020     while (*PFieldList)
2021     {
2022         SubtableStart = *PFieldList;
2023         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
2024                     &Subtable, TRUE);
2025         if (ACPI_FAILURE (Status))
2026         {
2027             return (Status);
2028         }
2029 
2030         ParentTable = DtPeekSubtable ();
2031         DtInsertSubtable (ParentTable, Subtable);
2032         DtPushSubtable (Subtable);
2033 
2034         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
2035 
2036         switch (SlicHeader->Type)
2037         {
2038         case ACPI_SLIC_TYPE_PUBLIC_KEY:
2039 
2040             InfoTable = AcpiDmTableInfoSlic0;
2041             break;
2042 
2043         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
2044 
2045             InfoTable = AcpiDmTableInfoSlic1;
2046             break;
2047 
2048         default:
2049 
2050             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
2051             return (AE_ERROR);
2052         }
2053 
2054         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2055         if (ACPI_FAILURE (Status))
2056         {
2057             return (Status);
2058         }
2059 
2060         ParentTable = DtPeekSubtable ();
2061         DtInsertSubtable (ParentTable, Subtable);
2062         DtPopSubtable ();
2063     }
2064 
2065     return (AE_OK);
2066 }
2067 
2068 
2069 /******************************************************************************
2070  *
2071  * FUNCTION:    DtCompileSlit
2072  *
2073  * PARAMETERS:  List                - Current field list pointer
2074  *
2075  * RETURN:      Status
2076  *
2077  * DESCRIPTION: Compile SLIT.
2078  *
2079  *****************************************************************************/
2080 
2081 ACPI_STATUS
2082 DtCompileSlit (
2083     void                    **List)
2084 {
2085     ACPI_STATUS             Status;
2086     DT_SUBTABLE             *Subtable;
2087     DT_SUBTABLE             *ParentTable;
2088     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2089     DT_FIELD                *FieldList;
2090     UINT32                  Localities;
2091     UINT8                   *LocalityBuffer;
2092 
2093 
2094     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2095                 &Subtable, TRUE);
2096     if (ACPI_FAILURE (Status))
2097     {
2098         return (Status);
2099     }
2100 
2101     ParentTable = DtPeekSubtable ();
2102     DtInsertSubtable (ParentTable, Subtable);
2103 
2104     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2105     LocalityBuffer = UtLocalCalloc (Localities);
2106 
2107     /* Compile each locality buffer */
2108 
2109     FieldList = *PFieldList;
2110     while (FieldList)
2111     {
2112         DtCompileBuffer (LocalityBuffer,
2113             FieldList->Value, FieldList, Localities);
2114 
2115         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2116         DtInsertSubtable (ParentTable, Subtable);
2117         FieldList = FieldList->Next;
2118     }
2119 
2120     ACPI_FREE (LocalityBuffer);
2121     return (AE_OK);
2122 }
2123 
2124 
2125 /******************************************************************************
2126  *
2127  * FUNCTION:    DtCompileSrat
2128  *
2129  * PARAMETERS:  List                - Current field list pointer
2130  *
2131  * RETURN:      Status
2132  *
2133  * DESCRIPTION: Compile SRAT.
2134  *
2135  *****************************************************************************/
2136 
2137 ACPI_STATUS
2138 DtCompileSrat (
2139     void                    **List)
2140 {
2141     ACPI_STATUS             Status;
2142     DT_SUBTABLE             *Subtable;
2143     DT_SUBTABLE             *ParentTable;
2144     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2145     DT_FIELD                *SubtableStart;
2146     ACPI_SUBTABLE_HEADER    *SratHeader;
2147     ACPI_DMTABLE_INFO       *InfoTable;
2148 
2149 
2150     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2151                 &Subtable, TRUE);
2152     if (ACPI_FAILURE (Status))
2153     {
2154         return (Status);
2155     }
2156 
2157     ParentTable = DtPeekSubtable ();
2158     DtInsertSubtable (ParentTable, Subtable);
2159 
2160     while (*PFieldList)
2161     {
2162         SubtableStart = *PFieldList;
2163         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2164                     &Subtable, TRUE);
2165         if (ACPI_FAILURE (Status))
2166         {
2167             return (Status);
2168         }
2169 
2170         ParentTable = DtPeekSubtable ();
2171         DtInsertSubtable (ParentTable, Subtable);
2172         DtPushSubtable (Subtable);
2173 
2174         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2175 
2176         switch (SratHeader->Type)
2177         {
2178         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2179 
2180             InfoTable = AcpiDmTableInfoSrat0;
2181             break;
2182 
2183         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2184 
2185             InfoTable = AcpiDmTableInfoSrat1;
2186             break;
2187 
2188         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2189 
2190             InfoTable = AcpiDmTableInfoSrat2;
2191             break;
2192 
2193         default:
2194 
2195             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2196             return (AE_ERROR);
2197         }
2198 
2199         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2200         if (ACPI_FAILURE (Status))
2201         {
2202             return (Status);
2203         }
2204 
2205         ParentTable = DtPeekSubtable ();
2206         DtInsertSubtable (ParentTable, Subtable);
2207         DtPopSubtable ();
2208     }
2209 
2210     return (AE_OK);
2211 }
2212 
2213 
2214 /******************************************************************************
2215  *
2216  * FUNCTION:    DtGetGenericTableInfo
2217  *
2218  * PARAMETERS:  Name                - Generic type name
2219  *
2220  * RETURN:      Info entry
2221  *
2222  * DESCRIPTION: Obtain table info for a generic name entry
2223  *
2224  *****************************************************************************/
2225 
2226 ACPI_DMTABLE_INFO *
2227 DtGetGenericTableInfo (
2228     char                    *Name)
2229 {
2230     ACPI_DMTABLE_INFO       *Info;
2231     UINT32                  i;
2232 
2233 
2234     if (!Name)
2235     {
2236         return (NULL);
2237     }
2238 
2239     /* Search info table for name match */
2240 
2241     for (i = 0; ; i++)
2242     {
2243         Info = AcpiDmTableInfoGeneric[i];
2244         if (Info->Opcode == ACPI_DMT_EXIT)
2245         {
2246             Info = NULL;
2247             break;
2248         }
2249 
2250         /* Use caseless compare for generic keywords */
2251 
2252         if (!AcpiUtStricmp (Name, Info->Name))
2253         {
2254             break;
2255         }
2256     }
2257 
2258     return (Info);
2259 }
2260 
2261 
2262 /******************************************************************************
2263  *
2264  * FUNCTION:    DtCompileUefi
2265  *
2266  * PARAMETERS:  List                - Current field list pointer
2267  *
2268  * RETURN:      Status
2269  *
2270  * DESCRIPTION: Compile UEFI.
2271  *
2272  *****************************************************************************/
2273 
2274 ACPI_STATUS
2275 DtCompileUefi (
2276     void                    **List)
2277 {
2278     ACPI_STATUS             Status;
2279     DT_SUBTABLE             *Subtable;
2280     DT_SUBTABLE             *ParentTable;
2281     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2282     UINT16                  *DataOffset;
2283 
2284 
2285     /* Compile the predefined portion of the UEFI table */
2286 
2287     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2288                 &Subtable, TRUE);
2289     if (ACPI_FAILURE (Status))
2290     {
2291         return (Status);
2292     }
2293 
2294     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2295     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2296 
2297     ParentTable = DtPeekSubtable ();
2298     DtInsertSubtable (ParentTable, Subtable);
2299 
2300     /*
2301      * Compile the "generic" portion of the UEFI table. This
2302      * part of the table is not predefined and any of the generic
2303      * operators may be used.
2304      */
2305 
2306     DtCompileGeneric ((void **) PFieldList);
2307 
2308     return (AE_OK);
2309 }
2310 
2311 
2312 /******************************************************************************
2313  *
2314  * FUNCTION:    DtCompileVrtc
2315  *
2316  * PARAMETERS:  List                - Current field list pointer
2317  *
2318  * RETURN:      Status
2319  *
2320  * DESCRIPTION: Compile VRTC.
2321  *
2322  *****************************************************************************/
2323 
2324 ACPI_STATUS
2325 DtCompileVrtc (
2326     void                    **List)
2327 {
2328     ACPI_STATUS             Status;
2329 
2330 
2331     Status = DtCompileTwoSubtables (List,
2332                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2333     return (Status);
2334 }
2335 
2336 
2337 /******************************************************************************
2338  *
2339  * FUNCTION:    DtCompileWdat
2340  *
2341  * PARAMETERS:  List                - Current field list pointer
2342  *
2343  * RETURN:      Status
2344  *
2345  * DESCRIPTION: Compile WDAT.
2346  *
2347  *****************************************************************************/
2348 
2349 ACPI_STATUS
2350 DtCompileWdat (
2351     void                    **List)
2352 {
2353     ACPI_STATUS             Status;
2354 
2355 
2356     Status = DtCompileTwoSubtables (List,
2357                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2358     return (Status);
2359 }
2360 
2361 
2362 /******************************************************************************
2363  *
2364  * FUNCTION:    DtCompileXsdt
2365  *
2366  * PARAMETERS:  List                - Current field list pointer
2367  *
2368  * RETURN:      Status
2369  *
2370  * DESCRIPTION: Compile XSDT.
2371  *
2372  *****************************************************************************/
2373 
2374 ACPI_STATUS
2375 DtCompileXsdt (
2376     void                    **List)
2377 {
2378     DT_SUBTABLE             *Subtable;
2379     DT_SUBTABLE             *ParentTable;
2380     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2381     UINT64                  Address;
2382 
2383     ParentTable = DtPeekSubtable ();
2384 
2385     while (FieldList)
2386     {
2387         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2388 
2389         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2390         DtInsertSubtable (ParentTable, Subtable);
2391         FieldList = FieldList->Next;
2392     }
2393 
2394     return (AE_OK);
2395 }
2396 
2397 
2398 /******************************************************************************
2399  *
2400  * FUNCTION:    DtCompileGeneric
2401  *
2402  * PARAMETERS:  List                - Current field list pointer
2403  *
2404  * RETURN:      Status
2405  *
2406  * DESCRIPTION: Compile generic unknown table.
2407  *
2408  *****************************************************************************/
2409 
2410 ACPI_STATUS
2411 DtCompileGeneric (
2412     void                    **List)
2413 {
2414     ACPI_STATUS             Status;
2415     DT_SUBTABLE             *Subtable;
2416     DT_SUBTABLE             *ParentTable;
2417     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2418     ACPI_DMTABLE_INFO       *Info;
2419 
2420 
2421     ParentTable = DtPeekSubtable ();
2422 
2423     /*
2424      * Compile the "generic" portion of the table. This
2425      * part of the table is not predefined and any of the generic
2426      * operators may be used.
2427      */
2428 
2429     /* Find any and all labels in the entire generic portion */
2430 
2431     DtDetectAllLabels (*PFieldList);
2432 
2433     /* Now we can actually compile the parse tree */
2434 
2435     while (*PFieldList)
2436     {
2437         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2438         if (!Info)
2439         {
2440             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2441                 (*PFieldList)->Name);
2442             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2443                 (*PFieldList), MsgBuffer);
2444 
2445             *PFieldList = (*PFieldList)->Next;
2446             continue;
2447         }
2448 
2449         Status = DtCompileTable (PFieldList, Info,
2450                     &Subtable, TRUE);
2451         if (ACPI_SUCCESS (Status))
2452         {
2453             DtInsertSubtable (ParentTable, Subtable);
2454         }
2455         else
2456         {
2457             *PFieldList = (*PFieldList)->Next;
2458 
2459             if (Status == AE_NOT_FOUND)
2460             {
2461                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2462                     (*PFieldList)->Name);
2463                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2464                     (*PFieldList), MsgBuffer);
2465             }
2466         }
2467     }
2468 
2469     return (AE_OK);
2470 }
2471