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