xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/dttable2.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /******************************************************************************
2  *
3  * Module Name: dttable2.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2017, 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, signatures starting with L-Z */
45 
46 #include "aslcompiler.h"
47 
48 #define _COMPONENT          DT_COMPILER
49         ACPI_MODULE_NAME    ("dttable2")
50 
51 
52 /******************************************************************************
53  *
54  * FUNCTION:    DtCompileLpit
55  *
56  * PARAMETERS:  List                - Current field list pointer
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: Compile LPIT.
61  *
62  *****************************************************************************/
63 
64 ACPI_STATUS
65 DtCompileLpit (
66     void                    **List)
67 {
68     ACPI_STATUS             Status;
69     DT_SUBTABLE             *Subtable;
70     DT_SUBTABLE             *ParentTable;
71     DT_FIELD                **PFieldList = (DT_FIELD **) List;
72     DT_FIELD                *SubtableStart;
73     ACPI_DMTABLE_INFO       *InfoTable;
74     ACPI_LPIT_HEADER        *LpitHeader;
75 
76 
77     /* Note: Main table consists only of the standard ACPI table header */
78 
79     while (*PFieldList)
80     {
81         SubtableStart = *PFieldList;
82 
83         /* LPIT Subtable header */
84 
85         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
86             &Subtable, TRUE);
87         if (ACPI_FAILURE (Status))
88         {
89             return (Status);
90         }
91 
92         ParentTable = DtPeekSubtable ();
93         DtInsertSubtable (ParentTable, Subtable);
94         DtPushSubtable (Subtable);
95 
96         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
97 
98         switch (LpitHeader->Type)
99         {
100         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
101 
102             InfoTable = AcpiDmTableInfoLpit0;
103             break;
104 
105         default:
106 
107             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
108             return (AE_ERROR);
109         }
110 
111         /* LPIT Subtable */
112 
113         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
114         if (ACPI_FAILURE (Status))
115         {
116             return (Status);
117         }
118 
119         ParentTable = DtPeekSubtable ();
120         DtInsertSubtable (ParentTable, Subtable);
121         DtPopSubtable ();
122     }
123 
124     return (AE_OK);
125 }
126 
127 
128 /******************************************************************************
129  *
130  * FUNCTION:    DtCompileMadt
131  *
132  * PARAMETERS:  List                - Current field list pointer
133  *
134  * RETURN:      Status
135  *
136  * DESCRIPTION: Compile MADT.
137  *
138  *****************************************************************************/
139 
140 ACPI_STATUS
141 DtCompileMadt (
142     void                    **List)
143 {
144     ACPI_STATUS             Status;
145     DT_SUBTABLE             *Subtable;
146     DT_SUBTABLE             *ParentTable;
147     DT_FIELD                **PFieldList = (DT_FIELD **) List;
148     DT_FIELD                *SubtableStart;
149     ACPI_SUBTABLE_HEADER    *MadtHeader;
150     ACPI_DMTABLE_INFO       *InfoTable;
151 
152 
153     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
154         &Subtable, TRUE);
155     if (ACPI_FAILURE (Status))
156     {
157         return (Status);
158     }
159 
160     ParentTable = DtPeekSubtable ();
161     DtInsertSubtable (ParentTable, Subtable);
162 
163     while (*PFieldList)
164     {
165         SubtableStart = *PFieldList;
166         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
167             &Subtable, TRUE);
168         if (ACPI_FAILURE (Status))
169         {
170             return (Status);
171         }
172 
173         ParentTable = DtPeekSubtable ();
174         DtInsertSubtable (ParentTable, Subtable);
175         DtPushSubtable (Subtable);
176 
177         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
178 
179         switch (MadtHeader->Type)
180         {
181         case ACPI_MADT_TYPE_LOCAL_APIC:
182 
183             InfoTable = AcpiDmTableInfoMadt0;
184             break;
185 
186         case ACPI_MADT_TYPE_IO_APIC:
187 
188             InfoTable = AcpiDmTableInfoMadt1;
189             break;
190 
191         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
192 
193             InfoTable = AcpiDmTableInfoMadt2;
194             break;
195 
196         case ACPI_MADT_TYPE_NMI_SOURCE:
197 
198             InfoTable = AcpiDmTableInfoMadt3;
199             break;
200 
201         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
202 
203             InfoTable = AcpiDmTableInfoMadt4;
204             break;
205 
206         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
207 
208             InfoTable = AcpiDmTableInfoMadt5;
209             break;
210 
211         case ACPI_MADT_TYPE_IO_SAPIC:
212 
213             InfoTable = AcpiDmTableInfoMadt6;
214             break;
215 
216         case ACPI_MADT_TYPE_LOCAL_SAPIC:
217 
218             InfoTable = AcpiDmTableInfoMadt7;
219             break;
220 
221         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
222 
223             InfoTable = AcpiDmTableInfoMadt8;
224             break;
225 
226         case ACPI_MADT_TYPE_LOCAL_X2APIC:
227 
228             InfoTable = AcpiDmTableInfoMadt9;
229             break;
230 
231         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
232 
233             InfoTable = AcpiDmTableInfoMadt10;
234             break;
235 
236         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
237 
238             InfoTable = AcpiDmTableInfoMadt11;
239             break;
240 
241         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
242 
243             InfoTable = AcpiDmTableInfoMadt12;
244             break;
245 
246         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
247 
248             InfoTable = AcpiDmTableInfoMadt13;
249             break;
250 
251         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
252 
253             InfoTable = AcpiDmTableInfoMadt14;
254             break;
255 
256         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
257 
258             InfoTable = AcpiDmTableInfoMadt15;
259             break;
260 
261         default:
262 
263             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
264             return (AE_ERROR);
265         }
266 
267         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
268         if (ACPI_FAILURE (Status))
269         {
270             return (Status);
271         }
272 
273         ParentTable = DtPeekSubtable ();
274         DtInsertSubtable (ParentTable, Subtable);
275         DtPopSubtable ();
276     }
277 
278     return (AE_OK);
279 }
280 
281 
282 /******************************************************************************
283  *
284  * FUNCTION:    DtCompileMcfg
285  *
286  * PARAMETERS:  List                - Current field list pointer
287  *
288  * RETURN:      Status
289  *
290  * DESCRIPTION: Compile MCFG.
291  *
292  *****************************************************************************/
293 
294 ACPI_STATUS
295 DtCompileMcfg (
296     void                    **List)
297 {
298     ACPI_STATUS             Status;
299 
300 
301     Status = DtCompileTwoSubtables (List,
302         AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
303     return (Status);
304 }
305 
306 
307 /******************************************************************************
308  *
309  * FUNCTION:    DtCompileMpst
310  *
311  * PARAMETERS:  List                - Current field list pointer
312  *
313  * RETURN:      Status
314  *
315  * DESCRIPTION: Compile MPST.
316  *
317  *****************************************************************************/
318 
319 ACPI_STATUS
320 DtCompileMpst (
321     void                    **List)
322 {
323     ACPI_STATUS             Status;
324     DT_SUBTABLE             *Subtable;
325     DT_SUBTABLE             *ParentTable;
326     DT_FIELD                **PFieldList = (DT_FIELD **) List;
327     ACPI_MPST_CHANNEL       *MpstChannelInfo;
328     ACPI_MPST_POWER_NODE    *MpstPowerNode;
329     ACPI_MPST_DATA_HDR      *MpstDataHeader;
330     UINT16                  SubtableCount;
331     UINT32                  PowerStateCount;
332     UINT32                  ComponentCount;
333 
334 
335     /* Main table */
336 
337     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
338     if (ACPI_FAILURE (Status))
339     {
340         return (Status);
341     }
342 
343     ParentTable = DtPeekSubtable ();
344     DtInsertSubtable (ParentTable, Subtable);
345     DtPushSubtable (Subtable);
346 
347     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
348     SubtableCount = MpstChannelInfo->PowerNodeCount;
349 
350     while (*PFieldList && SubtableCount)
351     {
352         /* Subtable: Memory Power Node(s) */
353 
354         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
355             &Subtable, TRUE);
356         if (ACPI_FAILURE (Status))
357         {
358             return (Status);
359         }
360 
361         ParentTable = DtPeekSubtable ();
362         DtInsertSubtable (ParentTable, Subtable);
363         DtPushSubtable (Subtable);
364 
365         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
366         PowerStateCount = MpstPowerNode->NumPowerStates;
367         ComponentCount = MpstPowerNode->NumPhysicalComponents;
368 
369         ParentTable = DtPeekSubtable ();
370 
371         /* Sub-subtables - Memory Power State Structure(s) */
372 
373         while (*PFieldList && PowerStateCount)
374         {
375             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
376                 &Subtable, TRUE);
377             if (ACPI_FAILURE (Status))
378             {
379                 return (Status);
380             }
381 
382             DtInsertSubtable (ParentTable, Subtable);
383             PowerStateCount--;
384         }
385 
386         /* Sub-subtables - Physical Component ID Structure(s) */
387 
388         while (*PFieldList && ComponentCount)
389         {
390             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
391                 &Subtable, TRUE);
392             if (ACPI_FAILURE (Status))
393             {
394                 return (Status);
395             }
396 
397             DtInsertSubtable (ParentTable, Subtable);
398             ComponentCount--;
399         }
400 
401         SubtableCount--;
402         DtPopSubtable ();
403     }
404 
405     /* Subtable: Count of Memory Power State Characteristic structures */
406 
407     DtPopSubtable ();
408 
409     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
410     if (ACPI_FAILURE (Status))
411     {
412         return (Status);
413     }
414 
415     ParentTable = DtPeekSubtable ();
416     DtInsertSubtable (ParentTable, Subtable);
417     DtPushSubtable (Subtable);
418 
419     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
420     SubtableCount = MpstDataHeader->CharacteristicsCount;
421 
422     ParentTable = DtPeekSubtable ();
423 
424     /* Subtable: Memory Power State Characteristics structure(s) */
425 
426     while (*PFieldList && SubtableCount)
427     {
428         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
429             &Subtable, TRUE);
430         if (ACPI_FAILURE (Status))
431         {
432             return (Status);
433         }
434 
435         DtInsertSubtable (ParentTable, Subtable);
436         SubtableCount--;
437     }
438 
439     DtPopSubtable ();
440     return (AE_OK);
441 }
442 
443 
444 /******************************************************************************
445  *
446  * FUNCTION:    DtCompileMsct
447  *
448  * PARAMETERS:  List                - Current field list pointer
449  *
450  * RETURN:      Status
451  *
452  * DESCRIPTION: Compile MSCT.
453  *
454  *****************************************************************************/
455 
456 ACPI_STATUS
457 DtCompileMsct (
458     void                    **List)
459 {
460     ACPI_STATUS             Status;
461 
462 
463     Status = DtCompileTwoSubtables (List,
464         AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
465     return (Status);
466 }
467 
468 
469 /******************************************************************************
470  *
471  * FUNCTION:    DtCompileMtmr
472  *
473  * PARAMETERS:  List                - Current field list pointer
474  *
475  * RETURN:      Status
476  *
477  * DESCRIPTION: Compile MTMR.
478  *
479  *****************************************************************************/
480 
481 ACPI_STATUS
482 DtCompileMtmr (
483     void                    **List)
484 {
485     ACPI_STATUS             Status;
486 
487 
488     Status = DtCompileTwoSubtables (List,
489         AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
490     return (Status);
491 }
492 
493 
494 /******************************************************************************
495  *
496  * FUNCTION:    DtCompileNfit
497  *
498  * PARAMETERS:  List                - Current field list pointer
499  *
500  * RETURN:      Status
501  *
502  * DESCRIPTION: Compile NFIT.
503  *
504  *****************************************************************************/
505 
506 ACPI_STATUS
507 DtCompileNfit (
508     void                    **List)
509 {
510     ACPI_STATUS             Status;
511     DT_SUBTABLE             *Subtable;
512     DT_SUBTABLE             *ParentTable;
513     DT_FIELD                **PFieldList = (DT_FIELD **) List;
514     DT_FIELD                *SubtableStart;
515     ACPI_NFIT_HEADER        *NfitHeader;
516     ACPI_DMTABLE_INFO       *InfoTable;
517     UINT32                  Count;
518     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
519     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
520 
521 
522     /* Main table */
523 
524     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
525         &Subtable, TRUE);
526     if (ACPI_FAILURE (Status))
527     {
528         return (Status);
529     }
530 
531     ParentTable = DtPeekSubtable ();
532     DtInsertSubtable (ParentTable, Subtable);
533     DtPushSubtable (Subtable);
534 
535     /* Subtables */
536 
537     while (*PFieldList)
538     {
539         SubtableStart = *PFieldList;
540         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
541             &Subtable, TRUE);
542         if (ACPI_FAILURE (Status))
543         {
544             return (Status);
545         }
546 
547         ParentTable = DtPeekSubtable ();
548         DtInsertSubtable (ParentTable, Subtable);
549         DtPushSubtable (Subtable);
550 
551         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
552 
553         switch (NfitHeader->Type)
554         {
555         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
556 
557             InfoTable = AcpiDmTableInfoNfit0;
558             break;
559 
560         case ACPI_NFIT_TYPE_MEMORY_MAP:
561 
562             InfoTable = AcpiDmTableInfoNfit1;
563             break;
564 
565         case ACPI_NFIT_TYPE_INTERLEAVE:
566 
567             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
568             InfoTable = AcpiDmTableInfoNfit2;
569             break;
570 
571         case ACPI_NFIT_TYPE_SMBIOS:
572 
573             InfoTable = AcpiDmTableInfoNfit3;
574             break;
575 
576         case ACPI_NFIT_TYPE_CONTROL_REGION:
577 
578             InfoTable = AcpiDmTableInfoNfit4;
579             break;
580 
581         case ACPI_NFIT_TYPE_DATA_REGION:
582 
583             InfoTable = AcpiDmTableInfoNfit5;
584             break;
585 
586         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
587 
588             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
589             InfoTable = AcpiDmTableInfoNfit6;
590             break;
591 
592         case ACPI_NFIT_TYPE_CAPABILITIES:
593 
594             InfoTable = AcpiDmTableInfoNfit7;
595             break;
596 
597         default:
598 
599             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
600             return (AE_ERROR);
601         }
602 
603         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
604         if (ACPI_FAILURE (Status))
605         {
606             return (Status);
607         }
608 
609         ParentTable = DtPeekSubtable ();
610         DtInsertSubtable (ParentTable, Subtable);
611         DtPopSubtable ();
612 
613         switch (NfitHeader->Type)
614         {
615         case ACPI_NFIT_TYPE_INTERLEAVE:
616 
617             Count = 0;
618             DtPushSubtable (Subtable);
619             while (*PFieldList)
620             {
621                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
622                     &Subtable, FALSE);
623                 if (ACPI_FAILURE (Status))
624                 {
625                     return (Status);
626                 }
627 
628                 if (!Subtable)
629                 {
630                     DtPopSubtable ();
631                     break;
632                 }
633 
634                 ParentTable = DtPeekSubtable ();
635                 DtInsertSubtable (ParentTable, Subtable);
636                 Count++;
637             }
638 
639             Interleave->LineCount = Count;
640             break;
641 
642         case ACPI_NFIT_TYPE_SMBIOS:
643 
644             if (*PFieldList)
645             {
646                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
647                     &Subtable, TRUE);
648                 if (ACPI_FAILURE (Status))
649                 {
650                     return (Status);
651                 }
652 
653                 if (Subtable)
654                 {
655                     DtInsertSubtable (ParentTable, Subtable);
656                 }
657             }
658             break;
659 
660         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
661 
662             Count = 0;
663             DtPushSubtable (Subtable);
664             while (*PFieldList)
665             {
666                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
667                     &Subtable, FALSE);
668                 if (ACPI_FAILURE (Status))
669                 {
670                     return (Status);
671                 }
672 
673                 if (!Subtable)
674                 {
675                     DtPopSubtable ();
676                     break;
677                 }
678 
679                 ParentTable = DtPeekSubtable ();
680                 DtInsertSubtable (ParentTable, Subtable);
681                 Count++;
682             }
683 
684             Hint->HintCount = (UINT16) Count;
685             break;
686 
687         default:
688             break;
689         }
690     }
691 
692     return (AE_OK);
693 }
694 
695 
696 /******************************************************************************
697  *
698  * FUNCTION:    DtCompilePcct
699  *
700  * PARAMETERS:  List                - Current field list pointer
701  *
702  * RETURN:      Status
703  *
704  * DESCRIPTION: Compile PCCT.
705  *
706  *****************************************************************************/
707 
708 ACPI_STATUS
709 DtCompilePcct (
710     void                    **List)
711 {
712     ACPI_STATUS             Status;
713     DT_SUBTABLE             *Subtable;
714     DT_SUBTABLE             *ParentTable;
715     DT_FIELD                **PFieldList = (DT_FIELD **) List;
716     DT_FIELD                *SubtableStart;
717     ACPI_SUBTABLE_HEADER    *PcctHeader;
718     ACPI_DMTABLE_INFO       *InfoTable;
719 
720 
721     /* Main table */
722 
723     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
724         &Subtable, TRUE);
725     if (ACPI_FAILURE (Status))
726     {
727         return (Status);
728     }
729 
730     ParentTable = DtPeekSubtable ();
731     DtInsertSubtable (ParentTable, Subtable);
732 
733     /* Subtables */
734 
735     while (*PFieldList)
736     {
737         SubtableStart = *PFieldList;
738         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
739             &Subtable, TRUE);
740         if (ACPI_FAILURE (Status))
741         {
742             return (Status);
743         }
744 
745         ParentTable = DtPeekSubtable ();
746         DtInsertSubtable (ParentTable, Subtable);
747         DtPushSubtable (Subtable);
748 
749         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
750 
751         switch (PcctHeader->Type)
752         {
753         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
754 
755             InfoTable = AcpiDmTableInfoPcct0;
756             break;
757 
758         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
759 
760             InfoTable = AcpiDmTableInfoPcct1;
761             break;
762 
763         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
764 
765             InfoTable = AcpiDmTableInfoPcct2;
766             break;
767 
768         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
769 
770             InfoTable = AcpiDmTableInfoPcct3;
771             break;
772 
773         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
774 
775             InfoTable = AcpiDmTableInfoPcct4;
776             break;
777 
778         default:
779 
780             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
781             return (AE_ERROR);
782         }
783 
784         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
785         if (ACPI_FAILURE (Status))
786         {
787             return (Status);
788         }
789 
790         ParentTable = DtPeekSubtable ();
791         DtInsertSubtable (ParentTable, Subtable);
792         DtPopSubtable ();
793     }
794 
795     return (AE_OK);
796 }
797 
798 
799 /******************************************************************************
800  *
801  * FUNCTION:    DtCompilePdtt
802  *
803  * PARAMETERS:  List                - Current field list pointer
804  *
805  * RETURN:      Status
806  *
807  * DESCRIPTION: Compile PDTT.
808  *
809  *****************************************************************************/
810 
811 ACPI_STATUS
812 DtCompilePdtt (
813     void                    **List)
814 {
815     ACPI_STATUS             Status;
816     DT_SUBTABLE             *Subtable;
817     DT_SUBTABLE             *ParentTable;
818     DT_FIELD                **PFieldList = (DT_FIELD **) List;
819     ACPI_TABLE_PDTT         *PdttHeader;
820     UINT32                  Count = 0;
821 
822 
823     /* Main table */
824 
825     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable, TRUE);
826     if (ACPI_FAILURE (Status))
827     {
828         return (Status);
829     }
830 
831     ParentTable = DtPeekSubtable ();
832     DtInsertSubtable (ParentTable, Subtable);
833 
834     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
835     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
836 
837     /* There is only one type of subtable at this time, no need to decode */
838 
839     while (*PFieldList)
840     {
841         /* List of subchannel IDs, each 2 bytes */
842 
843         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
844             &Subtable, TRUE);
845         if (ACPI_FAILURE (Status))
846         {
847             return (Status);
848         }
849 
850         DtInsertSubtable (ParentTable, Subtable);
851         Count++;
852     }
853 
854     PdttHeader->TriggerCount = (UINT8) Count;
855     return (AE_OK);
856 }
857 
858 
859 /******************************************************************************
860  *
861  * FUNCTION:    DtCompilePmtt
862  *
863  * PARAMETERS:  List                - Current field list pointer
864  *
865  * RETURN:      Status
866  *
867  * DESCRIPTION: Compile PMTT.
868  *
869  *****************************************************************************/
870 
871 ACPI_STATUS
872 DtCompilePmtt (
873     void                    **List)
874 {
875     ACPI_STATUS             Status;
876     DT_SUBTABLE             *Subtable;
877     DT_SUBTABLE             *ParentTable;
878     DT_FIELD                **PFieldList = (DT_FIELD **) List;
879     DT_FIELD                *SubtableStart;
880     ACPI_PMTT_HEADER        *PmttHeader;
881     ACPI_PMTT_CONTROLLER    *PmttController;
882     UINT16                  DomainCount;
883     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
884 
885 
886     /* Main table */
887 
888     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
889     if (ACPI_FAILURE (Status))
890     {
891         return (Status);
892     }
893 
894     ParentTable = DtPeekSubtable ();
895     DtInsertSubtable (ParentTable, Subtable);
896     DtPushSubtable (Subtable);
897 
898     while (*PFieldList)
899     {
900         SubtableStart = *PFieldList;
901         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
902             &Subtable, TRUE);
903         if (ACPI_FAILURE (Status))
904         {
905             return (Status);
906         }
907 
908         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
909         while (PrevType >= PmttHeader->Type)
910         {
911             DtPopSubtable ();
912 
913             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
914             {
915                 break;
916             }
917 
918             PrevType--;
919         }
920 
921         PrevType = PmttHeader->Type;
922 
923         ParentTable = DtPeekSubtable ();
924         DtInsertSubtable (ParentTable, Subtable);
925         DtPushSubtable (Subtable);
926 
927         switch (PmttHeader->Type)
928         {
929         case ACPI_PMTT_TYPE_SOCKET:
930 
931             /* Subtable: Socket Structure */
932 
933             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
934                 &Subtable, TRUE);
935             if (ACPI_FAILURE (Status))
936             {
937                 return (Status);
938             }
939 
940             ParentTable = DtPeekSubtable ();
941             DtInsertSubtable (ParentTable, Subtable);
942             break;
943 
944         case ACPI_PMTT_TYPE_CONTROLLER:
945 
946             /* Subtable: Memory Controller Structure */
947 
948             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
949                 &Subtable, TRUE);
950             if (ACPI_FAILURE (Status))
951             {
952                 return (Status);
953             }
954 
955             ParentTable = DtPeekSubtable ();
956             DtInsertSubtable (ParentTable, Subtable);
957 
958             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
959                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
960             DomainCount = PmttController->DomainCount;
961 
962             while (DomainCount)
963             {
964                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
965                     &Subtable, TRUE);
966                 if (ACPI_FAILURE (Status))
967                 {
968                     return (Status);
969                 }
970 
971                 DtInsertSubtable (ParentTable, Subtable);
972                 DomainCount--;
973             }
974             break;
975 
976         case ACPI_PMTT_TYPE_DIMM:
977 
978             /* Subtable: Physical Component Structure */
979 
980             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
981                 &Subtable, TRUE);
982             if (ACPI_FAILURE (Status))
983             {
984                 return (Status);
985             }
986 
987             ParentTable = DtPeekSubtable ();
988             DtInsertSubtable (ParentTable, Subtable);
989             break;
990 
991         default:
992 
993             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
994             return (AE_ERROR);
995         }
996     }
997 
998     return (Status);
999 }
1000 
1001 
1002 /******************************************************************************
1003  *
1004  * FUNCTION:    DtCompilePptt
1005  *
1006  * PARAMETERS:  List                - Current field list pointer
1007  *
1008  * RETURN:      Status
1009  *
1010  * DESCRIPTION: Compile PPTT.
1011  *
1012  *****************************************************************************/
1013 
1014 ACPI_STATUS
1015 DtCompilePptt (
1016     void                    **List)
1017 {
1018     ACPI_STATUS             Status;
1019     ACPI_SUBTABLE_HEADER    *PpttHeader;
1020     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
1021     DT_SUBTABLE             *Subtable;
1022     DT_SUBTABLE             *ParentTable;
1023     ACPI_DMTABLE_INFO       *InfoTable;
1024     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1025     DT_FIELD                *SubtableStart;
1026 
1027 
1028     ParentTable = DtPeekSubtable ();
1029     while (*PFieldList)
1030     {
1031         SubtableStart = *PFieldList;
1032 
1033         /* Compile PPTT subtable header */
1034 
1035         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1036             &Subtable, TRUE);
1037         if (ACPI_FAILURE (Status))
1038         {
1039             return (Status);
1040         }
1041         DtInsertSubtable (ParentTable, Subtable);
1042         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1043         PpttHeader->Length = (UINT8)(Subtable->Length);
1044 
1045         switch (PpttHeader->Type)
1046         {
1047         case ACPI_PPTT_TYPE_PROCESSOR:
1048 
1049             InfoTable = AcpiDmTableInfoPptt0;
1050             break;
1051 
1052         case ACPI_PPTT_TYPE_CACHE:
1053 
1054             InfoTable = AcpiDmTableInfoPptt1;
1055             break;
1056 
1057         case ACPI_PPTT_TYPE_ID:
1058 
1059             InfoTable = AcpiDmTableInfoPptt2;
1060             break;
1061 
1062         default:
1063 
1064             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1065             return (AE_ERROR);
1066         }
1067 
1068         /* Compile PPTT subtable body */
1069 
1070         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1071         if (ACPI_FAILURE (Status))
1072         {
1073             return (Status);
1074         }
1075         DtInsertSubtable (ParentTable, Subtable);
1076         PpttHeader->Length += (UINT8)(Subtable->Length);
1077 
1078         /* Compile PPTT subtable additionals */
1079 
1080         switch (PpttHeader->Type)
1081         {
1082         case ACPI_PPTT_TYPE_PROCESSOR:
1083 
1084             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1085                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1086             if (PpttProcessor)
1087             {
1088                 /* Compile initiator proximity domain list */
1089 
1090                 PpttProcessor->NumberOfPrivResources = 0;
1091                 while (*PFieldList)
1092                 {
1093                     Status = DtCompileTable (PFieldList,
1094                         AcpiDmTableInfoPptt0a, &Subtable, TRUE);
1095                     if (ACPI_FAILURE (Status))
1096                     {
1097                         return (Status);
1098                     }
1099                     if (!Subtable)
1100                     {
1101                         break;
1102                     }
1103 
1104                     DtInsertSubtable (ParentTable, Subtable);
1105                     PpttHeader->Length += (UINT8)(Subtable->Length);
1106                     PpttProcessor->NumberOfPrivResources++;
1107                 }
1108             }
1109             break;
1110 
1111         default:
1112 
1113             break;
1114         }
1115     }
1116 
1117     return (AE_OK);
1118 }
1119 
1120 
1121 /******************************************************************************
1122  *
1123  * FUNCTION:    DtCompileRsdt
1124  *
1125  * PARAMETERS:  List                - Current field list pointer
1126  *
1127  * RETURN:      Status
1128  *
1129  * DESCRIPTION: Compile RSDT.
1130  *
1131  *****************************************************************************/
1132 
1133 ACPI_STATUS
1134 DtCompileRsdt (
1135     void                    **List)
1136 {
1137     DT_SUBTABLE             *Subtable;
1138     DT_SUBTABLE             *ParentTable;
1139     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1140     UINT32                  Address;
1141 
1142 
1143     ParentTable = DtPeekSubtable ();
1144 
1145     while (FieldList)
1146     {
1147         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1148 
1149         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1150         DtInsertSubtable (ParentTable, Subtable);
1151         FieldList = FieldList->Next;
1152     }
1153 
1154     return (AE_OK);
1155 }
1156 
1157 
1158 /******************************************************************************
1159  *
1160  * FUNCTION:    DtCompileS3pt
1161  *
1162  * PARAMETERS:  PFieldList          - Current field list pointer
1163  *
1164  * RETURN:      Status
1165  *
1166  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1167  *
1168  *****************************************************************************/
1169 
1170 ACPI_STATUS
1171 DtCompileS3pt (
1172     DT_FIELD                **PFieldList)
1173 {
1174     ACPI_STATUS             Status;
1175     ACPI_FPDT_HEADER        *S3ptHeader;
1176     DT_SUBTABLE             *Subtable;
1177     DT_SUBTABLE             *ParentTable;
1178     ACPI_DMTABLE_INFO       *InfoTable;
1179     DT_FIELD                *SubtableStart;
1180 
1181 
1182     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1183         &Gbl_RootTable, TRUE);
1184     if (ACPI_FAILURE (Status))
1185     {
1186         return (Status);
1187     }
1188 
1189     DtPushSubtable (Gbl_RootTable);
1190 
1191     while (*PFieldList)
1192     {
1193         SubtableStart = *PFieldList;
1194         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1195             &Subtable, TRUE);
1196         if (ACPI_FAILURE (Status))
1197         {
1198             return (Status);
1199         }
1200 
1201         ParentTable = DtPeekSubtable ();
1202         DtInsertSubtable (ParentTable, Subtable);
1203         DtPushSubtable (Subtable);
1204 
1205         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1206 
1207         switch (S3ptHeader->Type)
1208         {
1209         case ACPI_S3PT_TYPE_RESUME:
1210 
1211             InfoTable = AcpiDmTableInfoS3pt0;
1212             break;
1213 
1214         case ACPI_S3PT_TYPE_SUSPEND:
1215 
1216             InfoTable = AcpiDmTableInfoS3pt1;
1217             break;
1218 
1219         default:
1220 
1221             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1222             return (AE_ERROR);
1223         }
1224 
1225         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1226         if (ACPI_FAILURE (Status))
1227         {
1228             return (Status);
1229         }
1230 
1231         ParentTable = DtPeekSubtable ();
1232         DtInsertSubtable (ParentTable, Subtable);
1233         DtPopSubtable ();
1234     }
1235 
1236     return (AE_OK);
1237 }
1238 
1239 
1240 /******************************************************************************
1241  *
1242  * FUNCTION:    DtCompileSdev
1243  *
1244  * PARAMETERS:  List                - Current field list pointer
1245  *
1246  * RETURN:      Status
1247  *
1248  * DESCRIPTION: Compile SDEV.
1249  *
1250  *****************************************************************************/
1251 
1252 ACPI_STATUS
1253 DtCompileSdev (
1254     void                    **List)
1255 {
1256     ACPI_STATUS             Status;
1257     ACPI_SDEV_HEADER        *SdevHeader;
1258     DT_SUBTABLE             *Subtable;
1259     DT_SUBTABLE             *ParentTable;
1260     ACPI_DMTABLE_INFO       *InfoTable;
1261     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1262     DT_FIELD                *SubtableStart;
1263     ACPI_SDEV_PCIE          *Pcie = NULL;
1264     ACPI_SDEV_NAMESPACE     *Namesp = NULL;
1265     UINT32                  EntryCount;
1266 
1267 
1268     /* Subtables */
1269 
1270     while (*PFieldList)
1271     {
1272         /* Compile common SDEV subtable header */
1273 
1274         SubtableStart = *PFieldList;
1275         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
1276             &Subtable, TRUE);
1277         if (ACPI_FAILURE (Status))
1278         {
1279             return (Status);
1280         }
1281 
1282         ParentTable = DtPeekSubtable ();
1283         DtInsertSubtable (ParentTable, Subtable);
1284         DtPushSubtable (Subtable);
1285 
1286         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1287         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
1288 
1289         switch (SdevHeader->Type)
1290         {
1291         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1292 
1293             InfoTable = AcpiDmTableInfoSdev0;
1294             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
1295             break;
1296 
1297         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1298 
1299             InfoTable = AcpiDmTableInfoSdev1;
1300             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
1301             break;
1302 
1303         default:
1304 
1305             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1306             return (AE_ERROR);
1307         }
1308 
1309         /* Compile SDEV subtable body */
1310 
1311         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1312         if (ACPI_FAILURE (Status))
1313         {
1314             return (Status);
1315         }
1316 
1317         ParentTable = DtPeekSubtable ();
1318         DtInsertSubtable (ParentTable, Subtable);
1319 
1320         /* Optional data fields are appended to the main subtable body */
1321 
1322         switch (SdevHeader->Type)
1323         {
1324         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1325 
1326             /* Append DeviceId namespace string */
1327 
1328             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
1329                 &Subtable, TRUE);
1330             if (ACPI_FAILURE (Status))
1331             {
1332                 return (Status);
1333             }
1334 
1335             if (!Subtable)
1336             {
1337                 break;
1338             }
1339 
1340             ParentTable = DtPeekSubtable ();
1341             DtInsertSubtable (ParentTable, Subtable);
1342 
1343             Namesp->DeviceIdOffset = sizeof (ACPI_SDEV_NAMESPACE);
1344             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
1345 
1346             /* Append Vendor data */
1347 
1348             Namesp->VendorDataLength = 0;
1349             Namesp->VendorDataOffset = 0;
1350 
1351             if (*PFieldList)
1352             {
1353                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1354                     &Subtable, TRUE);
1355                 if (ACPI_FAILURE (Status))
1356                 {
1357                     return (Status);
1358                 }
1359 
1360                 if (Subtable)
1361                 {
1362                     ParentTable = DtPeekSubtable ();
1363                     DtInsertSubtable (ParentTable, Subtable);
1364 
1365                     Namesp->VendorDataOffset =
1366                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
1367                     Namesp->VendorDataLength =
1368                         (UINT16) Subtable->Length;
1369                 }
1370             }
1371 
1372             /* Final size of entire namespace structure */
1373 
1374             SdevHeader->Length = (UINT16) (sizeof (ACPI_SDEV_NAMESPACE) +
1375                 Subtable->Length + Namesp->DeviceIdLength);
1376             break;
1377 
1378         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1379 
1380             /* Append the PCIe path info first */
1381 
1382             EntryCount = 0;
1383             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
1384             {
1385                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
1386                     &Subtable, FALSE);
1387                 if (ACPI_FAILURE (Status))
1388                 {
1389                     return (Status);
1390                 }
1391 
1392                 if (!Subtable)
1393                 {
1394                     DtPopSubtable ();
1395                     break;
1396                 }
1397 
1398                 ParentTable = DtPeekSubtable ();
1399                 DtInsertSubtable (ParentTable, Subtable);
1400                 EntryCount++;
1401             }
1402 
1403             /* Path offset will point immediately after the main subtable */
1404 
1405             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
1406             Pcie->PathLength = (UINT16)
1407                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
1408 
1409             /* Append the Vendor Data last */
1410 
1411             Pcie->VendorDataLength = 0;
1412             Pcie->VendorDataOffset = 0;
1413 
1414             if (*PFieldList)
1415             {
1416                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1417                     &Subtable, TRUE);
1418                 if (ACPI_FAILURE (Status))
1419                 {
1420                     return (Status);
1421                 }
1422 
1423                 if (Subtable)
1424                 {
1425                     ParentTable = DtPeekSubtable ();
1426                     DtInsertSubtable (ParentTable, Subtable);
1427 
1428                     Pcie->VendorDataOffset =
1429                         Pcie->PathOffset + Pcie->PathLength;
1430                     Pcie->VendorDataLength = (UINT16)
1431                         Subtable->Length;
1432                 }
1433             }
1434 
1435             SdevHeader->Length =
1436                 sizeof (ACPI_SDEV_PCIE) +
1437                 Pcie->PathLength + Pcie->VendorDataLength;
1438             break;
1439 
1440         default:
1441 
1442             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1443             return (AE_ERROR);
1444         }
1445 
1446         DtPopSubtable ();
1447     }
1448 
1449     return (AE_OK);
1450 }
1451 
1452 
1453 /******************************************************************************
1454  *
1455  * FUNCTION:    DtCompileSlic
1456  *
1457  * PARAMETERS:  List                - Current field list pointer
1458  *
1459  * RETURN:      Status
1460  *
1461  * DESCRIPTION: Compile SLIC.
1462  *
1463  *****************************************************************************/
1464 
1465 ACPI_STATUS
1466 DtCompileSlic (
1467     void                    **List)
1468 {
1469     ACPI_STATUS             Status;
1470     DT_SUBTABLE             *Subtable;
1471     DT_SUBTABLE             *ParentTable;
1472     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1473 
1474 
1475     while (*PFieldList)
1476     {
1477         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
1478             &Subtable, TRUE);
1479         if (ACPI_FAILURE (Status))
1480         {
1481             return (Status);
1482         }
1483 
1484         ParentTable = DtPeekSubtable ();
1485         DtInsertSubtable (ParentTable, Subtable);
1486         DtPushSubtable (Subtable);
1487         DtPopSubtable ();
1488     }
1489 
1490     return (AE_OK);
1491 }
1492 
1493 
1494 /******************************************************************************
1495  *
1496  * FUNCTION:    DtCompileSlit
1497  *
1498  * PARAMETERS:  List                - Current field list pointer
1499  *
1500  * RETURN:      Status
1501  *
1502  * DESCRIPTION: Compile SLIT.
1503  *
1504  *****************************************************************************/
1505 
1506 ACPI_STATUS
1507 DtCompileSlit (
1508     void                    **List)
1509 {
1510     ACPI_STATUS             Status;
1511     DT_SUBTABLE             *Subtable;
1512     DT_SUBTABLE             *ParentTable;
1513     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1514     DT_FIELD                *FieldList;
1515     UINT32                  Localities;
1516     UINT8                   *LocalityBuffer;
1517 
1518 
1519     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1520         &Subtable, TRUE);
1521     if (ACPI_FAILURE (Status))
1522     {
1523         return (Status);
1524     }
1525 
1526     ParentTable = DtPeekSubtable ();
1527     DtInsertSubtable (ParentTable, Subtable);
1528 
1529     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1530     LocalityBuffer = UtLocalCalloc (Localities);
1531 
1532     /* Compile each locality buffer */
1533 
1534     FieldList = *PFieldList;
1535     while (FieldList)
1536     {
1537         DtCompileBuffer (LocalityBuffer,
1538             FieldList->Value, FieldList, Localities);
1539 
1540         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1541         DtInsertSubtable (ParentTable, Subtable);
1542         FieldList = FieldList->Next;
1543     }
1544 
1545     ACPI_FREE (LocalityBuffer);
1546     return (AE_OK);
1547 }
1548 
1549 
1550 /******************************************************************************
1551  *
1552  * FUNCTION:    DtCompileSrat
1553  *
1554  * PARAMETERS:  List                - Current field list pointer
1555  *
1556  * RETURN:      Status
1557  *
1558  * DESCRIPTION: Compile SRAT.
1559  *
1560  *****************************************************************************/
1561 
1562 ACPI_STATUS
1563 DtCompileSrat (
1564     void                    **List)
1565 {
1566     ACPI_STATUS             Status;
1567     DT_SUBTABLE             *Subtable;
1568     DT_SUBTABLE             *ParentTable;
1569     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1570     DT_FIELD                *SubtableStart;
1571     ACPI_SUBTABLE_HEADER    *SratHeader;
1572     ACPI_DMTABLE_INFO       *InfoTable;
1573 
1574 
1575     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1576         &Subtable, TRUE);
1577     if (ACPI_FAILURE (Status))
1578     {
1579         return (Status);
1580     }
1581 
1582     ParentTable = DtPeekSubtable ();
1583     DtInsertSubtable (ParentTable, Subtable);
1584 
1585     while (*PFieldList)
1586     {
1587         SubtableStart = *PFieldList;
1588         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1589             &Subtable, TRUE);
1590         if (ACPI_FAILURE (Status))
1591         {
1592             return (Status);
1593         }
1594 
1595         ParentTable = DtPeekSubtable ();
1596         DtInsertSubtable (ParentTable, Subtable);
1597         DtPushSubtable (Subtable);
1598 
1599         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1600 
1601         switch (SratHeader->Type)
1602         {
1603         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1604 
1605             InfoTable = AcpiDmTableInfoSrat0;
1606             break;
1607 
1608         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1609 
1610             InfoTable = AcpiDmTableInfoSrat1;
1611             break;
1612 
1613         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1614 
1615             InfoTable = AcpiDmTableInfoSrat2;
1616             break;
1617 
1618         case ACPI_SRAT_TYPE_GICC_AFFINITY:
1619 
1620             InfoTable = AcpiDmTableInfoSrat3;
1621             break;
1622 
1623         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
1624 
1625             InfoTable = AcpiDmTableInfoSrat4;
1626             break;
1627 
1628         default:
1629 
1630             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1631             return (AE_ERROR);
1632         }
1633 
1634         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1635         if (ACPI_FAILURE (Status))
1636         {
1637             return (Status);
1638         }
1639 
1640         ParentTable = DtPeekSubtable ();
1641         DtInsertSubtable (ParentTable, Subtable);
1642         DtPopSubtable ();
1643     }
1644 
1645     return (AE_OK);
1646 }
1647 
1648 
1649 /******************************************************************************
1650  *
1651  * FUNCTION:    DtCompileStao
1652  *
1653  * PARAMETERS:  PFieldList          - Current field list pointer
1654  *
1655  * RETURN:      Status
1656  *
1657  * DESCRIPTION: Compile STAO.
1658  *
1659  *****************************************************************************/
1660 
1661 ACPI_STATUS
1662 DtCompileStao (
1663     void                    **List)
1664 {
1665     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1666     DT_SUBTABLE             *Subtable;
1667     DT_SUBTABLE             *ParentTable;
1668     ACPI_STATUS             Status;
1669 
1670 
1671     /* Compile the main table */
1672 
1673     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
1674         &Subtable, TRUE);
1675     if (ACPI_FAILURE (Status))
1676     {
1677         return (Status);
1678     }
1679 
1680     ParentTable = DtPeekSubtable ();
1681     DtInsertSubtable (ParentTable, Subtable);
1682 
1683     /* Compile each ASCII namestring as a subtable */
1684 
1685     while (*PFieldList)
1686     {
1687         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
1688             &Subtable, TRUE);
1689         if (ACPI_FAILURE (Status))
1690         {
1691             return (Status);
1692         }
1693 
1694         ParentTable = DtPeekSubtable ();
1695         DtInsertSubtable (ParentTable, Subtable);
1696     }
1697 
1698     return (AE_OK);
1699 }
1700 
1701 
1702 /******************************************************************************
1703  *
1704  * FUNCTION:    DtCompileTcpa
1705  *
1706  * PARAMETERS:  PFieldList          - Current field list pointer
1707  *
1708  * RETURN:      Status
1709  *
1710  * DESCRIPTION: Compile TCPA.
1711  *
1712  *****************************************************************************/
1713 
1714 ACPI_STATUS
1715 DtCompileTcpa (
1716     void                    **List)
1717 {
1718     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1719     DT_SUBTABLE             *Subtable;
1720     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
1721     DT_SUBTABLE             *ParentTable;
1722     ACPI_STATUS             Status;
1723 
1724 
1725     /* Compile the main table */
1726 
1727     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
1728         &Subtable, TRUE);
1729     if (ACPI_FAILURE (Status))
1730     {
1731         return (Status);
1732     }
1733 
1734     ParentTable = DtPeekSubtable ();
1735     DtInsertSubtable (ParentTable, Subtable);
1736 
1737     /*
1738      * Examine the PlatformClass field to determine the table type.
1739      * Either a client or server table. Only one.
1740      */
1741     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
1742 
1743     switch (TcpaHeader->PlatformClass)
1744     {
1745     case ACPI_TCPA_CLIENT_TABLE:
1746 
1747         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
1748             &Subtable, TRUE);
1749         break;
1750 
1751     case ACPI_TCPA_SERVER_TABLE:
1752 
1753         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
1754             &Subtable, TRUE);
1755         break;
1756 
1757     default:
1758 
1759         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
1760             TcpaHeader->PlatformClass);
1761         Status = AE_ERROR;
1762         break;
1763     }
1764 
1765     ParentTable = DtPeekSubtable ();
1766     DtInsertSubtable (ParentTable, Subtable);
1767     return (Status);
1768 }
1769 
1770 
1771 /******************************************************************************
1772  *
1773  * FUNCTION:    DtCompileTpm2
1774  *
1775  * PARAMETERS:  PFieldList          - Current field list pointer
1776  *
1777  * RETURN:      Status
1778  *
1779  * DESCRIPTION: Compile TPM2.
1780  *
1781  *****************************************************************************/
1782 
1783 ACPI_STATUS
1784 DtCompileTpm2 (
1785     void                    **List)
1786 {
1787     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1788     DT_SUBTABLE             *Subtable;
1789     ACPI_TABLE_TPM2         *Tpm2Header;
1790     DT_SUBTABLE             *ParentTable;
1791     ACPI_STATUS             Status = AE_OK;
1792 
1793 
1794     /* Compile the main table */
1795 
1796     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
1797         &Subtable, TRUE);
1798     if (ACPI_FAILURE (Status))
1799     {
1800         return (Status);
1801     }
1802 
1803     ParentTable = DtPeekSubtable ();
1804     DtInsertSubtable (ParentTable, Subtable);
1805 
1806     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
1807 
1808     /* Method parameters */
1809     /* Optional: Log area minimum length */
1810     /* Optional: Log area start address */
1811     /* TBD: Optional fields above not fully implemented (not optional at this time) */
1812 
1813     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
1814         &Subtable, TRUE);
1815     if (ACPI_FAILURE (Status))
1816     {
1817         return (Status);
1818     }
1819 
1820     ParentTable = DtPeekSubtable ();
1821     DtInsertSubtable (ParentTable, Subtable);
1822 
1823 
1824     /* Subtable type depends on the StartMethod */
1825 
1826     switch (Tpm2Header->StartMethod)
1827     {
1828     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
1829 
1830         /* Subtable specific to to ARM_SMC */
1831 
1832         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
1833             &Subtable, TRUE);
1834         if (ACPI_FAILURE (Status))
1835         {
1836             return (Status);
1837         }
1838 
1839         ParentTable = DtPeekSubtable ();
1840         DtInsertSubtable (ParentTable, Subtable);
1841         break;
1842 
1843     case ACPI_TPM2_START_METHOD:
1844     case ACPI_TPM2_MEMORY_MAPPED:
1845     case ACPI_TPM2_COMMAND_BUFFER:
1846     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
1847         break;
1848 
1849     case ACPI_TPM2_RESERVED1:
1850     case ACPI_TPM2_RESERVED3:
1851     case ACPI_TPM2_RESERVED4:
1852     case ACPI_TPM2_RESERVED5:
1853     case ACPI_TPM2_RESERVED9:
1854     case ACPI_TPM2_RESERVED10:
1855 
1856         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
1857             Tpm2Header->StartMethod);
1858         Status = AE_ERROR;
1859         break;
1860 
1861     case ACPI_TPM2_NOT_ALLOWED:
1862     default:
1863 
1864         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
1865             Tpm2Header->StartMethod);
1866         Status = AE_ERROR;
1867         break;
1868     }
1869 
1870     return (Status);
1871 }
1872 
1873 
1874 /******************************************************************************
1875  *
1876  * FUNCTION:    DtGetGenericTableInfo
1877  *
1878  * PARAMETERS:  Name                - Generic type name
1879  *
1880  * RETURN:      Info entry
1881  *
1882  * DESCRIPTION: Obtain table info for a generic name entry
1883  *
1884  *****************************************************************************/
1885 
1886 ACPI_DMTABLE_INFO *
1887 DtGetGenericTableInfo (
1888     char                    *Name)
1889 {
1890     ACPI_DMTABLE_INFO       *Info;
1891     UINT32                  i;
1892 
1893 
1894     if (!Name)
1895     {
1896         return (NULL);
1897     }
1898 
1899     /* Search info table for name match */
1900 
1901     for (i = 0; ; i++)
1902     {
1903         Info = AcpiDmTableInfoGeneric[i];
1904         if (Info->Opcode == ACPI_DMT_EXIT)
1905         {
1906             Info = NULL;
1907             break;
1908         }
1909 
1910         /* Use caseless compare for generic keywords */
1911 
1912         if (!AcpiUtStricmp (Name, Info->Name))
1913         {
1914             break;
1915         }
1916     }
1917 
1918     return (Info);
1919 }
1920 
1921 
1922 /******************************************************************************
1923  *
1924  * FUNCTION:    DtCompileUefi
1925  *
1926  * PARAMETERS:  List                - Current field list pointer
1927  *
1928  * RETURN:      Status
1929  *
1930  * DESCRIPTION: Compile UEFI.
1931  *
1932  *****************************************************************************/
1933 
1934 ACPI_STATUS
1935 DtCompileUefi (
1936     void                    **List)
1937 {
1938     ACPI_STATUS             Status;
1939     DT_SUBTABLE             *Subtable;
1940     DT_SUBTABLE             *ParentTable;
1941     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1942     UINT16                  *DataOffset;
1943 
1944 
1945     /* Compile the predefined portion of the UEFI table */
1946 
1947     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1948         &Subtable, TRUE);
1949     if (ACPI_FAILURE (Status))
1950     {
1951         return (Status);
1952     }
1953 
1954     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1955     *DataOffset = sizeof (ACPI_TABLE_UEFI);
1956 
1957     ParentTable = DtPeekSubtable ();
1958     DtInsertSubtable (ParentTable, Subtable);
1959 
1960     /*
1961      * Compile the "generic" portion of the UEFI table. This
1962      * part of the table is not predefined and any of the generic
1963      * operators may be used.
1964      */
1965     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
1966     return (AE_OK);
1967 }
1968 
1969 
1970 /******************************************************************************
1971  *
1972  * FUNCTION:    DtCompileVrtc
1973  *
1974  * PARAMETERS:  List                - Current field list pointer
1975  *
1976  * RETURN:      Status
1977  *
1978  * DESCRIPTION: Compile VRTC.
1979  *
1980  *****************************************************************************/
1981 
1982 ACPI_STATUS
1983 DtCompileVrtc (
1984     void                    **List)
1985 {
1986     ACPI_STATUS             Status;
1987 
1988 
1989     Status = DtCompileTwoSubtables (List,
1990         AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
1991     return (Status);
1992 }
1993 
1994 
1995 /******************************************************************************
1996  *
1997  * FUNCTION:    DtCompileWdat
1998  *
1999  * PARAMETERS:  List                - Current field list pointer
2000  *
2001  * RETURN:      Status
2002  *
2003  * DESCRIPTION: Compile WDAT.
2004  *
2005  *****************************************************************************/
2006 
2007 ACPI_STATUS
2008 DtCompileWdat (
2009     void                    **List)
2010 {
2011     ACPI_STATUS             Status;
2012 
2013 
2014     Status = DtCompileTwoSubtables (List,
2015         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2016     return (Status);
2017 }
2018 
2019 
2020 /******************************************************************************
2021  *
2022  * FUNCTION:    DtCompileWpbt
2023  *
2024  * PARAMETERS:  List                - Current field list pointer
2025  *
2026  * RETURN:      Status
2027  *
2028  * DESCRIPTION: Compile WPBT.
2029  *
2030  *****************************************************************************/
2031 
2032 ACPI_STATUS
2033 DtCompileWpbt (
2034     void                    **List)
2035 {
2036     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2037     DT_SUBTABLE             *Subtable;
2038     DT_SUBTABLE             *ParentTable;
2039     ACPI_TABLE_WPBT         *Table;
2040     ACPI_STATUS             Status;
2041     UINT16                  Length;
2042 
2043 
2044     /* Compile the main table */
2045 
2046     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
2047         &Subtable, TRUE);
2048     if (ACPI_FAILURE (Status))
2049     {
2050         return (Status);
2051     }
2052 
2053     ParentTable = DtPeekSubtable ();
2054     DtInsertSubtable (ParentTable, Subtable);
2055 
2056     /* Compile the argument list subtable */
2057 
2058     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
2059         &Subtable, TRUE);
2060     if (ACPI_FAILURE (Status))
2061     {
2062         return (Status);
2063     }
2064 
2065     /* Extract the length of the Arguments buffer, insert into main table */
2066 
2067     Length = (UINT16) Subtable->TotalLength;
2068     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
2069     Table->ArgumentsLength = Length;
2070 
2071     ParentTable = DtPeekSubtable ();
2072     DtInsertSubtable (ParentTable, Subtable);
2073     return (AE_OK);
2074 }
2075 
2076 
2077 /******************************************************************************
2078  *
2079  * FUNCTION:    DtCompileXsdt
2080  *
2081  * PARAMETERS:  List                - Current field list pointer
2082  *
2083  * RETURN:      Status
2084  *
2085  * DESCRIPTION: Compile XSDT.
2086  *
2087  *****************************************************************************/
2088 
2089 ACPI_STATUS
2090 DtCompileXsdt (
2091     void                    **List)
2092 {
2093     DT_SUBTABLE             *Subtable;
2094     DT_SUBTABLE             *ParentTable;
2095     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2096     UINT64                  Address;
2097 
2098 
2099     ParentTable = DtPeekSubtable ();
2100 
2101     while (FieldList)
2102     {
2103         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2104 
2105         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2106         DtInsertSubtable (ParentTable, Subtable);
2107         FieldList = FieldList->Next;
2108     }
2109 
2110     return (AE_OK);
2111 }
2112 
2113 
2114 /******************************************************************************
2115  *
2116  * FUNCTION:    DtCompileGeneric
2117  *
2118  * PARAMETERS:  List                - Current field list pointer
2119  *              Name                - Field name to end generic compiling
2120  *              Length              - Compiled table length to return
2121  *
2122  * RETURN:      Status
2123  *
2124  * DESCRIPTION: Compile generic unknown table.
2125  *
2126  *****************************************************************************/
2127 
2128 ACPI_STATUS
2129 DtCompileGeneric (
2130     void                    **List,
2131     char                    *Name,
2132     UINT32                  *Length)
2133 {
2134     ACPI_STATUS             Status;
2135     DT_SUBTABLE             *Subtable;
2136     DT_SUBTABLE             *ParentTable;
2137     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2138     ACPI_DMTABLE_INFO       *Info;
2139 
2140 
2141     ParentTable = DtPeekSubtable ();
2142 
2143     /*
2144      * Compile the "generic" portion of the table. This
2145      * part of the table is not predefined and any of the generic
2146      * operators may be used.
2147      */
2148 
2149     /* Find any and all labels in the entire generic portion */
2150 
2151     DtDetectAllLabels (*PFieldList);
2152 
2153     /* Now we can actually compile the parse tree */
2154 
2155     if (Length && *Length)
2156     {
2157         *Length = 0;
2158     }
2159     while (*PFieldList)
2160     {
2161         if (Name && !strcmp ((*PFieldList)->Name, Name))
2162         {
2163             break;
2164         }
2165 
2166         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2167         if (!Info)
2168         {
2169             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2170                 (*PFieldList)->Name);
2171             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2172                 (*PFieldList), MsgBuffer);
2173 
2174             *PFieldList = (*PFieldList)->Next;
2175             continue;
2176         }
2177 
2178         Status = DtCompileTable (PFieldList, Info,
2179             &Subtable, TRUE);
2180         if (ACPI_SUCCESS (Status))
2181         {
2182             DtInsertSubtable (ParentTable, Subtable);
2183             if (Length)
2184             {
2185                 *Length += Subtable->Length;
2186             }
2187         }
2188         else
2189         {
2190             *PFieldList = (*PFieldList)->Next;
2191 
2192             if (Status == AE_NOT_FOUND)
2193             {
2194                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2195                     (*PFieldList)->Name);
2196                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2197                     (*PFieldList), MsgBuffer);
2198             }
2199         }
2200     }
2201 
2202     return (AE_OK);
2203 }
2204