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