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