Sync ACPICA with Intel's version 20150515.
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / dttable.c
1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2015, 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 /* Compile all complex data tables */
45
46 #include "aslcompiler.h"
47 #include "dtcompiler.h"
48
49 #define _COMPONENT          DT_COMPILER
50         ACPI_MODULE_NAME    ("dttable")
51
52
53 /* TBD: merge these into dmtbinfo.c? */
54
55 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
56 {
57     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
58     {ACPI_DMT_EXIT,     0,               NULL, 0}
59 };
60
61 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
62 {
63     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
64     {ACPI_DMT_EXIT,     0,               NULL, 0}
65 };
66
67
68 /* Local prototypes */
69
70 static ACPI_STATUS
71 DtCompileTwoSubtables (
72     void                    **List,
73     ACPI_DMTABLE_INFO       *TableInfo1,
74     ACPI_DMTABLE_INFO       *TableInfo2);
75
76
77 /******************************************************************************
78  *
79  * FUNCTION:    DtCompileTwoSubtables
80  *
81  * PARAMETERS:  List                - Current field list pointer
82  *              TableInfo1          - Info table 1
83  *              TableInfo1          - Info table 2
84  *
85  * RETURN:      Status
86  *
87  * DESCRIPTION: Compile tables with a header and one or more same subtables.
88  *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
89  *
90  *****************************************************************************/
91
92 static ACPI_STATUS
93 DtCompileTwoSubtables (
94     void                    **List,
95     ACPI_DMTABLE_INFO       *TableInfo1,
96     ACPI_DMTABLE_INFO       *TableInfo2)
97 {
98     ACPI_STATUS             Status;
99     DT_SUBTABLE             *Subtable;
100     DT_SUBTABLE             *ParentTable;
101     DT_FIELD                **PFieldList = (DT_FIELD **) List;
102
103
104     Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
105     if (ACPI_FAILURE (Status))
106     {
107         return (Status);
108     }
109
110     ParentTable = DtPeekSubtable ();
111     DtInsertSubtable (ParentTable, Subtable);
112
113     while (*PFieldList)
114     {
115         Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
116         if (ACPI_FAILURE (Status))
117         {
118             return (Status);
119         }
120
121         DtInsertSubtable (ParentTable, Subtable);
122     }
123
124     return (AE_OK);
125 }
126
127
128 /******************************************************************************
129  *
130  * FUNCTION:    DtCompileFacs
131  *
132  * PARAMETERS:  PFieldList          - Current field list pointer
133  *
134  * RETURN:      Status
135  *
136  * DESCRIPTION: Compile FACS.
137  *
138  *****************************************************************************/
139
140 ACPI_STATUS
141 DtCompileFacs (
142     DT_FIELD                **PFieldList)
143 {
144     DT_SUBTABLE             *Subtable;
145     UINT8                   *ReservedBuffer;
146     ACPI_STATUS             Status;
147     UINT32                  ReservedSize;
148
149
150     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
151                 &Gbl_RootTable, TRUE);
152     if (ACPI_FAILURE (Status))
153     {
154         return (Status);
155     }
156
157     /* Large FACS reserved area at the end of the table */
158
159     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
160     ReservedBuffer = UtLocalCalloc (ReservedSize);
161
162     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
163
164     ACPI_FREE (ReservedBuffer);
165     DtInsertSubtable (Gbl_RootTable, Subtable);
166     return (AE_OK);
167 }
168
169
170 /******************************************************************************
171  *
172  * FUNCTION:    DtCompileRsdp
173  *
174  * PARAMETERS:  PFieldList          - Current field list pointer
175  *
176  * RETURN:      Status
177  *
178  * DESCRIPTION: Compile RSDP.
179  *
180  *****************************************************************************/
181
182 ACPI_STATUS
183 DtCompileRsdp (
184     DT_FIELD                **PFieldList)
185 {
186     DT_SUBTABLE             *Subtable;
187     ACPI_TABLE_RSDP         *Rsdp;
188     ACPI_RSDP_EXTENSION     *RsdpExtension;
189     ACPI_STATUS             Status;
190
191
192     /* Compile the "common" RSDP (ACPI 1.0) */
193
194     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
195                 &Gbl_RootTable, TRUE);
196     if (ACPI_FAILURE (Status))
197     {
198         return (Status);
199     }
200
201     Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
202     DtSetTableChecksum (&Rsdp->Checksum);
203
204     if (Rsdp->Revision > 0)
205     {
206         /* Compile the "extended" part of the RSDP as a subtable */
207
208         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
209                     &Subtable, TRUE);
210         if (ACPI_FAILURE (Status))
211         {
212             return (Status);
213         }
214
215         DtInsertSubtable (Gbl_RootTable, Subtable);
216
217         /* Set length and extended checksum for entire RSDP */
218
219         RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
220         RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
221         DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
222     }
223
224     return (AE_OK);
225 }
226
227
228 /******************************************************************************
229  *
230  * FUNCTION:    DtCompileAsf
231  *
232  * PARAMETERS:  List                - Current field list pointer
233  *
234  * RETURN:      Status
235  *
236  * DESCRIPTION: Compile ASF!.
237  *
238  *****************************************************************************/
239
240 ACPI_STATUS
241 DtCompileAsf (
242     void                    **List)
243 {
244     ACPI_ASF_INFO           *AsfTable;
245     DT_SUBTABLE             *Subtable;
246     DT_SUBTABLE             *ParentTable;
247     ACPI_DMTABLE_INFO       *InfoTable;
248     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
249     UINT32                  DataCount = 0;
250     ACPI_STATUS             Status;
251     UINT32                  i;
252     DT_FIELD                **PFieldList = (DT_FIELD **) List;
253     DT_FIELD                *SubtableStart;
254
255
256     while (*PFieldList)
257     {
258         SubtableStart = *PFieldList;
259         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
260                     &Subtable, TRUE);
261         if (ACPI_FAILURE (Status))
262         {
263             return (Status);
264         }
265
266         ParentTable = DtPeekSubtable ();
267         DtInsertSubtable (ParentTable, Subtable);
268         DtPushSubtable (Subtable);
269
270         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
271
272         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
273         {
274         case ACPI_ASF_TYPE_INFO:
275
276             InfoTable = AcpiDmTableInfoAsf0;
277             break;
278
279         case ACPI_ASF_TYPE_ALERT:
280
281             InfoTable = AcpiDmTableInfoAsf1;
282             break;
283
284         case ACPI_ASF_TYPE_CONTROL:
285
286             InfoTable = AcpiDmTableInfoAsf2;
287             break;
288
289         case ACPI_ASF_TYPE_BOOT:
290
291             InfoTable = AcpiDmTableInfoAsf3;
292             break;
293
294         case ACPI_ASF_TYPE_ADDRESS:
295
296             InfoTable = AcpiDmTableInfoAsf4;
297             break;
298
299         default:
300
301             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
302             return (AE_ERROR);
303         }
304
305         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
306         if (ACPI_FAILURE (Status))
307         {
308             return (Status);
309         }
310
311         ParentTable = DtPeekSubtable ();
312         DtInsertSubtable (ParentTable, Subtable);
313
314         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
315         {
316         case ACPI_ASF_TYPE_INFO:
317
318             DataInfoTable = NULL;
319             break;
320
321         case ACPI_ASF_TYPE_ALERT:
322
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
331             DataInfoTable = AcpiDmTableInfoAsf2a;
332             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
333                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
334                             sizeof (ACPI_ASF_HEADER)))->Controls;
335             break;
336
337         case ACPI_ASF_TYPE_BOOT:
338
339             DataInfoTable = NULL;
340             break;
341
342         case ACPI_ASF_TYPE_ADDRESS:
343
344             DataInfoTable = TableInfoAsfAddress;
345             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
346                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
347                             sizeof (ACPI_ASF_HEADER)))->Devices;
348             break;
349
350         default:
351
352             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
353             return (AE_ERROR);
354         }
355
356         if (DataInfoTable)
357         {
358             switch (AsfTable->Header.Type & 0x7F)
359             {
360             case ACPI_ASF_TYPE_ADDRESS:
361
362                 while (DataCount > 0)
363                 {
364                     Status = DtCompileTable (PFieldList, DataInfoTable,
365                                 &Subtable, TRUE);
366                     if (ACPI_FAILURE (Status))
367                     {
368                         return (Status);
369                     }
370
371                     DtInsertSubtable (ParentTable, Subtable);
372                     DataCount = DataCount - Subtable->Length;
373                 }
374                 break;
375
376             default:
377
378                 for (i = 0; i < DataCount; i++)
379                 {
380                     Status = DtCompileTable (PFieldList, DataInfoTable,
381                                 &Subtable, TRUE);
382                     if (ACPI_FAILURE (Status))
383                     {
384                         return (Status);
385                     }
386
387                     DtInsertSubtable (ParentTable, Subtable);
388                 }
389                 break;
390             }
391         }
392
393         DtPopSubtable ();
394     }
395
396     return (AE_OK);
397 }
398
399
400 /******************************************************************************
401  *
402  * FUNCTION:    DtCompileCpep
403  *
404  * PARAMETERS:  List                - Current field list pointer
405  *
406  * RETURN:      Status
407  *
408  * DESCRIPTION: Compile CPEP.
409  *
410  *****************************************************************************/
411
412 ACPI_STATUS
413 DtCompileCpep (
414     void                    **List)
415 {
416     ACPI_STATUS             Status;
417
418
419     Status = DtCompileTwoSubtables (List,
420                  AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
421     return (Status);
422 }
423
424
425 /******************************************************************************
426  *
427  * FUNCTION:    DtCompileCsrt
428  *
429  * PARAMETERS:  List                - Current field list pointer
430  *
431  * RETURN:      Status
432  *
433  * DESCRIPTION: Compile CSRT.
434  *
435  *****************************************************************************/
436
437 ACPI_STATUS
438 DtCompileCsrt (
439     void                    **List)
440 {
441     ACPI_STATUS             Status = AE_OK;
442     DT_SUBTABLE             *Subtable;
443     DT_SUBTABLE             *ParentTable;
444     DT_FIELD                **PFieldList = (DT_FIELD **) List;
445     UINT32                  DescriptorCount;
446     UINT32                  GroupLength;
447
448
449     /* Subtables (Resource Groups) */
450
451     ParentTable = DtPeekSubtable ();
452     while (*PFieldList)
453     {
454         /* Resource group subtable */
455
456         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
457                     &Subtable, TRUE);
458         if (ACPI_FAILURE (Status))
459         {
460             return (Status);
461         }
462
463         /* Compute the number of resource descriptors */
464
465         GroupLength =
466             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
467                 Subtable->Buffer))->Length -
468             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
469                 Subtable->Buffer))->SharedInfoLength -
470             sizeof (ACPI_CSRT_GROUP);
471
472         DescriptorCount = (GroupLength  /
473             sizeof (ACPI_CSRT_DESCRIPTOR));
474
475         DtInsertSubtable (ParentTable, Subtable);
476         DtPushSubtable (Subtable);
477         ParentTable = DtPeekSubtable ();
478
479         /* Shared info subtable (One per resource group) */
480
481         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
482                     &Subtable, TRUE);
483         if (ACPI_FAILURE (Status))
484         {
485             return (Status);
486         }
487
488         DtInsertSubtable (ParentTable, Subtable);
489
490         /* Sub-Subtables (Resource Descriptors) */
491
492         while (*PFieldList && DescriptorCount)
493         {
494
495             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
496                         &Subtable, TRUE);
497             if (ACPI_FAILURE (Status))
498             {
499                 return (Status);
500             }
501             DtInsertSubtable (ParentTable, Subtable);
502
503             DtPushSubtable (Subtable);
504             ParentTable = DtPeekSubtable ();
505             if (*PFieldList)
506             {
507                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
508                             &Subtable, TRUE);
509                 if (ACPI_FAILURE (Status))
510                 {
511                     return (Status);
512                 }
513                 if (Subtable)
514                 {
515                     DtInsertSubtable (ParentTable, Subtable);
516                 }
517             }
518             DtPopSubtable ();
519             ParentTable = DtPeekSubtable ();
520
521             DescriptorCount--;
522         }
523
524         DtPopSubtable ();
525         ParentTable = DtPeekSubtable ();
526     }
527
528     return (Status);
529 }
530
531
532 /******************************************************************************
533  *
534  * FUNCTION:    DtCompileDbg2
535  *
536  * PARAMETERS:  List                - Current field list pointer
537  *
538  * RETURN:      Status
539  *
540  * DESCRIPTION: Compile DBG2.
541  *
542  *****************************************************************************/
543
544 ACPI_STATUS
545 DtCompileDbg2 (
546     void                    **List)
547 {
548     ACPI_STATUS             Status;
549     DT_SUBTABLE             *Subtable;
550     DT_SUBTABLE             *ParentTable;
551     DT_FIELD                **PFieldList = (DT_FIELD **) List;
552     UINT32                  SubtableCount;
553     ACPI_DBG2_HEADER        *Dbg2Header;
554     ACPI_DBG2_DEVICE        *DeviceInfo;
555     UINT16                  CurrentOffset;
556     UINT32                  i;
557
558
559     /* Main table */
560
561     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
562     if (ACPI_FAILURE (Status))
563     {
564         return (Status);
565     }
566
567     ParentTable = DtPeekSubtable ();
568     DtInsertSubtable (ParentTable, Subtable);
569
570     /* Main table fields */
571
572     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
573     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
574         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
575
576     SubtableCount = Dbg2Header->InfoCount;
577     DtPushSubtable (Subtable);
578
579     /* Process all Device Information subtables (Count = InfoCount) */
580
581     while (*PFieldList && SubtableCount)
582     {
583         /* Subtable: Debug Device Information */
584
585         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
586                     &Subtable, TRUE);
587         if (ACPI_FAILURE (Status))
588         {
589             return (Status);
590         }
591
592         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
593         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
594
595         ParentTable = DtPeekSubtable ();
596         DtInsertSubtable (ParentTable, Subtable);
597         DtPushSubtable (Subtable);
598
599         ParentTable = DtPeekSubtable ();
600
601         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
602
603         DeviceInfo->BaseAddressOffset = CurrentOffset;
604         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
605         {
606             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
607                         &Subtable, TRUE);
608             if (ACPI_FAILURE (Status))
609             {
610                 return (Status);
611             }
612
613             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
614             DtInsertSubtable (ParentTable, Subtable);
615         }
616
617         /* AddressSize array (Required, size = RegisterCount) */
618
619         DeviceInfo->AddressSizeOffset = CurrentOffset;
620         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
621         {
622             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
623                         &Subtable, TRUE);
624             if (ACPI_FAILURE (Status))
625             {
626                 return (Status);
627             }
628
629             CurrentOffset += (UINT16) sizeof (UINT32);
630             DtInsertSubtable (ParentTable, Subtable);
631         }
632
633         /* NamespaceString device identifier (Required, size = NamePathLength) */
634
635         DeviceInfo->NamepathOffset = CurrentOffset;
636         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
637                     &Subtable, TRUE);
638         if (ACPI_FAILURE (Status))
639         {
640             return (Status);
641         }
642
643         /* Update the device info header */
644
645         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
646         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
647         DtInsertSubtable (ParentTable, Subtable);
648
649         /* OemData - Variable-length data (Optional, size = OemDataLength) */
650
651         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
652                     &Subtable, TRUE);
653         if (ACPI_FAILURE (Status))
654         {
655             return (Status);
656         }
657
658         /* Update the device info header (zeros if no OEM data present) */
659
660         DeviceInfo->OemDataOffset = 0;
661         DeviceInfo->OemDataLength = 0;
662
663         /* Optional subtable (OemData) */
664
665         if (Subtable && Subtable->Length)
666         {
667             DeviceInfo->OemDataOffset = CurrentOffset;
668             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
669
670             DtInsertSubtable (ParentTable, Subtable);
671         }
672
673         SubtableCount--;
674         DtPopSubtable (); /* Get next Device Information subtable */
675     }
676
677     DtPopSubtable ();
678     return (AE_OK);
679 }
680
681
682 /******************************************************************************
683  *
684  * FUNCTION:    DtCompileDmar
685  *
686  * PARAMETERS:  List                - Current field list pointer
687  *
688  * RETURN:      Status
689  *
690  * DESCRIPTION: Compile DMAR.
691  *
692  *****************************************************************************/
693
694 ACPI_STATUS
695 DtCompileDmar (
696     void                    **List)
697 {
698     ACPI_STATUS             Status;
699     DT_SUBTABLE             *Subtable;
700     DT_SUBTABLE             *ParentTable;
701     DT_FIELD                **PFieldList = (DT_FIELD **) List;
702     DT_FIELD                *SubtableStart;
703     ACPI_DMTABLE_INFO       *InfoTable;
704     ACPI_DMAR_HEADER        *DmarHeader;
705     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
706     UINT32                  DeviceScopeLength;
707     UINT32                  PciPathLength;
708
709
710     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &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     while (*PFieldList)
721     {
722         /* DMAR Header */
723
724         SubtableStart = *PFieldList;
725         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
726                     &Subtable, TRUE);
727         if (ACPI_FAILURE (Status))
728         {
729             return (Status);
730         }
731
732         ParentTable = DtPeekSubtable ();
733         DtInsertSubtable (ParentTable, Subtable);
734         DtPushSubtable (Subtable);
735
736         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
737
738         switch (DmarHeader->Type)
739         {
740         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
741
742             InfoTable = AcpiDmTableInfoDmar0;
743             break;
744
745         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
746
747             InfoTable = AcpiDmTableInfoDmar1;
748             break;
749
750         case ACPI_DMAR_TYPE_ROOT_ATS:
751
752             InfoTable = AcpiDmTableInfoDmar2;
753             break;
754
755         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
756
757             InfoTable = AcpiDmTableInfoDmar3;
758             break;
759
760         case ACPI_DMAR_TYPE_NAMESPACE:
761
762             InfoTable = AcpiDmTableInfoDmar4;
763             break;
764
765         default:
766
767             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
768             return (AE_ERROR);
769         }
770
771         /* DMAR Subtable */
772
773         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
774         if (ACPI_FAILURE (Status))
775         {
776             return (Status);
777         }
778
779         ParentTable = DtPeekSubtable ();
780         DtInsertSubtable (ParentTable, Subtable);
781
782         /*
783          * Optional Device Scope subtables
784          */
785         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
786             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
787         {
788             /* These types do not support device scopes */
789
790             DtPopSubtable ();
791             continue;
792         }
793
794         DtPushSubtable (Subtable);
795         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
796             ParentTable->Length;
797         while (DeviceScopeLength)
798         {
799             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
800                         &Subtable, FALSE);
801             if (Status == AE_NOT_FOUND)
802             {
803                 break;
804             }
805
806             ParentTable = DtPeekSubtable ();
807             DtInsertSubtable (ParentTable, Subtable);
808             DtPushSubtable (Subtable);
809
810             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
811
812             /* Optional PCI Paths */
813
814             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
815             while (PciPathLength)
816             {
817                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
818                             &Subtable, FALSE);
819                 if (Status == AE_NOT_FOUND)
820                 {
821                     DtPopSubtable ();
822                     break;
823                 }
824
825                 ParentTable = DtPeekSubtable ();
826                 DtInsertSubtable (ParentTable, Subtable);
827                 PciPathLength -= Subtable->Length;
828             }
829
830             DtPopSubtable ();
831             DeviceScopeLength -= DmarDeviceScope->Length;
832         }
833
834         DtPopSubtable ();
835         DtPopSubtable ();
836     }
837
838     return (AE_OK);
839 }
840
841
842 /******************************************************************************
843  *
844  * FUNCTION:    DtCompileDrtm
845  *
846  * PARAMETERS:  List                - Current field list pointer
847  *
848  * RETURN:      Status
849  *
850  * DESCRIPTION: Compile DRTM.
851  *
852  *****************************************************************************/
853
854 ACPI_STATUS
855 DtCompileDrtm (
856     void                    **List)
857 {
858     ACPI_STATUS             Status;
859     DT_SUBTABLE             *Subtable;
860     DT_SUBTABLE             *ParentTable;
861     DT_FIELD                **PFieldList = (DT_FIELD **) List;
862     UINT32                  Count;
863     /* ACPI_TABLE_DRTM         *Drtm; */
864     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
865     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
866     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
867
868
869     ParentTable = DtPeekSubtable ();
870
871     /* Compile DRTM header */
872
873     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
874                 &Subtable, TRUE);
875     if (ACPI_FAILURE (Status))
876     {
877         return (Status);
878     }
879     DtInsertSubtable (ParentTable, Subtable);
880
881     /*
882      * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
883      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
884      */
885 #if 0
886     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
887                     Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
888 #endif
889     /* Compile VTL */
890
891     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
892                 &Subtable, TRUE);
893     if (ACPI_FAILURE (Status))
894     {
895         return (Status);
896     }
897     DtInsertSubtable (ParentTable, Subtable);
898     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
899
900     DtPushSubtable (Subtable);
901     ParentTable = DtPeekSubtable ();
902     Count = 0;
903     while (*PFieldList)
904     {
905         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
906                     &Subtable, TRUE);
907         if (ACPI_FAILURE (Status))
908         {
909             return (Status);
910         }
911         if (!Subtable)
912         {
913             break;
914         }
915         DtInsertSubtable (ParentTable, Subtable);
916         Count++;
917     }
918     DrtmVtl->ValidatedTableCount = Count;
919     DtPopSubtable ();
920     ParentTable = DtPeekSubtable ();
921
922     /* Compile RL */
923
924     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
925                 &Subtable, TRUE);
926     if (ACPI_FAILURE (Status))
927     {
928         return (Status);
929     }
930     DtInsertSubtable (ParentTable, Subtable);
931     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
932
933     DtPushSubtable (Subtable);
934     ParentTable = DtPeekSubtable ();
935     Count = 0;
936     while (*PFieldList)
937     {
938         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
939                     &Subtable, TRUE);
940         if (ACPI_FAILURE (Status))
941         {
942             return (Status);
943         }
944         if (!Subtable)
945         {
946             break;
947         }
948         DtInsertSubtable (ParentTable, Subtable);
949         Count++;
950     }
951     DrtmRl->ResourceCount = Count;
952     DtPopSubtable ();
953     ParentTable = DtPeekSubtable ();
954
955     /* Compile DPS */
956
957     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
958                 &Subtable, TRUE);
959     if (ACPI_FAILURE (Status))
960     {
961         return (Status);
962     }
963     DtInsertSubtable (ParentTable, Subtable);
964     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
965
966
967     return (AE_OK);
968 }
969
970
971 /******************************************************************************
972  *
973  * FUNCTION:    DtCompileEinj
974  *
975  * PARAMETERS:  List                - Current field list pointer
976  *
977  * RETURN:      Status
978  *
979  * DESCRIPTION: Compile EINJ.
980  *
981  *****************************************************************************/
982
983 ACPI_STATUS
984 DtCompileEinj (
985     void                    **List)
986 {
987     ACPI_STATUS             Status;
988
989
990     Status = DtCompileTwoSubtables (List,
991                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
992     return (Status);
993 }
994
995
996 /******************************************************************************
997  *
998  * FUNCTION:    DtCompileErst
999  *
1000  * PARAMETERS:  List                - Current field list pointer
1001  *
1002  * RETURN:      Status
1003  *
1004  * DESCRIPTION: Compile ERST.
1005  *
1006  *****************************************************************************/
1007
1008 ACPI_STATUS
1009 DtCompileErst (
1010     void                    **List)
1011 {
1012     ACPI_STATUS             Status;
1013
1014
1015     Status = DtCompileTwoSubtables (List,
1016                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1017     return (Status);
1018 }
1019
1020
1021 /******************************************************************************
1022  *
1023  * FUNCTION:    DtCompileFadt
1024  *
1025  * PARAMETERS:  List                - Current field list pointer
1026  *
1027  * RETURN:      Status
1028  *
1029  * DESCRIPTION: Compile FADT.
1030  *
1031  *****************************************************************************/
1032
1033 ACPI_STATUS
1034 DtCompileFadt (
1035     void                    **List)
1036 {
1037     ACPI_STATUS             Status;
1038     DT_SUBTABLE             *Subtable;
1039     DT_SUBTABLE             *ParentTable;
1040     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1041     ACPI_TABLE_HEADER       *Table;
1042     UINT8                   Revision;
1043
1044
1045     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
1046                 &Subtable, TRUE);
1047     if (ACPI_FAILURE (Status))
1048     {
1049         return (Status);
1050     }
1051
1052     ParentTable = DtPeekSubtable ();
1053     DtInsertSubtable (ParentTable, Subtable);
1054
1055     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1056     Revision = Table->Revision;
1057
1058     if (Revision == 2)
1059     {
1060         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
1061                     &Subtable, TRUE);
1062         if (ACPI_FAILURE (Status))
1063         {
1064             return (Status);
1065         }
1066
1067         DtInsertSubtable (ParentTable, Subtable);
1068     }
1069     else if (Revision >= 2)
1070     {
1071         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
1072                     &Subtable, TRUE);
1073         if (ACPI_FAILURE (Status))
1074         {
1075             return (Status);
1076         }
1077
1078         DtInsertSubtable (ParentTable, Subtable);
1079
1080         if (Revision >= 5)
1081         {
1082             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
1083                         &Subtable, TRUE);
1084             if (ACPI_FAILURE (Status))
1085             {
1086                 return (Status);
1087             }
1088
1089             DtInsertSubtable (ParentTable, Subtable);
1090         }
1091
1092         if (Revision >= 6)
1093         {
1094             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt6,
1095                         &Subtable, TRUE);
1096             if (ACPI_FAILURE (Status))
1097             {
1098                 return (Status);
1099             }
1100
1101             DtInsertSubtable (ParentTable, Subtable);
1102         }
1103     }
1104
1105     return (AE_OK);
1106 }
1107
1108 /******************************************************************************
1109  *
1110  * FUNCTION:    DtCompileGtdt
1111  *
1112  * PARAMETERS:  List                - Current field list pointer
1113  *
1114  * RETURN:      Status
1115  *
1116  * DESCRIPTION: Compile GTDT.
1117  *
1118  *****************************************************************************/
1119
1120 ACPI_STATUS
1121 DtCompileGtdt (
1122     void                    **List)
1123 {
1124     ACPI_STATUS             Status;
1125     DT_SUBTABLE             *Subtable;
1126     DT_SUBTABLE             *ParentTable;
1127     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1128     DT_FIELD                *SubtableStart;
1129     ACPI_SUBTABLE_HEADER    *GtdtHeader;
1130     ACPI_DMTABLE_INFO       *InfoTable;
1131     UINT32                  GtCount;
1132
1133
1134     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1135                 &Subtable, TRUE);
1136     if (ACPI_FAILURE (Status))
1137     {
1138         return (Status);
1139     }
1140
1141     ParentTable = DtPeekSubtable ();
1142     DtInsertSubtable (ParentTable, Subtable);
1143
1144     while (*PFieldList)
1145     {
1146         SubtableStart = *PFieldList;
1147         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1148                     &Subtable, TRUE);
1149         if (ACPI_FAILURE (Status))
1150         {
1151             return (Status);
1152         }
1153
1154         ParentTable = DtPeekSubtable ();
1155         DtInsertSubtable (ParentTable, Subtable);
1156         DtPushSubtable (Subtable);
1157
1158         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1159
1160         switch (GtdtHeader->Type)
1161         {
1162         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1163
1164             InfoTable = AcpiDmTableInfoGtdt0;
1165             break;
1166
1167         case ACPI_GTDT_TYPE_WATCHDOG:
1168
1169             InfoTable = AcpiDmTableInfoGtdt1;
1170             break;
1171
1172         default:
1173
1174             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1175             return (AE_ERROR);
1176         }
1177
1178         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1179         if (ACPI_FAILURE (Status))
1180         {
1181             return (Status);
1182         }
1183
1184         ParentTable = DtPeekSubtable ();
1185         DtInsertSubtable (ParentTable, Subtable);
1186
1187         /*
1188          * Additional GT block subtable data
1189          */
1190
1191         switch (GtdtHeader->Type)
1192         {
1193         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1194
1195             DtPushSubtable (Subtable);
1196             ParentTable = DtPeekSubtable ();
1197
1198             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1199                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1200             while (GtCount)
1201             {
1202                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1203                             &Subtable, TRUE);
1204                 if (ACPI_FAILURE (Status))
1205                 {
1206                     return (Status);
1207                 }
1208
1209
1210                 DtInsertSubtable (ParentTable, Subtable);
1211                 GtCount--;
1212             }
1213             DtPopSubtable ();
1214             break;
1215
1216         default:
1217
1218             break;
1219         }
1220
1221         DtPopSubtable ();
1222     }
1223
1224     return (AE_OK);
1225 }
1226
1227
1228 /******************************************************************************
1229  *
1230  * FUNCTION:    DtCompileFpdt
1231  *
1232  * PARAMETERS:  List                - Current field list pointer
1233  *
1234  * RETURN:      Status
1235  *
1236  * DESCRIPTION: Compile FPDT.
1237  *
1238  *****************************************************************************/
1239
1240 ACPI_STATUS
1241 DtCompileFpdt (
1242     void                    **List)
1243 {
1244     ACPI_STATUS             Status;
1245     ACPI_FPDT_HEADER        *FpdtHeader;
1246     DT_SUBTABLE             *Subtable;
1247     DT_SUBTABLE             *ParentTable;
1248     ACPI_DMTABLE_INFO       *InfoTable;
1249     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1250     DT_FIELD                *SubtableStart;
1251
1252
1253     while (*PFieldList)
1254     {
1255         SubtableStart = *PFieldList;
1256         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1257                     &Subtable, TRUE);
1258         if (ACPI_FAILURE (Status))
1259         {
1260             return (Status);
1261         }
1262
1263         ParentTable = DtPeekSubtable ();
1264         DtInsertSubtable (ParentTable, Subtable);
1265         DtPushSubtable (Subtable);
1266
1267         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1268
1269         switch (FpdtHeader->Type)
1270         {
1271         case ACPI_FPDT_TYPE_BOOT:
1272
1273             InfoTable = AcpiDmTableInfoFpdt0;
1274             break;
1275
1276         case ACPI_FPDT_TYPE_S3PERF:
1277
1278             InfoTable = AcpiDmTableInfoFpdt1;
1279             break;
1280
1281         default:
1282
1283             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1284             return (AE_ERROR);
1285             break;
1286         }
1287
1288         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1289         if (ACPI_FAILURE (Status))
1290         {
1291             return (Status);
1292         }
1293
1294         ParentTable = DtPeekSubtable ();
1295         DtInsertSubtable (ParentTable, Subtable);
1296         DtPopSubtable ();
1297     }
1298
1299     return (AE_OK);
1300 }
1301
1302
1303 /******************************************************************************
1304  *
1305  * FUNCTION:    DtCompileHest
1306  *
1307  * PARAMETERS:  List                - Current field list pointer
1308  *
1309  * RETURN:      Status
1310  *
1311  * DESCRIPTION: Compile HEST.
1312  *
1313  *****************************************************************************/
1314
1315 ACPI_STATUS
1316 DtCompileHest (
1317     void                    **List)
1318 {
1319     ACPI_STATUS             Status;
1320     DT_SUBTABLE             *Subtable;
1321     DT_SUBTABLE             *ParentTable;
1322     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1323     DT_FIELD                *SubtableStart;
1324     ACPI_DMTABLE_INFO       *InfoTable;
1325     UINT16                  Type;
1326     UINT32                  BankCount;
1327
1328
1329     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1330                 &Subtable, TRUE);
1331     if (ACPI_FAILURE (Status))
1332     {
1333         return (Status);
1334     }
1335
1336     ParentTable = DtPeekSubtable ();
1337     DtInsertSubtable (ParentTable, Subtable);
1338
1339     while (*PFieldList)
1340     {
1341         /* Get subtable type */
1342
1343         SubtableStart = *PFieldList;
1344         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1345
1346         switch (Type)
1347         {
1348         case ACPI_HEST_TYPE_IA32_CHECK:
1349
1350             InfoTable = AcpiDmTableInfoHest0;
1351             break;
1352
1353         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1354
1355             InfoTable = AcpiDmTableInfoHest1;
1356             break;
1357
1358         case ACPI_HEST_TYPE_IA32_NMI:
1359
1360             InfoTable = AcpiDmTableInfoHest2;
1361             break;
1362
1363         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1364
1365             InfoTable = AcpiDmTableInfoHest6;
1366             break;
1367
1368         case ACPI_HEST_TYPE_AER_ENDPOINT:
1369
1370             InfoTable = AcpiDmTableInfoHest7;
1371             break;
1372
1373         case ACPI_HEST_TYPE_AER_BRIDGE:
1374
1375             InfoTable = AcpiDmTableInfoHest8;
1376             break;
1377
1378         case ACPI_HEST_TYPE_GENERIC_ERROR:
1379
1380             InfoTable = AcpiDmTableInfoHest9;
1381             break;
1382
1383         default:
1384
1385             /* Cannot continue on unknown type */
1386
1387             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1388             return (AE_ERROR);
1389         }
1390
1391         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1392         if (ACPI_FAILURE (Status))
1393         {
1394             return (Status);
1395         }
1396
1397         DtInsertSubtable (ParentTable, Subtable);
1398
1399         /*
1400          * Additional subtable data - IA32 Error Bank(s)
1401          */
1402         BankCount = 0;
1403         switch (Type)
1404         {
1405         case ACPI_HEST_TYPE_IA32_CHECK:
1406
1407             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1408                             Subtable->Buffer))->NumHardwareBanks;
1409             break;
1410
1411         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1412
1413             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1414                             Subtable->Buffer))->NumHardwareBanks;
1415             break;
1416
1417         default:
1418
1419             break;
1420         }
1421
1422         while (BankCount)
1423         {
1424             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1425                         &Subtable, TRUE);
1426             if (ACPI_FAILURE (Status))
1427             {
1428                 return (Status);
1429             }
1430
1431             DtInsertSubtable (ParentTable, Subtable);
1432             BankCount--;
1433         }
1434     }
1435
1436     return (AE_OK);
1437 }
1438
1439
1440 /******************************************************************************
1441  *
1442  * FUNCTION:    DtCompileIort
1443  *
1444  * PARAMETERS:  List                - Current field list pointer
1445  *
1446  * RETURN:      Status
1447  *
1448  * DESCRIPTION: Compile IORT.
1449  *
1450  *****************************************************************************/
1451
1452 ACPI_STATUS
1453 DtCompileIort (
1454     void                    **List)
1455 {
1456     ACPI_STATUS             Status;
1457     DT_SUBTABLE             *Subtable;
1458     DT_SUBTABLE             *ParentTable;
1459     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1460     DT_FIELD                *SubtableStart;
1461     ACPI_TABLE_IORT         *Iort;
1462     ACPI_IORT_NODE          *IortNode;
1463     ACPI_IORT_ITS_GROUP     *IortItsGroup;
1464     ACPI_IORT_SMMU          *IortSmmu;
1465     UINT32                  NodeNumber;
1466     UINT32                  NodeLength;
1467     UINT32                  IdMappingNumber;
1468     UINT32                  ItsNumber;
1469     UINT32                  ContextIrptNumber;
1470     UINT32                  PmuIrptNumber;
1471     UINT32                  PaddingLength;
1472
1473
1474     ParentTable = DtPeekSubtable ();
1475
1476     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1477                 &Subtable, TRUE);
1478     if (ACPI_FAILURE (Status))
1479     {
1480         return (Status);
1481     }
1482     DtInsertSubtable (ParentTable, Subtable);
1483
1484     /*
1485      * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
1486      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1487      */
1488     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1489                     Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1490
1491     /*
1492      * OptionalPadding - Variable-length data
1493      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1494      * Optionally allows the generic data types to be used for filling
1495      * this field.
1496      */
1497     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1498     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1499                     &Subtable, TRUE);
1500     if (ACPI_FAILURE (Status))
1501     {
1502         return (Status);
1503     }
1504     if (Subtable)
1505     {
1506         DtInsertSubtable (ParentTable, Subtable);
1507         Iort->NodeOffset += Subtable->Length;
1508     }
1509     else
1510     {
1511         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1512                     AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1513         if (ACPI_FAILURE (Status))
1514         {
1515             return (Status);
1516         }
1517         Iort->NodeOffset += PaddingLength;
1518     }
1519
1520     NodeNumber = 0;
1521     while (*PFieldList)
1522     {
1523         SubtableStart = *PFieldList;
1524         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1525                     &Subtable, TRUE);
1526         if (ACPI_FAILURE (Status))
1527         {
1528             return (Status);
1529         }
1530         DtInsertSubtable (ParentTable, Subtable);
1531         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1532         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1533
1534         DtPushSubtable (Subtable);
1535         ParentTable = DtPeekSubtable ();
1536
1537         switch (IortNode->Type)
1538         {
1539         case ACPI_IORT_NODE_ITS_GROUP:
1540
1541             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1542                         &Subtable, TRUE);
1543             if (ACPI_FAILURE (Status))
1544             {
1545                 return (Status);
1546             }
1547             DtInsertSubtable (ParentTable, Subtable);
1548             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1549             NodeLength += Subtable->Length;
1550
1551             ItsNumber = 0;
1552             while (*PFieldList)
1553             {
1554                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1555                             &Subtable, TRUE);
1556                 if (ACPI_FAILURE (Status))
1557                 {
1558                     return (Status);
1559                 }
1560                 if (!Subtable)
1561                 {
1562                     break;
1563                 }
1564                 DtInsertSubtable (ParentTable, Subtable);
1565                 NodeLength += Subtable->Length;
1566                 ItsNumber++;
1567             }
1568
1569             IortItsGroup->ItsCount = ItsNumber;
1570             break;
1571
1572         case ACPI_IORT_NODE_NAMED_COMPONENT:
1573
1574             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1575                         &Subtable, TRUE);
1576             if (ACPI_FAILURE (Status))
1577             {
1578                 return (Status);
1579             }
1580             DtInsertSubtable (ParentTable, Subtable);
1581             NodeLength += Subtable->Length;
1582
1583             /*
1584              * Padding - Variable-length data
1585              * Optionally allows the offset of the ID mappings to be used
1586              * for filling this field.
1587              */
1588             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1589                             &Subtable, TRUE);
1590             if (ACPI_FAILURE (Status))
1591             {
1592                 return (Status);
1593             }
1594             if (Subtable)
1595             {
1596                 DtInsertSubtable (ParentTable, Subtable);
1597                 NodeLength += Subtable->Length;
1598             }
1599             else
1600             {
1601                 if (NodeLength > IortNode->MappingOffset)
1602                 {
1603                     return (AE_BAD_DATA);
1604                 }
1605                 if (NodeLength < IortNode->MappingOffset)
1606                 {
1607                     Status = DtCompilePadding (
1608                                 IortNode->MappingOffset - NodeLength,
1609                                 &Subtable);
1610                     if (ACPI_FAILURE (Status))
1611                     {
1612                         return (Status);
1613                     }
1614                     DtInsertSubtable (ParentTable, Subtable);
1615                     NodeLength = IortNode->MappingOffset;
1616                 }
1617             }
1618             break;
1619
1620         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1621
1622             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1623                         &Subtable, TRUE);
1624             if (ACPI_FAILURE (Status))
1625             {
1626                 return (Status);
1627             }
1628             DtInsertSubtable (ParentTable, Subtable);
1629             NodeLength += Subtable->Length;
1630             break;
1631
1632         case ACPI_IORT_NODE_SMMU:
1633
1634             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1635                         &Subtable, TRUE);
1636             if (ACPI_FAILURE (Status))
1637             {
1638                 return (Status);
1639             }
1640             DtInsertSubtable (ParentTable, Subtable);
1641             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1642             NodeLength += Subtable->Length;
1643
1644             /* Compile global interrupt array */
1645
1646             IortSmmu->GlobalInterruptOffset = NodeLength;
1647             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1648                         &Subtable, TRUE);
1649             if (ACPI_FAILURE (Status))
1650             {
1651                 return (Status);
1652             }
1653             DtInsertSubtable (ParentTable, Subtable);
1654             NodeLength += Subtable->Length;
1655
1656             /* Compile context interrupt array */
1657
1658             ContextIrptNumber = 0;
1659             IortSmmu->ContextInterruptOffset = NodeLength;
1660             while (*PFieldList)
1661             {
1662                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1663                             &Subtable, TRUE);
1664                 if (ACPI_FAILURE (Status))
1665                 {
1666                     return (Status);
1667                 }
1668                 if (!Subtable)
1669                 {
1670                     break;
1671                 }
1672                 DtInsertSubtable (ParentTable, Subtable);
1673                 NodeLength += Subtable->Length;
1674                 ContextIrptNumber++;
1675             }
1676             IortSmmu->ContextInterruptCount = ContextIrptNumber;
1677
1678             /* Compile PMU interrupt array */
1679
1680             PmuIrptNumber = 0;
1681             IortSmmu->PmuInterruptOffset = NodeLength;
1682             while (*PFieldList)
1683             {
1684                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1685                             &Subtable, TRUE);
1686                 if (ACPI_FAILURE (Status))
1687                 {
1688                     return (Status);
1689                 }
1690                 if (!Subtable)
1691                 {
1692                     break;
1693                 }
1694                 DtInsertSubtable (ParentTable, Subtable);
1695                 NodeLength += Subtable->Length;
1696                 PmuIrptNumber++;
1697             }
1698             IortSmmu->PmuInterruptCount = PmuIrptNumber;
1699             break;
1700
1701         default:
1702
1703             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1704             return (AE_ERROR);
1705         }
1706
1707         /* Compile Array of ID mappings */
1708
1709         IortNode->MappingOffset = NodeLength;
1710         IdMappingNumber = 0;
1711         while (*PFieldList)
1712         {
1713             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1714                         &Subtable, TRUE);
1715             if (ACPI_FAILURE (Status))
1716             {
1717                 return (Status);
1718             }
1719             if (!Subtable)
1720             {
1721                 break;
1722             }
1723             DtInsertSubtable (ParentTable, Subtable);
1724             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1725             IdMappingNumber++;
1726         }
1727         IortNode->MappingCount = IdMappingNumber;
1728
1729         /*
1730          * Node length can be determined by DT_LENGTH option
1731          * IortNode->Length = NodeLength;
1732          */
1733         DtPopSubtable ();
1734         ParentTable = DtPeekSubtable ();
1735         NodeNumber++;
1736     }
1737     Iort->NodeCount = NodeNumber;
1738
1739     return (AE_OK);
1740 }
1741
1742
1743 /******************************************************************************
1744  *
1745  * FUNCTION:    DtCompileIvrs
1746  *
1747  * PARAMETERS:  List                - Current field list pointer
1748  *
1749  * RETURN:      Status
1750  *
1751  * DESCRIPTION: Compile IVRS.
1752  *
1753  *****************************************************************************/
1754
1755 ACPI_STATUS
1756 DtCompileIvrs (
1757     void                    **List)
1758 {
1759     ACPI_STATUS             Status;
1760     DT_SUBTABLE             *Subtable;
1761     DT_SUBTABLE             *ParentTable;
1762     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1763     DT_FIELD                *SubtableStart;
1764     ACPI_DMTABLE_INFO       *InfoTable;
1765     ACPI_IVRS_HEADER        *IvrsHeader;
1766     UINT8                   EntryType;
1767
1768
1769     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1770                 &Subtable, TRUE);
1771     if (ACPI_FAILURE (Status))
1772     {
1773         return (Status);
1774     }
1775
1776     ParentTable = DtPeekSubtable ();
1777     DtInsertSubtable (ParentTable, Subtable);
1778
1779     while (*PFieldList)
1780     {
1781         SubtableStart = *PFieldList;
1782         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1783                     &Subtable, TRUE);
1784         if (ACPI_FAILURE (Status))
1785         {
1786             return (Status);
1787         }
1788
1789         ParentTable = DtPeekSubtable ();
1790         DtInsertSubtable (ParentTable, Subtable);
1791         DtPushSubtable (Subtable);
1792
1793         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1794
1795         switch (IvrsHeader->Type)
1796         {
1797         case ACPI_IVRS_TYPE_HARDWARE:
1798
1799             InfoTable = AcpiDmTableInfoIvrs0;
1800             break;
1801
1802         case ACPI_IVRS_TYPE_MEMORY1:
1803         case ACPI_IVRS_TYPE_MEMORY2:
1804         case ACPI_IVRS_TYPE_MEMORY3:
1805
1806             InfoTable = AcpiDmTableInfoIvrs1;
1807             break;
1808
1809         default:
1810
1811             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1812             return (AE_ERROR);
1813         }
1814
1815         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1816         if (ACPI_FAILURE (Status))
1817         {
1818             return (Status);
1819         }
1820
1821         ParentTable = DtPeekSubtable ();
1822         DtInsertSubtable (ParentTable, Subtable);
1823
1824         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1825         {
1826             while (*PFieldList &&
1827                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1828             {
1829                 SubtableStart = *PFieldList;
1830                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1831
1832                 switch (EntryType)
1833                 {
1834                 /* 4-byte device entries */
1835
1836                 case ACPI_IVRS_TYPE_PAD4:
1837                 case ACPI_IVRS_TYPE_ALL:
1838                 case ACPI_IVRS_TYPE_SELECT:
1839                 case ACPI_IVRS_TYPE_START:
1840                 case ACPI_IVRS_TYPE_END:
1841
1842                     InfoTable = AcpiDmTableInfoIvrs4;
1843                     break;
1844
1845                 /* 8-byte entries, type A */
1846
1847                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1848                 case ACPI_IVRS_TYPE_ALIAS_START:
1849
1850                     InfoTable = AcpiDmTableInfoIvrs8a;
1851                     break;
1852
1853                 /* 8-byte entries, type B */
1854
1855                 case ACPI_IVRS_TYPE_PAD8:
1856                 case ACPI_IVRS_TYPE_EXT_SELECT:
1857                 case ACPI_IVRS_TYPE_EXT_START:
1858
1859                     InfoTable = AcpiDmTableInfoIvrs8b;
1860                     break;
1861
1862                 /* 8-byte entries, type C */
1863
1864                 case ACPI_IVRS_TYPE_SPECIAL:
1865
1866                     InfoTable = AcpiDmTableInfoIvrs8c;
1867                     break;
1868
1869                 default:
1870
1871                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1872                         "IVRS Device Entry");
1873                     return (AE_ERROR);
1874                 }
1875
1876                 Status = DtCompileTable (PFieldList, InfoTable,
1877                             &Subtable, TRUE);
1878                 if (ACPI_FAILURE (Status))
1879                 {
1880                     return (Status);
1881                 }
1882
1883                 DtInsertSubtable (ParentTable, Subtable);
1884             }
1885         }
1886
1887         DtPopSubtable ();
1888     }
1889
1890     return (AE_OK);
1891 }
1892
1893
1894 /******************************************************************************
1895  *
1896  * FUNCTION:    DtCompileLpit
1897  *
1898  * PARAMETERS:  List                - Current field list pointer
1899  *
1900  * RETURN:      Status
1901  *
1902  * DESCRIPTION: Compile LPIT.
1903  *
1904  *****************************************************************************/
1905
1906 ACPI_STATUS
1907 DtCompileLpit (
1908     void                    **List)
1909 {
1910     ACPI_STATUS             Status;
1911     DT_SUBTABLE             *Subtable;
1912     DT_SUBTABLE             *ParentTable;
1913     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1914     DT_FIELD                *SubtableStart;
1915     ACPI_DMTABLE_INFO       *InfoTable;
1916     ACPI_LPIT_HEADER        *LpitHeader;
1917
1918
1919     /* Note: Main table consists only of the standard ACPI table header */
1920
1921     while (*PFieldList)
1922     {
1923         SubtableStart = *PFieldList;
1924
1925         /* LPIT Subtable header */
1926
1927         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1928                     &Subtable, TRUE);
1929         if (ACPI_FAILURE (Status))
1930         {
1931             return (Status);
1932         }
1933
1934         ParentTable = DtPeekSubtable ();
1935         DtInsertSubtable (ParentTable, Subtable);
1936         DtPushSubtable (Subtable);
1937
1938         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1939
1940         switch (LpitHeader->Type)
1941         {
1942         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1943
1944             InfoTable = AcpiDmTableInfoLpit0;
1945             break;
1946
1947         default:
1948
1949             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1950             return (AE_ERROR);
1951         }
1952
1953         /* LPIT Subtable */
1954
1955         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1956         if (ACPI_FAILURE (Status))
1957         {
1958             return (Status);
1959         }
1960
1961         ParentTable = DtPeekSubtable ();
1962         DtInsertSubtable (ParentTable, Subtable);
1963         DtPopSubtable ();
1964     }
1965
1966     return (AE_OK);
1967 }
1968
1969
1970 /******************************************************************************
1971  *
1972  * FUNCTION:    DtCompileMadt
1973  *
1974  * PARAMETERS:  List                - Current field list pointer
1975  *
1976  * RETURN:      Status
1977  *
1978  * DESCRIPTION: Compile MADT.
1979  *
1980  *****************************************************************************/
1981
1982 ACPI_STATUS
1983 DtCompileMadt (
1984     void                    **List)
1985 {
1986     ACPI_STATUS             Status;
1987     DT_SUBTABLE             *Subtable;
1988     DT_SUBTABLE             *ParentTable;
1989     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1990     DT_FIELD                *SubtableStart;
1991     ACPI_SUBTABLE_HEADER    *MadtHeader;
1992     ACPI_DMTABLE_INFO       *InfoTable;
1993
1994
1995     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1996                 &Subtable, TRUE);
1997     if (ACPI_FAILURE (Status))
1998     {
1999         return (Status);
2000     }
2001
2002     ParentTable = DtPeekSubtable ();
2003     DtInsertSubtable (ParentTable, Subtable);
2004
2005     while (*PFieldList)
2006     {
2007         SubtableStart = *PFieldList;
2008         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
2009                     &Subtable, TRUE);
2010         if (ACPI_FAILURE (Status))
2011         {
2012             return (Status);
2013         }
2014
2015         ParentTable = DtPeekSubtable ();
2016         DtInsertSubtable (ParentTable, Subtable);
2017         DtPushSubtable (Subtable);
2018
2019         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2020
2021         switch (MadtHeader->Type)
2022         {
2023         case ACPI_MADT_TYPE_LOCAL_APIC:
2024
2025             InfoTable = AcpiDmTableInfoMadt0;
2026             break;
2027
2028         case ACPI_MADT_TYPE_IO_APIC:
2029
2030             InfoTable = AcpiDmTableInfoMadt1;
2031             break;
2032
2033         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
2034
2035             InfoTable = AcpiDmTableInfoMadt2;
2036             break;
2037
2038         case ACPI_MADT_TYPE_NMI_SOURCE:
2039
2040             InfoTable = AcpiDmTableInfoMadt3;
2041             break;
2042
2043         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
2044
2045             InfoTable = AcpiDmTableInfoMadt4;
2046             break;
2047
2048         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
2049
2050             InfoTable = AcpiDmTableInfoMadt5;
2051             break;
2052
2053         case ACPI_MADT_TYPE_IO_SAPIC:
2054
2055             InfoTable = AcpiDmTableInfoMadt6;
2056             break;
2057
2058         case ACPI_MADT_TYPE_LOCAL_SAPIC:
2059
2060             InfoTable = AcpiDmTableInfoMadt7;
2061             break;
2062
2063         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
2064
2065             InfoTable = AcpiDmTableInfoMadt8;
2066             break;
2067
2068         case ACPI_MADT_TYPE_LOCAL_X2APIC:
2069
2070             InfoTable = AcpiDmTableInfoMadt9;
2071             break;
2072
2073         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
2074
2075             InfoTable = AcpiDmTableInfoMadt10;
2076             break;
2077
2078         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
2079
2080             InfoTable = AcpiDmTableInfoMadt11;
2081             break;
2082
2083         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
2084
2085             InfoTable = AcpiDmTableInfoMadt12;
2086             break;
2087
2088         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
2089
2090             InfoTable = AcpiDmTableInfoMadt13;
2091             break;
2092
2093         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
2094
2095             InfoTable = AcpiDmTableInfoMadt14;
2096             break;
2097
2098         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
2099
2100             InfoTable = AcpiDmTableInfoMadt15;
2101             break;
2102
2103         default:
2104
2105             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
2106             return (AE_ERROR);
2107         }
2108
2109         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2110         if (ACPI_FAILURE (Status))
2111         {
2112             return (Status);
2113         }
2114
2115         ParentTable = DtPeekSubtable ();
2116         DtInsertSubtable (ParentTable, Subtable);
2117         DtPopSubtable ();
2118     }
2119
2120     return (AE_OK);
2121 }
2122
2123
2124 /******************************************************************************
2125  *
2126  * FUNCTION:    DtCompileMcfg
2127  *
2128  * PARAMETERS:  List                - Current field list pointer
2129  *
2130  * RETURN:      Status
2131  *
2132  * DESCRIPTION: Compile MCFG.
2133  *
2134  *****************************************************************************/
2135
2136 ACPI_STATUS
2137 DtCompileMcfg (
2138     void                    **List)
2139 {
2140     ACPI_STATUS             Status;
2141
2142
2143     Status = DtCompileTwoSubtables (List,
2144                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
2145     return (Status);
2146 }
2147
2148
2149 /******************************************************************************
2150  *
2151  * FUNCTION:    DtCompileMpst
2152  *
2153  * PARAMETERS:  List                - Current field list pointer
2154  *
2155  * RETURN:      Status
2156  *
2157  * DESCRIPTION: Compile MPST.
2158  *
2159  *****************************************************************************/
2160
2161 ACPI_STATUS
2162 DtCompileMpst (
2163     void                    **List)
2164 {
2165     ACPI_STATUS             Status;
2166     DT_SUBTABLE             *Subtable;
2167     DT_SUBTABLE             *ParentTable;
2168     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2169     ACPI_MPST_CHANNEL       *MpstChannelInfo;
2170     ACPI_MPST_POWER_NODE    *MpstPowerNode;
2171     ACPI_MPST_DATA_HDR      *MpstDataHeader;
2172     UINT16                  SubtableCount;
2173     UINT32                  PowerStateCount;
2174     UINT32                  ComponentCount;
2175
2176
2177     /* Main table */
2178
2179     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
2180     if (ACPI_FAILURE (Status))
2181     {
2182         return (Status);
2183     }
2184
2185     ParentTable = DtPeekSubtable ();
2186     DtInsertSubtable (ParentTable, Subtable);
2187     DtPushSubtable (Subtable);
2188
2189     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
2190     SubtableCount = MpstChannelInfo->PowerNodeCount;
2191
2192     while (*PFieldList && SubtableCount)
2193     {
2194         /* Subtable: Memory Power Node(s) */
2195
2196         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
2197                     &Subtable, TRUE);
2198         if (ACPI_FAILURE (Status))
2199         {
2200             return (Status);
2201         }
2202
2203         ParentTable = DtPeekSubtable ();
2204         DtInsertSubtable (ParentTable, Subtable);
2205         DtPushSubtable (Subtable);
2206
2207         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
2208         PowerStateCount = MpstPowerNode->NumPowerStates;
2209         ComponentCount = MpstPowerNode->NumPhysicalComponents;
2210
2211         ParentTable = DtPeekSubtable ();
2212
2213         /* Sub-subtables - Memory Power State Structure(s) */
2214
2215         while (*PFieldList && PowerStateCount)
2216         {
2217             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
2218                         &Subtable, TRUE);
2219             if (ACPI_FAILURE (Status))
2220             {
2221                 return (Status);
2222             }
2223
2224             DtInsertSubtable (ParentTable, Subtable);
2225             PowerStateCount--;
2226         }
2227
2228         /* Sub-subtables - Physical Component ID Structure(s) */
2229
2230         while (*PFieldList && ComponentCount)
2231         {
2232             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
2233                         &Subtable, TRUE);
2234             if (ACPI_FAILURE (Status))
2235             {
2236                 return (Status);
2237             }
2238
2239             DtInsertSubtable (ParentTable, Subtable);
2240             ComponentCount--;
2241         }
2242
2243         SubtableCount--;
2244         DtPopSubtable ();
2245     }
2246
2247     /* Subtable: Count of Memory Power State Characteristic structures */
2248
2249     DtPopSubtable ();
2250
2251     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
2252     if (ACPI_FAILURE (Status))
2253     {
2254         return (Status);
2255     }
2256
2257     ParentTable = DtPeekSubtable ();
2258     DtInsertSubtable (ParentTable, Subtable);
2259     DtPushSubtable (Subtable);
2260
2261     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
2262     SubtableCount = MpstDataHeader->CharacteristicsCount;
2263
2264     ParentTable = DtPeekSubtable ();
2265
2266     /* Subtable: Memory Power State Characteristics structure(s) */
2267
2268     while (*PFieldList && SubtableCount)
2269     {
2270         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
2271                     &Subtable, TRUE);
2272         if (ACPI_FAILURE (Status))
2273         {
2274             return (Status);
2275         }
2276
2277         DtInsertSubtable (ParentTable, Subtable);
2278         SubtableCount--;
2279     }
2280
2281     DtPopSubtable ();
2282     return (AE_OK);
2283 }
2284
2285
2286 /******************************************************************************
2287  *
2288  * FUNCTION:    DtCompileMsct
2289  *
2290  * PARAMETERS:  List                - Current field list pointer
2291  *
2292  * RETURN:      Status
2293  *
2294  * DESCRIPTION: Compile MSCT.
2295  *
2296  *****************************************************************************/
2297
2298 ACPI_STATUS
2299 DtCompileMsct (
2300     void                    **List)
2301 {
2302     ACPI_STATUS             Status;
2303
2304
2305     Status = DtCompileTwoSubtables (List,
2306                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
2307     return (Status);
2308 }
2309
2310
2311 /******************************************************************************
2312  *
2313  * FUNCTION:    DtCompileMtmr
2314  *
2315  * PARAMETERS:  List                - Current field list pointer
2316  *
2317  * RETURN:      Status
2318  *
2319  * DESCRIPTION: Compile MTMR.
2320  *
2321  *****************************************************************************/
2322
2323 ACPI_STATUS
2324 DtCompileMtmr (
2325     void                    **List)
2326 {
2327     ACPI_STATUS             Status;
2328
2329
2330     Status = DtCompileTwoSubtables (List,
2331                  AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
2332     return (Status);
2333 }
2334
2335
2336 /******************************************************************************
2337  *
2338  * FUNCTION:    DtCompileNfit
2339  *
2340  * PARAMETERS:  List                - Current field list pointer
2341  *
2342  * RETURN:      Status
2343  *
2344  * DESCRIPTION: Compile NFIT.
2345  *
2346  *****************************************************************************/
2347
2348 ACPI_STATUS
2349 DtCompileNfit (
2350     void                    **List)
2351 {
2352     ACPI_STATUS             Status;
2353     DT_SUBTABLE             *Subtable;
2354     DT_SUBTABLE             *ParentTable;
2355     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2356     DT_FIELD                *SubtableStart;
2357     ACPI_NFIT_HEADER        *NfitHeader;
2358     ACPI_DMTABLE_INFO       *InfoTable;
2359     UINT32                  Count;
2360     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
2361     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
2362
2363     /* Main table */
2364
2365     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
2366                 &Subtable, TRUE);
2367     if (ACPI_FAILURE (Status))
2368     {
2369         return (Status);
2370     }
2371
2372     ParentTable = DtPeekSubtable ();
2373     DtInsertSubtable (ParentTable, Subtable);
2374     DtPushSubtable (Subtable);
2375
2376     /* Subtables */
2377
2378     while (*PFieldList)
2379     {
2380         SubtableStart = *PFieldList;
2381         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
2382                     &Subtable, TRUE);
2383         if (ACPI_FAILURE (Status))
2384         {
2385             return (Status);
2386         }
2387
2388         ParentTable = DtPeekSubtable ();
2389         DtInsertSubtable (ParentTable, Subtable);
2390         DtPushSubtable (Subtable);
2391
2392         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
2393
2394         switch (NfitHeader->Type)
2395         {
2396         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2397
2398             InfoTable = AcpiDmTableInfoNfit0;
2399             break;
2400
2401         case ACPI_NFIT_TYPE_MEMORY_MAP:
2402
2403             InfoTable = AcpiDmTableInfoNfit1;
2404             break;
2405
2406         case ACPI_NFIT_TYPE_INTERLEAVE:
2407
2408             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
2409             InfoTable = AcpiDmTableInfoNfit2;
2410             break;
2411
2412         case ACPI_NFIT_TYPE_SMBIOS:
2413
2414             InfoTable = AcpiDmTableInfoNfit3;
2415             break;
2416
2417         case ACPI_NFIT_TYPE_CONTROL_REGION:
2418
2419             InfoTable = AcpiDmTableInfoNfit4;
2420             break;
2421
2422         case ACPI_NFIT_TYPE_DATA_REGION:
2423
2424             InfoTable = AcpiDmTableInfoNfit5;
2425             break;
2426
2427         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2428
2429             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
2430             InfoTable = AcpiDmTableInfoNfit6;
2431             break;
2432
2433         default:
2434
2435             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
2436             return (AE_ERROR);
2437         }
2438
2439         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2440         if (ACPI_FAILURE (Status))
2441         {
2442             return (Status);
2443         }
2444
2445         ParentTable = DtPeekSubtable ();
2446         DtInsertSubtable (ParentTable, Subtable);
2447         DtPopSubtable ();
2448
2449         switch (NfitHeader->Type)
2450         {
2451         case ACPI_NFIT_TYPE_INTERLEAVE:
2452
2453             Count = 0;
2454             DtPushSubtable (Subtable);
2455             while (*PFieldList)
2456             {
2457                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
2458                             &Subtable, FALSE);
2459                 if (ACPI_FAILURE (Status))
2460                 {
2461                     return (Status);
2462                 }
2463                 if (!Subtable)
2464                 {
2465                     DtPopSubtable ();
2466                     break;
2467                 }
2468
2469                 ParentTable = DtPeekSubtable ();
2470                 DtInsertSubtable (ParentTable, Subtable);
2471                 Count++;
2472             }
2473
2474             Interleave->LineCount = Count;
2475             DtPopSubtable ();
2476             break;
2477
2478         case ACPI_NFIT_TYPE_SMBIOS:
2479
2480             if (*PFieldList)
2481             {
2482                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
2483                             &Subtable, TRUE);
2484                 if (ACPI_FAILURE (Status))
2485                 {
2486                     return (Status);
2487                 }
2488                 if (Subtable)
2489                 {
2490                     DtInsertSubtable (ParentTable, Subtable);
2491                 }
2492             }
2493             break;
2494
2495         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2496
2497             Count = 0;
2498             DtPushSubtable (Subtable);
2499             while (*PFieldList)
2500             {
2501                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
2502                             &Subtable, FALSE);
2503                 if (ACPI_FAILURE (Status))
2504                 {
2505                     return (Status);
2506                 }
2507                 if (!Subtable)
2508                 {
2509                     DtPopSubtable ();
2510                     break;
2511                 }
2512
2513                 ParentTable = DtPeekSubtable ();
2514                 DtInsertSubtable (ParentTable, Subtable);
2515                 Count++;
2516             }
2517
2518             Hint->HintCount = (UINT16) Count;
2519             DtPopSubtable ();
2520             break;
2521
2522         default:
2523             break;
2524         }
2525     }
2526
2527     return (AE_OK);
2528 }
2529
2530
2531 /******************************************************************************
2532  *
2533  * FUNCTION:    DtCompilePcct
2534  *
2535  * PARAMETERS:  List                - Current field list pointer
2536  *
2537  * RETURN:      Status
2538  *
2539  * DESCRIPTION: Compile PCCT.
2540  *
2541  *****************************************************************************/
2542
2543 ACPI_STATUS
2544 DtCompilePcct (
2545     void                    **List)
2546 {
2547     ACPI_STATUS             Status;
2548     DT_SUBTABLE             *Subtable;
2549     DT_SUBTABLE             *ParentTable;
2550     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2551     DT_FIELD                *SubtableStart;
2552     ACPI_SUBTABLE_HEADER    *PcctHeader;
2553     ACPI_DMTABLE_INFO       *InfoTable;
2554
2555
2556     /* Main table */
2557
2558     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
2559                 &Subtable, TRUE);
2560     if (ACPI_FAILURE (Status))
2561     {
2562         return (Status);
2563     }
2564
2565     ParentTable = DtPeekSubtable ();
2566     DtInsertSubtable (ParentTable, Subtable);
2567
2568     /* Subtables */
2569
2570     while (*PFieldList)
2571     {
2572         SubtableStart = *PFieldList;
2573         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
2574                     &Subtable, TRUE);
2575         if (ACPI_FAILURE (Status))
2576         {
2577             return (Status);
2578         }
2579
2580         ParentTable = DtPeekSubtable ();
2581         DtInsertSubtable (ParentTable, Subtable);
2582         DtPushSubtable (Subtable);
2583
2584         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2585
2586         switch (PcctHeader->Type)
2587         {
2588         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
2589
2590             InfoTable = AcpiDmTableInfoPcct0;
2591             break;
2592
2593         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
2594
2595             InfoTable = AcpiDmTableInfoPcct1;
2596             break;
2597
2598         default:
2599
2600             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
2601             return (AE_ERROR);
2602         }
2603
2604         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2605         if (ACPI_FAILURE (Status))
2606         {
2607             return (Status);
2608         }
2609
2610         ParentTable = DtPeekSubtable ();
2611         DtInsertSubtable (ParentTable, Subtable);
2612         DtPopSubtable ();
2613     }
2614
2615     return (AE_OK);
2616 }
2617
2618
2619 /******************************************************************************
2620  *
2621  * FUNCTION:    DtCompilePmtt
2622  *
2623  * PARAMETERS:  List                - Current field list pointer
2624  *
2625  * RETURN:      Status
2626  *
2627  * DESCRIPTION: Compile PMTT.
2628  *
2629  *****************************************************************************/
2630
2631 ACPI_STATUS
2632 DtCompilePmtt (
2633     void                    **List)
2634 {
2635     ACPI_STATUS             Status;
2636     DT_SUBTABLE             *Subtable;
2637     DT_SUBTABLE             *ParentTable;
2638     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2639     DT_FIELD                *SubtableStart;
2640     ACPI_PMTT_HEADER        *PmttHeader;
2641     ACPI_PMTT_CONTROLLER    *PmttController;
2642     UINT16                  DomainCount;
2643     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
2644
2645
2646     /* Main table */
2647
2648     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
2649     if (ACPI_FAILURE (Status))
2650     {
2651         return (Status);
2652     }
2653
2654     ParentTable = DtPeekSubtable ();
2655     DtInsertSubtable (ParentTable, Subtable);
2656     DtPushSubtable (Subtable);
2657
2658     while (*PFieldList)
2659     {
2660         SubtableStart = *PFieldList;
2661         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
2662                     &Subtable, TRUE);
2663         if (ACPI_FAILURE (Status))
2664         {
2665             return (Status);
2666         }
2667
2668         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
2669         while (PrevType >= PmttHeader->Type)
2670         {
2671             DtPopSubtable ();
2672
2673             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
2674             {
2675                 break;
2676             }
2677             PrevType--;
2678         }
2679         PrevType = PmttHeader->Type;
2680
2681         ParentTable = DtPeekSubtable ();
2682         DtInsertSubtable (ParentTable, Subtable);
2683         DtPushSubtable (Subtable);
2684
2685         switch (PmttHeader->Type)
2686         {
2687         case ACPI_PMTT_TYPE_SOCKET:
2688
2689             /* Subtable: Socket Structure */
2690
2691             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
2692                     &Subtable, TRUE);
2693             if (ACPI_FAILURE (Status))
2694             {
2695                 return (Status);
2696             }
2697
2698             ParentTable = DtPeekSubtable ();
2699             DtInsertSubtable (ParentTable, Subtable);
2700             break;
2701
2702         case ACPI_PMTT_TYPE_CONTROLLER:
2703
2704             /* Subtable: Memory Controller Structure */
2705
2706             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
2707                     &Subtable, TRUE);
2708             if (ACPI_FAILURE (Status))
2709             {
2710                 return (Status);
2711             }
2712
2713             ParentTable = DtPeekSubtable ();
2714             DtInsertSubtable (ParentTable, Subtable);
2715
2716             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
2717                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
2718             DomainCount = PmttController->DomainCount;
2719
2720             while (DomainCount)
2721             {
2722                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
2723                     &Subtable, TRUE);
2724                 if (ACPI_FAILURE (Status))
2725                 {
2726                     return (Status);
2727                 }
2728
2729                 DtInsertSubtable (ParentTable, Subtable);
2730                 DomainCount--;
2731             }
2732             break;
2733
2734         case ACPI_PMTT_TYPE_DIMM:
2735
2736             /* Subtable: Physical Component Structure */
2737
2738             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
2739                     &Subtable, TRUE);
2740             if (ACPI_FAILURE (Status))
2741             {
2742                 return (Status);
2743             }
2744
2745             ParentTable = DtPeekSubtable ();
2746             DtInsertSubtable (ParentTable, Subtable);
2747             break;
2748
2749         default:
2750
2751             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
2752             return (AE_ERROR);
2753         }
2754     }
2755
2756     return (Status);
2757 }
2758
2759
2760 /******************************************************************************
2761  *
2762  * FUNCTION:    DtCompileRsdt
2763  *
2764  * PARAMETERS:  List                - Current field list pointer
2765  *
2766  * RETURN:      Status
2767  *
2768  * DESCRIPTION: Compile RSDT.
2769  *
2770  *****************************************************************************/
2771
2772 ACPI_STATUS
2773 DtCompileRsdt (
2774     void                    **List)
2775 {
2776     DT_SUBTABLE             *Subtable;
2777     DT_SUBTABLE             *ParentTable;
2778     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2779     UINT32                  Address;
2780
2781
2782     ParentTable = DtPeekSubtable ();
2783
2784     while (FieldList)
2785     {
2786         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2787
2788         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2789         DtInsertSubtable (ParentTable, Subtable);
2790         FieldList = FieldList->Next;
2791     }
2792
2793     return (AE_OK);
2794 }
2795
2796
2797 /******************************************************************************
2798  *
2799  * FUNCTION:    DtCompileS3pt
2800  *
2801  * PARAMETERS:  PFieldList          - Current field list pointer
2802  *
2803  * RETURN:      Status
2804  *
2805  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2806  *
2807  *****************************************************************************/
2808
2809 ACPI_STATUS
2810 DtCompileS3pt (
2811     DT_FIELD                **PFieldList)
2812 {
2813     ACPI_STATUS             Status;
2814     ACPI_S3PT_HEADER        *S3ptHeader;
2815     DT_SUBTABLE             *Subtable;
2816     DT_SUBTABLE             *ParentTable;
2817     ACPI_DMTABLE_INFO       *InfoTable;
2818     DT_FIELD                *SubtableStart;
2819
2820
2821     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2822                 &Gbl_RootTable, TRUE);
2823     if (ACPI_FAILURE (Status))
2824     {
2825         return (Status);
2826     }
2827
2828     DtPushSubtable (Gbl_RootTable);
2829
2830     while (*PFieldList)
2831     {
2832         SubtableStart = *PFieldList;
2833         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2834                     &Subtable, TRUE);
2835         if (ACPI_FAILURE (Status))
2836         {
2837             return (Status);
2838         }
2839
2840         ParentTable = DtPeekSubtable ();
2841         DtInsertSubtable (ParentTable, Subtable);
2842         DtPushSubtable (Subtable);
2843
2844         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2845
2846         switch (S3ptHeader->Type)
2847         {
2848         case ACPI_S3PT_TYPE_RESUME:
2849
2850             InfoTable = AcpiDmTableInfoS3pt0;
2851             break;
2852
2853         case ACPI_S3PT_TYPE_SUSPEND:
2854
2855             InfoTable = AcpiDmTableInfoS3pt1;
2856             break;
2857
2858         default:
2859
2860             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2861             return (AE_ERROR);
2862         }
2863
2864         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2865         if (ACPI_FAILURE (Status))
2866         {
2867             return (Status);
2868         }
2869
2870         ParentTable = DtPeekSubtable ();
2871         DtInsertSubtable (ParentTable, Subtable);
2872         DtPopSubtable ();
2873     }
2874
2875     return (AE_OK);
2876 }
2877
2878
2879 /******************************************************************************
2880  *
2881  * FUNCTION:    DtCompileSlic
2882  *
2883  * PARAMETERS:  List                - Current field list pointer
2884  *
2885  * RETURN:      Status
2886  *
2887  * DESCRIPTION: Compile SLIC.
2888  *
2889  *****************************************************************************/
2890
2891 ACPI_STATUS
2892 DtCompileSlic (
2893     void                    **List)
2894 {
2895     ACPI_STATUS             Status;
2896     DT_SUBTABLE             *Subtable;
2897     DT_SUBTABLE             *ParentTable;
2898     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2899
2900
2901     while (*PFieldList)
2902     {
2903         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2904                     &Subtable, TRUE);
2905         if (ACPI_FAILURE (Status))
2906         {
2907             return (Status);
2908         }
2909
2910         ParentTable = DtPeekSubtable ();
2911         DtInsertSubtable (ParentTable, Subtable);
2912         DtPushSubtable (Subtable);
2913         DtPopSubtable ();
2914     }
2915
2916     return (AE_OK);
2917 }
2918
2919
2920 /******************************************************************************
2921  *
2922  * FUNCTION:    DtCompileSlit
2923  *
2924  * PARAMETERS:  List                - Current field list pointer
2925  *
2926  * RETURN:      Status
2927  *
2928  * DESCRIPTION: Compile SLIT.
2929  *
2930  *****************************************************************************/
2931
2932 ACPI_STATUS
2933 DtCompileSlit (
2934     void                    **List)
2935 {
2936     ACPI_STATUS             Status;
2937     DT_SUBTABLE             *Subtable;
2938     DT_SUBTABLE             *ParentTable;
2939     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2940     DT_FIELD                *FieldList;
2941     UINT32                  Localities;
2942     UINT8                   *LocalityBuffer;
2943
2944
2945     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2946                 &Subtable, TRUE);
2947     if (ACPI_FAILURE (Status))
2948     {
2949         return (Status);
2950     }
2951
2952     ParentTable = DtPeekSubtable ();
2953     DtInsertSubtable (ParentTable, Subtable);
2954
2955     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2956     LocalityBuffer = UtLocalCalloc (Localities);
2957
2958     /* Compile each locality buffer */
2959
2960     FieldList = *PFieldList;
2961     while (FieldList)
2962     {
2963         DtCompileBuffer (LocalityBuffer,
2964             FieldList->Value, FieldList, Localities);
2965
2966         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2967         DtInsertSubtable (ParentTable, Subtable);
2968         FieldList = FieldList->Next;
2969     }
2970
2971     ACPI_FREE (LocalityBuffer);
2972     return (AE_OK);
2973 }
2974
2975
2976 /******************************************************************************
2977  *
2978  * FUNCTION:    DtCompileSrat
2979  *
2980  * PARAMETERS:  List                - Current field list pointer
2981  *
2982  * RETURN:      Status
2983  *
2984  * DESCRIPTION: Compile SRAT.
2985  *
2986  *****************************************************************************/
2987
2988 ACPI_STATUS
2989 DtCompileSrat (
2990     void                    **List)
2991 {
2992     ACPI_STATUS             Status;
2993     DT_SUBTABLE             *Subtable;
2994     DT_SUBTABLE             *ParentTable;
2995     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2996     DT_FIELD                *SubtableStart;
2997     ACPI_SUBTABLE_HEADER    *SratHeader;
2998     ACPI_DMTABLE_INFO       *InfoTable;
2999
3000
3001     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
3002                 &Subtable, TRUE);
3003     if (ACPI_FAILURE (Status))
3004     {
3005         return (Status);
3006     }
3007
3008     ParentTable = DtPeekSubtable ();
3009     DtInsertSubtable (ParentTable, Subtable);
3010
3011     while (*PFieldList)
3012     {
3013         SubtableStart = *PFieldList;
3014         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
3015                     &Subtable, TRUE);
3016         if (ACPI_FAILURE (Status))
3017         {
3018             return (Status);
3019         }
3020
3021         ParentTable = DtPeekSubtable ();
3022         DtInsertSubtable (ParentTable, Subtable);
3023         DtPushSubtable (Subtable);
3024
3025         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
3026
3027         switch (SratHeader->Type)
3028         {
3029         case ACPI_SRAT_TYPE_CPU_AFFINITY:
3030
3031             InfoTable = AcpiDmTableInfoSrat0;
3032             break;
3033
3034         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
3035
3036             InfoTable = AcpiDmTableInfoSrat1;
3037             break;
3038
3039         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
3040
3041             InfoTable = AcpiDmTableInfoSrat2;
3042             break;
3043
3044         case ACPI_SRAT_TYPE_GICC_AFFINITY:
3045
3046             InfoTable = AcpiDmTableInfoSrat3;
3047             break;
3048
3049         default:
3050
3051             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
3052             return (AE_ERROR);
3053         }
3054
3055         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
3056         if (ACPI_FAILURE (Status))
3057         {
3058             return (Status);
3059         }
3060
3061         ParentTable = DtPeekSubtable ();
3062         DtInsertSubtable (ParentTable, Subtable);
3063         DtPopSubtable ();
3064     }
3065
3066     return (AE_OK);
3067 }
3068
3069
3070 /******************************************************************************
3071  *
3072  * FUNCTION:    DtCompileStao
3073  *
3074  * PARAMETERS:  PFieldList          - Current field list pointer
3075  *
3076  * RETURN:      Status
3077  *
3078  * DESCRIPTION: Compile STAO.
3079  *
3080  *****************************************************************************/
3081
3082 ACPI_STATUS
3083 DtCompileStao (
3084     void                    **List)
3085 {
3086     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3087     DT_SUBTABLE             *Subtable;
3088     DT_SUBTABLE             *ParentTable;
3089     ACPI_STATUS             Status;
3090
3091
3092     /* Compile the main table */
3093
3094     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
3095                 &Subtable, TRUE);
3096     if (ACPI_FAILURE (Status))
3097     {
3098         return (Status);
3099     }
3100
3101     ParentTable = DtPeekSubtable ();
3102     DtInsertSubtable (ParentTable, Subtable);
3103
3104     /* Compile each ASCII namestring as a subtable */
3105
3106     while (*PFieldList)
3107     {
3108         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
3109                     &Subtable, TRUE);
3110         if (ACPI_FAILURE (Status))
3111         {
3112             return (Status);
3113         }
3114
3115         ParentTable = DtPeekSubtable ();
3116         DtInsertSubtable (ParentTable, Subtable);
3117     }
3118
3119     return (AE_OK);
3120 }
3121
3122
3123 /******************************************************************************
3124  *
3125  * FUNCTION:    DtGetGenericTableInfo
3126  *
3127  * PARAMETERS:  Name                - Generic type name
3128  *
3129  * RETURN:      Info entry
3130  *
3131  * DESCRIPTION: Obtain table info for a generic name entry
3132  *
3133  *****************************************************************************/
3134
3135 ACPI_DMTABLE_INFO *
3136 DtGetGenericTableInfo (
3137     char                    *Name)
3138 {
3139     ACPI_DMTABLE_INFO       *Info;
3140     UINT32                  i;
3141
3142
3143     if (!Name)
3144     {
3145         return (NULL);
3146     }
3147
3148     /* Search info table for name match */
3149
3150     for (i = 0; ; i++)
3151     {
3152         Info = AcpiDmTableInfoGeneric[i];
3153         if (Info->Opcode == ACPI_DMT_EXIT)
3154         {
3155             Info = NULL;
3156             break;
3157         }
3158
3159         /* Use caseless compare for generic keywords */
3160
3161         if (!AcpiUtStricmp (Name, Info->Name))
3162         {
3163             break;
3164         }
3165     }
3166
3167     return (Info);
3168 }
3169
3170
3171 /******************************************************************************
3172  *
3173  * FUNCTION:    DtCompileUefi
3174  *
3175  * PARAMETERS:  List                - Current field list pointer
3176  *
3177  * RETURN:      Status
3178  *
3179  * DESCRIPTION: Compile UEFI.
3180  *
3181  *****************************************************************************/
3182
3183 ACPI_STATUS
3184 DtCompileUefi (
3185     void                    **List)
3186 {
3187     ACPI_STATUS             Status;
3188     DT_SUBTABLE             *Subtable;
3189     DT_SUBTABLE             *ParentTable;
3190     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3191     UINT16                  *DataOffset;
3192
3193
3194     /* Compile the predefined portion of the UEFI table */
3195
3196     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
3197                 &Subtable, TRUE);
3198     if (ACPI_FAILURE (Status))
3199     {
3200         return (Status);
3201     }
3202
3203     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
3204     *DataOffset = sizeof (ACPI_TABLE_UEFI);
3205
3206     ParentTable = DtPeekSubtable ();
3207     DtInsertSubtable (ParentTable, Subtable);
3208
3209     /*
3210      * Compile the "generic" portion of the UEFI table. This
3211      * part of the table is not predefined and any of the generic
3212      * operators may be used.
3213      */
3214
3215     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
3216
3217     return (AE_OK);
3218 }
3219
3220
3221 /******************************************************************************
3222  *
3223  * FUNCTION:    DtCompileVrtc
3224  *
3225  * PARAMETERS:  List                - Current field list pointer
3226  *
3227  * RETURN:      Status
3228  *
3229  * DESCRIPTION: Compile VRTC.
3230  *
3231  *****************************************************************************/
3232
3233 ACPI_STATUS
3234 DtCompileVrtc (
3235     void                    **List)
3236 {
3237     ACPI_STATUS             Status;
3238
3239
3240     Status = DtCompileTwoSubtables (List,
3241                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
3242     return (Status);
3243 }
3244
3245
3246 /******************************************************************************
3247  *
3248  * FUNCTION:    DtCompileWdat
3249  *
3250  * PARAMETERS:  List                - Current field list pointer
3251  *
3252  * RETURN:      Status
3253  *
3254  * DESCRIPTION: Compile WDAT.
3255  *
3256  *****************************************************************************/
3257
3258 ACPI_STATUS
3259 DtCompileWdat (
3260     void                    **List)
3261 {
3262     ACPI_STATUS             Status;
3263
3264
3265     Status = DtCompileTwoSubtables (List,
3266                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3267     return (Status);
3268 }
3269
3270
3271 /******************************************************************************
3272  *
3273  * FUNCTION:    DtCompileWpbt
3274  *
3275  * PARAMETERS:  List                - Current field list pointer
3276  *
3277  * RETURN:      Status
3278  *
3279  * DESCRIPTION: Compile WPBT.
3280  *
3281  *****************************************************************************/
3282
3283 ACPI_STATUS
3284 DtCompileWpbt (
3285     void                    **List)
3286 {
3287     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3288     DT_SUBTABLE             *Subtable;
3289     DT_SUBTABLE             *ParentTable;
3290     ACPI_TABLE_WPBT         *Table;
3291     ACPI_STATUS             Status;
3292     UINT16                  Length;
3293
3294
3295     /* Compile the main table */
3296
3297     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
3298                 &Subtable, TRUE);
3299     if (ACPI_FAILURE (Status))
3300     {
3301         return (Status);
3302     }
3303
3304     ParentTable = DtPeekSubtable ();
3305     DtInsertSubtable (ParentTable, Subtable);
3306
3307     /* Compile the argument list subtable */
3308
3309     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
3310                 &Subtable, TRUE);
3311     if (ACPI_FAILURE (Status))
3312     {
3313         return (Status);
3314     }
3315
3316     /* Extract the length of the Arguments buffer, insert into main table */
3317
3318     Length = (UINT16) Subtable->TotalLength;
3319     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3320     Table->ArgumentsLength = Length;
3321
3322     ParentTable = DtPeekSubtable ();
3323     DtInsertSubtable (ParentTable, Subtable);
3324     return (AE_OK);
3325 }
3326
3327
3328 /******************************************************************************
3329  *
3330  * FUNCTION:    DtCompileXsdt
3331  *
3332  * PARAMETERS:  List                - Current field list pointer
3333  *
3334  * RETURN:      Status
3335  *
3336  * DESCRIPTION: Compile XSDT.
3337  *
3338  *****************************************************************************/
3339
3340 ACPI_STATUS
3341 DtCompileXsdt (
3342     void                    **List)
3343 {
3344     DT_SUBTABLE             *Subtable;
3345     DT_SUBTABLE             *ParentTable;
3346     DT_FIELD                *FieldList = *(DT_FIELD **) List;
3347     UINT64                  Address;
3348
3349
3350     ParentTable = DtPeekSubtable ();
3351
3352     while (FieldList)
3353     {
3354         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3355
3356         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3357         DtInsertSubtable (ParentTable, Subtable);
3358         FieldList = FieldList->Next;
3359     }
3360
3361     return (AE_OK);
3362 }
3363
3364
3365 /******************************************************************************
3366  *
3367  * FUNCTION:    DtCompileGeneric
3368  *
3369  * PARAMETERS:  List                - Current field list pointer
3370  *              Name                - Field name to end generic compiling
3371  *              Length              - Compiled table length to return
3372  *
3373  * RETURN:      Status
3374  *
3375  * DESCRIPTION: Compile generic unknown table.
3376  *
3377  *****************************************************************************/
3378
3379 ACPI_STATUS
3380 DtCompileGeneric (
3381     void                    **List,
3382     char                    *Name,
3383     UINT32                  *Length)
3384 {
3385     ACPI_STATUS             Status;
3386     DT_SUBTABLE             *Subtable;
3387     DT_SUBTABLE             *ParentTable;
3388     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3389     ACPI_DMTABLE_INFO       *Info;
3390
3391
3392     ParentTable = DtPeekSubtable ();
3393
3394     /*
3395      * Compile the "generic" portion of the table. This
3396      * part of the table is not predefined and any of the generic
3397      * operators may be used.
3398      */
3399
3400     /* Find any and all labels in the entire generic portion */
3401
3402     DtDetectAllLabels (*PFieldList);
3403
3404     /* Now we can actually compile the parse tree */
3405
3406     if (*Length)
3407     {
3408         *Length = 0;
3409     }
3410     while (*PFieldList)
3411     {
3412         if (Name && !ACPI_STRCMP ((*PFieldList)->Name, Name))
3413         {
3414             break;
3415         }
3416         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3417         if (!Info)
3418         {
3419             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
3420                 (*PFieldList)->Name);
3421             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3422                 (*PFieldList), MsgBuffer);
3423
3424             *PFieldList = (*PFieldList)->Next;
3425             continue;
3426         }
3427
3428         Status = DtCompileTable (PFieldList, Info,
3429                     &Subtable, TRUE);
3430         if (ACPI_SUCCESS (Status))
3431         {
3432             DtInsertSubtable (ParentTable, Subtable);
3433             if (Length)
3434             {
3435                 *Length += Subtable->Length;
3436             }
3437         }
3438         else
3439         {
3440             *PFieldList = (*PFieldList)->Next;
3441
3442             if (Status == AE_NOT_FOUND)
3443             {
3444                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
3445                     (*PFieldList)->Name);
3446                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3447                     (*PFieldList), MsgBuffer);
3448             }
3449         }
3450     }
3451
3452     return (AE_OK);
3453 }