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