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