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