xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable1.c (revision f0cfa1b168014f56c02b83e5f28412cc5f78d117)
1 /******************************************************************************
2  *
3  * Module Name: dttable1.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 - 2017, 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 A-I */
153 
154 #include <contrib/dev/acpica/compiler/aslcompiler.h>
155 
156 #define _COMPONENT          DT_COMPILER
157         ACPI_MODULE_NAME    ("dttable1")
158 
159 
160 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
161 {
162     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
163     {ACPI_DMT_EXIT,     0,               NULL, 0}
164 };
165 
166 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
167 {
168     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
169     {ACPI_DMT_EXIT,     0,               NULL, 0}
170 };
171 
172 
173 /******************************************************************************
174  *
175  * FUNCTION:    DtCompileAsf
176  *
177  * PARAMETERS:  List                - Current field list pointer
178  *
179  * RETURN:      Status
180  *
181  * DESCRIPTION: Compile ASF!.
182  *
183  *****************************************************************************/
184 
185 ACPI_STATUS
186 DtCompileAsf (
187     void                    **List)
188 {
189     ACPI_ASF_INFO           *AsfTable;
190     DT_SUBTABLE             *Subtable;
191     DT_SUBTABLE             *ParentTable;
192     ACPI_DMTABLE_INFO       *InfoTable;
193     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
194     UINT32                  DataCount = 0;
195     ACPI_STATUS             Status;
196     UINT32                  i;
197     DT_FIELD                **PFieldList = (DT_FIELD **) List;
198     DT_FIELD                *SubtableStart;
199 
200 
201     while (*PFieldList)
202     {
203         SubtableStart = *PFieldList;
204         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
205             &Subtable, TRUE);
206         if (ACPI_FAILURE (Status))
207         {
208             return (Status);
209         }
210 
211         ParentTable = DtPeekSubtable ();
212         DtInsertSubtable (ParentTable, Subtable);
213         DtPushSubtable (Subtable);
214 
215         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
216 
217         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
218         {
219         case ACPI_ASF_TYPE_INFO:
220 
221             InfoTable = AcpiDmTableInfoAsf0;
222             break;
223 
224         case ACPI_ASF_TYPE_ALERT:
225 
226             InfoTable = AcpiDmTableInfoAsf1;
227             break;
228 
229         case ACPI_ASF_TYPE_CONTROL:
230 
231             InfoTable = AcpiDmTableInfoAsf2;
232             break;
233 
234         case ACPI_ASF_TYPE_BOOT:
235 
236             InfoTable = AcpiDmTableInfoAsf3;
237             break;
238 
239         case ACPI_ASF_TYPE_ADDRESS:
240 
241             InfoTable = AcpiDmTableInfoAsf4;
242             break;
243 
244         default:
245 
246             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
247             return (AE_ERROR);
248         }
249 
250         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
251         if (ACPI_FAILURE (Status))
252         {
253             return (Status);
254         }
255 
256         ParentTable = DtPeekSubtable ();
257         DtInsertSubtable (ParentTable, Subtable);
258 
259         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
260         {
261         case ACPI_ASF_TYPE_INFO:
262 
263             DataInfoTable = NULL;
264             break;
265 
266         case ACPI_ASF_TYPE_ALERT:
267 
268             DataInfoTable = AcpiDmTableInfoAsf1a;
269             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
270                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
271                     sizeof (ACPI_ASF_HEADER)))->Alerts;
272             break;
273 
274         case ACPI_ASF_TYPE_CONTROL:
275 
276             DataInfoTable = AcpiDmTableInfoAsf2a;
277             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
278                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
279                     sizeof (ACPI_ASF_HEADER)))->Controls;
280             break;
281 
282         case ACPI_ASF_TYPE_BOOT:
283 
284             DataInfoTable = NULL;
285             break;
286 
287         case ACPI_ASF_TYPE_ADDRESS:
288 
289             DataInfoTable = TableInfoAsfAddress;
290             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
291                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
292                     sizeof (ACPI_ASF_HEADER)))->Devices;
293             break;
294 
295         default:
296 
297             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
298             return (AE_ERROR);
299         }
300 
301         if (DataInfoTable)
302         {
303             switch (AsfTable->Header.Type & 0x7F)
304             {
305             case ACPI_ASF_TYPE_ADDRESS:
306 
307                 while (DataCount > 0)
308                 {
309                     Status = DtCompileTable (PFieldList, DataInfoTable,
310                         &Subtable, TRUE);
311                     if (ACPI_FAILURE (Status))
312                     {
313                         return (Status);
314                     }
315 
316                     DtInsertSubtable (ParentTable, Subtable);
317                     DataCount = DataCount - Subtable->Length;
318                 }
319                 break;
320 
321             default:
322 
323                 for (i = 0; i < DataCount; i++)
324                 {
325                     Status = DtCompileTable (PFieldList, DataInfoTable,
326                         &Subtable, TRUE);
327                     if (ACPI_FAILURE (Status))
328                     {
329                         return (Status);
330                     }
331 
332                     DtInsertSubtable (ParentTable, Subtable);
333                 }
334                 break;
335             }
336         }
337 
338         DtPopSubtable ();
339     }
340 
341     return (AE_OK);
342 }
343 
344 
345 /******************************************************************************
346  *
347  * FUNCTION:    DtCompileCpep
348  *
349  * PARAMETERS:  List                - Current field list pointer
350  *
351  * RETURN:      Status
352  *
353  * DESCRIPTION: Compile CPEP.
354  *
355  *****************************************************************************/
356 
357 ACPI_STATUS
358 DtCompileCpep (
359     void                    **List)
360 {
361     ACPI_STATUS             Status;
362 
363 
364     Status = DtCompileTwoSubtables (List,
365         AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
366     return (Status);
367 }
368 
369 
370 /******************************************************************************
371  *
372  * FUNCTION:    DtCompileCsrt
373  *
374  * PARAMETERS:  List                - Current field list pointer
375  *
376  * RETURN:      Status
377  *
378  * DESCRIPTION: Compile CSRT.
379  *
380  *****************************************************************************/
381 
382 ACPI_STATUS
383 DtCompileCsrt (
384     void                    **List)
385 {
386     ACPI_STATUS             Status = AE_OK;
387     DT_SUBTABLE             *Subtable;
388     DT_SUBTABLE             *ParentTable;
389     DT_FIELD                **PFieldList = (DT_FIELD **) List;
390     UINT32                  DescriptorCount;
391     UINT32                  GroupLength;
392 
393 
394     /* Subtables (Resource Groups) */
395 
396     ParentTable = DtPeekSubtable ();
397     while (*PFieldList)
398     {
399         /* Resource group subtable */
400 
401         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
402             &Subtable, TRUE);
403         if (ACPI_FAILURE (Status))
404         {
405             return (Status);
406         }
407 
408         /* Compute the number of resource descriptors */
409 
410         GroupLength =
411             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
412                 Subtable->Buffer))->Length -
413             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
414                 Subtable->Buffer))->SharedInfoLength -
415             sizeof (ACPI_CSRT_GROUP);
416 
417         DescriptorCount = (GroupLength  /
418             sizeof (ACPI_CSRT_DESCRIPTOR));
419 
420         DtInsertSubtable (ParentTable, Subtable);
421         DtPushSubtable (Subtable);
422         ParentTable = DtPeekSubtable ();
423 
424         /* Shared info subtable (One per resource group) */
425 
426         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
427             &Subtable, TRUE);
428         if (ACPI_FAILURE (Status))
429         {
430             return (Status);
431         }
432 
433         DtInsertSubtable (ParentTable, Subtable);
434 
435         /* Sub-Subtables (Resource Descriptors) */
436 
437         while (*PFieldList && DescriptorCount)
438         {
439 
440             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
441                 &Subtable, TRUE);
442             if (ACPI_FAILURE (Status))
443             {
444                 return (Status);
445             }
446 
447             DtInsertSubtable (ParentTable, Subtable);
448 
449             DtPushSubtable (Subtable);
450             ParentTable = DtPeekSubtable ();
451             if (*PFieldList)
452             {
453                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
454                     &Subtable, TRUE);
455                 if (ACPI_FAILURE (Status))
456                 {
457                     return (Status);
458                 }
459                 if (Subtable)
460                 {
461                     DtInsertSubtable (ParentTable, Subtable);
462                 }
463             }
464 
465             DtPopSubtable ();
466             ParentTable = DtPeekSubtable ();
467             DescriptorCount--;
468         }
469 
470         DtPopSubtable ();
471         ParentTable = DtPeekSubtable ();
472     }
473 
474     return (Status);
475 }
476 
477 
478 /******************************************************************************
479  *
480  * FUNCTION:    DtCompileDbg2
481  *
482  * PARAMETERS:  List                - Current field list pointer
483  *
484  * RETURN:      Status
485  *
486  * DESCRIPTION: Compile DBG2.
487  *
488  *****************************************************************************/
489 
490 ACPI_STATUS
491 DtCompileDbg2 (
492     void                    **List)
493 {
494     ACPI_STATUS             Status;
495     DT_SUBTABLE             *Subtable;
496     DT_SUBTABLE             *ParentTable;
497     DT_FIELD                **PFieldList = (DT_FIELD **) List;
498     UINT32                  SubtableCount;
499     ACPI_DBG2_HEADER        *Dbg2Header;
500     ACPI_DBG2_DEVICE        *DeviceInfo;
501     UINT16                  CurrentOffset;
502     UINT32                  i;
503 
504 
505     /* Main table */
506 
507     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
508     if (ACPI_FAILURE (Status))
509     {
510         return (Status);
511     }
512 
513     ParentTable = DtPeekSubtable ();
514     DtInsertSubtable (ParentTable, Subtable);
515 
516     /* Main table fields */
517 
518     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
519     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
520         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
521 
522     SubtableCount = Dbg2Header->InfoCount;
523     DtPushSubtable (Subtable);
524 
525     /* Process all Device Information subtables (Count = InfoCount) */
526 
527     while (*PFieldList && SubtableCount)
528     {
529         /* Subtable: Debug Device Information */
530 
531         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
532             &Subtable, TRUE);
533         if (ACPI_FAILURE (Status))
534         {
535             return (Status);
536         }
537 
538         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
539         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
540 
541         ParentTable = DtPeekSubtable ();
542         DtInsertSubtable (ParentTable, Subtable);
543         DtPushSubtable (Subtable);
544 
545         ParentTable = DtPeekSubtable ();
546 
547         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
548 
549         DeviceInfo->BaseAddressOffset = CurrentOffset;
550         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
551         {
552             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
553                 &Subtable, TRUE);
554             if (ACPI_FAILURE (Status))
555             {
556                 return (Status);
557             }
558 
559             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
560             DtInsertSubtable (ParentTable, Subtable);
561         }
562 
563         /* AddressSize array (Required, size = RegisterCount) */
564 
565         DeviceInfo->AddressSizeOffset = CurrentOffset;
566         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
567         {
568             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
569                 &Subtable, TRUE);
570             if (ACPI_FAILURE (Status))
571             {
572                 return (Status);
573             }
574 
575             CurrentOffset += (UINT16) sizeof (UINT32);
576             DtInsertSubtable (ParentTable, Subtable);
577         }
578 
579         /* NamespaceString device identifier (Required, size = NamePathLength) */
580 
581         DeviceInfo->NamepathOffset = CurrentOffset;
582         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
583             &Subtable, TRUE);
584         if (ACPI_FAILURE (Status))
585         {
586             return (Status);
587         }
588 
589         /* Update the device info header */
590 
591         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
592         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
593         DtInsertSubtable (ParentTable, Subtable);
594 
595         /* OemData - Variable-length data (Optional, size = OemDataLength) */
596 
597         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
598             &Subtable, TRUE);
599         if (ACPI_FAILURE (Status))
600         {
601             return (Status);
602         }
603 
604         /* Update the device info header (zeros if no OEM data present) */
605 
606         DeviceInfo->OemDataOffset = 0;
607         DeviceInfo->OemDataLength = 0;
608 
609         /* Optional subtable (OemData) */
610 
611         if (Subtable && Subtable->Length)
612         {
613             DeviceInfo->OemDataOffset = CurrentOffset;
614             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
615 
616             DtInsertSubtable (ParentTable, Subtable);
617         }
618 
619         SubtableCount--;
620         DtPopSubtable (); /* Get next Device Information subtable */
621     }
622 
623     DtPopSubtable ();
624     return (AE_OK);
625 }
626 
627 
628 /******************************************************************************
629  *
630  * FUNCTION:    DtCompileDmar
631  *
632  * PARAMETERS:  List                - Current field list pointer
633  *
634  * RETURN:      Status
635  *
636  * DESCRIPTION: Compile DMAR.
637  *
638  *****************************************************************************/
639 
640 ACPI_STATUS
641 DtCompileDmar (
642     void                    **List)
643 {
644     ACPI_STATUS             Status;
645     DT_SUBTABLE             *Subtable;
646     DT_SUBTABLE             *ParentTable;
647     DT_FIELD                **PFieldList = (DT_FIELD **) List;
648     DT_FIELD                *SubtableStart;
649     ACPI_DMTABLE_INFO       *InfoTable;
650     ACPI_DMAR_HEADER        *DmarHeader;
651     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
652     UINT32                  DeviceScopeLength;
653     UINT32                  PciPathLength;
654 
655 
656     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
657     if (ACPI_FAILURE (Status))
658     {
659         return (Status);
660     }
661 
662     ParentTable = DtPeekSubtable ();
663     DtInsertSubtable (ParentTable, Subtable);
664     DtPushSubtable (Subtable);
665 
666     while (*PFieldList)
667     {
668         /* DMAR Header */
669 
670         SubtableStart = *PFieldList;
671         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
672             &Subtable, TRUE);
673         if (ACPI_FAILURE (Status))
674         {
675             return (Status);
676         }
677 
678         ParentTable = DtPeekSubtable ();
679         DtInsertSubtable (ParentTable, Subtable);
680         DtPushSubtable (Subtable);
681 
682         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
683 
684         switch (DmarHeader->Type)
685         {
686         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
687 
688             InfoTable = AcpiDmTableInfoDmar0;
689             break;
690 
691         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
692 
693             InfoTable = AcpiDmTableInfoDmar1;
694             break;
695 
696         case ACPI_DMAR_TYPE_ROOT_ATS:
697 
698             InfoTable = AcpiDmTableInfoDmar2;
699             break;
700 
701         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
702 
703             InfoTable = AcpiDmTableInfoDmar3;
704             break;
705 
706         case ACPI_DMAR_TYPE_NAMESPACE:
707 
708             InfoTable = AcpiDmTableInfoDmar4;
709             break;
710 
711         default:
712 
713             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
714             return (AE_ERROR);
715         }
716 
717         /* DMAR Subtable */
718 
719         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
720         if (ACPI_FAILURE (Status))
721         {
722             return (Status);
723         }
724 
725         ParentTable = DtPeekSubtable ();
726         DtInsertSubtable (ParentTable, Subtable);
727 
728         /*
729          * Optional Device Scope subtables
730          */
731         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
732             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
733         {
734             /* These types do not support device scopes */
735 
736             DtPopSubtable ();
737             continue;
738         }
739 
740         DtPushSubtable (Subtable);
741         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
742             ParentTable->Length;
743         while (DeviceScopeLength)
744         {
745             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
746                 &Subtable, FALSE);
747             if (Status == AE_NOT_FOUND)
748             {
749                 break;
750             }
751 
752             ParentTable = DtPeekSubtable ();
753             DtInsertSubtable (ParentTable, Subtable);
754             DtPushSubtable (Subtable);
755 
756             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
757 
758             /* Optional PCI Paths */
759 
760             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
761             while (PciPathLength)
762             {
763                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
764                     &Subtable, FALSE);
765                 if (Status == AE_NOT_FOUND)
766                 {
767                     DtPopSubtable ();
768                     break;
769                 }
770 
771                 ParentTable = DtPeekSubtable ();
772                 DtInsertSubtable (ParentTable, Subtable);
773                 PciPathLength -= Subtable->Length;
774             }
775 
776             DtPopSubtable ();
777             DeviceScopeLength -= DmarDeviceScope->Length;
778         }
779 
780         DtPopSubtable ();
781         DtPopSubtable ();
782     }
783 
784     return (AE_OK);
785 }
786 
787 
788 /******************************************************************************
789  *
790  * FUNCTION:    DtCompileDrtm
791  *
792  * PARAMETERS:  List                - Current field list pointer
793  *
794  * RETURN:      Status
795  *
796  * DESCRIPTION: Compile DRTM.
797  *
798  *****************************************************************************/
799 
800 ACPI_STATUS
801 DtCompileDrtm (
802     void                    **List)
803 {
804     ACPI_STATUS             Status;
805     DT_SUBTABLE             *Subtable;
806     DT_SUBTABLE             *ParentTable;
807     DT_FIELD                **PFieldList = (DT_FIELD **) List;
808     UINT32                  Count;
809     /* ACPI_TABLE_DRTM         *Drtm; */
810     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
811     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
812     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
813 
814 
815     ParentTable = DtPeekSubtable ();
816 
817     /* Compile DRTM header */
818 
819     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
820         &Subtable, TRUE);
821     if (ACPI_FAILURE (Status))
822     {
823         return (Status);
824     }
825     DtInsertSubtable (ParentTable, Subtable);
826 
827     /*
828      * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
829      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
830      */
831 #if 0
832     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
833         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
834 #endif
835     /* Compile VTL */
836 
837     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
838         &Subtable, TRUE);
839     if (ACPI_FAILURE (Status))
840     {
841         return (Status);
842     }
843 
844     DtInsertSubtable (ParentTable, Subtable);
845     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
846 
847     DtPushSubtable (Subtable);
848     ParentTable = DtPeekSubtable ();
849     Count = 0;
850 
851     while (*PFieldList)
852     {
853         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
854             &Subtable, TRUE);
855         if (ACPI_FAILURE (Status))
856         {
857             return (Status);
858         }
859         if (!Subtable)
860         {
861             break;
862         }
863         DtInsertSubtable (ParentTable, Subtable);
864         Count++;
865     }
866 
867     DrtmVtl->ValidatedTableCount = Count;
868     DtPopSubtable ();
869     ParentTable = DtPeekSubtable ();
870 
871     /* Compile RL */
872 
873     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
874         &Subtable, TRUE);
875     if (ACPI_FAILURE (Status))
876     {
877         return (Status);
878     }
879 
880     DtInsertSubtable (ParentTable, Subtable);
881     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
882 
883     DtPushSubtable (Subtable);
884     ParentTable = DtPeekSubtable ();
885     Count = 0;
886 
887     while (*PFieldList)
888     {
889         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
890             &Subtable, TRUE);
891         if (ACPI_FAILURE (Status))
892         {
893             return (Status);
894         }
895 
896         if (!Subtable)
897         {
898             break;
899         }
900 
901         DtInsertSubtable (ParentTable, Subtable);
902         Count++;
903     }
904 
905     DrtmRl->ResourceCount = Count;
906     DtPopSubtable ();
907     ParentTable = DtPeekSubtable ();
908 
909     /* Compile DPS */
910 
911     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
912         &Subtable, TRUE);
913     if (ACPI_FAILURE (Status))
914     {
915         return (Status);
916     }
917     DtInsertSubtable (ParentTable, Subtable);
918     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
919 
920 
921     return (AE_OK);
922 }
923 
924 
925 /******************************************************************************
926  *
927  * FUNCTION:    DtCompileEinj
928  *
929  * PARAMETERS:  List                - Current field list pointer
930  *
931  * RETURN:      Status
932  *
933  * DESCRIPTION: Compile EINJ.
934  *
935  *****************************************************************************/
936 
937 ACPI_STATUS
938 DtCompileEinj (
939     void                    **List)
940 {
941     ACPI_STATUS             Status;
942 
943 
944     Status = DtCompileTwoSubtables (List,
945         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
946     return (Status);
947 }
948 
949 
950 /******************************************************************************
951  *
952  * FUNCTION:    DtCompileErst
953  *
954  * PARAMETERS:  List                - Current field list pointer
955  *
956  * RETURN:      Status
957  *
958  * DESCRIPTION: Compile ERST.
959  *
960  *****************************************************************************/
961 
962 ACPI_STATUS
963 DtCompileErst (
964     void                    **List)
965 {
966     ACPI_STATUS             Status;
967 
968 
969     Status = DtCompileTwoSubtables (List,
970         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
971     return (Status);
972 }
973 
974 
975 /******************************************************************************
976  *
977  * FUNCTION:    DtCompileGtdt
978  *
979  * PARAMETERS:  List                - Current field list pointer
980  *
981  * RETURN:      Status
982  *
983  * DESCRIPTION: Compile GTDT.
984  *
985  *****************************************************************************/
986 
987 ACPI_STATUS
988 DtCompileGtdt (
989     void                    **List)
990 {
991     ACPI_STATUS             Status;
992     DT_SUBTABLE             *Subtable;
993     DT_SUBTABLE             *ParentTable;
994     DT_FIELD                **PFieldList = (DT_FIELD **) List;
995     DT_FIELD                *SubtableStart;
996     ACPI_SUBTABLE_HEADER    *GtdtHeader;
997     ACPI_DMTABLE_INFO       *InfoTable;
998     UINT32                  GtCount;
999 
1000 
1001     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1002         &Subtable, TRUE);
1003     if (ACPI_FAILURE (Status))
1004     {
1005         return (Status);
1006     }
1007 
1008     ParentTable = DtPeekSubtable ();
1009     DtInsertSubtable (ParentTable, Subtable);
1010 
1011     while (*PFieldList)
1012     {
1013         SubtableStart = *PFieldList;
1014         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1015             &Subtable, TRUE);
1016         if (ACPI_FAILURE (Status))
1017         {
1018             return (Status);
1019         }
1020 
1021         ParentTable = DtPeekSubtable ();
1022         DtInsertSubtable (ParentTable, Subtable);
1023         DtPushSubtable (Subtable);
1024 
1025         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1026 
1027         switch (GtdtHeader->Type)
1028         {
1029         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1030 
1031             InfoTable = AcpiDmTableInfoGtdt0;
1032             break;
1033 
1034         case ACPI_GTDT_TYPE_WATCHDOG:
1035 
1036             InfoTable = AcpiDmTableInfoGtdt1;
1037             break;
1038 
1039         default:
1040 
1041             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1042             return (AE_ERROR);
1043         }
1044 
1045         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1046         if (ACPI_FAILURE (Status))
1047         {
1048             return (Status);
1049         }
1050 
1051         ParentTable = DtPeekSubtable ();
1052         DtInsertSubtable (ParentTable, Subtable);
1053 
1054         /*
1055          * Additional GT block subtable data
1056          */
1057 
1058         switch (GtdtHeader->Type)
1059         {
1060         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1061 
1062             DtPushSubtable (Subtable);
1063             ParentTable = DtPeekSubtable ();
1064 
1065             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1066                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1067 
1068             while (GtCount)
1069             {
1070                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1071                     &Subtable, TRUE);
1072                 if (ACPI_FAILURE (Status))
1073                 {
1074                     return (Status);
1075                 }
1076 
1077                 DtInsertSubtable (ParentTable, Subtable);
1078                 GtCount--;
1079             }
1080 
1081             DtPopSubtable ();
1082             break;
1083 
1084         default:
1085 
1086             break;
1087         }
1088 
1089         DtPopSubtable ();
1090     }
1091 
1092     return (AE_OK);
1093 }
1094 
1095 
1096 /******************************************************************************
1097  *
1098  * FUNCTION:    DtCompileFpdt
1099  *
1100  * PARAMETERS:  List                - Current field list pointer
1101  *
1102  * RETURN:      Status
1103  *
1104  * DESCRIPTION: Compile FPDT.
1105  *
1106  *****************************************************************************/
1107 
1108 ACPI_STATUS
1109 DtCompileFpdt (
1110     void                    **List)
1111 {
1112     ACPI_STATUS             Status;
1113     ACPI_FPDT_HEADER        *FpdtHeader;
1114     DT_SUBTABLE             *Subtable;
1115     DT_SUBTABLE             *ParentTable;
1116     ACPI_DMTABLE_INFO       *InfoTable;
1117     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1118     DT_FIELD                *SubtableStart;
1119 
1120 
1121     while (*PFieldList)
1122     {
1123         SubtableStart = *PFieldList;
1124         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1125             &Subtable, TRUE);
1126         if (ACPI_FAILURE (Status))
1127         {
1128             return (Status);
1129         }
1130 
1131         ParentTable = DtPeekSubtable ();
1132         DtInsertSubtable (ParentTable, Subtable);
1133         DtPushSubtable (Subtable);
1134 
1135         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1136 
1137         switch (FpdtHeader->Type)
1138         {
1139         case ACPI_FPDT_TYPE_BOOT:
1140 
1141             InfoTable = AcpiDmTableInfoFpdt0;
1142             break;
1143 
1144         case ACPI_FPDT_TYPE_S3PERF:
1145 
1146             InfoTable = AcpiDmTableInfoFpdt1;
1147             break;
1148 
1149         default:
1150 
1151             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1152             return (AE_ERROR);
1153             break;
1154         }
1155 
1156         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1157         if (ACPI_FAILURE (Status))
1158         {
1159             return (Status);
1160         }
1161 
1162         ParentTable = DtPeekSubtable ();
1163         DtInsertSubtable (ParentTable, Subtable);
1164         DtPopSubtable ();
1165     }
1166 
1167     return (AE_OK);
1168 }
1169 
1170 
1171 /******************************************************************************
1172  *
1173  * FUNCTION:    DtCompileHest
1174  *
1175  * PARAMETERS:  List                - Current field list pointer
1176  *
1177  * RETURN:      Status
1178  *
1179  * DESCRIPTION: Compile HEST.
1180  *
1181  *****************************************************************************/
1182 
1183 ACPI_STATUS
1184 DtCompileHest (
1185     void                    **List)
1186 {
1187     ACPI_STATUS             Status;
1188     DT_SUBTABLE             *Subtable;
1189     DT_SUBTABLE             *ParentTable;
1190     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1191     DT_FIELD                *SubtableStart;
1192     ACPI_DMTABLE_INFO       *InfoTable;
1193     UINT16                  Type;
1194     UINT32                  BankCount;
1195 
1196 
1197     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1198         &Subtable, TRUE);
1199     if (ACPI_FAILURE (Status))
1200     {
1201         return (Status);
1202     }
1203 
1204     ParentTable = DtPeekSubtable ();
1205     DtInsertSubtable (ParentTable, Subtable);
1206 
1207     while (*PFieldList)
1208     {
1209         /* Get subtable type */
1210 
1211         SubtableStart = *PFieldList;
1212         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1213 
1214         switch (Type)
1215         {
1216         case ACPI_HEST_TYPE_IA32_CHECK:
1217 
1218             InfoTable = AcpiDmTableInfoHest0;
1219             break;
1220 
1221         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1222 
1223             InfoTable = AcpiDmTableInfoHest1;
1224             break;
1225 
1226         case ACPI_HEST_TYPE_IA32_NMI:
1227 
1228             InfoTable = AcpiDmTableInfoHest2;
1229             break;
1230 
1231         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1232 
1233             InfoTable = AcpiDmTableInfoHest6;
1234             break;
1235 
1236         case ACPI_HEST_TYPE_AER_ENDPOINT:
1237 
1238             InfoTable = AcpiDmTableInfoHest7;
1239             break;
1240 
1241         case ACPI_HEST_TYPE_AER_BRIDGE:
1242 
1243             InfoTable = AcpiDmTableInfoHest8;
1244             break;
1245 
1246         case ACPI_HEST_TYPE_GENERIC_ERROR:
1247 
1248             InfoTable = AcpiDmTableInfoHest9;
1249             break;
1250 
1251         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1252 
1253             InfoTable = AcpiDmTableInfoHest10;
1254             break;
1255 
1256         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1257 
1258             InfoTable = AcpiDmTableInfoHest11;
1259             break;
1260 
1261         default:
1262 
1263             /* Cannot continue on unknown type */
1264 
1265             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1266             return (AE_ERROR);
1267         }
1268 
1269         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1270         if (ACPI_FAILURE (Status))
1271         {
1272             return (Status);
1273         }
1274 
1275         DtInsertSubtable (ParentTable, Subtable);
1276 
1277         /*
1278          * Additional subtable data - IA32 Error Bank(s)
1279          */
1280         BankCount = 0;
1281         switch (Type)
1282         {
1283         case ACPI_HEST_TYPE_IA32_CHECK:
1284 
1285             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1286                 Subtable->Buffer))->NumHardwareBanks;
1287             break;
1288 
1289         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1290 
1291             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1292                 Subtable->Buffer))->NumHardwareBanks;
1293             break;
1294 
1295         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1296 
1297             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1298                 Subtable->Buffer))->NumHardwareBanks;
1299             break;
1300 
1301         default:
1302 
1303             break;
1304         }
1305 
1306         while (BankCount)
1307         {
1308             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1309                 &Subtable, TRUE);
1310             if (ACPI_FAILURE (Status))
1311             {
1312                 return (Status);
1313             }
1314 
1315             DtInsertSubtable (ParentTable, Subtable);
1316             BankCount--;
1317         }
1318     }
1319 
1320     return (AE_OK);
1321 }
1322 
1323 
1324 /******************************************************************************
1325  *
1326  * FUNCTION:    DtCompileHmat
1327  *
1328  * PARAMETERS:  List                - Current field list pointer
1329  *
1330  * RETURN:      Status
1331  *
1332  * DESCRIPTION: Compile HMAT.
1333  *
1334  *****************************************************************************/
1335 
1336 ACPI_STATUS
1337 DtCompileHmat (
1338     void                    **List)
1339 {
1340     ACPI_STATUS             Status;
1341     DT_SUBTABLE             *Subtable;
1342     DT_SUBTABLE             *ParentTable;
1343     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1344     DT_FIELD                *SubtableStart;
1345     DT_FIELD                *EntryStart;
1346     ACPI_HMAT_STRUCTURE     *HmatStruct;
1347     ACPI_HMAT_LOCALITY      *HmatLocality;
1348     ACPI_HMAT_CACHE         *HmatCache;
1349     ACPI_DMTABLE_INFO       *InfoTable;
1350     UINT32                  IntPDNumber;
1351     UINT32                  TgtPDNumber;
1352     UINT64                  EntryNumber;
1353     UINT16                  SMBIOSHandleNumber;
1354 
1355 
1356     ParentTable = DtPeekSubtable ();
1357 
1358     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
1359         &Subtable, TRUE);
1360     if (ACPI_FAILURE (Status))
1361     {
1362         return (Status);
1363     }
1364     DtInsertSubtable (ParentTable, Subtable);
1365 
1366     while (*PFieldList)
1367     {
1368         /* Compile HMAT structure header */
1369 
1370         SubtableStart = *PFieldList;
1371         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
1372             &Subtable, TRUE);
1373         if (ACPI_FAILURE (Status))
1374         {
1375             return (Status);
1376         }
1377         DtInsertSubtable (ParentTable, Subtable);
1378 
1379         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
1380         HmatStruct->Length = Subtable->Length;
1381 
1382         /* Compile HMAT structure body */
1383 
1384         switch (HmatStruct->Type)
1385         {
1386         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1387 
1388             InfoTable = AcpiDmTableInfoHmat0;
1389             break;
1390 
1391         case ACPI_HMAT_TYPE_LOCALITY:
1392 
1393             InfoTable = AcpiDmTableInfoHmat1;
1394             break;
1395 
1396         case ACPI_HMAT_TYPE_CACHE:
1397 
1398             InfoTable = AcpiDmTableInfoHmat2;
1399             break;
1400 
1401         default:
1402 
1403             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
1404             return (AE_ERROR);
1405         }
1406 
1407         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1408         if (ACPI_FAILURE (Status))
1409         {
1410             return (Status);
1411         }
1412         DtInsertSubtable (ParentTable, Subtable);
1413         HmatStruct->Length += Subtable->Length;
1414 
1415         /* Compile HMAT structure additionals */
1416 
1417         switch (HmatStruct->Type)
1418         {
1419         case ACPI_HMAT_TYPE_LOCALITY:
1420 
1421             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
1422                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
1423 
1424             /* Compile initiator proximity domain list */
1425 
1426             IntPDNumber = 0;
1427             while (*PFieldList)
1428             {
1429                 Status = DtCompileTable (PFieldList,
1430                     AcpiDmTableInfoHmat1a, &Subtable, TRUE);
1431                 if (ACPI_FAILURE (Status))
1432                 {
1433                     return (Status);
1434                 }
1435                 if (!Subtable)
1436                 {
1437                     break;
1438                 }
1439                 DtInsertSubtable (ParentTable, Subtable);
1440                 HmatStruct->Length += Subtable->Length;
1441                 IntPDNumber++;
1442             }
1443             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
1444 
1445             /* Compile target proximity domain list */
1446 
1447             TgtPDNumber = 0;
1448             while (*PFieldList)
1449             {
1450                 Status = DtCompileTable (PFieldList,
1451                     AcpiDmTableInfoHmat1b, &Subtable, TRUE);
1452                 if (ACPI_FAILURE (Status))
1453                 {
1454                     return (Status);
1455                 }
1456                 if (!Subtable)
1457                 {
1458                     break;
1459                 }
1460                 DtInsertSubtable (ParentTable, Subtable);
1461                 HmatStruct->Length += Subtable->Length;
1462                 TgtPDNumber++;
1463             }
1464             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
1465 
1466             /* Save start of the entries for reporting errors */
1467 
1468             EntryStart = *PFieldList;
1469 
1470             /* Compile latency/bandwidth entries */
1471 
1472             EntryNumber = 0;
1473             while (*PFieldList)
1474             {
1475                 Status = DtCompileTable (PFieldList,
1476                     AcpiDmTableInfoHmat1c, &Subtable, TRUE);
1477                 if (ACPI_FAILURE (Status))
1478                 {
1479                     return (Status);
1480                 }
1481                 if (!Subtable)
1482                 {
1483                     break;
1484                 }
1485                 DtInsertSubtable (ParentTable, Subtable);
1486                 HmatStruct->Length += Subtable->Length;
1487                 EntryNumber++;
1488             }
1489 
1490             /* Validate number of entries */
1491 
1492             if (EntryNumber !=
1493                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
1494             {
1495                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
1496                 return (AE_ERROR);
1497             }
1498             break;
1499 
1500         case ACPI_HMAT_TYPE_CACHE:
1501 
1502             /* Compile SMBIOS handles */
1503 
1504             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
1505                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
1506             SMBIOSHandleNumber = 0;
1507             while (*PFieldList)
1508             {
1509                 Status = DtCompileTable (PFieldList,
1510                     AcpiDmTableInfoHmat2a, &Subtable, TRUE);
1511                 if (ACPI_FAILURE (Status))
1512                 {
1513                     return (Status);
1514                 }
1515                 if (!Subtable)
1516                 {
1517                     break;
1518                 }
1519                 DtInsertSubtable (ParentTable, Subtable);
1520                 HmatStruct->Length += Subtable->Length;
1521                 SMBIOSHandleNumber++;
1522             }
1523             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
1524             break;
1525 
1526         default:
1527 
1528             break;
1529         }
1530     }
1531 
1532     return (AE_OK);
1533 }
1534 
1535 
1536 /******************************************************************************
1537  *
1538  * FUNCTION:    DtCompileIort
1539  *
1540  * PARAMETERS:  List                - Current field list pointer
1541  *
1542  * RETURN:      Status
1543  *
1544  * DESCRIPTION: Compile IORT.
1545  *
1546  *****************************************************************************/
1547 
1548 ACPI_STATUS
1549 DtCompileIort (
1550     void                    **List)
1551 {
1552     ACPI_STATUS             Status;
1553     DT_SUBTABLE             *Subtable;
1554     DT_SUBTABLE             *ParentTable;
1555     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1556     DT_FIELD                *SubtableStart;
1557     ACPI_TABLE_IORT         *Iort;
1558     ACPI_IORT_NODE          *IortNode;
1559     ACPI_IORT_ITS_GROUP     *IortItsGroup;
1560     ACPI_IORT_SMMU          *IortSmmu;
1561     UINT32                  NodeNumber;
1562     UINT32                  NodeLength;
1563     UINT32                  IdMappingNumber;
1564     UINT32                  ItsNumber;
1565     UINT32                  ContextIrptNumber;
1566     UINT32                  PmuIrptNumber;
1567     UINT32                  PaddingLength;
1568 
1569 
1570     ParentTable = DtPeekSubtable ();
1571 
1572     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1573         &Subtable, TRUE);
1574     if (ACPI_FAILURE (Status))
1575     {
1576         return (Status);
1577     }
1578     DtInsertSubtable (ParentTable, Subtable);
1579 
1580     /*
1581      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1582      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
1583      */
1584     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1585         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1586 
1587     /*
1588      * OptionalPadding - Variable-length data
1589      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1590      * Optionally allows the generic data types to be used for filling
1591      * this field.
1592      */
1593     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1594     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1595         &Subtable, TRUE);
1596     if (ACPI_FAILURE (Status))
1597     {
1598         return (Status);
1599     }
1600     if (Subtable)
1601     {
1602         DtInsertSubtable (ParentTable, Subtable);
1603         Iort->NodeOffset += Subtable->Length;
1604     }
1605     else
1606     {
1607         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1608             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1609         if (ACPI_FAILURE (Status))
1610         {
1611             return (Status);
1612         }
1613         Iort->NodeOffset += PaddingLength;
1614     }
1615 
1616     NodeNumber = 0;
1617     while (*PFieldList)
1618     {
1619         SubtableStart = *PFieldList;
1620         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1621             &Subtable, TRUE);
1622         if (ACPI_FAILURE (Status))
1623         {
1624             return (Status);
1625         }
1626 
1627         DtInsertSubtable (ParentTable, Subtable);
1628         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1629         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1630 
1631         DtPushSubtable (Subtable);
1632         ParentTable = DtPeekSubtable ();
1633 
1634         switch (IortNode->Type)
1635         {
1636         case ACPI_IORT_NODE_ITS_GROUP:
1637 
1638             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1639                 &Subtable, TRUE);
1640             if (ACPI_FAILURE (Status))
1641             {
1642                 return (Status);
1643             }
1644 
1645             DtInsertSubtable (ParentTable, Subtable);
1646             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1647             NodeLength += Subtable->Length;
1648 
1649             ItsNumber = 0;
1650             while (*PFieldList)
1651             {
1652                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1653                     &Subtable, TRUE);
1654                 if (ACPI_FAILURE (Status))
1655                 {
1656                     return (Status);
1657                 }
1658                 if (!Subtable)
1659                 {
1660                     break;
1661                 }
1662 
1663                 DtInsertSubtable (ParentTable, Subtable);
1664                 NodeLength += Subtable->Length;
1665                 ItsNumber++;
1666             }
1667 
1668             IortItsGroup->ItsCount = ItsNumber;
1669             break;
1670 
1671         case ACPI_IORT_NODE_NAMED_COMPONENT:
1672 
1673             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1674                 &Subtable, TRUE);
1675             if (ACPI_FAILURE (Status))
1676             {
1677                 return (Status);
1678             }
1679 
1680             DtInsertSubtable (ParentTable, Subtable);
1681             NodeLength += Subtable->Length;
1682 
1683             /*
1684              * Padding - Variable-length data
1685              * Optionally allows the offset of the ID mappings to be used
1686              * for filling this field.
1687              */
1688             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1689                 &Subtable, TRUE);
1690             if (ACPI_FAILURE (Status))
1691             {
1692                 return (Status);
1693             }
1694 
1695             if (Subtable)
1696             {
1697                 DtInsertSubtable (ParentTable, Subtable);
1698                 NodeLength += Subtable->Length;
1699             }
1700             else
1701             {
1702                 if (NodeLength > IortNode->MappingOffset)
1703                 {
1704                     return (AE_BAD_DATA);
1705                 }
1706 
1707                 if (NodeLength < IortNode->MappingOffset)
1708                 {
1709                     Status = DtCompilePadding (
1710                         IortNode->MappingOffset - NodeLength,
1711                         &Subtable);
1712                     if (ACPI_FAILURE (Status))
1713                     {
1714                         return (Status);
1715                     }
1716 
1717                     DtInsertSubtable (ParentTable, Subtable);
1718                     NodeLength = IortNode->MappingOffset;
1719                 }
1720             }
1721             break;
1722 
1723         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1724 
1725             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1726                 &Subtable, TRUE);
1727             if (ACPI_FAILURE (Status))
1728             {
1729                 return (Status);
1730             }
1731 
1732             DtInsertSubtable (ParentTable, Subtable);
1733             NodeLength += Subtable->Length;
1734             break;
1735 
1736         case ACPI_IORT_NODE_SMMU:
1737 
1738             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1739                 &Subtable, TRUE);
1740             if (ACPI_FAILURE (Status))
1741             {
1742                 return (Status);
1743             }
1744 
1745             DtInsertSubtable (ParentTable, Subtable);
1746             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1747             NodeLength += Subtable->Length;
1748 
1749             /* Compile global interrupt array */
1750 
1751             IortSmmu->GlobalInterruptOffset = NodeLength;
1752             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1753                 &Subtable, TRUE);
1754             if (ACPI_FAILURE (Status))
1755             {
1756                 return (Status);
1757             }
1758 
1759             DtInsertSubtable (ParentTable, Subtable);
1760             NodeLength += Subtable->Length;
1761 
1762             /* Compile context interrupt array */
1763 
1764             ContextIrptNumber = 0;
1765             IortSmmu->ContextInterruptOffset = NodeLength;
1766             while (*PFieldList)
1767             {
1768                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1769                     &Subtable, TRUE);
1770                 if (ACPI_FAILURE (Status))
1771                 {
1772                     return (Status);
1773                 }
1774 
1775                 if (!Subtable)
1776                 {
1777                     break;
1778                 }
1779 
1780                 DtInsertSubtable (ParentTable, Subtable);
1781                 NodeLength += Subtable->Length;
1782                 ContextIrptNumber++;
1783             }
1784 
1785             IortSmmu->ContextInterruptCount = ContextIrptNumber;
1786 
1787             /* Compile PMU interrupt array */
1788 
1789             PmuIrptNumber = 0;
1790             IortSmmu->PmuInterruptOffset = NodeLength;
1791             while (*PFieldList)
1792             {
1793                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1794                     &Subtable, TRUE);
1795                 if (ACPI_FAILURE (Status))
1796                 {
1797                     return (Status);
1798                 }
1799 
1800                 if (!Subtable)
1801                 {
1802                     break;
1803                 }
1804 
1805                 DtInsertSubtable (ParentTable, Subtable);
1806                 NodeLength += Subtable->Length;
1807                 PmuIrptNumber++;
1808             }
1809 
1810             IortSmmu->PmuInterruptCount = PmuIrptNumber;
1811             break;
1812 
1813         case ACPI_IORT_NODE_SMMU_V3:
1814 
1815             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
1816                 &Subtable, TRUE);
1817             if (ACPI_FAILURE (Status))
1818             {
1819                 return (Status);
1820             }
1821 
1822             DtInsertSubtable (ParentTable, Subtable);
1823             NodeLength += Subtable->Length;
1824             break;
1825 
1826         default:
1827 
1828             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1829             return (AE_ERROR);
1830         }
1831 
1832         /* Compile Array of ID mappings */
1833 
1834         IortNode->MappingOffset = NodeLength;
1835         IdMappingNumber = 0;
1836         while (*PFieldList)
1837         {
1838             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1839                 &Subtable, TRUE);
1840             if (ACPI_FAILURE (Status))
1841             {
1842                 return (Status);
1843             }
1844 
1845             if (!Subtable)
1846             {
1847                 break;
1848             }
1849 
1850             DtInsertSubtable (ParentTable, Subtable);
1851             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1852             IdMappingNumber++;
1853         }
1854 
1855         IortNode->MappingCount = IdMappingNumber;
1856         if (!IdMappingNumber)
1857         {
1858             IortNode->MappingOffset = 0;
1859         }
1860 
1861         /*
1862          * Node length can be determined by DT_LENGTH option
1863          * IortNode->Length = NodeLength;
1864          */
1865         DtPopSubtable ();
1866         ParentTable = DtPeekSubtable ();
1867         NodeNumber++;
1868     }
1869 
1870     Iort->NodeCount = NodeNumber;
1871     return (AE_OK);
1872 }
1873 
1874 
1875 /******************************************************************************
1876  *
1877  * FUNCTION:    DtCompileIvrs
1878  *
1879  * PARAMETERS:  List                - Current field list pointer
1880  *
1881  * RETURN:      Status
1882  *
1883  * DESCRIPTION: Compile IVRS.
1884  *
1885  *****************************************************************************/
1886 
1887 ACPI_STATUS
1888 DtCompileIvrs (
1889     void                    **List)
1890 {
1891     ACPI_STATUS             Status;
1892     DT_SUBTABLE             *Subtable;
1893     DT_SUBTABLE             *ParentTable;
1894     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1895     DT_FIELD                *SubtableStart;
1896     ACPI_DMTABLE_INFO       *InfoTable;
1897     ACPI_IVRS_HEADER        *IvrsHeader;
1898     UINT8                   EntryType;
1899 
1900 
1901     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1902         &Subtable, TRUE);
1903     if (ACPI_FAILURE (Status))
1904     {
1905         return (Status);
1906     }
1907 
1908     ParentTable = DtPeekSubtable ();
1909     DtInsertSubtable (ParentTable, Subtable);
1910 
1911     while (*PFieldList)
1912     {
1913         SubtableStart = *PFieldList;
1914         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1915             &Subtable, TRUE);
1916         if (ACPI_FAILURE (Status))
1917         {
1918             return (Status);
1919         }
1920 
1921         ParentTable = DtPeekSubtable ();
1922         DtInsertSubtable (ParentTable, Subtable);
1923         DtPushSubtable (Subtable);
1924 
1925         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1926 
1927         switch (IvrsHeader->Type)
1928         {
1929         case ACPI_IVRS_TYPE_HARDWARE:
1930 
1931             InfoTable = AcpiDmTableInfoIvrs0;
1932             break;
1933 
1934         case ACPI_IVRS_TYPE_MEMORY1:
1935         case ACPI_IVRS_TYPE_MEMORY2:
1936         case ACPI_IVRS_TYPE_MEMORY3:
1937 
1938             InfoTable = AcpiDmTableInfoIvrs1;
1939             break;
1940 
1941         default:
1942 
1943             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1944             return (AE_ERROR);
1945         }
1946 
1947         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1948         if (ACPI_FAILURE (Status))
1949         {
1950             return (Status);
1951         }
1952 
1953         ParentTable = DtPeekSubtable ();
1954         DtInsertSubtable (ParentTable, Subtable);
1955 
1956         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1957         {
1958             while (*PFieldList &&
1959                 !strcmp ((*PFieldList)->Name, "Entry Type"))
1960             {
1961                 SubtableStart = *PFieldList;
1962                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1963 
1964                 switch (EntryType)
1965                 {
1966                 /* 4-byte device entries */
1967 
1968                 case ACPI_IVRS_TYPE_PAD4:
1969                 case ACPI_IVRS_TYPE_ALL:
1970                 case ACPI_IVRS_TYPE_SELECT:
1971                 case ACPI_IVRS_TYPE_START:
1972                 case ACPI_IVRS_TYPE_END:
1973 
1974                     InfoTable = AcpiDmTableInfoIvrs4;
1975                     break;
1976 
1977                 /* 8-byte entries, type A */
1978 
1979                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1980                 case ACPI_IVRS_TYPE_ALIAS_START:
1981 
1982                     InfoTable = AcpiDmTableInfoIvrs8a;
1983                     break;
1984 
1985                 /* 8-byte entries, type B */
1986 
1987                 case ACPI_IVRS_TYPE_PAD8:
1988                 case ACPI_IVRS_TYPE_EXT_SELECT:
1989                 case ACPI_IVRS_TYPE_EXT_START:
1990 
1991                     InfoTable = AcpiDmTableInfoIvrs8b;
1992                     break;
1993 
1994                 /* 8-byte entries, type C */
1995 
1996                 case ACPI_IVRS_TYPE_SPECIAL:
1997 
1998                     InfoTable = AcpiDmTableInfoIvrs8c;
1999                     break;
2000 
2001                 default:
2002 
2003                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
2004                         "IVRS Device Entry");
2005                     return (AE_ERROR);
2006                 }
2007 
2008                 Status = DtCompileTable (PFieldList, InfoTable,
2009                     &Subtable, TRUE);
2010                 if (ACPI_FAILURE (Status))
2011                 {
2012                     return (Status);
2013                 }
2014 
2015                 DtInsertSubtable (ParentTable, Subtable);
2016             }
2017         }
2018 
2019         DtPopSubtable ();
2020     }
2021 
2022     return (AE_OK);
2023 }
2024