xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable2.c (revision f126890ac5386406dadf7c4cfa9566cbb56537c5)
1 /******************************************************************************
2  *
3  * Module Name: dttable2.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 /* Compile all complex data tables, signatures starting with L-Z */
153 
154 #include <contrib/dev/acpica/compiler/aslcompiler.h>
155 
156 #define _COMPONENT          DT_COMPILER
157         ACPI_MODULE_NAME    ("dttable2")
158 
159 
160 /******************************************************************************
161  *
162  * FUNCTION:    DtCompileLpit
163  *
164  * PARAMETERS:  List                - Current field list pointer
165  *
166  * RETURN:      Status
167  *
168  * DESCRIPTION: Compile LPIT.
169  *
170  *****************************************************************************/
171 
172 ACPI_STATUS
173 DtCompileLpit (
174     void                    **List)
175 {
176     ACPI_STATUS             Status;
177     DT_SUBTABLE             *Subtable;
178     DT_SUBTABLE             *ParentTable;
179     DT_FIELD                **PFieldList = (DT_FIELD **) List;
180     DT_FIELD                *SubtableStart;
181     ACPI_DMTABLE_INFO       *InfoTable;
182     ACPI_LPIT_HEADER        *LpitHeader;
183 
184 
185     /* Note: Main table consists only of the standard ACPI table header */
186 
187     while (*PFieldList)
188     {
189         SubtableStart = *PFieldList;
190 
191         /* LPIT Subtable header */
192 
193         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
194             &Subtable);
195         if (ACPI_FAILURE (Status))
196         {
197             return (Status);
198         }
199 
200         ParentTable = DtPeekSubtable ();
201         DtInsertSubtable (ParentTable, Subtable);
202         DtPushSubtable (Subtable);
203 
204         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
205 
206         switch (LpitHeader->Type)
207         {
208         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
209 
210             InfoTable = AcpiDmTableInfoLpit0;
211             break;
212 
213         default:
214 
215             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
216             return (AE_ERROR);
217         }
218 
219         /* LPIT Subtable */
220 
221         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
222         if (ACPI_FAILURE (Status))
223         {
224             return (Status);
225         }
226 
227         ParentTable = DtPeekSubtable ();
228         DtInsertSubtable (ParentTable, Subtable);
229         DtPopSubtable ();
230     }
231 
232     return (AE_OK);
233 }
234 
235 
236 /******************************************************************************
237  *
238  * FUNCTION:    DtCompileMadt
239  *
240  * PARAMETERS:  List                - Current field list pointer
241  *
242  * RETURN:      Status
243  *
244  * DESCRIPTION: Compile MADT.
245  *
246  *****************************************************************************/
247 
248 ACPI_STATUS
249 DtCompileMadt (
250     void                    **List)
251 {
252     ACPI_STATUS             Status;
253     DT_SUBTABLE             *Subtable;
254     DT_SUBTABLE             *ParentTable;
255     DT_FIELD                **PFieldList = (DT_FIELD **) List;
256     DT_FIELD                *SubtableStart;
257     ACPI_SUBTABLE_HEADER    *MadtHeader;
258     ACPI_DMTABLE_INFO       *InfoTable;
259 
260 
261     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
262         &Subtable);
263     if (ACPI_FAILURE (Status))
264     {
265         return (Status);
266     }
267 
268     ParentTable = DtPeekSubtable ();
269     DtInsertSubtable (ParentTable, Subtable);
270 
271     while (*PFieldList)
272     {
273         SubtableStart = *PFieldList;
274         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
275             &Subtable);
276         if (ACPI_FAILURE (Status))
277         {
278             return (Status);
279         }
280 
281         ParentTable = DtPeekSubtable ();
282         DtInsertSubtable (ParentTable, Subtable);
283         DtPushSubtable (Subtable);
284 
285         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
286 
287         switch (MadtHeader->Type)
288         {
289         case ACPI_MADT_TYPE_LOCAL_APIC:
290 
291             InfoTable = AcpiDmTableInfoMadt0;
292             break;
293 
294         case ACPI_MADT_TYPE_IO_APIC:
295 
296             InfoTable = AcpiDmTableInfoMadt1;
297             break;
298 
299         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
300 
301             InfoTable = AcpiDmTableInfoMadt2;
302             break;
303 
304         case ACPI_MADT_TYPE_NMI_SOURCE:
305 
306             InfoTable = AcpiDmTableInfoMadt3;
307             break;
308 
309         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
310 
311             InfoTable = AcpiDmTableInfoMadt4;
312             break;
313 
314         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
315 
316             InfoTable = AcpiDmTableInfoMadt5;
317             break;
318 
319         case ACPI_MADT_TYPE_IO_SAPIC:
320 
321             InfoTable = AcpiDmTableInfoMadt6;
322             break;
323 
324         case ACPI_MADT_TYPE_LOCAL_SAPIC:
325 
326             InfoTable = AcpiDmTableInfoMadt7;
327             break;
328 
329         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
330 
331             InfoTable = AcpiDmTableInfoMadt8;
332             break;
333 
334         case ACPI_MADT_TYPE_LOCAL_X2APIC:
335 
336             InfoTable = AcpiDmTableInfoMadt9;
337             break;
338 
339         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
340 
341             InfoTable = AcpiDmTableInfoMadt10;
342             break;
343 
344         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
345 
346             InfoTable = AcpiDmTableInfoMadt11;
347             break;
348 
349         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
350 
351             InfoTable = AcpiDmTableInfoMadt12;
352             break;
353 
354         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
355 
356             InfoTable = AcpiDmTableInfoMadt13;
357             break;
358 
359         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
360 
361             InfoTable = AcpiDmTableInfoMadt14;
362             break;
363 
364         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
365 
366             InfoTable = AcpiDmTableInfoMadt15;
367             break;
368 
369         case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
370 
371             InfoTable = AcpiDmTableInfoMadt16;
372             break;
373 
374         case ACPI_MADT_TYPE_CORE_PIC:
375 
376             InfoTable = AcpiDmTableInfoMadt17;
377             break;
378 
379         case ACPI_MADT_TYPE_LIO_PIC:
380 
381             InfoTable = AcpiDmTableInfoMadt18;
382             break;
383 
384         case ACPI_MADT_TYPE_HT_PIC:
385 
386             InfoTable = AcpiDmTableInfoMadt19;
387             break;
388 
389         case ACPI_MADT_TYPE_EIO_PIC:
390 
391             InfoTable = AcpiDmTableInfoMadt20;
392             break;
393 
394         case ACPI_MADT_TYPE_MSI_PIC:
395 
396             InfoTable = AcpiDmTableInfoMadt21;
397             break;
398 
399         case ACPI_MADT_TYPE_BIO_PIC:
400 
401             InfoTable = AcpiDmTableInfoMadt22;
402             break;
403 
404         case ACPI_MADT_TYPE_LPC_PIC:
405 
406             InfoTable = AcpiDmTableInfoMadt23;
407             break;
408 
409         case ACPI_MADT_TYPE_RINTC:
410 
411             InfoTable = AcpiDmTableInfoMadt24;
412             break;
413 
414         case ACPI_MADT_TYPE_IMSIC:
415 
416             InfoTable = AcpiDmTableInfoMadt25;
417             break;
418 
419         case ACPI_MADT_TYPE_APLIC:
420 
421             InfoTable = AcpiDmTableInfoMadt26;
422             break;
423 
424         case ACPI_MADT_TYPE_PLIC:
425 
426             InfoTable = AcpiDmTableInfoMadt27;
427             break;
428 
429         default:
430 
431             if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED)
432             {
433                 InfoTable = AcpiDmTableInfoMadt128;
434             }
435             else
436             {
437                 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
438                 return (AE_ERROR);
439             }
440 
441             break;
442         }
443 
444         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
445         if (ACPI_FAILURE (Status))
446         {
447             return (Status);
448         }
449 
450         ParentTable = DtPeekSubtable ();
451         DtInsertSubtable (ParentTable, Subtable);
452         DtPopSubtable ();
453     }
454 
455     return (AE_OK);
456 }
457 
458 
459 /******************************************************************************
460  *
461  * FUNCTION:    DtCompileMcfg
462  *
463  * PARAMETERS:  List                - Current field list pointer
464  *
465  * RETURN:      Status
466  *
467  * DESCRIPTION: Compile MCFG.
468  *
469  *****************************************************************************/
470 
471 ACPI_STATUS
472 DtCompileMcfg (
473     void                    **List)
474 {
475     ACPI_STATUS             Status;
476 
477 
478     Status = DtCompileTwoSubtables (List,
479         AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
480     return (Status);
481 }
482 
483 /******************************************************************************
484  *
485  * FUNCTION:    DtCompileMpam
486  *
487  * PARAMETERS:  List                - Current field list pointer
488  *
489  * RETURN:      Status
490  *
491  * DESCRIPTION: Compile MPAM.
492  *
493  *****************************************************************************/
494 
495 ACPI_STATUS
496 DtCompileMpam (
497     void                    **List)
498 {
499     ACPI_STATUS             Status;
500     DT_SUBTABLE             *ParentTable;
501     DT_SUBTABLE             *Subtable;
502     DT_FIELD                *SubtableStart;
503     DT_FIELD                **PFieldList = (DT_FIELD **) List;
504     ACPI_MPAM_MSC_NODE      *MpamMscNode;
505     ACPI_MPAM_RESOURCE_NODE *MpamResourceNode;
506     UINT32                  FuncDepsCount;
507     UINT32                  RisLength;
508     ACPI_DMTABLE_INFO       *InfoTable;
509 
510     ParentTable = DtPeekSubtable ();
511 
512     while (*PFieldList)
513     {
514         SubtableStart = *PFieldList;
515 
516         /* Main MSC Node table */
517         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0,
518             &Subtable);
519         if (ACPI_FAILURE (Status))
520         {
521             return (Status);
522         }
523 
524         MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer);
525 
526         ParentTable = DtPeekSubtable ();
527         DtInsertSubtable (ParentTable, Subtable);
528         DtPushSubtable (Subtable);
529 
530         ParentTable = DtPeekSubtable ();
531 
532         /*
533          * RIS(es) per MSC node have variable lengths depending on how many RISes there and
534          * any how many functional dependencies per RIS. Calculate it in order
535          * to properly set the overall MSC length.
536          */
537         RisLength = 0;
538 
539         /* Iterate over RIS subtables per MSC node */
540         for (UINT32 ris = 0; ris < MpamMscNode->NumResouceNodes; ris++)
541         {
542             /* Compile RIS subtable */
543             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1,
544                 &Subtable);
545             if (ACPI_FAILURE (Status))
546             {
547                 return (Status);
548             }
549 
550             MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer);
551             DtInsertSubtable (ParentTable, Subtable);
552             DtPushSubtable (Subtable);
553 
554             ParentTable = DtPeekSubtable ();
555 
556             switch (MpamResourceNode->LocatorType)
557             {
558                 case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE:
559                     InfoTable = AcpiDmTableInfoMpam1A;
560                     break;
561                 case ACPI_MPAM_LOCATION_TYPE_MEMORY:
562                     InfoTable = AcpiDmTableInfoMpam1B;
563                     break;
564                 case ACPI_MPAM_LOCATION_TYPE_SMMU:
565                     InfoTable = AcpiDmTableInfoMpam1C;
566                     break;
567                 case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE:
568                     InfoTable = AcpiDmTableInfoMpam1D;
569                     break;
570                 case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE:
571                     InfoTable = AcpiDmTableInfoMpam1E;
572                     break;
573                 case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT:
574                     InfoTable = AcpiDmTableInfoMpam1F;
575                     break;
576                 case ACPI_MPAM_LOCATION_TYPE_UNKNOWN:
577                     InfoTable = AcpiDmTableInfoMpam1G;
578                 default:
579                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type");
580                     return (AE_ERROR);
581             }
582 
583             /* Compile Resource Locator Table */
584             Status = DtCompileTable (PFieldList, InfoTable,
585                 &Subtable);
586 
587             if (ACPI_FAILURE (Status))
588             {
589                 return (Status);
590             }
591 
592             DtInsertSubtable (ParentTable, Subtable);
593 
594             /* Compile the number of functional dependencies per RIS */
595             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps,
596                 &Subtable);
597 
598             if (ACPI_FAILURE (Status))
599             {
600                 return (Status);
601             }
602 
603             DtInsertSubtable (ParentTable, Subtable);
604             FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
605 
606             RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) +
607                 FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS);
608 
609             /* Iterate over functional dependencies per RIS */
610             for (UINT32 funcDep = 0; funcDep < FuncDepsCount; funcDep++)
611             {
612                 /* Compiler functional dependencies table */
613                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2,
614                     &Subtable);
615 
616                 if (ACPI_FAILURE (Status))
617                 {
618                     return (Status);
619                 }
620 
621                 DtInsertSubtable (ParentTable, Subtable);
622             }
623 
624             DtPopSubtable ();
625         }
626 
627         /* Check if the length of the MSC is correct and override with the correct length */
628         if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength)
629         {
630             MpamMscNode->Length = (UINT16) (sizeof(ACPI_MPAM_MSC_NODE) + RisLength);
631             DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length);
632         }
633 
634         DtPopSubtable ();
635     }
636 
637     return (AE_OK);
638 }
639 
640 
641 /******************************************************************************
642  *
643  * FUNCTION:    DtCompileMpst
644  *
645  * PARAMETERS:  List                - Current field list pointer
646  *
647  * RETURN:      Status
648  *
649  * DESCRIPTION: Compile MPST.
650  *
651  *****************************************************************************/
652 
653 ACPI_STATUS
654 DtCompileMpst (
655     void                    **List)
656 {
657     ACPI_STATUS             Status;
658     DT_SUBTABLE             *Subtable;
659     DT_SUBTABLE             *ParentTable;
660     DT_FIELD                **PFieldList = (DT_FIELD **) List;
661     ACPI_MPST_CHANNEL       *MpstChannelInfo;
662     ACPI_MPST_POWER_NODE    *MpstPowerNode;
663     ACPI_MPST_DATA_HDR      *MpstDataHeader;
664     UINT16                  SubtableCount;
665     UINT32                  PowerStateCount;
666     UINT32                  ComponentCount;
667 
668 
669     /* Main table */
670 
671     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable);
672     if (ACPI_FAILURE (Status))
673     {
674         return (Status);
675     }
676 
677     ParentTable = DtPeekSubtable ();
678     DtInsertSubtable (ParentTable, Subtable);
679     DtPushSubtable (Subtable);
680 
681     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
682     SubtableCount = MpstChannelInfo->PowerNodeCount;
683 
684     while (*PFieldList && SubtableCount)
685     {
686         /* Subtable: Memory Power Node(s) */
687 
688         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
689             &Subtable);
690         if (ACPI_FAILURE (Status))
691         {
692             return (Status);
693         }
694 
695         ParentTable = DtPeekSubtable ();
696         DtInsertSubtable (ParentTable, Subtable);
697         DtPushSubtable (Subtable);
698 
699         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
700         PowerStateCount = MpstPowerNode->NumPowerStates;
701         ComponentCount = MpstPowerNode->NumPhysicalComponents;
702 
703         ParentTable = DtPeekSubtable ();
704 
705         /* Sub-subtables - Memory Power State Structure(s) */
706 
707         while (*PFieldList && PowerStateCount)
708         {
709             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
710                 &Subtable);
711             if (ACPI_FAILURE (Status))
712             {
713                 return (Status);
714             }
715 
716             DtInsertSubtable (ParentTable, Subtable);
717             PowerStateCount--;
718         }
719 
720         /* Sub-subtables - Physical Component ID Structure(s) */
721 
722         while (*PFieldList && ComponentCount)
723         {
724             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
725                 &Subtable);
726             if (ACPI_FAILURE (Status))
727             {
728                 return (Status);
729             }
730 
731             DtInsertSubtable (ParentTable, Subtable);
732             ComponentCount--;
733         }
734 
735         SubtableCount--;
736         DtPopSubtable ();
737     }
738 
739     /* Subtable: Count of Memory Power State Characteristic structures */
740 
741     DtPopSubtable ();
742 
743     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable);
744     if (ACPI_FAILURE (Status))
745     {
746         return (Status);
747     }
748 
749     ParentTable = DtPeekSubtable ();
750     DtInsertSubtable (ParentTable, Subtable);
751     DtPushSubtable (Subtable);
752 
753     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
754     SubtableCount = MpstDataHeader->CharacteristicsCount;
755 
756     ParentTable = DtPeekSubtable ();
757 
758     /* Subtable: Memory Power State Characteristics structure(s) */
759 
760     while (*PFieldList && SubtableCount)
761     {
762         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
763             &Subtable);
764         if (ACPI_FAILURE (Status))
765         {
766             return (Status);
767         }
768 
769         DtInsertSubtable (ParentTable, Subtable);
770         SubtableCount--;
771     }
772 
773     DtPopSubtable ();
774     return (AE_OK);
775 }
776 
777 
778 /******************************************************************************
779  *
780  * FUNCTION:    DtCompileMsct
781  *
782  * PARAMETERS:  List                - Current field list pointer
783  *
784  * RETURN:      Status
785  *
786  * DESCRIPTION: Compile MSCT.
787  *
788  *****************************************************************************/
789 
790 ACPI_STATUS
791 DtCompileMsct (
792     void                    **List)
793 {
794     ACPI_STATUS             Status;
795 
796 
797     Status = DtCompileTwoSubtables (List,
798         AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
799     return (Status);
800 }
801 
802 
803 /******************************************************************************
804  *
805  * FUNCTION:    DtCompileNfit
806  *
807  * PARAMETERS:  List                - Current field list pointer
808  *
809  * RETURN:      Status
810  *
811  * DESCRIPTION: Compile NFIT.
812  *
813  *****************************************************************************/
814 
815 ACPI_STATUS
816 DtCompileNfit (
817     void                    **List)
818 {
819     ACPI_STATUS             Status;
820     DT_SUBTABLE             *Subtable;
821     DT_SUBTABLE             *ParentTable;
822     DT_FIELD                **PFieldList = (DT_FIELD **) List;
823     DT_FIELD                *SubtableStart;
824     ACPI_NFIT_HEADER        *NfitHeader;
825     ACPI_DMTABLE_INFO       *InfoTable;
826     UINT32                  Count;
827     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
828     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
829 
830 
831     /* Main table */
832 
833     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
834         &Subtable);
835     if (ACPI_FAILURE (Status))
836     {
837         return (Status);
838     }
839 
840     ParentTable = DtPeekSubtable ();
841     DtInsertSubtable (ParentTable, Subtable);
842     DtPushSubtable (Subtable);
843 
844     /* Subtables */
845 
846     while (*PFieldList)
847     {
848         SubtableStart = *PFieldList;
849         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
850             &Subtable);
851         if (ACPI_FAILURE (Status))
852         {
853             return (Status);
854         }
855 
856         ParentTable = DtPeekSubtable ();
857         DtInsertSubtable (ParentTable, Subtable);
858         DtPushSubtable (Subtable);
859 
860         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
861 
862         switch (NfitHeader->Type)
863         {
864         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
865 
866             InfoTable = AcpiDmTableInfoNfit0;
867             break;
868 
869         case ACPI_NFIT_TYPE_MEMORY_MAP:
870 
871             InfoTable = AcpiDmTableInfoNfit1;
872             break;
873 
874         case ACPI_NFIT_TYPE_INTERLEAVE:
875 
876             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
877             InfoTable = AcpiDmTableInfoNfit2;
878             break;
879 
880         case ACPI_NFIT_TYPE_SMBIOS:
881 
882             InfoTable = AcpiDmTableInfoNfit3;
883             break;
884 
885         case ACPI_NFIT_TYPE_CONTROL_REGION:
886 
887             InfoTable = AcpiDmTableInfoNfit4;
888             break;
889 
890         case ACPI_NFIT_TYPE_DATA_REGION:
891 
892             InfoTable = AcpiDmTableInfoNfit5;
893             break;
894 
895         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
896 
897             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
898             InfoTable = AcpiDmTableInfoNfit6;
899             break;
900 
901         case ACPI_NFIT_TYPE_CAPABILITIES:
902 
903             InfoTable = AcpiDmTableInfoNfit7;
904             break;
905 
906         default:
907 
908             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
909             return (AE_ERROR);
910         }
911 
912         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
913         if (ACPI_FAILURE (Status))
914         {
915             return (Status);
916         }
917 
918         ParentTable = DtPeekSubtable ();
919         DtInsertSubtable (ParentTable, Subtable);
920         DtPopSubtable ();
921 
922         switch (NfitHeader->Type)
923         {
924         case ACPI_NFIT_TYPE_INTERLEAVE:
925 
926             Count = 0;
927             DtPushSubtable (Subtable);
928             while (*PFieldList)
929             {
930                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
931                     &Subtable);
932                 if (ACPI_FAILURE (Status))
933                 {
934                     return (Status);
935                 }
936 
937                 if (!Subtable)
938                 {
939                     DtPopSubtable ();
940                     break;
941                 }
942 
943                 ParentTable = DtPeekSubtable ();
944                 DtInsertSubtable (ParentTable, Subtable);
945                 Count++;
946             }
947 
948             Interleave->LineCount = Count;
949             break;
950 
951         case ACPI_NFIT_TYPE_SMBIOS:
952 
953             if (*PFieldList)
954             {
955                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
956                     &Subtable);
957                 if (ACPI_FAILURE (Status))
958                 {
959                     return (Status);
960                 }
961 
962                 if (Subtable)
963                 {
964                     DtInsertSubtable (ParentTable, Subtable);
965                 }
966             }
967             break;
968 
969         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
970 
971             Count = 0;
972             DtPushSubtable (Subtable);
973             while (*PFieldList)
974             {
975                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
976                     &Subtable);
977                 if (ACPI_FAILURE (Status))
978                 {
979                     return (Status);
980                 }
981 
982                 if (!Subtable)
983                 {
984                     DtPopSubtable ();
985                     break;
986                 }
987 
988                 ParentTable = DtPeekSubtable ();
989                 DtInsertSubtable (ParentTable, Subtable);
990                 Count++;
991             }
992 
993             Hint->HintCount = (UINT16) Count;
994             break;
995 
996         default:
997             break;
998         }
999     }
1000 
1001     return (AE_OK);
1002 }
1003 
1004 
1005 /******************************************************************************
1006  *
1007  * FUNCTION:    DtCompileNhlt
1008  *
1009  * PARAMETERS:  List                - Current field list pointer
1010  *
1011  * RETURN:      Status
1012  *
1013  * DESCRIPTION: Compile NHLT.
1014  *
1015  *****************************************************************************/
1016 
1017 ACPI_STATUS
1018 DtCompileNhlt (
1019     void                    **List)
1020 {
1021     ACPI_STATUS             Status;
1022     UINT32                  EndpointCount;
1023     UINT32                  MicrophoneCount;
1024     UINT32                  FormatsCount;
1025     DT_SUBTABLE             *Subtable;
1026     DT_SUBTABLE             *ParentTable;
1027     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1028     UINT32                  CapabilitiesSize;
1029     UINT8                   ArrayType;
1030     UINT8                   ConfigType;
1031     UINT8                   DeviceInfoCount;
1032     UINT32                  i;
1033     UINT32                  j;
1034     ACPI_TABLE_NHLT_ENDPOINT_COUNT      *MainTable;
1035     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A  *DevSpecific;
1036     ACPI_NHLT_VENDOR_MIC_COUNT          *MicCount;
1037     ACPI_NHLT_FORMATS_CONFIG            *FormatsConfig;
1038     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D  *ConfigSpecific;
1039     ACPI_NHLT_DEVICE_INFO_COUNT         *DeviceInfo;
1040     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B  *Terminator;
1041 
1042 
1043     /* Main table */
1044 
1045     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt,
1046         &Subtable);
1047     if (ACPI_FAILURE (Status))
1048     {
1049         return (Status);
1050     }
1051 
1052     /* Get the Endpoint Descriptor count */
1053 
1054     ParentTable = DtPeekSubtable ();
1055     DtInsertSubtable (ParentTable, Subtable);
1056     DtPushSubtable (Subtable);
1057 
1058     MainTable = ACPI_CAST_PTR (ACPI_TABLE_NHLT_ENDPOINT_COUNT, Subtable->Buffer);
1059     EndpointCount = MainTable->EndpointCount;
1060 
1061     /* Subtables */
1062 
1063     while (*PFieldList)
1064     {
1065         /* Variable number of Endpoint descriptors */
1066 
1067         for (i = 0; i < EndpointCount; i++)
1068         {
1069             /* Do the Endpoint Descriptor */
1070 
1071             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt0,
1072                 &Subtable);
1073             if (ACPI_FAILURE (Status))
1074             {
1075                 return (Status);
1076             }
1077 
1078             ParentTable = DtPeekSubtable ();
1079             DtInsertSubtable (ParentTable, Subtable);
1080             DtPushSubtable (Subtable);
1081 
1082             /* Do the Device Specific table */
1083 
1084             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b,
1085                 &Subtable);
1086             if (ACPI_FAILURE (Status))
1087             {
1088                 return (Status);
1089             }
1090 
1091             ParentTable = DtPeekSubtable ();
1092             DtInsertSubtable (ParentTable, Subtable);
1093             DtPushSubtable (Subtable);
1094 
1095             DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable->Buffer);
1096             CapabilitiesSize = DevSpecific->CapabilitiesSize;
1097 
1098             ArrayType = 0;
1099             ConfigType = 0;
1100 
1101             switch (CapabilitiesSize)
1102             {
1103             case 0:
1104                 break;
1105 
1106             case 1:
1107 
1108                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5c,
1109                     &Subtable);
1110                 if (ACPI_FAILURE (Status))
1111                 {
1112                     return (Status);
1113                 }
1114 
1115                 ParentTable = DtPeekSubtable ();
1116                 DtInsertSubtable (ParentTable, Subtable);
1117                 break;
1118 
1119             case 2:
1120 
1121                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5,
1122                     &Subtable);
1123                 if (ACPI_FAILURE (Status))
1124                 {
1125                     return (Status);
1126                 }
1127 
1128                 ParentTable = DtPeekSubtable ();
1129                 DtInsertSubtable (ParentTable, Subtable);
1130                 break;
1131 
1132             case 3:
1133 
1134                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a,
1135                     &Subtable);
1136                 if (ACPI_FAILURE (Status))
1137                 {
1138                     return (Status);
1139                 }
1140 
1141                 ParentTable = DtPeekSubtable ();
1142                 DtInsertSubtable (ParentTable, Subtable);
1143 
1144                 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer);
1145                 ArrayType = ConfigSpecific->ArrayType;
1146                 ConfigType = ConfigSpecific->ConfigType;
1147                 break;
1148 
1149             case 7:
1150 
1151                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5,
1152                     &Subtable);
1153                 if (ACPI_FAILURE (Status))
1154                 {
1155                     return (Status);
1156                 }
1157 
1158                 ParentTable = DtPeekSubtable ();
1159                 DtInsertSubtable (ParentTable, Subtable);
1160 
1161                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6b,
1162                     &Subtable);
1163                 if (ACPI_FAILURE (Status))
1164                 {
1165                     return (Status);
1166                 }
1167 
1168                 ParentTable = DtPeekSubtable ();
1169                 DtInsertSubtable (ParentTable, Subtable);
1170 
1171                 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer);
1172                 ArrayType = ConfigSpecific->ArrayType;
1173                 ConfigType = ConfigSpecific->ConfigType;
1174                 break;
1175 
1176             default:
1177 
1178                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a,
1179                     &Subtable);
1180                 if (ACPI_FAILURE (Status))
1181                 {
1182                     return (Status);
1183                 }
1184 
1185                 ParentTable = DtPeekSubtable ();
1186                 DtInsertSubtable (ParentTable, Subtable);
1187 
1188                 ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer);
1189                 ArrayType = ConfigSpecific->ArrayType;
1190                 ConfigType = ConfigSpecific->ConfigType;
1191                 break;
1192 
1193             } /* switch (CapabilitiesSize) */
1194 
1195             if (CapabilitiesSize >= 3)
1196             {
1197                 /* Check for a vendor-defined mic array */
1198 
1199                 if (ConfigType == ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY)
1200                 {
1201                     if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_MASK) == ACPI_NHLT_VENDOR_DEFINED)
1202                     {
1203                         /* Get the microphone count */
1204 
1205                         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6a,
1206                             &Subtable);
1207                         if (ACPI_FAILURE (Status))
1208                         {
1209                             return (Status);
1210                         }
1211 
1212                         MicCount = ACPI_CAST_PTR (ACPI_NHLT_VENDOR_MIC_COUNT, Subtable->Buffer);
1213                         MicrophoneCount = MicCount->MicrophoneCount;
1214 
1215                         ParentTable = DtPeekSubtable ();
1216                         DtInsertSubtable (ParentTable, Subtable);
1217 
1218                         /* Variable number of microphones */
1219 
1220                         for (j = 0; j < MicrophoneCount; j++)
1221                         {
1222                             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6,
1223                                 &Subtable);
1224                             if (ACPI_FAILURE (Status))
1225                             {
1226                                 return (Status);
1227                             }
1228 
1229                             ParentTable = DtPeekSubtable ();
1230                             DtInsertSubtable (ParentTable, Subtable);
1231                         }
1232 
1233                         /* Do the MIC_SNR_SENSITIVITY_EXTENSION, if present */
1234 
1235                         if (ArrayType & ACPI_NHLT_ARRAY_TYPE_EXT_MASK)
1236                         {
1237                             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt9,
1238                                 &Subtable);
1239                             if (ACPI_FAILURE (Status))
1240                             {
1241                                 return (Status);
1242                             }
1243 
1244                             ParentTable = DtPeekSubtable ();
1245                             DtInsertSubtable (ParentTable, Subtable);
1246                         }
1247                     }
1248                 }
1249             }
1250 
1251             /* Get the formats count */
1252 
1253             DtPopSubtable ();
1254             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt4,
1255                 &Subtable);
1256             if (ACPI_FAILURE (Status))
1257             {
1258                 return (Status);
1259             }
1260 
1261             ParentTable = DtPeekSubtable ();
1262             DtInsertSubtable (ParentTable, Subtable);
1263 
1264             FormatsConfig = ACPI_CAST_PTR (ACPI_NHLT_FORMATS_CONFIG, Subtable->Buffer);
1265             FormatsCount = FormatsConfig->FormatsCount;
1266 
1267             /* Variable number of wave_format_extensible structs */
1268 
1269             for (j = 0; j < FormatsCount; j++)
1270             {
1271                 /* Do the main wave_format_extensible structure */
1272 
1273                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3,
1274                     &Subtable);
1275                 if (ACPI_FAILURE (Status))
1276                 {
1277                     return (Status);
1278                 }
1279 
1280                 ParentTable = DtPeekSubtable ();
1281                 DtInsertSubtable (ParentTable, Subtable);
1282                 DtPushSubtable (Subtable);
1283 
1284                 /* Do the capabilities list */
1285 
1286                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a,
1287                     &Subtable);
1288                 if (ACPI_FAILURE (Status))
1289                 {
1290                     return (Status);
1291                 }
1292 
1293                 DtPopSubtable ();
1294                 ParentTable = DtPeekSubtable ();
1295                 DtInsertSubtable (ParentTable, Subtable);
1296 
1297             } /* for (j = 0; j < FormatsCount; j++) */
1298 
1299             /*
1300              * If we are not done with the current Endpoint yet, then there must be
1301              * some non documented structure(s) yet to be processed. First, get
1302              * the count of such structure(s).
1303              */
1304             if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Device Info struct count")))
1305             {
1306                 /* Get the count of non documented structures */
1307 
1308                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7,
1309                     &Subtable);
1310                 if (ACPI_FAILURE (Status))
1311                 {
1312                     return (Status);
1313                 }
1314 
1315                 ParentTable = DtPeekSubtable ();
1316                 DtInsertSubtable (ParentTable, Subtable);
1317 
1318                 DeviceInfo = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_INFO_COUNT, Subtable->Buffer);
1319                 DeviceInfoCount = DeviceInfo->StructureCount;
1320 
1321                 for (j = 0; j < DeviceInfoCount; j++)
1322                 {
1323                     /*
1324                      * Compile the following Device Info fields:
1325                      *  1) Device ID
1326                      *  2) Device Instance ID
1327                      *  3) Device Port ID
1328                      */
1329                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7a,
1330                         &Subtable);
1331                     if (ACPI_FAILURE (Status))
1332                     {
1333                         return (Status);
1334                     }
1335 
1336                     ParentTable = DtPeekSubtable ();
1337                     DtInsertSubtable (ParentTable, Subtable);
1338                 } /* for (j = 0; j < LinuxSpecificCount; j++) */
1339 
1340                 /* Undocumented data at the end of endpoint */
1341                 if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Bytes")))
1342                 {
1343                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7b,
1344                         &Subtable);
1345                     if (ACPI_FAILURE (Status))
1346                     {
1347                         return (Status);
1348                     }
1349 
1350                     ParentTable = DtPeekSubtable ();
1351                     DtInsertSubtable (ParentTable, Subtable);
1352                 }
1353             }
1354 
1355             DtPopSubtable ();
1356 
1357         } /* for (i = 0; i < EndpointCount; i++) */
1358 
1359         /*
1360          * All Endpoint Descriptors are completed.
1361          * Do the table terminator specific config (not in NHLT spec, optional)
1362          */
1363         if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Capabilities Size")))
1364         {
1365             Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b,
1366                 &Subtable);
1367             if (ACPI_FAILURE (Status))
1368             {
1369                 return (Status);
1370             }
1371 
1372             ParentTable = DtPeekSubtable ();
1373             DtInsertSubtable (ParentTable, Subtable);
1374 
1375             Terminator = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B, Subtable->Buffer);
1376 
1377             if (Terminator->CapabilitiesSize)
1378             {
1379                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a,
1380                     &Subtable);
1381                 if (ACPI_FAILURE (Status))
1382                 {
1383                     return (Status);
1384                 }
1385 
1386                 ParentTable = DtPeekSubtable ();
1387                 DtInsertSubtable (ParentTable, Subtable);
1388             }
1389         }
1390 
1391         return (AE_OK);
1392     }
1393 
1394     return (AE_OK);
1395 }
1396 
1397 
1398 /******************************************************************************
1399  *
1400  * FUNCTION:    DtCompilePcct
1401  *
1402  * PARAMETERS:  List                - Current field list pointer
1403  *
1404  * RETURN:      Status
1405  *
1406  * DESCRIPTION: Compile PCCT.
1407  *
1408  *****************************************************************************/
1409 
1410 ACPI_STATUS
1411 DtCompilePcct (
1412     void                    **List)
1413 {
1414     ACPI_STATUS             Status;
1415     DT_SUBTABLE             *Subtable;
1416     DT_SUBTABLE             *ParentTable;
1417     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1418     DT_FIELD                *SubtableStart;
1419     ACPI_SUBTABLE_HEADER    *PcctHeader;
1420     ACPI_DMTABLE_INFO       *InfoTable;
1421 
1422 
1423     /* Main table */
1424 
1425     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1426         &Subtable);
1427     if (ACPI_FAILURE (Status))
1428     {
1429         return (Status);
1430     }
1431 
1432     ParentTable = DtPeekSubtable ();
1433     DtInsertSubtable (ParentTable, Subtable);
1434 
1435     /* Subtables */
1436 
1437     while (*PFieldList)
1438     {
1439         SubtableStart = *PFieldList;
1440         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1441             &Subtable);
1442         if (ACPI_FAILURE (Status))
1443         {
1444             return (Status);
1445         }
1446 
1447         ParentTable = DtPeekSubtable ();
1448         DtInsertSubtable (ParentTable, Subtable);
1449         DtPushSubtable (Subtable);
1450 
1451         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1452 
1453         switch (PcctHeader->Type)
1454         {
1455         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1456 
1457             InfoTable = AcpiDmTableInfoPcct0;
1458             break;
1459 
1460         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1461 
1462             InfoTable = AcpiDmTableInfoPcct1;
1463             break;
1464 
1465         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
1466 
1467             InfoTable = AcpiDmTableInfoPcct2;
1468             break;
1469 
1470         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
1471 
1472             InfoTable = AcpiDmTableInfoPcct3;
1473             break;
1474 
1475         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
1476 
1477             InfoTable = AcpiDmTableInfoPcct4;
1478             break;
1479 
1480         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
1481 
1482             InfoTable = AcpiDmTableInfoPcct5;
1483             break;
1484 
1485         default:
1486 
1487             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1488             return (AE_ERROR);
1489         }
1490 
1491         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1492         if (ACPI_FAILURE (Status))
1493         {
1494             return (Status);
1495         }
1496 
1497         ParentTable = DtPeekSubtable ();
1498         DtInsertSubtable (ParentTable, Subtable);
1499         DtPopSubtable ();
1500     }
1501 
1502     return (AE_OK);
1503 }
1504 
1505 
1506 /******************************************************************************
1507  *
1508  * FUNCTION:    DtCompilePdtt
1509  *
1510  * PARAMETERS:  List                - Current field list pointer
1511  *
1512  * RETURN:      Status
1513  *
1514  * DESCRIPTION: Compile PDTT.
1515  *
1516  *****************************************************************************/
1517 
1518 ACPI_STATUS
1519 DtCompilePdtt (
1520     void                    **List)
1521 {
1522     ACPI_STATUS             Status;
1523     DT_SUBTABLE             *Subtable;
1524     DT_SUBTABLE             *ParentTable;
1525     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1526     ACPI_TABLE_PDTT         *PdttHeader;
1527     UINT32                  Count = 0;
1528 
1529 
1530     /* Main table */
1531 
1532     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
1533     if (ACPI_FAILURE (Status))
1534     {
1535         return (Status);
1536     }
1537 
1538     ParentTable = DtPeekSubtable ();
1539     DtInsertSubtable (ParentTable, Subtable);
1540 
1541     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
1542     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
1543 
1544     /* There is only one type of subtable at this time, no need to decode */
1545 
1546     while (*PFieldList)
1547     {
1548         /* List of subchannel IDs, each 2 bytes */
1549 
1550         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
1551             &Subtable);
1552         if (ACPI_FAILURE (Status))
1553         {
1554             return (Status);
1555         }
1556 
1557         DtInsertSubtable (ParentTable, Subtable);
1558         Count++;
1559     }
1560 
1561     PdttHeader->TriggerCount = (UINT8) Count;
1562     return (AE_OK);
1563 }
1564 
1565 
1566 /******************************************************************************
1567  *
1568  * FUNCTION:    DtCompilePhat
1569  *
1570  * PARAMETERS:  List                - Current field list pointer
1571  *
1572  * RETURN:      Status
1573  *
1574  * DESCRIPTION: Compile Phat.
1575  *
1576  *****************************************************************************/
1577 
1578 ACPI_STATUS
1579 DtCompilePhat (
1580     void                    **List)
1581 {
1582     ACPI_STATUS             Status = AE_OK;
1583     DT_SUBTABLE             *Subtable;
1584     DT_SUBTABLE             *ParentTable;
1585     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1586     ACPI_PHAT_HEADER        *PhatHeader;
1587     ACPI_DMTABLE_INFO       *Info;
1588     ACPI_PHAT_VERSION_DATA  *VersionData;
1589     UINT32                  DeviceDataLength;
1590     UINT32                  RecordCount;
1591     DT_FIELD                *DataOffsetField;
1592     DT_FIELD                *DevicePathField;
1593     UINT32                  TableOffset = 0;
1594     UINT32                  DataOffsetValue;
1595     UINT32                  i;
1596 
1597 
1598     /* The table consists of subtables */
1599 
1600     while (*PFieldList)
1601     {
1602         /* Compile the common subtable header */
1603 
1604         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
1605         if (ACPI_FAILURE (Status))
1606         {
1607             return (Status);
1608         }
1609 
1610         TableOffset += Subtable->Length;
1611         DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length);
1612 
1613         ParentTable = DtPeekSubtable ();
1614         DtInsertSubtable (ParentTable, Subtable);
1615         DtPushSubtable (Subtable);
1616 
1617         PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
1618 
1619         switch (PhatHeader->Type)
1620         {
1621         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1622 
1623             /* Compile the middle portion of the Firmware Version Data */
1624 
1625             Info = AcpiDmTableInfoPhat0;
1626             PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
1627             DataOffsetField = NULL;
1628             break;
1629 
1630         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1631 
1632             DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n",
1633                 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length);
1634 
1635             DataOffsetField = *PFieldList;
1636 
1637             /* Walk the field list to get to the "Device-specific data Offset" field */
1638 
1639             TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA);
1640             for (i = 0; i < 3; i++)
1641             {
1642                 DataOffsetField = DataOffsetField->Next;
1643                 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n",
1644                     TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
1645             }
1646 
1647             /* Convert DataOffsetField->Value (a char * string) to an integer value */
1648 
1649             sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
1650 
1651             /*
1652              * Get the next field (Device Path):
1653              * DataOffsetField points to "Device-Specific Offset", next field is
1654              * "Device Path".
1655              */
1656             DevicePathField = DataOffsetField->Next;
1657 
1658             /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */
1659 
1660             DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2;
1661             TableOffset += DevicePathField->StringLength;
1662 
1663             DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n",
1664                 TableOffset, Subtable->Length, DevicePathField->StringLength);
1665 
1666             /* Set the DataOffsetField to the current TableOffset */
1667             /* Must set the DataOffsetField here (not later) */
1668 
1669             if (DataOffsetValue != 0)
1670             {
1671                 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset);
1672             }
1673 
1674             DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length);
1675 
1676             DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: "
1677                 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n",
1678                 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength,
1679                 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset);
1680 
1681             /* Compile the middle portion of the Health Data Record */
1682 
1683             Info = AcpiDmTableInfoPhat1;
1684             PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
1685             break;
1686 
1687         default:
1688 
1689             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1690             return (AE_ERROR);
1691         }
1692 
1693         /* Compile either the Version Data or the Health Data */
1694 
1695         Status = DtCompileTable (PFieldList, Info, &Subtable);
1696         if (ACPI_FAILURE (Status))
1697         {
1698             return (Status);
1699         }
1700 
1701         DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n",
1702             TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length);
1703 
1704         ParentTable = DtPeekSubtable ();
1705         DtInsertSubtable (ParentTable, Subtable);
1706 
1707         switch (PhatHeader->Type)
1708         {
1709         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1710 
1711             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
1712                 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
1713             RecordCount = VersionData->ElementCount;
1714 
1715             /* Compile all of the Version Elements */
1716 
1717             while (RecordCount)
1718             {
1719                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
1720                     &Subtable);
1721                 if (ACPI_FAILURE (Status))
1722                 {
1723                     return (Status);
1724                 }
1725 
1726                 ParentTable = DtPeekSubtable ();
1727                 DtInsertSubtable (ParentTable, Subtable);
1728 
1729                 TableOffset += Subtable->Length;
1730                 RecordCount--;
1731                 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
1732             }
1733 
1734             DtPopSubtable ();
1735             break;
1736 
1737         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1738 
1739             /* Compile the Device Path */
1740 
1741             DeviceDataLength = Subtable->Length;
1742             TableOffset += Subtable->Length;
1743 
1744             DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: "
1745                 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength,
1746                 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value,
1747                 Subtable->Length, TableOffset);
1748 
1749             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
1750             if (ACPI_FAILURE (Status))
1751             {
1752                 return (Status);
1753             }
1754             ParentTable = DtPeekSubtable ();
1755             DtInsertSubtable (ParentTable, Subtable);
1756 
1757             /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */
1758 
1759             if (!*PFieldList)
1760             {
1761                 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n");
1762                 return (AE_OK);
1763             }
1764 
1765             DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s"
1766                 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n",
1767                 DeviceDataLength, (*PFieldList)->Name, TableOffset,
1768                 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length);
1769 
1770             PhatHeader->Length += (UINT16) Subtable->Length;
1771 
1772             /* Convert DataOffsetField->Value (a hex char * string) to an integer value */
1773 
1774             sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
1775 
1776             DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n",
1777                 DataOffsetValue, TableOffset);
1778             if (DataOffsetValue != 0)
1779             {
1780                 /* Compile Device-Specific Data - only if the Data Offset is non-zero */
1781 
1782                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
1783                 if (ACPI_FAILURE (Status))
1784                 {
1785                     return (Status);
1786                 }
1787 
1788                 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n",
1789                     Subtable, TableOffset);
1790                 if (Subtable)
1791                 {
1792                     DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: "
1793                         "%X FieldName \"%s\" SubtableLength %X\n",
1794                         DeviceDataLength, DataOffsetField->Name, Subtable->Length);
1795 
1796                     DeviceDataLength += Subtable->Length;
1797 
1798                     ParentTable = DtPeekSubtable ();
1799                     DtInsertSubtable (ParentTable, Subtable);
1800 
1801                     PhatHeader->Length += (UINT16) Subtable->Length;
1802                 }
1803             }
1804 
1805             DtPopSubtable ();
1806 
1807             DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n",
1808                 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
1809             break;
1810 
1811         default:
1812 
1813             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1814             return (AE_ERROR);
1815         }
1816     }
1817 
1818     return (Status);
1819 }
1820 
1821 
1822 /******************************************************************************
1823  *
1824  * FUNCTION:    DtCompilePmtt
1825  *
1826  * PARAMETERS:  List                - Current field list pointer
1827  *
1828  * RETURN:      Status
1829  *
1830  * DESCRIPTION: Compile PMTT.
1831  *
1832  *****************************************************************************/
1833 
1834 ACPI_STATUS
1835 DtCompilePmtt (
1836     void                    **List)
1837 {
1838     ACPI_STATUS             Status;
1839     DT_SUBTABLE             *Subtable;
1840     DT_SUBTABLE             *ParentTable;
1841     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1842     DT_FIELD                *SubtableStart;
1843     UINT16                  Type;
1844 
1845 
1846     /* Main table */
1847 
1848     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
1849     if (ACPI_FAILURE (Status))
1850     {
1851         return (Status);
1852     }
1853 
1854     ParentTable = DtPeekSubtable ();
1855     DtInsertSubtable (ParentTable, Subtable);
1856     DtPushSubtable (Subtable);
1857 
1858     /* Subtables */
1859 
1860     while (*PFieldList)
1861     {
1862         SubtableStart = *PFieldList;
1863         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1864 
1865         switch (Type)
1866         {
1867         case ACPI_PMTT_TYPE_SOCKET:
1868 
1869             /* Subtable: Socket Structure */
1870 
1871             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
1872 
1873             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1874                 &Subtable);
1875             if (ACPI_FAILURE (Status))
1876             {
1877                 return (Status);
1878             }
1879 
1880             break;
1881 
1882         case ACPI_PMTT_TYPE_CONTROLLER:
1883 
1884             /* Subtable: Memory Controller Structure */
1885 
1886             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
1887 
1888             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1889                 &Subtable);
1890             if (ACPI_FAILURE (Status))
1891             {
1892                 return (Status);
1893             }
1894 
1895             break;
1896 
1897         case ACPI_PMTT_TYPE_DIMM:
1898 
1899             /* Subtable: Physical Component (DIMM) Structure */
1900 
1901             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
1902             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1903                 &Subtable);
1904             if (ACPI_FAILURE (Status))
1905             {
1906                 return (Status);
1907             }
1908 
1909             break;
1910 
1911         case ACPI_PMTT_TYPE_VENDOR:
1912 
1913             /* Subtable: Vendor-specific Structure */
1914 
1915             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
1916             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
1917                 &Subtable);
1918             if (ACPI_FAILURE (Status))
1919             {
1920                 return (Status);
1921             }
1922 
1923             break;
1924 
1925         default:
1926 
1927             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1928             return (AE_ERROR);
1929         }
1930 
1931         DtInsertSubtable (ParentTable, Subtable);
1932     }
1933 
1934     return (Status);
1935 }
1936 
1937 
1938 /******************************************************************************
1939  *
1940  * FUNCTION:    DtCompilePptt
1941  *
1942  * PARAMETERS:  List                - Current field list pointer
1943  *
1944  * RETURN:      Status
1945  *
1946  * DESCRIPTION: Compile PPTT.
1947  *
1948  *****************************************************************************/
1949 
1950 ACPI_STATUS
1951 DtCompilePptt (
1952     void                    **List)
1953 {
1954     ACPI_STATUS             Status;
1955     ACPI_SUBTABLE_HEADER    *PpttHeader;
1956     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
1957     DT_SUBTABLE             *Subtable;
1958     DT_SUBTABLE             *ParentTable;
1959     ACPI_DMTABLE_INFO       *InfoTable;
1960     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1961     DT_FIELD                *SubtableStart;
1962     ACPI_TABLE_HEADER       *PpttAcpiHeader;
1963 
1964 
1965     ParentTable = DtPeekSubtable ();
1966     while (*PFieldList)
1967     {
1968         SubtableStart = *PFieldList;
1969 
1970         /* Compile PPTT subtable header */
1971 
1972         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1973             &Subtable);
1974         if (ACPI_FAILURE (Status))
1975         {
1976             return (Status);
1977         }
1978         DtInsertSubtable (ParentTable, Subtable);
1979         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1980         PpttHeader->Length = (UINT8)(Subtable->Length);
1981 
1982         switch (PpttHeader->Type)
1983         {
1984         case ACPI_PPTT_TYPE_PROCESSOR:
1985 
1986             InfoTable = AcpiDmTableInfoPptt0;
1987             break;
1988 
1989         case ACPI_PPTT_TYPE_CACHE:
1990 
1991             InfoTable = AcpiDmTableInfoPptt1;
1992             break;
1993 
1994         case ACPI_PPTT_TYPE_ID:
1995 
1996             InfoTable = AcpiDmTableInfoPptt2;
1997             break;
1998 
1999         default:
2000 
2001             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
2002             return (AE_ERROR);
2003         }
2004 
2005         /* Compile PPTT subtable body */
2006 
2007         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2008         if (ACPI_FAILURE (Status))
2009         {
2010             return (Status);
2011         }
2012         DtInsertSubtable (ParentTable, Subtable);
2013         PpttHeader->Length += (UINT8)(Subtable->Length);
2014 
2015         /* Compile PPTT subtable additional */
2016 
2017         switch (PpttHeader->Type)
2018         {
2019         case ACPI_PPTT_TYPE_PROCESSOR:
2020 
2021             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
2022                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
2023             if (PpttProcessor)
2024             {
2025                 /* Compile initiator proximity domain list */
2026 
2027                 PpttProcessor->NumberOfPrivResources = 0;
2028                 while (*PFieldList)
2029                 {
2030                     Status = DtCompileTable (PFieldList,
2031                         AcpiDmTableInfoPptt0a, &Subtable);
2032                     if (ACPI_FAILURE (Status))
2033                     {
2034                         return (Status);
2035                     }
2036                     if (!Subtable)
2037                     {
2038                         break;
2039                     }
2040 
2041                     DtInsertSubtable (ParentTable, Subtable);
2042                     PpttHeader->Length += (UINT8)(Subtable->Length);
2043                     PpttProcessor->NumberOfPrivResources++;
2044                 }
2045             }
2046             break;
2047 
2048         case ACPI_PPTT_TYPE_CACHE:
2049 
2050             PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
2051                 AslGbl_RootTable->Buffer);
2052             if (PpttAcpiHeader->Revision < 3)
2053             {
2054                 break;
2055             }
2056             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
2057                 &Subtable);
2058             DtInsertSubtable (ParentTable, Subtable);
2059             PpttHeader->Length += (UINT8)(Subtable->Length);
2060             break;
2061 
2062         default:
2063 
2064             break;
2065         }
2066     }
2067 
2068     return (AE_OK);
2069 }
2070 
2071 
2072 /******************************************************************************
2073  *
2074  * FUNCTION:    DtCompilePrmt
2075  *
2076  * PARAMETERS:  List                - Current field list pointer
2077  *
2078  * RETURN:      Status
2079  *
2080  * DESCRIPTION: Compile PRMT.
2081  *
2082  *****************************************************************************/
2083 
2084 ACPI_STATUS
2085 DtCompilePrmt (
2086     void                    **List)
2087 {
2088     ACPI_STATUS             Status;
2089     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
2090     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
2091     DT_SUBTABLE             *Subtable;
2092     DT_SUBTABLE             *ParentTable;
2093     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2094     UINT32                  i, j;
2095 
2096     ParentTable = DtPeekSubtable ();
2097 
2098     /* Compile PRMT subtable header */
2099 
2100     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
2101         &Subtable);
2102     if (ACPI_FAILURE (Status))
2103     {
2104         return (Status);
2105     }
2106     DtInsertSubtable (ParentTable, Subtable);
2107     PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
2108 
2109     for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
2110     {
2111         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
2112             &Subtable);
2113         if (ACPI_FAILURE (Status))
2114         {
2115             return (Status);
2116         }
2117         DtInsertSubtable (ParentTable, Subtable);
2118         PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
2119 
2120         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
2121         {
2122             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
2123                 &Subtable);
2124             if (ACPI_FAILURE (Status))
2125             {
2126                 return (Status);
2127             }
2128             DtInsertSubtable (ParentTable, Subtable);
2129         }
2130     }
2131 
2132     return (AE_OK);
2133 }
2134 
2135 
2136 /******************************************************************************
2137  *
2138  * FUNCTION:    DtCompileRgrt
2139  *
2140  * PARAMETERS:  List                - Current field list pointer
2141  *
2142  * RETURN:      Status
2143  *
2144  * DESCRIPTION: Compile RGRT.
2145  *
2146  *****************************************************************************/
2147 
2148 ACPI_STATUS
2149 DtCompileRgrt (
2150     void                    **List)
2151 {
2152     ACPI_STATUS             Status;
2153     DT_SUBTABLE             *Subtable;
2154     DT_SUBTABLE             *ParentTable;
2155     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2156 
2157 
2158     /* Compile the main table */
2159 
2160     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
2161         &Subtable);
2162     if (ACPI_FAILURE (Status))
2163     {
2164         return (Status);
2165     }
2166 
2167     ParentTable = DtPeekSubtable ();
2168     DtInsertSubtable (ParentTable, Subtable);
2169 
2170     /* Compile the "Subtable" -- actually just the binary (PNG) image */
2171 
2172     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
2173         &Subtable);
2174     if (ACPI_FAILURE (Status))
2175     {
2176         return (Status);
2177     }
2178 
2179     DtInsertSubtable (ParentTable, Subtable);
2180     return (AE_OK);
2181 }
2182 
2183 
2184 /******************************************************************************
2185  *
2186  * FUNCTION:    DtCompileRhct
2187  *
2188  * PARAMETERS:  List                - Current field list pointer
2189  *
2190  * RETURN:      Status
2191  *
2192  * DESCRIPTION: Compile RHCT.
2193  *
2194  *****************************************************************************/
2195 
2196 ACPI_STATUS
2197 DtCompileRhct (
2198     void                    **List)
2199 {
2200     ACPI_STATUS             Status;
2201     ACPI_RHCT_NODE_HEADER   *RhctHeader;
2202     ACPI_RHCT_HART_INFO     *RhctHartInfo = NULL;
2203     DT_SUBTABLE             *Subtable;
2204     DT_SUBTABLE             *ParentTable;
2205     ACPI_DMTABLE_INFO       *InfoTable;
2206     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2207     DT_FIELD                *SubtableStart;
2208 
2209 
2210     /* Compile the main table */
2211 
2212     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct,
2213         &Subtable);
2214     if (ACPI_FAILURE (Status))
2215     {
2216         return (Status);
2217     }
2218 
2219     ParentTable = DtPeekSubtable ();
2220     while (*PFieldList)
2221     {
2222         SubtableStart = *PFieldList;
2223 
2224         /* Compile RHCT subtable header */
2225 
2226         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr,
2227             &Subtable);
2228         if (ACPI_FAILURE (Status))
2229         {
2230             return (Status);
2231         }
2232         DtInsertSubtable (ParentTable, Subtable);
2233         RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer);
2234         RhctHeader->Length = (UINT16)(Subtable->Length);
2235 
2236         switch (RhctHeader->Type)
2237         {
2238         case ACPI_RHCT_NODE_TYPE_ISA_STRING:
2239 
2240             InfoTable = AcpiDmTableInfoRhctIsa1;
2241             break;
2242 
2243         case ACPI_RHCT_NODE_TYPE_HART_INFO:
2244 
2245             InfoTable = AcpiDmTableInfoRhctHartInfo1;
2246             break;
2247 
2248         case ACPI_RHCT_NODE_TYPE_CMO:
2249 
2250             InfoTable = AcpiDmTableInfoRhctCmo1;
2251             break;
2252 
2253         case ACPI_RHCT_NODE_TYPE_MMU:
2254 
2255             InfoTable = AcpiDmTableInfoRhctMmu1;
2256             break;
2257 
2258         default:
2259 
2260             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT");
2261             return (AE_ERROR);
2262         }
2263 
2264         /* Compile RHCT subtable body */
2265 
2266         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2267         if (ACPI_FAILURE (Status))
2268         {
2269             return (Status);
2270         }
2271         DtInsertSubtable (ParentTable, Subtable);
2272         RhctHeader->Length += (UINT16)(Subtable->Length);
2273 
2274         /* Compile RHCT subtable additionals */
2275 
2276         switch (RhctHeader->Type)
2277         {
2278         case ACPI_RHCT_NODE_TYPE_HART_INFO:
2279 
2280             RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO,
2281                 Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER));
2282             if (RhctHartInfo)
2283             {
2284 
2285                 RhctHartInfo->NumOffsets = 0;
2286                 while (*PFieldList)
2287                 {
2288                     Status = DtCompileTable (PFieldList,
2289                         AcpiDmTableInfoRhctHartInfo2, &Subtable);
2290                     if (ACPI_FAILURE (Status))
2291                     {
2292                         return (Status);
2293                     }
2294                     if (!Subtable)
2295                     {
2296                         break;
2297                     }
2298 
2299                     DtInsertSubtable (ParentTable, Subtable);
2300                     RhctHeader->Length += (UINT16)(Subtable->Length);
2301                     RhctHartInfo->NumOffsets++;
2302                 }
2303             }
2304             break;
2305 
2306         default:
2307 
2308             break;
2309         }
2310     }
2311 
2312     return (AE_OK);
2313 }
2314 
2315 
2316 /******************************************************************************
2317  *
2318  * FUNCTION:    DtCompileRsdt
2319  *
2320  * PARAMETERS:  List                - Current field list pointer
2321  *
2322  * RETURN:      Status
2323  *
2324  * DESCRIPTION: Compile RSDT.
2325  *
2326  *****************************************************************************/
2327 
2328 ACPI_STATUS
2329 DtCompileRsdt (
2330     void                    **List)
2331 {
2332     DT_SUBTABLE             *Subtable;
2333     DT_SUBTABLE             *ParentTable;
2334     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2335     UINT32                  Address;
2336 
2337 
2338     ParentTable = DtPeekSubtable ();
2339 
2340     while (FieldList)
2341     {
2342         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2343 
2344         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2345         DtInsertSubtable (ParentTable, Subtable);
2346         FieldList = FieldList->Next;
2347     }
2348 
2349     return (AE_OK);
2350 }
2351 
2352 
2353 /******************************************************************************
2354  *
2355  * FUNCTION:    DtCompileS3pt
2356  *
2357  * PARAMETERS:  PFieldList          - Current field list pointer
2358  *
2359  * RETURN:      Status
2360  *
2361  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2362  *
2363  *****************************************************************************/
2364 
2365 ACPI_STATUS
2366 DtCompileS3pt (
2367     DT_FIELD                **PFieldList)
2368 {
2369     ACPI_STATUS             Status;
2370     ACPI_FPDT_HEADER        *S3ptHeader;
2371     DT_SUBTABLE             *Subtable;
2372     DT_SUBTABLE             *ParentTable;
2373     ACPI_DMTABLE_INFO       *InfoTable;
2374     DT_FIELD                *SubtableStart;
2375 
2376 
2377     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2378         &AslGbl_RootTable);
2379     if (ACPI_FAILURE (Status))
2380     {
2381         return (Status);
2382     }
2383 
2384     DtPushSubtable (AslGbl_RootTable);
2385 
2386     while (*PFieldList)
2387     {
2388         SubtableStart = *PFieldList;
2389         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2390             &Subtable);
2391         if (ACPI_FAILURE (Status))
2392         {
2393             return (Status);
2394         }
2395 
2396         ParentTable = DtPeekSubtable ();
2397         DtInsertSubtable (ParentTable, Subtable);
2398         DtPushSubtable (Subtable);
2399 
2400         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
2401 
2402         switch (S3ptHeader->Type)
2403         {
2404         case ACPI_S3PT_TYPE_RESUME:
2405 
2406             InfoTable = AcpiDmTableInfoS3pt0;
2407             break;
2408 
2409         case ACPI_S3PT_TYPE_SUSPEND:
2410 
2411             InfoTable = AcpiDmTableInfoS3pt1;
2412             break;
2413 
2414         default:
2415 
2416             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2417             return (AE_ERROR);
2418         }
2419 
2420         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2421         if (ACPI_FAILURE (Status))
2422         {
2423             return (Status);
2424         }
2425 
2426         ParentTable = DtPeekSubtable ();
2427         DtInsertSubtable (ParentTable, Subtable);
2428         DtPopSubtable ();
2429     }
2430 
2431     return (AE_OK);
2432 }
2433 
2434 
2435 /******************************************************************************
2436  *
2437  * FUNCTION:    DtCompileSdev
2438  *
2439  * PARAMETERS:  List                - Current field list pointer
2440  *
2441  * RETURN:      Status
2442  *
2443  * DESCRIPTION: Compile SDEV.
2444  *
2445  *****************************************************************************/
2446 
2447 ACPI_STATUS
2448 DtCompileSdev (
2449     void                    **List)
2450 {
2451     ACPI_STATUS                 Status;
2452     ACPI_SDEV_HEADER            *SdevHeader;
2453     ACPI_SDEV_HEADER            *SecureComponentHeader;
2454     DT_SUBTABLE                 *Subtable;
2455     DT_SUBTABLE                 *ParentTable;
2456     ACPI_DMTABLE_INFO           *InfoTable;
2457     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
2458     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
2459     DT_FIELD                    *SubtableStart;
2460     ACPI_SDEV_PCIE              *Pcie = NULL;
2461     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
2462     UINT32                      EntryCount;
2463     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
2464     UINT16                      ComponentLength = 0;
2465 
2466 
2467     /* Subtables */
2468 
2469     while (*PFieldList)
2470     {
2471         /* Compile common SDEV subtable header */
2472 
2473         SubtableStart = *PFieldList;
2474         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
2475             &Subtable);
2476         if (ACPI_FAILURE (Status))
2477         {
2478             return (Status);
2479         }
2480 
2481         ParentTable = DtPeekSubtable ();
2482         DtInsertSubtable (ParentTable, Subtable);
2483         DtPushSubtable (Subtable);
2484 
2485         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2486         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
2487 
2488         switch (SdevHeader->Type)
2489         {
2490         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2491 
2492             InfoTable = AcpiDmTableInfoSdev0;
2493             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
2494             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2495                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
2496             break;
2497 
2498         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2499 
2500             InfoTable = AcpiDmTableInfoSdev1;
2501             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
2502             break;
2503 
2504         default:
2505 
2506             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2507             return (AE_ERROR);
2508         }
2509 
2510         /* Compile SDEV subtable body */
2511 
2512         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2513         if (ACPI_FAILURE (Status))
2514         {
2515             return (Status);
2516         }
2517 
2518         ParentTable = DtPeekSubtable ();
2519         DtInsertSubtable (ParentTable, Subtable);
2520 
2521         /* Optional data fields are appended to the main subtable body */
2522 
2523         switch (SdevHeader->Type)
2524         {
2525         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2526 
2527             /*
2528              * Device Id Offset will be be calculated differently depending on
2529              * the presence of secure access components.
2530              */
2531             Namesp->DeviceIdOffset = 0;
2532             ComponentLength = 0;
2533 
2534             /* If the secure access component exists, get the structures */
2535 
2536             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2537             {
2538                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
2539                     &Subtable);
2540                 if (ACPI_FAILURE (Status))
2541                 {
2542                     return (Status);
2543                 }
2544                 ParentTable = DtPeekSubtable ();
2545                 DtInsertSubtable (ParentTable, Subtable);
2546 
2547                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2548 
2549                 /* Compile a secure access component header */
2550 
2551                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
2552                     &Subtable);
2553                 if (ACPI_FAILURE (Status))
2554                 {
2555                     return (Status);
2556                 }
2557                 ParentTable = DtPeekSubtable ();
2558                 DtInsertSubtable (ParentTable, Subtable);
2559 
2560                 /* Compile the secure access component */
2561 
2562                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2563                 switch (SecureComponentHeader->Type)
2564                 {
2565                 case ACPI_SDEV_TYPE_ID_COMPONENT:
2566 
2567                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2568                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
2569                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
2570                     break;
2571 
2572                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2573 
2574                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2575                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
2576                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
2577                     break;
2578 
2579                 default:
2580 
2581                     /* Any other secure component types are undefined */
2582 
2583                     return (AE_ERROR);
2584                 }
2585 
2586                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
2587                     &Subtable);
2588                 if (ACPI_FAILURE (Status))
2589                 {
2590                     return (Status);
2591                 }
2592                 ParentTable = DtPeekSubtable ();
2593                 DtInsertSubtable (ParentTable, Subtable);
2594 
2595                 SecureComponent->SecureComponentOffset =
2596                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
2597                 SecureComponent->SecureComponentLength = ComponentLength;
2598 
2599 
2600                 /*
2601                  * Add the secure component to the subtable to be added for the
2602                  * the namespace subtable's length
2603                  */
2604                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2605             }
2606 
2607             /* Append DeviceId namespace string */
2608 
2609             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
2610                 &Subtable);
2611             if (ACPI_FAILURE (Status))
2612             {
2613                 return (Status);
2614             }
2615 
2616             if (!Subtable)
2617             {
2618                 break;
2619             }
2620 
2621             ParentTable = DtPeekSubtable ();
2622             DtInsertSubtable (ParentTable, Subtable);
2623 
2624             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
2625 
2626             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
2627 
2628             /* Append Vendor data */
2629 
2630             Namesp->VendorDataLength = 0;
2631             Namesp->VendorDataOffset = 0;
2632 
2633             if (*PFieldList)
2634             {
2635                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2636                     &Subtable);
2637                 if (ACPI_FAILURE (Status))
2638                 {
2639                     return (Status);
2640                 }
2641 
2642                 if (Subtable)
2643                 {
2644                     ParentTable = DtPeekSubtable ();
2645                     DtInsertSubtable (ParentTable, Subtable);
2646 
2647                     Namesp->VendorDataOffset =
2648                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2649                     Namesp->VendorDataLength =
2650                         (UINT16) Subtable->Length;
2651 
2652                     /* Final size of entire namespace structure */
2653 
2654                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
2655                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
2656                 }
2657             }
2658 
2659             break;
2660 
2661         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2662 
2663             /* Append the PCIe path info first */
2664 
2665             EntryCount = 0;
2666             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
2667             {
2668                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
2669                     &Subtable);
2670                 if (ACPI_FAILURE (Status))
2671                 {
2672                     return (Status);
2673                 }
2674 
2675                 if (!Subtable)
2676                 {
2677                     DtPopSubtable ();
2678                     break;
2679                 }
2680 
2681                 ParentTable = DtPeekSubtable ();
2682                 DtInsertSubtable (ParentTable, Subtable);
2683                 EntryCount++;
2684             }
2685 
2686             /* Path offset will point immediately after the main subtable */
2687 
2688             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
2689             Pcie->PathLength = (UINT16)
2690                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
2691 
2692             /* Append the Vendor Data last */
2693 
2694             Pcie->VendorDataLength = 0;
2695             Pcie->VendorDataOffset = 0;
2696 
2697             if (*PFieldList)
2698             {
2699                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2700                     &Subtable);
2701                 if (ACPI_FAILURE (Status))
2702                 {
2703                     return (Status);
2704                 }
2705 
2706                 if (Subtable)
2707                 {
2708                     ParentTable = DtPeekSubtable ();
2709                     DtInsertSubtable (ParentTable, Subtable);
2710 
2711                     Pcie->VendorDataOffset =
2712                         Pcie->PathOffset + Pcie->PathLength;
2713                     Pcie->VendorDataLength = (UINT16)
2714                         Subtable->Length;
2715                 }
2716             }
2717 
2718             SdevHeader->Length =
2719                 sizeof (ACPI_SDEV_PCIE) +
2720                 Pcie->PathLength + Pcie->VendorDataLength;
2721             break;
2722 
2723         default:
2724 
2725             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2726             return (AE_ERROR);
2727         }
2728 
2729         DtPopSubtable ();
2730     }
2731 
2732     return (AE_OK);
2733 }
2734 
2735 
2736 /******************************************************************************
2737  *
2738  * FUNCTION:    DtCompileSlic
2739  *
2740  * PARAMETERS:  List                - Current field list pointer
2741  *
2742  * RETURN:      Status
2743  *
2744  * DESCRIPTION: Compile SLIC.
2745  *
2746  *****************************************************************************/
2747 
2748 ACPI_STATUS
2749 DtCompileSlic (
2750     void                    **List)
2751 {
2752     ACPI_STATUS             Status;
2753     DT_SUBTABLE             *Subtable;
2754     DT_SUBTABLE             *ParentTable;
2755     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2756 
2757 
2758     while (*PFieldList)
2759     {
2760         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2761             &Subtable);
2762         if (ACPI_FAILURE (Status))
2763         {
2764             return (Status);
2765         }
2766 
2767         ParentTable = DtPeekSubtable ();
2768         DtInsertSubtable (ParentTable, Subtable);
2769         DtPushSubtable (Subtable);
2770         DtPopSubtable ();
2771     }
2772 
2773     return (AE_OK);
2774 }
2775 
2776 
2777 /******************************************************************************
2778  *
2779  * FUNCTION:    DtCompileSlit
2780  *
2781  * PARAMETERS:  List                - Current field list pointer
2782  *
2783  * RETURN:      Status
2784  *
2785  * DESCRIPTION: Compile SLIT.
2786  *
2787  *****************************************************************************/
2788 
2789 ACPI_STATUS
2790 DtCompileSlit (
2791     void                    **List)
2792 {
2793     ACPI_STATUS             Status;
2794     DT_SUBTABLE             *Subtable;
2795     DT_SUBTABLE             *ParentTable;
2796     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2797     DT_FIELD                *FieldList;
2798     DT_FIELD                *EndOfFieldList = NULL;
2799     UINT32                  Localities;
2800     UINT32                  LocalityListLength;
2801     UINT8                   *LocalityBuffer;
2802 
2803 
2804     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2805         &Subtable);
2806     if (ACPI_FAILURE (Status))
2807     {
2808         return (Status);
2809     }
2810 
2811     ParentTable = DtPeekSubtable ();
2812     DtInsertSubtable (ParentTable, Subtable);
2813 
2814     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2815     LocalityBuffer = UtLocalCalloc (Localities);
2816     LocalityListLength = 0;
2817 
2818     /* Compile each locality buffer */
2819 
2820     FieldList = *PFieldList;
2821     while (FieldList)
2822     {
2823         DtCompileBuffer (LocalityBuffer,
2824             FieldList->Value, FieldList, Localities);
2825 
2826         LocalityListLength++;
2827         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2828         DtInsertSubtable (ParentTable, Subtable);
2829         EndOfFieldList = FieldList;
2830         FieldList = FieldList->Next;
2831     }
2832 
2833     if (LocalityListLength != Localities)
2834     {
2835         sprintf(AslGbl_MsgBuffer,
2836             "Found %u entries, must match LocalityCount: %u",
2837             LocalityListLength, Localities);
2838         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
2839         ACPI_FREE (LocalityBuffer);
2840         return (AE_LIMIT);
2841     }
2842 
2843     ACPI_FREE (LocalityBuffer);
2844     return (AE_OK);
2845 }
2846 
2847 
2848 /******************************************************************************
2849  *
2850  * FUNCTION:    DtCompileSrat
2851  *
2852  * PARAMETERS:  List                - Current field list pointer
2853  *
2854  * RETURN:      Status
2855  *
2856  * DESCRIPTION: Compile SRAT.
2857  *
2858  *****************************************************************************/
2859 
2860 ACPI_STATUS
2861 DtCompileSrat (
2862     void                    **List)
2863 {
2864     ACPI_STATUS             Status;
2865     DT_SUBTABLE             *Subtable;
2866     DT_SUBTABLE             *ParentTable;
2867     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2868     DT_FIELD                *SubtableStart;
2869     ACPI_SUBTABLE_HEADER    *SratHeader;
2870     ACPI_DMTABLE_INFO       *InfoTable;
2871 
2872 
2873     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2874         &Subtable);
2875     if (ACPI_FAILURE (Status))
2876     {
2877         return (Status);
2878     }
2879 
2880     ParentTable = DtPeekSubtable ();
2881     DtInsertSubtable (ParentTable, Subtable);
2882 
2883     while (*PFieldList)
2884     {
2885         SubtableStart = *PFieldList;
2886         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2887             &Subtable);
2888         if (ACPI_FAILURE (Status))
2889         {
2890             return (Status);
2891         }
2892 
2893         ParentTable = DtPeekSubtable ();
2894         DtInsertSubtable (ParentTable, Subtable);
2895         DtPushSubtable (Subtable);
2896 
2897         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2898 
2899         switch (SratHeader->Type)
2900         {
2901         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2902 
2903             InfoTable = AcpiDmTableInfoSrat0;
2904             break;
2905 
2906         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2907 
2908             InfoTable = AcpiDmTableInfoSrat1;
2909             break;
2910 
2911         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2912 
2913             InfoTable = AcpiDmTableInfoSrat2;
2914             break;
2915 
2916         case ACPI_SRAT_TYPE_GICC_AFFINITY:
2917 
2918             InfoTable = AcpiDmTableInfoSrat3;
2919             break;
2920 
2921         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
2922 
2923             InfoTable = AcpiDmTableInfoSrat4;
2924             break;
2925 
2926         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
2927 
2928             InfoTable = AcpiDmTableInfoSrat5;
2929             break;
2930 
2931         case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
2932 
2933             InfoTable = AcpiDmTableInfoSrat6;
2934             break;
2935 
2936         default:
2937 
2938             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2939             return (AE_ERROR);
2940         }
2941 
2942         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2943         if (ACPI_FAILURE (Status))
2944         {
2945             return (Status);
2946         }
2947 
2948         ParentTable = DtPeekSubtable ();
2949         DtInsertSubtable (ParentTable, Subtable);
2950         DtPopSubtable ();
2951     }
2952 
2953     return (AE_OK);
2954 }
2955 
2956 
2957 /******************************************************************************
2958  *
2959  * FUNCTION:    DtCompileStao
2960  *
2961  * PARAMETERS:  PFieldList          - Current field list pointer
2962  *
2963  * RETURN:      Status
2964  *
2965  * DESCRIPTION: Compile STAO.
2966  *
2967  *****************************************************************************/
2968 
2969 ACPI_STATUS
2970 DtCompileStao (
2971     void                    **List)
2972 {
2973     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2974     DT_SUBTABLE             *Subtable;
2975     DT_SUBTABLE             *ParentTable;
2976     ACPI_STATUS             Status;
2977 
2978 
2979     /* Compile the main table */
2980 
2981     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
2982         &Subtable);
2983     if (ACPI_FAILURE (Status))
2984     {
2985         return (Status);
2986     }
2987 
2988     ParentTable = DtPeekSubtable ();
2989     DtInsertSubtable (ParentTable, Subtable);
2990 
2991     /* Compile each ASCII namestring as a subtable */
2992 
2993     while (*PFieldList)
2994     {
2995         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
2996             &Subtable);
2997         if (ACPI_FAILURE (Status))
2998         {
2999             return (Status);
3000         }
3001 
3002         ParentTable = DtPeekSubtable ();
3003         DtInsertSubtable (ParentTable, Subtable);
3004     }
3005 
3006     return (AE_OK);
3007 }
3008 
3009 
3010 /******************************************************************************
3011  *
3012  * FUNCTION:    DtCompileSvkl
3013  *
3014  * PARAMETERS:  PFieldList          - Current field list pointer
3015  *
3016  * RETURN:      Status
3017  *
3018  * DESCRIPTION: Compile SVKL.
3019  *
3020  * NOTES: SVKL is essentially a flat table, with a small main table and
3021  *          a variable number of a single type of subtable.
3022  *
3023  *****************************************************************************/
3024 
3025 ACPI_STATUS
3026 DtCompileSvkl (
3027     void                    **List)
3028 {
3029     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3030     DT_SUBTABLE             *Subtable;
3031     DT_SUBTABLE             *ParentTable;
3032     ACPI_STATUS             Status;
3033 
3034 
3035     /* Compile the main table */
3036 
3037     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
3038         &Subtable);
3039     if (ACPI_FAILURE (Status))
3040     {
3041         return (Status);
3042     }
3043 
3044     ParentTable = DtPeekSubtable ();
3045     DtInsertSubtable (ParentTable, Subtable);
3046 
3047     /* Compile each subtable */
3048 
3049     while (*PFieldList)
3050     {
3051         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
3052             &Subtable);
3053         if (ACPI_FAILURE (Status))
3054         {
3055             return (Status);
3056         }
3057 
3058         ParentTable = DtPeekSubtable ();
3059         DtInsertSubtable (ParentTable, Subtable);
3060     }
3061 
3062     return (AE_OK);
3063 }
3064 
3065 
3066 /******************************************************************************
3067  *
3068  * FUNCTION:    DtCompileTcpa
3069  *
3070  * PARAMETERS:  PFieldList          - Current field list pointer
3071  *
3072  * RETURN:      Status
3073  *
3074  * DESCRIPTION: Compile TCPA.
3075  *
3076  *****************************************************************************/
3077 
3078 ACPI_STATUS
3079 DtCompileTcpa (
3080     void                    **List)
3081 {
3082     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3083     DT_SUBTABLE             *Subtable;
3084     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
3085     DT_SUBTABLE             *ParentTable;
3086     ACPI_STATUS             Status;
3087 
3088 
3089     /* Compile the main table */
3090 
3091     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
3092         &Subtable);
3093     if (ACPI_FAILURE (Status))
3094     {
3095         return (Status);
3096     }
3097 
3098     ParentTable = DtPeekSubtable ();
3099     DtInsertSubtable (ParentTable, Subtable);
3100 
3101     /*
3102      * Examine the PlatformClass field to determine the table type.
3103      * Either a client or server table. Only one.
3104      */
3105     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
3106 
3107     switch (TcpaHeader->PlatformClass)
3108     {
3109     case ACPI_TCPA_CLIENT_TABLE:
3110 
3111         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
3112             &Subtable);
3113         break;
3114 
3115     case ACPI_TCPA_SERVER_TABLE:
3116 
3117         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
3118             &Subtable);
3119         break;
3120 
3121     default:
3122 
3123         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
3124             TcpaHeader->PlatformClass);
3125         Status = AE_ERROR;
3126         break;
3127     }
3128 
3129     ParentTable = DtPeekSubtable ();
3130     DtInsertSubtable (ParentTable, Subtable);
3131     return (Status);
3132 }
3133 
3134 
3135 /******************************************************************************
3136  *
3137  * FUNCTION:    DtCompileTpm2Rev3
3138  *
3139  * PARAMETERS:  PFieldList          - Current field list pointer
3140  *
3141  * RETURN:      Status
3142  *
3143  * DESCRIPTION: Compile TPM2 revision 3
3144  *
3145  *****************************************************************************/
3146 static ACPI_STATUS
3147 DtCompileTpm2Rev3 (
3148     void                    **List)
3149 {
3150     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3151     DT_SUBTABLE             *Subtable;
3152     ACPI_TABLE_TPM23        *Tpm23Header;
3153     DT_SUBTABLE             *ParentTable;
3154     ACPI_STATUS             Status = AE_OK;
3155 
3156 
3157     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
3158         &Subtable);
3159 
3160     ParentTable = DtPeekSubtable ();
3161     DtInsertSubtable (ParentTable, Subtable);
3162     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
3163 
3164     /* Subtable type depends on the StartMethod */
3165 
3166     switch (Tpm23Header->StartMethod)
3167     {
3168     case ACPI_TPM23_ACPI_START_METHOD:
3169 
3170         /* Subtable specific to to ARM_SMC */
3171 
3172         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
3173             &Subtable);
3174         if (ACPI_FAILURE (Status))
3175         {
3176             return (Status);
3177         }
3178 
3179         ParentTable = DtPeekSubtable ();
3180         DtInsertSubtable (ParentTable, Subtable);
3181         break;
3182 
3183     default:
3184         break;
3185     }
3186 
3187     return (Status);
3188 }
3189 
3190 
3191 /******************************************************************************
3192  *
3193  * FUNCTION:    DtCompileTpm2
3194  *
3195  * PARAMETERS:  PFieldList          - Current field list pointer
3196  *
3197  * RETURN:      Status
3198  *
3199  * DESCRIPTION: Compile TPM2.
3200  *
3201  *****************************************************************************/
3202 
3203 ACPI_STATUS
3204 DtCompileTpm2 (
3205     void                    **List)
3206 {
3207     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3208     DT_SUBTABLE             *Subtable;
3209     ACPI_TABLE_TPM2         *Tpm2Header;
3210     DT_SUBTABLE             *ParentTable;
3211     ACPI_STATUS             Status = AE_OK;
3212     ACPI_TABLE_HEADER       *Header;
3213 
3214 
3215     ParentTable = DtPeekSubtable ();
3216 
3217     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
3218 
3219     if (Header->Revision == 3)
3220     {
3221         return (DtCompileTpm2Rev3 (List));
3222     }
3223 
3224     /* Compile the main table */
3225 
3226     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
3227         &Subtable);
3228     if (ACPI_FAILURE (Status))
3229     {
3230         return (Status);
3231     }
3232 
3233     ParentTable = DtPeekSubtable ();
3234     DtInsertSubtable (ParentTable, Subtable);
3235 
3236     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
3237 
3238     /* Method parameters */
3239     /* Optional: Log area minimum length */
3240     /* Optional: Log area start address */
3241     /* TBD: Optional fields above not fully implemented (not optional at this time) */
3242 
3243     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
3244         &Subtable);
3245     if (ACPI_FAILURE (Status))
3246     {
3247         return (Status);
3248     }
3249 
3250     ParentTable = DtPeekSubtable ();
3251     DtInsertSubtable (ParentTable, Subtable);
3252 
3253 
3254     /* Subtable type depends on the StartMethod */
3255 
3256     switch (Tpm2Header->StartMethod)
3257     {
3258     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
3259 
3260         /* Subtable specific to to ARM_SMC */
3261 
3262         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
3263             &Subtable);
3264         if (ACPI_FAILURE (Status))
3265         {
3266             return (Status);
3267         }
3268 
3269         ParentTable = DtPeekSubtable ();
3270         DtInsertSubtable (ParentTable, Subtable);
3271         break;
3272 
3273     case ACPI_TPM2_START_METHOD:
3274     case ACPI_TPM2_MEMORY_MAPPED:
3275     case ACPI_TPM2_COMMAND_BUFFER:
3276     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
3277         break;
3278 
3279     case ACPI_TPM2_RESERVED1:
3280     case ACPI_TPM2_RESERVED3:
3281     case ACPI_TPM2_RESERVED4:
3282     case ACPI_TPM2_RESERVED5:
3283     case ACPI_TPM2_RESERVED9:
3284     case ACPI_TPM2_RESERVED10:
3285 
3286         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
3287             Tpm2Header->StartMethod);
3288         Status = AE_ERROR;
3289         break;
3290 
3291     case ACPI_TPM2_NOT_ALLOWED:
3292     default:
3293 
3294         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
3295             Tpm2Header->StartMethod);
3296         Status = AE_ERROR;
3297         break;
3298     }
3299 
3300     return (Status);
3301 }
3302 
3303 
3304 /******************************************************************************
3305  *
3306  * FUNCTION:    DtGetGenericTableInfo
3307  *
3308  * PARAMETERS:  Name                - Generic type name
3309  *
3310  * RETURN:      Info entry
3311  *
3312  * DESCRIPTION: Obtain table info for a generic name entry
3313  *
3314  *****************************************************************************/
3315 
3316 ACPI_DMTABLE_INFO *
3317 DtGetGenericTableInfo (
3318     char                    *Name)
3319 {
3320     ACPI_DMTABLE_INFO       *Info;
3321     UINT32                  i;
3322 
3323 
3324     if (!Name)
3325     {
3326         return (NULL);
3327     }
3328 
3329     /* Search info table for name match */
3330 
3331     for (i = 0; ; i++)
3332     {
3333         Info = AcpiDmTableInfoGeneric[i];
3334         if (Info->Opcode == ACPI_DMT_EXIT)
3335         {
3336             Info = NULL;
3337             break;
3338         }
3339 
3340         /* Use caseless compare for generic keywords */
3341 
3342         if (!AcpiUtStricmp (Name, Info->Name))
3343         {
3344             break;
3345         }
3346     }
3347 
3348     return (Info);
3349 }
3350 
3351 
3352 /******************************************************************************
3353  *
3354  * FUNCTION:    DtCompileUefi
3355  *
3356  * PARAMETERS:  List                - Current field list pointer
3357  *
3358  * RETURN:      Status
3359  *
3360  * DESCRIPTION: Compile UEFI.
3361  *
3362  *****************************************************************************/
3363 
3364 ACPI_STATUS
3365 DtCompileUefi (
3366     void                    **List)
3367 {
3368     ACPI_STATUS             Status;
3369     DT_SUBTABLE             *Subtable;
3370     DT_SUBTABLE             *ParentTable;
3371     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3372     UINT16                  *DataOffset;
3373 
3374 
3375     /* Compile the predefined portion of the UEFI table */
3376 
3377     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
3378         &Subtable);
3379     if (ACPI_FAILURE (Status))
3380     {
3381         return (Status);
3382     }
3383 
3384     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
3385     *DataOffset = sizeof (ACPI_TABLE_UEFI);
3386 
3387     ParentTable = DtPeekSubtable ();
3388     DtInsertSubtable (ParentTable, Subtable);
3389 
3390     /*
3391      * Compile the "generic" portion of the UEFI table. This
3392      * part of the table is not predefined and any of the generic
3393      * operators may be used.
3394      */
3395     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
3396     return (AE_OK);
3397 }
3398 
3399 
3400 /******************************************************************************
3401  *
3402  * FUNCTION:    DtCompileViot
3403  *
3404  * PARAMETERS:  List                - Current field list pointer
3405  *
3406  * RETURN:      Status
3407  *
3408  * DESCRIPTION: Compile VIOT.
3409  *
3410  *****************************************************************************/
3411 
3412 ACPI_STATUS
3413 DtCompileViot (
3414     void                    **List)
3415 {
3416     ACPI_STATUS             Status;
3417     DT_SUBTABLE             *Subtable;
3418     DT_SUBTABLE             *ParentTable;
3419     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3420     DT_FIELD                *SubtableStart;
3421     ACPI_TABLE_VIOT         *Viot;
3422     ACPI_VIOT_HEADER        *ViotHeader;
3423     ACPI_DMTABLE_INFO       *InfoTable;
3424     UINT16                  NodeCount;
3425 
3426     ParentTable = DtPeekSubtable ();
3427 
3428     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
3429     if (ACPI_FAILURE (Status))
3430     {
3431         return (Status);
3432     }
3433     DtInsertSubtable (ParentTable, Subtable);
3434 
3435     /*
3436      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
3437      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
3438      */
3439     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
3440         sizeof (ACPI_TABLE_HEADER));
3441 
3442     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
3443 
3444     NodeCount = 0;
3445     while (*PFieldList) {
3446         SubtableStart = *PFieldList;
3447         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
3448             &Subtable);
3449         if (ACPI_FAILURE (Status))
3450         {
3451             return (Status);
3452         }
3453 
3454         ParentTable = DtPeekSubtable ();
3455         DtInsertSubtable (ParentTable, Subtable);
3456         DtPushSubtable (Subtable);
3457 
3458         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
3459 
3460         switch (ViotHeader->Type)
3461         {
3462         case ACPI_VIOT_NODE_PCI_RANGE:
3463 
3464             InfoTable = AcpiDmTableInfoViot1;
3465             break;
3466 
3467         case ACPI_VIOT_NODE_MMIO:
3468 
3469             InfoTable = AcpiDmTableInfoViot2;
3470             break;
3471 
3472         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
3473 
3474             InfoTable = AcpiDmTableInfoViot3;
3475             break;
3476 
3477         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
3478 
3479             InfoTable = AcpiDmTableInfoViot4;
3480             break;
3481 
3482         default:
3483 
3484             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
3485             return (AE_ERROR);
3486         }
3487 
3488         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
3489         if (ACPI_FAILURE (Status))
3490         {
3491             return (Status);
3492         }
3493 
3494         ParentTable = DtPeekSubtable ();
3495         DtInsertSubtable (ParentTable, Subtable);
3496         DtPopSubtable ();
3497         NodeCount++;
3498     }
3499 
3500     Viot->NodeCount = NodeCount;
3501     return (AE_OK);
3502 }
3503 
3504 
3505 /******************************************************************************
3506  *
3507  * FUNCTION:    DtCompileWdat
3508  *
3509  * PARAMETERS:  List                - Current field list pointer
3510  *
3511  * RETURN:      Status
3512  *
3513  * DESCRIPTION: Compile WDAT.
3514  *
3515  *****************************************************************************/
3516 
3517 ACPI_STATUS
3518 DtCompileWdat (
3519     void                    **List)
3520 {
3521     ACPI_STATUS             Status;
3522 
3523 
3524     Status = DtCompileTwoSubtables (List,
3525         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3526     return (Status);
3527 }
3528 
3529 
3530 /******************************************************************************
3531  *
3532  * FUNCTION:    DtCompileWpbt
3533  *
3534  * PARAMETERS:  List                - Current field list pointer
3535  *
3536  * RETURN:      Status
3537  *
3538  * DESCRIPTION: Compile WPBT.
3539  *
3540  *****************************************************************************/
3541 
3542 ACPI_STATUS
3543 DtCompileWpbt (
3544     void                    **List)
3545 {
3546     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3547     DT_SUBTABLE             *Subtable;
3548     DT_SUBTABLE             *ParentTable;
3549     ACPI_TABLE_WPBT         *Table;
3550     ACPI_STATUS             Status;
3551 
3552 
3553     /* Compile the main table */
3554 
3555     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
3556     if (ACPI_FAILURE (Status))
3557     {
3558         return (Status);
3559     }
3560 
3561     ParentTable = DtPeekSubtable ();
3562     DtInsertSubtable (ParentTable, Subtable);
3563     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3564 
3565     /*
3566      * Exit now if there are no arguments specified. This is indicated by:
3567      * The "Command-line Arguments" field has not been specified (if specified,
3568      * it will be the last field in the field list -- after the main table).
3569      * Set the Argument Length in the main table to zero.
3570      */
3571     if (!*PFieldList)
3572     {
3573         Table->ArgumentsLength = 0;
3574         return (AE_OK);
3575     }
3576 
3577     /* Compile the argument list subtable */
3578 
3579     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
3580     if (ACPI_FAILURE (Status))
3581     {
3582         return (Status);
3583     }
3584 
3585     /* Extract the length of the Arguments buffer, insert into main table */
3586 
3587     Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
3588     DtInsertSubtable (ParentTable, Subtable);
3589     return (AE_OK);
3590 }
3591 
3592 
3593 /******************************************************************************
3594  *
3595  * FUNCTION:    DtCompileXsdt
3596  *
3597  * PARAMETERS:  List                - Current field list pointer
3598  *
3599  * RETURN:      Status
3600  *
3601  * DESCRIPTION: Compile XSDT.
3602  *
3603  *****************************************************************************/
3604 
3605 ACPI_STATUS
3606 DtCompileXsdt (
3607     void                    **List)
3608 {
3609     DT_SUBTABLE             *Subtable;
3610     DT_SUBTABLE             *ParentTable;
3611     DT_FIELD                *FieldList = *(DT_FIELD **) List;
3612     UINT64                  Address;
3613 
3614 
3615     ParentTable = DtPeekSubtable ();
3616 
3617     while (FieldList)
3618     {
3619         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3620 
3621         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3622         DtInsertSubtable (ParentTable, Subtable);
3623         FieldList = FieldList->Next;
3624     }
3625 
3626     return (AE_OK);
3627 }
3628 
3629 
3630 /******************************************************************************
3631  *
3632  * FUNCTION:    DtCompileGeneric
3633  *
3634  * PARAMETERS:  List                - Current field list pointer
3635  *              Name                - Field name to end generic compiling
3636  *              Length              - Compiled table length to return
3637  *
3638  * RETURN:      Status
3639  *
3640  * DESCRIPTION: Compile generic unknown table.
3641  *
3642  *****************************************************************************/
3643 
3644 ACPI_STATUS
3645 DtCompileGeneric (
3646     void                    **List,
3647     char                    *Name,
3648     UINT32                  *Length)
3649 {
3650     ACPI_STATUS             Status;
3651     DT_SUBTABLE             *Subtable;
3652     DT_SUBTABLE             *ParentTable;
3653     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3654     ACPI_DMTABLE_INFO       *Info;
3655 
3656 
3657     ParentTable = DtPeekSubtable ();
3658 
3659     /*
3660      * Compile the "generic" portion of the table. This
3661      * part of the table is not predefined and any of the generic
3662      * operators may be used.
3663      */
3664 
3665     /* Find any and all labels in the entire generic portion */
3666 
3667     DtDetectAllLabels (*PFieldList);
3668 
3669     /* Now we can actually compile the parse tree */
3670 
3671     if (Length && *Length)
3672     {
3673         *Length = 0;
3674     }
3675     while (*PFieldList)
3676     {
3677         if (Name && !strcmp ((*PFieldList)->Name, Name))
3678         {
3679             break;
3680         }
3681 
3682         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3683         if (!Info)
3684         {
3685             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3686                 (*PFieldList)->Name);
3687             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3688                 (*PFieldList), AslGbl_MsgBuffer);
3689 
3690             *PFieldList = (*PFieldList)->Next;
3691             continue;
3692         }
3693 
3694         Status = DtCompileTable (PFieldList, Info,
3695             &Subtable);
3696         if (ACPI_SUCCESS (Status))
3697         {
3698             DtInsertSubtable (ParentTable, Subtable);
3699             if (Length)
3700             {
3701                 *Length += Subtable->Length;
3702             }
3703         }
3704         else
3705         {
3706             *PFieldList = (*PFieldList)->Next;
3707 
3708             if (Status == AE_NOT_FOUND)
3709             {
3710                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3711                     (*PFieldList)->Name);
3712                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3713                     (*PFieldList), AslGbl_MsgBuffer);
3714             }
3715         }
3716     }
3717 
3718     return (AE_OK);
3719 }
3720