xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable.c (revision 8a166cafe0965f6bd72cd3d2f5372704f05cb5e8)
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:    DtCompilePmtt
1416  *
1417  * PARAMETERS:  List                - Current field list pointer
1418  *
1419  * RETURN:      Status
1420  *
1421  * DESCRIPTION: Compile PMTT.
1422  *
1423  *****************************************************************************/
1424 
1425 ACPI_STATUS
1426 DtCompilePmtt (
1427     void                    **List)
1428 {
1429     ACPI_STATUS             Status;
1430     DT_SUBTABLE             *Subtable;
1431     DT_SUBTABLE             *ParentTable;
1432     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1433     DT_FIELD                *SubtableStart;
1434     ACPI_PMTT_HEADER        *PmttHeader;
1435     ACPI_PMTT_CONTROLLER    *PmttController;
1436     UINT16                  DomainCount;
1437     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1438 
1439 
1440     /* Main table */
1441 
1442     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1443     if (ACPI_FAILURE (Status))
1444     {
1445         return (Status);
1446     }
1447 
1448     ParentTable = DtPeekSubtable ();
1449     DtInsertSubtable (ParentTable, Subtable);
1450     DtPushSubtable (Subtable);
1451 
1452     while (*PFieldList)
1453     {
1454         SubtableStart = *PFieldList;
1455         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
1456                     &Subtable, TRUE);
1457         if (ACPI_FAILURE (Status))
1458         {
1459             return (Status);
1460         }
1461 
1462         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
1463         while (PrevType >= PmttHeader->Type)
1464         {
1465             DtPopSubtable ();
1466 
1467             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
1468             {
1469                 break;
1470             }
1471             PrevType--;
1472         }
1473         PrevType = PmttHeader->Type;
1474 
1475         ParentTable = DtPeekSubtable ();
1476         DtInsertSubtable (ParentTable, Subtable);
1477         DtPushSubtable (Subtable);
1478 
1479         switch (PmttHeader->Type)
1480         {
1481         case ACPI_PMTT_TYPE_SOCKET:
1482 
1483             /* Subtable: Socket Structure */
1484 
1485             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1486                     &Subtable, TRUE);
1487             if (ACPI_FAILURE (Status))
1488             {
1489                 return (Status);
1490             }
1491 
1492             ParentTable = DtPeekSubtable ();
1493             DtInsertSubtable (ParentTable, Subtable);
1494             break;
1495 
1496         case ACPI_PMTT_TYPE_CONTROLLER:
1497 
1498             /* Subtable: Memory Controller Structure */
1499 
1500             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1501                     &Subtable, TRUE);
1502             if (ACPI_FAILURE (Status))
1503             {
1504                 return (Status);
1505             }
1506 
1507             ParentTable = DtPeekSubtable ();
1508             DtInsertSubtable (ParentTable, Subtable);
1509 
1510             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
1511                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
1512             DomainCount = PmttController->DomainCount;
1513 
1514             while (DomainCount)
1515             {
1516                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
1517                     &Subtable, TRUE);
1518                 if (ACPI_FAILURE (Status))
1519                 {
1520                     return (Status);
1521                 }
1522 
1523                 DtInsertSubtable (ParentTable, Subtable);
1524                 DomainCount--;
1525             }
1526             break;
1527 
1528         case ACPI_PMTT_TYPE_DIMM:
1529 
1530             /* Subtable: Physical Component Structure */
1531 
1532             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1533                     &Subtable, TRUE);
1534             if (ACPI_FAILURE (Status))
1535             {
1536                 return (Status);
1537             }
1538 
1539             ParentTable = DtPeekSubtable ();
1540             DtInsertSubtable (ParentTable, Subtable);
1541             break;
1542 
1543         default:
1544 
1545             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1546             return (AE_ERROR);
1547         }
1548     }
1549 
1550     return (Status);
1551 }
1552 
1553 
1554 /******************************************************************************
1555  *
1556  * FUNCTION:    DtCompileRsdt
1557  *
1558  * PARAMETERS:  List                - Current field list pointer
1559  *
1560  * RETURN:      Status
1561  *
1562  * DESCRIPTION: Compile RSDT.
1563  *
1564  *****************************************************************************/
1565 
1566 ACPI_STATUS
1567 DtCompileRsdt (
1568     void                    **List)
1569 {
1570     DT_SUBTABLE             *Subtable;
1571     DT_SUBTABLE             *ParentTable;
1572     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1573     UINT32                  Address;
1574 
1575 
1576     ParentTable = DtPeekSubtable ();
1577 
1578     while (FieldList)
1579     {
1580         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1581 
1582         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1583         DtInsertSubtable (ParentTable, Subtable);
1584         FieldList = FieldList->Next;
1585     }
1586 
1587     return (AE_OK);
1588 }
1589 
1590 
1591 /******************************************************************************
1592  *
1593  * FUNCTION:    DtCompileS3pt
1594  *
1595  * PARAMETERS:  PFieldList          - Current field list pointer
1596  *
1597  * RETURN:      Status
1598  *
1599  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1600  *
1601  *****************************************************************************/
1602 
1603 ACPI_STATUS
1604 DtCompileS3pt (
1605     DT_FIELD                **PFieldList)
1606 {
1607     ACPI_STATUS             Status;
1608     ACPI_S3PT_HEADER        *S3ptHeader;
1609     DT_SUBTABLE             *Subtable;
1610     DT_SUBTABLE             *ParentTable;
1611     ACPI_DMTABLE_INFO       *InfoTable;
1612     DT_FIELD                *SubtableStart;
1613 
1614 
1615     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1616                 &Gbl_RootTable, TRUE);
1617     if (ACPI_FAILURE (Status))
1618     {
1619         return (Status);
1620     }
1621 
1622     DtPushSubtable (Gbl_RootTable);
1623 
1624     while (*PFieldList)
1625     {
1626         SubtableStart = *PFieldList;
1627         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1628                     &Subtable, TRUE);
1629         if (ACPI_FAILURE (Status))
1630         {
1631             return (Status);
1632         }
1633 
1634         ParentTable = DtPeekSubtable ();
1635         DtInsertSubtable (ParentTable, Subtable);
1636         DtPushSubtable (Subtable);
1637 
1638         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
1639 
1640         switch (S3ptHeader->Type)
1641         {
1642         case ACPI_S3PT_TYPE_RESUME:
1643             InfoTable = AcpiDmTableInfoS3pt0;
1644             break;
1645 
1646         case ACPI_S3PT_TYPE_SUSPEND:
1647             InfoTable = AcpiDmTableInfoS3pt1;
1648             break;
1649 
1650         default:
1651             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1652             return (AE_ERROR);
1653         }
1654 
1655         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1656         if (ACPI_FAILURE (Status))
1657         {
1658             return (Status);
1659         }
1660 
1661         ParentTable = DtPeekSubtable ();
1662         DtInsertSubtable (ParentTable, Subtable);
1663         DtPopSubtable ();
1664     }
1665 
1666     return (AE_OK);
1667 }
1668 
1669 
1670 /******************************************************************************
1671  *
1672  * FUNCTION:    DtCompileSlic
1673  *
1674  * PARAMETERS:  List                - Current field list pointer
1675  *
1676  * RETURN:      Status
1677  *
1678  * DESCRIPTION: Compile SLIC.
1679  *
1680  *****************************************************************************/
1681 
1682 ACPI_STATUS
1683 DtCompileSlic (
1684     void                    **List)
1685 {
1686     ACPI_STATUS             Status;
1687     DT_SUBTABLE             *Subtable;
1688     DT_SUBTABLE             *ParentTable;
1689     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1690     DT_FIELD                *SubtableStart;
1691     ACPI_SLIC_HEADER        *SlicHeader;
1692     ACPI_DMTABLE_INFO       *InfoTable;
1693 
1694 
1695     while (*PFieldList)
1696     {
1697         SubtableStart = *PFieldList;
1698         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
1699                     &Subtable, TRUE);
1700         if (ACPI_FAILURE (Status))
1701         {
1702             return (Status);
1703         }
1704 
1705         ParentTable = DtPeekSubtable ();
1706         DtInsertSubtable (ParentTable, Subtable);
1707         DtPushSubtable (Subtable);
1708 
1709         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
1710 
1711         switch (SlicHeader->Type)
1712         {
1713         case ACPI_SLIC_TYPE_PUBLIC_KEY:
1714             InfoTable = AcpiDmTableInfoSlic0;
1715             break;
1716         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
1717             InfoTable = AcpiDmTableInfoSlic1;
1718             break;
1719         default:
1720             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
1721             return (AE_ERROR);
1722         }
1723 
1724         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1725         if (ACPI_FAILURE (Status))
1726         {
1727             return (Status);
1728         }
1729 
1730         ParentTable = DtPeekSubtable ();
1731         DtInsertSubtable (ParentTable, Subtable);
1732         DtPopSubtable ();
1733     }
1734 
1735     return (AE_OK);
1736 }
1737 
1738 
1739 /******************************************************************************
1740  *
1741  * FUNCTION:    DtCompileSlit
1742  *
1743  * PARAMETERS:  List                - Current field list pointer
1744  *
1745  * RETURN:      Status
1746  *
1747  * DESCRIPTION: Compile SLIT.
1748  *
1749  *****************************************************************************/
1750 
1751 ACPI_STATUS
1752 DtCompileSlit (
1753     void                    **List)
1754 {
1755     ACPI_STATUS             Status;
1756     DT_SUBTABLE             *Subtable;
1757     DT_SUBTABLE             *ParentTable;
1758     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1759     DT_FIELD                *FieldList;
1760     UINT32                  Localities;
1761     UINT8                   *LocalityBuffer;
1762 
1763 
1764     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1765                 &Subtable, TRUE);
1766     if (ACPI_FAILURE (Status))
1767     {
1768         return (Status);
1769     }
1770 
1771     ParentTable = DtPeekSubtable ();
1772     DtInsertSubtable (ParentTable, Subtable);
1773 
1774     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1775     LocalityBuffer = UtLocalCalloc (Localities);
1776 
1777     /* Compile each locality buffer */
1778 
1779     FieldList = *PFieldList;
1780     while (FieldList)
1781     {
1782         DtCompileBuffer (LocalityBuffer,
1783             FieldList->Value, FieldList, Localities);
1784 
1785         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1786         DtInsertSubtable (ParentTable, Subtable);
1787         FieldList = FieldList->Next;
1788     }
1789 
1790     ACPI_FREE (LocalityBuffer);
1791     return (AE_OK);
1792 }
1793 
1794 
1795 /******************************************************************************
1796  *
1797  * FUNCTION:    DtCompileSrat
1798  *
1799  * PARAMETERS:  List                - Current field list pointer
1800  *
1801  * RETURN:      Status
1802  *
1803  * DESCRIPTION: Compile SRAT.
1804  *
1805  *****************************************************************************/
1806 
1807 ACPI_STATUS
1808 DtCompileSrat (
1809     void                    **List)
1810 {
1811     ACPI_STATUS             Status;
1812     DT_SUBTABLE             *Subtable;
1813     DT_SUBTABLE             *ParentTable;
1814     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1815     DT_FIELD                *SubtableStart;
1816     ACPI_SUBTABLE_HEADER    *SratHeader;
1817     ACPI_DMTABLE_INFO       *InfoTable;
1818 
1819 
1820     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1821                 &Subtable, TRUE);
1822     if (ACPI_FAILURE (Status))
1823     {
1824         return (Status);
1825     }
1826 
1827     ParentTable = DtPeekSubtable ();
1828     DtInsertSubtable (ParentTable, Subtable);
1829 
1830     while (*PFieldList)
1831     {
1832         SubtableStart = *PFieldList;
1833         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1834                     &Subtable, TRUE);
1835         if (ACPI_FAILURE (Status))
1836         {
1837             return (Status);
1838         }
1839 
1840         ParentTable = DtPeekSubtable ();
1841         DtInsertSubtable (ParentTable, Subtable);
1842         DtPushSubtable (Subtable);
1843 
1844         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1845 
1846         switch (SratHeader->Type)
1847         {
1848         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1849             InfoTable = AcpiDmTableInfoSrat0;
1850             break;
1851         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1852             InfoTable = AcpiDmTableInfoSrat1;
1853             break;
1854         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1855             InfoTable = AcpiDmTableInfoSrat2;
1856             break;
1857         default:
1858             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1859             return (AE_ERROR);
1860         }
1861 
1862         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1863         if (ACPI_FAILURE (Status))
1864         {
1865             return (Status);
1866         }
1867 
1868         ParentTable = DtPeekSubtable ();
1869         DtInsertSubtable (ParentTable, Subtable);
1870         DtPopSubtable ();
1871     }
1872 
1873     return (AE_OK);
1874 }
1875 
1876 
1877 /******************************************************************************
1878  *
1879  * FUNCTION:    DtGetGenericTableInfo
1880  *
1881  * PARAMETERS:  Name                - Generic type name
1882  *
1883  * RETURN:      Info entry
1884  *
1885  * DESCRIPTION: Obtain table info for a generic name entry
1886  *
1887  *****************************************************************************/
1888 
1889 ACPI_DMTABLE_INFO *
1890 DtGetGenericTableInfo (
1891     char                    *Name)
1892 {
1893     ACPI_DMTABLE_INFO       *Info;
1894     UINT32                  i;
1895 
1896 
1897     if (!Name)
1898     {
1899         return (NULL);
1900     }
1901 
1902     /* Search info table for name match */
1903 
1904     for (i = 0; ; i++)
1905     {
1906         Info = AcpiDmTableInfoGeneric[i];
1907         if (Info->Opcode == ACPI_DMT_EXIT)
1908         {
1909             Info = NULL;
1910             break;
1911         }
1912 
1913         /* Use caseless compare for generic keywords */
1914 
1915         if (!AcpiUtStricmp (Name, Info->Name))
1916         {
1917             break;
1918         }
1919     }
1920 
1921     return (Info);
1922 }
1923 
1924 
1925 /******************************************************************************
1926  *
1927  * FUNCTION:    DtCompileUefi
1928  *
1929  * PARAMETERS:  List                - Current field list pointer
1930  *
1931  * RETURN:      Status
1932  *
1933  * DESCRIPTION: Compile UEFI.
1934  *
1935  *****************************************************************************/
1936 
1937 ACPI_STATUS
1938 DtCompileUefi (
1939     void                    **List)
1940 {
1941     ACPI_STATUS             Status;
1942     DT_SUBTABLE             *Subtable;
1943     DT_SUBTABLE             *ParentTable;
1944     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1945     UINT16                  *DataOffset;
1946 
1947 
1948     /* Compile the predefined portion of the UEFI table */
1949 
1950     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1951                 &Subtable, TRUE);
1952     if (ACPI_FAILURE (Status))
1953     {
1954         return (Status);
1955     }
1956 
1957     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1958     *DataOffset = sizeof (ACPI_TABLE_UEFI);
1959 
1960     ParentTable = DtPeekSubtable ();
1961     DtInsertSubtable (ParentTable, Subtable);
1962 
1963     /*
1964      * Compile the "generic" portion of the UEFI table. This
1965      * part of the table is not predefined and any of the generic
1966      * operators may be used.
1967      */
1968 
1969     DtCompileGeneric ((void **) PFieldList);
1970 
1971     return (AE_OK);
1972 }
1973 
1974 
1975 /******************************************************************************
1976  *
1977  * FUNCTION:    DtCompileWdat
1978  *
1979  * PARAMETERS:  List                - Current field list pointer
1980  *
1981  * RETURN:      Status
1982  *
1983  * DESCRIPTION: Compile WDAT.
1984  *
1985  *****************************************************************************/
1986 
1987 ACPI_STATUS
1988 DtCompileWdat (
1989     void                    **List)
1990 {
1991     ACPI_STATUS             Status;
1992 
1993 
1994     Status = DtCompileTwoSubtables (List,
1995                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
1996     return (Status);
1997 }
1998 
1999 
2000 /******************************************************************************
2001  *
2002  * FUNCTION:    DtCompileXsdt
2003  *
2004  * PARAMETERS:  List                - Current field list pointer
2005  *
2006  * RETURN:      Status
2007  *
2008  * DESCRIPTION: Compile XSDT.
2009  *
2010  *****************************************************************************/
2011 
2012 ACPI_STATUS
2013 DtCompileXsdt (
2014     void                    **List)
2015 {
2016     DT_SUBTABLE             *Subtable;
2017     DT_SUBTABLE             *ParentTable;
2018     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2019     UINT64                  Address;
2020 
2021     ParentTable = DtPeekSubtable ();
2022 
2023     while (FieldList)
2024     {
2025         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2026 
2027         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2028         DtInsertSubtable (ParentTable, Subtable);
2029         FieldList = FieldList->Next;
2030     }
2031 
2032     return (AE_OK);
2033 }
2034 
2035 
2036 /******************************************************************************
2037  *
2038  * FUNCTION:    DtCompileGeneric
2039  *
2040  * PARAMETERS:  List                - Current field list pointer
2041  *
2042  * RETURN:      Status
2043  *
2044  * DESCRIPTION: Compile generic unknown table.
2045  *
2046  *****************************************************************************/
2047 
2048 ACPI_STATUS
2049 DtCompileGeneric (
2050     void                    **List)
2051 {
2052     ACPI_STATUS             Status;
2053     DT_SUBTABLE             *Subtable;
2054     DT_SUBTABLE             *ParentTable;
2055     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2056     ACPI_DMTABLE_INFO       *Info;
2057 
2058 
2059     ParentTable = DtPeekSubtable ();
2060 
2061     /*
2062      * Compile the "generic" portion of the table. This
2063      * part of the table is not predefined and any of the generic
2064      * operators may be used.
2065      */
2066 
2067     /* Find any and all labels in the entire generic portion */
2068 
2069     DtDetectAllLabels (*PFieldList);
2070 
2071     /* Now we can actually compile the parse tree */
2072 
2073     while (*PFieldList)
2074     {
2075         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2076         if (!Info)
2077         {
2078             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2079                 (*PFieldList)->Name);
2080             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2081                 (*PFieldList), MsgBuffer);
2082 
2083             *PFieldList = (*PFieldList)->Next;
2084             continue;
2085         }
2086 
2087         Status = DtCompileTable (PFieldList, Info,
2088                     &Subtable, TRUE);
2089         if (ACPI_SUCCESS (Status))
2090         {
2091             DtInsertSubtable (ParentTable, Subtable);
2092         }
2093         else
2094         {
2095             *PFieldList = (*PFieldList)->Next;
2096 
2097             if (Status == AE_NOT_FOUND)
2098             {
2099                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2100                     (*PFieldList)->Name);
2101                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2102                     (*PFieldList), MsgBuffer);
2103             }
2104         }
2105     }
2106 
2107     return (AE_OK);
2108 }
2109