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