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