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