]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/compiler/dttable.c
Import ACPICA 20120215.
[FreeBSD/FreeBSD.git] / source / compiler / dttable.c
1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #define __DTTABLE_C__
45
46 /* Compile all complex data tables */
47
48 #include "aslcompiler.h"
49 #include "dtcompiler.h"
50
51 #define _COMPONENT          DT_COMPILER
52         ACPI_MODULE_NAME    ("dttable")
53
54
55 /* TBD: merge these into dmtbinfo.c? */
56
57 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
58 {
59     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
60     {ACPI_DMT_EXIT,     0,               NULL, 0}
61 };
62
63 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
64 {
65     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
66     {ACPI_DMT_EXIT,     0,               NULL, 0}
67 };
68
69
70 /* TBD: move to acmacros.h */
71
72 #define ACPI_SUB_PTR(t, a, b) \
73     ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
74
75
76 /* Local prototypes */
77
78 static ACPI_STATUS
79 DtCompileTwoSubtables (
80     void                    **List,
81     ACPI_DMTABLE_INFO       *TableInfo1,
82     ACPI_DMTABLE_INFO       *TableInfo2);
83
84
85 /******************************************************************************
86  *
87  * FUNCTION:    DtCompileTwoSubtables
88  *
89  * PARAMETERS:  List                - Current field list pointer
90  *              TableInfo1          - Info table 1
91  *              TableInfo1          - Info table 2
92  *
93  * RETURN:      Status
94  *
95  * DESCRIPTION: Compile tables with a header and one or more same subtables.
96  *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
97  *
98  *****************************************************************************/
99
100 static ACPI_STATUS
101 DtCompileTwoSubtables (
102     void                    **List,
103     ACPI_DMTABLE_INFO       *TableInfo1,
104     ACPI_DMTABLE_INFO       *TableInfo2)
105 {
106     ACPI_STATUS             Status;
107     DT_SUBTABLE             *Subtable;
108     DT_SUBTABLE             *ParentTable;
109     DT_FIELD                **PFieldList = (DT_FIELD **) List;
110
111
112     Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
113     if (ACPI_FAILURE (Status))
114     {
115         return (Status);
116     }
117
118     ParentTable = DtPeekSubtable ();
119     DtInsertSubtable (ParentTable, Subtable);
120
121     while (*PFieldList)
122     {
123         Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
124         if (ACPI_FAILURE (Status))
125         {
126             return (Status);
127         }
128
129         DtInsertSubtable (ParentTable, Subtable);
130     }
131
132     return (AE_OK);
133 }
134
135
136 /******************************************************************************
137  *
138  * FUNCTION:    DtCompileFacs
139  *
140  * PARAMETERS:  PFieldList          - Current field list pointer
141  *
142  * RETURN:      Status
143  *
144  * DESCRIPTION: Compile FACS.
145  *
146  *****************************************************************************/
147
148 ACPI_STATUS
149 DtCompileFacs (
150     DT_FIELD                **PFieldList)
151 {
152     DT_SUBTABLE             *Subtable;
153     UINT8                   *ReservedBuffer;
154     ACPI_STATUS             Status;
155     UINT32                  ReservedSize;
156
157
158     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
159                 &Gbl_RootTable, TRUE);
160     if (ACPI_FAILURE (Status))
161     {
162         return (Status);
163     }
164
165     /* Large FACS reserved area at the end of the table */
166
167     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
168     ReservedBuffer = UtLocalCalloc (ReservedSize);
169
170     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
171
172     ACPI_FREE (ReservedBuffer);
173     DtInsertSubtable (Gbl_RootTable, Subtable);
174     return (AE_OK);
175 }
176
177
178 /******************************************************************************
179  *
180  * FUNCTION:    DtCompileRsdp
181  *
182  * PARAMETERS:  PFieldList          - Current field list pointer
183  *
184  * RETURN:      Status
185  *
186  * DESCRIPTION: Compile RSDP.
187  *
188  *****************************************************************************/
189
190 ACPI_STATUS
191 DtCompileRsdp (
192     DT_FIELD                **PFieldList)
193 {
194     DT_SUBTABLE             *Subtable;
195     ACPI_TABLE_RSDP         *Rsdp;
196     ACPI_RSDP_EXTENSION     *RsdpExtension;
197     ACPI_STATUS             Status;
198
199
200     /* Compile the "common" RSDP (ACPI 1.0) */
201
202     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
203                 &Gbl_RootTable, TRUE);
204     if (ACPI_FAILURE (Status))
205     {
206         return (Status);
207     }
208
209     Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
210     DtSetTableChecksum (&Rsdp->Checksum);
211
212     if (Rsdp->Revision > 0)
213     {
214         /* Compile the "extended" part of the RSDP as a subtable */
215
216         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
217                     &Subtable, TRUE);
218         if (ACPI_FAILURE (Status))
219         {
220             return (Status);
221         }
222
223         DtInsertSubtable (Gbl_RootTable, Subtable);
224
225         /* Set length and extended checksum for entire RSDP */
226
227         RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
228         RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
229         DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
230     }
231
232     return (AE_OK);
233 }
234
235
236 /******************************************************************************
237  *
238  * FUNCTION:    DtCompileAsf
239  *
240  * PARAMETERS:  List                - Current field list pointer
241  *
242  * RETURN:      Status
243  *
244  * DESCRIPTION: Compile ASF!.
245  *
246  *****************************************************************************/
247
248 ACPI_STATUS
249 DtCompileAsf (
250     void                    **List)
251 {
252     ACPI_ASF_INFO           *AsfTable;
253     DT_SUBTABLE             *Subtable;
254     DT_SUBTABLE             *ParentTable;
255     ACPI_DMTABLE_INFO       *InfoTable;
256     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
257     UINT32                  DataCount = 0;
258     ACPI_STATUS             Status;
259     UINT32                  i;
260     DT_FIELD                **PFieldList = (DT_FIELD **) List;
261     DT_FIELD                *SubtableStart;
262
263
264     while (*PFieldList)
265     {
266         SubtableStart = *PFieldList;
267         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
268                     &Subtable, TRUE);
269         if (ACPI_FAILURE (Status))
270         {
271             return (Status);
272         }
273
274         ParentTable = DtPeekSubtable ();
275         DtInsertSubtable (ParentTable, Subtable);
276         DtPushSubtable (Subtable);
277
278         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
279
280         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
281         {
282         case ACPI_ASF_TYPE_INFO:
283             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:    DtCompileDmar
424  *
425  * PARAMETERS:  List                - Current field list pointer
426  *
427  * RETURN:      Status
428  *
429  * DESCRIPTION: Compile DMAR.
430  *
431  *****************************************************************************/
432
433 ACPI_STATUS
434 DtCompileDmar (
435     void                    **List)
436 {
437     ACPI_STATUS             Status;
438     DT_SUBTABLE             *Subtable;
439     DT_SUBTABLE             *ParentTable;
440     DT_FIELD                **PFieldList = (DT_FIELD **) List;
441     DT_FIELD                *SubtableStart;
442     ACPI_DMTABLE_INFO       *InfoTable;
443     ACPI_DMAR_HEADER        *DmarHeader;
444     UINT8                   *ReservedBuffer;
445     UINT32                  ReservedSize;
446
447
448     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
449     if (ACPI_FAILURE (Status))
450     {
451         return (Status);
452     }
453
454     ParentTable = DtPeekSubtable ();
455     DtInsertSubtable (ParentTable, Subtable);
456
457     /* DMAR Reserved area */
458
459     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved);
460     ReservedBuffer = UtLocalCalloc (ReservedSize);
461
462     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
463
464     ACPI_FREE (ReservedBuffer);
465     ParentTable = DtPeekSubtable ();
466     DtInsertSubtable (ParentTable, Subtable);
467
468     while (*PFieldList)
469     {
470         /* DMAR Header */
471
472         SubtableStart = *PFieldList;
473         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
474                     &Subtable, TRUE);
475         if (ACPI_FAILURE (Status))
476         {
477             return (Status);
478         }
479
480         ParentTable = DtPeekSubtable ();
481         DtInsertSubtable (ParentTable, Subtable);
482         DtPushSubtable (Subtable);
483
484         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
485
486         switch (DmarHeader->Type)
487         {
488         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
489             InfoTable = AcpiDmTableInfoDmar0;
490             break;
491         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
492             InfoTable = AcpiDmTableInfoDmar1;
493             break;
494         case ACPI_DMAR_TYPE_ATSR:
495             InfoTable = AcpiDmTableInfoDmar2;
496             break;
497         case ACPI_DMAR_HARDWARE_AFFINITY:
498             InfoTable = AcpiDmTableInfoDmar3;
499             break;
500         default:
501             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
502             return (AE_ERROR);
503         }
504
505         /* DMAR Subtable */
506
507         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
508         if (ACPI_FAILURE (Status))
509         {
510             return (Status);
511         }
512
513         ParentTable = DtPeekSubtable ();
514         DtInsertSubtable (ParentTable, Subtable);
515
516         /* Optional Device Scope subtables */
517
518         while (*PFieldList)
519         {
520             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
521                         &Subtable, FALSE);
522             if (Status == AE_NOT_FOUND)
523             {
524                 break;
525             }
526
527             ParentTable = DtPeekSubtable ();
528             DtInsertSubtable (ParentTable, Subtable);
529             DtPushSubtable (Subtable);
530
531             /* Optional PCI Paths */
532
533             while (*PFieldList)
534             {
535                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
536                             &Subtable, FALSE);
537                 if (Status == AE_NOT_FOUND)
538                 {
539                     DtPopSubtable ();
540                     break;
541                 }
542
543                 ParentTable = DtPeekSubtable ();
544                 DtInsertSubtable (ParentTable, Subtable);
545             }
546         }
547
548         DtPopSubtable ();
549     }
550
551     return (AE_OK);
552 }
553
554
555 /******************************************************************************
556  *
557  * FUNCTION:    DtCompileEinj
558  *
559  * PARAMETERS:  List                - Current field list pointer
560  *
561  * RETURN:      Status
562  *
563  * DESCRIPTION: Compile EINJ.
564  *
565  *****************************************************************************/
566
567 ACPI_STATUS
568 DtCompileEinj (
569     void                    **List)
570 {
571     ACPI_STATUS             Status;
572
573
574     Status = DtCompileTwoSubtables (List,
575                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
576     return (Status);
577 }
578
579
580 /******************************************************************************
581  *
582  * FUNCTION:    DtCompileErst
583  *
584  * PARAMETERS:  List                - Current field list pointer
585  *
586  * RETURN:      Status
587  *
588  * DESCRIPTION: Compile ERST.
589  *
590  *****************************************************************************/
591
592 ACPI_STATUS
593 DtCompileErst (
594     void                    **List)
595 {
596     ACPI_STATUS             Status;
597
598
599     Status = DtCompileTwoSubtables (List,
600                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
601     return (Status);
602 }
603
604
605 /******************************************************************************
606  *
607  * FUNCTION:    DtCompileFadt
608  *
609  * PARAMETERS:  List                - Current field list pointer
610  *
611  * RETURN:      Status
612  *
613  * DESCRIPTION: Compile FADT.
614  *
615  *****************************************************************************/
616
617 ACPI_STATUS
618 DtCompileFadt (
619     void                    **List)
620 {
621     ACPI_STATUS             Status;
622     DT_SUBTABLE             *Subtable;
623     DT_SUBTABLE             *ParentTable;
624     DT_FIELD                **PFieldList = (DT_FIELD **) List;
625     ACPI_TABLE_HEADER       *Table;
626     UINT8                   Revision;
627
628
629     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
630                 &Subtable, TRUE);
631     if (ACPI_FAILURE (Status))
632     {
633         return (Status);
634     }
635
636     ParentTable = DtPeekSubtable ();
637     DtInsertSubtable (ParentTable, Subtable);
638
639     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
640     Revision = Table->Revision;
641
642     if (Revision == 2)
643     {
644         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
645                     &Subtable, TRUE);
646         if (ACPI_FAILURE (Status))
647         {
648             return (Status);
649         }
650
651         DtInsertSubtable (ParentTable, Subtable);
652     }
653     else if (Revision >= 2)
654     {
655         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
656                     &Subtable, TRUE);
657         if (ACPI_FAILURE (Status))
658         {
659             return (Status);
660         }
661
662         DtInsertSubtable (ParentTable, Subtable);
663
664         if (Revision >= 5)
665         {
666             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
667                         &Subtable, TRUE);
668             if (ACPI_FAILURE (Status))
669             {
670                 return (Status);
671             }
672
673             DtInsertSubtable (ParentTable, Subtable);
674         }
675     }
676
677     return (AE_OK);
678 }
679
680
681 /******************************************************************************
682  *
683  * FUNCTION:    DtCompileFpdt
684  *
685  * PARAMETERS:  List                - Current field list pointer
686  *
687  * RETURN:      Status
688  *
689  * DESCRIPTION: Compile FPDT.
690  *
691  *****************************************************************************/
692
693 ACPI_STATUS
694 DtCompileFpdt (
695     void                    **List)
696 {
697     ACPI_STATUS             Status;
698     ACPI_FPDT_HEADER        *FpdtHeader;
699     DT_SUBTABLE             *Subtable;
700     DT_SUBTABLE             *ParentTable;
701     ACPI_DMTABLE_INFO       *InfoTable;
702     DT_FIELD                **PFieldList = (DT_FIELD **) List;
703     DT_FIELD                *SubtableStart;
704
705
706     while (*PFieldList)
707     {
708         SubtableStart = *PFieldList;
709         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
710                     &Subtable, TRUE);
711         if (ACPI_FAILURE (Status))
712         {
713             return (Status);
714         }
715
716         ParentTable = DtPeekSubtable ();
717         DtInsertSubtable (ParentTable, Subtable);
718         DtPushSubtable (Subtable);
719
720         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
721
722         switch (FpdtHeader->Type)
723         {
724         case ACPI_FPDT_TYPE_BOOT:
725             InfoTable = AcpiDmTableInfoFpdt0;
726             break;
727
728         case ACPI_FPDT_TYPE_S3PERF:
729             InfoTable = AcpiDmTableInfoFpdt1;
730             break;
731
732         default:
733             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
734             return (AE_ERROR);
735             break;
736         }
737
738         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
739         if (ACPI_FAILURE (Status))
740         {
741             return (Status);
742         }
743
744         ParentTable = DtPeekSubtable ();
745         DtInsertSubtable (ParentTable, Subtable);
746         DtPopSubtable ();
747     }
748
749     return (AE_OK);
750 }
751
752
753 /******************************************************************************
754  *
755  * FUNCTION:    DtCompileHest
756  *
757  * PARAMETERS:  List                - Current field list pointer
758  *
759  * RETURN:      Status
760  *
761  * DESCRIPTION: Compile HEST.
762  *
763  *****************************************************************************/
764
765 ACPI_STATUS
766 DtCompileHest (
767     void                    **List)
768 {
769     ACPI_STATUS             Status;
770     DT_SUBTABLE             *Subtable;
771     DT_SUBTABLE             *ParentTable;
772     DT_FIELD                **PFieldList = (DT_FIELD **) List;
773     DT_FIELD                *SubtableStart;
774     ACPI_DMTABLE_INFO       *InfoTable;
775     UINT16                  Type;
776     UINT32                  BankCount;
777
778
779     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
780                 &Subtable, TRUE);
781     if (ACPI_FAILURE (Status))
782     {
783         return (Status);
784     }
785
786     ParentTable = DtPeekSubtable ();
787     DtInsertSubtable (ParentTable, Subtable);
788
789     while (*PFieldList)
790     {
791         /* Get subtable type */
792
793         SubtableStart = *PFieldList;
794         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
795
796         switch (Type)
797         {
798         case ACPI_HEST_TYPE_IA32_CHECK:
799             InfoTable = AcpiDmTableInfoHest0;
800             break;
801
802         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
803             InfoTable = AcpiDmTableInfoHest1;
804             break;
805
806         case ACPI_HEST_TYPE_IA32_NMI:
807             InfoTable = AcpiDmTableInfoHest2;
808             break;
809
810         case ACPI_HEST_TYPE_AER_ROOT_PORT:
811             InfoTable = AcpiDmTableInfoHest6;
812             break;
813
814         case ACPI_HEST_TYPE_AER_ENDPOINT:
815             InfoTable = AcpiDmTableInfoHest7;
816             break;
817
818         case ACPI_HEST_TYPE_AER_BRIDGE:
819             InfoTable = AcpiDmTableInfoHest8;
820             break;
821
822         case ACPI_HEST_TYPE_GENERIC_ERROR:
823             InfoTable = AcpiDmTableInfoHest9;
824             break;
825
826         default:
827             /* Cannot continue on unknown type */
828
829             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
830             return (AE_ERROR);
831         }
832
833         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
834         if (ACPI_FAILURE (Status))
835         {
836             return (Status);
837         }
838
839         DtInsertSubtable (ParentTable, Subtable);
840
841         /*
842          * Additional subtable data - IA32 Error Bank(s)
843          */
844         BankCount = 0;
845         switch (Type)
846         {
847         case ACPI_HEST_TYPE_IA32_CHECK:
848             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
849                             Subtable->Buffer))->NumHardwareBanks;
850             break;
851
852         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
853             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
854                             Subtable->Buffer))->NumHardwareBanks;
855             break;
856
857         default:
858             break;
859         }
860
861         while (BankCount)
862         {
863             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
864                         &Subtable, TRUE);
865             if (ACPI_FAILURE (Status))
866             {
867                 return (Status);
868             }
869
870             DtInsertSubtable (ParentTable, Subtable);
871             BankCount--;
872         }
873     }
874
875     return AE_OK;
876 }
877
878
879 /******************************************************************************
880  *
881  * FUNCTION:    DtCompileIvrs
882  *
883  * PARAMETERS:  List                - Current field list pointer
884  *
885  * RETURN:      Status
886  *
887  * DESCRIPTION: Compile IVRS.
888  *
889  *****************************************************************************/
890
891 ACPI_STATUS
892 DtCompileIvrs (
893     void                    **List)
894 {
895     ACPI_STATUS             Status;
896     DT_SUBTABLE             *Subtable;
897     DT_SUBTABLE             *ParentTable;
898     DT_FIELD                **PFieldList = (DT_FIELD **) List;
899     DT_FIELD                *SubtableStart;
900     ACPI_DMTABLE_INFO       *InfoTable;
901     ACPI_IVRS_HEADER        *IvrsHeader;
902     UINT8                   EntryType;
903
904
905     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
906                 &Subtable, TRUE);
907     if (ACPI_FAILURE (Status))
908     {
909         return (Status);
910     }
911
912     ParentTable = DtPeekSubtable ();
913     DtInsertSubtable (ParentTable, Subtable);
914
915     while (*PFieldList)
916     {
917         SubtableStart = *PFieldList;
918         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
919                     &Subtable, TRUE);
920         if (ACPI_FAILURE (Status))
921         {
922             return (Status);
923         }
924
925         ParentTable = DtPeekSubtable ();
926         DtInsertSubtable (ParentTable, Subtable);
927         DtPushSubtable (Subtable);
928
929         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
930
931         switch (IvrsHeader->Type)
932         {
933         case ACPI_IVRS_TYPE_HARDWARE:
934             InfoTable = AcpiDmTableInfoIvrs0;
935             break;
936
937         case ACPI_IVRS_TYPE_MEMORY1:
938         case ACPI_IVRS_TYPE_MEMORY2:
939         case ACPI_IVRS_TYPE_MEMORY3:
940             InfoTable = AcpiDmTableInfoIvrs1;
941             break;
942
943         default:
944             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
945             return (AE_ERROR);
946         }
947
948         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
949         if (ACPI_FAILURE (Status))
950         {
951             return (Status);
952         }
953
954         ParentTable = DtPeekSubtable ();
955         DtInsertSubtable (ParentTable, Subtable);
956
957         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
958         {
959             while (*PFieldList &&
960                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
961             {
962                 SubtableStart = *PFieldList;
963                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
964
965                 switch (EntryType)
966                 {
967                 /* 4-byte device entries */
968
969                 case ACPI_IVRS_TYPE_PAD4:
970                 case ACPI_IVRS_TYPE_ALL:
971                 case ACPI_IVRS_TYPE_SELECT:
972                 case ACPI_IVRS_TYPE_START:
973                 case ACPI_IVRS_TYPE_END:
974
975                     InfoTable = AcpiDmTableInfoIvrs4;
976                     break;
977
978                 /* 8-byte entries, type A */
979
980                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
981                 case ACPI_IVRS_TYPE_ALIAS_START:
982
983                     InfoTable = AcpiDmTableInfoIvrs8a;
984                     break;
985
986                 /* 8-byte entries, type B */
987
988                 case ACPI_IVRS_TYPE_PAD8:
989                 case ACPI_IVRS_TYPE_EXT_SELECT:
990                 case ACPI_IVRS_TYPE_EXT_START:
991
992                     InfoTable = AcpiDmTableInfoIvrs8b;
993                     break;
994
995                 /* 8-byte entries, type C */
996
997                 case ACPI_IVRS_TYPE_SPECIAL:
998
999                     InfoTable = AcpiDmTableInfoIvrs8c;
1000                     break;
1001
1002                 default:
1003                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1004                         "IVRS Device Entry");
1005                     return (AE_ERROR);
1006                 }
1007
1008                 Status = DtCompileTable (PFieldList, InfoTable,
1009                             &Subtable, TRUE);
1010                 if (ACPI_FAILURE (Status))
1011                 {
1012                     return (Status);
1013                 }
1014
1015                 DtInsertSubtable (ParentTable, Subtable);
1016             }
1017         }
1018
1019         DtPopSubtable ();
1020     }
1021
1022     return (AE_OK);
1023 }
1024
1025
1026 /******************************************************************************
1027  *
1028  * FUNCTION:    DtCompileMadt
1029  *
1030  * PARAMETERS:  List                - Current field list pointer
1031  *
1032  * RETURN:      Status
1033  *
1034  * DESCRIPTION: Compile MADT.
1035  *
1036  *****************************************************************************/
1037
1038 ACPI_STATUS
1039 DtCompileMadt (
1040     void                    **List)
1041 {
1042     ACPI_STATUS             Status;
1043     DT_SUBTABLE             *Subtable;
1044     DT_SUBTABLE             *ParentTable;
1045     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1046     DT_FIELD                *SubtableStart;
1047     ACPI_SUBTABLE_HEADER    *MadtHeader;
1048     ACPI_DMTABLE_INFO       *InfoTable;
1049
1050
1051     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1052                 &Subtable, TRUE);
1053     if (ACPI_FAILURE (Status))
1054     {
1055         return (Status);
1056     }
1057
1058     ParentTable = DtPeekSubtable ();
1059     DtInsertSubtable (ParentTable, Subtable);
1060
1061     while (*PFieldList)
1062     {
1063         SubtableStart = *PFieldList;
1064         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1065                     &Subtable, TRUE);
1066         if (ACPI_FAILURE (Status))
1067         {
1068             return (Status);
1069         }
1070
1071         ParentTable = DtPeekSubtable ();
1072         DtInsertSubtable (ParentTable, Subtable);
1073         DtPushSubtable (Subtable);
1074
1075         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1076
1077         switch (MadtHeader->Type)
1078         {
1079         case ACPI_MADT_TYPE_LOCAL_APIC:
1080             InfoTable = AcpiDmTableInfoMadt0;
1081             break;
1082         case ACPI_MADT_TYPE_IO_APIC:
1083             InfoTable = AcpiDmTableInfoMadt1;
1084             break;
1085         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1086             InfoTable = AcpiDmTableInfoMadt2;
1087             break;
1088         case ACPI_MADT_TYPE_NMI_SOURCE:
1089             InfoTable = AcpiDmTableInfoMadt3;
1090             break;
1091         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1092             InfoTable = AcpiDmTableInfoMadt4;
1093             break;
1094         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1095             InfoTable = AcpiDmTableInfoMadt5;
1096             break;
1097         case ACPI_MADT_TYPE_IO_SAPIC:
1098             InfoTable = AcpiDmTableInfoMadt6;
1099             break;
1100         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1101             InfoTable = AcpiDmTableInfoMadt7;
1102             break;
1103         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1104             InfoTable = AcpiDmTableInfoMadt8;
1105             break;
1106         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1107             InfoTable = AcpiDmTableInfoMadt9;
1108             break;
1109         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1110             InfoTable = AcpiDmTableInfoMadt10;
1111             break;
1112         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1113             InfoTable = AcpiDmTableInfoMadt11;
1114             break;
1115         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1116             InfoTable = AcpiDmTableInfoMadt12;
1117             break;
1118         default:
1119             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1120             return (AE_ERROR);
1121         }
1122
1123         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1124         if (ACPI_FAILURE (Status))
1125         {
1126             return (Status);
1127         }
1128
1129         ParentTable = DtPeekSubtable ();
1130         DtInsertSubtable (ParentTable, Subtable);
1131         DtPopSubtable ();
1132     }
1133
1134     return (AE_OK);
1135 }
1136
1137
1138 /******************************************************************************
1139  *
1140  * FUNCTION:    DtCompileMcfg
1141  *
1142  * PARAMETERS:  List                - Current field list pointer
1143  *
1144  * RETURN:      Status
1145  *
1146  * DESCRIPTION: Compile MCFG.
1147  *
1148  *****************************************************************************/
1149
1150 ACPI_STATUS
1151 DtCompileMcfg (
1152     void                    **List)
1153 {
1154     ACPI_STATUS             Status;
1155
1156
1157     Status = DtCompileTwoSubtables (List,
1158                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1159     return (Status);
1160 }
1161
1162
1163 /******************************************************************************
1164  *
1165  * FUNCTION:    DtCompileMpst
1166  *
1167  * PARAMETERS:  List                - Current field list pointer
1168  *
1169  * RETURN:      Status
1170  *
1171  * DESCRIPTION: Compile MPST.
1172  *
1173  *****************************************************************************/
1174
1175 ACPI_STATUS
1176 DtCompileMpst (
1177     void                    **List)
1178 {
1179     ACPI_STATUS             Status;
1180     DT_SUBTABLE             *Subtable;
1181     DT_SUBTABLE             *ParentTable;
1182     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1183     ACPI_MPST_CHANNEL       *MpstChannelInfo;
1184     ACPI_MPST_POWER_NODE    *MpstPowerNode;
1185     ACPI_MPST_DATA_HDR      *MpstDataHeader;
1186     UINT16                  SubtableCount;
1187     UINT8                   PowerStateCount;
1188     UINT8                   ComponentCount;
1189
1190
1191     /* Main table */
1192
1193     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1194     if (ACPI_FAILURE (Status))
1195     {
1196         return (Status);
1197     }
1198
1199     ParentTable = DtPeekSubtable ();
1200     DtInsertSubtable (ParentTable, Subtable);
1201     DtPushSubtable (Subtable);
1202
1203     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1204     SubtableCount = MpstChannelInfo->PowerNodeCount;
1205
1206     while (*PFieldList && SubtableCount)
1207     {
1208         /* Subtable: Memory Power Node(s) */
1209
1210         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1211                     &Subtable, TRUE);
1212         if (ACPI_FAILURE (Status))
1213         {
1214             return (Status);
1215         }
1216
1217         ParentTable = DtPeekSubtable ();
1218         DtInsertSubtable (ParentTable, Subtable);
1219         DtPushSubtable (Subtable);
1220
1221         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1222         PowerStateCount = MpstPowerNode->NumPowerStates;
1223         ComponentCount = MpstPowerNode->NumPhysicalComponents;
1224
1225         ParentTable = DtPeekSubtable ();
1226
1227         /* Sub-subtables - Memory Power State Structure(s) */
1228
1229         while (*PFieldList && PowerStateCount)
1230         {
1231             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1232                         &Subtable, TRUE);
1233             if (ACPI_FAILURE (Status))
1234             {
1235                 return (Status);
1236             }
1237
1238             DtInsertSubtable (ParentTable, Subtable);
1239             PowerStateCount--;
1240         }
1241
1242         /* Sub-subtables - Physical Component ID Structure(s) */
1243
1244         while (*PFieldList && ComponentCount)
1245         {
1246             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1247                         &Subtable, TRUE);
1248             if (ACPI_FAILURE (Status))
1249             {
1250                 return (Status);
1251             }
1252
1253             DtInsertSubtable (ParentTable, Subtable);
1254             ComponentCount--;
1255         }
1256
1257         SubtableCount--;
1258         DtPopSubtable ();
1259     }
1260
1261     /* Subtable: Count of Memory Power State Characteristic structures */
1262
1263     DtPopSubtable ();
1264
1265     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1266     if (ACPI_FAILURE (Status))
1267     {
1268         return (Status);
1269     }
1270
1271     ParentTable = DtPeekSubtable ();
1272     DtInsertSubtable (ParentTable, Subtable);
1273     DtPushSubtable (Subtable);
1274
1275     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1276     SubtableCount = MpstDataHeader->CharacteristicsCount;
1277
1278     ParentTable = DtPeekSubtable ();
1279
1280     /* Subtable: Memory Power State Characteristics structure(s) */
1281
1282     while (*PFieldList && SubtableCount)
1283     {
1284         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1285                     &Subtable, TRUE);
1286         if (ACPI_FAILURE (Status))
1287         {
1288             return (Status);
1289         }
1290
1291         DtInsertSubtable (ParentTable, Subtable);
1292         SubtableCount--;
1293     }
1294
1295     DtPopSubtable ();
1296     return (AE_OK);
1297 }
1298
1299
1300 /******************************************************************************
1301  *
1302  * FUNCTION:    DtCompileMsct
1303  *
1304  * PARAMETERS:  List                - Current field list pointer
1305  *
1306  * RETURN:      Status
1307  *
1308  * DESCRIPTION: Compile MSCT.
1309  *
1310  *****************************************************************************/
1311
1312 ACPI_STATUS
1313 DtCompileMsct (
1314     void                    **List)
1315 {
1316     ACPI_STATUS             Status;
1317
1318
1319     Status = DtCompileTwoSubtables (List,
1320                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1321     return (Status);
1322 }
1323
1324
1325 /******************************************************************************
1326  *
1327  * FUNCTION:    DtCompilePmtt
1328  *
1329  * PARAMETERS:  List                - Current field list pointer
1330  *
1331  * RETURN:      Status
1332  *
1333  * DESCRIPTION: Compile PMTT.
1334  *
1335  *****************************************************************************/
1336
1337 ACPI_STATUS
1338 DtCompilePmtt (
1339     void                    **List)
1340 {
1341     ACPI_STATUS             Status;
1342     DT_SUBTABLE             *Subtable;
1343     DT_SUBTABLE             *ParentTable;
1344     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1345     DT_FIELD                *SubtableStart;
1346     ACPI_PMTT_HEADER        *PmttHeader;
1347     ACPI_PMTT_CONTROLLER    *PmttController;
1348     UINT16                  DomainCount;
1349     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1350
1351
1352     /* Main table */
1353
1354     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1355     if (ACPI_FAILURE (Status))
1356     {
1357         return (Status);
1358     }
1359
1360     ParentTable = DtPeekSubtable ();
1361     DtInsertSubtable (ParentTable, Subtable);
1362     DtPushSubtable (Subtable);
1363
1364     while (*PFieldList)
1365     {
1366         SubtableStart = *PFieldList;
1367         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
1368                     &Subtable, TRUE);
1369         if (ACPI_FAILURE (Status))
1370         {
1371             return (Status);
1372         }
1373
1374         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
1375         while (PrevType >= PmttHeader->Type)
1376         {
1377             DtPopSubtable ();
1378
1379             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
1380             {
1381                 break;
1382             }
1383             PrevType--;
1384         }
1385         PrevType = PmttHeader->Type;
1386
1387         ParentTable = DtPeekSubtable ();
1388         DtInsertSubtable (ParentTable, Subtable);
1389         DtPushSubtable (Subtable);
1390
1391         switch (PmttHeader->Type)
1392         {
1393         case ACPI_PMTT_TYPE_SOCKET:
1394
1395             /* Subtable: Socket Structure */
1396
1397             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1398                     &Subtable, TRUE);
1399             if (ACPI_FAILURE (Status))
1400             {
1401                 return (Status);
1402             }
1403
1404             ParentTable = DtPeekSubtable ();
1405             DtInsertSubtable (ParentTable, Subtable);
1406             break;
1407
1408         case ACPI_PMTT_TYPE_CONTROLLER:
1409
1410             /* Subtable: Memory Controller Structure */
1411
1412             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1413                     &Subtable, TRUE);
1414             if (ACPI_FAILURE (Status))
1415             {
1416                 return (Status);
1417             }
1418
1419             ParentTable = DtPeekSubtable ();
1420             DtInsertSubtable (ParentTable, Subtable);
1421
1422             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
1423                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
1424             DomainCount = PmttController->DomainCount;
1425
1426             while (DomainCount)
1427             {
1428                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
1429                     &Subtable, TRUE);
1430                 if (ACPI_FAILURE (Status))
1431                 {
1432                     return (Status);
1433                 }
1434
1435                 DtInsertSubtable (ParentTable, Subtable);
1436                 DomainCount--;
1437             }
1438             break;
1439
1440         case ACPI_PMTT_TYPE_DIMM:
1441
1442             /* Subtable: Physical Component Structure */
1443
1444             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1445                     &Subtable, TRUE);
1446             if (ACPI_FAILURE (Status))
1447             {
1448                 return (Status);
1449             }
1450
1451             ParentTable = DtPeekSubtable ();
1452             DtInsertSubtable (ParentTable, Subtable);
1453             break;
1454
1455         default:
1456
1457             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1458             return (AE_ERROR);
1459         }
1460     }
1461
1462     return (Status);
1463 }
1464
1465
1466 /******************************************************************************
1467  *
1468  * FUNCTION:    DtCompileRsdt
1469  *
1470  * PARAMETERS:  List                - Current field list pointer
1471  *
1472  * RETURN:      Status
1473  *
1474  * DESCRIPTION: Compile RSDT.
1475  *
1476  *****************************************************************************/
1477
1478 ACPI_STATUS
1479 DtCompileRsdt (
1480     void                    **List)
1481 {
1482     DT_SUBTABLE             *Subtable;
1483     DT_SUBTABLE             *ParentTable;
1484     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1485     UINT32                  Address;
1486
1487
1488     ParentTable = DtPeekSubtable ();
1489
1490     while (FieldList)
1491     {
1492         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1493
1494         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1495         DtInsertSubtable (ParentTable, Subtable);
1496         FieldList = FieldList->Next;
1497     }
1498
1499     return (AE_OK);
1500 }
1501
1502
1503 /******************************************************************************
1504  *
1505  * FUNCTION:    DtCompileS3pt
1506  *
1507  * PARAMETERS:  PFieldList          - Current field list pointer
1508  *
1509  * RETURN:      Status
1510  *
1511  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1512  *
1513  *****************************************************************************/
1514
1515 ACPI_STATUS
1516 DtCompileS3pt (
1517     DT_FIELD                **PFieldList)
1518 {
1519     ACPI_STATUS             Status;
1520     ACPI_S3PT_HEADER        *S3ptHeader;
1521     DT_SUBTABLE             *Subtable;
1522     DT_SUBTABLE             *ParentTable;
1523     ACPI_DMTABLE_INFO       *InfoTable;
1524     DT_FIELD                *SubtableStart;
1525
1526
1527     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1528                 &Gbl_RootTable, TRUE);
1529     if (ACPI_FAILURE (Status))
1530     {
1531         return (Status);
1532     }
1533
1534     DtPushSubtable (Gbl_RootTable);
1535
1536     while (*PFieldList)
1537     {
1538         SubtableStart = *PFieldList;
1539         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1540                     &Subtable, TRUE);
1541         if (ACPI_FAILURE (Status))
1542         {
1543             return (Status);
1544         }
1545
1546         ParentTable = DtPeekSubtable ();
1547         DtInsertSubtable (ParentTable, Subtable);
1548         DtPushSubtable (Subtable);
1549
1550         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
1551
1552         switch (S3ptHeader->Type)
1553         {
1554         case ACPI_S3PT_TYPE_RESUME:
1555             InfoTable = AcpiDmTableInfoS3pt0;
1556             break;
1557
1558         case ACPI_S3PT_TYPE_SUSPEND:
1559             InfoTable = AcpiDmTableInfoS3pt1;
1560             break;
1561
1562         default:
1563             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1564             return (AE_ERROR);
1565         }
1566
1567         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1568         if (ACPI_FAILURE (Status))
1569         {
1570             return (Status);
1571         }
1572
1573         ParentTable = DtPeekSubtable ();
1574         DtInsertSubtable (ParentTable, Subtable);
1575         DtPopSubtable ();
1576     }
1577
1578     return (AE_OK);
1579 }
1580
1581
1582 /******************************************************************************
1583  *
1584  * FUNCTION:    DtCompileSlic
1585  *
1586  * PARAMETERS:  List                - Current field list pointer
1587  *
1588  * RETURN:      Status
1589  *
1590  * DESCRIPTION: Compile SLIC.
1591  *
1592  *****************************************************************************/
1593
1594 ACPI_STATUS
1595 DtCompileSlic (
1596     void                    **List)
1597 {
1598     ACPI_STATUS             Status;
1599     DT_SUBTABLE             *Subtable;
1600     DT_SUBTABLE             *ParentTable;
1601     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1602     DT_FIELD                *SubtableStart;
1603     ACPI_SLIC_HEADER        *SlicHeader;
1604     ACPI_DMTABLE_INFO       *InfoTable;
1605
1606
1607     while (*PFieldList)
1608     {
1609         SubtableStart = *PFieldList;
1610         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
1611                     &Subtable, TRUE);
1612         if (ACPI_FAILURE (Status))
1613         {
1614             return (Status);
1615         }
1616
1617         ParentTable = DtPeekSubtable ();
1618         DtInsertSubtable (ParentTable, Subtable);
1619         DtPushSubtable (Subtable);
1620
1621         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
1622
1623         switch (SlicHeader->Type)
1624         {
1625         case ACPI_SLIC_TYPE_PUBLIC_KEY:
1626             InfoTable = AcpiDmTableInfoSlic0;
1627             break;
1628         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
1629             InfoTable = AcpiDmTableInfoSlic1;
1630             break;
1631         default:
1632             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
1633             return (AE_ERROR);
1634         }
1635
1636         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1637         if (ACPI_FAILURE (Status))
1638         {
1639             return (Status);
1640         }
1641
1642         ParentTable = DtPeekSubtable ();
1643         DtInsertSubtable (ParentTable, Subtable);
1644         DtPopSubtable ();
1645     }
1646
1647     return (AE_OK);
1648 }
1649
1650
1651 /******************************************************************************
1652  *
1653  * FUNCTION:    DtCompileSlit
1654  *
1655  * PARAMETERS:  List                - Current field list pointer
1656  *
1657  * RETURN:      Status
1658  *
1659  * DESCRIPTION: Compile SLIT.
1660  *
1661  *****************************************************************************/
1662
1663 ACPI_STATUS
1664 DtCompileSlit (
1665     void                    **List)
1666 {
1667     ACPI_STATUS             Status;
1668     DT_SUBTABLE             *Subtable;
1669     DT_SUBTABLE             *ParentTable;
1670     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1671     DT_FIELD                *FieldList;
1672     UINT32                  Localities;
1673     UINT8                   *LocalityBuffer;
1674
1675
1676     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1677                 &Subtable, TRUE);
1678     if (ACPI_FAILURE (Status))
1679     {
1680         return (Status);
1681     }
1682
1683     ParentTable = DtPeekSubtable ();
1684     DtInsertSubtable (ParentTable, Subtable);
1685
1686     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1687     LocalityBuffer = UtLocalCalloc (Localities);
1688
1689     /* Compile each locality buffer */
1690
1691     FieldList = *PFieldList;
1692     while (FieldList)
1693     {
1694         DtCompileBuffer (LocalityBuffer,
1695             FieldList->Value, FieldList, Localities);
1696
1697         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1698         DtInsertSubtable (ParentTable, Subtable);
1699         FieldList = FieldList->Next;
1700     }
1701
1702     ACPI_FREE (LocalityBuffer);
1703     return (AE_OK);
1704 }
1705
1706
1707 /******************************************************************************
1708  *
1709  * FUNCTION:    DtCompileSrat
1710  *
1711  * PARAMETERS:  List                - Current field list pointer
1712  *
1713  * RETURN:      Status
1714  *
1715  * DESCRIPTION: Compile SRAT.
1716  *
1717  *****************************************************************************/
1718
1719 ACPI_STATUS
1720 DtCompileSrat (
1721     void                    **List)
1722 {
1723     ACPI_STATUS             Status;
1724     DT_SUBTABLE             *Subtable;
1725     DT_SUBTABLE             *ParentTable;
1726     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1727     DT_FIELD                *SubtableStart;
1728     ACPI_SUBTABLE_HEADER    *SratHeader;
1729     ACPI_DMTABLE_INFO       *InfoTable;
1730
1731
1732     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1733                 &Subtable, TRUE);
1734     if (ACPI_FAILURE (Status))
1735     {
1736         return (Status);
1737     }
1738
1739     ParentTable = DtPeekSubtable ();
1740     DtInsertSubtable (ParentTable, Subtable);
1741
1742     while (*PFieldList)
1743     {
1744         SubtableStart = *PFieldList;
1745         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1746                     &Subtable, TRUE);
1747         if (ACPI_FAILURE (Status))
1748         {
1749             return (Status);
1750         }
1751
1752         ParentTable = DtPeekSubtable ();
1753         DtInsertSubtable (ParentTable, Subtable);
1754         DtPushSubtable (Subtable);
1755
1756         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1757
1758         switch (SratHeader->Type)
1759         {
1760         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1761             InfoTable = AcpiDmTableInfoSrat0;
1762             break;
1763         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1764             InfoTable = AcpiDmTableInfoSrat1;
1765             break;
1766         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1767             InfoTable = AcpiDmTableInfoSrat2;
1768             break;
1769         default:
1770             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1771             return (AE_ERROR);
1772         }
1773
1774         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1775         if (ACPI_FAILURE (Status))
1776         {
1777             return (Status);
1778         }
1779
1780         ParentTable = DtPeekSubtable ();
1781         DtInsertSubtable (ParentTable, Subtable);
1782         DtPopSubtable ();
1783     }
1784
1785     return (AE_OK);
1786 }
1787
1788
1789 /******************************************************************************
1790  *
1791  * FUNCTION:    DtGetGenericTableInfo
1792  *
1793  * PARAMETERS:  Name                - Generic type name
1794  *
1795  * RETURN:      Info entry
1796  *
1797  * DESCRIPTION: Obtain table info for a generic name entry
1798  *
1799  *****************************************************************************/
1800
1801 ACPI_DMTABLE_INFO *
1802 DtGetGenericTableInfo (
1803     char                    *Name)
1804 {
1805     ACPI_DMTABLE_INFO       *Info;
1806     UINT32                  i;
1807
1808
1809     if (!Name)
1810     {
1811         return (NULL);
1812     }
1813
1814     /* Search info table for name match */
1815
1816     for (i = 0; ; i++)
1817     {
1818         Info = AcpiDmTableInfoGeneric[i];
1819         if (Info->Opcode == ACPI_DMT_EXIT)
1820         {
1821             Info = NULL;
1822             break;
1823         }
1824
1825         /* Use caseless compare for generic keywords */
1826
1827         if (!AcpiUtStricmp (Name, Info->Name))
1828         {
1829             break;
1830         }
1831     }
1832
1833     return (Info);
1834 }
1835
1836
1837 /******************************************************************************
1838  *
1839  * FUNCTION:    DtCompileUefi
1840  *
1841  * PARAMETERS:  List                - Current field list pointer
1842  *
1843  * RETURN:      Status
1844  *
1845  * DESCRIPTION: Compile UEFI.
1846  *
1847  *****************************************************************************/
1848
1849 ACPI_STATUS
1850 DtCompileUefi (
1851     void                    **List)
1852 {
1853     ACPI_STATUS             Status;
1854     DT_SUBTABLE             *Subtable;
1855     DT_SUBTABLE             *ParentTable;
1856     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1857     UINT16                  *DataOffset;
1858
1859
1860     /* Compile the predefined portion of the UEFI table */
1861
1862     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1863                 &Subtable, TRUE);
1864     if (ACPI_FAILURE (Status))
1865     {
1866         return (Status);
1867     }
1868
1869     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1870     *DataOffset = sizeof (ACPI_TABLE_UEFI);
1871
1872     ParentTable = DtPeekSubtable ();
1873     DtInsertSubtable (ParentTable, Subtable);
1874
1875     /*
1876      * Compile the "generic" portion of the UEFI table. This
1877      * part of the table is not predefined and any of the generic
1878      * operators may be used.
1879      */
1880
1881     DtCompileGeneric ((void **) PFieldList);
1882
1883     return (AE_OK);
1884 }
1885
1886
1887 /******************************************************************************
1888  *
1889  * FUNCTION:    DtCompileWdat
1890  *
1891  * PARAMETERS:  List                - Current field list pointer
1892  *
1893  * RETURN:      Status
1894  *
1895  * DESCRIPTION: Compile WDAT.
1896  *
1897  *****************************************************************************/
1898
1899 ACPI_STATUS
1900 DtCompileWdat (
1901     void                    **List)
1902 {
1903     ACPI_STATUS             Status;
1904
1905
1906     Status = DtCompileTwoSubtables (List,
1907                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
1908     return (Status);
1909 }
1910
1911
1912 /******************************************************************************
1913  *
1914  * FUNCTION:    DtCompileXsdt
1915  *
1916  * PARAMETERS:  List                - Current field list pointer
1917  *
1918  * RETURN:      Status
1919  *
1920  * DESCRIPTION: Compile XSDT.
1921  *
1922  *****************************************************************************/
1923
1924 ACPI_STATUS
1925 DtCompileXsdt (
1926     void                    **List)
1927 {
1928     DT_SUBTABLE             *Subtable;
1929     DT_SUBTABLE             *ParentTable;
1930     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1931     UINT64                  Address;
1932
1933     ParentTable = DtPeekSubtable ();
1934
1935     while (FieldList)
1936     {
1937         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
1938
1939         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
1940         DtInsertSubtable (ParentTable, Subtable);
1941         FieldList = FieldList->Next;
1942     }
1943
1944     return (AE_OK);
1945 }
1946
1947
1948 /******************************************************************************
1949  *
1950  * FUNCTION:    DtCompileGeneric
1951  *
1952  * PARAMETERS:  List                - Current field list pointer
1953  *
1954  * RETURN:      Status
1955  *
1956  * DESCRIPTION: Compile generic unknown table.
1957  *
1958  *****************************************************************************/
1959
1960 ACPI_STATUS
1961 DtCompileGeneric (
1962     void                    **List)
1963 {
1964     ACPI_STATUS             Status;
1965     DT_SUBTABLE             *Subtable;
1966     DT_SUBTABLE             *ParentTable;
1967     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1968     ACPI_DMTABLE_INFO       *Info;
1969
1970
1971     ParentTable = DtPeekSubtable ();
1972
1973     /*
1974      * Compile the "generic" portion of the table. This
1975      * part of the table is not predefined and any of the generic
1976      * operators may be used.
1977      */
1978
1979     /* Find any and all labels in the entire generic portion */
1980
1981     DtDetectAllLabels (*PFieldList);
1982
1983     /* Now we can actually compile the parse tree */
1984
1985     while (*PFieldList)
1986     {
1987         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
1988         if (!Info)
1989         {
1990             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
1991                 (*PFieldList)->Name);
1992             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
1993                 (*PFieldList), MsgBuffer);
1994
1995             *PFieldList = (*PFieldList)->Next;
1996             continue;
1997         }
1998
1999         Status = DtCompileTable (PFieldList, Info,
2000                     &Subtable, TRUE);
2001         if (ACPI_SUCCESS (Status))
2002         {
2003             DtInsertSubtable (ParentTable, Subtable);
2004         }
2005         else
2006         {
2007             *PFieldList = (*PFieldList)->Next;
2008
2009             if (Status == AE_NOT_FOUND)
2010             {
2011                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2012                     (*PFieldList)->Name);
2013                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2014                     (*PFieldList), MsgBuffer);
2015             }
2016         }
2017     }
2018
2019     return (AE_OK);
2020 }