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