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