xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable1.c (revision 058ac3e8063366dafa634d9107642e12b038bf09)
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 - 2022, 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:    DtCompileAest
176  *
177  * PARAMETERS:  List                - Current field list pointer
178  *
179  * RETURN:      Status
180  *
181  * DESCRIPTION: Compile AEST.
182  *
183  * NOTE: Assumes the following table structure:
184  *      For all AEST Error Nodes:
185  *          1) An AEST Error Node, followed immediately by:
186  *          2) Any node-specific data
187  *          3) An Interface Structure (one)
188  *          4) A list (array) of Interrupt Structures, the count as specified
189  *              in the NodeInterruptCount field of the Error Node header.
190  *
191  * AEST - ARM Error Source table. Conforms to:
192  * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020
193  *
194  *****************************************************************************/
195 
196 ACPI_STATUS
197 DtCompileAest (
198     void                    **List)
199 {
200     ACPI_AEST_HEADER        *ErrorNodeHeader;
201     ACPI_AEST_PROCESSOR     *AestProcessor;
202     DT_SUBTABLE             *Subtable;
203     DT_SUBTABLE             *ParentTable;
204     ACPI_DMTABLE_INFO       *InfoTable;
205     ACPI_STATUS             Status;
206     UINT32                  i;
207     UINT32                  Offset;
208     DT_FIELD                **PFieldList = (DT_FIELD **) List;
209 
210 
211     while (*PFieldList)
212     {
213         /* Compile the common error node header */
214 
215         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr,
216             &Subtable);
217         if (ACPI_FAILURE (Status))
218         {
219             return (Status);
220         }
221 
222         ParentTable = DtPeekSubtable ();
223         DtInsertSubtable (ParentTable, Subtable);
224 
225         /* Everything past the error node header will be a subtable */
226 
227         DtPushSubtable (Subtable);
228 
229         /*
230          * Compile the node-specific structure (Based on the error
231          * node header Type field)
232          */
233         ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer);
234 
235         /* Point past the common error node header */
236 
237         Offset = sizeof (ACPI_AEST_HEADER);
238         ErrorNodeHeader->NodeSpecificOffset = Offset;
239 
240         /* Decode the error node type */
241 
242         switch (ErrorNodeHeader->Type)
243         {
244         case ACPI_AEST_PROCESSOR_ERROR_NODE:
245 
246             InfoTable = AcpiDmTableInfoAestProcError;
247             break;
248 
249         case ACPI_AEST_MEMORY_ERROR_NODE:
250 
251             InfoTable = AcpiDmTableInfoAestMemError;
252             break;
253 
254         case ACPI_AEST_SMMU_ERROR_NODE:
255 
256             InfoTable = AcpiDmTableInfoAestSmmuError;
257             break;
258 
259         case ACPI_AEST_VENDOR_ERROR_NODE:
260 
261             InfoTable = AcpiDmTableInfoAestVendorError;
262             break;
263 
264         case ACPI_AEST_GIC_ERROR_NODE:
265 
266             InfoTable = AcpiDmTableInfoAestGicError;
267             break;
268 
269         /* Error case below */
270         default:
271             AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n",
272                 ErrorNodeHeader->Type);
273             return (AE_ERROR);
274         }
275 
276         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
277         if (ACPI_FAILURE (Status))
278         {
279             return (Status);
280         }
281 
282         /* Point past the node-specific structure */
283 
284         Offset += Subtable->Length;
285         ErrorNodeHeader->NodeInterfaceOffset = Offset;
286 
287         ParentTable = DtPeekSubtable ();
288         DtInsertSubtable (ParentTable, Subtable);
289 
290         /* Compile any additional node-specific substructures */
291 
292         if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
293         {
294             /*
295              * Special handling for PROCESSOR_ERROR_NODE subtables
296              * (to handle the Resource Substructure via the ResourceType
297              * field).
298              */
299             AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR,
300                 Subtable->Buffer);
301 
302             switch (AestProcessor->ResourceType)
303             {
304             case ACPI_AEST_CACHE_RESOURCE:
305 
306                 InfoTable = AcpiDmTableInfoAestCacheRsrc;
307                 break;
308 
309             case ACPI_AEST_TLB_RESOURCE:
310 
311                 InfoTable = AcpiDmTableInfoAestTlbRsrc;
312                 break;
313 
314             case ACPI_AEST_GENERIC_RESOURCE:
315 
316                 InfoTable = AcpiDmTableInfoAestGenRsrc;
317                 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n",
318                     AestProcessor->ResourceType);
319                 return (AE_ERROR);
320 
321             /* Error case below */
322             default:
323                 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n",
324                     AestProcessor->ResourceType);
325                 return (AE_ERROR);
326             }
327 
328             Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
329             if (ACPI_FAILURE (Status))
330             {
331                 return (Status);
332             }
333 
334             /* Point past the resource substructure subtable */
335 
336             Offset += Subtable->Length;
337             ErrorNodeHeader->NodeInterfaceOffset = Offset;
338 
339             ParentTable = DtPeekSubtable ();
340             DtInsertSubtable (ParentTable, Subtable);
341         }
342 
343         /* Compile the (required) node interface structure */
344 
345         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface,
346             &Subtable);
347         if (ACPI_FAILURE (Status))
348         {
349             return (Status);
350         }
351 
352         ErrorNodeHeader->NodeInterruptOffset = 0;
353         ParentTable = DtPeekSubtable ();
354         DtInsertSubtable (ParentTable, Subtable);
355 
356         /* Compile each of the node interrupt structures */
357 
358         if (ErrorNodeHeader->NodeInterruptCount)
359         {
360             /* Point to the first interrupt structure */
361 
362             Offset += Subtable->Length;
363             ErrorNodeHeader->NodeInterruptOffset = Offset;
364         }
365 
366         /* Compile each of the interrupt structures */
367 
368         for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++)
369         {
370             Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt,
371                 &Subtable);
372             if (ACPI_FAILURE (Status))
373             {
374                 return (Status);
375             }
376 
377             ParentTable = DtPeekSubtable ();
378             DtInsertSubtable (ParentTable, Subtable);
379         }
380 
381         /* Prepare for the next AEST Error node */
382 
383         DtPopSubtable ();
384     }
385 
386     return (AE_OK);
387 }
388 
389 
390 /******************************************************************************
391  *
392  * FUNCTION:    DtCompileApmt
393  *
394  * PARAMETERS:  List                - Current field list pointer
395  *
396  * RETURN:      Status
397  *
398  * DESCRIPTION: Compile APMT.
399  *
400  *****************************************************************************/
401 
402 ACPI_STATUS
403 DtCompileApmt (
404     void                    **List)
405 {
406     ACPI_STATUS             Status;
407     ACPI_TABLE_HEADER       *Header;
408     ACPI_APMT_NODE          *ApmtNode;
409     ACPI_APMT_NODE          *PeerApmtNode;
410     DT_SUBTABLE             *Subtable;
411     DT_SUBTABLE             *PeerSubtable;
412     DT_SUBTABLE             *ParentTable;
413     DT_FIELD                **PFieldList = (DT_FIELD**)List;
414     DT_FIELD                *SubtableStart;
415     UINT32                  CurLength;
416     char                    MsgBuffer[64] = "";
417 
418     ParentTable = DtPeekSubtable();
419 
420     Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer);
421 
422     CurLength = sizeof(ACPI_TABLE_HEADER);
423 
424     /* Walk the parse tree */
425 
426     while (*PFieldList)
427     {
428         /* APMT Node Subtable */
429 
430         SubtableStart = *PFieldList;
431 
432         Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable);
433 
434         if (ACPI_FAILURE(Status))
435         {
436             return (Status);
437         }
438 
439         ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer);
440 
441         if (ApmtNode->Length != sizeof(ACPI_APMT_NODE))
442         {
443             DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT");
444             return (AE_ERROR);
445         }
446 
447         if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT)
448         {
449             snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type);
450             DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer);
451             return (AE_ERROR);
452         }
453 
454         PeerSubtable = DtGetNextSubtable(ParentTable, NULL);
455 
456         /* Validate the node id needs to be unique. */
457         while(PeerSubtable)
458         {
459             PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer);
460             if (PeerApmtNode->Id == ApmtNode->Id)
461             {
462                 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id);
463                 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer);
464                 return (AE_ERROR);
465             }
466 
467             PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable);
468         }
469 
470         CurLength += ApmtNode->Length;
471 
472         DtInsertSubtable(ParentTable, Subtable);
473     }
474 
475     if (Header->Length != CurLength)
476     {
477         snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)",
478             Header->Length, CurLength);
479         DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer);
480         return (AE_ERROR);
481     }
482 
483     return (AE_OK);
484 }
485 
486 /******************************************************************************
487  *
488  * FUNCTION:    DtCompileAsf
489  *
490  * PARAMETERS:  List                - Current field list pointer
491  *
492  * RETURN:      Status
493  *
494  * DESCRIPTION: Compile ASF!.
495  *
496  *****************************************************************************/
497 
498 ACPI_STATUS
499 DtCompileAsf (
500     void                    **List)
501 {
502     ACPI_ASF_INFO           *AsfTable;
503     DT_SUBTABLE             *Subtable;
504     DT_SUBTABLE             *ParentTable;
505     ACPI_DMTABLE_INFO       *InfoTable;
506     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
507     UINT32                  DataCount = 0;
508     ACPI_STATUS             Status;
509     UINT32                  i;
510     DT_FIELD                **PFieldList = (DT_FIELD **) List;
511     DT_FIELD                *SubtableStart;
512 
513 
514     while (*PFieldList)
515     {
516         SubtableStart = *PFieldList;
517         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
518             &Subtable);
519         if (ACPI_FAILURE (Status))
520         {
521             return (Status);
522         }
523 
524         ParentTable = DtPeekSubtable ();
525         DtInsertSubtable (ParentTable, Subtable);
526         DtPushSubtable (Subtable);
527 
528         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
529 
530         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
531         {
532         case ACPI_ASF_TYPE_INFO:
533 
534             InfoTable = AcpiDmTableInfoAsf0;
535             break;
536 
537         case ACPI_ASF_TYPE_ALERT:
538 
539             InfoTable = AcpiDmTableInfoAsf1;
540             break;
541 
542         case ACPI_ASF_TYPE_CONTROL:
543 
544             InfoTable = AcpiDmTableInfoAsf2;
545             break;
546 
547         case ACPI_ASF_TYPE_BOOT:
548 
549             InfoTable = AcpiDmTableInfoAsf3;
550             break;
551 
552         case ACPI_ASF_TYPE_ADDRESS:
553 
554             InfoTable = AcpiDmTableInfoAsf4;
555             break;
556 
557         default:
558 
559             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
560             return (AE_ERROR);
561         }
562 
563         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
564         if (ACPI_FAILURE (Status))
565         {
566             return (Status);
567         }
568 
569         ParentTable = DtPeekSubtable ();
570         DtInsertSubtable (ParentTable, Subtable);
571 
572         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
573         {
574         case ACPI_ASF_TYPE_INFO:
575 
576             DataInfoTable = NULL;
577             break;
578 
579         case ACPI_ASF_TYPE_ALERT:
580 
581             DataInfoTable = AcpiDmTableInfoAsf1a;
582             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
583                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
584                     sizeof (ACPI_ASF_HEADER)))->Alerts;
585             break;
586 
587         case ACPI_ASF_TYPE_CONTROL:
588 
589             DataInfoTable = AcpiDmTableInfoAsf2a;
590             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
591                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
592                     sizeof (ACPI_ASF_HEADER)))->Controls;
593             break;
594 
595         case ACPI_ASF_TYPE_BOOT:
596 
597             DataInfoTable = NULL;
598             break;
599 
600         case ACPI_ASF_TYPE_ADDRESS:
601 
602             DataInfoTable = TableInfoAsfAddress;
603             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
604                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
605                     sizeof (ACPI_ASF_HEADER)))->Devices;
606             break;
607 
608         default:
609 
610             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
611             return (AE_ERROR);
612         }
613 
614         if (DataInfoTable)
615         {
616             switch (AsfTable->Header.Type & 0x7F)
617             {
618             case ACPI_ASF_TYPE_ADDRESS:
619 
620                 while (DataCount > 0)
621                 {
622                     Status = DtCompileTable (PFieldList, DataInfoTable,
623                         &Subtable);
624                     if (ACPI_FAILURE (Status))
625                     {
626                         return (Status);
627                     }
628 
629                     DtInsertSubtable (ParentTable, Subtable);
630                     DataCount = DataCount - Subtable->Length;
631                 }
632                 break;
633 
634             default:
635 
636                 for (i = 0; i < DataCount; i++)
637                 {
638                     Status = DtCompileTable (PFieldList, DataInfoTable,
639                         &Subtable);
640                     if (ACPI_FAILURE (Status))
641                     {
642                         return (Status);
643                     }
644 
645                     DtInsertSubtable (ParentTable, Subtable);
646                 }
647                 break;
648             }
649         }
650 
651         DtPopSubtable ();
652     }
653 
654     return (AE_OK);
655 }
656 
657 
658 /******************************************************************************
659  *
660  * FUNCTION:    DtCompileCdat
661  *
662  * PARAMETERS:  List                - Current field list pointer
663  *
664  * RETURN:      Status
665  *
666  * DESCRIPTION: Compile CDAT.
667  *
668  *****************************************************************************/
669 
670 ACPI_STATUS
671 DtCompileCdat (
672     void                    **List)
673 {
674     ACPI_STATUS             Status = AE_OK;
675     DT_SUBTABLE             *Subtable;
676     DT_SUBTABLE             *ParentTable;
677     DT_FIELD                **PFieldList = (DT_FIELD **) List;
678     ACPI_CDAT_HEADER        *CdatHeader;
679     ACPI_DMTABLE_INFO       *InfoTable = NULL;
680     DT_FIELD                *SubtableStart;
681 
682 
683     /* Walk the parse tree.
684      *
685      * Note: Main table consists of only the CDAT table header
686      * (This is not the standard ACPI table header, however)--
687      * Followed by some number of subtables.
688      */
689     while (*PFieldList)
690     {
691         SubtableStart = *PFieldList;
692 
693         /* Compile the expected CDAT Subtable header */
694 
695         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader,
696             &Subtable);
697         if (ACPI_FAILURE (Status))
698         {
699             return (Status);
700         }
701 
702         ParentTable = DtPeekSubtable ();
703         DtInsertSubtable (ParentTable, Subtable);
704         DtPushSubtable (Subtable);
705 
706         CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer);
707 
708         /* Decode the subtable by type */
709 
710         switch (CdatHeader->Type)
711         {
712         case ACPI_CDAT_TYPE_DSMAS:
713             InfoTable = AcpiDmTableInfoCdat0;
714             break;
715 
716         case ACPI_CDAT_TYPE_DSLBIS:
717             InfoTable = AcpiDmTableInfoCdat1;
718             break;
719 
720         case ACPI_CDAT_TYPE_DSMSCIS:
721             InfoTable = AcpiDmTableInfoCdat2;
722             break;
723 
724         case ACPI_CDAT_TYPE_DSIS:
725             InfoTable = AcpiDmTableInfoCdat3;
726             break;
727 
728         case ACPI_CDAT_TYPE_DSEMTS:
729             InfoTable = AcpiDmTableInfoCdat4;
730             break;
731 
732         case ACPI_CDAT_TYPE_SSLBIS:
733             InfoTable = AcpiDmTableInfoCdat5;
734             break;
735 
736         default:
737             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT");
738         }
739 
740         /* Compile the CDAT subtable */
741 
742         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
743         if (ACPI_FAILURE (Status))
744         {
745             return (Status);
746         }
747 
748         ParentTable = DtPeekSubtable ();
749         DtInsertSubtable (ParentTable, Subtable);
750 
751         switch (CdatHeader->Type)
752         {
753         /* Multiple entries supported for this type */
754 
755         case ACPI_CDAT_TYPE_SSLBIS:
756 
757             /*
758              * Check for multiple SSLBEs
759              */
760             while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID"))
761             {
762                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable);
763                 if (ACPI_FAILURE (Status))
764                 {
765                     return (Status);
766                 }
767                 ParentTable = DtPeekSubtable ();
768                 DtInsertSubtable (ParentTable, Subtable);
769             }
770             break;
771 
772         default:
773              break;
774         }
775 
776         /* Pop off the CDAT Subtable header subtree */
777 
778         DtPopSubtable ();
779     }
780 
781     return (AE_OK);
782 }
783 
784 
785 /******************************************************************************
786  *
787  * FUNCTION:    DtCompileCedt
788  *
789  * PARAMETERS:  List                - Current field list pointer
790  *
791  * RETURN:      Status
792  *
793  * DESCRIPTION: Compile CEDT.
794  *
795  *****************************************************************************/
796 
797 ACPI_STATUS
798 DtCompileCedt (
799     void                    **List)
800 {
801     ACPI_STATUS             Status;
802     DT_SUBTABLE             *Subtable;
803     DT_SUBTABLE             *ParentTable;
804     DT_FIELD                **PFieldList = (DT_FIELD **) List;
805     ACPI_CEDT_HEADER        *CedtHeader;
806     DT_FIELD                *SubtableStart;
807 
808 
809     /* Walk the parse tree */
810 
811     while (*PFieldList)
812     {
813         /* if CFMWS and has more than one target, then set to zero later */
814 
815         int InsertFlag = 1;
816         SubtableStart = *PFieldList;
817 
818         /* CEDT Header */
819 
820         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
821             &Subtable);
822         if (ACPI_FAILURE (Status))
823         {
824             return (Status);
825         }
826 
827         ParentTable = DtPeekSubtable ();
828         DtInsertSubtable (ParentTable, Subtable);
829         DtPushSubtable (Subtable);
830 
831         CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
832 
833         switch (CedtHeader->Type)
834         {
835         case ACPI_CEDT_TYPE_CHBS:
836             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
837             if (ACPI_FAILURE (Status))
838             {
839                 return (Status);
840             }
841             break;
842         case ACPI_CEDT_TYPE_CFMWS: {
843             unsigned char *dump;
844             unsigned int idx, offset, max = 0;
845 
846             /* Compile table with first "Interleave target" */
847 
848             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable);
849             if (ACPI_FAILURE (Status))
850             {
851                 return (Status);
852             }
853 
854             /* Look in buffer for the number of targets */
855             offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays);
856             dump = (unsigned char *) Subtable->Buffer - 4;     /* place at beginning of cedt1 */
857             max = 0x01 << dump[offset];     /* 2^max, so 0=1, 1=2, 2=4, 3=8.  8 is MAX */
858             if (max > 8)    max=1;          /* Error in encoding Interleaving Ways. */
859             if (max == 1)                   /* if only one target, then break here. */
860                 break;                      /* break if only one target. */
861 
862             /* We need to add more interleave targets, so write the current Subtable. */
863 
864             ParentTable = DtPeekSubtable ();
865             DtInsertSubtable (ParentTable, Subtable);   /* Insert AcpiDmTableInfoCedt1 table so we can put in */
866             DtPushSubtable (Subtable);                  /* the targets > the first. */
867 
868             /* Now, find out all interleave targets beyond the first. */
869 
870             for (idx = 1; idx < max; idx++) {
871                 ParentTable = DtPeekSubtable ();
872 
873                 if (*PFieldList)
874                 {
875                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable);
876                     if (ACPI_FAILURE (Status))
877                     {
878                         return (Status);
879                     }
880                     if (Subtable)
881                     {
882                         DtInsertSubtable (ParentTable, Subtable);       /* got a target, so insert table. */
883                         InsertFlag = 0;
884                     }
885                 }
886             }
887 
888             DtPopSubtable ();
889             ParentTable = DtPeekSubtable ();
890             break;
891         }
892 
893         default:
894             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
895             return (AE_ERROR);
896         }
897 
898         ParentTable = DtPeekSubtable ();
899         if (InsertFlag == 1) {
900                 DtInsertSubtable (ParentTable, Subtable);
901         }
902         DtPopSubtable ();
903     }
904 
905     return (AE_OK);
906 }
907 
908 
909 /******************************************************************************
910  *
911  * FUNCTION:    DtCompileCpep
912  *
913  * PARAMETERS:  List                - Current field list pointer
914  *
915  * RETURN:      Status
916  *
917  * DESCRIPTION: Compile CPEP.
918  *
919  *****************************************************************************/
920 
921 ACPI_STATUS
922 DtCompileCpep (
923     void                    **List)
924 {
925     ACPI_STATUS             Status;
926 
927 
928     Status = DtCompileTwoSubtables (List,
929         AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
930     return (Status);
931 }
932 
933 
934 /******************************************************************************
935  *
936  * FUNCTION:    DtCompileCsrt
937  *
938  * PARAMETERS:  List                - Current field list pointer
939  *
940  * RETURN:      Status
941  *
942  * DESCRIPTION: Compile CSRT.
943  *
944  *****************************************************************************/
945 
946 ACPI_STATUS
947 DtCompileCsrt (
948     void                    **List)
949 {
950     ACPI_STATUS             Status = AE_OK;
951     DT_SUBTABLE             *Subtable;
952     DT_SUBTABLE             *ParentTable;
953     DT_FIELD                **PFieldList = (DT_FIELD **) List;
954     UINT32                  DescriptorCount;
955     UINT32                  GroupLength;
956 
957 
958     /* Subtables (Resource Groups) */
959 
960     ParentTable = DtPeekSubtable ();
961     while (*PFieldList)
962     {
963         /* Resource group subtable */
964 
965         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
966             &Subtable);
967         if (ACPI_FAILURE (Status))
968         {
969             return (Status);
970         }
971 
972         /* Compute the number of resource descriptors */
973 
974         GroupLength =
975             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
976                 Subtable->Buffer))->Length -
977             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
978                 Subtable->Buffer))->SharedInfoLength -
979             sizeof (ACPI_CSRT_GROUP);
980 
981         DescriptorCount = (GroupLength  /
982             sizeof (ACPI_CSRT_DESCRIPTOR));
983 
984         DtInsertSubtable (ParentTable, Subtable);
985         DtPushSubtable (Subtable);
986         ParentTable = DtPeekSubtable ();
987 
988         /* Shared info subtable (One per resource group) */
989 
990         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
991             &Subtable);
992         if (ACPI_FAILURE (Status))
993         {
994             return (Status);
995         }
996 
997         DtInsertSubtable (ParentTable, Subtable);
998 
999         /* Sub-Subtables (Resource Descriptors) */
1000 
1001         while (*PFieldList && DescriptorCount)
1002         {
1003 
1004             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
1005                 &Subtable);
1006             if (ACPI_FAILURE (Status))
1007             {
1008                 return (Status);
1009             }
1010 
1011             DtInsertSubtable (ParentTable, Subtable);
1012 
1013             DtPushSubtable (Subtable);
1014             ParentTable = DtPeekSubtable ();
1015             if (*PFieldList)
1016             {
1017                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
1018                     &Subtable);
1019                 if (ACPI_FAILURE (Status))
1020                 {
1021                     return (Status);
1022                 }
1023                 if (Subtable)
1024                 {
1025                     DtInsertSubtable (ParentTable, Subtable);
1026                 }
1027             }
1028 
1029             DtPopSubtable ();
1030             ParentTable = DtPeekSubtable ();
1031             DescriptorCount--;
1032         }
1033 
1034         DtPopSubtable ();
1035         ParentTable = DtPeekSubtable ();
1036     }
1037 
1038     return (Status);
1039 }
1040 
1041 
1042 /******************************************************************************
1043  *
1044  * FUNCTION:    DtCompileDbg2
1045  *
1046  * PARAMETERS:  List                - Current field list pointer
1047  *
1048  * RETURN:      Status
1049  *
1050  * DESCRIPTION: Compile DBG2.
1051  *
1052  *****************************************************************************/
1053 
1054 ACPI_STATUS
1055 DtCompileDbg2 (
1056     void                    **List)
1057 {
1058     ACPI_STATUS             Status;
1059     DT_SUBTABLE             *Subtable;
1060     DT_SUBTABLE             *ParentTable;
1061     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1062     UINT32                  SubtableCount;
1063     ACPI_DBG2_HEADER        *Dbg2Header;
1064     ACPI_DBG2_DEVICE        *DeviceInfo;
1065     UINT16                  CurrentOffset;
1066     UINT32                  i;
1067 
1068 
1069     /* Main table */
1070 
1071     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
1072     if (ACPI_FAILURE (Status))
1073     {
1074         return (Status);
1075     }
1076 
1077     ParentTable = DtPeekSubtable ();
1078     DtInsertSubtable (ParentTable, Subtable);
1079 
1080     /* Main table fields */
1081 
1082     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
1083     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
1084         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
1085 
1086     SubtableCount = Dbg2Header->InfoCount;
1087     DtPushSubtable (Subtable);
1088 
1089     /* Process all Device Information subtables (Count = InfoCount) */
1090 
1091     while (*PFieldList && SubtableCount)
1092     {
1093         /* Subtable: Debug Device Information */
1094 
1095         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
1096             &Subtable);
1097         if (ACPI_FAILURE (Status))
1098         {
1099             return (Status);
1100         }
1101 
1102         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
1103         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
1104 
1105         ParentTable = DtPeekSubtable ();
1106         DtInsertSubtable (ParentTable, Subtable);
1107         DtPushSubtable (Subtable);
1108 
1109         ParentTable = DtPeekSubtable ();
1110 
1111         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
1112 
1113         DeviceInfo->BaseAddressOffset = CurrentOffset;
1114         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
1115         {
1116             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
1117                 &Subtable);
1118             if (ACPI_FAILURE (Status))
1119             {
1120                 return (Status);
1121             }
1122 
1123             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
1124             DtInsertSubtable (ParentTable, Subtable);
1125         }
1126 
1127         /* AddressSize array (Required, size = RegisterCount) */
1128 
1129         DeviceInfo->AddressSizeOffset = CurrentOffset;
1130         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
1131         {
1132             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
1133                 &Subtable);
1134             if (ACPI_FAILURE (Status))
1135             {
1136                 return (Status);
1137             }
1138 
1139             CurrentOffset += (UINT16) sizeof (UINT32);
1140             DtInsertSubtable (ParentTable, Subtable);
1141         }
1142 
1143         /* NamespaceString device identifier (Required, size = NamePathLength) */
1144 
1145         DeviceInfo->NamepathOffset = CurrentOffset;
1146         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
1147             &Subtable);
1148         if (ACPI_FAILURE (Status))
1149         {
1150             return (Status);
1151         }
1152 
1153         /* Update the device info header */
1154 
1155         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
1156         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
1157         DtInsertSubtable (ParentTable, Subtable);
1158 
1159         /* OemData - Variable-length data (Optional, size = OemDataLength) */
1160 
1161         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
1162             &Subtable);
1163         if (Status == AE_END_OF_TABLE)
1164         {
1165             /* optional field was not found and we're at the end of the file */
1166 
1167             goto subtableDone;
1168         }
1169         else if (ACPI_FAILURE (Status))
1170         {
1171             return (Status);
1172         }
1173 
1174         /* Update the device info header (zeros if no OEM data present) */
1175 
1176         DeviceInfo->OemDataOffset = 0;
1177         DeviceInfo->OemDataLength = 0;
1178 
1179         /* Optional subtable (OemData) */
1180 
1181         if (Subtable && Subtable->Length)
1182         {
1183             DeviceInfo->OemDataOffset = CurrentOffset;
1184             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
1185 
1186             DtInsertSubtable (ParentTable, Subtable);
1187         }
1188 subtableDone:
1189         SubtableCount--;
1190         DtPopSubtable (); /* Get next Device Information subtable */
1191     }
1192 
1193     DtPopSubtable ();
1194     return (AE_OK);
1195 }
1196 
1197 
1198 /******************************************************************************
1199  *
1200  * FUNCTION:    DtCompileDmar
1201  *
1202  * PARAMETERS:  List                - Current field list pointer
1203  *
1204  * RETURN:      Status
1205  *
1206  * DESCRIPTION: Compile DMAR.
1207  *
1208  *****************************************************************************/
1209 
1210 ACPI_STATUS
1211 DtCompileDmar (
1212     void                    **List)
1213 {
1214     ACPI_STATUS             Status;
1215     DT_SUBTABLE             *Subtable;
1216     DT_SUBTABLE             *ParentTable;
1217     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1218     DT_FIELD                *SubtableStart;
1219     ACPI_DMTABLE_INFO       *InfoTable;
1220     ACPI_DMAR_HEADER        *DmarHeader;
1221     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
1222     UINT32                  DeviceScopeLength;
1223     UINT32                  PciPathLength;
1224 
1225 
1226     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
1227     if (ACPI_FAILURE (Status))
1228     {
1229         return (Status);
1230     }
1231 
1232     ParentTable = DtPeekSubtable ();
1233     DtInsertSubtable (ParentTable, Subtable);
1234     DtPushSubtable (Subtable);
1235 
1236     while (*PFieldList)
1237     {
1238         /* DMAR Header */
1239 
1240         SubtableStart = *PFieldList;
1241         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
1242             &Subtable);
1243         if (ACPI_FAILURE (Status))
1244         {
1245             return (Status);
1246         }
1247 
1248         ParentTable = DtPeekSubtable ();
1249         DtInsertSubtable (ParentTable, Subtable);
1250         DtPushSubtable (Subtable);
1251 
1252         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
1253 
1254         switch (DmarHeader->Type)
1255         {
1256         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1257 
1258             InfoTable = AcpiDmTableInfoDmar0;
1259             break;
1260 
1261         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1262 
1263             InfoTable = AcpiDmTableInfoDmar1;
1264             break;
1265 
1266         case ACPI_DMAR_TYPE_ROOT_ATS:
1267 
1268             InfoTable = AcpiDmTableInfoDmar2;
1269             break;
1270 
1271         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1272 
1273             InfoTable = AcpiDmTableInfoDmar3;
1274             break;
1275 
1276         case ACPI_DMAR_TYPE_NAMESPACE:
1277 
1278             InfoTable = AcpiDmTableInfoDmar4;
1279             break;
1280 
1281         case ACPI_DMAR_TYPE_SATC:
1282 
1283             InfoTable = AcpiDmTableInfoDmar5;
1284             break;
1285 
1286         default:
1287 
1288             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
1289             return (AE_ERROR);
1290         }
1291 
1292         /* DMAR Subtable */
1293 
1294         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1295         if (ACPI_FAILURE (Status))
1296         {
1297             return (Status);
1298         }
1299 
1300         ParentTable = DtPeekSubtable ();
1301         DtInsertSubtable (ParentTable, Subtable);
1302 
1303         /*
1304          * Optional Device Scope subtables
1305          */
1306         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1307             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
1308         {
1309             /* These types do not support device scopes */
1310 
1311             DtPopSubtable ();
1312             continue;
1313         }
1314 
1315         DtPushSubtable (Subtable);
1316         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
1317             ParentTable->Length;
1318         while (DeviceScopeLength)
1319         {
1320             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
1321                 &Subtable);
1322             if (Status == AE_NOT_FOUND)
1323             {
1324                 break;
1325             }
1326 
1327             ParentTable = DtPeekSubtable ();
1328             DtInsertSubtable (ParentTable, Subtable);
1329             DtPushSubtable (Subtable);
1330 
1331             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
1332 
1333             /* Optional PCI Paths */
1334 
1335             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
1336             while (PciPathLength)
1337             {
1338                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
1339                     &Subtable);
1340                 if (Status == AE_NOT_FOUND)
1341                 {
1342                     DtPopSubtable ();
1343                     break;
1344                 }
1345 
1346                 ParentTable = DtPeekSubtable ();
1347                 DtInsertSubtable (ParentTable, Subtable);
1348                 PciPathLength -= Subtable->Length;
1349             }
1350 
1351             DtPopSubtable ();
1352             DeviceScopeLength -= DmarDeviceScope->Length;
1353         }
1354 
1355         DtPopSubtable ();
1356         DtPopSubtable ();
1357     }
1358 
1359     return (AE_OK);
1360 }
1361 
1362 
1363 /******************************************************************************
1364  *
1365  * FUNCTION:    DtCompileDrtm
1366  *
1367  * PARAMETERS:  List                - Current field list pointer
1368  *
1369  * RETURN:      Status
1370  *
1371  * DESCRIPTION: Compile DRTM.
1372  *
1373  *****************************************************************************/
1374 
1375 ACPI_STATUS
1376 DtCompileDrtm (
1377     void                    **List)
1378 {
1379     ACPI_STATUS             Status;
1380     DT_SUBTABLE             *Subtable;
1381     DT_SUBTABLE             *ParentTable;
1382     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1383     UINT32                  Count;
1384     /* ACPI_TABLE_DRTM         *Drtm; */
1385     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
1386     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1387     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
1388 
1389 
1390     ParentTable = DtPeekSubtable ();
1391 
1392     /* Compile DRTM header */
1393 
1394     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
1395         &Subtable);
1396     if (ACPI_FAILURE (Status))
1397     {
1398         return (Status);
1399     }
1400     DtInsertSubtable (ParentTable, Subtable);
1401 
1402     /*
1403      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1404      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1405      */
1406 #if 0
1407     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
1408         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1409 #endif
1410     /* Compile VTL */
1411 
1412     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
1413         &Subtable);
1414     if (ACPI_FAILURE (Status))
1415     {
1416         return (Status);
1417     }
1418 
1419     DtInsertSubtable (ParentTable, Subtable);
1420     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
1421 
1422     DtPushSubtable (Subtable);
1423     ParentTable = DtPeekSubtable ();
1424     Count = 0;
1425 
1426     while (*PFieldList)
1427     {
1428         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
1429             &Subtable);
1430         if (ACPI_FAILURE (Status))
1431         {
1432             return (Status);
1433         }
1434         if (!Subtable)
1435         {
1436             break;
1437         }
1438         DtInsertSubtable (ParentTable, Subtable);
1439         Count++;
1440     }
1441 
1442     DrtmVtl->ValidatedTableCount = Count;
1443     DtPopSubtable ();
1444     ParentTable = DtPeekSubtable ();
1445 
1446     /* Compile RL */
1447 
1448     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
1449         &Subtable);
1450     if (ACPI_FAILURE (Status))
1451     {
1452         return (Status);
1453     }
1454 
1455     DtInsertSubtable (ParentTable, Subtable);
1456     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
1457 
1458     DtPushSubtable (Subtable);
1459     ParentTable = DtPeekSubtable ();
1460     Count = 0;
1461 
1462     while (*PFieldList)
1463     {
1464         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
1465             &Subtable);
1466         if (ACPI_FAILURE (Status))
1467         {
1468             return (Status);
1469         }
1470 
1471         if (!Subtable)
1472         {
1473             break;
1474         }
1475 
1476         DtInsertSubtable (ParentTable, Subtable);
1477         Count++;
1478     }
1479 
1480     DrtmRl->ResourceCount = Count;
1481     DtPopSubtable ();
1482     ParentTable = DtPeekSubtable ();
1483 
1484     /* Compile DPS */
1485 
1486     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
1487         &Subtable);
1488     if (ACPI_FAILURE (Status))
1489     {
1490         return (Status);
1491     }
1492     DtInsertSubtable (ParentTable, Subtable);
1493     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
1494 
1495 
1496     return (AE_OK);
1497 }
1498 
1499 
1500 /******************************************************************************
1501  *
1502  * FUNCTION:    DtCompileEinj
1503  *
1504  * PARAMETERS:  List                - Current field list pointer
1505  *
1506  * RETURN:      Status
1507  *
1508  * DESCRIPTION: Compile EINJ.
1509  *
1510  *****************************************************************************/
1511 
1512 ACPI_STATUS
1513 DtCompileEinj (
1514     void                    **List)
1515 {
1516     ACPI_STATUS             Status;
1517 
1518 
1519     Status = DtCompileTwoSubtables (List,
1520         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
1521     return (Status);
1522 }
1523 
1524 
1525 /******************************************************************************
1526  *
1527  * FUNCTION:    DtCompileErst
1528  *
1529  * PARAMETERS:  List                - Current field list pointer
1530  *
1531  * RETURN:      Status
1532  *
1533  * DESCRIPTION: Compile ERST.
1534  *
1535  *****************************************************************************/
1536 
1537 ACPI_STATUS
1538 DtCompileErst (
1539     void                    **List)
1540 {
1541     ACPI_STATUS             Status;
1542 
1543 
1544     Status = DtCompileTwoSubtables (List,
1545         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1546     return (Status);
1547 }
1548 
1549 
1550 /******************************************************************************
1551  *
1552  * FUNCTION:    DtCompileGtdt
1553  *
1554  * PARAMETERS:  List                - Current field list pointer
1555  *
1556  * RETURN:      Status
1557  *
1558  * DESCRIPTION: Compile GTDT.
1559  *
1560  *****************************************************************************/
1561 
1562 ACPI_STATUS
1563 DtCompileGtdt (
1564     void                    **List)
1565 {
1566     ACPI_STATUS             Status;
1567     DT_SUBTABLE             *Subtable;
1568     DT_SUBTABLE             *ParentTable;
1569     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1570     DT_FIELD                *SubtableStart;
1571     ACPI_SUBTABLE_HEADER    *GtdtHeader;
1572     ACPI_DMTABLE_INFO       *InfoTable;
1573     UINT32                  GtCount;
1574     ACPI_TABLE_HEADER       *Header;
1575 
1576 
1577     ParentTable = DtPeekSubtable ();
1578 
1579     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1580 
1581     /* Compile the main table */
1582 
1583     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1584         &Subtable);
1585     if (ACPI_FAILURE (Status))
1586     {
1587         return (Status);
1588     }
1589 
1590     /* GTDT revision 3 later contains 2 extra fields before subtables */
1591 
1592     if (Header->Revision > 2)
1593     {
1594         ParentTable = DtPeekSubtable ();
1595         DtInsertSubtable (ParentTable, Subtable);
1596 
1597         Status = DtCompileTable (PFieldList,
1598             AcpiDmTableInfoGtdtEl2, &Subtable);
1599         if (ACPI_FAILURE (Status))
1600         {
1601             return (Status);
1602         }
1603     }
1604 
1605     ParentTable = DtPeekSubtable ();
1606     DtInsertSubtable (ParentTable, Subtable);
1607 
1608     while (*PFieldList)
1609     {
1610         SubtableStart = *PFieldList;
1611         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1612             &Subtable);
1613         if (ACPI_FAILURE (Status))
1614         {
1615             return (Status);
1616         }
1617 
1618         ParentTable = DtPeekSubtable ();
1619         DtInsertSubtable (ParentTable, Subtable);
1620         DtPushSubtable (Subtable);
1621 
1622         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1623 
1624         switch (GtdtHeader->Type)
1625         {
1626         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1627 
1628             InfoTable = AcpiDmTableInfoGtdt0;
1629             break;
1630 
1631         case ACPI_GTDT_TYPE_WATCHDOG:
1632 
1633             InfoTable = AcpiDmTableInfoGtdt1;
1634             break;
1635 
1636         default:
1637 
1638             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1639             return (AE_ERROR);
1640         }
1641 
1642         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1643         if (ACPI_FAILURE (Status))
1644         {
1645             return (Status);
1646         }
1647 
1648         ParentTable = DtPeekSubtable ();
1649         DtInsertSubtable (ParentTable, Subtable);
1650 
1651         /*
1652          * Additional GT block subtable data
1653          */
1654 
1655         switch (GtdtHeader->Type)
1656         {
1657         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1658 
1659             DtPushSubtable (Subtable);
1660             ParentTable = DtPeekSubtable ();
1661 
1662             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1663                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1664 
1665             while (GtCount)
1666             {
1667                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1668                     &Subtable);
1669                 if (ACPI_FAILURE (Status))
1670                 {
1671                     return (Status);
1672                 }
1673 
1674                 DtInsertSubtable (ParentTable, Subtable);
1675                 GtCount--;
1676             }
1677 
1678             DtPopSubtable ();
1679             break;
1680 
1681         default:
1682 
1683             break;
1684         }
1685 
1686         DtPopSubtable ();
1687     }
1688 
1689     return (AE_OK);
1690 }
1691 
1692 
1693 /******************************************************************************
1694  *
1695  * FUNCTION:    DtCompileFpdt
1696  *
1697  * PARAMETERS:  List                - Current field list pointer
1698  *
1699  * RETURN:      Status
1700  *
1701  * DESCRIPTION: Compile FPDT.
1702  *
1703  *****************************************************************************/
1704 
1705 ACPI_STATUS
1706 DtCompileFpdt (
1707     void                    **List)
1708 {
1709     ACPI_STATUS             Status;
1710     ACPI_FPDT_HEADER        *FpdtHeader;
1711     DT_SUBTABLE             *Subtable;
1712     DT_SUBTABLE             *ParentTable;
1713     ACPI_DMTABLE_INFO       *InfoTable;
1714     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1715     DT_FIELD                *SubtableStart;
1716 
1717 
1718     while (*PFieldList)
1719     {
1720         SubtableStart = *PFieldList;
1721         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1722             &Subtable);
1723         if (ACPI_FAILURE (Status))
1724         {
1725             return (Status);
1726         }
1727 
1728         ParentTable = DtPeekSubtable ();
1729         DtInsertSubtable (ParentTable, Subtable);
1730         DtPushSubtable (Subtable);
1731 
1732         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1733 
1734         switch (FpdtHeader->Type)
1735         {
1736         case ACPI_FPDT_TYPE_BOOT:
1737 
1738             InfoTable = AcpiDmTableInfoFpdt0;
1739             break;
1740 
1741         case ACPI_FPDT_TYPE_S3PERF:
1742 
1743             InfoTable = AcpiDmTableInfoFpdt1;
1744             break;
1745 
1746         default:
1747 
1748             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1749             return (AE_ERROR);
1750             break;
1751         }
1752 
1753         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1754         if (ACPI_FAILURE (Status))
1755         {
1756             return (Status);
1757         }
1758 
1759         ParentTable = DtPeekSubtable ();
1760         DtInsertSubtable (ParentTable, Subtable);
1761         DtPopSubtable ();
1762     }
1763 
1764     return (AE_OK);
1765 }
1766 
1767 
1768 /******************************************************************************
1769  *
1770  * FUNCTION:    DtCompileHest
1771  *
1772  * PARAMETERS:  List                - Current field list pointer
1773  *
1774  * RETURN:      Status
1775  *
1776  * DESCRIPTION: Compile HEST.
1777  *
1778  *****************************************************************************/
1779 
1780 ACPI_STATUS
1781 DtCompileHest (
1782     void                    **List)
1783 {
1784     ACPI_STATUS             Status;
1785     DT_SUBTABLE             *Subtable;
1786     DT_SUBTABLE             *ParentTable;
1787     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1788     DT_FIELD                *SubtableStart;
1789     ACPI_DMTABLE_INFO       *InfoTable;
1790     UINT16                  Type;
1791     UINT32                  BankCount;
1792 
1793 
1794     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1795         &Subtable);
1796     if (ACPI_FAILURE (Status))
1797     {
1798         return (Status);
1799     }
1800 
1801     ParentTable = DtPeekSubtable ();
1802     DtInsertSubtable (ParentTable, Subtable);
1803 
1804     while (*PFieldList)
1805     {
1806         /* Get subtable type */
1807 
1808         SubtableStart = *PFieldList;
1809         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1810 
1811         switch (Type)
1812         {
1813         case ACPI_HEST_TYPE_IA32_CHECK:
1814 
1815             InfoTable = AcpiDmTableInfoHest0;
1816             break;
1817 
1818         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1819 
1820             InfoTable = AcpiDmTableInfoHest1;
1821             break;
1822 
1823         case ACPI_HEST_TYPE_IA32_NMI:
1824 
1825             InfoTable = AcpiDmTableInfoHest2;
1826             break;
1827 
1828         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1829 
1830             InfoTable = AcpiDmTableInfoHest6;
1831             break;
1832 
1833         case ACPI_HEST_TYPE_AER_ENDPOINT:
1834 
1835             InfoTable = AcpiDmTableInfoHest7;
1836             break;
1837 
1838         case ACPI_HEST_TYPE_AER_BRIDGE:
1839 
1840             InfoTable = AcpiDmTableInfoHest8;
1841             break;
1842 
1843         case ACPI_HEST_TYPE_GENERIC_ERROR:
1844 
1845             InfoTable = AcpiDmTableInfoHest9;
1846             break;
1847 
1848         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1849 
1850             InfoTable = AcpiDmTableInfoHest10;
1851             break;
1852 
1853         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1854 
1855             InfoTable = AcpiDmTableInfoHest11;
1856             break;
1857 
1858         default:
1859 
1860             /* Cannot continue on unknown type */
1861 
1862             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1863             return (AE_ERROR);
1864         }
1865 
1866         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1867         if (ACPI_FAILURE (Status))
1868         {
1869             return (Status);
1870         }
1871 
1872         DtInsertSubtable (ParentTable, Subtable);
1873 
1874         /*
1875          * Additional subtable data - IA32 Error Bank(s)
1876          */
1877         BankCount = 0;
1878         switch (Type)
1879         {
1880         case ACPI_HEST_TYPE_IA32_CHECK:
1881 
1882             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1883                 Subtable->Buffer))->NumHardwareBanks;
1884             break;
1885 
1886         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1887 
1888             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1889                 Subtable->Buffer))->NumHardwareBanks;
1890             break;
1891 
1892         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1893 
1894             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1895                 Subtable->Buffer))->NumHardwareBanks;
1896             break;
1897 
1898         default:
1899 
1900             break;
1901         }
1902 
1903         while (BankCount)
1904         {
1905             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1906                 &Subtable);
1907             if (ACPI_FAILURE (Status))
1908             {
1909                 return (Status);
1910             }
1911 
1912             DtInsertSubtable (ParentTable, Subtable);
1913             BankCount--;
1914         }
1915     }
1916 
1917     return (AE_OK);
1918 }
1919 
1920 
1921 /******************************************************************************
1922  *
1923  * FUNCTION:    DtCompileHmat
1924  *
1925  * PARAMETERS:  List                - Current field list pointer
1926  *
1927  * RETURN:      Status
1928  *
1929  * DESCRIPTION: Compile HMAT.
1930  *
1931  *****************************************************************************/
1932 
1933 ACPI_STATUS
1934 DtCompileHmat (
1935     void                    **List)
1936 {
1937     ACPI_STATUS             Status;
1938     DT_SUBTABLE             *Subtable;
1939     DT_SUBTABLE             *ParentTable;
1940     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1941     DT_FIELD                *SubtableStart;
1942     DT_FIELD                *EntryStart;
1943     ACPI_HMAT_STRUCTURE     *HmatStruct;
1944     ACPI_HMAT_LOCALITY      *HmatLocality;
1945     ACPI_HMAT_CACHE         *HmatCache;
1946     ACPI_DMTABLE_INFO       *InfoTable;
1947     UINT32                  IntPDNumber;
1948     UINT32                  TgtPDNumber;
1949     UINT64                  EntryNumber;
1950     UINT16                  SMBIOSHandleNumber;
1951 
1952 
1953     ParentTable = DtPeekSubtable ();
1954 
1955     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
1956         &Subtable);
1957     if (ACPI_FAILURE (Status))
1958     {
1959         return (Status);
1960     }
1961     DtInsertSubtable (ParentTable, Subtable);
1962 
1963     while (*PFieldList)
1964     {
1965         /* Compile HMAT structure header */
1966 
1967         SubtableStart = *PFieldList;
1968         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
1969             &Subtable);
1970         if (ACPI_FAILURE (Status))
1971         {
1972             return (Status);
1973         }
1974         DtInsertSubtable (ParentTable, Subtable);
1975 
1976         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
1977         HmatStruct->Length = Subtable->Length;
1978 
1979         /* Compile HMAT structure body */
1980 
1981         switch (HmatStruct->Type)
1982         {
1983         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1984 
1985             InfoTable = AcpiDmTableInfoHmat0;
1986             break;
1987 
1988         case ACPI_HMAT_TYPE_LOCALITY:
1989 
1990             InfoTable = AcpiDmTableInfoHmat1;
1991             break;
1992 
1993         case ACPI_HMAT_TYPE_CACHE:
1994 
1995             InfoTable = AcpiDmTableInfoHmat2;
1996             break;
1997 
1998         default:
1999 
2000             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
2001             return (AE_ERROR);
2002         }
2003 
2004         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2005         if (ACPI_FAILURE (Status))
2006         {
2007             return (Status);
2008         }
2009         DtInsertSubtable (ParentTable, Subtable);
2010         HmatStruct->Length += Subtable->Length;
2011 
2012         /* Compile HMAT structure additionals */
2013 
2014         switch (HmatStruct->Type)
2015         {
2016         case ACPI_HMAT_TYPE_LOCALITY:
2017 
2018             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
2019                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2020 
2021             /* Compile initiator proximity domain list */
2022 
2023             IntPDNumber = 0;
2024             while (*PFieldList)
2025             {
2026                 Status = DtCompileTable (PFieldList,
2027                     AcpiDmTableInfoHmat1a, &Subtable);
2028                 if (ACPI_FAILURE (Status))
2029                 {
2030                     return (Status);
2031                 }
2032                 if (!Subtable)
2033                 {
2034                     break;
2035                 }
2036                 DtInsertSubtable (ParentTable, Subtable);
2037                 HmatStruct->Length += Subtable->Length;
2038                 IntPDNumber++;
2039             }
2040             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
2041 
2042             /* Compile target proximity domain list */
2043 
2044             TgtPDNumber = 0;
2045             while (*PFieldList)
2046             {
2047                 Status = DtCompileTable (PFieldList,
2048                     AcpiDmTableInfoHmat1b, &Subtable);
2049                 if (ACPI_FAILURE (Status))
2050                 {
2051                     return (Status);
2052                 }
2053                 if (!Subtable)
2054                 {
2055                     break;
2056                 }
2057                 DtInsertSubtable (ParentTable, Subtable);
2058                 HmatStruct->Length += Subtable->Length;
2059                 TgtPDNumber++;
2060             }
2061             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
2062 
2063             /* Save start of the entries for reporting errors */
2064 
2065             EntryStart = *PFieldList;
2066 
2067             /* Compile latency/bandwidth entries */
2068 
2069             EntryNumber = 0;
2070             while (*PFieldList)
2071             {
2072                 Status = DtCompileTable (PFieldList,
2073                     AcpiDmTableInfoHmat1c, &Subtable);
2074                 if (ACPI_FAILURE (Status))
2075                 {
2076                     return (Status);
2077                 }
2078                 if (!Subtable)
2079                 {
2080                     break;
2081                 }
2082                 DtInsertSubtable (ParentTable, Subtable);
2083                 HmatStruct->Length += Subtable->Length;
2084                 EntryNumber++;
2085             }
2086 
2087             /* Validate number of entries */
2088 
2089             if (EntryNumber !=
2090                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
2091             {
2092                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
2093                 return (AE_ERROR);
2094             }
2095             break;
2096 
2097         case ACPI_HMAT_TYPE_CACHE:
2098 
2099             /* Compile SMBIOS handles */
2100 
2101             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
2102                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2103             SMBIOSHandleNumber = 0;
2104             while (*PFieldList)
2105             {
2106                 Status = DtCompileTable (PFieldList,
2107                     AcpiDmTableInfoHmat2a, &Subtable);
2108                 if (ACPI_FAILURE (Status))
2109                 {
2110                     return (Status);
2111                 }
2112                 if (!Subtable)
2113                 {
2114                     break;
2115                 }
2116                 DtInsertSubtable (ParentTable, Subtable);
2117                 HmatStruct->Length += Subtable->Length;
2118                 SMBIOSHandleNumber++;
2119             }
2120             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
2121             break;
2122 
2123         default:
2124 
2125             break;
2126         }
2127     }
2128 
2129     return (AE_OK);
2130 }
2131 
2132 
2133 /******************************************************************************
2134  *
2135  * FUNCTION:    DtCompileIort
2136  *
2137  * PARAMETERS:  List                - Current field list pointer
2138  *
2139  * RETURN:      Status
2140  *
2141  * DESCRIPTION: Compile IORT.
2142  *
2143  *****************************************************************************/
2144 
2145 ACPI_STATUS
2146 DtCompileIort (
2147     void                    **List)
2148 {
2149     ACPI_STATUS             Status;
2150     DT_SUBTABLE             *Subtable;
2151     DT_SUBTABLE             *ParentTable;
2152     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2153     DT_FIELD                *SubtableStart;
2154     ACPI_TABLE_HEADER       *Table;
2155     ACPI_TABLE_IORT         *Iort;
2156     ACPI_IORT_NODE          *IortNode;
2157     ACPI_IORT_ITS_GROUP     *IortItsGroup;
2158     ACPI_IORT_SMMU          *IortSmmu;
2159     ACPI_IORT_RMR           *IortRmr;
2160     UINT32                  NodeNumber;
2161     UINT32                  NodeLength;
2162     UINT32                  IdMappingNumber;
2163     UINT32                  ItsNumber;
2164     UINT32                  ContextIrptNumber;
2165     UINT32                  PmuIrptNumber;
2166     UINT32                  PaddingLength;
2167     UINT8                   Revision;
2168     UINT32                  RmrCount;
2169 
2170 
2171     ParentTable = DtPeekSubtable ();
2172 
2173     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
2174         &Subtable);
2175     if (ACPI_FAILURE (Status))
2176     {
2177         return (Status);
2178     }
2179     DtInsertSubtable (ParentTable, Subtable);
2180 
2181     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2182     Revision = Table->Revision;
2183 
2184     /* IORT Revisions E, E.a & E.c have known issues and are not supported */
2185 
2186     if (Revision == 1 || Revision == 2 || Revision == 4)
2187     {
2188         DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
2189         return (AE_ERROR);
2190     }
2191 
2192     /*
2193      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2194      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2195      */
2196     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
2197         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
2198 
2199     /*
2200      * OptionalPadding - Variable-length data
2201      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
2202      * Optionally allows the generic data types to be used for filling
2203      * this field.
2204      */
2205     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
2206     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
2207         &Subtable);
2208     if (ACPI_FAILURE (Status))
2209     {
2210         return (Status);
2211     }
2212     if (Subtable)
2213     {
2214         DtInsertSubtable (ParentTable, Subtable);
2215         Iort->NodeOffset += Subtable->Length;
2216     }
2217     else
2218     {
2219         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
2220             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
2221         if (ACPI_FAILURE (Status))
2222         {
2223             return (Status);
2224         }
2225         Iort->NodeOffset += PaddingLength;
2226     }
2227 
2228     NodeNumber = 0;
2229     while (*PFieldList)
2230     {
2231         SubtableStart = *PFieldList;
2232         if (Revision == 0)
2233         {
2234             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
2235                 &Subtable);
2236         }
2237         else if (Revision >= 3)
2238         {
2239             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
2240                 &Subtable);
2241         }
2242 
2243         if (ACPI_FAILURE (Status))
2244         {
2245             return (Status);
2246         }
2247 
2248         DtInsertSubtable (ParentTable, Subtable);
2249         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
2250         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
2251 
2252         DtPushSubtable (Subtable);
2253         ParentTable = DtPeekSubtable ();
2254 
2255         switch (IortNode->Type)
2256         {
2257         case ACPI_IORT_NODE_ITS_GROUP:
2258 
2259             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
2260                 &Subtable);
2261             if (ACPI_FAILURE (Status))
2262             {
2263                 return (Status);
2264             }
2265 
2266             DtInsertSubtable (ParentTable, Subtable);
2267             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
2268             NodeLength += Subtable->Length;
2269 
2270             ItsNumber = 0;
2271             while (*PFieldList)
2272             {
2273                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
2274                     &Subtable);
2275                 if (ACPI_FAILURE (Status))
2276                 {
2277                     return (Status);
2278                 }
2279                 if (!Subtable)
2280                 {
2281                     break;
2282                 }
2283 
2284                 DtInsertSubtable (ParentTable, Subtable);
2285                 NodeLength += Subtable->Length;
2286                 ItsNumber++;
2287             }
2288 
2289             IortItsGroup->ItsCount = ItsNumber;
2290             break;
2291 
2292         case ACPI_IORT_NODE_NAMED_COMPONENT:
2293 
2294             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
2295                 &Subtable);
2296             if (ACPI_FAILURE (Status))
2297             {
2298                 return (Status);
2299             }
2300 
2301             DtInsertSubtable (ParentTable, Subtable);
2302             NodeLength += Subtable->Length;
2303 
2304             /*
2305              * Padding - Variable-length data
2306              * Optionally allows the offset of the ID mappings to be used
2307              * for filling this field.
2308              */
2309             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
2310                 &Subtable);
2311             if (ACPI_FAILURE (Status))
2312             {
2313                 return (Status);
2314             }
2315 
2316             if (Subtable)
2317             {
2318                 DtInsertSubtable (ParentTable, Subtable);
2319                 NodeLength += Subtable->Length;
2320             }
2321             else
2322             {
2323                 if (NodeLength > IortNode->MappingOffset)
2324                 {
2325                     return (AE_BAD_DATA);
2326                 }
2327 
2328                 if (NodeLength < IortNode->MappingOffset)
2329                 {
2330                     Status = DtCompilePadding (
2331                         IortNode->MappingOffset - NodeLength,
2332                         &Subtable);
2333                     if (ACPI_FAILURE (Status))
2334                     {
2335                         return (Status);
2336                     }
2337 
2338                     DtInsertSubtable (ParentTable, Subtable);
2339                     NodeLength = IortNode->MappingOffset;
2340                 }
2341             }
2342             break;
2343 
2344         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
2345 
2346             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
2347                 &Subtable);
2348             if (ACPI_FAILURE (Status))
2349             {
2350                 return (Status);
2351             }
2352 
2353             DtInsertSubtable (ParentTable, Subtable);
2354             NodeLength += Subtable->Length;
2355             break;
2356 
2357         case ACPI_IORT_NODE_SMMU:
2358 
2359             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
2360                 &Subtable);
2361             if (ACPI_FAILURE (Status))
2362             {
2363                 return (Status);
2364             }
2365 
2366             DtInsertSubtable (ParentTable, Subtable);
2367             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
2368             NodeLength += Subtable->Length;
2369 
2370             /* Compile global interrupt array */
2371 
2372             IortSmmu->GlobalInterruptOffset = NodeLength;
2373             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
2374                 &Subtable);
2375             if (ACPI_FAILURE (Status))
2376             {
2377                 return (Status);
2378             }
2379 
2380             DtInsertSubtable (ParentTable, Subtable);
2381             NodeLength += Subtable->Length;
2382 
2383             /* Compile context interrupt array */
2384 
2385             ContextIrptNumber = 0;
2386             IortSmmu->ContextInterruptOffset = NodeLength;
2387             while (*PFieldList)
2388             {
2389                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
2390                     &Subtable);
2391                 if (ACPI_FAILURE (Status))
2392                 {
2393                     return (Status);
2394                 }
2395 
2396                 if (!Subtable)
2397                 {
2398                     break;
2399                 }
2400 
2401                 DtInsertSubtable (ParentTable, Subtable);
2402                 NodeLength += Subtable->Length;
2403                 ContextIrptNumber++;
2404             }
2405 
2406             IortSmmu->ContextInterruptCount = ContextIrptNumber;
2407 
2408             /* Compile PMU interrupt array */
2409 
2410             PmuIrptNumber = 0;
2411             IortSmmu->PmuInterruptOffset = NodeLength;
2412             while (*PFieldList)
2413             {
2414                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
2415                     &Subtable);
2416                 if (ACPI_FAILURE (Status))
2417                 {
2418                     return (Status);
2419                 }
2420 
2421                 if (!Subtable)
2422                 {
2423                     break;
2424                 }
2425 
2426                 DtInsertSubtable (ParentTable, Subtable);
2427                 NodeLength += Subtable->Length;
2428                 PmuIrptNumber++;
2429             }
2430 
2431             IortSmmu->PmuInterruptCount = PmuIrptNumber;
2432             break;
2433 
2434         case ACPI_IORT_NODE_SMMU_V3:
2435 
2436             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
2437                 &Subtable);
2438             if (ACPI_FAILURE (Status))
2439             {
2440                 return (Status);
2441             }
2442 
2443             DtInsertSubtable (ParentTable, Subtable);
2444             NodeLength += Subtable->Length;
2445             break;
2446 
2447         case ACPI_IORT_NODE_PMCG:
2448 
2449             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
2450                 &Subtable);
2451             if (ACPI_FAILURE (Status))
2452             {
2453                 return (Status);
2454             }
2455 
2456             DtInsertSubtable (ParentTable, Subtable);
2457             NodeLength += Subtable->Length;
2458             break;
2459 
2460         case ACPI_IORT_NODE_RMR:
2461 
2462             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
2463                 &Subtable);
2464             if (ACPI_FAILURE (Status))
2465             {
2466                 return (Status);
2467             }
2468 
2469             DtInsertSubtable (ParentTable, Subtable);
2470             IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
2471             NodeLength += Subtable->Length;
2472 
2473             /* Compile RMR Descriptors */
2474 
2475             RmrCount = 0;
2476             IortRmr->RmrOffset = NodeLength;
2477             while (*PFieldList)
2478             {
2479                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
2480                     &Subtable);
2481                 if (ACPI_FAILURE (Status))
2482                 {
2483                     return (Status);
2484                 }
2485 
2486                 if (!Subtable)
2487                 {
2488                     break;
2489                 }
2490 
2491                 DtInsertSubtable (ParentTable, Subtable);
2492                 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
2493                 RmrCount++;
2494             }
2495 
2496             IortRmr->RmrCount = RmrCount;
2497             break;
2498 
2499         default:
2500 
2501             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
2502             return (AE_ERROR);
2503         }
2504 
2505         /* Compile Array of ID mappings */
2506 
2507         IortNode->MappingOffset = NodeLength;
2508         IdMappingNumber = 0;
2509         while (*PFieldList)
2510         {
2511             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
2512                 &Subtable);
2513             if (ACPI_FAILURE (Status))
2514             {
2515                 return (Status);
2516             }
2517 
2518             if (!Subtable)
2519             {
2520                 break;
2521             }
2522 
2523             DtInsertSubtable (ParentTable, Subtable);
2524             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
2525             IdMappingNumber++;
2526         }
2527 
2528         IortNode->MappingCount = IdMappingNumber;
2529         if (!IdMappingNumber)
2530         {
2531             IortNode->MappingOffset = 0;
2532         }
2533 
2534         /*
2535          * Node length can be determined by DT_LENGTH option
2536          * IortNode->Length = NodeLength;
2537          */
2538         DtPopSubtable ();
2539         ParentTable = DtPeekSubtable ();
2540         NodeNumber++;
2541     }
2542 
2543     Iort->NodeCount = NodeNumber;
2544     return (AE_OK);
2545 }
2546 
2547 
2548 /******************************************************************************
2549  *
2550  * FUNCTION:    DtCompileIvrs
2551  *
2552  * PARAMETERS:  List                - Current field list pointer
2553  *
2554  * RETURN:      Status
2555  *
2556  * DESCRIPTION: Compile IVRS. Notes:
2557  *              The IVRS is essentially a flat table, with the following
2558  *              structure:
2559  *              <Main ACPI Table Header>
2560  *              <Main subtable - virtualization info>
2561  *              <IVHD>
2562  *                  <Device Entries>
2563  *              ...
2564  *              <IVHD>
2565  *                  <Device Entries>
2566  *              <IVMD>
2567  *              ...
2568  *
2569  *****************************************************************************/
2570 
2571 ACPI_STATUS
2572 DtCompileIvrs (
2573     void                    **List)
2574 {
2575     ACPI_STATUS             Status;
2576     DT_SUBTABLE             *Subtable;
2577     DT_SUBTABLE             *ParentTable;
2578     DT_SUBTABLE             *MainSubtable;
2579     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2580     DT_FIELD                *SubtableStart;
2581     ACPI_DMTABLE_INFO       *InfoTable = NULL;
2582     UINT8                   SubtableType;
2583     UINT8                   Temp64[16];
2584     UINT8                   Temp8;
2585 
2586 
2587     /* Main table */
2588 
2589     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
2590         &Subtable);
2591     if (ACPI_FAILURE (Status))
2592     {
2593         return (Status);
2594     }
2595 
2596     ParentTable = DtPeekSubtable ();
2597     DtInsertSubtable (ParentTable, Subtable);
2598     DtPushSubtable (Subtable);
2599 
2600     /* Save a pointer to the main subtable */
2601 
2602     MainSubtable = Subtable;
2603 
2604     while (*PFieldList)
2605     {
2606         SubtableStart = *PFieldList;
2607 
2608         /* Compile the SubtableType integer */
2609 
2610         DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
2611 
2612         switch (SubtableType)
2613         {
2614 
2615         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
2616 
2617         case ACPI_IVRS_TYPE_HARDWARE1:
2618 
2619             InfoTable = AcpiDmTableInfoIvrsHware1;
2620             break;
2621 
2622         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
2623 
2624         case ACPI_IVRS_TYPE_HARDWARE2:
2625         case ACPI_IVRS_TYPE_HARDWARE3:
2626 
2627             InfoTable = AcpiDmTableInfoIvrsHware23;
2628             break;
2629 
2630         /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
2631 
2632         case ACPI_IVRS_TYPE_MEMORY1:
2633         case ACPI_IVRS_TYPE_MEMORY2:
2634         case ACPI_IVRS_TYPE_MEMORY3:
2635 
2636             InfoTable = AcpiDmTableInfoIvrsMemory;
2637             break;
2638 
2639         /* 4-byte device entries */
2640 
2641         case ACPI_IVRS_TYPE_PAD4:
2642         case ACPI_IVRS_TYPE_ALL:
2643         case ACPI_IVRS_TYPE_SELECT:
2644         case ACPI_IVRS_TYPE_START:
2645         case ACPI_IVRS_TYPE_END:
2646 
2647             InfoTable = AcpiDmTableInfoIvrs4;
2648             break;
2649 
2650         /* 8-byte device entries, type A */
2651 
2652         case ACPI_IVRS_TYPE_ALIAS_SELECT:
2653         case ACPI_IVRS_TYPE_ALIAS_START:
2654 
2655             InfoTable = AcpiDmTableInfoIvrs8a;
2656             break;
2657 
2658         /* 8-byte device entries, type B */
2659 
2660         case ACPI_IVRS_TYPE_EXT_SELECT:
2661         case ACPI_IVRS_TYPE_EXT_START:
2662 
2663             InfoTable = AcpiDmTableInfoIvrs8b;
2664             break;
2665 
2666         /* 8-byte device entries, type C */
2667 
2668         case ACPI_IVRS_TYPE_SPECIAL:
2669 
2670             InfoTable = AcpiDmTableInfoIvrs8c;
2671             break;
2672 
2673         /* Variable device entries, type F0h */
2674 
2675         case ACPI_IVRS_TYPE_HID:
2676 
2677             InfoTable = AcpiDmTableInfoIvrsHid;
2678             break;
2679 
2680         default:
2681 
2682             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
2683                 "IVRS Device Entry");
2684             return (AE_ERROR);
2685         }
2686 
2687         /* Compile the InfoTable from above */
2688 
2689         Status = DtCompileTable (PFieldList, InfoTable,
2690             &Subtable);
2691         if (ACPI_FAILURE (Status))
2692         {
2693             return (Status);
2694         }
2695 
2696         ParentTable = DtPeekSubtable ();
2697         if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
2698             SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
2699             SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
2700             SubtableType != ACPI_IVRS_TYPE_HID &&
2701             SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
2702             SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
2703             SubtableType != ACPI_IVRS_TYPE_MEMORY3)
2704         {
2705             if (ParentTable)
2706                 DtInsertSubtable (ParentTable, Subtable);
2707         }
2708 
2709         switch (SubtableType)
2710         {
2711         case ACPI_IVRS_TYPE_HARDWARE1:
2712         case ACPI_IVRS_TYPE_HARDWARE2:
2713         case ACPI_IVRS_TYPE_HARDWARE3:
2714         case ACPI_IVRS_TYPE_MEMORY1:
2715         case ACPI_IVRS_TYPE_MEMORY2:
2716         case ACPI_IVRS_TYPE_MEMORY3:
2717 
2718             /* Insert these IVHDs/IVMDs at the root subtable */
2719 
2720             DtInsertSubtable (MainSubtable, Subtable);
2721             DtPushSubtable (Subtable);
2722             break;
2723 
2724         case ACPI_IVRS_TYPE_HID:
2725 
2726             /* Special handling for the HID named device entry (0xF0) */
2727 
2728             if (ParentTable)
2729             {
2730                 DtInsertSubtable (ParentTable, Subtable);
2731             }
2732 
2733             /*
2734              * Process the HID value. First, get the HID value as a string.
2735              */
2736             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2737 
2738                /*
2739                 * Determine if the HID is an integer or a string.
2740                 * An integer is defined to be 32 bits, with the upper 32 bits
2741                 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
2742                 * integer or a character string. If an integer, the lower
2743                 * 4 bytes of the field contain the integer and the upper
2744                 * 4 bytes are padded with 0".
2745                 */
2746             if (UtIsIdInteger ((UINT8 *) &Temp64))
2747             {
2748                 /* Compile the HID value as an integer */
2749 
2750                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2751 
2752                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
2753                     &Subtable);
2754                 if (ACPI_FAILURE (Status))
2755                 {
2756                     return (Status);
2757                 }
2758             }
2759             else
2760             {
2761                 /* Compile the HID value as a string */
2762 
2763                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
2764                     &Subtable);
2765                 if (ACPI_FAILURE (Status))
2766                 {
2767                     return (Status);
2768                 }
2769             }
2770 
2771             DtInsertSubtable (ParentTable, Subtable);
2772 
2773             /*
2774              * Process the CID value. First, get the CID value as a string.
2775              */
2776             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2777 
2778             if (UtIsIdInteger ((UINT8 *) &Temp64))
2779             {
2780                 /* Compile the CID value as an integer */
2781 
2782                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2783 
2784                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
2785                     &Subtable);
2786                 if (ACPI_FAILURE (Status))
2787                 {
2788                     return (Status);
2789                 }
2790             }
2791             else
2792             {
2793                 /* Compile the CID value as a string */
2794 
2795                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
2796                     &Subtable);
2797                 if (ACPI_FAILURE (Status))
2798                 {
2799                     return (Status);
2800                 }
2801             }
2802 
2803             DtInsertSubtable (ParentTable, Subtable);
2804 
2805             /*
2806              * Process the UID value. First, get and decode the "UID Format" field (Integer).
2807              */
2808             if (!*PFieldList)
2809             {
2810                 return (AE_OK);
2811             }
2812 
2813             DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
2814 
2815             switch (Temp8)
2816             {
2817             case ACPI_IVRS_UID_NOT_PRESENT:
2818                 break;
2819 
2820             case ACPI_IVRS_UID_IS_INTEGER:
2821 
2822                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
2823                     &Subtable);
2824                 if (ACPI_FAILURE (Status))
2825                 {
2826                     return (Status);
2827                 }
2828                 DtInsertSubtable (ParentTable, Subtable);
2829                 break;
2830 
2831             case ACPI_IVRS_UID_IS_STRING:
2832 
2833                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
2834                     &Subtable);
2835                 if (ACPI_FAILURE (Status))
2836                 {
2837                     return (Status);
2838                 }
2839                 DtInsertSubtable (ParentTable, Subtable);
2840                 break;
2841 
2842             default:
2843 
2844                 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
2845                     "IVRS Device Entry");
2846                 return (AE_ERROR);
2847             }
2848 
2849         default:
2850 
2851             /* All other subtable types come through here */
2852             break;
2853         }
2854     }
2855 
2856     return (AE_OK);
2857 }
2858