xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable.c (revision e8e8c939350bdf3c228a411caa9660c607c27a11)
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 <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include <contrib/dev/acpica/compiler/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                     !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 && *Length)
3407     {
3408         *Length = 0;
3409     }
3410     while (*PFieldList)
3411     {
3412         if (Name && !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 }
3454