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