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