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