xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable1.c (revision 92f570c32e9b9b9b4db9b6921c4ab79be686a498)
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 - 2024, 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         default:
1511 
1512             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
1513             return (AE_ERROR);
1514         }
1515 
1516         /* DMAR Subtable */
1517 
1518         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1519         if (ACPI_FAILURE (Status))
1520         {
1521             return (Status);
1522         }
1523 
1524         ParentTable = DtPeekSubtable ();
1525         DtInsertSubtable (ParentTable, Subtable);
1526 
1527         /*
1528          * Optional Device Scope subtables
1529          */
1530         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1531             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
1532         {
1533             /* These types do not support device scopes */
1534 
1535             DtPopSubtable ();
1536             continue;
1537         }
1538 
1539         DtPushSubtable (Subtable);
1540         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
1541             ParentTable->Length;
1542         while (DeviceScopeLength)
1543         {
1544             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
1545                 &Subtable);
1546             if (Status == AE_NOT_FOUND)
1547             {
1548                 break;
1549             }
1550 
1551             ParentTable = DtPeekSubtable ();
1552             DtInsertSubtable (ParentTable, Subtable);
1553             DtPushSubtable (Subtable);
1554 
1555             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
1556 
1557             /* Optional PCI Paths */
1558 
1559             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
1560             while (PciPathLength)
1561             {
1562                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
1563                     &Subtable);
1564                 if (Status == AE_NOT_FOUND)
1565                 {
1566                     DtPopSubtable ();
1567                     break;
1568                 }
1569 
1570                 ParentTable = DtPeekSubtable ();
1571                 DtInsertSubtable (ParentTable, Subtable);
1572                 PciPathLength -= Subtable->Length;
1573             }
1574 
1575             DtPopSubtable ();
1576             DeviceScopeLength -= DmarDeviceScope->Length;
1577         }
1578 
1579         DtPopSubtable ();
1580         DtPopSubtable ();
1581     }
1582 
1583     return (AE_OK);
1584 }
1585 
1586 
1587 /******************************************************************************
1588  *
1589  * FUNCTION:    DtCompileDrtm
1590  *
1591  * PARAMETERS:  List                - Current field list pointer
1592  *
1593  * RETURN:      Status
1594  *
1595  * DESCRIPTION: Compile DRTM.
1596  *
1597  *****************************************************************************/
1598 
1599 ACPI_STATUS
DtCompileDrtm(void ** List)1600 DtCompileDrtm (
1601     void                    **List)
1602 {
1603     ACPI_STATUS             Status;
1604     DT_SUBTABLE             *Subtable;
1605     DT_SUBTABLE             *ParentTable;
1606     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1607     UINT32                  Count;
1608     /* ACPI_TABLE_DRTM         *Drtm; */
1609     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
1610     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1611     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
1612 
1613 
1614     ParentTable = DtPeekSubtable ();
1615 
1616     /* Compile DRTM header */
1617 
1618     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
1619         &Subtable);
1620     if (ACPI_FAILURE (Status))
1621     {
1622         return (Status);
1623     }
1624     DtInsertSubtable (ParentTable, Subtable);
1625 
1626     /*
1627      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1628      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1629      */
1630 #if 0
1631     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
1632         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1633 #endif
1634     /* Compile VTL */
1635 
1636     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
1637         &Subtable);
1638     if (ACPI_FAILURE (Status))
1639     {
1640         return (Status);
1641     }
1642 
1643     DtInsertSubtable (ParentTable, Subtable);
1644     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
1645 
1646     DtPushSubtable (Subtable);
1647     ParentTable = DtPeekSubtable ();
1648     Count = 0;
1649 
1650     while (*PFieldList)
1651     {
1652         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
1653             &Subtable);
1654         if (ACPI_FAILURE (Status))
1655         {
1656             return (Status);
1657         }
1658         if (!Subtable)
1659         {
1660             break;
1661         }
1662         DtInsertSubtable (ParentTable, Subtable);
1663         Count++;
1664     }
1665 
1666     DrtmVtl->ValidatedTableCount = Count;
1667     DtPopSubtable ();
1668     ParentTable = DtPeekSubtable ();
1669 
1670     /* Compile RL */
1671 
1672     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
1673         &Subtable);
1674     if (ACPI_FAILURE (Status))
1675     {
1676         return (Status);
1677     }
1678 
1679     DtInsertSubtable (ParentTable, Subtable);
1680     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
1681 
1682     DtPushSubtable (Subtable);
1683     ParentTable = DtPeekSubtable ();
1684     Count = 0;
1685 
1686     while (*PFieldList)
1687     {
1688         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
1689             &Subtable);
1690         if (ACPI_FAILURE (Status))
1691         {
1692             return (Status);
1693         }
1694 
1695         if (!Subtable)
1696         {
1697             break;
1698         }
1699 
1700         DtInsertSubtable (ParentTable, Subtable);
1701         Count++;
1702     }
1703 
1704     DrtmRl->ResourceCount = Count;
1705     DtPopSubtable ();
1706     ParentTable = DtPeekSubtable ();
1707 
1708     /* Compile DPS */
1709 
1710     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
1711         &Subtable);
1712     if (ACPI_FAILURE (Status))
1713     {
1714         return (Status);
1715     }
1716     DtInsertSubtable (ParentTable, Subtable);
1717     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
1718 
1719 
1720     return (AE_OK);
1721 }
1722 
1723 
1724 /******************************************************************************
1725  *
1726  * FUNCTION:    DtCompileEinj
1727  *
1728  * PARAMETERS:  List                - Current field list pointer
1729  *
1730  * RETURN:      Status
1731  *
1732  * DESCRIPTION: Compile EINJ.
1733  *
1734  *****************************************************************************/
1735 
1736 ACPI_STATUS
DtCompileEinj(void ** List)1737 DtCompileEinj (
1738     void                    **List)
1739 {
1740     ACPI_STATUS             Status;
1741 
1742 
1743     Status = DtCompileTwoSubtables (List,
1744         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
1745     return (Status);
1746 }
1747 
1748 
1749 /******************************************************************************
1750  *
1751  * FUNCTION:    DtCompileErst
1752  *
1753  * PARAMETERS:  List                - Current field list pointer
1754  *
1755  * RETURN:      Status
1756  *
1757  * DESCRIPTION: Compile ERST.
1758  *
1759  *****************************************************************************/
1760 
1761 ACPI_STATUS
DtCompileErst(void ** List)1762 DtCompileErst (
1763     void                    **List)
1764 {
1765     ACPI_STATUS             Status;
1766 
1767 
1768     Status = DtCompileTwoSubtables (List,
1769         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1770     return (Status);
1771 }
1772 
1773 
1774 /******************************************************************************
1775  *
1776  * FUNCTION:    DtCompileGtdt
1777  *
1778  * PARAMETERS:  List                - Current field list pointer
1779  *
1780  * RETURN:      Status
1781  *
1782  * DESCRIPTION: Compile GTDT.
1783  *
1784  *****************************************************************************/
1785 
1786 ACPI_STATUS
DtCompileGtdt(void ** List)1787 DtCompileGtdt (
1788     void                    **List)
1789 {
1790     ACPI_STATUS             Status;
1791     DT_SUBTABLE             *Subtable;
1792     DT_SUBTABLE             *ParentTable;
1793     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1794     DT_FIELD                *SubtableStart;
1795     ACPI_SUBTABLE_HEADER    *GtdtHeader;
1796     ACPI_DMTABLE_INFO       *InfoTable;
1797     UINT32                  GtCount;
1798     ACPI_TABLE_HEADER       *Header;
1799 
1800 
1801     ParentTable = DtPeekSubtable ();
1802 
1803     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1804 
1805     /* Compile the main table */
1806 
1807     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1808         &Subtable);
1809     if (ACPI_FAILURE (Status))
1810     {
1811         return (Status);
1812     }
1813 
1814     /* GTDT revision 3 later contains 2 extra fields before subtables */
1815 
1816     if (Header->Revision > 2)
1817     {
1818         ParentTable = DtPeekSubtable ();
1819         DtInsertSubtable (ParentTable, Subtable);
1820 
1821         Status = DtCompileTable (PFieldList,
1822             AcpiDmTableInfoGtdtEl2, &Subtable);
1823         if (ACPI_FAILURE (Status))
1824         {
1825             return (Status);
1826         }
1827     }
1828 
1829     ParentTable = DtPeekSubtable ();
1830     DtInsertSubtable (ParentTable, Subtable);
1831 
1832     while (*PFieldList)
1833     {
1834         SubtableStart = *PFieldList;
1835         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1836             &Subtable);
1837         if (ACPI_FAILURE (Status))
1838         {
1839             return (Status);
1840         }
1841 
1842         ParentTable = DtPeekSubtable ();
1843         DtInsertSubtable (ParentTable, Subtable);
1844         DtPushSubtable (Subtable);
1845 
1846         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1847 
1848         switch (GtdtHeader->Type)
1849         {
1850         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1851 
1852             InfoTable = AcpiDmTableInfoGtdt0;
1853             break;
1854 
1855         case ACPI_GTDT_TYPE_WATCHDOG:
1856 
1857             InfoTable = AcpiDmTableInfoGtdt1;
1858             break;
1859 
1860         default:
1861 
1862             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1863             return (AE_ERROR);
1864         }
1865 
1866         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1867         if (ACPI_FAILURE (Status))
1868         {
1869             return (Status);
1870         }
1871 
1872         ParentTable = DtPeekSubtable ();
1873         DtInsertSubtable (ParentTable, Subtable);
1874 
1875         /*
1876          * Additional GT block subtable data
1877          */
1878 
1879         switch (GtdtHeader->Type)
1880         {
1881         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1882 
1883             DtPushSubtable (Subtable);
1884             ParentTable = DtPeekSubtable ();
1885 
1886             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1887                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1888 
1889             while (GtCount)
1890             {
1891                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1892                     &Subtable);
1893                 if (ACPI_FAILURE (Status))
1894                 {
1895                     return (Status);
1896                 }
1897 
1898                 DtInsertSubtable (ParentTable, Subtable);
1899                 GtCount--;
1900             }
1901 
1902             DtPopSubtable ();
1903             break;
1904 
1905         default:
1906 
1907             break;
1908         }
1909 
1910         DtPopSubtable ();
1911     }
1912 
1913     return (AE_OK);
1914 }
1915 
1916 
1917 /******************************************************************************
1918  *
1919  * FUNCTION:    DtCompileFpdt
1920  *
1921  * PARAMETERS:  List                - Current field list pointer
1922  *
1923  * RETURN:      Status
1924  *
1925  * DESCRIPTION: Compile FPDT.
1926  *
1927  *****************************************************************************/
1928 
1929 ACPI_STATUS
DtCompileFpdt(void ** List)1930 DtCompileFpdt (
1931     void                    **List)
1932 {
1933     ACPI_STATUS             Status;
1934     ACPI_FPDT_HEADER        *FpdtHeader;
1935     DT_SUBTABLE             *Subtable;
1936     DT_SUBTABLE             *ParentTable;
1937     ACPI_DMTABLE_INFO       *InfoTable;
1938     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1939     DT_FIELD                *SubtableStart;
1940 
1941 
1942     while (*PFieldList)
1943     {
1944         SubtableStart = *PFieldList;
1945         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1946             &Subtable);
1947         if (ACPI_FAILURE (Status))
1948         {
1949             return (Status);
1950         }
1951 
1952         ParentTable = DtPeekSubtable ();
1953         DtInsertSubtable (ParentTable, Subtable);
1954         DtPushSubtable (Subtable);
1955 
1956         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1957 
1958         switch (FpdtHeader->Type)
1959         {
1960         case ACPI_FPDT_TYPE_BOOT:
1961 
1962             InfoTable = AcpiDmTableInfoFpdt0;
1963             break;
1964 
1965         case ACPI_FPDT_TYPE_S3PERF:
1966 
1967             InfoTable = AcpiDmTableInfoFpdt1;
1968             break;
1969 
1970         default:
1971 
1972             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1973             return (AE_ERROR);
1974             break;
1975         }
1976 
1977         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1978         if (ACPI_FAILURE (Status))
1979         {
1980             return (Status);
1981         }
1982 
1983         ParentTable = DtPeekSubtable ();
1984         DtInsertSubtable (ParentTable, Subtable);
1985         DtPopSubtable ();
1986     }
1987 
1988     return (AE_OK);
1989 }
1990 
1991 
1992 /******************************************************************************
1993  *
1994  * FUNCTION:    DtCompileHest
1995  *
1996  * PARAMETERS:  List                - Current field list pointer
1997  *
1998  * RETURN:      Status
1999  *
2000  * DESCRIPTION: Compile HEST.
2001  *
2002  *****************************************************************************/
2003 
2004 ACPI_STATUS
DtCompileHest(void ** List)2005 DtCompileHest (
2006     void                    **List)
2007 {
2008     ACPI_STATUS             Status;
2009     DT_SUBTABLE             *Subtable;
2010     DT_SUBTABLE             *ParentTable;
2011     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2012     DT_FIELD                *SubtableStart;
2013     ACPI_DMTABLE_INFO       *InfoTable;
2014     UINT16                  Type;
2015     UINT32                  BankCount;
2016 
2017 
2018     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
2019         &Subtable);
2020     if (ACPI_FAILURE (Status))
2021     {
2022         return (Status);
2023     }
2024 
2025     ParentTable = DtPeekSubtable ();
2026     DtInsertSubtable (ParentTable, Subtable);
2027 
2028     while (*PFieldList)
2029     {
2030         /* Get subtable type */
2031 
2032         SubtableStart = *PFieldList;
2033         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
2034 
2035         switch (Type)
2036         {
2037         case ACPI_HEST_TYPE_IA32_CHECK:
2038 
2039             InfoTable = AcpiDmTableInfoHest0;
2040             break;
2041 
2042         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
2043 
2044             InfoTable = AcpiDmTableInfoHest1;
2045             break;
2046 
2047         case ACPI_HEST_TYPE_IA32_NMI:
2048 
2049             InfoTable = AcpiDmTableInfoHest2;
2050             break;
2051 
2052         case ACPI_HEST_TYPE_AER_ROOT_PORT:
2053 
2054             InfoTable = AcpiDmTableInfoHest6;
2055             break;
2056 
2057         case ACPI_HEST_TYPE_AER_ENDPOINT:
2058 
2059             InfoTable = AcpiDmTableInfoHest7;
2060             break;
2061 
2062         case ACPI_HEST_TYPE_AER_BRIDGE:
2063 
2064             InfoTable = AcpiDmTableInfoHest8;
2065             break;
2066 
2067         case ACPI_HEST_TYPE_GENERIC_ERROR:
2068 
2069             InfoTable = AcpiDmTableInfoHest9;
2070             break;
2071 
2072         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
2073 
2074             InfoTable = AcpiDmTableInfoHest10;
2075             break;
2076 
2077         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
2078 
2079             InfoTable = AcpiDmTableInfoHest11;
2080             break;
2081 
2082         default:
2083 
2084             /* Cannot continue on unknown type */
2085 
2086             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
2087             return (AE_ERROR);
2088         }
2089 
2090         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2091         if (ACPI_FAILURE (Status))
2092         {
2093             return (Status);
2094         }
2095 
2096         DtInsertSubtable (ParentTable, Subtable);
2097 
2098         /*
2099          * Additional subtable data - IA32 Error Bank(s)
2100          */
2101         BankCount = 0;
2102         switch (Type)
2103         {
2104         case ACPI_HEST_TYPE_IA32_CHECK:
2105 
2106             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
2107                 Subtable->Buffer))->NumHardwareBanks;
2108             break;
2109 
2110         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
2111 
2112             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
2113                 Subtable->Buffer))->NumHardwareBanks;
2114             break;
2115 
2116         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
2117 
2118             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
2119                 Subtable->Buffer))->NumHardwareBanks;
2120             break;
2121 
2122         default:
2123 
2124             break;
2125         }
2126 
2127         while (BankCount)
2128         {
2129             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
2130                 &Subtable);
2131             if (ACPI_FAILURE (Status))
2132             {
2133                 return (Status);
2134             }
2135 
2136             DtInsertSubtable (ParentTable, Subtable);
2137             BankCount--;
2138         }
2139     }
2140 
2141     return (AE_OK);
2142 }
2143 
2144 
2145 /******************************************************************************
2146  *
2147  * FUNCTION:    DtCompileHmat
2148  *
2149  * PARAMETERS:  List                - Current field list pointer
2150  *
2151  * RETURN:      Status
2152  *
2153  * DESCRIPTION: Compile HMAT.
2154  *
2155  *****************************************************************************/
2156 
2157 ACPI_STATUS
DtCompileHmat(void ** List)2158 DtCompileHmat (
2159     void                    **List)
2160 {
2161     ACPI_STATUS             Status;
2162     DT_SUBTABLE             *Subtable;
2163     DT_SUBTABLE             *ParentTable;
2164     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2165     DT_FIELD                *SubtableStart;
2166     DT_FIELD                *EntryStart;
2167     ACPI_HMAT_STRUCTURE     *HmatStruct;
2168     ACPI_HMAT_LOCALITY      *HmatLocality;
2169     ACPI_HMAT_CACHE         *HmatCache;
2170     ACPI_DMTABLE_INFO       *InfoTable;
2171     UINT32                  IntPDNumber;
2172     UINT32                  TgtPDNumber;
2173     UINT64                  EntryNumber;
2174     UINT16                  SMBIOSHandleNumber;
2175 
2176 
2177     ParentTable = DtPeekSubtable ();
2178 
2179     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
2180         &Subtable);
2181     if (ACPI_FAILURE (Status))
2182     {
2183         return (Status);
2184     }
2185     DtInsertSubtable (ParentTable, Subtable);
2186 
2187     while (*PFieldList)
2188     {
2189         /* Compile HMAT structure header */
2190 
2191         SubtableStart = *PFieldList;
2192         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
2193             &Subtable);
2194         if (ACPI_FAILURE (Status))
2195         {
2196             return (Status);
2197         }
2198         DtInsertSubtable (ParentTable, Subtable);
2199 
2200         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
2201         HmatStruct->Length = Subtable->Length;
2202 
2203         /* Compile HMAT structure body */
2204 
2205         switch (HmatStruct->Type)
2206         {
2207         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
2208 
2209             InfoTable = AcpiDmTableInfoHmat0;
2210             break;
2211 
2212         case ACPI_HMAT_TYPE_LOCALITY:
2213 
2214             InfoTable = AcpiDmTableInfoHmat1;
2215             break;
2216 
2217         case ACPI_HMAT_TYPE_CACHE:
2218 
2219             InfoTable = AcpiDmTableInfoHmat2;
2220             break;
2221 
2222         default:
2223 
2224             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
2225             return (AE_ERROR);
2226         }
2227 
2228         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2229         if (ACPI_FAILURE (Status))
2230         {
2231             return (Status);
2232         }
2233         DtInsertSubtable (ParentTable, Subtable);
2234         HmatStruct->Length += Subtable->Length;
2235 
2236         /* Compile HMAT structure additional */
2237 
2238         switch (HmatStruct->Type)
2239         {
2240         case ACPI_HMAT_TYPE_LOCALITY:
2241 
2242             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
2243                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2244 
2245             /* Compile initiator proximity domain list */
2246 
2247             IntPDNumber = 0;
2248             while (*PFieldList)
2249             {
2250                 Status = DtCompileTable (PFieldList,
2251                     AcpiDmTableInfoHmat1a, &Subtable);
2252                 if (ACPI_FAILURE (Status))
2253                 {
2254                     return (Status);
2255                 }
2256                 if (!Subtable)
2257                 {
2258                     break;
2259                 }
2260                 DtInsertSubtable (ParentTable, Subtable);
2261                 HmatStruct->Length += Subtable->Length;
2262                 IntPDNumber++;
2263             }
2264             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
2265 
2266             /* Compile target proximity domain list */
2267 
2268             TgtPDNumber = 0;
2269             while (*PFieldList)
2270             {
2271                 Status = DtCompileTable (PFieldList,
2272                     AcpiDmTableInfoHmat1b, &Subtable);
2273                 if (ACPI_FAILURE (Status))
2274                 {
2275                     return (Status);
2276                 }
2277                 if (!Subtable)
2278                 {
2279                     break;
2280                 }
2281                 DtInsertSubtable (ParentTable, Subtable);
2282                 HmatStruct->Length += Subtable->Length;
2283                 TgtPDNumber++;
2284             }
2285             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
2286 
2287             /* Save start of the entries for reporting errors */
2288 
2289             EntryStart = *PFieldList;
2290 
2291             /* Compile latency/bandwidth entries */
2292 
2293             EntryNumber = 0;
2294             while (*PFieldList)
2295             {
2296                 Status = DtCompileTable (PFieldList,
2297                     AcpiDmTableInfoHmat1c, &Subtable);
2298                 if (ACPI_FAILURE (Status))
2299                 {
2300                     return (Status);
2301                 }
2302                 if (!Subtable)
2303                 {
2304                     break;
2305                 }
2306                 DtInsertSubtable (ParentTable, Subtable);
2307                 HmatStruct->Length += Subtable->Length;
2308                 EntryNumber++;
2309             }
2310 
2311             /* Validate number of entries */
2312 
2313             if (EntryNumber !=
2314                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
2315             {
2316                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
2317                 return (AE_ERROR);
2318             }
2319             break;
2320 
2321         case ACPI_HMAT_TYPE_CACHE:
2322 
2323             /* Compile SMBIOS handles */
2324 
2325             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
2326                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2327             SMBIOSHandleNumber = 0;
2328             while (*PFieldList)
2329             {
2330                 Status = DtCompileTable (PFieldList,
2331                     AcpiDmTableInfoHmat2a, &Subtable);
2332                 if (ACPI_FAILURE (Status))
2333                 {
2334                     return (Status);
2335                 }
2336                 if (!Subtable)
2337                 {
2338                     break;
2339                 }
2340                 DtInsertSubtable (ParentTable, Subtable);
2341                 HmatStruct->Length += Subtable->Length;
2342                 SMBIOSHandleNumber++;
2343             }
2344             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
2345             break;
2346 
2347         default:
2348 
2349             break;
2350         }
2351     }
2352 
2353     return (AE_OK);
2354 }
2355 
2356 
2357 /******************************************************************************
2358  *
2359  * FUNCTION:    DtCompileIort
2360  *
2361  * PARAMETERS:  List                - Current field list pointer
2362  *
2363  * RETURN:      Status
2364  *
2365  * DESCRIPTION: Compile IORT.
2366  *
2367  *****************************************************************************/
2368 
2369 ACPI_STATUS
DtCompileIort(void ** List)2370 DtCompileIort (
2371     void                    **List)
2372 {
2373     ACPI_STATUS             Status;
2374     DT_SUBTABLE             *Subtable;
2375     DT_SUBTABLE             *ParentTable;
2376     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2377     DT_FIELD                *SubtableStart;
2378     ACPI_TABLE_HEADER       *Table;
2379     ACPI_TABLE_IORT         *Iort;
2380     ACPI_IORT_NODE          *IortNode;
2381     ACPI_IORT_ITS_GROUP     *IortItsGroup;
2382     ACPI_IORT_SMMU          *IortSmmu;
2383     ACPI_IORT_RMR           *IortRmr;
2384     UINT32                  NodeNumber;
2385     UINT32                  NodeLength;
2386     UINT32                  IdMappingNumber;
2387     UINT32                  ItsNumber;
2388     UINT32                  ContextIrptNumber;
2389     UINT32                  PmuIrptNumber;
2390     UINT32                  PaddingLength;
2391     UINT8                   Revision;
2392     UINT32                  RmrCount;
2393 
2394 
2395     ParentTable = DtPeekSubtable ();
2396 
2397     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
2398         &Subtable);
2399     if (ACPI_FAILURE (Status))
2400     {
2401         return (Status);
2402     }
2403     DtInsertSubtable (ParentTable, Subtable);
2404 
2405     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2406     Revision = Table->Revision;
2407 
2408     /* IORT Revisions E, E.a & E.c have known issues and are not supported */
2409 
2410     if (Revision == 1 || Revision == 2 || Revision == 4)
2411     {
2412         DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
2413         return (AE_ERROR);
2414     }
2415 
2416     /*
2417      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2418      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2419      */
2420     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
2421         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
2422 
2423     /*
2424      * OptionalPadding - Variable-length data
2425      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
2426      * Optionally allows the generic data types to be used for filling
2427      * this field.
2428      */
2429     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
2430     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
2431         &Subtable);
2432     if (ACPI_FAILURE (Status))
2433     {
2434         return (Status);
2435     }
2436     if (Subtable)
2437     {
2438         DtInsertSubtable (ParentTable, Subtable);
2439         Iort->NodeOffset += Subtable->Length;
2440     }
2441     else
2442     {
2443         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
2444             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
2445         if (ACPI_FAILURE (Status))
2446         {
2447             return (Status);
2448         }
2449         Iort->NodeOffset += PaddingLength;
2450     }
2451 
2452     NodeNumber = 0;
2453     while (*PFieldList)
2454     {
2455         SubtableStart = *PFieldList;
2456         if (Revision == 0)
2457         {
2458             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
2459                 &Subtable);
2460         }
2461         else if (Revision >= 3)
2462         {
2463             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
2464                 &Subtable);
2465         }
2466 
2467         if (ACPI_FAILURE (Status))
2468         {
2469             return (Status);
2470         }
2471 
2472         DtInsertSubtable (ParentTable, Subtable);
2473         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
2474         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
2475 
2476         DtPushSubtable (Subtable);
2477         ParentTable = DtPeekSubtable ();
2478 
2479         switch (IortNode->Type)
2480         {
2481         case ACPI_IORT_NODE_ITS_GROUP:
2482 
2483             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
2484                 &Subtable);
2485             if (ACPI_FAILURE (Status))
2486             {
2487                 return (Status);
2488             }
2489 
2490             DtInsertSubtable (ParentTable, Subtable);
2491             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
2492             NodeLength += Subtable->Length;
2493 
2494             ItsNumber = 0;
2495             while (*PFieldList)
2496             {
2497                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
2498                     &Subtable);
2499                 if (ACPI_FAILURE (Status))
2500                 {
2501                     return (Status);
2502                 }
2503                 if (!Subtable)
2504                 {
2505                     break;
2506                 }
2507 
2508                 DtInsertSubtable (ParentTable, Subtable);
2509                 NodeLength += Subtable->Length;
2510                 ItsNumber++;
2511             }
2512 
2513             IortItsGroup->ItsCount = ItsNumber;
2514             break;
2515 
2516         case ACPI_IORT_NODE_NAMED_COMPONENT:
2517 
2518             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
2519                 &Subtable);
2520             if (ACPI_FAILURE (Status))
2521             {
2522                 return (Status);
2523             }
2524 
2525             DtInsertSubtable (ParentTable, Subtable);
2526             NodeLength += Subtable->Length;
2527 
2528             /*
2529              * Padding - Variable-length data
2530              * Optionally allows the offset of the ID mappings to be used
2531              * for filling this field.
2532              */
2533             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
2534                 &Subtable);
2535             if (ACPI_FAILURE (Status))
2536             {
2537                 return (Status);
2538             }
2539 
2540             if (Subtable)
2541             {
2542                 DtInsertSubtable (ParentTable, Subtable);
2543                 NodeLength += Subtable->Length;
2544             }
2545             else
2546             {
2547                 if (NodeLength > IortNode->MappingOffset)
2548                 {
2549                     return (AE_BAD_DATA);
2550                 }
2551 
2552                 if (NodeLength < IortNode->MappingOffset)
2553                 {
2554                     Status = DtCompilePadding (
2555                         IortNode->MappingOffset - NodeLength,
2556                         &Subtable);
2557                     if (ACPI_FAILURE (Status))
2558                     {
2559                         return (Status);
2560                     }
2561 
2562                     DtInsertSubtable (ParentTable, Subtable);
2563                     NodeLength = IortNode->MappingOffset;
2564                 }
2565             }
2566             break;
2567 
2568         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
2569 
2570             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
2571                 &Subtable);
2572             if (ACPI_FAILURE (Status))
2573             {
2574                 return (Status);
2575             }
2576 
2577             DtInsertSubtable (ParentTable, Subtable);
2578             NodeLength += Subtable->Length;
2579             break;
2580 
2581         case ACPI_IORT_NODE_SMMU:
2582 
2583             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
2584                 &Subtable);
2585             if (ACPI_FAILURE (Status))
2586             {
2587                 return (Status);
2588             }
2589 
2590             DtInsertSubtable (ParentTable, Subtable);
2591             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
2592             NodeLength += Subtable->Length;
2593 
2594             /* Compile global interrupt array */
2595 
2596             IortSmmu->GlobalInterruptOffset = NodeLength;
2597             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
2598                 &Subtable);
2599             if (ACPI_FAILURE (Status))
2600             {
2601                 return (Status);
2602             }
2603 
2604             DtInsertSubtable (ParentTable, Subtable);
2605             NodeLength += Subtable->Length;
2606 
2607             /* Compile context interrupt array */
2608 
2609             ContextIrptNumber = 0;
2610             IortSmmu->ContextInterruptOffset = NodeLength;
2611             while (*PFieldList)
2612             {
2613                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
2614                     &Subtable);
2615                 if (ACPI_FAILURE (Status))
2616                 {
2617                     return (Status);
2618                 }
2619 
2620                 if (!Subtable)
2621                 {
2622                     break;
2623                 }
2624 
2625                 DtInsertSubtable (ParentTable, Subtable);
2626                 NodeLength += Subtable->Length;
2627                 ContextIrptNumber++;
2628             }
2629 
2630             IortSmmu->ContextInterruptCount = ContextIrptNumber;
2631 
2632             /* Compile PMU interrupt array */
2633 
2634             PmuIrptNumber = 0;
2635             IortSmmu->PmuInterruptOffset = NodeLength;
2636             while (*PFieldList)
2637             {
2638                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
2639                     &Subtable);
2640                 if (ACPI_FAILURE (Status))
2641                 {
2642                     return (Status);
2643                 }
2644 
2645                 if (!Subtable)
2646                 {
2647                     break;
2648                 }
2649 
2650                 DtInsertSubtable (ParentTable, Subtable);
2651                 NodeLength += Subtable->Length;
2652                 PmuIrptNumber++;
2653             }
2654 
2655             IortSmmu->PmuInterruptCount = PmuIrptNumber;
2656             break;
2657 
2658         case ACPI_IORT_NODE_SMMU_V3:
2659 
2660             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
2661                 &Subtable);
2662             if (ACPI_FAILURE (Status))
2663             {
2664                 return (Status);
2665             }
2666 
2667             DtInsertSubtable (ParentTable, Subtable);
2668             NodeLength += Subtable->Length;
2669             break;
2670 
2671         case ACPI_IORT_NODE_PMCG:
2672 
2673             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
2674                 &Subtable);
2675             if (ACPI_FAILURE (Status))
2676             {
2677                 return (Status);
2678             }
2679 
2680             DtInsertSubtable (ParentTable, Subtable);
2681             NodeLength += Subtable->Length;
2682             break;
2683 
2684         case ACPI_IORT_NODE_RMR:
2685 
2686             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
2687                 &Subtable);
2688             if (ACPI_FAILURE (Status))
2689             {
2690                 return (Status);
2691             }
2692 
2693             DtInsertSubtable (ParentTable, Subtable);
2694             IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
2695             NodeLength += Subtable->Length;
2696 
2697             /* Compile RMR Descriptors */
2698 
2699             RmrCount = 0;
2700             IortRmr->RmrOffset = NodeLength;
2701             while (*PFieldList)
2702             {
2703                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
2704                     &Subtable);
2705                 if (ACPI_FAILURE (Status))
2706                 {
2707                     return (Status);
2708                 }
2709 
2710                 if (!Subtable)
2711                 {
2712                     break;
2713                 }
2714 
2715                 DtInsertSubtable (ParentTable, Subtable);
2716                 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
2717                 RmrCount++;
2718             }
2719 
2720             IortRmr->RmrCount = RmrCount;
2721             break;
2722 
2723         default:
2724 
2725             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
2726             return (AE_ERROR);
2727         }
2728 
2729         /* Compile Array of ID mappings */
2730 
2731         IortNode->MappingOffset = NodeLength;
2732         IdMappingNumber = 0;
2733         while (*PFieldList)
2734         {
2735             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
2736                 &Subtable);
2737             if (ACPI_FAILURE (Status))
2738             {
2739                 return (Status);
2740             }
2741 
2742             if (!Subtable)
2743             {
2744                 break;
2745             }
2746 
2747             DtInsertSubtable (ParentTable, Subtable);
2748             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
2749             IdMappingNumber++;
2750         }
2751 
2752         IortNode->MappingCount = IdMappingNumber;
2753         if (!IdMappingNumber)
2754         {
2755             IortNode->MappingOffset = 0;
2756         }
2757 
2758         /*
2759          * Node length can be determined by DT_LENGTH option
2760          * IortNode->Length = NodeLength;
2761          */
2762         DtPopSubtable ();
2763         ParentTable = DtPeekSubtable ();
2764         NodeNumber++;
2765     }
2766 
2767     Iort->NodeCount = NodeNumber;
2768     return (AE_OK);
2769 }
2770 
2771 
2772 /******************************************************************************
2773  *
2774  * FUNCTION:    DtCompileIvrs
2775  *
2776  * PARAMETERS:  List                - Current field list pointer
2777  *
2778  * RETURN:      Status
2779  *
2780  * DESCRIPTION: Compile IVRS. Notes:
2781  *              The IVRS is essentially a flat table, with the following
2782  *              structure:
2783  *              <Main ACPI Table Header>
2784  *              <Main subtable - virtualization info>
2785  *              <IVHD>
2786  *                  <Device Entries>
2787  *              ...
2788  *              <IVHD>
2789  *                  <Device Entries>
2790  *              <IVMD>
2791  *              ...
2792  *
2793  *****************************************************************************/
2794 
2795 ACPI_STATUS
DtCompileIvrs(void ** List)2796 DtCompileIvrs (
2797     void                    **List)
2798 {
2799     ACPI_STATUS             Status;
2800     DT_SUBTABLE             *Subtable;
2801     DT_SUBTABLE             *ParentTable;
2802     DT_SUBTABLE             *MainSubtable;
2803     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2804     DT_FIELD                *SubtableStart;
2805     ACPI_DMTABLE_INFO       *InfoTable = NULL;
2806     UINT8                   SubtableType;
2807     UINT8                   Temp64[16];
2808     UINT8                   Temp8;
2809 
2810 
2811     /* Main table */
2812 
2813     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
2814         &Subtable);
2815     if (ACPI_FAILURE (Status))
2816     {
2817         return (Status);
2818     }
2819 
2820     ParentTable = DtPeekSubtable ();
2821     DtInsertSubtable (ParentTable, Subtable);
2822     DtPushSubtable (Subtable);
2823 
2824     /* Save a pointer to the main subtable */
2825 
2826     MainSubtable = Subtable;
2827 
2828     while (*PFieldList)
2829     {
2830         SubtableStart = *PFieldList;
2831 
2832         /* Compile the SubtableType integer */
2833 
2834         DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
2835 
2836         switch (SubtableType)
2837         {
2838 
2839         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
2840 
2841         case ACPI_IVRS_TYPE_HARDWARE1:
2842 
2843             InfoTable = AcpiDmTableInfoIvrsHware1;
2844             break;
2845 
2846         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
2847 
2848         case ACPI_IVRS_TYPE_HARDWARE2:
2849         case ACPI_IVRS_TYPE_HARDWARE3:
2850 
2851             InfoTable = AcpiDmTableInfoIvrsHware23;
2852             break;
2853 
2854         /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
2855 
2856         case ACPI_IVRS_TYPE_MEMORY1:
2857         case ACPI_IVRS_TYPE_MEMORY2:
2858         case ACPI_IVRS_TYPE_MEMORY3:
2859 
2860             InfoTable = AcpiDmTableInfoIvrsMemory;
2861             break;
2862 
2863         /* 4-byte device entries */
2864 
2865         case ACPI_IVRS_TYPE_PAD4:
2866         case ACPI_IVRS_TYPE_ALL:
2867         case ACPI_IVRS_TYPE_SELECT:
2868         case ACPI_IVRS_TYPE_START:
2869         case ACPI_IVRS_TYPE_END:
2870 
2871             InfoTable = AcpiDmTableInfoIvrs4;
2872             break;
2873 
2874         /* 8-byte device entries, type A */
2875 
2876         case ACPI_IVRS_TYPE_ALIAS_SELECT:
2877         case ACPI_IVRS_TYPE_ALIAS_START:
2878 
2879             InfoTable = AcpiDmTableInfoIvrs8a;
2880             break;
2881 
2882         /* 8-byte device entries, type B */
2883 
2884         case ACPI_IVRS_TYPE_EXT_SELECT:
2885         case ACPI_IVRS_TYPE_EXT_START:
2886 
2887             InfoTable = AcpiDmTableInfoIvrs8b;
2888             break;
2889 
2890         /* 8-byte device entries, type C */
2891 
2892         case ACPI_IVRS_TYPE_SPECIAL:
2893 
2894             InfoTable = AcpiDmTableInfoIvrs8c;
2895             break;
2896 
2897         /* Variable device entries, type F0h */
2898 
2899         case ACPI_IVRS_TYPE_HID:
2900 
2901             InfoTable = AcpiDmTableInfoIvrsHid;
2902             break;
2903 
2904         default:
2905 
2906             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
2907                 "IVRS Device Entry");
2908             return (AE_ERROR);
2909         }
2910 
2911         /* Compile the InfoTable from above */
2912 
2913         Status = DtCompileTable (PFieldList, InfoTable,
2914             &Subtable);
2915         if (ACPI_FAILURE (Status))
2916         {
2917             return (Status);
2918         }
2919 
2920         ParentTable = DtPeekSubtable ();
2921         if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
2922             SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
2923             SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
2924             SubtableType != ACPI_IVRS_TYPE_HID &&
2925             SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
2926             SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
2927             SubtableType != ACPI_IVRS_TYPE_MEMORY3)
2928         {
2929             if (ParentTable)
2930                 DtInsertSubtable (ParentTable, Subtable);
2931         }
2932 
2933         switch (SubtableType)
2934         {
2935         case ACPI_IVRS_TYPE_HARDWARE1:
2936         case ACPI_IVRS_TYPE_HARDWARE2:
2937         case ACPI_IVRS_TYPE_HARDWARE3:
2938         case ACPI_IVRS_TYPE_MEMORY1:
2939         case ACPI_IVRS_TYPE_MEMORY2:
2940         case ACPI_IVRS_TYPE_MEMORY3:
2941 
2942             /* Insert these IVHDs/IVMDs at the root subtable */
2943 
2944             DtInsertSubtable (MainSubtable, Subtable);
2945             DtPushSubtable (Subtable);
2946             break;
2947 
2948         case ACPI_IVRS_TYPE_HID:
2949 
2950             /* Special handling for the HID named device entry (0xF0) */
2951 
2952             if (ParentTable)
2953             {
2954                 DtInsertSubtable (ParentTable, Subtable);
2955             }
2956 
2957             /*
2958              * Process the HID value. First, get the HID value as a string.
2959              */
2960             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2961 
2962                /*
2963                 * Determine if the HID is an integer or a string.
2964                 * An integer is defined to be 32 bits, with the upper 32 bits
2965                 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
2966                 * integer or a character string. If an integer, the lower
2967                 * 4 bytes of the field contain the integer and the upper
2968                 * 4 bytes are padded with 0".
2969                 */
2970             if (UtIsIdInteger ((UINT8 *) &Temp64))
2971             {
2972                 /* Compile the HID value as an integer */
2973 
2974                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2975 
2976                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
2977                     &Subtable);
2978                 if (ACPI_FAILURE (Status))
2979                 {
2980                     return (Status);
2981                 }
2982             }
2983             else
2984             {
2985                 /* Compile the HID value as a string */
2986 
2987                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
2988                     &Subtable);
2989                 if (ACPI_FAILURE (Status))
2990                 {
2991                     return (Status);
2992                 }
2993             }
2994 
2995             DtInsertSubtable (ParentTable, Subtable);
2996 
2997             /*
2998              * Process the CID value. First, get the CID value as a string.
2999              */
3000             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
3001 
3002             if (UtIsIdInteger ((UINT8 *) &Temp64))
3003             {
3004                 /* Compile the CID value as an integer */
3005 
3006                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
3007 
3008                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
3009                     &Subtable);
3010                 if (ACPI_FAILURE (Status))
3011                 {
3012                     return (Status);
3013                 }
3014             }
3015             else
3016             {
3017                 /* Compile the CID value as a string */
3018 
3019                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
3020                     &Subtable);
3021                 if (ACPI_FAILURE (Status))
3022                 {
3023                     return (Status);
3024                 }
3025             }
3026 
3027             DtInsertSubtable (ParentTable, Subtable);
3028 
3029             /*
3030              * Process the UID value. First, get and decode the "UID Format" field (Integer).
3031              */
3032             if (!*PFieldList)
3033             {
3034                 return (AE_OK);
3035             }
3036 
3037             DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
3038 
3039             switch (Temp8)
3040             {
3041             case ACPI_IVRS_UID_NOT_PRESENT:
3042                 break;
3043 
3044             case ACPI_IVRS_UID_IS_INTEGER:
3045 
3046                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
3047                     &Subtable);
3048                 if (ACPI_FAILURE (Status))
3049                 {
3050                     return (Status);
3051                 }
3052                 DtInsertSubtable (ParentTable, Subtable);
3053                 break;
3054 
3055             case ACPI_IVRS_UID_IS_STRING:
3056 
3057                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
3058                     &Subtable);
3059                 if (ACPI_FAILURE (Status))
3060                 {
3061                     return (Status);
3062                 }
3063                 DtInsertSubtable (ParentTable, Subtable);
3064                 break;
3065 
3066             default:
3067 
3068                 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
3069                     "IVRS Device Entry");
3070                 return (AE_ERROR);
3071             }
3072 
3073         default:
3074 
3075             /* All other subtable types come through here */
3076             break;
3077         }
3078     }
3079 
3080     return (AE_OK);
3081 }
3082