xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/dttable2.c (revision aef5eb5f59cdfe8314f1b5f78ac04eb144e44010)
1 /******************************************************************************
2  *
3  * Module Name: dttable2.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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);
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);
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);
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);
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         case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
262 
263             InfoTable = AcpiDmTableInfoMadt16;
264             break;
265 
266         default:
267 
268             if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED)
269             {
270                 InfoTable = AcpiDmTableInfoMadt17;
271             }
272             else
273             {
274                 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
275                 return (AE_ERROR);
276             }
277 
278             break;
279         }
280 
281         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
282         if (ACPI_FAILURE (Status))
283         {
284             return (Status);
285         }
286 
287         ParentTable = DtPeekSubtable ();
288         DtInsertSubtable (ParentTable, Subtable);
289         DtPopSubtable ();
290     }
291 
292     return (AE_OK);
293 }
294 
295 
296 /******************************************************************************
297  *
298  * FUNCTION:    DtCompileMcfg
299  *
300  * PARAMETERS:  List                - Current field list pointer
301  *
302  * RETURN:      Status
303  *
304  * DESCRIPTION: Compile MCFG.
305  *
306  *****************************************************************************/
307 
308 ACPI_STATUS
309 DtCompileMcfg (
310     void                    **List)
311 {
312     ACPI_STATUS             Status;
313 
314 
315     Status = DtCompileTwoSubtables (List,
316         AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
317     return (Status);
318 }
319 
320 
321 /******************************************************************************
322  *
323  * FUNCTION:    DtCompileMpst
324  *
325  * PARAMETERS:  List                - Current field list pointer
326  *
327  * RETURN:      Status
328  *
329  * DESCRIPTION: Compile MPST.
330  *
331  *****************************************************************************/
332 
333 ACPI_STATUS
334 DtCompileMpst (
335     void                    **List)
336 {
337     ACPI_STATUS             Status;
338     DT_SUBTABLE             *Subtable;
339     DT_SUBTABLE             *ParentTable;
340     DT_FIELD                **PFieldList = (DT_FIELD **) List;
341     ACPI_MPST_CHANNEL       *MpstChannelInfo;
342     ACPI_MPST_POWER_NODE    *MpstPowerNode;
343     ACPI_MPST_DATA_HDR      *MpstDataHeader;
344     UINT16                  SubtableCount;
345     UINT32                  PowerStateCount;
346     UINT32                  ComponentCount;
347 
348 
349     /* Main table */
350 
351     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable);
352     if (ACPI_FAILURE (Status))
353     {
354         return (Status);
355     }
356 
357     ParentTable = DtPeekSubtable ();
358     DtInsertSubtable (ParentTable, Subtable);
359     DtPushSubtable (Subtable);
360 
361     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
362     SubtableCount = MpstChannelInfo->PowerNodeCount;
363 
364     while (*PFieldList && SubtableCount)
365     {
366         /* Subtable: Memory Power Node(s) */
367 
368         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
369             &Subtable);
370         if (ACPI_FAILURE (Status))
371         {
372             return (Status);
373         }
374 
375         ParentTable = DtPeekSubtable ();
376         DtInsertSubtable (ParentTable, Subtable);
377         DtPushSubtable (Subtable);
378 
379         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
380         PowerStateCount = MpstPowerNode->NumPowerStates;
381         ComponentCount = MpstPowerNode->NumPhysicalComponents;
382 
383         ParentTable = DtPeekSubtable ();
384 
385         /* Sub-subtables - Memory Power State Structure(s) */
386 
387         while (*PFieldList && PowerStateCount)
388         {
389             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
390                 &Subtable);
391             if (ACPI_FAILURE (Status))
392             {
393                 return (Status);
394             }
395 
396             DtInsertSubtable (ParentTable, Subtable);
397             PowerStateCount--;
398         }
399 
400         /* Sub-subtables - Physical Component ID Structure(s) */
401 
402         while (*PFieldList && ComponentCount)
403         {
404             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
405                 &Subtable);
406             if (ACPI_FAILURE (Status))
407             {
408                 return (Status);
409             }
410 
411             DtInsertSubtable (ParentTable, Subtable);
412             ComponentCount--;
413         }
414 
415         SubtableCount--;
416         DtPopSubtable ();
417     }
418 
419     /* Subtable: Count of Memory Power State Characteristic structures */
420 
421     DtPopSubtable ();
422 
423     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable);
424     if (ACPI_FAILURE (Status))
425     {
426         return (Status);
427     }
428 
429     ParentTable = DtPeekSubtable ();
430     DtInsertSubtable (ParentTable, Subtable);
431     DtPushSubtable (Subtable);
432 
433     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
434     SubtableCount = MpstDataHeader->CharacteristicsCount;
435 
436     ParentTable = DtPeekSubtable ();
437 
438     /* Subtable: Memory Power State Characteristics structure(s) */
439 
440     while (*PFieldList && SubtableCount)
441     {
442         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
443             &Subtable);
444         if (ACPI_FAILURE (Status))
445         {
446             return (Status);
447         }
448 
449         DtInsertSubtable (ParentTable, Subtable);
450         SubtableCount--;
451     }
452 
453     DtPopSubtable ();
454     return (AE_OK);
455 }
456 
457 
458 /******************************************************************************
459  *
460  * FUNCTION:    DtCompileMsct
461  *
462  * PARAMETERS:  List                - Current field list pointer
463  *
464  * RETURN:      Status
465  *
466  * DESCRIPTION: Compile MSCT.
467  *
468  *****************************************************************************/
469 
470 ACPI_STATUS
471 DtCompileMsct (
472     void                    **List)
473 {
474     ACPI_STATUS             Status;
475 
476 
477     Status = DtCompileTwoSubtables (List,
478         AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
479     return (Status);
480 }
481 
482 
483 /******************************************************************************
484  *
485  * FUNCTION:    DtCompileNfit
486  *
487  * PARAMETERS:  List                - Current field list pointer
488  *
489  * RETURN:      Status
490  *
491  * DESCRIPTION: Compile NFIT.
492  *
493  *****************************************************************************/
494 
495 ACPI_STATUS
496 DtCompileNfit (
497     void                    **List)
498 {
499     ACPI_STATUS             Status;
500     DT_SUBTABLE             *Subtable;
501     DT_SUBTABLE             *ParentTable;
502     DT_FIELD                **PFieldList = (DT_FIELD **) List;
503     DT_FIELD                *SubtableStart;
504     ACPI_NFIT_HEADER        *NfitHeader;
505     ACPI_DMTABLE_INFO       *InfoTable;
506     UINT32                  Count;
507     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
508     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
509 
510 
511     /* Main table */
512 
513     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
514         &Subtable);
515     if (ACPI_FAILURE (Status))
516     {
517         return (Status);
518     }
519 
520     ParentTable = DtPeekSubtable ();
521     DtInsertSubtable (ParentTable, Subtable);
522     DtPushSubtable (Subtable);
523 
524     /* Subtables */
525 
526     while (*PFieldList)
527     {
528         SubtableStart = *PFieldList;
529         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
530             &Subtable);
531         if (ACPI_FAILURE (Status))
532         {
533             return (Status);
534         }
535 
536         ParentTable = DtPeekSubtable ();
537         DtInsertSubtable (ParentTable, Subtable);
538         DtPushSubtable (Subtable);
539 
540         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
541 
542         switch (NfitHeader->Type)
543         {
544         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
545 
546             InfoTable = AcpiDmTableInfoNfit0;
547             break;
548 
549         case ACPI_NFIT_TYPE_MEMORY_MAP:
550 
551             InfoTable = AcpiDmTableInfoNfit1;
552             break;
553 
554         case ACPI_NFIT_TYPE_INTERLEAVE:
555 
556             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
557             InfoTable = AcpiDmTableInfoNfit2;
558             break;
559 
560         case ACPI_NFIT_TYPE_SMBIOS:
561 
562             InfoTable = AcpiDmTableInfoNfit3;
563             break;
564 
565         case ACPI_NFIT_TYPE_CONTROL_REGION:
566 
567             InfoTable = AcpiDmTableInfoNfit4;
568             break;
569 
570         case ACPI_NFIT_TYPE_DATA_REGION:
571 
572             InfoTable = AcpiDmTableInfoNfit5;
573             break;
574 
575         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
576 
577             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
578             InfoTable = AcpiDmTableInfoNfit6;
579             break;
580 
581         case ACPI_NFIT_TYPE_CAPABILITIES:
582 
583             InfoTable = AcpiDmTableInfoNfit7;
584             break;
585 
586         default:
587 
588             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
589             return (AE_ERROR);
590         }
591 
592         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
593         if (ACPI_FAILURE (Status))
594         {
595             return (Status);
596         }
597 
598         ParentTable = DtPeekSubtable ();
599         DtInsertSubtable (ParentTable, Subtable);
600         DtPopSubtable ();
601 
602         switch (NfitHeader->Type)
603         {
604         case ACPI_NFIT_TYPE_INTERLEAVE:
605 
606             Count = 0;
607             DtPushSubtable (Subtable);
608             while (*PFieldList)
609             {
610                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
611                     &Subtable);
612                 if (ACPI_FAILURE (Status))
613                 {
614                     return (Status);
615                 }
616 
617                 if (!Subtable)
618                 {
619                     DtPopSubtable ();
620                     break;
621                 }
622 
623                 ParentTable = DtPeekSubtable ();
624                 DtInsertSubtable (ParentTable, Subtable);
625                 Count++;
626             }
627 
628             Interleave->LineCount = Count;
629             break;
630 
631         case ACPI_NFIT_TYPE_SMBIOS:
632 
633             if (*PFieldList)
634             {
635                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
636                     &Subtable);
637                 if (ACPI_FAILURE (Status))
638                 {
639                     return (Status);
640                 }
641 
642                 if (Subtable)
643                 {
644                     DtInsertSubtable (ParentTable, Subtable);
645                 }
646             }
647             break;
648 
649         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
650 
651             Count = 0;
652             DtPushSubtable (Subtable);
653             while (*PFieldList)
654             {
655                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
656                     &Subtable);
657                 if (ACPI_FAILURE (Status))
658                 {
659                     return (Status);
660                 }
661 
662                 if (!Subtable)
663                 {
664                     DtPopSubtable ();
665                     break;
666                 }
667 
668                 ParentTable = DtPeekSubtable ();
669                 DtInsertSubtable (ParentTable, Subtable);
670                 Count++;
671             }
672 
673             Hint->HintCount = (UINT16) Count;
674             break;
675 
676         default:
677             break;
678         }
679     }
680 
681     return (AE_OK);
682 }
683 
684 
685 /******************************************************************************
686  *
687  * FUNCTION:    DtCompileNhlt
688  *
689  * PARAMETERS:  List                - Current field list pointer
690  *
691  * RETURN:      Status
692  *
693  * DESCRIPTION: Compile NHLT.
694  *
695  *****************************************************************************/
696 
697 ACPI_STATUS
698 DtCompileNhlt (
699     void                    **List)
700 {
701     ACPI_STATUS             Status;
702     UINT32                  EndpointCount;
703     UINT32                  MicrophoneCount;
704     UINT32                  FormatsCount;
705     DT_SUBTABLE             *Subtable;
706     DT_SUBTABLE             *ParentTable;
707     DT_FIELD                **PFieldList = (DT_FIELD **) List;
708     UINT32                  CapabilitiesSize;
709     UINT8                   ArrayType;
710     UINT8                   ConfigType;
711     UINT8                   DeviceInfoCount;
712     UINT32                  i;
713     UINT32                  j;
714     ACPI_TABLE_NHLT_ENDPOINT_COUNT      *MainTable;
715     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A  *DevSpecific;
716     ACPI_NHLT_VENDOR_MIC_COUNT          *MicCount;
717     ACPI_NHLT_FORMATS_CONFIG            *FormatsConfig;
718     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D  *ConfigSpecific;
719     ACPI_NHLT_DEVICE_INFO_COUNT         *DeviceInfo;
720 
721 
722     /* Main table */
723 
724     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt,
725         &Subtable);
726     if (ACPI_FAILURE (Status))
727     {
728         return (Status);
729     }
730 
731     /* Get the Endpoint Descriptor count */
732 
733     ParentTable = DtPeekSubtable ();
734     DtInsertSubtable (ParentTable, Subtable);
735     DtPushSubtable (Subtable);
736 
737     MainTable = ACPI_CAST_PTR (ACPI_TABLE_NHLT_ENDPOINT_COUNT, Subtable->Buffer);
738     EndpointCount = MainTable->EndpointCount;
739 
740     /* Subtables */
741 
742     while (*PFieldList)
743     {
744         /* Variable number of Endpoint descriptors */
745 
746         for (i = 0; i < EndpointCount; i++)
747         {
748             /* Do the Endpoint Descriptor */
749 
750             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt0,
751                 &Subtable);
752             if (ACPI_FAILURE (Status))
753             {
754                 return (Status);
755             }
756 
757             ParentTable = DtPeekSubtable ();
758             DtInsertSubtable (ParentTable, Subtable);
759             DtPushSubtable (Subtable);
760 
761             /* Do the Device Specific table */
762 
763             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b,
764                 &Subtable);
765             if (ACPI_FAILURE (Status))
766             {
767                 return (Status);
768             }
769 
770             ParentTable = DtPeekSubtable ();
771             DtInsertSubtable (ParentTable, Subtable);
772             DtPushSubtable (Subtable);
773 
774             DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable->Buffer);
775             CapabilitiesSize = DevSpecific->CapabilitiesSize;
776 
777             ArrayType = 0;
778             ConfigType = 0;
779 
780             switch (CapabilitiesSize)
781             {
782             case 0:
783                 break;
784 
785             case 1:
786 
787                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5c,
788                     &Subtable);
789                 if (ACPI_FAILURE (Status))
790                 {
791                     return (Status);
792                 }
793 
794                 ParentTable = DtPeekSubtable ();
795                 DtInsertSubtable (ParentTable, Subtable);
796                 break;
797 
798             case 2:
799 
800                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5,
801                     &Subtable);
802                 if (ACPI_FAILURE (Status))
803                 {
804                     return (Status);
805                 }
806 
807                 ParentTable = DtPeekSubtable ();
808                 DtInsertSubtable (ParentTable, Subtable);
809                 break;
810 
811             case 3:
812 
813                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a,
814                     &Subtable);
815                 if (ACPI_FAILURE (Status))
816                 {
817                     return (Status);
818                 }
819 
820                 ParentTable = DtPeekSubtable ();
821                 DtInsertSubtable (ParentTable, Subtable);
822 
823                 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer);
824                 ArrayType = ConfigSpecific->ArrayType;
825                 ConfigType = ConfigSpecific->ConfigType;
826                 break;
827 
828             case 7:
829 
830                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5,
831                     &Subtable);
832                 if (ACPI_FAILURE (Status))
833                 {
834                     return (Status);
835                 }
836 
837                 ParentTable = DtPeekSubtable ();
838                 DtInsertSubtable (ParentTable, Subtable);
839 
840                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6b,
841                     &Subtable);
842                 if (ACPI_FAILURE (Status))
843                 {
844                     return (Status);
845                 }
846 
847                 ParentTable = DtPeekSubtable ();
848                 DtInsertSubtable (ParentTable, Subtable);
849 
850                 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer);
851                 ArrayType = ConfigSpecific->ArrayType;
852                 ConfigType = ConfigSpecific->ConfigType;
853                 break;
854 
855             default:
856 
857                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a,
858                     &Subtable);
859                 if (ACPI_FAILURE (Status))
860                 {
861                     return (Status);
862                 }
863 
864                 ParentTable = DtPeekSubtable ();
865                 DtInsertSubtable (ParentTable, Subtable);
866 
867                 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer);
868                 ArrayType = ConfigSpecific->ArrayType;
869                 ConfigType = ConfigSpecific->ConfigType;
870                 break;
871 
872             } /* switch (CapabilitiesSize) */
873 
874             if (CapabilitiesSize >= 3)
875             {
876                 /* Check for a vendor-defined mic array */
877 
878                 if (ConfigType == ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY)
879                 {
880                     if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_MASK) == ACPI_NHLT_VENDOR_DEFINED)
881                     {
882                         /* Get the microphone count */
883 
884                         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6a,
885                             &Subtable);
886                         if (ACPI_FAILURE (Status))
887                         {
888                             return (Status);
889                         }
890 
891                         MicCount = ACPI_CAST_PTR (ACPI_NHLT_VENDOR_MIC_COUNT, Subtable->Buffer);
892                         MicrophoneCount = MicCount->MicrophoneCount;
893 
894                         ParentTable = DtPeekSubtable ();
895                         DtInsertSubtable (ParentTable, Subtable);
896 
897                         /* Variable number of microphones */
898 
899                         for (j = 0; j < MicrophoneCount; j++)
900                         {
901                             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6,
902                                 &Subtable);
903                             if (ACPI_FAILURE (Status))
904                             {
905                                 return (Status);
906                             }
907 
908                             ParentTable = DtPeekSubtable ();
909                             DtInsertSubtable (ParentTable, Subtable);
910                         }
911 
912                         /* Do the MIC_SNR_SENSITIVITY_EXTENSION, if present */
913 
914                         if (ArrayType & ACPI_NHLT_ARRAY_TYPE_EXT_MASK)
915                         {
916                             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt9,
917                                 &Subtable);
918                             if (ACPI_FAILURE (Status))
919                             {
920                                 return (Status);
921                             }
922 
923                             ParentTable = DtPeekSubtable ();
924                             DtInsertSubtable (ParentTable, Subtable);
925                         }
926                     }
927                 }
928             }
929 
930             /* Get the formats count */
931 
932             DtPopSubtable ();
933             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt4,
934                 &Subtable);
935             if (ACPI_FAILURE (Status))
936             {
937                 return (Status);
938             }
939 
940             ParentTable = DtPeekSubtable ();
941             DtInsertSubtable (ParentTable, Subtable);
942 
943             FormatsConfig = ACPI_CAST_PTR (ACPI_NHLT_FORMATS_CONFIG, Subtable->Buffer);
944             FormatsCount = FormatsConfig->FormatsCount;
945 
946             /* Variable number of wave_format_extensible structs */
947 
948             for (j = 0; j < FormatsCount; j++)
949             {
950                 /* Do the main wave_format_extensible structure */
951 
952                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3,
953                     &Subtable);
954                 if (ACPI_FAILURE (Status))
955                 {
956                     return (Status);
957                 }
958 
959                 ParentTable = DtPeekSubtable ();
960                 DtInsertSubtable (ParentTable, Subtable);
961                 DtPushSubtable (Subtable);
962 
963                 /* Do the capabilities list */
964 
965                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a,
966                     &Subtable);
967                 if (ACPI_FAILURE (Status))
968                 {
969                     return (Status);
970                 }
971 
972                 DtPopSubtable ();
973                 ParentTable = DtPeekSubtable ();
974                 DtInsertSubtable (ParentTable, Subtable);
975 
976             } /* for (j = 0; j < FormatsCount; j++) */
977 
978             /*
979              * If we are not done with the current Endpoint yet, then there must be
980              * some non documeneted structure(s) yet to be processed. First, get
981              * the count of such structure(s).
982              */
983             if (*PFieldList && (strcmp ((const char *) (*PFieldList)->Name, "Descriptor Length")))
984             {
985                 /* Get the count of non documented structures */
986 
987                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7,
988                     &Subtable);
989                 if (ACPI_FAILURE (Status))
990                 {
991                     return (Status);
992                 }
993 
994                 ParentTable = DtPeekSubtable ();
995                 DtInsertSubtable (ParentTable, Subtable);
996 
997                 DeviceInfo = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_INFO_COUNT, Subtable->Buffer);
998                 DeviceInfoCount = DeviceInfo->StructureCount;
999 
1000                 for (j = 0; j < DeviceInfoCount; j++)
1001                 {
1002                     /*
1003                      * Compile the following Device Info fields:
1004                      *  1) Device ID
1005                      *  2) Device Instance ID
1006                      *  3) Device Port ID
1007                      */
1008                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7a,
1009                         &Subtable);
1010                     if (ACPI_FAILURE (Status))
1011                     {
1012                         return (Status);
1013                     }
1014 
1015                     ParentTable = DtPeekSubtable ();
1016                     DtInsertSubtable (ParentTable, Subtable);
1017                 } /* for (j = 0; j < LinuxSpecificCount; j++) */
1018 
1019 
1020                 /* Undocumented data at the end of endpoint */
1021                 if (*PFieldList && (strcmp ((const char *) (*PFieldList)->Name, "Descriptor Length")))
1022                 {
1023                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7b,
1024                         &Subtable);
1025                     if (ACPI_FAILURE (Status))
1026                     {
1027                         return (Status);
1028                     }
1029 
1030                     ParentTable = DtPeekSubtable ();
1031                     DtInsertSubtable (ParentTable, Subtable);
1032                 }
1033             }
1034 
1035             DtPopSubtable ();
1036 
1037         } /* for (i = 0; i < EndpointCount; i++) */
1038 
1039         /*
1040          * All Endpoint Descriptors are completed.
1041          * Do the table terminator specific config (not in NHLT spec, optional)
1042          */
1043         if (*PFieldList && (strcmp ((const char *) (*PFieldList)->Name, "Descriptor Length")))
1044         {
1045             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b,
1046                 &Subtable);
1047             if (ACPI_FAILURE (Status))
1048             {
1049                 return (Status);
1050             }
1051 
1052             ParentTable = DtPeekSubtable ();
1053             DtInsertSubtable (ParentTable, Subtable);
1054 
1055             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a,
1056                 &Subtable);
1057             if (ACPI_FAILURE (Status))
1058             {
1059                 return (Status);
1060             }
1061 
1062             ParentTable = DtPeekSubtable ();
1063             DtInsertSubtable (ParentTable, Subtable);
1064         }
1065 
1066         return (AE_OK);
1067     }
1068 
1069     return (AE_OK);
1070 }
1071 
1072 
1073 /******************************************************************************
1074  *
1075  * FUNCTION:    DtCompilePcct
1076  *
1077  * PARAMETERS:  List                - Current field list pointer
1078  *
1079  * RETURN:      Status
1080  *
1081  * DESCRIPTION: Compile PCCT.
1082  *
1083  *****************************************************************************/
1084 
1085 ACPI_STATUS
1086 DtCompilePcct (
1087     void                    **List)
1088 {
1089     ACPI_STATUS             Status;
1090     DT_SUBTABLE             *Subtable;
1091     DT_SUBTABLE             *ParentTable;
1092     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1093     DT_FIELD                *SubtableStart;
1094     ACPI_SUBTABLE_HEADER    *PcctHeader;
1095     ACPI_DMTABLE_INFO       *InfoTable;
1096 
1097 
1098     /* Main table */
1099 
1100     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1101         &Subtable);
1102     if (ACPI_FAILURE (Status))
1103     {
1104         return (Status);
1105     }
1106 
1107     ParentTable = DtPeekSubtable ();
1108     DtInsertSubtable (ParentTable, Subtable);
1109 
1110     /* Subtables */
1111 
1112     while (*PFieldList)
1113     {
1114         SubtableStart = *PFieldList;
1115         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1116             &Subtable);
1117         if (ACPI_FAILURE (Status))
1118         {
1119             return (Status);
1120         }
1121 
1122         ParentTable = DtPeekSubtable ();
1123         DtInsertSubtable (ParentTable, Subtable);
1124         DtPushSubtable (Subtable);
1125 
1126         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1127 
1128         switch (PcctHeader->Type)
1129         {
1130         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1131 
1132             InfoTable = AcpiDmTableInfoPcct0;
1133             break;
1134 
1135         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1136 
1137             InfoTable = AcpiDmTableInfoPcct1;
1138             break;
1139 
1140         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
1141 
1142             InfoTable = AcpiDmTableInfoPcct2;
1143             break;
1144 
1145         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
1146 
1147             InfoTable = AcpiDmTableInfoPcct3;
1148             break;
1149 
1150         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
1151 
1152             InfoTable = AcpiDmTableInfoPcct4;
1153             break;
1154 
1155         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
1156 
1157             InfoTable = AcpiDmTableInfoPcct5;
1158             break;
1159 
1160         default:
1161 
1162             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1163             return (AE_ERROR);
1164         }
1165 
1166         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1167         if (ACPI_FAILURE (Status))
1168         {
1169             return (Status);
1170         }
1171 
1172         ParentTable = DtPeekSubtable ();
1173         DtInsertSubtable (ParentTable, Subtable);
1174         DtPopSubtable ();
1175     }
1176 
1177     return (AE_OK);
1178 }
1179 
1180 
1181 /******************************************************************************
1182  *
1183  * FUNCTION:    DtCompilePdtt
1184  *
1185  * PARAMETERS:  List                - Current field list pointer
1186  *
1187  * RETURN:      Status
1188  *
1189  * DESCRIPTION: Compile PDTT.
1190  *
1191  *****************************************************************************/
1192 
1193 ACPI_STATUS
1194 DtCompilePdtt (
1195     void                    **List)
1196 {
1197     ACPI_STATUS             Status;
1198     DT_SUBTABLE             *Subtable;
1199     DT_SUBTABLE             *ParentTable;
1200     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1201     ACPI_TABLE_PDTT         *PdttHeader;
1202     UINT32                  Count = 0;
1203 
1204 
1205     /* Main table */
1206 
1207     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
1208     if (ACPI_FAILURE (Status))
1209     {
1210         return (Status);
1211     }
1212 
1213     ParentTable = DtPeekSubtable ();
1214     DtInsertSubtable (ParentTable, Subtable);
1215 
1216     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
1217     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
1218 
1219     /* There is only one type of subtable at this time, no need to decode */
1220 
1221     while (*PFieldList)
1222     {
1223         /* List of subchannel IDs, each 2 bytes */
1224 
1225         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
1226             &Subtable);
1227         if (ACPI_FAILURE (Status))
1228         {
1229             return (Status);
1230         }
1231 
1232         DtInsertSubtable (ParentTable, Subtable);
1233         Count++;
1234     }
1235 
1236     PdttHeader->TriggerCount = (UINT8) Count;
1237     return (AE_OK);
1238 }
1239 
1240 
1241 /******************************************************************************
1242  *
1243  * FUNCTION:    DtCompilePhat
1244  *
1245  * PARAMETERS:  List                - Current field list pointer
1246  *
1247  * RETURN:      Status
1248  *
1249  * DESCRIPTION: Compile Phat.
1250  *
1251  *****************************************************************************/
1252 
1253 ACPI_STATUS
1254 DtCompilePhat (
1255     void                    **List)
1256 {
1257     ACPI_STATUS             Status = AE_OK;
1258     DT_SUBTABLE             *Subtable;
1259     DT_SUBTABLE             *ParentTable;
1260     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1261     ACPI_PHAT_HEADER        *PhatHeader;
1262     ACPI_DMTABLE_INFO       *Info;
1263     ACPI_PHAT_VERSION_DATA  *VersionData;
1264     UINT32                  RecordCount;
1265 
1266 
1267     /* The table consist of subtables */
1268 
1269     while (*PFieldList)
1270     {
1271         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
1272         if (ACPI_FAILURE (Status))
1273         {
1274             return (Status);
1275         }
1276 
1277         ParentTable = DtPeekSubtable ();
1278         DtInsertSubtable (ParentTable, Subtable);
1279         DtPushSubtable (Subtable);
1280 
1281         PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
1282 
1283         switch (PhatHeader->Type)
1284         {
1285         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1286 
1287             Info = AcpiDmTableInfoPhat0;
1288             PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
1289             break;
1290 
1291         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1292 
1293             Info = AcpiDmTableInfoPhat1;
1294             PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
1295             break;
1296 
1297         default:
1298 
1299             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1300             return (AE_ERROR);
1301 
1302             break;
1303         }
1304 
1305         Status = DtCompileTable (PFieldList, Info, &Subtable);
1306         if (ACPI_FAILURE (Status))
1307         {
1308             return (Status);
1309         }
1310 
1311         ParentTable = DtPeekSubtable ();
1312         DtInsertSubtable (ParentTable, Subtable);
1313 
1314         switch (PhatHeader->Type)
1315         {
1316         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1317 
1318             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
1319                 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
1320             RecordCount = VersionData->ElementCount;
1321 
1322             while (RecordCount)
1323             {
1324                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
1325                     &Subtable);
1326                 if (ACPI_FAILURE (Status))
1327                 {
1328                     return (Status);
1329                 }
1330                 ParentTable = DtPeekSubtable ();
1331                 DtInsertSubtable (ParentTable, Subtable);
1332 
1333                 RecordCount--;
1334                 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
1335             }
1336             break;
1337 
1338         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1339 
1340             /* Compile device path */
1341 
1342             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
1343             if (ACPI_FAILURE (Status))
1344             {
1345                 return (Status);
1346             }
1347             ParentTable = DtPeekSubtable ();
1348             DtInsertSubtable (ParentTable, Subtable);
1349 
1350             PhatHeader->Length += (UINT16) Subtable->Length;
1351 
1352             /* Compile vendor specific data */
1353 
1354             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
1355             if (ACPI_FAILURE (Status))
1356             {
1357                 return (Status);
1358             }
1359             ParentTable = DtPeekSubtable ();
1360             DtInsertSubtable (ParentTable, Subtable);
1361 
1362             PhatHeader->Length += (UINT16) Subtable->Length;
1363 
1364             break;
1365 
1366         default:
1367 
1368             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1369             return (AE_ERROR);
1370         }
1371     }
1372 
1373     return (Status);
1374 }
1375 
1376 
1377 /******************************************************************************
1378  *
1379  * FUNCTION:    DtCompilePmtt
1380  *
1381  * PARAMETERS:  List                - Current field list pointer
1382  *
1383  * RETURN:      Status
1384  *
1385  * DESCRIPTION: Compile PMTT.
1386  *
1387  *****************************************************************************/
1388 
1389 ACPI_STATUS
1390 DtCompilePmtt (
1391     void                    **List)
1392 {
1393     ACPI_STATUS             Status;
1394     DT_SUBTABLE             *Subtable;
1395     DT_SUBTABLE             *ParentTable;
1396     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1397     DT_FIELD                *SubtableStart;
1398     UINT16                  Type;
1399 
1400 
1401     /* Main table */
1402 
1403     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
1404     if (ACPI_FAILURE (Status))
1405     {
1406         return (Status);
1407     }
1408 
1409     ParentTable = DtPeekSubtable ();
1410     DtInsertSubtable (ParentTable, Subtable);
1411     DtPushSubtable (Subtable);
1412 
1413     /* Subtables */
1414 
1415     while (*PFieldList)
1416     {
1417         SubtableStart = *PFieldList;
1418         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1419 
1420         switch (Type)
1421         {
1422         case ACPI_PMTT_TYPE_SOCKET:
1423 
1424             /* Subtable: Socket Structure */
1425 
1426             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
1427 
1428             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1429                 &Subtable);
1430             if (ACPI_FAILURE (Status))
1431             {
1432                 return (Status);
1433             }
1434 
1435             break;
1436 
1437         case ACPI_PMTT_TYPE_CONTROLLER:
1438 
1439             /* Subtable: Memory Controller Structure */
1440 
1441             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
1442 
1443             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1444                 &Subtable);
1445             if (ACPI_FAILURE (Status))
1446             {
1447                 return (Status);
1448             }
1449 
1450             break;
1451 
1452         case ACPI_PMTT_TYPE_DIMM:
1453 
1454             /* Subtable: Physical Component (DIMM) Structure */
1455 
1456             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
1457             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1458                 &Subtable);
1459             if (ACPI_FAILURE (Status))
1460             {
1461                 return (Status);
1462             }
1463 
1464             break;
1465 
1466         case ACPI_PMTT_TYPE_VENDOR:
1467 
1468             /* Subtable: Vendor-specific Structure */
1469 
1470             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
1471             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
1472                 &Subtable);
1473             if (ACPI_FAILURE (Status))
1474             {
1475                 return (Status);
1476             }
1477 
1478             break;
1479 
1480         default:
1481 
1482             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1483             return (AE_ERROR);
1484         }
1485 
1486         DtInsertSubtable (ParentTable, Subtable);
1487     }
1488 
1489     return (Status);
1490 }
1491 
1492 
1493 /******************************************************************************
1494  *
1495  * FUNCTION:    DtCompilePptt
1496  *
1497  * PARAMETERS:  List                - Current field list pointer
1498  *
1499  * RETURN:      Status
1500  *
1501  * DESCRIPTION: Compile PPTT.
1502  *
1503  *****************************************************************************/
1504 
1505 ACPI_STATUS
1506 DtCompilePptt (
1507     void                    **List)
1508 {
1509     ACPI_STATUS             Status;
1510     ACPI_SUBTABLE_HEADER    *PpttHeader;
1511     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
1512     DT_SUBTABLE             *Subtable;
1513     DT_SUBTABLE             *ParentTable;
1514     ACPI_DMTABLE_INFO       *InfoTable;
1515     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1516     DT_FIELD                *SubtableStart;
1517     ACPI_TABLE_HEADER       *PpttAcpiHeader;
1518 
1519 
1520     ParentTable = DtPeekSubtable ();
1521     while (*PFieldList)
1522     {
1523         SubtableStart = *PFieldList;
1524 
1525         /* Compile PPTT subtable header */
1526 
1527         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1528             &Subtable);
1529         if (ACPI_FAILURE (Status))
1530         {
1531             return (Status);
1532         }
1533         DtInsertSubtable (ParentTable, Subtable);
1534         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1535         PpttHeader->Length = (UINT8)(Subtable->Length);
1536 
1537         switch (PpttHeader->Type)
1538         {
1539         case ACPI_PPTT_TYPE_PROCESSOR:
1540 
1541             InfoTable = AcpiDmTableInfoPptt0;
1542             break;
1543 
1544         case ACPI_PPTT_TYPE_CACHE:
1545 
1546             InfoTable = AcpiDmTableInfoPptt1;
1547             break;
1548 
1549         case ACPI_PPTT_TYPE_ID:
1550 
1551             InfoTable = AcpiDmTableInfoPptt2;
1552             break;
1553 
1554         default:
1555 
1556             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1557             return (AE_ERROR);
1558         }
1559 
1560         /* Compile PPTT subtable body */
1561 
1562         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1563         if (ACPI_FAILURE (Status))
1564         {
1565             return (Status);
1566         }
1567         DtInsertSubtable (ParentTable, Subtable);
1568         PpttHeader->Length += (UINT8)(Subtable->Length);
1569 
1570         /* Compile PPTT subtable additionals */
1571 
1572         switch (PpttHeader->Type)
1573         {
1574         case ACPI_PPTT_TYPE_PROCESSOR:
1575 
1576             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1577                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1578             if (PpttProcessor)
1579             {
1580                 /* Compile initiator proximity domain list */
1581 
1582                 PpttProcessor->NumberOfPrivResources = 0;
1583                 while (*PFieldList)
1584                 {
1585                     Status = DtCompileTable (PFieldList,
1586                         AcpiDmTableInfoPptt0a, &Subtable);
1587                     if (ACPI_FAILURE (Status))
1588                     {
1589                         return (Status);
1590                     }
1591                     if (!Subtable)
1592                     {
1593                         break;
1594                     }
1595 
1596                     DtInsertSubtable (ParentTable, Subtable);
1597                     PpttHeader->Length += (UINT8)(Subtable->Length);
1598                     PpttProcessor->NumberOfPrivResources++;
1599                 }
1600             }
1601             break;
1602 
1603         case ACPI_PPTT_TYPE_CACHE:
1604 
1605             PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1606                 AslGbl_RootTable->Buffer);
1607             if (PpttAcpiHeader->Revision < 3)
1608             {
1609                 break;
1610             }
1611             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
1612                 &Subtable);
1613             DtInsertSubtable (ParentTable, Subtable);
1614             PpttHeader->Length += (UINT8)(Subtable->Length);
1615             break;
1616 
1617         default:
1618 
1619             break;
1620         }
1621     }
1622 
1623     return (AE_OK);
1624 }
1625 
1626 
1627 /******************************************************************************
1628  *
1629  * FUNCTION:    DtCompilePrmt
1630  *
1631  * PARAMETERS:  List                - Current field list pointer
1632  *
1633  * RETURN:      Status
1634  *
1635  * DESCRIPTION: Compile PRMT.
1636  *
1637  *****************************************************************************/
1638 
1639 ACPI_STATUS
1640 DtCompilePrmt (
1641     void                    **List)
1642 {
1643     ACPI_STATUS             Status;
1644     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
1645     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
1646     DT_SUBTABLE             *Subtable;
1647     DT_SUBTABLE             *ParentTable;
1648     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1649     UINT32                  i, j;
1650 
1651     ParentTable = DtPeekSubtable ();
1652 
1653     /* Compile PRMT subtable header */
1654 
1655     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
1656         &Subtable);
1657     if (ACPI_FAILURE (Status))
1658     {
1659         return (Status);
1660     }
1661     DtInsertSubtable (ParentTable, Subtable);
1662     PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
1663 
1664     for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
1665     {
1666         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
1667             &Subtable);
1668         if (ACPI_FAILURE (Status))
1669         {
1670             return (Status);
1671         }
1672         DtInsertSubtable (ParentTable, Subtable);
1673         PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
1674 
1675         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
1676         {
1677             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
1678                 &Subtable);
1679             if (ACPI_FAILURE (Status))
1680             {
1681                 return (Status);
1682             }
1683             DtInsertSubtable (ParentTable, Subtable);
1684         }
1685     }
1686 
1687     return (AE_OK);
1688 }
1689 
1690 
1691 /******************************************************************************
1692  *
1693  * FUNCTION:    DtCompileRgrt
1694  *
1695  * PARAMETERS:  List                - Current field list pointer
1696  *
1697  * RETURN:      Status
1698  *
1699  * DESCRIPTION: Compile RGRT.
1700  *
1701  *****************************************************************************/
1702 
1703 ACPI_STATUS
1704 DtCompileRgrt (
1705     void                    **List)
1706 {
1707     ACPI_STATUS             Status;
1708     DT_SUBTABLE             *Subtable;
1709     DT_SUBTABLE             *ParentTable;
1710     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1711 
1712 
1713     /* Compile the main table */
1714 
1715     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
1716         &Subtable);
1717     if (ACPI_FAILURE (Status))
1718     {
1719         return (Status);
1720     }
1721 
1722     ParentTable = DtPeekSubtable ();
1723     DtInsertSubtable (ParentTable, Subtable);
1724 
1725     /* Compile the "Subtable" -- actually just the binary (PNG) image */
1726 
1727     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
1728         &Subtable);
1729     if (ACPI_FAILURE (Status))
1730     {
1731         return (Status);
1732     }
1733 
1734     DtInsertSubtable (ParentTable, Subtable);
1735     return (AE_OK);
1736 }
1737 
1738 
1739 /******************************************************************************
1740  *
1741  * FUNCTION:    DtCompileRsdt
1742  *
1743  * PARAMETERS:  List                - Current field list pointer
1744  *
1745  * RETURN:      Status
1746  *
1747  * DESCRIPTION: Compile RSDT.
1748  *
1749  *****************************************************************************/
1750 
1751 ACPI_STATUS
1752 DtCompileRsdt (
1753     void                    **List)
1754 {
1755     DT_SUBTABLE             *Subtable;
1756     DT_SUBTABLE             *ParentTable;
1757     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1758     UINT32                  Address;
1759 
1760 
1761     ParentTable = DtPeekSubtable ();
1762 
1763     while (FieldList)
1764     {
1765         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1766 
1767         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1768         DtInsertSubtable (ParentTable, Subtable);
1769         FieldList = FieldList->Next;
1770     }
1771 
1772     return (AE_OK);
1773 }
1774 
1775 
1776 /******************************************************************************
1777  *
1778  * FUNCTION:    DtCompileS3pt
1779  *
1780  * PARAMETERS:  PFieldList          - Current field list pointer
1781  *
1782  * RETURN:      Status
1783  *
1784  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1785  *
1786  *****************************************************************************/
1787 
1788 ACPI_STATUS
1789 DtCompileS3pt (
1790     DT_FIELD                **PFieldList)
1791 {
1792     ACPI_STATUS             Status;
1793     ACPI_FPDT_HEADER        *S3ptHeader;
1794     DT_SUBTABLE             *Subtable;
1795     DT_SUBTABLE             *ParentTable;
1796     ACPI_DMTABLE_INFO       *InfoTable;
1797     DT_FIELD                *SubtableStart;
1798 
1799 
1800     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1801         &AslGbl_RootTable);
1802     if (ACPI_FAILURE (Status))
1803     {
1804         return (Status);
1805     }
1806 
1807     DtPushSubtable (AslGbl_RootTable);
1808 
1809     while (*PFieldList)
1810     {
1811         SubtableStart = *PFieldList;
1812         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1813             &Subtable);
1814         if (ACPI_FAILURE (Status))
1815         {
1816             return (Status);
1817         }
1818 
1819         ParentTable = DtPeekSubtable ();
1820         DtInsertSubtable (ParentTable, Subtable);
1821         DtPushSubtable (Subtable);
1822 
1823         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1824 
1825         switch (S3ptHeader->Type)
1826         {
1827         case ACPI_S3PT_TYPE_RESUME:
1828 
1829             InfoTable = AcpiDmTableInfoS3pt0;
1830             break;
1831 
1832         case ACPI_S3PT_TYPE_SUSPEND:
1833 
1834             InfoTable = AcpiDmTableInfoS3pt1;
1835             break;
1836 
1837         default:
1838 
1839             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1840             return (AE_ERROR);
1841         }
1842 
1843         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1844         if (ACPI_FAILURE (Status))
1845         {
1846             return (Status);
1847         }
1848 
1849         ParentTable = DtPeekSubtable ();
1850         DtInsertSubtable (ParentTable, Subtable);
1851         DtPopSubtable ();
1852     }
1853 
1854     return (AE_OK);
1855 }
1856 
1857 
1858 /******************************************************************************
1859  *
1860  * FUNCTION:    DtCompileSdev
1861  *
1862  * PARAMETERS:  List                - Current field list pointer
1863  *
1864  * RETURN:      Status
1865  *
1866  * DESCRIPTION: Compile SDEV.
1867  *
1868  *****************************************************************************/
1869 
1870 ACPI_STATUS
1871 DtCompileSdev (
1872     void                    **List)
1873 {
1874     ACPI_STATUS                 Status;
1875     ACPI_SDEV_HEADER            *SdevHeader;
1876     ACPI_SDEV_HEADER            *SecureComponentHeader;
1877     DT_SUBTABLE                 *Subtable;
1878     DT_SUBTABLE                 *ParentTable;
1879     ACPI_DMTABLE_INFO           *InfoTable;
1880     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
1881     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
1882     DT_FIELD                    *SubtableStart;
1883     ACPI_SDEV_PCIE              *Pcie = NULL;
1884     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
1885     UINT32                      EntryCount;
1886     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
1887     UINT16                      ComponentLength = 0;
1888 
1889 
1890     /* Subtables */
1891 
1892     while (*PFieldList)
1893     {
1894         /* Compile common SDEV subtable header */
1895 
1896         SubtableStart = *PFieldList;
1897         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
1898             &Subtable);
1899         if (ACPI_FAILURE (Status))
1900         {
1901             return (Status);
1902         }
1903 
1904         ParentTable = DtPeekSubtable ();
1905         DtInsertSubtable (ParentTable, Subtable);
1906         DtPushSubtable (Subtable);
1907 
1908         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1909         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
1910 
1911         switch (SdevHeader->Type)
1912         {
1913         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1914 
1915             InfoTable = AcpiDmTableInfoSdev0;
1916             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
1917             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
1918                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
1919             break;
1920 
1921         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1922 
1923             InfoTable = AcpiDmTableInfoSdev1;
1924             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
1925             break;
1926 
1927         default:
1928 
1929             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1930             return (AE_ERROR);
1931         }
1932 
1933         /* Compile SDEV subtable body */
1934 
1935         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1936         if (ACPI_FAILURE (Status))
1937         {
1938             return (Status);
1939         }
1940 
1941         ParentTable = DtPeekSubtable ();
1942         DtInsertSubtable (ParentTable, Subtable);
1943 
1944         /* Optional data fields are appended to the main subtable body */
1945 
1946         switch (SdevHeader->Type)
1947         {
1948         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1949 
1950             /*
1951              * Device Id Offset will be be calculated differently depending on
1952              * the presence of secure access components.
1953              */
1954             Namesp->DeviceIdOffset = 0;
1955             ComponentLength = 0;
1956 
1957             /* If the secure access component exists, get the structures */
1958 
1959             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
1960             {
1961                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
1962                     &Subtable);
1963                 if (ACPI_FAILURE (Status))
1964                 {
1965                     return (Status);
1966                 }
1967                 ParentTable = DtPeekSubtable ();
1968                 DtInsertSubtable (ParentTable, Subtable);
1969 
1970                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
1971 
1972                 /* Compile a secure access component header */
1973 
1974                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
1975                     &Subtable);
1976                 if (ACPI_FAILURE (Status))
1977                 {
1978                     return (Status);
1979                 }
1980                 ParentTable = DtPeekSubtable ();
1981                 DtInsertSubtable (ParentTable, Subtable);
1982 
1983                 /* Compile the secure access component */
1984 
1985                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1986                 switch (SecureComponentHeader->Type)
1987                 {
1988                 case ACPI_SDEV_TYPE_ID_COMPONENT:
1989 
1990                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
1991                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
1992                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
1993                     break;
1994 
1995                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
1996 
1997                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
1998                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
1999                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
2000                     break;
2001 
2002                 default:
2003 
2004                     /* Any other secure component types are undefined */
2005 
2006                     return (AE_ERROR);
2007                 }
2008 
2009                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
2010                     &Subtable);
2011                 if (ACPI_FAILURE (Status))
2012                 {
2013                     return (Status);
2014                 }
2015                 ParentTable = DtPeekSubtable ();
2016                 DtInsertSubtable (ParentTable, Subtable);
2017 
2018                 SecureComponent->SecureComponentOffset =
2019                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
2020                 SecureComponent->SecureComponentLength = ComponentLength;
2021 
2022 
2023                 /*
2024                  * Add the secure component to the subtable to be added for the
2025                  * the namespace subtable's length
2026                  */
2027                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2028             }
2029 
2030             /* Append DeviceId namespace string */
2031 
2032             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
2033                 &Subtable);
2034             if (ACPI_FAILURE (Status))
2035             {
2036                 return (Status);
2037             }
2038 
2039             if (!Subtable)
2040             {
2041                 break;
2042             }
2043 
2044             ParentTable = DtPeekSubtable ();
2045             DtInsertSubtable (ParentTable, Subtable);
2046 
2047             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
2048 
2049             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
2050 
2051             /* Append Vendor data */
2052 
2053             Namesp->VendorDataLength = 0;
2054             Namesp->VendorDataOffset = 0;
2055 
2056             if (*PFieldList)
2057             {
2058                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2059                     &Subtable);
2060                 if (ACPI_FAILURE (Status))
2061                 {
2062                     return (Status);
2063                 }
2064 
2065                 if (Subtable)
2066                 {
2067                     ParentTable = DtPeekSubtable ();
2068                     DtInsertSubtable (ParentTable, Subtable);
2069 
2070                     Namesp->VendorDataOffset =
2071                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2072                     Namesp->VendorDataLength =
2073                         (UINT16) Subtable->Length;
2074 
2075                     /* Final size of entire namespace structure */
2076 
2077                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
2078                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
2079                 }
2080             }
2081 
2082             break;
2083 
2084         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2085 
2086             /* Append the PCIe path info first */
2087 
2088             EntryCount = 0;
2089             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
2090             {
2091                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
2092                     &Subtable);
2093                 if (ACPI_FAILURE (Status))
2094                 {
2095                     return (Status);
2096                 }
2097 
2098                 if (!Subtable)
2099                 {
2100                     DtPopSubtable ();
2101                     break;
2102                 }
2103 
2104                 ParentTable = DtPeekSubtable ();
2105                 DtInsertSubtable (ParentTable, Subtable);
2106                 EntryCount++;
2107             }
2108 
2109             /* Path offset will point immediately after the main subtable */
2110 
2111             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
2112             Pcie->PathLength = (UINT16)
2113                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
2114 
2115             /* Append the Vendor Data last */
2116 
2117             Pcie->VendorDataLength = 0;
2118             Pcie->VendorDataOffset = 0;
2119 
2120             if (*PFieldList)
2121             {
2122                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2123                     &Subtable);
2124                 if (ACPI_FAILURE (Status))
2125                 {
2126                     return (Status);
2127                 }
2128 
2129                 if (Subtable)
2130                 {
2131                     ParentTable = DtPeekSubtable ();
2132                     DtInsertSubtable (ParentTable, Subtable);
2133 
2134                     Pcie->VendorDataOffset =
2135                         Pcie->PathOffset + Pcie->PathLength;
2136                     Pcie->VendorDataLength = (UINT16)
2137                         Subtable->Length;
2138                 }
2139             }
2140 
2141             SdevHeader->Length =
2142                 sizeof (ACPI_SDEV_PCIE) +
2143                 Pcie->PathLength + Pcie->VendorDataLength;
2144             break;
2145 
2146         default:
2147 
2148             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2149             return (AE_ERROR);
2150         }
2151 
2152         DtPopSubtable ();
2153     }
2154 
2155     return (AE_OK);
2156 }
2157 
2158 
2159 /******************************************************************************
2160  *
2161  * FUNCTION:    DtCompileSlic
2162  *
2163  * PARAMETERS:  List                - Current field list pointer
2164  *
2165  * RETURN:      Status
2166  *
2167  * DESCRIPTION: Compile SLIC.
2168  *
2169  *****************************************************************************/
2170 
2171 ACPI_STATUS
2172 DtCompileSlic (
2173     void                    **List)
2174 {
2175     ACPI_STATUS             Status;
2176     DT_SUBTABLE             *Subtable;
2177     DT_SUBTABLE             *ParentTable;
2178     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2179 
2180 
2181     while (*PFieldList)
2182     {
2183         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2184             &Subtable);
2185         if (ACPI_FAILURE (Status))
2186         {
2187             return (Status);
2188         }
2189 
2190         ParentTable = DtPeekSubtable ();
2191         DtInsertSubtable (ParentTable, Subtable);
2192         DtPushSubtable (Subtable);
2193         DtPopSubtable ();
2194     }
2195 
2196     return (AE_OK);
2197 }
2198 
2199 
2200 /******************************************************************************
2201  *
2202  * FUNCTION:    DtCompileSlit
2203  *
2204  * PARAMETERS:  List                - Current field list pointer
2205  *
2206  * RETURN:      Status
2207  *
2208  * DESCRIPTION: Compile SLIT.
2209  *
2210  *****************************************************************************/
2211 
2212 ACPI_STATUS
2213 DtCompileSlit (
2214     void                    **List)
2215 {
2216     ACPI_STATUS             Status;
2217     DT_SUBTABLE             *Subtable;
2218     DT_SUBTABLE             *ParentTable;
2219     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2220     DT_FIELD                *FieldList;
2221     DT_FIELD                *EndOfFieldList = NULL;
2222     UINT32                  Localities;
2223     UINT32                  LocalityListLength;
2224     UINT8                   *LocalityBuffer;
2225 
2226 
2227     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2228         &Subtable);
2229     if (ACPI_FAILURE (Status))
2230     {
2231         return (Status);
2232     }
2233 
2234     ParentTable = DtPeekSubtable ();
2235     DtInsertSubtable (ParentTable, Subtable);
2236 
2237     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2238     LocalityBuffer = UtLocalCalloc (Localities);
2239     LocalityListLength = 0;
2240 
2241     /* Compile each locality buffer */
2242 
2243     FieldList = *PFieldList;
2244     while (FieldList)
2245     {
2246         DtCompileBuffer (LocalityBuffer,
2247             FieldList->Value, FieldList, Localities);
2248 
2249         LocalityListLength++;
2250         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2251         DtInsertSubtable (ParentTable, Subtable);
2252         EndOfFieldList = FieldList;
2253         FieldList = FieldList->Next;
2254     }
2255 
2256     if (LocalityListLength != Localities)
2257     {
2258         sprintf(AslGbl_MsgBuffer,
2259             "Found %u entries, must match LocalityCount: %u",
2260             LocalityListLength, Localities);
2261         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
2262         ACPI_FREE (LocalityBuffer);
2263         return (AE_LIMIT);
2264     }
2265 
2266     ACPI_FREE (LocalityBuffer);
2267     return (AE_OK);
2268 }
2269 
2270 
2271 /******************************************************************************
2272  *
2273  * FUNCTION:    DtCompileSrat
2274  *
2275  * PARAMETERS:  List                - Current field list pointer
2276  *
2277  * RETURN:      Status
2278  *
2279  * DESCRIPTION: Compile SRAT.
2280  *
2281  *****************************************************************************/
2282 
2283 ACPI_STATUS
2284 DtCompileSrat (
2285     void                    **List)
2286 {
2287     ACPI_STATUS             Status;
2288     DT_SUBTABLE             *Subtable;
2289     DT_SUBTABLE             *ParentTable;
2290     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2291     DT_FIELD                *SubtableStart;
2292     ACPI_SUBTABLE_HEADER    *SratHeader;
2293     ACPI_DMTABLE_INFO       *InfoTable;
2294 
2295 
2296     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2297         &Subtable);
2298     if (ACPI_FAILURE (Status))
2299     {
2300         return (Status);
2301     }
2302 
2303     ParentTable = DtPeekSubtable ();
2304     DtInsertSubtable (ParentTable, Subtable);
2305 
2306     while (*PFieldList)
2307     {
2308         SubtableStart = *PFieldList;
2309         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2310             &Subtable);
2311         if (ACPI_FAILURE (Status))
2312         {
2313             return (Status);
2314         }
2315 
2316         ParentTable = DtPeekSubtable ();
2317         DtInsertSubtable (ParentTable, Subtable);
2318         DtPushSubtable (Subtable);
2319 
2320         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2321 
2322         switch (SratHeader->Type)
2323         {
2324         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2325 
2326             InfoTable = AcpiDmTableInfoSrat0;
2327             break;
2328 
2329         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2330 
2331             InfoTable = AcpiDmTableInfoSrat1;
2332             break;
2333 
2334         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2335 
2336             InfoTable = AcpiDmTableInfoSrat2;
2337             break;
2338 
2339         case ACPI_SRAT_TYPE_GICC_AFFINITY:
2340 
2341             InfoTable = AcpiDmTableInfoSrat3;
2342             break;
2343 
2344         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
2345 
2346             InfoTable = AcpiDmTableInfoSrat4;
2347             break;
2348 
2349         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
2350 
2351             InfoTable = AcpiDmTableInfoSrat5;
2352             break;
2353 
2354         case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
2355 
2356             InfoTable = AcpiDmTableInfoSrat6;
2357             break;
2358 
2359         default:
2360 
2361             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2362             return (AE_ERROR);
2363         }
2364 
2365         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2366         if (ACPI_FAILURE (Status))
2367         {
2368             return (Status);
2369         }
2370 
2371         ParentTable = DtPeekSubtable ();
2372         DtInsertSubtable (ParentTable, Subtable);
2373         DtPopSubtable ();
2374     }
2375 
2376     return (AE_OK);
2377 }
2378 
2379 
2380 /******************************************************************************
2381  *
2382  * FUNCTION:    DtCompileStao
2383  *
2384  * PARAMETERS:  PFieldList          - Current field list pointer
2385  *
2386  * RETURN:      Status
2387  *
2388  * DESCRIPTION: Compile STAO.
2389  *
2390  *****************************************************************************/
2391 
2392 ACPI_STATUS
2393 DtCompileStao (
2394     void                    **List)
2395 {
2396     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2397     DT_SUBTABLE             *Subtable;
2398     DT_SUBTABLE             *ParentTable;
2399     ACPI_STATUS             Status;
2400 
2401 
2402     /* Compile the main table */
2403 
2404     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
2405         &Subtable);
2406     if (ACPI_FAILURE (Status))
2407     {
2408         return (Status);
2409     }
2410 
2411     ParentTable = DtPeekSubtable ();
2412     DtInsertSubtable (ParentTable, Subtable);
2413 
2414     /* Compile each ASCII namestring as a subtable */
2415 
2416     while (*PFieldList)
2417     {
2418         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
2419             &Subtable);
2420         if (ACPI_FAILURE (Status))
2421         {
2422             return (Status);
2423         }
2424 
2425         ParentTable = DtPeekSubtable ();
2426         DtInsertSubtable (ParentTable, Subtable);
2427     }
2428 
2429     return (AE_OK);
2430 }
2431 
2432 
2433 /******************************************************************************
2434  *
2435  * FUNCTION:    DtCompileSvkl
2436  *
2437  * PARAMETERS:  PFieldList          - Current field list pointer
2438  *
2439  * RETURN:      Status
2440  *
2441  * DESCRIPTION: Compile SVKL.
2442  *
2443  * NOTES: SVKL is essentially a flat table, with a small main table and
2444  *          a variable number of a single type of subtable.
2445  *
2446  *****************************************************************************/
2447 
2448 ACPI_STATUS
2449 DtCompileSvkl (
2450     void                    **List)
2451 {
2452     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2453     DT_SUBTABLE             *Subtable;
2454     DT_SUBTABLE             *ParentTable;
2455     ACPI_STATUS             Status;
2456 
2457 
2458     /* Compile the main table */
2459 
2460     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
2461         &Subtable);
2462     if (ACPI_FAILURE (Status))
2463     {
2464         return (Status);
2465     }
2466 
2467     ParentTable = DtPeekSubtable ();
2468     DtInsertSubtable (ParentTable, Subtable);
2469 
2470     /* Compile each subtable */
2471 
2472     while (*PFieldList)
2473     {
2474         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
2475             &Subtable);
2476         if (ACPI_FAILURE (Status))
2477         {
2478             return (Status);
2479         }
2480 
2481         ParentTable = DtPeekSubtable ();
2482         DtInsertSubtable (ParentTable, Subtable);
2483     }
2484 
2485     return (AE_OK);
2486 }
2487 
2488 
2489 /******************************************************************************
2490  *
2491  * FUNCTION:    DtCompileTcpa
2492  *
2493  * PARAMETERS:  PFieldList          - Current field list pointer
2494  *
2495  * RETURN:      Status
2496  *
2497  * DESCRIPTION: Compile TCPA.
2498  *
2499  *****************************************************************************/
2500 
2501 ACPI_STATUS
2502 DtCompileTcpa (
2503     void                    **List)
2504 {
2505     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2506     DT_SUBTABLE             *Subtable;
2507     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
2508     DT_SUBTABLE             *ParentTable;
2509     ACPI_STATUS             Status;
2510 
2511 
2512     /* Compile the main table */
2513 
2514     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
2515         &Subtable);
2516     if (ACPI_FAILURE (Status))
2517     {
2518         return (Status);
2519     }
2520 
2521     ParentTable = DtPeekSubtable ();
2522     DtInsertSubtable (ParentTable, Subtable);
2523 
2524     /*
2525      * Examine the PlatformClass field to determine the table type.
2526      * Either a client or server table. Only one.
2527      */
2528     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
2529 
2530     switch (TcpaHeader->PlatformClass)
2531     {
2532     case ACPI_TCPA_CLIENT_TABLE:
2533 
2534         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
2535             &Subtable);
2536         break;
2537 
2538     case ACPI_TCPA_SERVER_TABLE:
2539 
2540         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
2541             &Subtable);
2542         break;
2543 
2544     default:
2545 
2546         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
2547             TcpaHeader->PlatformClass);
2548         Status = AE_ERROR;
2549         break;
2550     }
2551 
2552     ParentTable = DtPeekSubtable ();
2553     DtInsertSubtable (ParentTable, Subtable);
2554     return (Status);
2555 }
2556 
2557 
2558 /******************************************************************************
2559  *
2560  * FUNCTION:    DtCompileTpm2Rev3
2561  *
2562  * PARAMETERS:  PFieldList          - Current field list pointer
2563  *
2564  * RETURN:      Status
2565  *
2566  * DESCRIPTION: Compile TPM2 revision 3
2567  *
2568  *****************************************************************************/
2569 static ACPI_STATUS
2570 DtCompileTpm2Rev3 (
2571     void                    **List)
2572 {
2573     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2574     DT_SUBTABLE             *Subtable;
2575     ACPI_TABLE_TPM23        *Tpm23Header;
2576     DT_SUBTABLE             *ParentTable;
2577     ACPI_STATUS             Status = AE_OK;
2578 
2579 
2580     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
2581         &Subtable);
2582 
2583     ParentTable = DtPeekSubtable ();
2584     DtInsertSubtable (ParentTable, Subtable);
2585     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
2586 
2587     /* Subtable type depends on the StartMethod */
2588 
2589     switch (Tpm23Header->StartMethod)
2590     {
2591     case ACPI_TPM23_ACPI_START_METHOD:
2592 
2593         /* Subtable specific to to ARM_SMC */
2594 
2595         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
2596             &Subtable);
2597         if (ACPI_FAILURE (Status))
2598         {
2599             return (Status);
2600         }
2601 
2602         ParentTable = DtPeekSubtable ();
2603         DtInsertSubtable (ParentTable, Subtable);
2604         break;
2605 
2606     default:
2607         break;
2608     }
2609 
2610     return (Status);
2611 }
2612 
2613 
2614 /******************************************************************************
2615  *
2616  * FUNCTION:    DtCompileTpm2
2617  *
2618  * PARAMETERS:  PFieldList          - Current field list pointer
2619  *
2620  * RETURN:      Status
2621  *
2622  * DESCRIPTION: Compile TPM2.
2623  *
2624  *****************************************************************************/
2625 
2626 ACPI_STATUS
2627 DtCompileTpm2 (
2628     void                    **List)
2629 {
2630     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2631     DT_SUBTABLE             *Subtable;
2632     ACPI_TABLE_TPM2         *Tpm2Header;
2633     DT_SUBTABLE             *ParentTable;
2634     ACPI_STATUS             Status = AE_OK;
2635     ACPI_TABLE_HEADER       *Header;
2636 
2637 
2638     ParentTable = DtPeekSubtable ();
2639 
2640     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2641 
2642     if (Header->Revision == 3)
2643     {
2644         return (DtCompileTpm2Rev3 (List));
2645     }
2646 
2647     /* Compile the main table */
2648 
2649     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
2650         &Subtable);
2651     if (ACPI_FAILURE (Status))
2652     {
2653         return (Status);
2654     }
2655 
2656     ParentTable = DtPeekSubtable ();
2657     DtInsertSubtable (ParentTable, Subtable);
2658 
2659     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
2660 
2661     /* Method parameters */
2662     /* Optional: Log area minimum length */
2663     /* Optional: Log area start address */
2664     /* TBD: Optional fields above not fully implemented (not optional at this time) */
2665 
2666     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
2667         &Subtable);
2668     if (ACPI_FAILURE (Status))
2669     {
2670         return (Status);
2671     }
2672 
2673     ParentTable = DtPeekSubtable ();
2674     DtInsertSubtable (ParentTable, Subtable);
2675 
2676 
2677     /* Subtable type depends on the StartMethod */
2678 
2679     switch (Tpm2Header->StartMethod)
2680     {
2681     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
2682 
2683         /* Subtable specific to to ARM_SMC */
2684 
2685         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
2686             &Subtable);
2687         if (ACPI_FAILURE (Status))
2688         {
2689             return (Status);
2690         }
2691 
2692         ParentTable = DtPeekSubtable ();
2693         DtInsertSubtable (ParentTable, Subtable);
2694         break;
2695 
2696     case ACPI_TPM2_START_METHOD:
2697     case ACPI_TPM2_MEMORY_MAPPED:
2698     case ACPI_TPM2_COMMAND_BUFFER:
2699     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
2700         break;
2701 
2702     case ACPI_TPM2_RESERVED1:
2703     case ACPI_TPM2_RESERVED3:
2704     case ACPI_TPM2_RESERVED4:
2705     case ACPI_TPM2_RESERVED5:
2706     case ACPI_TPM2_RESERVED9:
2707     case ACPI_TPM2_RESERVED10:
2708 
2709         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
2710             Tpm2Header->StartMethod);
2711         Status = AE_ERROR;
2712         break;
2713 
2714     case ACPI_TPM2_NOT_ALLOWED:
2715     default:
2716 
2717         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
2718             Tpm2Header->StartMethod);
2719         Status = AE_ERROR;
2720         break;
2721     }
2722 
2723     return (Status);
2724 }
2725 
2726 
2727 /******************************************************************************
2728  *
2729  * FUNCTION:    DtGetGenericTableInfo
2730  *
2731  * PARAMETERS:  Name                - Generic type name
2732  *
2733  * RETURN:      Info entry
2734  *
2735  * DESCRIPTION: Obtain table info for a generic name entry
2736  *
2737  *****************************************************************************/
2738 
2739 ACPI_DMTABLE_INFO *
2740 DtGetGenericTableInfo (
2741     char                    *Name)
2742 {
2743     ACPI_DMTABLE_INFO       *Info;
2744     UINT32                  i;
2745 
2746 
2747     if (!Name)
2748     {
2749         return (NULL);
2750     }
2751 
2752     /* Search info table for name match */
2753 
2754     for (i = 0; ; i++)
2755     {
2756         Info = AcpiDmTableInfoGeneric[i];
2757         if (Info->Opcode == ACPI_DMT_EXIT)
2758         {
2759             Info = NULL;
2760             break;
2761         }
2762 
2763         /* Use caseless compare for generic keywords */
2764 
2765         if (!AcpiUtStricmp (Name, Info->Name))
2766         {
2767             break;
2768         }
2769     }
2770 
2771     return (Info);
2772 }
2773 
2774 
2775 /******************************************************************************
2776  *
2777  * FUNCTION:    DtCompileUefi
2778  *
2779  * PARAMETERS:  List                - Current field list pointer
2780  *
2781  * RETURN:      Status
2782  *
2783  * DESCRIPTION: Compile UEFI.
2784  *
2785  *****************************************************************************/
2786 
2787 ACPI_STATUS
2788 DtCompileUefi (
2789     void                    **List)
2790 {
2791     ACPI_STATUS             Status;
2792     DT_SUBTABLE             *Subtable;
2793     DT_SUBTABLE             *ParentTable;
2794     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2795     UINT16                  *DataOffset;
2796 
2797 
2798     /* Compile the predefined portion of the UEFI table */
2799 
2800     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2801         &Subtable);
2802     if (ACPI_FAILURE (Status))
2803     {
2804         return (Status);
2805     }
2806 
2807     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2808     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2809 
2810     ParentTable = DtPeekSubtable ();
2811     DtInsertSubtable (ParentTable, Subtable);
2812 
2813     /*
2814      * Compile the "generic" portion of the UEFI table. This
2815      * part of the table is not predefined and any of the generic
2816      * operators may be used.
2817      */
2818     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
2819     return (AE_OK);
2820 }
2821 
2822 
2823 /******************************************************************************
2824  *
2825  * FUNCTION:    DtCompileViot
2826  *
2827  * PARAMETERS:  List                - Current field list pointer
2828  *
2829  * RETURN:      Status
2830  *
2831  * DESCRIPTION: Compile VIOT.
2832  *
2833  *****************************************************************************/
2834 
2835 ACPI_STATUS
2836 DtCompileViot (
2837     void                    **List)
2838 {
2839     ACPI_STATUS             Status;
2840     DT_SUBTABLE             *Subtable;
2841     DT_SUBTABLE             *ParentTable;
2842     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2843     DT_FIELD                *SubtableStart;
2844     ACPI_TABLE_VIOT         *Viot;
2845     ACPI_VIOT_HEADER        *ViotHeader;
2846     ACPI_DMTABLE_INFO       *InfoTable;
2847     UINT16                  NodeCount;
2848 
2849     ParentTable = DtPeekSubtable ();
2850 
2851     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
2852     if (ACPI_FAILURE (Status))
2853     {
2854         return (Status);
2855     }
2856     DtInsertSubtable (ParentTable, Subtable);
2857 
2858     /*
2859      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2860      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2861      */
2862     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
2863         sizeof (ACPI_TABLE_HEADER));
2864 
2865     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
2866 
2867     NodeCount = 0;
2868     while (*PFieldList) {
2869         SubtableStart = *PFieldList;
2870         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
2871             &Subtable);
2872         if (ACPI_FAILURE (Status))
2873         {
2874             return (Status);
2875         }
2876 
2877         ParentTable = DtPeekSubtable ();
2878         DtInsertSubtable (ParentTable, Subtable);
2879         DtPushSubtable (Subtable);
2880 
2881         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
2882 
2883         switch (ViotHeader->Type)
2884         {
2885         case ACPI_VIOT_NODE_PCI_RANGE:
2886 
2887             InfoTable = AcpiDmTableInfoViot1;
2888             break;
2889 
2890         case ACPI_VIOT_NODE_MMIO:
2891 
2892             InfoTable = AcpiDmTableInfoViot2;
2893             break;
2894 
2895         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
2896 
2897             InfoTable = AcpiDmTableInfoViot3;
2898             break;
2899 
2900         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
2901 
2902             InfoTable = AcpiDmTableInfoViot4;
2903             break;
2904 
2905         default:
2906 
2907             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
2908             return (AE_ERROR);
2909         }
2910 
2911         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2912         if (ACPI_FAILURE (Status))
2913         {
2914             return (Status);
2915         }
2916 
2917         ParentTable = DtPeekSubtable ();
2918         DtInsertSubtable (ParentTable, Subtable);
2919         DtPopSubtable ();
2920         NodeCount++;
2921     }
2922 
2923     Viot->NodeCount = NodeCount;
2924     return (AE_OK);
2925 }
2926 
2927 
2928 /******************************************************************************
2929  *
2930  * FUNCTION:    DtCompileWdat
2931  *
2932  * PARAMETERS:  List                - Current field list pointer
2933  *
2934  * RETURN:      Status
2935  *
2936  * DESCRIPTION: Compile WDAT.
2937  *
2938  *****************************************************************************/
2939 
2940 ACPI_STATUS
2941 DtCompileWdat (
2942     void                    **List)
2943 {
2944     ACPI_STATUS             Status;
2945 
2946 
2947     Status = DtCompileTwoSubtables (List,
2948         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2949     return (Status);
2950 }
2951 
2952 
2953 /******************************************************************************
2954  *
2955  * FUNCTION:    DtCompileWpbt
2956  *
2957  * PARAMETERS:  List                - Current field list pointer
2958  *
2959  * RETURN:      Status
2960  *
2961  * DESCRIPTION: Compile WPBT.
2962  *
2963  *****************************************************************************/
2964 
2965 ACPI_STATUS
2966 DtCompileWpbt (
2967     void                    **List)
2968 {
2969     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2970     DT_SUBTABLE             *Subtable;
2971     DT_SUBTABLE             *ParentTable;
2972     ACPI_TABLE_WPBT         *Table;
2973     ACPI_STATUS             Status;
2974 
2975 
2976     /* Compile the main table */
2977 
2978     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
2979     if (ACPI_FAILURE (Status))
2980     {
2981         return (Status);
2982     }
2983 
2984     ParentTable = DtPeekSubtable ();
2985     DtInsertSubtable (ParentTable, Subtable);
2986     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
2987 
2988     /*
2989      * Exit now if there are no arguments specified. This is indicated by:
2990      * The "Command-line Arguments" field has not been specified (if specified,
2991      * it will be the last field in the field list -- after the main table).
2992      * Set the Argument Length in the main table to zero.
2993      */
2994     if (!*PFieldList)
2995     {
2996         Table->ArgumentsLength = 0;
2997         return (AE_OK);
2998     }
2999 
3000     /* Compile the argument list subtable */
3001 
3002     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
3003     if (ACPI_FAILURE (Status))
3004     {
3005         return (Status);
3006     }
3007 
3008     /* Extract the length of the Arguments buffer, insert into main table */
3009 
3010     Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
3011     DtInsertSubtable (ParentTable, Subtable);
3012     return (AE_OK);
3013 }
3014 
3015 
3016 /******************************************************************************
3017  *
3018  * FUNCTION:    DtCompileXsdt
3019  *
3020  * PARAMETERS:  List                - Current field list pointer
3021  *
3022  * RETURN:      Status
3023  *
3024  * DESCRIPTION: Compile XSDT.
3025  *
3026  *****************************************************************************/
3027 
3028 ACPI_STATUS
3029 DtCompileXsdt (
3030     void                    **List)
3031 {
3032     DT_SUBTABLE             *Subtable;
3033     DT_SUBTABLE             *ParentTable;
3034     DT_FIELD                *FieldList = *(DT_FIELD **) List;
3035     UINT64                  Address;
3036 
3037 
3038     ParentTable = DtPeekSubtable ();
3039 
3040     while (FieldList)
3041     {
3042         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3043 
3044         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3045         DtInsertSubtable (ParentTable, Subtable);
3046         FieldList = FieldList->Next;
3047     }
3048 
3049     return (AE_OK);
3050 }
3051 
3052 
3053 /******************************************************************************
3054  *
3055  * FUNCTION:    DtCompileGeneric
3056  *
3057  * PARAMETERS:  List                - Current field list pointer
3058  *              Name                - Field name to end generic compiling
3059  *              Length              - Compiled table length to return
3060  *
3061  * RETURN:      Status
3062  *
3063  * DESCRIPTION: Compile generic unknown table.
3064  *
3065  *****************************************************************************/
3066 
3067 ACPI_STATUS
3068 DtCompileGeneric (
3069     void                    **List,
3070     char                    *Name,
3071     UINT32                  *Length)
3072 {
3073     ACPI_STATUS             Status;
3074     DT_SUBTABLE             *Subtable;
3075     DT_SUBTABLE             *ParentTable;
3076     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3077     ACPI_DMTABLE_INFO       *Info;
3078 
3079 
3080     ParentTable = DtPeekSubtable ();
3081 
3082     /*
3083      * Compile the "generic" portion of the table. This
3084      * part of the table is not predefined and any of the generic
3085      * operators may be used.
3086      */
3087 
3088     /* Find any and all labels in the entire generic portion */
3089 
3090     DtDetectAllLabels (*PFieldList);
3091 
3092     /* Now we can actually compile the parse tree */
3093 
3094     if (Length && *Length)
3095     {
3096         *Length = 0;
3097     }
3098     while (*PFieldList)
3099     {
3100         if (Name && !strcmp ((*PFieldList)->Name, Name))
3101         {
3102             break;
3103         }
3104 
3105         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3106         if (!Info)
3107         {
3108             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3109                 (*PFieldList)->Name);
3110             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3111                 (*PFieldList), AslGbl_MsgBuffer);
3112 
3113             *PFieldList = (*PFieldList)->Next;
3114             continue;
3115         }
3116 
3117         Status = DtCompileTable (PFieldList, Info,
3118             &Subtable);
3119         if (ACPI_SUCCESS (Status))
3120         {
3121             DtInsertSubtable (ParentTable, Subtable);
3122             if (Length)
3123             {
3124                 *Length += Subtable->Length;
3125             }
3126         }
3127         else
3128         {
3129             *PFieldList = (*PFieldList)->Next;
3130 
3131             if (Status == AE_NOT_FOUND)
3132             {
3133                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3134                     (*PFieldList)->Name);
3135                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3136                     (*PFieldList), AslGbl_MsgBuffer);
3137             }
3138         }
3139     }
3140 
3141     return (AE_OK);
3142 }
3143