xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable.c (revision 11c5cac53f6cc9a2d94cb6f58728b2655e92d3a5)
1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
49 #include <contrib/dev/acpica/compiler/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             InfoTable = AcpiDmTableInfoAsf0;
284             break;
285 
286         case ACPI_ASF_TYPE_ALERT:
287             InfoTable = AcpiDmTableInfoAsf1;
288             break;
289 
290         case ACPI_ASF_TYPE_CONTROL:
291             InfoTable = AcpiDmTableInfoAsf2;
292             break;
293 
294         case ACPI_ASF_TYPE_BOOT:
295             InfoTable = AcpiDmTableInfoAsf3;
296             break;
297 
298         case ACPI_ASF_TYPE_ADDRESS:
299             InfoTable = AcpiDmTableInfoAsf4;
300             break;
301 
302         default:
303             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
304             return (AE_ERROR);
305         }
306 
307         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
308         if (ACPI_FAILURE (Status))
309         {
310             return (Status);
311         }
312 
313         ParentTable = DtPeekSubtable ();
314         DtInsertSubtable (ParentTable, Subtable);
315 
316         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
317         {
318         case ACPI_ASF_TYPE_INFO:
319             DataInfoTable = NULL;
320             break;
321 
322         case ACPI_ASF_TYPE_ALERT:
323             DataInfoTable = AcpiDmTableInfoAsf1a;
324             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
325                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
326                             sizeof (ACPI_ASF_HEADER)))->Alerts;
327             break;
328 
329         case ACPI_ASF_TYPE_CONTROL:
330             DataInfoTable = AcpiDmTableInfoAsf2a;
331             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
332                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
333                             sizeof (ACPI_ASF_HEADER)))->Controls;
334             break;
335 
336         case ACPI_ASF_TYPE_BOOT:
337             DataInfoTable = NULL;
338             break;
339 
340         case ACPI_ASF_TYPE_ADDRESS:
341             DataInfoTable = TableInfoAsfAddress;
342             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
343                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
344                             sizeof (ACPI_ASF_HEADER)))->Devices;
345             break;
346 
347         default:
348             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
349             return (AE_ERROR);
350         }
351 
352         if (DataInfoTable)
353         {
354             switch (AsfTable->Header.Type & 0x7F)
355             {
356             case ACPI_ASF_TYPE_ADDRESS:
357 
358                 while (DataCount > 0)
359                 {
360                     Status = DtCompileTable (PFieldList, DataInfoTable,
361                                 &Subtable, TRUE);
362                     if (ACPI_FAILURE (Status))
363                     {
364                         return (Status);
365                     }
366 
367                     DtInsertSubtable (ParentTable, Subtable);
368                     DataCount = DataCount - Subtable->Length;
369                 }
370                 break;
371 
372             default:
373 
374                 for (i = 0; i < DataCount; i++)
375                 {
376                     Status = DtCompileTable (PFieldList, DataInfoTable,
377                                 &Subtable, TRUE);
378                     if (ACPI_FAILURE (Status))
379                     {
380                         return (Status);
381                     }
382 
383                     DtInsertSubtable (ParentTable, Subtable);
384                 }
385                 break;
386             }
387         }
388 
389         DtPopSubtable ();
390     }
391 
392     return (AE_OK);
393 }
394 
395 
396 /******************************************************************************
397  *
398  * FUNCTION:    DtCompileCpep
399  *
400  * PARAMETERS:  List                - Current field list pointer
401  *
402  * RETURN:      Status
403  *
404  * DESCRIPTION: Compile CPEP.
405  *
406  *****************************************************************************/
407 
408 ACPI_STATUS
409 DtCompileCpep (
410     void                    **List)
411 {
412     ACPI_STATUS             Status;
413 
414 
415     Status = DtCompileTwoSubtables (List,
416                  AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
417     return (Status);
418 }
419 
420 
421 /******************************************************************************
422  *
423  * FUNCTION:    DtCompileCsrt
424  *
425  * PARAMETERS:  List                - Current field list pointer
426  *
427  * RETURN:      Status
428  *
429  * DESCRIPTION: Compile CSRT.
430  *
431  *****************************************************************************/
432 
433 ACPI_STATUS
434 DtCompileCsrt (
435     void                    **List)
436 {
437     ACPI_STATUS             Status = AE_OK;
438     DT_SUBTABLE             *Subtable;
439     DT_SUBTABLE             *ParentTable;
440     DT_FIELD                **PFieldList = (DT_FIELD **) List;
441     UINT32                  DescriptorCount;
442     UINT32                  GroupLength;
443 
444 
445     /* Sub-tables (Resource Groups) */
446 
447     while (*PFieldList)
448     {
449         /* Resource group subtable */
450 
451         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
452                     &Subtable, TRUE);
453         if (ACPI_FAILURE (Status))
454         {
455             return (Status);
456         }
457 
458         /* Compute the number of resource descriptors */
459 
460         GroupLength =
461             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
462                 Subtable->Buffer))->Length -
463             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
464                 Subtable->Buffer))->SharedInfoLength -
465             sizeof (ACPI_CSRT_GROUP);
466 
467         DescriptorCount = (GroupLength  /
468             sizeof (ACPI_CSRT_DESCRIPTOR));
469 
470         ParentTable = DtPeekSubtable ();
471         DtInsertSubtable (ParentTable, Subtable);
472         DtPushSubtable (Subtable);
473 
474         /* Shared info subtable (One per resource group) */
475 
476         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
477                     &Subtable, TRUE);
478         if (ACPI_FAILURE (Status))
479         {
480             return (Status);
481         }
482 
483         ParentTable = DtPeekSubtable ();
484         DtInsertSubtable (ParentTable, Subtable);
485 
486         /* Sub-Subtables (Resource Descriptors) */
487 
488         while (*PFieldList && DescriptorCount)
489         {
490             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
491                         &Subtable, TRUE);
492             if (ACPI_FAILURE (Status))
493             {
494                 return (Status);
495             }
496 
497             ParentTable = DtPeekSubtable ();
498             DtInsertSubtable (ParentTable, Subtable);
499             DescriptorCount--;
500         }
501 
502         DtPopSubtable ();
503     }
504 
505     return (Status);
506 }
507 
508 
509 /******************************************************************************
510  *
511  * FUNCTION:    DtCompileDmar
512  *
513  * PARAMETERS:  List                - Current field list pointer
514  *
515  * RETURN:      Status
516  *
517  * DESCRIPTION: Compile DMAR.
518  *
519  *****************************************************************************/
520 
521 ACPI_STATUS
522 DtCompileDmar (
523     void                    **List)
524 {
525     ACPI_STATUS             Status;
526     DT_SUBTABLE             *Subtable;
527     DT_SUBTABLE             *ParentTable;
528     DT_FIELD                **PFieldList = (DT_FIELD **) List;
529     DT_FIELD                *SubtableStart;
530     ACPI_DMTABLE_INFO       *InfoTable;
531     ACPI_DMAR_HEADER        *DmarHeader;
532     UINT8                   *ReservedBuffer;
533     UINT32                  ReservedSize;
534 
535 
536     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
537     if (ACPI_FAILURE (Status))
538     {
539         return (Status);
540     }
541 
542     ParentTable = DtPeekSubtable ();
543     DtInsertSubtable (ParentTable, Subtable);
544 
545     /* DMAR Reserved area */
546 
547     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved);
548     ReservedBuffer = UtLocalCalloc (ReservedSize);
549 
550     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
551 
552     ACPI_FREE (ReservedBuffer);
553     ParentTable = DtPeekSubtable ();
554     DtInsertSubtable (ParentTable, Subtable);
555 
556     while (*PFieldList)
557     {
558         /* DMAR Header */
559 
560         SubtableStart = *PFieldList;
561         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
562                     &Subtable, TRUE);
563         if (ACPI_FAILURE (Status))
564         {
565             return (Status);
566         }
567 
568         ParentTable = DtPeekSubtable ();
569         DtInsertSubtable (ParentTable, Subtable);
570         DtPushSubtable (Subtable);
571 
572         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
573 
574         switch (DmarHeader->Type)
575         {
576         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
577             InfoTable = AcpiDmTableInfoDmar0;
578             break;
579         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
580             InfoTable = AcpiDmTableInfoDmar1;
581             break;
582         case ACPI_DMAR_TYPE_ATSR:
583             InfoTable = AcpiDmTableInfoDmar2;
584             break;
585         case ACPI_DMAR_HARDWARE_AFFINITY:
586             InfoTable = AcpiDmTableInfoDmar3;
587             break;
588         default:
589             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
590             return (AE_ERROR);
591         }
592 
593         /* DMAR Subtable */
594 
595         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
596         if (ACPI_FAILURE (Status))
597         {
598             return (Status);
599         }
600 
601         ParentTable = DtPeekSubtable ();
602         DtInsertSubtable (ParentTable, Subtable);
603 
604         /* Optional Device Scope subtables */
605 
606         while (*PFieldList)
607         {
608             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
609                         &Subtable, FALSE);
610             if (Status == AE_NOT_FOUND)
611             {
612                 break;
613             }
614 
615             ParentTable = DtPeekSubtable ();
616             DtInsertSubtable (ParentTable, Subtable);
617             DtPushSubtable (Subtable);
618 
619             /* Optional PCI Paths */
620 
621             while (*PFieldList)
622             {
623                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
624                             &Subtable, FALSE);
625                 if (Status == AE_NOT_FOUND)
626                 {
627                     DtPopSubtable ();
628                     break;
629                 }
630 
631                 ParentTable = DtPeekSubtable ();
632                 DtInsertSubtable (ParentTable, Subtable);
633             }
634         }
635 
636         DtPopSubtable ();
637     }
638 
639     return (AE_OK);
640 }
641 
642 
643 /******************************************************************************
644  *
645  * FUNCTION:    DtCompileEinj
646  *
647  * PARAMETERS:  List                - Current field list pointer
648  *
649  * RETURN:      Status
650  *
651  * DESCRIPTION: Compile EINJ.
652  *
653  *****************************************************************************/
654 
655 ACPI_STATUS
656 DtCompileEinj (
657     void                    **List)
658 {
659     ACPI_STATUS             Status;
660 
661 
662     Status = DtCompileTwoSubtables (List,
663                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
664     return (Status);
665 }
666 
667 
668 /******************************************************************************
669  *
670  * FUNCTION:    DtCompileErst
671  *
672  * PARAMETERS:  List                - Current field list pointer
673  *
674  * RETURN:      Status
675  *
676  * DESCRIPTION: Compile ERST.
677  *
678  *****************************************************************************/
679 
680 ACPI_STATUS
681 DtCompileErst (
682     void                    **List)
683 {
684     ACPI_STATUS             Status;
685 
686 
687     Status = DtCompileTwoSubtables (List,
688                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
689     return (Status);
690 }
691 
692 
693 /******************************************************************************
694  *
695  * FUNCTION:    DtCompileFadt
696  *
697  * PARAMETERS:  List                - Current field list pointer
698  *
699  * RETURN:      Status
700  *
701  * DESCRIPTION: Compile FADT.
702  *
703  *****************************************************************************/
704 
705 ACPI_STATUS
706 DtCompileFadt (
707     void                    **List)
708 {
709     ACPI_STATUS             Status;
710     DT_SUBTABLE             *Subtable;
711     DT_SUBTABLE             *ParentTable;
712     DT_FIELD                **PFieldList = (DT_FIELD **) List;
713     ACPI_TABLE_HEADER       *Table;
714     UINT8                   Revision;
715 
716 
717     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
718                 &Subtable, TRUE);
719     if (ACPI_FAILURE (Status))
720     {
721         return (Status);
722     }
723 
724     ParentTable = DtPeekSubtable ();
725     DtInsertSubtable (ParentTable, Subtable);
726 
727     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
728     Revision = Table->Revision;
729 
730     if (Revision == 2)
731     {
732         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
733                     &Subtable, TRUE);
734         if (ACPI_FAILURE (Status))
735         {
736             return (Status);
737         }
738 
739         DtInsertSubtable (ParentTable, Subtable);
740     }
741     else if (Revision >= 2)
742     {
743         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
744                     &Subtable, TRUE);
745         if (ACPI_FAILURE (Status))
746         {
747             return (Status);
748         }
749 
750         DtInsertSubtable (ParentTable, Subtable);
751 
752         if (Revision >= 5)
753         {
754             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
755                         &Subtable, TRUE);
756             if (ACPI_FAILURE (Status))
757             {
758                 return (Status);
759             }
760 
761             DtInsertSubtable (ParentTable, Subtable);
762         }
763     }
764 
765     return (AE_OK);
766 }
767 
768 
769 /******************************************************************************
770  *
771  * FUNCTION:    DtCompileFpdt
772  *
773  * PARAMETERS:  List                - Current field list pointer
774  *
775  * RETURN:      Status
776  *
777  * DESCRIPTION: Compile FPDT.
778  *
779  *****************************************************************************/
780 
781 ACPI_STATUS
782 DtCompileFpdt (
783     void                    **List)
784 {
785     ACPI_STATUS             Status;
786     ACPI_FPDT_HEADER        *FpdtHeader;
787     DT_SUBTABLE             *Subtable;
788     DT_SUBTABLE             *ParentTable;
789     ACPI_DMTABLE_INFO       *InfoTable;
790     DT_FIELD                **PFieldList = (DT_FIELD **) List;
791     DT_FIELD                *SubtableStart;
792 
793 
794     while (*PFieldList)
795     {
796         SubtableStart = *PFieldList;
797         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
798                     &Subtable, TRUE);
799         if (ACPI_FAILURE (Status))
800         {
801             return (Status);
802         }
803 
804         ParentTable = DtPeekSubtable ();
805         DtInsertSubtable (ParentTable, Subtable);
806         DtPushSubtable (Subtable);
807 
808         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
809 
810         switch (FpdtHeader->Type)
811         {
812         case ACPI_FPDT_TYPE_BOOT:
813             InfoTable = AcpiDmTableInfoFpdt0;
814             break;
815 
816         case ACPI_FPDT_TYPE_S3PERF:
817             InfoTable = AcpiDmTableInfoFpdt1;
818             break;
819 
820         default:
821             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
822             return (AE_ERROR);
823             break;
824         }
825 
826         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
827         if (ACPI_FAILURE (Status))
828         {
829             return (Status);
830         }
831 
832         ParentTable = DtPeekSubtable ();
833         DtInsertSubtable (ParentTable, Subtable);
834         DtPopSubtable ();
835     }
836 
837     return (AE_OK);
838 }
839 
840 
841 /******************************************************************************
842  *
843  * FUNCTION:    DtCompileHest
844  *
845  * PARAMETERS:  List                - Current field list pointer
846  *
847  * RETURN:      Status
848  *
849  * DESCRIPTION: Compile HEST.
850  *
851  *****************************************************************************/
852 
853 ACPI_STATUS
854 DtCompileHest (
855     void                    **List)
856 {
857     ACPI_STATUS             Status;
858     DT_SUBTABLE             *Subtable;
859     DT_SUBTABLE             *ParentTable;
860     DT_FIELD                **PFieldList = (DT_FIELD **) List;
861     DT_FIELD                *SubtableStart;
862     ACPI_DMTABLE_INFO       *InfoTable;
863     UINT16                  Type;
864     UINT32                  BankCount;
865 
866 
867     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
868                 &Subtable, TRUE);
869     if (ACPI_FAILURE (Status))
870     {
871         return (Status);
872     }
873 
874     ParentTable = DtPeekSubtable ();
875     DtInsertSubtable (ParentTable, Subtable);
876 
877     while (*PFieldList)
878     {
879         /* Get subtable type */
880 
881         SubtableStart = *PFieldList;
882         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
883 
884         switch (Type)
885         {
886         case ACPI_HEST_TYPE_IA32_CHECK:
887             InfoTable = AcpiDmTableInfoHest0;
888             break;
889 
890         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
891             InfoTable = AcpiDmTableInfoHest1;
892             break;
893 
894         case ACPI_HEST_TYPE_IA32_NMI:
895             InfoTable = AcpiDmTableInfoHest2;
896             break;
897 
898         case ACPI_HEST_TYPE_AER_ROOT_PORT:
899             InfoTable = AcpiDmTableInfoHest6;
900             break;
901 
902         case ACPI_HEST_TYPE_AER_ENDPOINT:
903             InfoTable = AcpiDmTableInfoHest7;
904             break;
905 
906         case ACPI_HEST_TYPE_AER_BRIDGE:
907             InfoTable = AcpiDmTableInfoHest8;
908             break;
909 
910         case ACPI_HEST_TYPE_GENERIC_ERROR:
911             InfoTable = AcpiDmTableInfoHest9;
912             break;
913 
914         default:
915             /* Cannot continue on unknown type */
916 
917             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
918             return (AE_ERROR);
919         }
920 
921         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
922         if (ACPI_FAILURE (Status))
923         {
924             return (Status);
925         }
926 
927         DtInsertSubtable (ParentTable, Subtable);
928 
929         /*
930          * Additional subtable data - IA32 Error Bank(s)
931          */
932         BankCount = 0;
933         switch (Type)
934         {
935         case ACPI_HEST_TYPE_IA32_CHECK:
936             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
937                             Subtable->Buffer))->NumHardwareBanks;
938             break;
939 
940         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
941             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
942                             Subtable->Buffer))->NumHardwareBanks;
943             break;
944 
945         default:
946             break;
947         }
948 
949         while (BankCount)
950         {
951             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
952                         &Subtable, TRUE);
953             if (ACPI_FAILURE (Status))
954             {
955                 return (Status);
956             }
957 
958             DtInsertSubtable (ParentTable, Subtable);
959             BankCount--;
960         }
961     }
962 
963     return (AE_OK);
964 }
965 
966 
967 /******************************************************************************
968  *
969  * FUNCTION:    DtCompileIvrs
970  *
971  * PARAMETERS:  List                - Current field list pointer
972  *
973  * RETURN:      Status
974  *
975  * DESCRIPTION: Compile IVRS.
976  *
977  *****************************************************************************/
978 
979 ACPI_STATUS
980 DtCompileIvrs (
981     void                    **List)
982 {
983     ACPI_STATUS             Status;
984     DT_SUBTABLE             *Subtable;
985     DT_SUBTABLE             *ParentTable;
986     DT_FIELD                **PFieldList = (DT_FIELD **) List;
987     DT_FIELD                *SubtableStart;
988     ACPI_DMTABLE_INFO       *InfoTable;
989     ACPI_IVRS_HEADER        *IvrsHeader;
990     UINT8                   EntryType;
991 
992 
993     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
994                 &Subtable, TRUE);
995     if (ACPI_FAILURE (Status))
996     {
997         return (Status);
998     }
999 
1000     ParentTable = DtPeekSubtable ();
1001     DtInsertSubtable (ParentTable, Subtable);
1002 
1003     while (*PFieldList)
1004     {
1005         SubtableStart = *PFieldList;
1006         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1007                     &Subtable, TRUE);
1008         if (ACPI_FAILURE (Status))
1009         {
1010             return (Status);
1011         }
1012 
1013         ParentTable = DtPeekSubtable ();
1014         DtInsertSubtable (ParentTable, Subtable);
1015         DtPushSubtable (Subtable);
1016 
1017         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1018 
1019         switch (IvrsHeader->Type)
1020         {
1021         case ACPI_IVRS_TYPE_HARDWARE:
1022             InfoTable = AcpiDmTableInfoIvrs0;
1023             break;
1024 
1025         case ACPI_IVRS_TYPE_MEMORY1:
1026         case ACPI_IVRS_TYPE_MEMORY2:
1027         case ACPI_IVRS_TYPE_MEMORY3:
1028             InfoTable = AcpiDmTableInfoIvrs1;
1029             break;
1030 
1031         default:
1032             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1033             return (AE_ERROR);
1034         }
1035 
1036         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1037         if (ACPI_FAILURE (Status))
1038         {
1039             return (Status);
1040         }
1041 
1042         ParentTable = DtPeekSubtable ();
1043         DtInsertSubtable (ParentTable, Subtable);
1044 
1045         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1046         {
1047             while (*PFieldList &&
1048                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1049             {
1050                 SubtableStart = *PFieldList;
1051                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1052 
1053                 switch (EntryType)
1054                 {
1055                 /* 4-byte device entries */
1056 
1057                 case ACPI_IVRS_TYPE_PAD4:
1058                 case ACPI_IVRS_TYPE_ALL:
1059                 case ACPI_IVRS_TYPE_SELECT:
1060                 case ACPI_IVRS_TYPE_START:
1061                 case ACPI_IVRS_TYPE_END:
1062 
1063                     InfoTable = AcpiDmTableInfoIvrs4;
1064                     break;
1065 
1066                 /* 8-byte entries, type A */
1067 
1068                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1069                 case ACPI_IVRS_TYPE_ALIAS_START:
1070 
1071                     InfoTable = AcpiDmTableInfoIvrs8a;
1072                     break;
1073 
1074                 /* 8-byte entries, type B */
1075 
1076                 case ACPI_IVRS_TYPE_PAD8:
1077                 case ACPI_IVRS_TYPE_EXT_SELECT:
1078                 case ACPI_IVRS_TYPE_EXT_START:
1079 
1080                     InfoTable = AcpiDmTableInfoIvrs8b;
1081                     break;
1082 
1083                 /* 8-byte entries, type C */
1084 
1085                 case ACPI_IVRS_TYPE_SPECIAL:
1086 
1087                     InfoTable = AcpiDmTableInfoIvrs8c;
1088                     break;
1089 
1090                 default:
1091                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1092                         "IVRS Device Entry");
1093                     return (AE_ERROR);
1094                 }
1095 
1096                 Status = DtCompileTable (PFieldList, InfoTable,
1097                             &Subtable, TRUE);
1098                 if (ACPI_FAILURE (Status))
1099                 {
1100                     return (Status);
1101                 }
1102 
1103                 DtInsertSubtable (ParentTable, Subtable);
1104             }
1105         }
1106 
1107         DtPopSubtable ();
1108     }
1109 
1110     return (AE_OK);
1111 }
1112 
1113 
1114 /******************************************************************************
1115  *
1116  * FUNCTION:    DtCompileMadt
1117  *
1118  * PARAMETERS:  List                - Current field list pointer
1119  *
1120  * RETURN:      Status
1121  *
1122  * DESCRIPTION: Compile MADT.
1123  *
1124  *****************************************************************************/
1125 
1126 ACPI_STATUS
1127 DtCompileMadt (
1128     void                    **List)
1129 {
1130     ACPI_STATUS             Status;
1131     DT_SUBTABLE             *Subtable;
1132     DT_SUBTABLE             *ParentTable;
1133     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1134     DT_FIELD                *SubtableStart;
1135     ACPI_SUBTABLE_HEADER    *MadtHeader;
1136     ACPI_DMTABLE_INFO       *InfoTable;
1137 
1138 
1139     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1140                 &Subtable, TRUE);
1141     if (ACPI_FAILURE (Status))
1142     {
1143         return (Status);
1144     }
1145 
1146     ParentTable = DtPeekSubtable ();
1147     DtInsertSubtable (ParentTable, Subtable);
1148 
1149     while (*PFieldList)
1150     {
1151         SubtableStart = *PFieldList;
1152         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1153                     &Subtable, TRUE);
1154         if (ACPI_FAILURE (Status))
1155         {
1156             return (Status);
1157         }
1158 
1159         ParentTable = DtPeekSubtable ();
1160         DtInsertSubtable (ParentTable, Subtable);
1161         DtPushSubtable (Subtable);
1162 
1163         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1164 
1165         switch (MadtHeader->Type)
1166         {
1167         case ACPI_MADT_TYPE_LOCAL_APIC:
1168             InfoTable = AcpiDmTableInfoMadt0;
1169             break;
1170         case ACPI_MADT_TYPE_IO_APIC:
1171             InfoTable = AcpiDmTableInfoMadt1;
1172             break;
1173         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1174             InfoTable = AcpiDmTableInfoMadt2;
1175             break;
1176         case ACPI_MADT_TYPE_NMI_SOURCE:
1177             InfoTable = AcpiDmTableInfoMadt3;
1178             break;
1179         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1180             InfoTable = AcpiDmTableInfoMadt4;
1181             break;
1182         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1183             InfoTable = AcpiDmTableInfoMadt5;
1184             break;
1185         case ACPI_MADT_TYPE_IO_SAPIC:
1186             InfoTable = AcpiDmTableInfoMadt6;
1187             break;
1188         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1189             InfoTable = AcpiDmTableInfoMadt7;
1190             break;
1191         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1192             InfoTable = AcpiDmTableInfoMadt8;
1193             break;
1194         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1195             InfoTable = AcpiDmTableInfoMadt9;
1196             break;
1197         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1198             InfoTable = AcpiDmTableInfoMadt10;
1199             break;
1200         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1201             InfoTable = AcpiDmTableInfoMadt11;
1202             break;
1203         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1204             InfoTable = AcpiDmTableInfoMadt12;
1205             break;
1206         default:
1207             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1208             return (AE_ERROR);
1209         }
1210 
1211         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1212         if (ACPI_FAILURE (Status))
1213         {
1214             return (Status);
1215         }
1216 
1217         ParentTable = DtPeekSubtable ();
1218         DtInsertSubtable (ParentTable, Subtable);
1219         DtPopSubtable ();
1220     }
1221 
1222     return (AE_OK);
1223 }
1224 
1225 
1226 /******************************************************************************
1227  *
1228  * FUNCTION:    DtCompileMcfg
1229  *
1230  * PARAMETERS:  List                - Current field list pointer
1231  *
1232  * RETURN:      Status
1233  *
1234  * DESCRIPTION: Compile MCFG.
1235  *
1236  *****************************************************************************/
1237 
1238 ACPI_STATUS
1239 DtCompileMcfg (
1240     void                    **List)
1241 {
1242     ACPI_STATUS             Status;
1243 
1244 
1245     Status = DtCompileTwoSubtables (List,
1246                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1247     return (Status);
1248 }
1249 
1250 
1251 /******************************************************************************
1252  *
1253  * FUNCTION:    DtCompileMpst
1254  *
1255  * PARAMETERS:  List                - Current field list pointer
1256  *
1257  * RETURN:      Status
1258  *
1259  * DESCRIPTION: Compile MPST.
1260  *
1261  *****************************************************************************/
1262 
1263 ACPI_STATUS
1264 DtCompileMpst (
1265     void                    **List)
1266 {
1267     ACPI_STATUS             Status;
1268     DT_SUBTABLE             *Subtable;
1269     DT_SUBTABLE             *ParentTable;
1270     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1271     ACPI_MPST_CHANNEL       *MpstChannelInfo;
1272     ACPI_MPST_POWER_NODE    *MpstPowerNode;
1273     ACPI_MPST_DATA_HDR      *MpstDataHeader;
1274     UINT16                  SubtableCount;
1275     UINT32                  PowerStateCount;
1276     UINT32                  ComponentCount;
1277 
1278 
1279     /* Main table */
1280 
1281     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1282     if (ACPI_FAILURE (Status))
1283     {
1284         return (Status);
1285     }
1286 
1287     ParentTable = DtPeekSubtable ();
1288     DtInsertSubtable (ParentTable, Subtable);
1289     DtPushSubtable (Subtable);
1290 
1291     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1292     SubtableCount = MpstChannelInfo->PowerNodeCount;
1293 
1294     while (*PFieldList && SubtableCount)
1295     {
1296         /* Subtable: Memory Power Node(s) */
1297 
1298         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1299                     &Subtable, TRUE);
1300         if (ACPI_FAILURE (Status))
1301         {
1302             return (Status);
1303         }
1304 
1305         ParentTable = DtPeekSubtable ();
1306         DtInsertSubtable (ParentTable, Subtable);
1307         DtPushSubtable (Subtable);
1308 
1309         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1310         PowerStateCount = MpstPowerNode->NumPowerStates;
1311         ComponentCount = MpstPowerNode->NumPhysicalComponents;
1312 
1313         ParentTable = DtPeekSubtable ();
1314 
1315         /* Sub-subtables - Memory Power State Structure(s) */
1316 
1317         while (*PFieldList && PowerStateCount)
1318         {
1319             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1320                         &Subtable, TRUE);
1321             if (ACPI_FAILURE (Status))
1322             {
1323                 return (Status);
1324             }
1325 
1326             DtInsertSubtable (ParentTable, Subtable);
1327             PowerStateCount--;
1328         }
1329 
1330         /* Sub-subtables - Physical Component ID Structure(s) */
1331 
1332         while (*PFieldList && ComponentCount)
1333         {
1334             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1335                         &Subtable, TRUE);
1336             if (ACPI_FAILURE (Status))
1337             {
1338                 return (Status);
1339             }
1340 
1341             DtInsertSubtable (ParentTable, Subtable);
1342             ComponentCount--;
1343         }
1344 
1345         SubtableCount--;
1346         DtPopSubtable ();
1347     }
1348 
1349     /* Subtable: Count of Memory Power State Characteristic structures */
1350 
1351     DtPopSubtable ();
1352 
1353     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1354     if (ACPI_FAILURE (Status))
1355     {
1356         return (Status);
1357     }
1358 
1359     ParentTable = DtPeekSubtable ();
1360     DtInsertSubtable (ParentTable, Subtable);
1361     DtPushSubtable (Subtable);
1362 
1363     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1364     SubtableCount = MpstDataHeader->CharacteristicsCount;
1365 
1366     ParentTable = DtPeekSubtable ();
1367 
1368     /* Subtable: Memory Power State Characteristics structure(s) */
1369 
1370     while (*PFieldList && SubtableCount)
1371     {
1372         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1373                     &Subtable, TRUE);
1374         if (ACPI_FAILURE (Status))
1375         {
1376             return (Status);
1377         }
1378 
1379         DtInsertSubtable (ParentTable, Subtable);
1380         SubtableCount--;
1381     }
1382 
1383     DtPopSubtable ();
1384     return (AE_OK);
1385 }
1386 
1387 
1388 /******************************************************************************
1389  *
1390  * FUNCTION:    DtCompileMsct
1391  *
1392  * PARAMETERS:  List                - Current field list pointer
1393  *
1394  * RETURN:      Status
1395  *
1396  * DESCRIPTION: Compile MSCT.
1397  *
1398  *****************************************************************************/
1399 
1400 ACPI_STATUS
1401 DtCompileMsct (
1402     void                    **List)
1403 {
1404     ACPI_STATUS             Status;
1405 
1406 
1407     Status = DtCompileTwoSubtables (List,
1408                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1409     return (Status);
1410 }
1411 
1412 
1413 /******************************************************************************
1414  *
1415  * FUNCTION:    DtCompileMtmr
1416  *
1417  * PARAMETERS:  List                - Current field list pointer
1418  *
1419  * RETURN:      Status
1420  *
1421  * DESCRIPTION: Compile MTMR.
1422  *
1423  *****************************************************************************/
1424 
1425 ACPI_STATUS
1426 DtCompileMtmr (
1427     void                    **List)
1428 {
1429     ACPI_STATUS             Status;
1430 
1431 
1432     Status = DtCompileTwoSubtables (List,
1433                  AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1434     return (Status);
1435 }
1436 
1437 
1438 /******************************************************************************
1439  *
1440  * FUNCTION:    DtCompilePmtt
1441  *
1442  * PARAMETERS:  List                - Current field list pointer
1443  *
1444  * RETURN:      Status
1445  *
1446  * DESCRIPTION: Compile PMTT.
1447  *
1448  *****************************************************************************/
1449 
1450 ACPI_STATUS
1451 DtCompilePmtt (
1452     void                    **List)
1453 {
1454     ACPI_STATUS             Status;
1455     DT_SUBTABLE             *Subtable;
1456     DT_SUBTABLE             *ParentTable;
1457     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1458     DT_FIELD                *SubtableStart;
1459     ACPI_PMTT_HEADER        *PmttHeader;
1460     ACPI_PMTT_CONTROLLER    *PmttController;
1461     UINT16                  DomainCount;
1462     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1463 
1464 
1465     /* Main table */
1466 
1467     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1468     if (ACPI_FAILURE (Status))
1469     {
1470         return (Status);
1471     }
1472 
1473     ParentTable = DtPeekSubtable ();
1474     DtInsertSubtable (ParentTable, Subtable);
1475     DtPushSubtable (Subtable);
1476 
1477     while (*PFieldList)
1478     {
1479         SubtableStart = *PFieldList;
1480         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
1481                     &Subtable, TRUE);
1482         if (ACPI_FAILURE (Status))
1483         {
1484             return (Status);
1485         }
1486 
1487         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
1488         while (PrevType >= PmttHeader->Type)
1489         {
1490             DtPopSubtable ();
1491 
1492             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
1493             {
1494                 break;
1495             }
1496             PrevType--;
1497         }
1498         PrevType = PmttHeader->Type;
1499 
1500         ParentTable = DtPeekSubtable ();
1501         DtInsertSubtable (ParentTable, Subtable);
1502         DtPushSubtable (Subtable);
1503 
1504         switch (PmttHeader->Type)
1505         {
1506         case ACPI_PMTT_TYPE_SOCKET:
1507 
1508             /* Subtable: Socket Structure */
1509 
1510             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1511                     &Subtable, TRUE);
1512             if (ACPI_FAILURE (Status))
1513             {
1514                 return (Status);
1515             }
1516 
1517             ParentTable = DtPeekSubtable ();
1518             DtInsertSubtable (ParentTable, Subtable);
1519             break;
1520 
1521         case ACPI_PMTT_TYPE_CONTROLLER:
1522 
1523             /* Subtable: Memory Controller Structure */
1524 
1525             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1526                     &Subtable, TRUE);
1527             if (ACPI_FAILURE (Status))
1528             {
1529                 return (Status);
1530             }
1531 
1532             ParentTable = DtPeekSubtable ();
1533             DtInsertSubtable (ParentTable, Subtable);
1534 
1535             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
1536                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
1537             DomainCount = PmttController->DomainCount;
1538 
1539             while (DomainCount)
1540             {
1541                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
1542                     &Subtable, TRUE);
1543                 if (ACPI_FAILURE (Status))
1544                 {
1545                     return (Status);
1546                 }
1547 
1548                 DtInsertSubtable (ParentTable, Subtable);
1549                 DomainCount--;
1550             }
1551             break;
1552 
1553         case ACPI_PMTT_TYPE_DIMM:
1554 
1555             /* Subtable: Physical Component Structure */
1556 
1557             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1558                     &Subtable, TRUE);
1559             if (ACPI_FAILURE (Status))
1560             {
1561                 return (Status);
1562             }
1563 
1564             ParentTable = DtPeekSubtable ();
1565             DtInsertSubtable (ParentTable, Subtable);
1566             break;
1567 
1568         default:
1569 
1570             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1571             return (AE_ERROR);
1572         }
1573     }
1574 
1575     return (Status);
1576 }
1577 
1578 
1579 /******************************************************************************
1580  *
1581  * FUNCTION:    DtCompileRsdt
1582  *
1583  * PARAMETERS:  List                - Current field list pointer
1584  *
1585  * RETURN:      Status
1586  *
1587  * DESCRIPTION: Compile RSDT.
1588  *
1589  *****************************************************************************/
1590 
1591 ACPI_STATUS
1592 DtCompileRsdt (
1593     void                    **List)
1594 {
1595     DT_SUBTABLE             *Subtable;
1596     DT_SUBTABLE             *ParentTable;
1597     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1598     UINT32                  Address;
1599 
1600 
1601     ParentTable = DtPeekSubtable ();
1602 
1603     while (FieldList)
1604     {
1605         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1606 
1607         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1608         DtInsertSubtable (ParentTable, Subtable);
1609         FieldList = FieldList->Next;
1610     }
1611 
1612     return (AE_OK);
1613 }
1614 
1615 
1616 /******************************************************************************
1617  *
1618  * FUNCTION:    DtCompileS3pt
1619  *
1620  * PARAMETERS:  PFieldList          - Current field list pointer
1621  *
1622  * RETURN:      Status
1623  *
1624  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1625  *
1626  *****************************************************************************/
1627 
1628 ACPI_STATUS
1629 DtCompileS3pt (
1630     DT_FIELD                **PFieldList)
1631 {
1632     ACPI_STATUS             Status;
1633     ACPI_S3PT_HEADER        *S3ptHeader;
1634     DT_SUBTABLE             *Subtable;
1635     DT_SUBTABLE             *ParentTable;
1636     ACPI_DMTABLE_INFO       *InfoTable;
1637     DT_FIELD                *SubtableStart;
1638 
1639 
1640     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1641                 &Gbl_RootTable, TRUE);
1642     if (ACPI_FAILURE (Status))
1643     {
1644         return (Status);
1645     }
1646 
1647     DtPushSubtable (Gbl_RootTable);
1648 
1649     while (*PFieldList)
1650     {
1651         SubtableStart = *PFieldList;
1652         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1653                     &Subtable, TRUE);
1654         if (ACPI_FAILURE (Status))
1655         {
1656             return (Status);
1657         }
1658 
1659         ParentTable = DtPeekSubtable ();
1660         DtInsertSubtable (ParentTable, Subtable);
1661         DtPushSubtable (Subtable);
1662 
1663         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
1664 
1665         switch (S3ptHeader->Type)
1666         {
1667         case ACPI_S3PT_TYPE_RESUME:
1668             InfoTable = AcpiDmTableInfoS3pt0;
1669             break;
1670 
1671         case ACPI_S3PT_TYPE_SUSPEND:
1672             InfoTable = AcpiDmTableInfoS3pt1;
1673             break;
1674 
1675         default:
1676             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1677             return (AE_ERROR);
1678         }
1679 
1680         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1681         if (ACPI_FAILURE (Status))
1682         {
1683             return (Status);
1684         }
1685 
1686         ParentTable = DtPeekSubtable ();
1687         DtInsertSubtable (ParentTable, Subtable);
1688         DtPopSubtable ();
1689     }
1690 
1691     return (AE_OK);
1692 }
1693 
1694 
1695 /******************************************************************************
1696  *
1697  * FUNCTION:    DtCompileSlic
1698  *
1699  * PARAMETERS:  List                - Current field list pointer
1700  *
1701  * RETURN:      Status
1702  *
1703  * DESCRIPTION: Compile SLIC.
1704  *
1705  *****************************************************************************/
1706 
1707 ACPI_STATUS
1708 DtCompileSlic (
1709     void                    **List)
1710 {
1711     ACPI_STATUS             Status;
1712     DT_SUBTABLE             *Subtable;
1713     DT_SUBTABLE             *ParentTable;
1714     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1715     DT_FIELD                *SubtableStart;
1716     ACPI_SLIC_HEADER        *SlicHeader;
1717     ACPI_DMTABLE_INFO       *InfoTable;
1718 
1719 
1720     while (*PFieldList)
1721     {
1722         SubtableStart = *PFieldList;
1723         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
1724                     &Subtable, TRUE);
1725         if (ACPI_FAILURE (Status))
1726         {
1727             return (Status);
1728         }
1729 
1730         ParentTable = DtPeekSubtable ();
1731         DtInsertSubtable (ParentTable, Subtable);
1732         DtPushSubtable (Subtable);
1733 
1734         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
1735 
1736         switch (SlicHeader->Type)
1737         {
1738         case ACPI_SLIC_TYPE_PUBLIC_KEY:
1739             InfoTable = AcpiDmTableInfoSlic0;
1740             break;
1741         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
1742             InfoTable = AcpiDmTableInfoSlic1;
1743             break;
1744         default:
1745             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
1746             return (AE_ERROR);
1747         }
1748 
1749         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1750         if (ACPI_FAILURE (Status))
1751         {
1752             return (Status);
1753         }
1754 
1755         ParentTable = DtPeekSubtable ();
1756         DtInsertSubtable (ParentTable, Subtable);
1757         DtPopSubtable ();
1758     }
1759 
1760     return (AE_OK);
1761 }
1762 
1763 
1764 /******************************************************************************
1765  *
1766  * FUNCTION:    DtCompileSlit
1767  *
1768  * PARAMETERS:  List                - Current field list pointer
1769  *
1770  * RETURN:      Status
1771  *
1772  * DESCRIPTION: Compile SLIT.
1773  *
1774  *****************************************************************************/
1775 
1776 ACPI_STATUS
1777 DtCompileSlit (
1778     void                    **List)
1779 {
1780     ACPI_STATUS             Status;
1781     DT_SUBTABLE             *Subtable;
1782     DT_SUBTABLE             *ParentTable;
1783     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1784     DT_FIELD                *FieldList;
1785     UINT32                  Localities;
1786     UINT8                   *LocalityBuffer;
1787 
1788 
1789     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1790                 &Subtable, TRUE);
1791     if (ACPI_FAILURE (Status))
1792     {
1793         return (Status);
1794     }
1795 
1796     ParentTable = DtPeekSubtable ();
1797     DtInsertSubtable (ParentTable, Subtable);
1798 
1799     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1800     LocalityBuffer = UtLocalCalloc (Localities);
1801 
1802     /* Compile each locality buffer */
1803 
1804     FieldList = *PFieldList;
1805     while (FieldList)
1806     {
1807         DtCompileBuffer (LocalityBuffer,
1808             FieldList->Value, FieldList, Localities);
1809 
1810         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1811         DtInsertSubtable (ParentTable, Subtable);
1812         FieldList = FieldList->Next;
1813     }
1814 
1815     ACPI_FREE (LocalityBuffer);
1816     return (AE_OK);
1817 }
1818 
1819 
1820 /******************************************************************************
1821  *
1822  * FUNCTION:    DtCompileSrat
1823  *
1824  * PARAMETERS:  List                - Current field list pointer
1825  *
1826  * RETURN:      Status
1827  *
1828  * DESCRIPTION: Compile SRAT.
1829  *
1830  *****************************************************************************/
1831 
1832 ACPI_STATUS
1833 DtCompileSrat (
1834     void                    **List)
1835 {
1836     ACPI_STATUS             Status;
1837     DT_SUBTABLE             *Subtable;
1838     DT_SUBTABLE             *ParentTable;
1839     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1840     DT_FIELD                *SubtableStart;
1841     ACPI_SUBTABLE_HEADER    *SratHeader;
1842     ACPI_DMTABLE_INFO       *InfoTable;
1843 
1844 
1845     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1846                 &Subtable, TRUE);
1847     if (ACPI_FAILURE (Status))
1848     {
1849         return (Status);
1850     }
1851 
1852     ParentTable = DtPeekSubtable ();
1853     DtInsertSubtable (ParentTable, Subtable);
1854 
1855     while (*PFieldList)
1856     {
1857         SubtableStart = *PFieldList;
1858         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1859                     &Subtable, TRUE);
1860         if (ACPI_FAILURE (Status))
1861         {
1862             return (Status);
1863         }
1864 
1865         ParentTable = DtPeekSubtable ();
1866         DtInsertSubtable (ParentTable, Subtable);
1867         DtPushSubtable (Subtable);
1868 
1869         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1870 
1871         switch (SratHeader->Type)
1872         {
1873         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1874             InfoTable = AcpiDmTableInfoSrat0;
1875             break;
1876         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1877             InfoTable = AcpiDmTableInfoSrat1;
1878             break;
1879         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1880             InfoTable = AcpiDmTableInfoSrat2;
1881             break;
1882         default:
1883             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1884             return (AE_ERROR);
1885         }
1886 
1887         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1888         if (ACPI_FAILURE (Status))
1889         {
1890             return (Status);
1891         }
1892 
1893         ParentTable = DtPeekSubtable ();
1894         DtInsertSubtable (ParentTable, Subtable);
1895         DtPopSubtable ();
1896     }
1897 
1898     return (AE_OK);
1899 }
1900 
1901 
1902 /******************************************************************************
1903  *
1904  * FUNCTION:    DtGetGenericTableInfo
1905  *
1906  * PARAMETERS:  Name                - Generic type name
1907  *
1908  * RETURN:      Info entry
1909  *
1910  * DESCRIPTION: Obtain table info for a generic name entry
1911  *
1912  *****************************************************************************/
1913 
1914 ACPI_DMTABLE_INFO *
1915 DtGetGenericTableInfo (
1916     char                    *Name)
1917 {
1918     ACPI_DMTABLE_INFO       *Info;
1919     UINT32                  i;
1920 
1921 
1922     if (!Name)
1923     {
1924         return (NULL);
1925     }
1926 
1927     /* Search info table for name match */
1928 
1929     for (i = 0; ; i++)
1930     {
1931         Info = AcpiDmTableInfoGeneric[i];
1932         if (Info->Opcode == ACPI_DMT_EXIT)
1933         {
1934             Info = NULL;
1935             break;
1936         }
1937 
1938         /* Use caseless compare for generic keywords */
1939 
1940         if (!AcpiUtStricmp (Name, Info->Name))
1941         {
1942             break;
1943         }
1944     }
1945 
1946     return (Info);
1947 }
1948 
1949 
1950 /******************************************************************************
1951  *
1952  * FUNCTION:    DtCompileUefi
1953  *
1954  * PARAMETERS:  List                - Current field list pointer
1955  *
1956  * RETURN:      Status
1957  *
1958  * DESCRIPTION: Compile UEFI.
1959  *
1960  *****************************************************************************/
1961 
1962 ACPI_STATUS
1963 DtCompileUefi (
1964     void                    **List)
1965 {
1966     ACPI_STATUS             Status;
1967     DT_SUBTABLE             *Subtable;
1968     DT_SUBTABLE             *ParentTable;
1969     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1970     UINT16                  *DataOffset;
1971 
1972 
1973     /* Compile the predefined portion of the UEFI table */
1974 
1975     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1976                 &Subtable, TRUE);
1977     if (ACPI_FAILURE (Status))
1978     {
1979         return (Status);
1980     }
1981 
1982     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1983     *DataOffset = sizeof (ACPI_TABLE_UEFI);
1984 
1985     ParentTable = DtPeekSubtable ();
1986     DtInsertSubtable (ParentTable, Subtable);
1987 
1988     /*
1989      * Compile the "generic" portion of the UEFI table. This
1990      * part of the table is not predefined and any of the generic
1991      * operators may be used.
1992      */
1993 
1994     DtCompileGeneric ((void **) PFieldList);
1995 
1996     return (AE_OK);
1997 }
1998 
1999 
2000 /******************************************************************************
2001  *
2002  * FUNCTION:    DtCompileVrtc
2003  *
2004  * PARAMETERS:  List                - Current field list pointer
2005  *
2006  * RETURN:      Status
2007  *
2008  * DESCRIPTION: Compile VRTC.
2009  *
2010  *****************************************************************************/
2011 
2012 ACPI_STATUS
2013 DtCompileVrtc (
2014     void                    **List)
2015 {
2016     ACPI_STATUS             Status;
2017 
2018 
2019     Status = DtCompileTwoSubtables (List,
2020                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2021     return (Status);
2022 }
2023 
2024 
2025 /******************************************************************************
2026  *
2027  * FUNCTION:    DtCompileWdat
2028  *
2029  * PARAMETERS:  List                - Current field list pointer
2030  *
2031  * RETURN:      Status
2032  *
2033  * DESCRIPTION: Compile WDAT.
2034  *
2035  *****************************************************************************/
2036 
2037 ACPI_STATUS
2038 DtCompileWdat (
2039     void                    **List)
2040 {
2041     ACPI_STATUS             Status;
2042 
2043 
2044     Status = DtCompileTwoSubtables (List,
2045                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2046     return (Status);
2047 }
2048 
2049 
2050 /******************************************************************************
2051  *
2052  * FUNCTION:    DtCompileXsdt
2053  *
2054  * PARAMETERS:  List                - Current field list pointer
2055  *
2056  * RETURN:      Status
2057  *
2058  * DESCRIPTION: Compile XSDT.
2059  *
2060  *****************************************************************************/
2061 
2062 ACPI_STATUS
2063 DtCompileXsdt (
2064     void                    **List)
2065 {
2066     DT_SUBTABLE             *Subtable;
2067     DT_SUBTABLE             *ParentTable;
2068     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2069     UINT64                  Address;
2070 
2071     ParentTable = DtPeekSubtable ();
2072 
2073     while (FieldList)
2074     {
2075         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2076 
2077         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2078         DtInsertSubtable (ParentTable, Subtable);
2079         FieldList = FieldList->Next;
2080     }
2081 
2082     return (AE_OK);
2083 }
2084 
2085 
2086 /******************************************************************************
2087  *
2088  * FUNCTION:    DtCompileGeneric
2089  *
2090  * PARAMETERS:  List                - Current field list pointer
2091  *
2092  * RETURN:      Status
2093  *
2094  * DESCRIPTION: Compile generic unknown table.
2095  *
2096  *****************************************************************************/
2097 
2098 ACPI_STATUS
2099 DtCompileGeneric (
2100     void                    **List)
2101 {
2102     ACPI_STATUS             Status;
2103     DT_SUBTABLE             *Subtable;
2104     DT_SUBTABLE             *ParentTable;
2105     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2106     ACPI_DMTABLE_INFO       *Info;
2107 
2108 
2109     ParentTable = DtPeekSubtable ();
2110 
2111     /*
2112      * Compile the "generic" portion of the table. This
2113      * part of the table is not predefined and any of the generic
2114      * operators may be used.
2115      */
2116 
2117     /* Find any and all labels in the entire generic portion */
2118 
2119     DtDetectAllLabels (*PFieldList);
2120 
2121     /* Now we can actually compile the parse tree */
2122 
2123     while (*PFieldList)
2124     {
2125         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2126         if (!Info)
2127         {
2128             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2129                 (*PFieldList)->Name);
2130             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2131                 (*PFieldList), MsgBuffer);
2132 
2133             *PFieldList = (*PFieldList)->Next;
2134             continue;
2135         }
2136 
2137         Status = DtCompileTable (PFieldList, Info,
2138                     &Subtable, TRUE);
2139         if (ACPI_SUCCESS (Status))
2140         {
2141             DtInsertSubtable (ParentTable, Subtable);
2142         }
2143         else
2144         {
2145             *PFieldList = (*PFieldList)->Next;
2146 
2147             if (Status == AE_NOT_FOUND)
2148             {
2149                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2150                     (*PFieldList)->Name);
2151                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2152                     (*PFieldList), MsgBuffer);
2153             }
2154         }
2155     }
2156 
2157     return (AE_OK);
2158 }
2159