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