xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable1.c (revision 722b16673c40aedf280895f2f2f676bb494518d7)
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 
160 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
161 {
162     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
163     {ACPI_DMT_EXIT,     0,               NULL, 0}
164 };
165 
166 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
167 {
168     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
169     {ACPI_DMT_EXIT,     0,               NULL, 0}
170 };
171 
172 
173 /******************************************************************************
174  *
175  * FUNCTION:    DtCompileAest
176  *
177  * PARAMETERS:  List                - Current field list pointer
178  *
179  * RETURN:      Status
180  *
181  * DESCRIPTION: Compile AEST.
182  *
183  * NOTE: Assumes the following table structure:
184  *      For all AEST Error Nodes:
185  *          1) An AEST Error Node, followed immediately by:
186  *          2) Any node-specific data
187  *          3) An Interface Structure (one)
188  *          4) A list (array) of Interrupt Structures, the count as specified
189  *              in the NodeInterruptCount field of the Error Node header.
190  *
191  * AEST - ARM Error Source table. Conforms to:
192  * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020
193  *
194  *****************************************************************************/
195 
196 ACPI_STATUS
DtCompileAest(void ** List)197 DtCompileAest (
198     void                    **List)
199 {
200     ACPI_AEST_HEADER        *ErrorNodeHeader;
201     ACPI_AEST_PROCESSOR     *AestProcessor;
202     DT_SUBTABLE             *Subtable;
203     DT_SUBTABLE             *ParentTable;
204     ACPI_DMTABLE_INFO       *InfoTable;
205     ACPI_STATUS             Status;
206     UINT32                  i;
207     UINT32                  Offset;
208     DT_FIELD                **PFieldList = (DT_FIELD **) List;
209 
210 
211     while (*PFieldList)
212     {
213         /* Compile the common error node header */
214 
215         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr,
216             &Subtable);
217         if (ACPI_FAILURE (Status))
218         {
219             return (Status);
220         }
221 
222         ParentTable = DtPeekSubtable ();
223         DtInsertSubtable (ParentTable, Subtable);
224 
225         /* Everything past the error node header will be a subtable */
226 
227         DtPushSubtable (Subtable);
228 
229         /*
230          * Compile the node-specific structure (Based on the error
231          * node header Type field)
232          */
233         ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer);
234 
235         /* Point past the common error node header */
236 
237         Offset = sizeof (ACPI_AEST_HEADER);
238         ErrorNodeHeader->NodeSpecificOffset = Offset;
239 
240         /* Decode the error node type */
241 
242         switch (ErrorNodeHeader->Type)
243         {
244         case ACPI_AEST_PROCESSOR_ERROR_NODE:
245 
246             InfoTable = AcpiDmTableInfoAestProcError;
247             break;
248 
249         case ACPI_AEST_MEMORY_ERROR_NODE:
250 
251             InfoTable = AcpiDmTableInfoAestMemError;
252             break;
253 
254         case ACPI_AEST_SMMU_ERROR_NODE:
255 
256             InfoTable = AcpiDmTableInfoAestSmmuError;
257             break;
258 
259         case ACPI_AEST_VENDOR_ERROR_NODE:
260 
261             InfoTable = AcpiDmTableInfoAestVendorError;
262             break;
263 
264         case ACPI_AEST_GIC_ERROR_NODE:
265 
266             InfoTable = AcpiDmTableInfoAestGicError;
267             break;
268 
269         /* Error case below */
270         default:
271             AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n",
272                 ErrorNodeHeader->Type);
273             return (AE_ERROR);
274         }
275 
276         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
277         if (ACPI_FAILURE (Status))
278         {
279             return (Status);
280         }
281 
282         /* Point past the node-specific structure */
283 
284         Offset += Subtable->Length;
285         ErrorNodeHeader->NodeInterfaceOffset = Offset;
286 
287         ParentTable = DtPeekSubtable ();
288         DtInsertSubtable (ParentTable, Subtable);
289 
290         /* Compile any additional node-specific substructures */
291 
292         if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
293         {
294             /*
295              * Special handling for PROCESSOR_ERROR_NODE subtables
296              * (to handle the Resource Substructure via the ResourceType
297              * field).
298              */
299             AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR,
300                 Subtable->Buffer);
301 
302             switch (AestProcessor->ResourceType)
303             {
304             case ACPI_AEST_CACHE_RESOURCE:
305 
306                 InfoTable = AcpiDmTableInfoAestCacheRsrc;
307                 break;
308 
309             case ACPI_AEST_TLB_RESOURCE:
310 
311                 InfoTable = AcpiDmTableInfoAestTlbRsrc;
312                 break;
313 
314             case ACPI_AEST_GENERIC_RESOURCE:
315 
316                 InfoTable = AcpiDmTableInfoAestGenRsrc;
317                 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n",
318                     AestProcessor->ResourceType);
319                 return (AE_ERROR);
320 
321             /* Error case below */
322             default:
323                 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n",
324                     AestProcessor->ResourceType);
325                 return (AE_ERROR);
326             }
327 
328             Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
329             if (ACPI_FAILURE (Status))
330             {
331                 return (Status);
332             }
333 
334             /* Point past the resource substructure subtable */
335 
336             Offset += Subtable->Length;
337             ErrorNodeHeader->NodeInterfaceOffset = Offset;
338 
339             ParentTable = DtPeekSubtable ();
340             DtInsertSubtable (ParentTable, Subtable);
341         }
342 
343         /* Compile the (required) node interface structure */
344 
345         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface,
346             &Subtable);
347         if (ACPI_FAILURE (Status))
348         {
349             return (Status);
350         }
351 
352         ErrorNodeHeader->NodeInterruptOffset = 0;
353         ParentTable = DtPeekSubtable ();
354         DtInsertSubtable (ParentTable, Subtable);
355 
356         /* Compile each of the node interrupt structures */
357 
358         if (ErrorNodeHeader->NodeInterruptCount)
359         {
360             /* Point to the first interrupt structure */
361 
362             Offset += Subtable->Length;
363             ErrorNodeHeader->NodeInterruptOffset = Offset;
364         }
365 
366         /* Compile each of the interrupt structures */
367 
368         for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++)
369         {
370             Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt,
371                 &Subtable);
372             if (ACPI_FAILURE (Status))
373             {
374                 return (Status);
375             }
376 
377             ParentTable = DtPeekSubtable ();
378             DtInsertSubtable (ParentTable, Subtable);
379         }
380 
381         /* Prepare for the next AEST Error node */
382 
383         DtPopSubtable ();
384     }
385 
386     return (AE_OK);
387 }
388 
389 
390 /******************************************************************************
391  *
392  * FUNCTION:    DtCompileApmt
393  *
394  * PARAMETERS:  List                - Current field list pointer
395  *
396  * RETURN:      Status
397  *
398  * DESCRIPTION: Compile APMT.
399  *
400  *****************************************************************************/
401 
402 ACPI_STATUS
DtCompileApmt(void ** List)403 DtCompileApmt (
404     void                    **List)
405 {
406     ACPI_STATUS             Status;
407     ACPI_TABLE_HEADER       *Header;
408     ACPI_APMT_NODE          *ApmtNode;
409     ACPI_APMT_NODE          *PeerApmtNode;
410     DT_SUBTABLE             *Subtable;
411     DT_SUBTABLE             *PeerSubtable;
412     DT_SUBTABLE             *ParentTable;
413     DT_FIELD                **PFieldList = (DT_FIELD**)List;
414     DT_FIELD                *SubtableStart;
415     UINT32                  CurLength;
416     char                    MsgBuffer[64] = "";
417 
418     ParentTable = DtPeekSubtable();
419 
420     Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer);
421 
422     CurLength = sizeof(ACPI_TABLE_HEADER);
423 
424     /* Walk the parse tree */
425 
426     while (*PFieldList)
427     {
428         /* APMT Node Subtable */
429 
430         SubtableStart = *PFieldList;
431 
432         Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable);
433 
434         if (ACPI_FAILURE(Status))
435         {
436             return (Status);
437         }
438 
439         ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer);
440 
441         if (ApmtNode->Length != sizeof(ACPI_APMT_NODE))
442         {
443             DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT");
444             return (AE_ERROR);
445         }
446 
447         if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT)
448         {
449             snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type);
450             DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer);
451             return (AE_ERROR);
452         }
453 
454         PeerSubtable = DtGetNextSubtable(ParentTable, NULL);
455 
456         /* Validate the node id needs to be unique. */
457         while(PeerSubtable)
458         {
459             PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer);
460             if (PeerApmtNode->Id == ApmtNode->Id)
461             {
462                 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id);
463                 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer);
464                 return (AE_ERROR);
465             }
466 
467             PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable);
468         }
469 
470         CurLength += ApmtNode->Length;
471 
472         DtInsertSubtable(ParentTable, Subtable);
473     }
474 
475     if (Header->Length != CurLength)
476     {
477         snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)",
478             Header->Length, CurLength);
479         DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer);
480         return (AE_ERROR);
481     }
482 
483     return (AE_OK);
484 }
485 
486 /******************************************************************************
487  *
488  * FUNCTION:    DtCompileAsf
489  *
490  * PARAMETERS:  List                - Current field list pointer
491  *
492  * RETURN:      Status
493  *
494  * DESCRIPTION: Compile ASF!.
495  *
496  *****************************************************************************/
497 
498 ACPI_STATUS
DtCompileAsf(void ** List)499 DtCompileAsf (
500     void                    **List)
501 {
502     ACPI_ASF_INFO           *AsfTable;
503     DT_SUBTABLE             *Subtable;
504     DT_SUBTABLE             *ParentTable;
505     ACPI_DMTABLE_INFO       *InfoTable;
506     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
507     UINT32                  DataCount = 0;
508     ACPI_STATUS             Status;
509     UINT32                  i;
510     DT_FIELD                **PFieldList = (DT_FIELD **) List;
511     DT_FIELD                *SubtableStart;
512 
513 
514     while (*PFieldList)
515     {
516         SubtableStart = *PFieldList;
517         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
518             &Subtable);
519         if (ACPI_FAILURE (Status))
520         {
521             return (Status);
522         }
523 
524         ParentTable = DtPeekSubtable ();
525         DtInsertSubtable (ParentTable, Subtable);
526         DtPushSubtable (Subtable);
527 
528         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
529 
530         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
531         {
532         case ACPI_ASF_TYPE_INFO:
533 
534             InfoTable = AcpiDmTableInfoAsf0;
535             break;
536 
537         case ACPI_ASF_TYPE_ALERT:
538 
539             InfoTable = AcpiDmTableInfoAsf1;
540             break;
541 
542         case ACPI_ASF_TYPE_CONTROL:
543 
544             InfoTable = AcpiDmTableInfoAsf2;
545             break;
546 
547         case ACPI_ASF_TYPE_BOOT:
548 
549             InfoTable = AcpiDmTableInfoAsf3;
550             break;
551 
552         case ACPI_ASF_TYPE_ADDRESS:
553 
554             InfoTable = AcpiDmTableInfoAsf4;
555             break;
556 
557         default:
558 
559             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
560             return (AE_ERROR);
561         }
562 
563         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
564         if (ACPI_FAILURE (Status))
565         {
566             return (Status);
567         }
568 
569         ParentTable = DtPeekSubtable ();
570         DtInsertSubtable (ParentTable, Subtable);
571 
572         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
573         {
574         case ACPI_ASF_TYPE_INFO:
575 
576             DataInfoTable = NULL;
577             break;
578 
579         case ACPI_ASF_TYPE_ALERT:
580 
581             DataInfoTable = AcpiDmTableInfoAsf1a;
582             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
583                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
584                     sizeof (ACPI_ASF_HEADER)))->Alerts;
585             break;
586 
587         case ACPI_ASF_TYPE_CONTROL:
588 
589             DataInfoTable = AcpiDmTableInfoAsf2a;
590             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
591                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
592                     sizeof (ACPI_ASF_HEADER)))->Controls;
593             break;
594 
595         case ACPI_ASF_TYPE_BOOT:
596 
597             DataInfoTable = NULL;
598             break;
599 
600         case ACPI_ASF_TYPE_ADDRESS:
601 
602             DataInfoTable = TableInfoAsfAddress;
603             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
604                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
605                     sizeof (ACPI_ASF_HEADER)))->Devices;
606             break;
607 
608         default:
609 
610             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
611             return (AE_ERROR);
612         }
613 
614         if (DataInfoTable)
615         {
616             switch (AsfTable->Header.Type & 0x7F)
617             {
618             case ACPI_ASF_TYPE_ADDRESS:
619 
620                 while (DataCount > 0)
621                 {
622                     Status = DtCompileTable (PFieldList, DataInfoTable,
623                         &Subtable);
624                     if (ACPI_FAILURE (Status))
625                     {
626                         return (Status);
627                     }
628 
629                     DtInsertSubtable (ParentTable, Subtable);
630                     DataCount = DataCount - Subtable->Length;
631                 }
632                 break;
633 
634             default:
635 
636                 for (i = 0; i < DataCount; i++)
637                 {
638                     Status = DtCompileTable (PFieldList, DataInfoTable,
639                         &Subtable);
640                     if (ACPI_FAILURE (Status))
641                     {
642                         return (Status);
643                     }
644 
645                     DtInsertSubtable (ParentTable, Subtable);
646                 }
647                 break;
648             }
649         }
650 
651         DtPopSubtable ();
652     }
653 
654     return (AE_OK);
655 }
656 
657 /******************************************************************************
658  *
659  * FUNCTION:    DtCompileAspt
660  *
661  * PARAMETERS:  List                - Current field list pointer
662  *
663  * RETURN:      Status
664  *
665  * DESCRIPTION: Compile ASPT.
666  *
667  *****************************************************************************/
668 
669 ACPI_STATUS
DtCompileAspt(void ** List)670 DtCompileAspt (
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 
755 ACPI_STATUS
DtCompileCdat(void ** List)756 DtCompileCdat (
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 
882 ACPI_STATUS
DtCompileCedt(void ** List)883 DtCompileCedt (
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 
1006 ACPI_STATUS
DtCompileCpep(void ** List)1007 DtCompileCpep (
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 
1031 ACPI_STATUS
DtCompileCsrt(void ** List)1032 DtCompileCsrt (
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 
1139 ACPI_STATUS
DtCompileDbg2(void ** List)1140 DtCompileDbg2 (
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         }
1273 subtableDone:
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 
1295 ACPI_STATUS
DtCompileDmar(void ** List)1296 DtCompileDmar (
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 
1460 ACPI_STATUS
DtCompileDrtm(void ** List)1461 DtCompileDrtm (
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 
1597 ACPI_STATUS
DtCompileEinj(void ** List)1598 DtCompileEinj (
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 
1622 ACPI_STATUS
DtCompileErst(void ** List)1623 DtCompileErst (
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 
1647 ACPI_STATUS
DtCompileGtdt(void ** List)1648 DtCompileGtdt (
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 
1790 ACPI_STATUS
DtCompileFpdt(void ** List)1791 DtCompileFpdt (
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 
1865 ACPI_STATUS
DtCompileHest(void ** List)1866 DtCompileHest (
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 
2018 ACPI_STATUS
DtCompileHmat(void ** List)2019 DtCompileHmat (
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 
2230 ACPI_STATUS
DtCompileIort(void ** List)2231 DtCompileIort (
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 
2656 ACPI_STATUS
DtCompileIvrs(void ** List)2657 DtCompileIvrs (
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