xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable2.c (revision 58308fadece25ae4c12bd2f4dce3d73d9c23be43)
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 = NULL;
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 
1939 
1940     /* Compile the main table */
1941 
1942     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct,
1943         &Subtable);
1944     if (ACPI_FAILURE (Status))
1945     {
1946         return (Status);
1947     }
1948 
1949     ParentTable = DtPeekSubtable ();
1950     while (*PFieldList)
1951     {
1952         SubtableStart = *PFieldList;
1953 
1954         /* Compile RHCT subtable header */
1955 
1956         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr,
1957             &Subtable);
1958         if (ACPI_FAILURE (Status))
1959         {
1960             return (Status);
1961         }
1962         DtInsertSubtable (ParentTable, Subtable);
1963         RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer);
1964         RhctHeader->Length = (UINT16)(Subtable->Length);
1965 
1966         switch (RhctHeader->Type)
1967         {
1968         case ACPI_RHCT_NODE_TYPE_ISA_STRING:
1969 
1970             InfoTable = AcpiDmTableInfoRhctIsa1;
1971             break;
1972 
1973         case ACPI_RHCT_NODE_TYPE_HART_INFO:
1974 
1975             InfoTable = AcpiDmTableInfoRhctHartInfo1;
1976             break;
1977 
1978         case ACPI_RHCT_NODE_TYPE_CMO:
1979 
1980             InfoTable = AcpiDmTableInfoRhctCmo1;
1981             break;
1982 
1983         case ACPI_RHCT_NODE_TYPE_MMU:
1984 
1985             InfoTable = AcpiDmTableInfoRhctMmu1;
1986             break;
1987 
1988         default:
1989 
1990             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT");
1991             return (AE_ERROR);
1992         }
1993 
1994         /* Compile RHCT subtable body */
1995 
1996         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1997         if (ACPI_FAILURE (Status))
1998         {
1999             return (Status);
2000         }
2001         DtInsertSubtable (ParentTable, Subtable);
2002         RhctHeader->Length += (UINT16)(Subtable->Length);
2003 
2004         /* Compile RHCT subtable additionals */
2005 
2006         switch (RhctHeader->Type)
2007         {
2008         case ACPI_RHCT_NODE_TYPE_HART_INFO:
2009 
2010             RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO,
2011                 Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER));
2012             if (RhctHartInfo)
2013             {
2014 
2015                 RhctHartInfo->NumOffsets = 0;
2016                 while (*PFieldList)
2017                 {
2018                     Status = DtCompileTable (PFieldList,
2019                         AcpiDmTableInfoRhctHartInfo2, &Subtable);
2020                     if (ACPI_FAILURE (Status))
2021                     {
2022                         return (Status);
2023                     }
2024                     if (!Subtable)
2025                     {
2026                         break;
2027                     }
2028 
2029                     DtInsertSubtable (ParentTable, Subtable);
2030                     RhctHeader->Length += (UINT16)(Subtable->Length);
2031                     RhctHartInfo->NumOffsets++;
2032                 }
2033             }
2034             break;
2035 
2036         default:
2037 
2038             break;
2039         }
2040     }
2041 
2042     return (AE_OK);
2043 }
2044 
2045 
2046 /******************************************************************************
2047  *
2048  * FUNCTION:    DtCompileRsdt
2049  *
2050  * PARAMETERS:  List                - Current field list pointer
2051  *
2052  * RETURN:      Status
2053  *
2054  * DESCRIPTION: Compile RSDT.
2055  *
2056  *****************************************************************************/
2057 
2058 ACPI_STATUS
DtCompileRsdt(void ** List)2059 DtCompileRsdt (
2060     void                    **List)
2061 {
2062     DT_SUBTABLE             *Subtable;
2063     DT_SUBTABLE             *ParentTable;
2064     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2065     UINT32                  Address;
2066 
2067 
2068     ParentTable = DtPeekSubtable ();
2069 
2070     while (FieldList)
2071     {
2072         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2073 
2074         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2075         DtInsertSubtable (ParentTable, Subtable);
2076         FieldList = FieldList->Next;
2077     }
2078 
2079     return (AE_OK);
2080 }
2081 
2082 
2083 /******************************************************************************
2084  *
2085  * FUNCTION:    DtCompileS3pt
2086  *
2087  * PARAMETERS:  PFieldList          - Current field list pointer
2088  *
2089  * RETURN:      Status
2090  *
2091  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2092  *
2093  *****************************************************************************/
2094 
2095 ACPI_STATUS
DtCompileS3pt(DT_FIELD ** PFieldList)2096 DtCompileS3pt (
2097     DT_FIELD                **PFieldList)
2098 {
2099     ACPI_STATUS             Status;
2100     ACPI_FPDT_HEADER        *S3ptHeader;
2101     DT_SUBTABLE             *Subtable;
2102     DT_SUBTABLE             *ParentTable;
2103     ACPI_DMTABLE_INFO       *InfoTable;
2104     DT_FIELD                *SubtableStart;
2105 
2106 
2107     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2108         &AslGbl_RootTable);
2109     if (ACPI_FAILURE (Status))
2110     {
2111         return (Status);
2112     }
2113 
2114     DtPushSubtable (AslGbl_RootTable);
2115 
2116     while (*PFieldList)
2117     {
2118         SubtableStart = *PFieldList;
2119         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2120             &Subtable);
2121         if (ACPI_FAILURE (Status))
2122         {
2123             return (Status);
2124         }
2125 
2126         ParentTable = DtPeekSubtable ();
2127         DtInsertSubtable (ParentTable, Subtable);
2128         DtPushSubtable (Subtable);
2129 
2130         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
2131 
2132         switch (S3ptHeader->Type)
2133         {
2134         case ACPI_S3PT_TYPE_RESUME:
2135 
2136             InfoTable = AcpiDmTableInfoS3pt0;
2137             break;
2138 
2139         case ACPI_S3PT_TYPE_SUSPEND:
2140 
2141             InfoTable = AcpiDmTableInfoS3pt1;
2142             break;
2143 
2144         default:
2145 
2146             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2147             return (AE_ERROR);
2148         }
2149 
2150         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2151         if (ACPI_FAILURE (Status))
2152         {
2153             return (Status);
2154         }
2155 
2156         ParentTable = DtPeekSubtable ();
2157         DtInsertSubtable (ParentTable, Subtable);
2158         DtPopSubtable ();
2159     }
2160 
2161     return (AE_OK);
2162 }
2163 
2164 
2165 /******************************************************************************
2166  *
2167  * FUNCTION:    DtCompileSdev
2168  *
2169  * PARAMETERS:  List                - Current field list pointer
2170  *
2171  * RETURN:      Status
2172  *
2173  * DESCRIPTION: Compile SDEV.
2174  *
2175  *****************************************************************************/
2176 
2177 ACPI_STATUS
DtCompileSdev(void ** List)2178 DtCompileSdev (
2179     void                    **List)
2180 {
2181     ACPI_STATUS                 Status;
2182     ACPI_SDEV_HEADER            *SdevHeader;
2183     ACPI_SDEV_HEADER            *SecureComponentHeader;
2184     DT_SUBTABLE                 *Subtable;
2185     DT_SUBTABLE                 *ParentTable;
2186     ACPI_DMTABLE_INFO           *InfoTable;
2187     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
2188     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
2189     DT_FIELD                    *SubtableStart;
2190     ACPI_SDEV_PCIE              *Pcie = NULL;
2191     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
2192     UINT32                      EntryCount;
2193     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
2194     UINT16                      ComponentLength = 0;
2195 
2196 
2197     /* Subtables */
2198 
2199     while (*PFieldList)
2200     {
2201         /* Compile common SDEV subtable header */
2202 
2203         SubtableStart = *PFieldList;
2204         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
2205             &Subtable);
2206         if (ACPI_FAILURE (Status))
2207         {
2208             return (Status);
2209         }
2210 
2211         ParentTable = DtPeekSubtable ();
2212         DtInsertSubtable (ParentTable, Subtable);
2213         DtPushSubtable (Subtable);
2214 
2215         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2216         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
2217 
2218         switch (SdevHeader->Type)
2219         {
2220         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2221 
2222             InfoTable = AcpiDmTableInfoSdev0;
2223             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
2224             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2225                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
2226             break;
2227 
2228         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2229 
2230             InfoTable = AcpiDmTableInfoSdev1;
2231             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
2232             break;
2233 
2234         default:
2235 
2236             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2237             return (AE_ERROR);
2238         }
2239 
2240         /* Compile SDEV subtable body */
2241 
2242         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2243         if (ACPI_FAILURE (Status))
2244         {
2245             return (Status);
2246         }
2247 
2248         ParentTable = DtPeekSubtable ();
2249         DtInsertSubtable (ParentTable, Subtable);
2250 
2251         /* Optional data fields are appended to the main subtable body */
2252 
2253         switch (SdevHeader->Type)
2254         {
2255         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2256 
2257             /*
2258              * Device Id Offset will be be calculated differently depending on
2259              * the presence of secure access components.
2260              */
2261             Namesp->DeviceIdOffset = 0;
2262             ComponentLength = 0;
2263 
2264             /* If the secure access component exists, get the structures */
2265 
2266             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2267             {
2268                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
2269                     &Subtable);
2270                 if (ACPI_FAILURE (Status))
2271                 {
2272                     return (Status);
2273                 }
2274                 ParentTable = DtPeekSubtable ();
2275                 DtInsertSubtable (ParentTable, Subtable);
2276 
2277                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2278 
2279                 /* Compile a secure access component header */
2280 
2281                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
2282                     &Subtable);
2283                 if (ACPI_FAILURE (Status))
2284                 {
2285                     return (Status);
2286                 }
2287                 ParentTable = DtPeekSubtable ();
2288                 DtInsertSubtable (ParentTable, Subtable);
2289 
2290                 /* Compile the secure access component */
2291 
2292                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2293                 switch (SecureComponentHeader->Type)
2294                 {
2295                 case ACPI_SDEV_TYPE_ID_COMPONENT:
2296 
2297                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2298                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
2299                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
2300                     break;
2301 
2302                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2303 
2304                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2305                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
2306                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
2307                     break;
2308 
2309                 default:
2310 
2311                     /* Any other secure component types are undefined */
2312 
2313                     return (AE_ERROR);
2314                 }
2315 
2316                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
2317                     &Subtable);
2318                 if (ACPI_FAILURE (Status))
2319                 {
2320                     return (Status);
2321                 }
2322                 ParentTable = DtPeekSubtable ();
2323                 DtInsertSubtable (ParentTable, Subtable);
2324 
2325                 SecureComponent->SecureComponentOffset =
2326                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
2327                 SecureComponent->SecureComponentLength = ComponentLength;
2328 
2329 
2330                 /*
2331                  * Add the secure component to the subtable to be added for the
2332                  * the namespace subtable's length
2333                  */
2334                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2335             }
2336 
2337             /* Append DeviceId namespace string */
2338 
2339             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
2340                 &Subtable);
2341             if (ACPI_FAILURE (Status))
2342             {
2343                 return (Status);
2344             }
2345 
2346             if (!Subtable)
2347             {
2348                 break;
2349             }
2350 
2351             ParentTable = DtPeekSubtable ();
2352             DtInsertSubtable (ParentTable, Subtable);
2353 
2354             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
2355 
2356             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
2357 
2358             /* Append Vendor data */
2359 
2360             Namesp->VendorDataLength = 0;
2361             Namesp->VendorDataOffset = 0;
2362 
2363             if (*PFieldList)
2364             {
2365                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2366                     &Subtable);
2367                 if (ACPI_FAILURE (Status))
2368                 {
2369                     return (Status);
2370                 }
2371 
2372                 if (Subtable)
2373                 {
2374                     ParentTable = DtPeekSubtable ();
2375                     DtInsertSubtable (ParentTable, Subtable);
2376 
2377                     Namesp->VendorDataOffset =
2378                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2379                     Namesp->VendorDataLength =
2380                         (UINT16) Subtable->Length;
2381 
2382                     /* Final size of entire namespace structure */
2383 
2384                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
2385                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
2386                 }
2387             }
2388 
2389             break;
2390 
2391         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2392 
2393             /* Append the PCIe path info first */
2394 
2395             EntryCount = 0;
2396             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
2397             {
2398                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
2399                     &Subtable);
2400                 if (ACPI_FAILURE (Status))
2401                 {
2402                     return (Status);
2403                 }
2404 
2405                 if (!Subtable)
2406                 {
2407                     DtPopSubtable ();
2408                     break;
2409                 }
2410 
2411                 ParentTable = DtPeekSubtable ();
2412                 DtInsertSubtable (ParentTable, Subtable);
2413                 EntryCount++;
2414             }
2415 
2416             /* Path offset will point immediately after the main subtable */
2417 
2418             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
2419             Pcie->PathLength = (UINT16)
2420                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
2421 
2422             /* Append the Vendor Data last */
2423 
2424             Pcie->VendorDataLength = 0;
2425             Pcie->VendorDataOffset = 0;
2426 
2427             if (*PFieldList)
2428             {
2429                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2430                     &Subtable);
2431                 if (ACPI_FAILURE (Status))
2432                 {
2433                     return (Status);
2434                 }
2435 
2436                 if (Subtable)
2437                 {
2438                     ParentTable = DtPeekSubtable ();
2439                     DtInsertSubtable (ParentTable, Subtable);
2440 
2441                     Pcie->VendorDataOffset =
2442                         Pcie->PathOffset + Pcie->PathLength;
2443                     Pcie->VendorDataLength = (UINT16)
2444                         Subtable->Length;
2445                 }
2446             }
2447 
2448             SdevHeader->Length =
2449                 sizeof (ACPI_SDEV_PCIE) +
2450                 Pcie->PathLength + Pcie->VendorDataLength;
2451             break;
2452 
2453         default:
2454 
2455             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2456             return (AE_ERROR);
2457         }
2458 
2459         DtPopSubtable ();
2460     }
2461 
2462     return (AE_OK);
2463 }
2464 
2465 
2466 /******************************************************************************
2467  *
2468  * FUNCTION:    DtCompileSlic
2469  *
2470  * PARAMETERS:  List                - Current field list pointer
2471  *
2472  * RETURN:      Status
2473  *
2474  * DESCRIPTION: Compile SLIC.
2475  *
2476  *****************************************************************************/
2477 
2478 ACPI_STATUS
DtCompileSlic(void ** List)2479 DtCompileSlic (
2480     void                    **List)
2481 {
2482     ACPI_STATUS             Status;
2483     DT_SUBTABLE             *Subtable;
2484     DT_SUBTABLE             *ParentTable;
2485     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2486 
2487 
2488     while (*PFieldList)
2489     {
2490         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2491             &Subtable);
2492         if (ACPI_FAILURE (Status))
2493         {
2494             return (Status);
2495         }
2496 
2497         ParentTable = DtPeekSubtable ();
2498         DtInsertSubtable (ParentTable, Subtable);
2499         DtPushSubtable (Subtable);
2500         DtPopSubtable ();
2501     }
2502 
2503     return (AE_OK);
2504 }
2505 
2506 
2507 /******************************************************************************
2508  *
2509  * FUNCTION:    DtCompileSlit
2510  *
2511  * PARAMETERS:  List                - Current field list pointer
2512  *
2513  * RETURN:      Status
2514  *
2515  * DESCRIPTION: Compile SLIT.
2516  *
2517  *****************************************************************************/
2518 
2519 ACPI_STATUS
DtCompileSlit(void ** List)2520 DtCompileSlit (
2521     void                    **List)
2522 {
2523     ACPI_STATUS             Status;
2524     DT_SUBTABLE             *Subtable;
2525     DT_SUBTABLE             *ParentTable;
2526     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2527     DT_FIELD                *FieldList;
2528     DT_FIELD                *EndOfFieldList = NULL;
2529     UINT32                  Localities;
2530     UINT32                  LocalityListLength;
2531     UINT8                   *LocalityBuffer;
2532 
2533 
2534     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2535         &Subtable);
2536     if (ACPI_FAILURE (Status))
2537     {
2538         return (Status);
2539     }
2540 
2541     ParentTable = DtPeekSubtable ();
2542     DtInsertSubtable (ParentTable, Subtable);
2543 
2544     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2545     LocalityBuffer = UtLocalCalloc (Localities);
2546     LocalityListLength = 0;
2547 
2548     /* Compile each locality buffer */
2549 
2550     FieldList = *PFieldList;
2551     while (FieldList)
2552     {
2553         DtCompileBuffer (LocalityBuffer,
2554             FieldList->Value, FieldList, Localities);
2555 
2556         LocalityListLength++;
2557         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2558         DtInsertSubtable (ParentTable, Subtable);
2559         EndOfFieldList = FieldList;
2560         FieldList = FieldList->Next;
2561     }
2562 
2563     if (LocalityListLength != Localities)
2564     {
2565         sprintf(AslGbl_MsgBuffer,
2566             "Found %u entries, must match LocalityCount: %u",
2567             LocalityListLength, Localities);
2568         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
2569         ACPI_FREE (LocalityBuffer);
2570         return (AE_LIMIT);
2571     }
2572 
2573     ACPI_FREE (LocalityBuffer);
2574     return (AE_OK);
2575 }
2576 
2577 
2578 /******************************************************************************
2579  *
2580  * FUNCTION:    DtCompileSrat
2581  *
2582  * PARAMETERS:  List                - Current field list pointer
2583  *
2584  * RETURN:      Status
2585  *
2586  * DESCRIPTION: Compile SRAT.
2587  *
2588  *****************************************************************************/
2589 
2590 ACPI_STATUS
DtCompileSrat(void ** List)2591 DtCompileSrat (
2592     void                    **List)
2593 {
2594     ACPI_STATUS             Status;
2595     DT_SUBTABLE             *Subtable;
2596     DT_SUBTABLE             *ParentTable;
2597     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2598     DT_FIELD                *SubtableStart;
2599     ACPI_SUBTABLE_HEADER    *SratHeader;
2600     ACPI_DMTABLE_INFO       *InfoTable;
2601 
2602 
2603     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2604         &Subtable);
2605     if (ACPI_FAILURE (Status))
2606     {
2607         return (Status);
2608     }
2609 
2610     ParentTable = DtPeekSubtable ();
2611     DtInsertSubtable (ParentTable, Subtable);
2612 
2613     while (*PFieldList)
2614     {
2615         SubtableStart = *PFieldList;
2616         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2617             &Subtable);
2618         if (ACPI_FAILURE (Status))
2619         {
2620             return (Status);
2621         }
2622 
2623         ParentTable = DtPeekSubtable ();
2624         DtInsertSubtable (ParentTable, Subtable);
2625         DtPushSubtable (Subtable);
2626 
2627         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2628 
2629         switch (SratHeader->Type)
2630         {
2631         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2632 
2633             InfoTable = AcpiDmTableInfoSrat0;
2634             break;
2635 
2636         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2637 
2638             InfoTable = AcpiDmTableInfoSrat1;
2639             break;
2640 
2641         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2642 
2643             InfoTable = AcpiDmTableInfoSrat2;
2644             break;
2645 
2646         case ACPI_SRAT_TYPE_GICC_AFFINITY:
2647 
2648             InfoTable = AcpiDmTableInfoSrat3;
2649             break;
2650 
2651         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
2652 
2653             InfoTable = AcpiDmTableInfoSrat4;
2654             break;
2655 
2656         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
2657 
2658             InfoTable = AcpiDmTableInfoSrat5;
2659             break;
2660 
2661         case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
2662 
2663             InfoTable = AcpiDmTableInfoSrat6;
2664             break;
2665 
2666         case ACPI_SRAT_TYPE_RINTC_AFFINITY:
2667 
2668             InfoTable = AcpiDmTableInfoSrat7;
2669             break;
2670 
2671         default:
2672 
2673             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2674             return (AE_ERROR);
2675         }
2676 
2677         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2678         if (ACPI_FAILURE (Status))
2679         {
2680             return (Status);
2681         }
2682 
2683         ParentTable = DtPeekSubtable ();
2684         DtInsertSubtable (ParentTable, Subtable);
2685         DtPopSubtable ();
2686     }
2687 
2688     return (AE_OK);
2689 }
2690 
2691 
2692 /******************************************************************************
2693  *
2694  * FUNCTION:    DtCompileStao
2695  *
2696  * PARAMETERS:  PFieldList          - Current field list pointer
2697  *
2698  * RETURN:      Status
2699  *
2700  * DESCRIPTION: Compile STAO.
2701  *
2702  *****************************************************************************/
2703 
2704 ACPI_STATUS
DtCompileStao(void ** List)2705 DtCompileStao (
2706     void                    **List)
2707 {
2708     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2709     DT_SUBTABLE             *Subtable;
2710     DT_SUBTABLE             *ParentTable;
2711     ACPI_STATUS             Status;
2712 
2713 
2714     /* Compile the main table */
2715 
2716     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
2717         &Subtable);
2718     if (ACPI_FAILURE (Status))
2719     {
2720         return (Status);
2721     }
2722 
2723     ParentTable = DtPeekSubtable ();
2724     DtInsertSubtable (ParentTable, Subtable);
2725 
2726     /* Compile each ASCII namestring as a subtable */
2727 
2728     while (*PFieldList)
2729     {
2730         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
2731             &Subtable);
2732         if (ACPI_FAILURE (Status))
2733         {
2734             return (Status);
2735         }
2736 
2737         ParentTable = DtPeekSubtable ();
2738         DtInsertSubtable (ParentTable, Subtable);
2739     }
2740 
2741     return (AE_OK);
2742 }
2743 
2744 
2745 /******************************************************************************
2746  *
2747  * FUNCTION:    DtCompileSvkl
2748  *
2749  * PARAMETERS:  PFieldList          - Current field list pointer
2750  *
2751  * RETURN:      Status
2752  *
2753  * DESCRIPTION: Compile SVKL.
2754  *
2755  * NOTES: SVKL is essentially a flat table, with a small main table and
2756  *          a variable number of a single type of subtable.
2757  *
2758  *****************************************************************************/
2759 
2760 ACPI_STATUS
DtCompileSvkl(void ** List)2761 DtCompileSvkl (
2762     void                    **List)
2763 {
2764     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2765     DT_SUBTABLE             *Subtable;
2766     DT_SUBTABLE             *ParentTable;
2767     ACPI_STATUS             Status;
2768 
2769 
2770     /* Compile the main table */
2771 
2772     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
2773         &Subtable);
2774     if (ACPI_FAILURE (Status))
2775     {
2776         return (Status);
2777     }
2778 
2779     ParentTable = DtPeekSubtable ();
2780     DtInsertSubtable (ParentTable, Subtable);
2781 
2782     /* Compile each subtable */
2783 
2784     while (*PFieldList)
2785     {
2786         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
2787             &Subtable);
2788         if (ACPI_FAILURE (Status))
2789         {
2790             return (Status);
2791         }
2792 
2793         ParentTable = DtPeekSubtable ();
2794         DtInsertSubtable (ParentTable, Subtable);
2795     }
2796 
2797     return (AE_OK);
2798 }
2799 
2800 
2801 /******************************************************************************
2802  *
2803  * FUNCTION:    DtCompileTcpa
2804  *
2805  * PARAMETERS:  PFieldList          - Current field list pointer
2806  *
2807  * RETURN:      Status
2808  *
2809  * DESCRIPTION: Compile TCPA.
2810  *
2811  *****************************************************************************/
2812 
2813 ACPI_STATUS
DtCompileTcpa(void ** List)2814 DtCompileTcpa (
2815     void                    **List)
2816 {
2817     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2818     DT_SUBTABLE             *Subtable;
2819     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
2820     DT_SUBTABLE             *ParentTable;
2821     ACPI_STATUS             Status;
2822 
2823 
2824     /* Compile the main table */
2825 
2826     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
2827         &Subtable);
2828     if (ACPI_FAILURE (Status))
2829     {
2830         return (Status);
2831     }
2832 
2833     ParentTable = DtPeekSubtable ();
2834     DtInsertSubtable (ParentTable, Subtable);
2835 
2836     /*
2837      * Examine the PlatformClass field to determine the table type.
2838      * Either a client or server table. Only one.
2839      */
2840     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
2841 
2842     switch (TcpaHeader->PlatformClass)
2843     {
2844     case ACPI_TCPA_CLIENT_TABLE:
2845 
2846         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
2847             &Subtable);
2848         break;
2849 
2850     case ACPI_TCPA_SERVER_TABLE:
2851 
2852         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
2853             &Subtable);
2854         break;
2855 
2856     default:
2857 
2858         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
2859             TcpaHeader->PlatformClass);
2860         Status = AE_ERROR;
2861         break;
2862     }
2863 
2864     ParentTable = DtPeekSubtable ();
2865     DtInsertSubtable (ParentTable, Subtable);
2866     return (Status);
2867 }
2868 
2869 
2870 /******************************************************************************
2871  *
2872  * FUNCTION:    DtCompileTpm2Rev3
2873  *
2874  * PARAMETERS:  PFieldList          - Current field list pointer
2875  *
2876  * RETURN:      Status
2877  *
2878  * DESCRIPTION: Compile TPM2 revision 3
2879  *
2880  *****************************************************************************/
2881 static ACPI_STATUS
DtCompileTpm2Rev3(void ** List)2882 DtCompileTpm2Rev3 (
2883     void                    **List)
2884 {
2885     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2886     DT_SUBTABLE             *Subtable;
2887     ACPI_TABLE_TPM23        *Tpm23Header;
2888     DT_SUBTABLE             *ParentTable;
2889     ACPI_STATUS             Status = AE_OK;
2890 
2891 
2892     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
2893         &Subtable);
2894 
2895     ParentTable = DtPeekSubtable ();
2896     DtInsertSubtable (ParentTable, Subtable);
2897     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
2898 
2899     /* Subtable type depends on the StartMethod */
2900 
2901     switch (Tpm23Header->StartMethod)
2902     {
2903     case ACPI_TPM23_ACPI_START_METHOD:
2904 
2905         /* Subtable specific to to ARM_SMC */
2906 
2907         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
2908             &Subtable);
2909         if (ACPI_FAILURE (Status))
2910         {
2911             return (Status);
2912         }
2913 
2914         ParentTable = DtPeekSubtable ();
2915         DtInsertSubtable (ParentTable, Subtable);
2916         break;
2917 
2918     default:
2919         break;
2920     }
2921 
2922     return (Status);
2923 }
2924 
2925 
2926 /******************************************************************************
2927  *
2928  * FUNCTION:    DtCompileTpm2
2929  *
2930  * PARAMETERS:  PFieldList          - Current field list pointer
2931  *
2932  * RETURN:      Status
2933  *
2934  * DESCRIPTION: Compile TPM2.
2935  *
2936  *****************************************************************************/
2937 
2938 ACPI_STATUS
DtCompileTpm2(void ** List)2939 DtCompileTpm2 (
2940     void                    **List)
2941 {
2942     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2943     DT_SUBTABLE             *Subtable;
2944     ACPI_TABLE_TPM2         *Tpm2Header;
2945     DT_SUBTABLE             *ParentTable;
2946     ACPI_STATUS             Status = AE_OK;
2947     ACPI_TABLE_HEADER       *Header;
2948 
2949 
2950     ParentTable = DtPeekSubtable ();
2951 
2952     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2953 
2954     if (Header->Revision == 3)
2955     {
2956         return (DtCompileTpm2Rev3 (List));
2957     }
2958 
2959     /* Compile the main table */
2960 
2961     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
2962         &Subtable);
2963     if (ACPI_FAILURE (Status))
2964     {
2965         return (Status);
2966     }
2967 
2968     ParentTable = DtPeekSubtable ();
2969     DtInsertSubtable (ParentTable, Subtable);
2970 
2971     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
2972 
2973     /* Method parameters */
2974     /* Optional: Log area minimum length */
2975     /* Optional: Log area start address */
2976     /* TBD: Optional fields above not fully implemented (not optional at this time) */
2977 
2978     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
2979         &Subtable);
2980     if (ACPI_FAILURE (Status))
2981     {
2982         return (Status);
2983     }
2984 
2985     ParentTable = DtPeekSubtable ();
2986     DtInsertSubtable (ParentTable, Subtable);
2987 
2988 
2989     /* Subtable type depends on the StartMethod */
2990 
2991     switch (Tpm2Header->StartMethod)
2992     {
2993     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
2994 
2995         /* Subtable specific to to ARM_SMC */
2996 
2997         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
2998             &Subtable);
2999         if (ACPI_FAILURE (Status))
3000         {
3001             return (Status);
3002         }
3003 
3004         ParentTable = DtPeekSubtable ();
3005         DtInsertSubtable (ParentTable, Subtable);
3006         break;
3007 
3008     case ACPI_TPM2_START_METHOD:
3009     case ACPI_TPM2_MEMORY_MAPPED:
3010     case ACPI_TPM2_COMMAND_BUFFER:
3011     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
3012         break;
3013 
3014     case ACPI_TPM2_RESERVED1:
3015     case ACPI_TPM2_RESERVED3:
3016     case ACPI_TPM2_RESERVED4:
3017     case ACPI_TPM2_RESERVED5:
3018     case ACPI_TPM2_RESERVED9:
3019     case ACPI_TPM2_RESERVED10:
3020 
3021         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
3022             Tpm2Header->StartMethod);
3023         Status = AE_ERROR;
3024         break;
3025 
3026     case ACPI_TPM2_NOT_ALLOWED:
3027     default:
3028 
3029         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
3030             Tpm2Header->StartMethod);
3031         Status = AE_ERROR;
3032         break;
3033     }
3034 
3035     return (Status);
3036 }
3037 
3038 
3039 /******************************************************************************
3040  *
3041  * FUNCTION:    DtGetGenericTableInfo
3042  *
3043  * PARAMETERS:  Name                - Generic type name
3044  *
3045  * RETURN:      Info entry
3046  *
3047  * DESCRIPTION: Obtain table info for a generic name entry
3048  *
3049  *****************************************************************************/
3050 
3051 ACPI_DMTABLE_INFO *
DtGetGenericTableInfo(char * Name)3052 DtGetGenericTableInfo (
3053     char                    *Name)
3054 {
3055     ACPI_DMTABLE_INFO       *Info;
3056     UINT32                  i;
3057 
3058 
3059     if (!Name)
3060     {
3061         return (NULL);
3062     }
3063 
3064     /* Search info table for name match */
3065 
3066     for (i = 0; ; i++)
3067     {
3068         Info = AcpiDmTableInfoGeneric[i];
3069         if (Info->Opcode == ACPI_DMT_EXIT)
3070         {
3071             Info = NULL;
3072             break;
3073         }
3074 
3075         /* Use caseless compare for generic keywords */
3076 
3077         if (!AcpiUtStricmp (Name, Info->Name))
3078         {
3079             break;
3080         }
3081     }
3082 
3083     return (Info);
3084 }
3085 
3086 
3087 /******************************************************************************
3088  *
3089  * FUNCTION:    DtCompileUefi
3090  *
3091  * PARAMETERS:  List                - Current field list pointer
3092  *
3093  * RETURN:      Status
3094  *
3095  * DESCRIPTION: Compile UEFI.
3096  *
3097  *****************************************************************************/
3098 
3099 ACPI_STATUS
DtCompileUefi(void ** List)3100 DtCompileUefi (
3101     void                    **List)
3102 {
3103     ACPI_STATUS             Status;
3104     DT_SUBTABLE             *Subtable;
3105     DT_SUBTABLE             *ParentTable;
3106     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3107     UINT16                  *DataOffset;
3108 
3109 
3110     /* Compile the predefined portion of the UEFI table */
3111 
3112     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
3113         &Subtable);
3114     if (ACPI_FAILURE (Status))
3115     {
3116         return (Status);
3117     }
3118 
3119     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
3120     *DataOffset = sizeof (ACPI_TABLE_UEFI);
3121 
3122     ParentTable = DtPeekSubtable ();
3123     DtInsertSubtable (ParentTable, Subtable);
3124 
3125     /*
3126      * Compile the "generic" portion of the UEFI table. This
3127      * part of the table is not predefined and any of the generic
3128      * operators may be used.
3129      */
3130     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
3131     return (AE_OK);
3132 }
3133 
3134 
3135 /******************************************************************************
3136  *
3137  * FUNCTION:    DtCompileViot
3138  *
3139  * PARAMETERS:  List                - Current field list pointer
3140  *
3141  * RETURN:      Status
3142  *
3143  * DESCRIPTION: Compile VIOT.
3144  *
3145  *****************************************************************************/
3146 
3147 ACPI_STATUS
DtCompileViot(void ** List)3148 DtCompileViot (
3149     void                    **List)
3150 {
3151     ACPI_STATUS             Status;
3152     DT_SUBTABLE             *Subtable;
3153     DT_SUBTABLE             *ParentTable;
3154     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3155     DT_FIELD                *SubtableStart;
3156     ACPI_TABLE_VIOT         *Viot;
3157     ACPI_VIOT_HEADER        *ViotHeader;
3158     ACPI_DMTABLE_INFO       *InfoTable;
3159     UINT16                  NodeCount;
3160 
3161     ParentTable = DtPeekSubtable ();
3162 
3163     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
3164     if (ACPI_FAILURE (Status))
3165     {
3166         return (Status);
3167     }
3168     DtInsertSubtable (ParentTable, Subtable);
3169 
3170     /*
3171      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
3172      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
3173      */
3174     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
3175         sizeof (ACPI_TABLE_HEADER));
3176 
3177     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
3178 
3179     NodeCount = 0;
3180     while (*PFieldList) {
3181         SubtableStart = *PFieldList;
3182         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
3183             &Subtable);
3184         if (ACPI_FAILURE (Status))
3185         {
3186             return (Status);
3187         }
3188 
3189         ParentTable = DtPeekSubtable ();
3190         DtInsertSubtable (ParentTable, Subtable);
3191         DtPushSubtable (Subtable);
3192 
3193         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
3194 
3195         switch (ViotHeader->Type)
3196         {
3197         case ACPI_VIOT_NODE_PCI_RANGE:
3198 
3199             InfoTable = AcpiDmTableInfoViot1;
3200             break;
3201 
3202         case ACPI_VIOT_NODE_MMIO:
3203 
3204             InfoTable = AcpiDmTableInfoViot2;
3205             break;
3206 
3207         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
3208 
3209             InfoTable = AcpiDmTableInfoViot3;
3210             break;
3211 
3212         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
3213 
3214             InfoTable = AcpiDmTableInfoViot4;
3215             break;
3216 
3217         default:
3218 
3219             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
3220             return (AE_ERROR);
3221         }
3222 
3223         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
3224         if (ACPI_FAILURE (Status))
3225         {
3226             return (Status);
3227         }
3228 
3229         ParentTable = DtPeekSubtable ();
3230         DtInsertSubtable (ParentTable, Subtable);
3231         DtPopSubtable ();
3232         NodeCount++;
3233     }
3234 
3235     Viot->NodeCount = NodeCount;
3236     return (AE_OK);
3237 }
3238 
3239 
3240 /******************************************************************************
3241  *
3242  * FUNCTION:    DtCompileWdat
3243  *
3244  * PARAMETERS:  List                - Current field list pointer
3245  *
3246  * RETURN:      Status
3247  *
3248  * DESCRIPTION: Compile WDAT.
3249  *
3250  *****************************************************************************/
3251 
3252 ACPI_STATUS
DtCompileWdat(void ** List)3253 DtCompileWdat (
3254     void                    **List)
3255 {
3256     ACPI_STATUS             Status;
3257 
3258 
3259     Status = DtCompileTwoSubtables (List,
3260         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3261     return (Status);
3262 }
3263 
3264 
3265 /******************************************************************************
3266  *
3267  * FUNCTION:    DtCompileWpbt
3268  *
3269  * PARAMETERS:  List                - Current field list pointer
3270  *
3271  * RETURN:      Status
3272  *
3273  * DESCRIPTION: Compile WPBT.
3274  *
3275  *****************************************************************************/
3276 
3277 ACPI_STATUS
DtCompileWpbt(void ** List)3278 DtCompileWpbt (
3279     void                    **List)
3280 {
3281     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3282     DT_SUBTABLE             *Subtable;
3283     DT_SUBTABLE             *ParentTable;
3284     ACPI_TABLE_WPBT         *Table;
3285     ACPI_STATUS             Status;
3286 
3287 
3288     /* Compile the main table */
3289 
3290     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
3291     if (ACPI_FAILURE (Status))
3292     {
3293         return (Status);
3294     }
3295 
3296     ParentTable = DtPeekSubtable ();
3297     DtInsertSubtable (ParentTable, Subtable);
3298     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3299 
3300     /*
3301      * Exit now if there are no arguments specified. This is indicated by:
3302      * The "Command-line Arguments" field has not been specified (if specified,
3303      * it will be the last field in the field list -- after the main table).
3304      * Set the Argument Length in the main table to zero.
3305      */
3306     if (!*PFieldList)
3307     {
3308         Table->ArgumentsLength = 0;
3309         return (AE_OK);
3310     }
3311 
3312     /* Compile the argument list subtable */
3313 
3314     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
3315     if (ACPI_FAILURE (Status))
3316     {
3317         return (Status);
3318     }
3319 
3320     /* Extract the length of the Arguments buffer, insert into main table */
3321 
3322     Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
3323     DtInsertSubtable (ParentTable, Subtable);
3324     return (AE_OK);
3325 }
3326 
3327 
3328 /******************************************************************************
3329  *
3330  * FUNCTION:    DtCompileXsdt
3331  *
3332  * PARAMETERS:  List                - Current field list pointer
3333  *
3334  * RETURN:      Status
3335  *
3336  * DESCRIPTION: Compile XSDT.
3337  *
3338  *****************************************************************************/
3339 
3340 ACPI_STATUS
DtCompileXsdt(void ** List)3341 DtCompileXsdt (
3342     void                    **List)
3343 {
3344     DT_SUBTABLE             *Subtable;
3345     DT_SUBTABLE             *ParentTable;
3346     DT_FIELD                *FieldList = *(DT_FIELD **) List;
3347     UINT64                  Address;
3348 
3349 
3350     ParentTable = DtPeekSubtable ();
3351 
3352     while (FieldList)
3353     {
3354         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3355 
3356         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3357         DtInsertSubtable (ParentTable, Subtable);
3358         FieldList = FieldList->Next;
3359     }
3360 
3361     return (AE_OK);
3362 }
3363 
3364 
3365 /******************************************************************************
3366  *
3367  * FUNCTION:    DtCompileGeneric
3368  *
3369  * PARAMETERS:  List                - Current field list pointer
3370  *              Name                - Field name to end generic compiling
3371  *              Length              - Compiled table length to return
3372  *
3373  * RETURN:      Status
3374  *
3375  * DESCRIPTION: Compile generic unknown table.
3376  *
3377  *****************************************************************************/
3378 
3379 ACPI_STATUS
DtCompileGeneric(void ** List,char * Name,UINT32 * Length)3380 DtCompileGeneric (
3381     void                    **List,
3382     char                    *Name,
3383     UINT32                  *Length)
3384 {
3385     ACPI_STATUS             Status;
3386     DT_SUBTABLE             *Subtable;
3387     DT_SUBTABLE             *ParentTable;
3388     DT_FIELD                **PFieldList = (DT_FIELD **) List;
3389     ACPI_DMTABLE_INFO       *Info;
3390 
3391 
3392     ParentTable = DtPeekSubtable ();
3393 
3394     /*
3395      * Compile the "generic" portion of the table. This
3396      * part of the table is not predefined and any of the generic
3397      * operators may be used.
3398      */
3399 
3400     /* Find any and all labels in the entire generic portion */
3401 
3402     DtDetectAllLabels (*PFieldList);
3403 
3404     /* Now we can actually compile the parse tree */
3405 
3406     if (Length && *Length)
3407     {
3408         *Length = 0;
3409     }
3410     while (*PFieldList)
3411     {
3412         if (Name && !strcmp ((*PFieldList)->Name, Name))
3413         {
3414             break;
3415         }
3416 
3417         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3418         if (!Info)
3419         {
3420             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3421                 (*PFieldList)->Name);
3422             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3423                 (*PFieldList), AslGbl_MsgBuffer);
3424 
3425             *PFieldList = (*PFieldList)->Next;
3426             continue;
3427         }
3428 
3429         Status = DtCompileTable (PFieldList, Info,
3430             &Subtable);
3431         if (ACPI_SUCCESS (Status))
3432         {
3433             DtInsertSubtable (ParentTable, Subtable);
3434             if (Length)
3435             {
3436                 *Length += Subtable->Length;
3437             }
3438         }
3439         else
3440         {
3441             *PFieldList = (*PFieldList)->Next;
3442 
3443             if (Status == AE_NOT_FOUND)
3444             {
3445                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3446                     (*PFieldList)->Name);
3447                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3448                     (*PFieldList), AslGbl_MsgBuffer);
3449             }
3450         }
3451     }
3452 
3453     return (AE_OK);
3454 }
3455