xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/dttable2.c (revision 122b5006ee1bd67145794b4cde92f4fe4781a5ec)
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:    DtCompilePcct
679  *
680  * PARAMETERS:  List                - Current field list pointer
681  *
682  * RETURN:      Status
683  *
684  * DESCRIPTION: Compile PCCT.
685  *
686  *****************************************************************************/
687 
688 ACPI_STATUS
689 DtCompilePcct (
690     void                    **List)
691 {
692     ACPI_STATUS             Status;
693     DT_SUBTABLE             *Subtable;
694     DT_SUBTABLE             *ParentTable;
695     DT_FIELD                **PFieldList = (DT_FIELD **) List;
696     DT_FIELD                *SubtableStart;
697     ACPI_SUBTABLE_HEADER    *PcctHeader;
698     ACPI_DMTABLE_INFO       *InfoTable;
699 
700 
701     /* Main table */
702 
703     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
704         &Subtable);
705     if (ACPI_FAILURE (Status))
706     {
707         return (Status);
708     }
709 
710     ParentTable = DtPeekSubtable ();
711     DtInsertSubtable (ParentTable, Subtable);
712 
713     /* Subtables */
714 
715     while (*PFieldList)
716     {
717         SubtableStart = *PFieldList;
718         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
719             &Subtable);
720         if (ACPI_FAILURE (Status))
721         {
722             return (Status);
723         }
724 
725         ParentTable = DtPeekSubtable ();
726         DtInsertSubtable (ParentTable, Subtable);
727         DtPushSubtable (Subtable);
728 
729         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
730 
731         switch (PcctHeader->Type)
732         {
733         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
734 
735             InfoTable = AcpiDmTableInfoPcct0;
736             break;
737 
738         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
739 
740             InfoTable = AcpiDmTableInfoPcct1;
741             break;
742 
743         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
744 
745             InfoTable = AcpiDmTableInfoPcct2;
746             break;
747 
748         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
749 
750             InfoTable = AcpiDmTableInfoPcct3;
751             break;
752 
753         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
754 
755             InfoTable = AcpiDmTableInfoPcct4;
756             break;
757 
758         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
759 
760             InfoTable = AcpiDmTableInfoPcct5;
761             break;
762 
763         default:
764 
765             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
766             return (AE_ERROR);
767         }
768 
769         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
770         if (ACPI_FAILURE (Status))
771         {
772             return (Status);
773         }
774 
775         ParentTable = DtPeekSubtable ();
776         DtInsertSubtable (ParentTable, Subtable);
777         DtPopSubtable ();
778     }
779 
780     return (AE_OK);
781 }
782 
783 
784 /******************************************************************************
785  *
786  * FUNCTION:    DtCompilePdtt
787  *
788  * PARAMETERS:  List                - Current field list pointer
789  *
790  * RETURN:      Status
791  *
792  * DESCRIPTION: Compile PDTT.
793  *
794  *****************************************************************************/
795 
796 ACPI_STATUS
797 DtCompilePdtt (
798     void                    **List)
799 {
800     ACPI_STATUS             Status;
801     DT_SUBTABLE             *Subtable;
802     DT_SUBTABLE             *ParentTable;
803     DT_FIELD                **PFieldList = (DT_FIELD **) List;
804     ACPI_TABLE_PDTT         *PdttHeader;
805     UINT32                  Count = 0;
806 
807 
808     /* Main table */
809 
810     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
811     if (ACPI_FAILURE (Status))
812     {
813         return (Status);
814     }
815 
816     ParentTable = DtPeekSubtable ();
817     DtInsertSubtable (ParentTable, Subtable);
818 
819     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
820     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
821 
822     /* There is only one type of subtable at this time, no need to decode */
823 
824     while (*PFieldList)
825     {
826         /* List of subchannel IDs, each 2 bytes */
827 
828         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
829             &Subtable);
830         if (ACPI_FAILURE (Status))
831         {
832             return (Status);
833         }
834 
835         DtInsertSubtable (ParentTable, Subtable);
836         Count++;
837     }
838 
839     PdttHeader->TriggerCount = (UINT8) Count;
840     return (AE_OK);
841 }
842 
843 
844 /******************************************************************************
845  *
846  * FUNCTION:    DtCompilePhat
847  *
848  * PARAMETERS:  List                - Current field list pointer
849  *
850  * RETURN:      Status
851  *
852  * DESCRIPTION: Compile Phat.
853  *
854  *****************************************************************************/
855 
856 ACPI_STATUS
857 DtCompilePhat (
858     void                    **List)
859 {
860     ACPI_STATUS             Status = AE_OK;
861     DT_SUBTABLE             *Subtable;
862     DT_SUBTABLE             *ParentTable;
863     DT_FIELD                **PFieldList = (DT_FIELD **) List;
864     ACPI_PHAT_HEADER        *PhatHeader;
865     ACPI_DMTABLE_INFO       *Info;
866     ACPI_PHAT_VERSION_DATA  *VersionData;
867     UINT32                  RecordCount;
868 
869 
870     /* The table consist of subtables */
871 
872     while (*PFieldList)
873     {
874         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
875         if (ACPI_FAILURE (Status))
876         {
877             return (Status);
878         }
879 
880         ParentTable = DtPeekSubtable ();
881         DtInsertSubtable (ParentTable, Subtable);
882         DtPushSubtable (Subtable);
883 
884         PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
885 
886         switch (PhatHeader->Type)
887         {
888         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
889 
890             Info = AcpiDmTableInfoPhat0;
891             PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
892             break;
893 
894         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
895 
896             Info = AcpiDmTableInfoPhat1;
897             PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
898             break;
899 
900         default:
901 
902             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
903             return (AE_ERROR);
904 
905             break;
906         }
907 
908         Status = DtCompileTable (PFieldList, Info, &Subtable);
909         if (ACPI_FAILURE (Status))
910         {
911             return (Status);
912         }
913 
914         ParentTable = DtPeekSubtable ();
915         DtInsertSubtable (ParentTable, Subtable);
916 
917         switch (PhatHeader->Type)
918         {
919         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
920 
921             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
922                 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
923             RecordCount = VersionData->ElementCount;
924 
925             while (RecordCount)
926             {
927                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
928                     &Subtable);
929                 if (ACPI_FAILURE (Status))
930                 {
931                     return (Status);
932                 }
933                 ParentTable = DtPeekSubtable ();
934                 DtInsertSubtable (ParentTable, Subtable);
935 
936                 RecordCount--;
937                 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
938             }
939             break;
940 
941         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
942 
943             /* Compile device path */
944 
945             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
946             if (ACPI_FAILURE (Status))
947             {
948                 return (Status);
949             }
950             ParentTable = DtPeekSubtable ();
951             DtInsertSubtable (ParentTable, Subtable);
952 
953             PhatHeader->Length += (UINT16) Subtable->Length;
954 
955             /* Compile vendor specific data */
956 
957             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
958             if (ACPI_FAILURE (Status))
959             {
960                 return (Status);
961             }
962             ParentTable = DtPeekSubtable ();
963             DtInsertSubtable (ParentTable, Subtable);
964 
965             PhatHeader->Length += (UINT16) Subtable->Length;
966 
967             break;
968 
969         default:
970 
971             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
972             return (AE_ERROR);
973         }
974     }
975 
976     return (Status);
977 }
978 
979 
980 /******************************************************************************
981  *
982  * FUNCTION:    DtCompilePmtt
983  *
984  * PARAMETERS:  List                - Current field list pointer
985  *
986  * RETURN:      Status
987  *
988  * DESCRIPTION: Compile PMTT.
989  *
990  *****************************************************************************/
991 
992 ACPI_STATUS
993 DtCompilePmtt (
994     void                    **List)
995 {
996     ACPI_STATUS             Status;
997     DT_SUBTABLE             *Subtable;
998     DT_SUBTABLE             *ParentTable;
999     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1000     DT_FIELD                *SubtableStart;
1001     UINT16                  Type;
1002 
1003 
1004     /* Main table */
1005 
1006     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
1007     if (ACPI_FAILURE (Status))
1008     {
1009         return (Status);
1010     }
1011 
1012     ParentTable = DtPeekSubtable ();
1013     DtInsertSubtable (ParentTable, Subtable);
1014     DtPushSubtable (Subtable);
1015 
1016     /* Subtables */
1017 
1018     while (*PFieldList)
1019     {
1020         SubtableStart = *PFieldList;
1021         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1022 
1023         switch (Type)
1024         {
1025         case ACPI_PMTT_TYPE_SOCKET:
1026 
1027             /* Subtable: Socket Structure */
1028 
1029             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
1030 
1031             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1032                 &Subtable);
1033             if (ACPI_FAILURE (Status))
1034             {
1035                 return (Status);
1036             }
1037 
1038             break;
1039 
1040         case ACPI_PMTT_TYPE_CONTROLLER:
1041 
1042             /* Subtable: Memory Controller Structure */
1043 
1044             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
1045 
1046             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1047                 &Subtable);
1048             if (ACPI_FAILURE (Status))
1049             {
1050                 return (Status);
1051             }
1052 
1053             break;
1054 
1055         case ACPI_PMTT_TYPE_DIMM:
1056 
1057             /* Subtable: Physical Component (DIMM) Structure */
1058 
1059             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
1060             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1061                 &Subtable);
1062             if (ACPI_FAILURE (Status))
1063             {
1064                 return (Status);
1065             }
1066 
1067             break;
1068 
1069         case ACPI_PMTT_TYPE_VENDOR:
1070 
1071             /* Subtable: Vendor-specific Structure */
1072 
1073             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
1074             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
1075                 &Subtable);
1076             if (ACPI_FAILURE (Status))
1077             {
1078                 return (Status);
1079             }
1080 
1081             break;
1082 
1083         default:
1084 
1085             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1086             return (AE_ERROR);
1087         }
1088 
1089         DtInsertSubtable (ParentTable, Subtable);
1090     }
1091 
1092     return (Status);
1093 }
1094 
1095 
1096 /******************************************************************************
1097  *
1098  * FUNCTION:    DtCompilePptt
1099  *
1100  * PARAMETERS:  List                - Current field list pointer
1101  *
1102  * RETURN:      Status
1103  *
1104  * DESCRIPTION: Compile PPTT.
1105  *
1106  *****************************************************************************/
1107 
1108 ACPI_STATUS
1109 DtCompilePptt (
1110     void                    **List)
1111 {
1112     ACPI_STATUS             Status;
1113     ACPI_SUBTABLE_HEADER    *PpttHeader;
1114     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
1115     DT_SUBTABLE             *Subtable;
1116     DT_SUBTABLE             *ParentTable;
1117     ACPI_DMTABLE_INFO       *InfoTable;
1118     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1119     DT_FIELD                *SubtableStart;
1120     ACPI_TABLE_HEADER       *PpttAcpiHeader;
1121 
1122 
1123     ParentTable = DtPeekSubtable ();
1124     while (*PFieldList)
1125     {
1126         SubtableStart = *PFieldList;
1127 
1128         /* Compile PPTT subtable header */
1129 
1130         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1131             &Subtable);
1132         if (ACPI_FAILURE (Status))
1133         {
1134             return (Status);
1135         }
1136         DtInsertSubtable (ParentTable, Subtable);
1137         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1138         PpttHeader->Length = (UINT8)(Subtable->Length);
1139 
1140         switch (PpttHeader->Type)
1141         {
1142         case ACPI_PPTT_TYPE_PROCESSOR:
1143 
1144             InfoTable = AcpiDmTableInfoPptt0;
1145             break;
1146 
1147         case ACPI_PPTT_TYPE_CACHE:
1148 
1149             InfoTable = AcpiDmTableInfoPptt1;
1150             break;
1151 
1152         case ACPI_PPTT_TYPE_ID:
1153 
1154             InfoTable = AcpiDmTableInfoPptt2;
1155             break;
1156 
1157         default:
1158 
1159             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1160             return (AE_ERROR);
1161         }
1162 
1163         /* Compile PPTT subtable body */
1164 
1165         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1166         if (ACPI_FAILURE (Status))
1167         {
1168             return (Status);
1169         }
1170         DtInsertSubtable (ParentTable, Subtable);
1171         PpttHeader->Length += (UINT8)(Subtable->Length);
1172 
1173         /* Compile PPTT subtable additionals */
1174 
1175         switch (PpttHeader->Type)
1176         {
1177         case ACPI_PPTT_TYPE_PROCESSOR:
1178 
1179             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1180                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1181             if (PpttProcessor)
1182             {
1183                 /* Compile initiator proximity domain list */
1184 
1185                 PpttProcessor->NumberOfPrivResources = 0;
1186                 while (*PFieldList)
1187                 {
1188                     Status = DtCompileTable (PFieldList,
1189                         AcpiDmTableInfoPptt0a, &Subtable);
1190                     if (ACPI_FAILURE (Status))
1191                     {
1192                         return (Status);
1193                     }
1194                     if (!Subtable)
1195                     {
1196                         break;
1197                     }
1198 
1199                     DtInsertSubtable (ParentTable, Subtable);
1200                     PpttHeader->Length += (UINT8)(Subtable->Length);
1201                     PpttProcessor->NumberOfPrivResources++;
1202                 }
1203             }
1204             break;
1205 
1206         case ACPI_PPTT_TYPE_CACHE:
1207 
1208             PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1209                 AslGbl_RootTable->Buffer);
1210             if (PpttAcpiHeader->Revision < 3)
1211             {
1212                 break;
1213             }
1214             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
1215                 &Subtable);
1216             DtInsertSubtable (ParentTable, Subtable);
1217             PpttHeader->Length += (UINT8)(Subtable->Length);
1218             break;
1219 
1220         default:
1221 
1222             break;
1223         }
1224     }
1225 
1226     return (AE_OK);
1227 }
1228 
1229 
1230 /******************************************************************************
1231  *
1232  * FUNCTION:    DtCompilePrmt
1233  *
1234  * PARAMETERS:  List                - Current field list pointer
1235  *
1236  * RETURN:      Status
1237  *
1238  * DESCRIPTION: Compile PRMT.
1239  *
1240  *****************************************************************************/
1241 
1242 ACPI_STATUS
1243 DtCompilePrmt (
1244     void                    **List)
1245 {
1246     ACPI_STATUS             Status;
1247     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
1248     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
1249     DT_SUBTABLE             *Subtable;
1250     DT_SUBTABLE             *ParentTable;
1251     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1252     UINT32                  i, j;
1253 
1254     ParentTable = DtPeekSubtable ();
1255 
1256     /* Compile PRMT subtable header */
1257 
1258     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
1259         &Subtable);
1260     if (ACPI_FAILURE (Status))
1261     {
1262         return (Status);
1263     }
1264     DtInsertSubtable (ParentTable, Subtable);
1265     PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
1266 
1267     for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
1268     {
1269         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
1270             &Subtable);
1271         if (ACPI_FAILURE (Status))
1272         {
1273             return (Status);
1274         }
1275         DtInsertSubtable (ParentTable, Subtable);
1276         PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
1277 
1278         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
1279         {
1280             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
1281                 &Subtable);
1282             if (ACPI_FAILURE (Status))
1283             {
1284                 return (Status);
1285             }
1286             DtInsertSubtable (ParentTable, Subtable);
1287         }
1288     }
1289 
1290     return (AE_OK);
1291 }
1292 
1293 
1294 /******************************************************************************
1295  *
1296  * FUNCTION:    DtCompileRgrt
1297  *
1298  * PARAMETERS:  List                - Current field list pointer
1299  *
1300  * RETURN:      Status
1301  *
1302  * DESCRIPTION: Compile RGRT.
1303  *
1304  *****************************************************************************/
1305 
1306 ACPI_STATUS
1307 DtCompileRgrt (
1308     void                    **List)
1309 {
1310     ACPI_STATUS             Status;
1311     DT_SUBTABLE             *Subtable;
1312     DT_SUBTABLE             *ParentTable;
1313     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1314 
1315 
1316     /* Compile the main table */
1317 
1318     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
1319         &Subtable);
1320     if (ACPI_FAILURE (Status))
1321     {
1322         return (Status);
1323     }
1324 
1325     ParentTable = DtPeekSubtable ();
1326     DtInsertSubtable (ParentTable, Subtable);
1327 
1328     /* Compile the "Subtable" -- actually just the binary (PNG) image */
1329 
1330     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
1331         &Subtable);
1332     if (ACPI_FAILURE (Status))
1333     {
1334         return (Status);
1335     }
1336 
1337     DtInsertSubtable (ParentTable, Subtable);
1338     return (AE_OK);
1339 }
1340 
1341 
1342 /******************************************************************************
1343  *
1344  * FUNCTION:    DtCompileRsdt
1345  *
1346  * PARAMETERS:  List                - Current field list pointer
1347  *
1348  * RETURN:      Status
1349  *
1350  * DESCRIPTION: Compile RSDT.
1351  *
1352  *****************************************************************************/
1353 
1354 ACPI_STATUS
1355 DtCompileRsdt (
1356     void                    **List)
1357 {
1358     DT_SUBTABLE             *Subtable;
1359     DT_SUBTABLE             *ParentTable;
1360     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1361     UINT32                  Address;
1362 
1363 
1364     ParentTable = DtPeekSubtable ();
1365 
1366     while (FieldList)
1367     {
1368         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1369 
1370         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1371         DtInsertSubtable (ParentTable, Subtable);
1372         FieldList = FieldList->Next;
1373     }
1374 
1375     return (AE_OK);
1376 }
1377 
1378 
1379 /******************************************************************************
1380  *
1381  * FUNCTION:    DtCompileS3pt
1382  *
1383  * PARAMETERS:  PFieldList          - Current field list pointer
1384  *
1385  * RETURN:      Status
1386  *
1387  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1388  *
1389  *****************************************************************************/
1390 
1391 ACPI_STATUS
1392 DtCompileS3pt (
1393     DT_FIELD                **PFieldList)
1394 {
1395     ACPI_STATUS             Status;
1396     ACPI_FPDT_HEADER        *S3ptHeader;
1397     DT_SUBTABLE             *Subtable;
1398     DT_SUBTABLE             *ParentTable;
1399     ACPI_DMTABLE_INFO       *InfoTable;
1400     DT_FIELD                *SubtableStart;
1401 
1402 
1403     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1404         &AslGbl_RootTable);
1405     if (ACPI_FAILURE (Status))
1406     {
1407         return (Status);
1408     }
1409 
1410     DtPushSubtable (AslGbl_RootTable);
1411 
1412     while (*PFieldList)
1413     {
1414         SubtableStart = *PFieldList;
1415         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1416             &Subtable);
1417         if (ACPI_FAILURE (Status))
1418         {
1419             return (Status);
1420         }
1421 
1422         ParentTable = DtPeekSubtable ();
1423         DtInsertSubtable (ParentTable, Subtable);
1424         DtPushSubtable (Subtable);
1425 
1426         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1427 
1428         switch (S3ptHeader->Type)
1429         {
1430         case ACPI_S3PT_TYPE_RESUME:
1431 
1432             InfoTable = AcpiDmTableInfoS3pt0;
1433             break;
1434 
1435         case ACPI_S3PT_TYPE_SUSPEND:
1436 
1437             InfoTable = AcpiDmTableInfoS3pt1;
1438             break;
1439 
1440         default:
1441 
1442             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1443             return (AE_ERROR);
1444         }
1445 
1446         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1447         if (ACPI_FAILURE (Status))
1448         {
1449             return (Status);
1450         }
1451 
1452         ParentTable = DtPeekSubtable ();
1453         DtInsertSubtable (ParentTable, Subtable);
1454         DtPopSubtable ();
1455     }
1456 
1457     return (AE_OK);
1458 }
1459 
1460 
1461 /******************************************************************************
1462  *
1463  * FUNCTION:    DtCompileSdev
1464  *
1465  * PARAMETERS:  List                - Current field list pointer
1466  *
1467  * RETURN:      Status
1468  *
1469  * DESCRIPTION: Compile SDEV.
1470  *
1471  *****************************************************************************/
1472 
1473 ACPI_STATUS
1474 DtCompileSdev (
1475     void                    **List)
1476 {
1477     ACPI_STATUS                 Status;
1478     ACPI_SDEV_HEADER            *SdevHeader;
1479     ACPI_SDEV_HEADER            *SecureComponentHeader;
1480     DT_SUBTABLE                 *Subtable;
1481     DT_SUBTABLE                 *ParentTable;
1482     ACPI_DMTABLE_INFO           *InfoTable;
1483     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
1484     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
1485     DT_FIELD                    *SubtableStart;
1486     ACPI_SDEV_PCIE              *Pcie = NULL;
1487     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
1488     UINT32                      EntryCount;
1489     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
1490     UINT16                      ComponentLength = 0;
1491 
1492 
1493     /* Subtables */
1494 
1495     while (*PFieldList)
1496     {
1497         /* Compile common SDEV subtable header */
1498 
1499         SubtableStart = *PFieldList;
1500         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
1501             &Subtable);
1502         if (ACPI_FAILURE (Status))
1503         {
1504             return (Status);
1505         }
1506 
1507         ParentTable = DtPeekSubtable ();
1508         DtInsertSubtable (ParentTable, Subtable);
1509         DtPushSubtable (Subtable);
1510 
1511         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1512         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
1513 
1514         switch (SdevHeader->Type)
1515         {
1516         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1517 
1518             InfoTable = AcpiDmTableInfoSdev0;
1519             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
1520             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
1521                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
1522             break;
1523 
1524         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1525 
1526             InfoTable = AcpiDmTableInfoSdev1;
1527             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
1528             break;
1529 
1530         default:
1531 
1532             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1533             return (AE_ERROR);
1534         }
1535 
1536         /* Compile SDEV subtable body */
1537 
1538         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1539         if (ACPI_FAILURE (Status))
1540         {
1541             return (Status);
1542         }
1543 
1544         ParentTable = DtPeekSubtable ();
1545         DtInsertSubtable (ParentTable, Subtable);
1546 
1547         /* Optional data fields are appended to the main subtable body */
1548 
1549         switch (SdevHeader->Type)
1550         {
1551         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1552 
1553             /*
1554              * Device Id Offset will be be calculated differently depending on
1555              * the presence of secure access components.
1556              */
1557             Namesp->DeviceIdOffset = 0;
1558             ComponentLength = 0;
1559 
1560             /* If the secure access component exists, get the structures */
1561 
1562             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
1563             {
1564                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
1565                     &Subtable);
1566                 if (ACPI_FAILURE (Status))
1567                 {
1568                     return (Status);
1569                 }
1570                 ParentTable = DtPeekSubtable ();
1571                 DtInsertSubtable (ParentTable, Subtable);
1572 
1573                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
1574 
1575                 /* Compile a secure access component header */
1576 
1577                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
1578                     &Subtable);
1579                 if (ACPI_FAILURE (Status))
1580                 {
1581                     return (Status);
1582                 }
1583                 ParentTable = DtPeekSubtable ();
1584                 DtInsertSubtable (ParentTable, Subtable);
1585 
1586                 /* Compile the secure access component */
1587 
1588                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1589                 switch (SecureComponentHeader->Type)
1590                 {
1591                 case ACPI_SDEV_TYPE_ID_COMPONENT:
1592 
1593                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
1594                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
1595                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
1596                     break;
1597 
1598                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
1599 
1600                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
1601                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
1602                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
1603                     break;
1604 
1605                 default:
1606 
1607                     /* Any other secure component types are undefined */
1608 
1609                     return (AE_ERROR);
1610                 }
1611 
1612                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
1613                     &Subtable);
1614                 if (ACPI_FAILURE (Status))
1615                 {
1616                     return (Status);
1617                 }
1618                 ParentTable = DtPeekSubtable ();
1619                 DtInsertSubtable (ParentTable, Subtable);
1620 
1621                 SecureComponent->SecureComponentOffset =
1622                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
1623                 SecureComponent->SecureComponentLength = ComponentLength;
1624 
1625 
1626                 /*
1627                  * Add the secure component to the subtable to be added for the
1628                  * the namespace subtable's length
1629                  */
1630                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
1631             }
1632 
1633             /* Append DeviceId namespace string */
1634 
1635             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
1636                 &Subtable);
1637             if (ACPI_FAILURE (Status))
1638             {
1639                 return (Status);
1640             }
1641 
1642             if (!Subtable)
1643             {
1644                 break;
1645             }
1646 
1647             ParentTable = DtPeekSubtable ();
1648             DtInsertSubtable (ParentTable, Subtable);
1649 
1650             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
1651 
1652             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
1653 
1654             /* Append Vendor data */
1655 
1656             Namesp->VendorDataLength = 0;
1657             Namesp->VendorDataOffset = 0;
1658 
1659             if (*PFieldList)
1660             {
1661                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1662                     &Subtable);
1663                 if (ACPI_FAILURE (Status))
1664                 {
1665                     return (Status);
1666                 }
1667 
1668                 if (Subtable)
1669                 {
1670                     ParentTable = DtPeekSubtable ();
1671                     DtInsertSubtable (ParentTable, Subtable);
1672 
1673                     Namesp->VendorDataOffset =
1674                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
1675                     Namesp->VendorDataLength =
1676                         (UINT16) Subtable->Length;
1677 
1678                     /* Final size of entire namespace structure */
1679 
1680                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
1681                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
1682                 }
1683             }
1684 
1685             break;
1686 
1687         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1688 
1689             /* Append the PCIe path info first */
1690 
1691             EntryCount = 0;
1692             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
1693             {
1694                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
1695                     &Subtable);
1696                 if (ACPI_FAILURE (Status))
1697                 {
1698                     return (Status);
1699                 }
1700 
1701                 if (!Subtable)
1702                 {
1703                     DtPopSubtable ();
1704                     break;
1705                 }
1706 
1707                 ParentTable = DtPeekSubtable ();
1708                 DtInsertSubtable (ParentTable, Subtable);
1709                 EntryCount++;
1710             }
1711 
1712             /* Path offset will point immediately after the main subtable */
1713 
1714             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
1715             Pcie->PathLength = (UINT16)
1716                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
1717 
1718             /* Append the Vendor Data last */
1719 
1720             Pcie->VendorDataLength = 0;
1721             Pcie->VendorDataOffset = 0;
1722 
1723             if (*PFieldList)
1724             {
1725                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1726                     &Subtable);
1727                 if (ACPI_FAILURE (Status))
1728                 {
1729                     return (Status);
1730                 }
1731 
1732                 if (Subtable)
1733                 {
1734                     ParentTable = DtPeekSubtable ();
1735                     DtInsertSubtable (ParentTable, Subtable);
1736 
1737                     Pcie->VendorDataOffset =
1738                         Pcie->PathOffset + Pcie->PathLength;
1739                     Pcie->VendorDataLength = (UINT16)
1740                         Subtable->Length;
1741                 }
1742             }
1743 
1744             SdevHeader->Length =
1745                 sizeof (ACPI_SDEV_PCIE) +
1746                 Pcie->PathLength + Pcie->VendorDataLength;
1747             break;
1748 
1749         default:
1750 
1751             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1752             return (AE_ERROR);
1753         }
1754 
1755         DtPopSubtable ();
1756     }
1757 
1758     return (AE_OK);
1759 }
1760 
1761 
1762 /******************************************************************************
1763  *
1764  * FUNCTION:    DtCompileSlic
1765  *
1766  * PARAMETERS:  List                - Current field list pointer
1767  *
1768  * RETURN:      Status
1769  *
1770  * DESCRIPTION: Compile SLIC.
1771  *
1772  *****************************************************************************/
1773 
1774 ACPI_STATUS
1775 DtCompileSlic (
1776     void                    **List)
1777 {
1778     ACPI_STATUS             Status;
1779     DT_SUBTABLE             *Subtable;
1780     DT_SUBTABLE             *ParentTable;
1781     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1782 
1783 
1784     while (*PFieldList)
1785     {
1786         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
1787             &Subtable);
1788         if (ACPI_FAILURE (Status))
1789         {
1790             return (Status);
1791         }
1792 
1793         ParentTable = DtPeekSubtable ();
1794         DtInsertSubtable (ParentTable, Subtable);
1795         DtPushSubtable (Subtable);
1796         DtPopSubtable ();
1797     }
1798 
1799     return (AE_OK);
1800 }
1801 
1802 
1803 /******************************************************************************
1804  *
1805  * FUNCTION:    DtCompileSlit
1806  *
1807  * PARAMETERS:  List                - Current field list pointer
1808  *
1809  * RETURN:      Status
1810  *
1811  * DESCRIPTION: Compile SLIT.
1812  *
1813  *****************************************************************************/
1814 
1815 ACPI_STATUS
1816 DtCompileSlit (
1817     void                    **List)
1818 {
1819     ACPI_STATUS             Status;
1820     DT_SUBTABLE             *Subtable;
1821     DT_SUBTABLE             *ParentTable;
1822     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1823     DT_FIELD                *FieldList;
1824     DT_FIELD                *EndOfFieldList = NULL;
1825     UINT32                  Localities;
1826     UINT32                  LocalityListLength;
1827     UINT8                   *LocalityBuffer;
1828 
1829 
1830     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1831         &Subtable);
1832     if (ACPI_FAILURE (Status))
1833     {
1834         return (Status);
1835     }
1836 
1837     ParentTable = DtPeekSubtable ();
1838     DtInsertSubtable (ParentTable, Subtable);
1839 
1840     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1841     LocalityBuffer = UtLocalCalloc (Localities);
1842     LocalityListLength = 0;
1843 
1844     /* Compile each locality buffer */
1845 
1846     FieldList = *PFieldList;
1847     while (FieldList)
1848     {
1849         DtCompileBuffer (LocalityBuffer,
1850             FieldList->Value, FieldList, Localities);
1851 
1852         LocalityListLength++;
1853         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1854         DtInsertSubtable (ParentTable, Subtable);
1855         EndOfFieldList = FieldList;
1856         FieldList = FieldList->Next;
1857     }
1858 
1859     if (LocalityListLength != Localities)
1860     {
1861         sprintf(AslGbl_MsgBuffer,
1862             "Found %u entries, must match LocalityCount: %u",
1863             LocalityListLength, Localities);
1864         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
1865         ACPI_FREE (LocalityBuffer);
1866         return (AE_LIMIT);
1867     }
1868 
1869     ACPI_FREE (LocalityBuffer);
1870     return (AE_OK);
1871 }
1872 
1873 
1874 /******************************************************************************
1875  *
1876  * FUNCTION:    DtCompileSrat
1877  *
1878  * PARAMETERS:  List                - Current field list pointer
1879  *
1880  * RETURN:      Status
1881  *
1882  * DESCRIPTION: Compile SRAT.
1883  *
1884  *****************************************************************************/
1885 
1886 ACPI_STATUS
1887 DtCompileSrat (
1888     void                    **List)
1889 {
1890     ACPI_STATUS             Status;
1891     DT_SUBTABLE             *Subtable;
1892     DT_SUBTABLE             *ParentTable;
1893     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1894     DT_FIELD                *SubtableStart;
1895     ACPI_SUBTABLE_HEADER    *SratHeader;
1896     ACPI_DMTABLE_INFO       *InfoTable;
1897 
1898 
1899     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1900         &Subtable);
1901     if (ACPI_FAILURE (Status))
1902     {
1903         return (Status);
1904     }
1905 
1906     ParentTable = DtPeekSubtable ();
1907     DtInsertSubtable (ParentTable, Subtable);
1908 
1909     while (*PFieldList)
1910     {
1911         SubtableStart = *PFieldList;
1912         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1913             &Subtable);
1914         if (ACPI_FAILURE (Status))
1915         {
1916             return (Status);
1917         }
1918 
1919         ParentTable = DtPeekSubtable ();
1920         DtInsertSubtable (ParentTable, Subtable);
1921         DtPushSubtable (Subtable);
1922 
1923         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1924 
1925         switch (SratHeader->Type)
1926         {
1927         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1928 
1929             InfoTable = AcpiDmTableInfoSrat0;
1930             break;
1931 
1932         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1933 
1934             InfoTable = AcpiDmTableInfoSrat1;
1935             break;
1936 
1937         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1938 
1939             InfoTable = AcpiDmTableInfoSrat2;
1940             break;
1941 
1942         case ACPI_SRAT_TYPE_GICC_AFFINITY:
1943 
1944             InfoTable = AcpiDmTableInfoSrat3;
1945             break;
1946 
1947         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
1948 
1949             InfoTable = AcpiDmTableInfoSrat4;
1950             break;
1951 
1952         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
1953 
1954             InfoTable = AcpiDmTableInfoSrat5;
1955             break;
1956 
1957         case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
1958 
1959             InfoTable = AcpiDmTableInfoSrat6;
1960             break;
1961 
1962         default:
1963 
1964             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1965             return (AE_ERROR);
1966         }
1967 
1968         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1969         if (ACPI_FAILURE (Status))
1970         {
1971             return (Status);
1972         }
1973 
1974         ParentTable = DtPeekSubtable ();
1975         DtInsertSubtable (ParentTable, Subtable);
1976         DtPopSubtable ();
1977     }
1978 
1979     return (AE_OK);
1980 }
1981 
1982 
1983 /******************************************************************************
1984  *
1985  * FUNCTION:    DtCompileStao
1986  *
1987  * PARAMETERS:  PFieldList          - Current field list pointer
1988  *
1989  * RETURN:      Status
1990  *
1991  * DESCRIPTION: Compile STAO.
1992  *
1993  *****************************************************************************/
1994 
1995 ACPI_STATUS
1996 DtCompileStao (
1997     void                    **List)
1998 {
1999     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2000     DT_SUBTABLE             *Subtable;
2001     DT_SUBTABLE             *ParentTable;
2002     ACPI_STATUS             Status;
2003 
2004 
2005     /* Compile the main table */
2006 
2007     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
2008         &Subtable);
2009     if (ACPI_FAILURE (Status))
2010     {
2011         return (Status);
2012     }
2013 
2014     ParentTable = DtPeekSubtable ();
2015     DtInsertSubtable (ParentTable, Subtable);
2016 
2017     /* Compile each ASCII namestring as a subtable */
2018 
2019     while (*PFieldList)
2020     {
2021         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
2022             &Subtable);
2023         if (ACPI_FAILURE (Status))
2024         {
2025             return (Status);
2026         }
2027 
2028         ParentTable = DtPeekSubtable ();
2029         DtInsertSubtable (ParentTable, Subtable);
2030     }
2031 
2032     return (AE_OK);
2033 }
2034 
2035 
2036 
2037 /******************************************************************************
2038  *
2039  * FUNCTION:    DtCompileSvkl
2040  *
2041  * PARAMETERS:  PFieldList          - Current field list pointer
2042  *
2043  * RETURN:      Status
2044  *
2045  * DESCRIPTION: Compile SVKL.
2046  *
2047  * NOTES: SVKL is essentially a flat table, with a small main table and
2048  *          a variable number of a single type of subtable.
2049  *
2050  *****************************************************************************/
2051 
2052 ACPI_STATUS
2053 DtCompileSvkl (
2054     void                    **List)
2055 {
2056     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2057     DT_SUBTABLE             *Subtable;
2058     DT_SUBTABLE             *ParentTable;
2059     ACPI_STATUS             Status;
2060 
2061 
2062     /* Compile the main table */
2063 
2064     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
2065         &Subtable);
2066     if (ACPI_FAILURE (Status))
2067     {
2068         return (Status);
2069     }
2070 
2071     ParentTable = DtPeekSubtable ();
2072     DtInsertSubtable (ParentTable, Subtable);
2073 
2074     /* Compile each subtable */
2075 
2076     while (*PFieldList)
2077     {
2078         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
2079             &Subtable);
2080         if (ACPI_FAILURE (Status))
2081         {
2082             return (Status);
2083         }
2084 
2085         ParentTable = DtPeekSubtable ();
2086         DtInsertSubtable (ParentTable, Subtable);
2087     }
2088 
2089     return (AE_OK);
2090 }
2091 
2092 
2093 /******************************************************************************
2094  *
2095  * FUNCTION:    DtCompileTcpa
2096  *
2097  * PARAMETERS:  PFieldList          - Current field list pointer
2098  *
2099  * RETURN:      Status
2100  *
2101  * DESCRIPTION: Compile TCPA.
2102  *
2103  *****************************************************************************/
2104 
2105 ACPI_STATUS
2106 DtCompileTcpa (
2107     void                    **List)
2108 {
2109     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2110     DT_SUBTABLE             *Subtable;
2111     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
2112     DT_SUBTABLE             *ParentTable;
2113     ACPI_STATUS             Status;
2114 
2115 
2116     /* Compile the main table */
2117 
2118     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
2119         &Subtable);
2120     if (ACPI_FAILURE (Status))
2121     {
2122         return (Status);
2123     }
2124 
2125     ParentTable = DtPeekSubtable ();
2126     DtInsertSubtable (ParentTable, Subtable);
2127 
2128     /*
2129      * Examine the PlatformClass field to determine the table type.
2130      * Either a client or server table. Only one.
2131      */
2132     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
2133 
2134     switch (TcpaHeader->PlatformClass)
2135     {
2136     case ACPI_TCPA_CLIENT_TABLE:
2137 
2138         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
2139             &Subtable);
2140         break;
2141 
2142     case ACPI_TCPA_SERVER_TABLE:
2143 
2144         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
2145             &Subtable);
2146         break;
2147 
2148     default:
2149 
2150         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
2151             TcpaHeader->PlatformClass);
2152         Status = AE_ERROR;
2153         break;
2154     }
2155 
2156     ParentTable = DtPeekSubtable ();
2157     DtInsertSubtable (ParentTable, Subtable);
2158     return (Status);
2159 }
2160 
2161 
2162 /******************************************************************************
2163  *
2164  * FUNCTION:    DtCompileTpm2Rev3
2165  *
2166  * PARAMETERS:  PFieldList          - Current field list pointer
2167  *
2168  * RETURN:      Status
2169  *
2170  * DESCRIPTION: Compile TPM2 revision 3
2171  *
2172  *****************************************************************************/
2173 static ACPI_STATUS
2174 DtCompileTpm2Rev3 (
2175     void                    **List)
2176 {
2177     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2178     DT_SUBTABLE             *Subtable;
2179     ACPI_TABLE_TPM23        *Tpm23Header;
2180     DT_SUBTABLE             *ParentTable;
2181     ACPI_STATUS             Status = AE_OK;
2182 
2183 
2184     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
2185         &Subtable);
2186 
2187     ParentTable = DtPeekSubtable ();
2188     DtInsertSubtable (ParentTable, Subtable);
2189     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
2190 
2191     /* Subtable type depends on the StartMethod */
2192 
2193     switch (Tpm23Header->StartMethod)
2194     {
2195     case ACPI_TPM23_ACPI_START_METHOD:
2196 
2197         /* Subtable specific to to ARM_SMC */
2198 
2199         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
2200             &Subtable);
2201         if (ACPI_FAILURE (Status))
2202         {
2203             return (Status);
2204         }
2205 
2206         ParentTable = DtPeekSubtable ();
2207         DtInsertSubtable (ParentTable, Subtable);
2208         break;
2209 
2210     default:
2211         break;
2212     }
2213 
2214     return (Status);
2215 }
2216 
2217 
2218 /******************************************************************************
2219  *
2220  * FUNCTION:    DtCompileTpm2
2221  *
2222  * PARAMETERS:  PFieldList          - Current field list pointer
2223  *
2224  * RETURN:      Status
2225  *
2226  * DESCRIPTION: Compile TPM2.
2227  *
2228  *****************************************************************************/
2229 
2230 ACPI_STATUS
2231 DtCompileTpm2 (
2232     void                    **List)
2233 {
2234     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2235     DT_SUBTABLE             *Subtable;
2236     ACPI_TABLE_TPM2         *Tpm2Header;
2237     DT_SUBTABLE             *ParentTable;
2238     ACPI_STATUS             Status = AE_OK;
2239     ACPI_TABLE_HEADER       *Header;
2240 
2241 
2242     ParentTable = DtPeekSubtable ();
2243 
2244     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2245 
2246     if (Header->Revision == 3)
2247     {
2248         return (DtCompileTpm2Rev3 (List));
2249     }
2250 
2251     /* Compile the main table */
2252 
2253     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
2254         &Subtable);
2255     if (ACPI_FAILURE (Status))
2256     {
2257         return (Status);
2258     }
2259 
2260     ParentTable = DtPeekSubtable ();
2261     DtInsertSubtable (ParentTable, Subtable);
2262 
2263     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
2264 
2265     /* Method parameters */
2266     /* Optional: Log area minimum length */
2267     /* Optional: Log area start address */
2268     /* TBD: Optional fields above not fully implemented (not optional at this time) */
2269 
2270     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
2271         &Subtable);
2272     if (ACPI_FAILURE (Status))
2273     {
2274         return (Status);
2275     }
2276 
2277     ParentTable = DtPeekSubtable ();
2278     DtInsertSubtable (ParentTable, Subtable);
2279 
2280 
2281     /* Subtable type depends on the StartMethod */
2282 
2283     switch (Tpm2Header->StartMethod)
2284     {
2285     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
2286 
2287         /* Subtable specific to to ARM_SMC */
2288 
2289         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
2290             &Subtable);
2291         if (ACPI_FAILURE (Status))
2292         {
2293             return (Status);
2294         }
2295 
2296         ParentTable = DtPeekSubtable ();
2297         DtInsertSubtable (ParentTable, Subtable);
2298         break;
2299 
2300     case ACPI_TPM2_START_METHOD:
2301     case ACPI_TPM2_MEMORY_MAPPED:
2302     case ACPI_TPM2_COMMAND_BUFFER:
2303     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
2304         break;
2305 
2306     case ACPI_TPM2_RESERVED1:
2307     case ACPI_TPM2_RESERVED3:
2308     case ACPI_TPM2_RESERVED4:
2309     case ACPI_TPM2_RESERVED5:
2310     case ACPI_TPM2_RESERVED9:
2311     case ACPI_TPM2_RESERVED10:
2312 
2313         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
2314             Tpm2Header->StartMethod);
2315         Status = AE_ERROR;
2316         break;
2317 
2318     case ACPI_TPM2_NOT_ALLOWED:
2319     default:
2320 
2321         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
2322             Tpm2Header->StartMethod);
2323         Status = AE_ERROR;
2324         break;
2325     }
2326 
2327     return (Status);
2328 }
2329 
2330 
2331 /******************************************************************************
2332  *
2333  * FUNCTION:    DtGetGenericTableInfo
2334  *
2335  * PARAMETERS:  Name                - Generic type name
2336  *
2337  * RETURN:      Info entry
2338  *
2339  * DESCRIPTION: Obtain table info for a generic name entry
2340  *
2341  *****************************************************************************/
2342 
2343 ACPI_DMTABLE_INFO *
2344 DtGetGenericTableInfo (
2345     char                    *Name)
2346 {
2347     ACPI_DMTABLE_INFO       *Info;
2348     UINT32                  i;
2349 
2350 
2351     if (!Name)
2352     {
2353         return (NULL);
2354     }
2355 
2356     /* Search info table for name match */
2357 
2358     for (i = 0; ; i++)
2359     {
2360         Info = AcpiDmTableInfoGeneric[i];
2361         if (Info->Opcode == ACPI_DMT_EXIT)
2362         {
2363             Info = NULL;
2364             break;
2365         }
2366 
2367         /* Use caseless compare for generic keywords */
2368 
2369         if (!AcpiUtStricmp (Name, Info->Name))
2370         {
2371             break;
2372         }
2373     }
2374 
2375     return (Info);
2376 }
2377 
2378 
2379 /******************************************************************************
2380  *
2381  * FUNCTION:    DtCompileUefi
2382  *
2383  * PARAMETERS:  List                - Current field list pointer
2384  *
2385  * RETURN:      Status
2386  *
2387  * DESCRIPTION: Compile UEFI.
2388  *
2389  *****************************************************************************/
2390 
2391 ACPI_STATUS
2392 DtCompileUefi (
2393     void                    **List)
2394 {
2395     ACPI_STATUS             Status;
2396     DT_SUBTABLE             *Subtable;
2397     DT_SUBTABLE             *ParentTable;
2398     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2399     UINT16                  *DataOffset;
2400 
2401 
2402     /* Compile the predefined portion of the UEFI table */
2403 
2404     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2405         &Subtable);
2406     if (ACPI_FAILURE (Status))
2407     {
2408         return (Status);
2409     }
2410 
2411     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2412     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2413 
2414     ParentTable = DtPeekSubtable ();
2415     DtInsertSubtable (ParentTable, Subtable);
2416 
2417     /*
2418      * Compile the "generic" portion of the UEFI table. This
2419      * part of the table is not predefined and any of the generic
2420      * operators may be used.
2421      */
2422     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
2423     return (AE_OK);
2424 }
2425 
2426 
2427 /******************************************************************************
2428  *
2429  * FUNCTION:    DtCompileViot
2430  *
2431  * PARAMETERS:  List                - Current field list pointer
2432  *
2433  * RETURN:      Status
2434  *
2435  * DESCRIPTION: Compile VIOT.
2436  *
2437  *****************************************************************************/
2438 
2439 ACPI_STATUS
2440 DtCompileViot (
2441     void                    **List)
2442 {
2443     ACPI_STATUS             Status;
2444     DT_SUBTABLE             *Subtable;
2445     DT_SUBTABLE             *ParentTable;
2446     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2447     DT_FIELD                *SubtableStart;
2448     ACPI_TABLE_VIOT         *Viot;
2449     ACPI_VIOT_HEADER        *ViotHeader;
2450     ACPI_DMTABLE_INFO       *InfoTable;
2451     UINT16                  NodeCount;
2452 
2453     ParentTable = DtPeekSubtable ();
2454 
2455     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
2456     if (ACPI_FAILURE (Status))
2457     {
2458         return (Status);
2459     }
2460     DtInsertSubtable (ParentTable, Subtable);
2461 
2462     /*
2463      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2464      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2465      */
2466     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
2467         sizeof (ACPI_TABLE_HEADER));
2468 
2469     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
2470 
2471     NodeCount = 0;
2472     while (*PFieldList) {
2473         SubtableStart = *PFieldList;
2474         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
2475             &Subtable);
2476         if (ACPI_FAILURE (Status))
2477         {
2478             return (Status);
2479         }
2480 
2481         ParentTable = DtPeekSubtable ();
2482         DtInsertSubtable (ParentTable, Subtable);
2483         DtPushSubtable (Subtable);
2484 
2485         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
2486 
2487         switch (ViotHeader->Type)
2488         {
2489         case ACPI_VIOT_NODE_PCI_RANGE:
2490 
2491             InfoTable = AcpiDmTableInfoViot1;
2492             break;
2493 
2494         case ACPI_VIOT_NODE_MMIO:
2495 
2496             InfoTable = AcpiDmTableInfoViot2;
2497             break;
2498 
2499         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
2500 
2501             InfoTable = AcpiDmTableInfoViot3;
2502             break;
2503 
2504         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
2505 
2506             InfoTable = AcpiDmTableInfoViot4;
2507             break;
2508 
2509         default:
2510 
2511             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
2512             return (AE_ERROR);
2513         }
2514 
2515         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2516         if (ACPI_FAILURE (Status))
2517         {
2518             return (Status);
2519         }
2520 
2521         ParentTable = DtPeekSubtable ();
2522         DtInsertSubtable (ParentTable, Subtable);
2523         DtPopSubtable ();
2524         NodeCount++;
2525     }
2526 
2527     Viot->NodeCount = NodeCount;
2528     return (AE_OK);
2529 }
2530 
2531 
2532 /******************************************************************************
2533  *
2534  * FUNCTION:    DtCompileWdat
2535  *
2536  * PARAMETERS:  List                - Current field list pointer
2537  *
2538  * RETURN:      Status
2539  *
2540  * DESCRIPTION: Compile WDAT.
2541  *
2542  *****************************************************************************/
2543 
2544 ACPI_STATUS
2545 DtCompileWdat (
2546     void                    **List)
2547 {
2548     ACPI_STATUS             Status;
2549 
2550 
2551     Status = DtCompileTwoSubtables (List,
2552         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2553     return (Status);
2554 }
2555 
2556 
2557 /******************************************************************************
2558  *
2559  * FUNCTION:    DtCompileWpbt
2560  *
2561  * PARAMETERS:  List                - Current field list pointer
2562  *
2563  * RETURN:      Status
2564  *
2565  * DESCRIPTION: Compile WPBT.
2566  *
2567  *****************************************************************************/
2568 
2569 ACPI_STATUS
2570 DtCompileWpbt (
2571     void                    **List)
2572 {
2573     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2574     DT_SUBTABLE             *Subtable;
2575     DT_SUBTABLE             *ParentTable;
2576     ACPI_TABLE_WPBT         *Table;
2577     ACPI_STATUS             Status;
2578 
2579 
2580     /* Compile the main table */
2581 
2582     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
2583     if (ACPI_FAILURE (Status))
2584     {
2585         return (Status);
2586     }
2587 
2588     ParentTable = DtPeekSubtable ();
2589     DtInsertSubtable (ParentTable, Subtable);
2590     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
2591 
2592     /*
2593      * Exit now if there are no arguments specified. This is indicated by:
2594      * The "Command-line Arguments" field has not been specified (if specified,
2595      * it will be the last field in the field list -- after the main table).
2596      * Set the Argument Length in the main table to zero.
2597      */
2598     if (!*PFieldList)
2599     {
2600         Table->ArgumentsLength = 0;
2601         return (AE_OK);
2602     }
2603 
2604     /* Compile the argument list subtable */
2605 
2606     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
2607     if (ACPI_FAILURE (Status))
2608     {
2609         return (Status);
2610     }
2611 
2612     /* Extract the length of the Arguments buffer, insert into main table */
2613 
2614     Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
2615     DtInsertSubtable (ParentTable, Subtable);
2616     return (AE_OK);
2617 }
2618 
2619 
2620 /******************************************************************************
2621  *
2622  * FUNCTION:    DtCompileXsdt
2623  *
2624  * PARAMETERS:  List                - Current field list pointer
2625  *
2626  * RETURN:      Status
2627  *
2628  * DESCRIPTION: Compile XSDT.
2629  *
2630  *****************************************************************************/
2631 
2632 ACPI_STATUS
2633 DtCompileXsdt (
2634     void                    **List)
2635 {
2636     DT_SUBTABLE             *Subtable;
2637     DT_SUBTABLE             *ParentTable;
2638     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2639     UINT64                  Address;
2640 
2641 
2642     ParentTable = DtPeekSubtable ();
2643 
2644     while (FieldList)
2645     {
2646         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2647 
2648         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2649         DtInsertSubtable (ParentTable, Subtable);
2650         FieldList = FieldList->Next;
2651     }
2652 
2653     return (AE_OK);
2654 }
2655 
2656 
2657 /******************************************************************************
2658  *
2659  * FUNCTION:    DtCompileGeneric
2660  *
2661  * PARAMETERS:  List                - Current field list pointer
2662  *              Name                - Field name to end generic compiling
2663  *              Length              - Compiled table length to return
2664  *
2665  * RETURN:      Status
2666  *
2667  * DESCRIPTION: Compile generic unknown table.
2668  *
2669  *****************************************************************************/
2670 
2671 ACPI_STATUS
2672 DtCompileGeneric (
2673     void                    **List,
2674     char                    *Name,
2675     UINT32                  *Length)
2676 {
2677     ACPI_STATUS             Status;
2678     DT_SUBTABLE             *Subtable;
2679     DT_SUBTABLE             *ParentTable;
2680     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2681     ACPI_DMTABLE_INFO       *Info;
2682 
2683 
2684     ParentTable = DtPeekSubtable ();
2685 
2686     /*
2687      * Compile the "generic" portion of the table. This
2688      * part of the table is not predefined and any of the generic
2689      * operators may be used.
2690      */
2691 
2692     /* Find any and all labels in the entire generic portion */
2693 
2694     DtDetectAllLabels (*PFieldList);
2695 
2696     /* Now we can actually compile the parse tree */
2697 
2698     if (Length && *Length)
2699     {
2700         *Length = 0;
2701     }
2702     while (*PFieldList)
2703     {
2704         if (Name && !strcmp ((*PFieldList)->Name, Name))
2705         {
2706             break;
2707         }
2708 
2709         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2710         if (!Info)
2711         {
2712             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
2713                 (*PFieldList)->Name);
2714             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2715                 (*PFieldList), AslGbl_MsgBuffer);
2716 
2717             *PFieldList = (*PFieldList)->Next;
2718             continue;
2719         }
2720 
2721         Status = DtCompileTable (PFieldList, Info,
2722             &Subtable);
2723         if (ACPI_SUCCESS (Status))
2724         {
2725             DtInsertSubtable (ParentTable, Subtable);
2726             if (Length)
2727             {
2728                 *Length += Subtable->Length;
2729             }
2730         }
2731         else
2732         {
2733             *PFieldList = (*PFieldList)->Next;
2734 
2735             if (Status == AE_NOT_FOUND)
2736             {
2737                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
2738                     (*PFieldList)->Name);
2739                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2740                     (*PFieldList), AslGbl_MsgBuffer);
2741             }
2742         }
2743     }
2744 
2745     return (AE_OK);
2746 }
2747