1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2014, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 /* Compile all complex data tables */
45 
46 #include "aslcompiler.h"
47 #include "dtcompiler.h"
48 
49 #define _COMPONENT          DT_COMPILER
50         ACPI_MODULE_NAME    ("dttable")
51 
52 
53 /* TBD: merge these into dmtbinfo.c? */
54 
55 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
56 {
57     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
58     {ACPI_DMT_EXIT,     0,               NULL, 0}
59 };
60 
61 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
62 {
63     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
64     {ACPI_DMT_EXIT,     0,               NULL, 0}
65 };
66 
67 
68 /* TBD: move to acmacros.h */
69 
70 #define ACPI_SUB_PTR(t, a, b) \
71     ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
72 
73 
74 /* Local prototypes */
75 
76 static ACPI_STATUS
77 DtCompileTwoSubtables (
78     void                    **List,
79     ACPI_DMTABLE_INFO       *TableInfo1,
80     ACPI_DMTABLE_INFO       *TableInfo2);
81 
82 
83 /******************************************************************************
84  *
85  * FUNCTION:    DtCompileTwoSubtables
86  *
87  * PARAMETERS:  List                - Current field list pointer
88  *              TableInfo1          - Info table 1
89  *              TableInfo1          - Info table 2
90  *
91  * RETURN:      Status
92  *
93  * DESCRIPTION: Compile tables with a header and one or more same subtables.
94  *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
95  *
96  *****************************************************************************/
97 
98 static ACPI_STATUS
99 DtCompileTwoSubtables (
100     void                    **List,
101     ACPI_DMTABLE_INFO       *TableInfo1,
102     ACPI_DMTABLE_INFO       *TableInfo2)
103 {
104     ACPI_STATUS             Status;
105     DT_SUBTABLE             *Subtable;
106     DT_SUBTABLE             *ParentTable;
107     DT_FIELD                **PFieldList = (DT_FIELD **) List;
108 
109 
110     Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
111     if (ACPI_FAILURE (Status))
112     {
113         return (Status);
114     }
115 
116     ParentTable = DtPeekSubtable ();
117     DtInsertSubtable (ParentTable, Subtable);
118 
119     while (*PFieldList)
120     {
121         Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
122         if (ACPI_FAILURE (Status))
123         {
124             return (Status);
125         }
126 
127         DtInsertSubtable (ParentTable, Subtable);
128     }
129 
130     return (AE_OK);
131 }
132 
133 
134 /******************************************************************************
135  *
136  * FUNCTION:    DtCompileFacs
137  *
138  * PARAMETERS:  PFieldList          - Current field list pointer
139  *
140  * RETURN:      Status
141  *
142  * DESCRIPTION: Compile FACS.
143  *
144  *****************************************************************************/
145 
146 ACPI_STATUS
147 DtCompileFacs (
148     DT_FIELD                **PFieldList)
149 {
150     DT_SUBTABLE             *Subtable;
151     UINT8                   *ReservedBuffer;
152     ACPI_STATUS             Status;
153     UINT32                  ReservedSize;
154 
155 
156     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
157                 &Gbl_RootTable, TRUE);
158     if (ACPI_FAILURE (Status))
159     {
160         return (Status);
161     }
162 
163     /* Large FACS reserved area at the end of the table */
164 
165     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
166     ReservedBuffer = UtLocalCalloc (ReservedSize);
167 
168     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
169 
170     ACPI_FREE (ReservedBuffer);
171     DtInsertSubtable (Gbl_RootTable, Subtable);
172     return (AE_OK);
173 }
174 
175 
176 /******************************************************************************
177  *
178  * FUNCTION:    DtCompileRsdp
179  *
180  * PARAMETERS:  PFieldList          - Current field list pointer
181  *
182  * RETURN:      Status
183  *
184  * DESCRIPTION: Compile RSDP.
185  *
186  *****************************************************************************/
187 
188 ACPI_STATUS
189 DtCompileRsdp (
190     DT_FIELD                **PFieldList)
191 {
192     DT_SUBTABLE             *Subtable;
193     ACPI_TABLE_RSDP         *Rsdp;
194     ACPI_RSDP_EXTENSION     *RsdpExtension;
195     ACPI_STATUS             Status;
196 
197 
198     /* Compile the "common" RSDP (ACPI 1.0) */
199 
200     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
201                 &Gbl_RootTable, TRUE);
202     if (ACPI_FAILURE (Status))
203     {
204         return (Status);
205     }
206 
207     Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
208     DtSetTableChecksum (&Rsdp->Checksum);
209 
210     if (Rsdp->Revision > 0)
211     {
212         /* Compile the "extended" part of the RSDP as a subtable */
213 
214         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
215                     &Subtable, TRUE);
216         if (ACPI_FAILURE (Status))
217         {
218             return (Status);
219         }
220 
221         DtInsertSubtable (Gbl_RootTable, Subtable);
222 
223         /* Set length and extended checksum for entire RSDP */
224 
225         RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
226         RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
227         DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
228     }
229 
230     return (AE_OK);
231 }
232 
233 
234 /******************************************************************************
235  *
236  * FUNCTION:    DtCompileAsf
237  *
238  * PARAMETERS:  List                - Current field list pointer
239  *
240  * RETURN:      Status
241  *
242  * DESCRIPTION: Compile ASF!.
243  *
244  *****************************************************************************/
245 
246 ACPI_STATUS
247 DtCompileAsf (
248     void                    **List)
249 {
250     ACPI_ASF_INFO           *AsfTable;
251     DT_SUBTABLE             *Subtable;
252     DT_SUBTABLE             *ParentTable;
253     ACPI_DMTABLE_INFO       *InfoTable;
254     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
255     UINT32                  DataCount = 0;
256     ACPI_STATUS             Status;
257     UINT32                  i;
258     DT_FIELD                **PFieldList = (DT_FIELD **) List;
259     DT_FIELD                *SubtableStart;
260 
261 
262     while (*PFieldList)
263     {
264         SubtableStart = *PFieldList;
265         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
266                     &Subtable, TRUE);
267         if (ACPI_FAILURE (Status))
268         {
269             return (Status);
270         }
271 
272         ParentTable = DtPeekSubtable ();
273         DtInsertSubtable (ParentTable, Subtable);
274         DtPushSubtable (Subtable);
275 
276         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
277 
278         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
279         {
280         case ACPI_ASF_TYPE_INFO:
281 
282             InfoTable = AcpiDmTableInfoAsf0;
283             break;
284 
285         case ACPI_ASF_TYPE_ALERT:
286 
287             InfoTable = AcpiDmTableInfoAsf1;
288             break;
289 
290         case ACPI_ASF_TYPE_CONTROL:
291 
292             InfoTable = AcpiDmTableInfoAsf2;
293             break;
294 
295         case ACPI_ASF_TYPE_BOOT:
296 
297             InfoTable = AcpiDmTableInfoAsf3;
298             break;
299 
300         case ACPI_ASF_TYPE_ADDRESS:
301 
302             InfoTable = AcpiDmTableInfoAsf4;
303             break;
304 
305         default:
306 
307             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
308             return (AE_ERROR);
309         }
310 
311         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
312         if (ACPI_FAILURE (Status))
313         {
314             return (Status);
315         }
316 
317         ParentTable = DtPeekSubtable ();
318         DtInsertSubtable (ParentTable, Subtable);
319 
320         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
321         {
322         case ACPI_ASF_TYPE_INFO:
323 
324             DataInfoTable = NULL;
325             break;
326 
327         case ACPI_ASF_TYPE_ALERT:
328 
329             DataInfoTable = AcpiDmTableInfoAsf1a;
330             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
331                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
332                             sizeof (ACPI_ASF_HEADER)))->Alerts;
333             break;
334 
335         case ACPI_ASF_TYPE_CONTROL:
336 
337             DataInfoTable = AcpiDmTableInfoAsf2a;
338             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
339                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
340                             sizeof (ACPI_ASF_HEADER)))->Controls;
341             break;
342 
343         case ACPI_ASF_TYPE_BOOT:
344 
345             DataInfoTable = NULL;
346             break;
347 
348         case ACPI_ASF_TYPE_ADDRESS:
349 
350             DataInfoTable = TableInfoAsfAddress;
351             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
352                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
353                             sizeof (ACPI_ASF_HEADER)))->Devices;
354             break;
355 
356         default:
357 
358             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
359             return (AE_ERROR);
360         }
361 
362         if (DataInfoTable)
363         {
364             switch (AsfTable->Header.Type & 0x7F)
365             {
366             case ACPI_ASF_TYPE_ADDRESS:
367 
368                 while (DataCount > 0)
369                 {
370                     Status = DtCompileTable (PFieldList, DataInfoTable,
371                                 &Subtable, TRUE);
372                     if (ACPI_FAILURE (Status))
373                     {
374                         return (Status);
375                     }
376 
377                     DtInsertSubtable (ParentTable, Subtable);
378                     DataCount = DataCount - Subtable->Length;
379                 }
380                 break;
381 
382             default:
383 
384                 for (i = 0; i < DataCount; i++)
385                 {
386                     Status = DtCompileTable (PFieldList, DataInfoTable,
387                                 &Subtable, TRUE);
388                     if (ACPI_FAILURE (Status))
389                     {
390                         return (Status);
391                     }
392 
393                     DtInsertSubtable (ParentTable, Subtable);
394                 }
395                 break;
396             }
397         }
398 
399         DtPopSubtable ();
400     }
401 
402     return (AE_OK);
403 }
404 
405 
406 /******************************************************************************
407  *
408  * FUNCTION:    DtCompileCpep
409  *
410  * PARAMETERS:  List                - Current field list pointer
411  *
412  * RETURN:      Status
413  *
414  * DESCRIPTION: Compile CPEP.
415  *
416  *****************************************************************************/
417 
418 ACPI_STATUS
419 DtCompileCpep (
420     void                    **List)
421 {
422     ACPI_STATUS             Status;
423 
424 
425     Status = DtCompileTwoSubtables (List,
426                  AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
427     return (Status);
428 }
429 
430 
431 /******************************************************************************
432  *
433  * FUNCTION:    DtCompileCsrt
434  *
435  * PARAMETERS:  List                - Current field list pointer
436  *
437  * RETURN:      Status
438  *
439  * DESCRIPTION: Compile CSRT.
440  *
441  *****************************************************************************/
442 
443 ACPI_STATUS
444 DtCompileCsrt (
445     void                    **List)
446 {
447     ACPI_STATUS             Status = AE_OK;
448     DT_SUBTABLE             *Subtable;
449     DT_SUBTABLE             *ParentTable;
450     DT_FIELD                **PFieldList = (DT_FIELD **) List;
451     UINT32                  DescriptorCount;
452     UINT32                  GroupLength;
453 
454 
455     /* Subtables (Resource Groups) */
456 
457     while (*PFieldList)
458     {
459         /* Resource group subtable */
460 
461         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
462                     &Subtable, TRUE);
463         if (ACPI_FAILURE (Status))
464         {
465             return (Status);
466         }
467 
468         /* Compute the number of resource descriptors */
469 
470         GroupLength =
471             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
472                 Subtable->Buffer))->Length -
473             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
474                 Subtable->Buffer))->SharedInfoLength -
475             sizeof (ACPI_CSRT_GROUP);
476 
477         DescriptorCount = (GroupLength  /
478             sizeof (ACPI_CSRT_DESCRIPTOR));
479 
480         ParentTable = DtPeekSubtable ();
481         DtInsertSubtable (ParentTable, Subtable);
482         DtPushSubtable (Subtable);
483 
484         /* Shared info subtable (One per resource group) */
485 
486         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
487                     &Subtable, TRUE);
488         if (ACPI_FAILURE (Status))
489         {
490             return (Status);
491         }
492 
493         ParentTable = DtPeekSubtable ();
494         DtInsertSubtable (ParentTable, Subtable);
495 
496         /* Sub-Subtables (Resource Descriptors) */
497 
498         while (*PFieldList && DescriptorCount)
499         {
500             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
501                         &Subtable, TRUE);
502             if (ACPI_FAILURE (Status))
503             {
504                 return (Status);
505             }
506 
507             ParentTable = DtPeekSubtable ();
508             DtInsertSubtable (ParentTable, Subtable);
509             DescriptorCount--;
510         }
511 
512         DtPopSubtable ();
513     }
514 
515     return (Status);
516 }
517 
518 
519 /******************************************************************************
520  *
521  * FUNCTION:    DtCompileDbg2
522  *
523  * PARAMETERS:  List                - Current field list pointer
524  *
525  * RETURN:      Status
526  *
527  * DESCRIPTION: Compile DBG2.
528  *
529  *****************************************************************************/
530 
531 ACPI_STATUS
532 DtCompileDbg2 (
533     void                    **List)
534 {
535     ACPI_STATUS             Status;
536     DT_SUBTABLE             *Subtable;
537     DT_SUBTABLE             *ParentTable;
538     DT_FIELD                **PFieldList = (DT_FIELD **) List;
539     UINT32                  SubtableCount;
540     ACPI_DBG2_HEADER        *Dbg2Header;
541     ACPI_DBG2_DEVICE        *DeviceInfo;
542     UINT16                  CurrentOffset;
543     UINT32                  i;
544 
545 
546     /* Main table */
547 
548     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
549     if (ACPI_FAILURE (Status))
550     {
551         return (Status);
552     }
553 
554     ParentTable = DtPeekSubtable ();
555     DtInsertSubtable (ParentTable, Subtable);
556 
557     /* Main table fields */
558 
559     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
560     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
561         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
562 
563     SubtableCount = Dbg2Header->InfoCount;
564     DtPushSubtable (Subtable);
565 
566     /* Process all Device Information subtables (Count = InfoCount) */
567 
568     while (*PFieldList && SubtableCount)
569     {
570         /* Subtable: Debug Device Information */
571 
572         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
573                     &Subtable, TRUE);
574         if (ACPI_FAILURE (Status))
575         {
576             return (Status);
577         }
578 
579         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
580         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
581 
582         ParentTable = DtPeekSubtable ();
583         DtInsertSubtable (ParentTable, Subtable);
584         DtPushSubtable (Subtable);
585 
586         ParentTable = DtPeekSubtable ();
587 
588         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
589 
590         DeviceInfo->BaseAddressOffset = CurrentOffset;
591         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
592         {
593             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
594                         &Subtable, TRUE);
595             if (ACPI_FAILURE (Status))
596             {
597                 return (Status);
598             }
599 
600             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
601             DtInsertSubtable (ParentTable, Subtable);
602         }
603 
604         /* AddressSize array (Required, size = RegisterCount) */
605 
606         DeviceInfo->AddressSizeOffset = CurrentOffset;
607         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
608         {
609             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
610                         &Subtable, TRUE);
611             if (ACPI_FAILURE (Status))
612             {
613                 return (Status);
614             }
615 
616             CurrentOffset += (UINT16) sizeof (UINT32);
617             DtInsertSubtable (ParentTable, Subtable);
618         }
619 
620         /* NamespaceString device identifier (Required, size = NamePathLength) */
621 
622         DeviceInfo->NamepathOffset = CurrentOffset;
623         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
624                     &Subtable, TRUE);
625         if (ACPI_FAILURE (Status))
626         {
627             return (Status);
628         }
629 
630         /* Update the device info header */
631 
632         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
633         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
634         DtInsertSubtable (ParentTable, Subtable);
635 
636         /* OemData - Variable-length data (Optional, size = OemDataLength) */
637 
638         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
639                     &Subtable, TRUE);
640         if (ACPI_FAILURE (Status))
641         {
642             return (Status);
643         }
644 
645         /* Update the device info header (zeros if no OEM data present) */
646 
647         DeviceInfo->OemDataOffset = 0;
648         DeviceInfo->OemDataLength = 0;
649 
650         /* Optional subtable (OemData) */
651 
652         if (Subtable && Subtable->Length)
653         {
654             DeviceInfo->OemDataOffset = CurrentOffset;
655             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
656 
657             DtInsertSubtable (ParentTable, Subtable);
658         }
659 
660         SubtableCount--;
661         DtPopSubtable (); /* Get next Device Information subtable */
662     }
663 
664     DtPopSubtable ();
665     return (AE_OK);
666 }
667 
668 
669 /******************************************************************************
670  *
671  * FUNCTION:    DtCompileDmar
672  *
673  * PARAMETERS:  List                - Current field list pointer
674  *
675  * RETURN:      Status
676  *
677  * DESCRIPTION: Compile DMAR.
678  *
679  *****************************************************************************/
680 
681 ACPI_STATUS
682 DtCompileDmar (
683     void                    **List)
684 {
685     ACPI_STATUS             Status;
686     DT_SUBTABLE             *Subtable;
687     DT_SUBTABLE             *ParentTable;
688     DT_FIELD                **PFieldList = (DT_FIELD **) List;
689     DT_FIELD                *SubtableStart;
690     ACPI_DMTABLE_INFO       *InfoTable;
691     ACPI_DMAR_HEADER        *DmarHeader;
692     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
693     UINT32                  DeviceScopeLength;
694     UINT32                  PciPathLength;
695 
696 
697     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
698     if (ACPI_FAILURE (Status))
699     {
700         return (Status);
701     }
702 
703     ParentTable = DtPeekSubtable ();
704     DtInsertSubtable (ParentTable, Subtable);
705     DtPushSubtable (Subtable);
706 
707     while (*PFieldList)
708     {
709         /* DMAR Header */
710 
711         SubtableStart = *PFieldList;
712         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
713                     &Subtable, TRUE);
714         if (ACPI_FAILURE (Status))
715         {
716             return (Status);
717         }
718 
719         ParentTable = DtPeekSubtable ();
720         DtInsertSubtable (ParentTable, Subtable);
721         DtPushSubtable (Subtable);
722 
723         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
724 
725         switch (DmarHeader->Type)
726         {
727         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
728 
729             InfoTable = AcpiDmTableInfoDmar0;
730             break;
731 
732         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
733 
734             InfoTable = AcpiDmTableInfoDmar1;
735             break;
736 
737         case ACPI_DMAR_TYPE_ROOT_ATS:
738 
739             InfoTable = AcpiDmTableInfoDmar2;
740             break;
741 
742         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
743 
744             InfoTable = AcpiDmTableInfoDmar3;
745             break;
746 
747         case ACPI_DMAR_TYPE_NAMESPACE:
748 
749             InfoTable = AcpiDmTableInfoDmar4;
750             break;
751 
752         default:
753 
754             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
755             return (AE_ERROR);
756         }
757 
758         /* DMAR Subtable */
759 
760         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
761         if (ACPI_FAILURE (Status))
762         {
763             return (Status);
764         }
765 
766         ParentTable = DtPeekSubtable ();
767         DtInsertSubtable (ParentTable, Subtable);
768 
769         /*
770          * Optional Device Scope subtables
771          */
772         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
773             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
774         {
775             /* These types do not support device scopes */
776 
777             DtPopSubtable ();
778             continue;
779         }
780 
781         DtPushSubtable (Subtable);
782         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
783             ParentTable->Length;
784         while (DeviceScopeLength)
785         {
786             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
787                         &Subtable, FALSE);
788             if (Status == AE_NOT_FOUND)
789             {
790                 break;
791             }
792 
793             ParentTable = DtPeekSubtable ();
794             DtInsertSubtable (ParentTable, Subtable);
795             DtPushSubtable (Subtable);
796 
797             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
798 
799             /* Optional PCI Paths */
800 
801             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
802             while (PciPathLength)
803             {
804                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
805                             &Subtable, FALSE);
806                 if (Status == AE_NOT_FOUND)
807                 {
808                     DtPopSubtable ();
809                     break;
810                 }
811 
812                 ParentTable = DtPeekSubtable ();
813                 DtInsertSubtable (ParentTable, Subtable);
814                 PciPathLength -= Subtable->Length;
815             }
816 
817             DtPopSubtable ();
818             DeviceScopeLength -= DmarDeviceScope->Length;
819         }
820 
821         DtPopSubtable ();
822         DtPopSubtable ();
823     }
824 
825     return (AE_OK);
826 }
827 
828 
829 /******************************************************************************
830  *
831  * FUNCTION:    DtCompileEinj
832  *
833  * PARAMETERS:  List                - Current field list pointer
834  *
835  * RETURN:      Status
836  *
837  * DESCRIPTION: Compile EINJ.
838  *
839  *****************************************************************************/
840 
841 ACPI_STATUS
842 DtCompileEinj (
843     void                    **List)
844 {
845     ACPI_STATUS             Status;
846 
847 
848     Status = DtCompileTwoSubtables (List,
849                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
850     return (Status);
851 }
852 
853 
854 /******************************************************************************
855  *
856  * FUNCTION:    DtCompileErst
857  *
858  * PARAMETERS:  List                - Current field list pointer
859  *
860  * RETURN:      Status
861  *
862  * DESCRIPTION: Compile ERST.
863  *
864  *****************************************************************************/
865 
866 ACPI_STATUS
867 DtCompileErst (
868     void                    **List)
869 {
870     ACPI_STATUS             Status;
871 
872 
873     Status = DtCompileTwoSubtables (List,
874                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
875     return (Status);
876 }
877 
878 
879 /******************************************************************************
880  *
881  * FUNCTION:    DtCompileFadt
882  *
883  * PARAMETERS:  List                - Current field list pointer
884  *
885  * RETURN:      Status
886  *
887  * DESCRIPTION: Compile FADT.
888  *
889  *****************************************************************************/
890 
891 ACPI_STATUS
892 DtCompileFadt (
893     void                    **List)
894 {
895     ACPI_STATUS             Status;
896     DT_SUBTABLE             *Subtable;
897     DT_SUBTABLE             *ParentTable;
898     DT_FIELD                **PFieldList = (DT_FIELD **) List;
899     ACPI_TABLE_HEADER       *Table;
900     UINT8                   Revision;
901 
902 
903     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
904                 &Subtable, TRUE);
905     if (ACPI_FAILURE (Status))
906     {
907         return (Status);
908     }
909 
910     ParentTable = DtPeekSubtable ();
911     DtInsertSubtable (ParentTable, Subtable);
912 
913     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
914     Revision = Table->Revision;
915 
916     if (Revision == 2)
917     {
918         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
919                     &Subtable, TRUE);
920         if (ACPI_FAILURE (Status))
921         {
922             return (Status);
923         }
924 
925         DtInsertSubtable (ParentTable, Subtable);
926     }
927     else if (Revision >= 2)
928     {
929         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
930                     &Subtable, TRUE);
931         if (ACPI_FAILURE (Status))
932         {
933             return (Status);
934         }
935 
936         DtInsertSubtable (ParentTable, Subtable);
937 
938         if (Revision >= 5)
939         {
940             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
941                         &Subtable, TRUE);
942             if (ACPI_FAILURE (Status))
943             {
944                 return (Status);
945             }
946 
947             DtInsertSubtable (ParentTable, Subtable);
948         }
949     }
950 
951     return (AE_OK);
952 }
953 
954 /******************************************************************************
955  *
956  * FUNCTION:    DtCompileGtdt
957  *
958  * PARAMETERS:  List                - Current field list pointer
959  *
960  * RETURN:      Status
961  *
962  * DESCRIPTION: Compile GTDT.
963  *
964  *****************************************************************************/
965 
966 ACPI_STATUS
967 DtCompileGtdt (
968     void                    **List)
969 {
970     ACPI_STATUS             Status;
971     DT_SUBTABLE             *Subtable;
972     DT_SUBTABLE             *ParentTable;
973     DT_FIELD                **PFieldList = (DT_FIELD **) List;
974     DT_FIELD                *SubtableStart;
975     ACPI_SUBTABLE_HEADER    *GtdtHeader;
976     ACPI_DMTABLE_INFO       *InfoTable;
977     UINT32                  GtCount;
978 
979 
980     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
981                 &Subtable, TRUE);
982     if (ACPI_FAILURE (Status))
983     {
984         return (Status);
985     }
986 
987     ParentTable = DtPeekSubtable ();
988     DtInsertSubtable (ParentTable, Subtable);
989 
990     while (*PFieldList)
991     {
992         SubtableStart = *PFieldList;
993         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
994                     &Subtable, TRUE);
995         if (ACPI_FAILURE (Status))
996         {
997             return (Status);
998         }
999 
1000         ParentTable = DtPeekSubtable ();
1001         DtInsertSubtable (ParentTable, Subtable);
1002         DtPushSubtable (Subtable);
1003 
1004         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1005 
1006         switch (GtdtHeader->Type)
1007         {
1008         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1009 
1010             InfoTable = AcpiDmTableInfoGtdt0;
1011             break;
1012 
1013         case ACPI_GTDT_TYPE_WATCHDOG:
1014 
1015             InfoTable = AcpiDmTableInfoGtdt1;
1016             break;
1017 
1018         default:
1019 
1020             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1021             return (AE_ERROR);
1022         }
1023 
1024         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1025         if (ACPI_FAILURE (Status))
1026         {
1027             return (Status);
1028         }
1029 
1030         ParentTable = DtPeekSubtable ();
1031         DtInsertSubtable (ParentTable, Subtable);
1032 
1033         /*
1034          * Additional GT block subtable data
1035          */
1036 
1037         switch (GtdtHeader->Type)
1038         {
1039         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1040 
1041             DtPushSubtable (Subtable);
1042             ParentTable = DtPeekSubtable ();
1043 
1044             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1045                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1046             while (GtCount)
1047             {
1048                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1049                             &Subtable, TRUE);
1050                 if (ACPI_FAILURE (Status))
1051                 {
1052                     return (Status);
1053                 }
1054 
1055 
1056                 DtInsertSubtable (ParentTable, Subtable);
1057                 GtCount--;
1058             }
1059             DtPopSubtable ();
1060             break;
1061 
1062         default:
1063 
1064             break;
1065         }
1066 
1067         DtPopSubtable ();
1068     }
1069 
1070     return (AE_OK);
1071 }
1072 
1073 
1074 /******************************************************************************
1075  *
1076  * FUNCTION:    DtCompileFpdt
1077  *
1078  * PARAMETERS:  List                - Current field list pointer
1079  *
1080  * RETURN:      Status
1081  *
1082  * DESCRIPTION: Compile FPDT.
1083  *
1084  *****************************************************************************/
1085 
1086 ACPI_STATUS
1087 DtCompileFpdt (
1088     void                    **List)
1089 {
1090     ACPI_STATUS             Status;
1091     ACPI_FPDT_HEADER        *FpdtHeader;
1092     DT_SUBTABLE             *Subtable;
1093     DT_SUBTABLE             *ParentTable;
1094     ACPI_DMTABLE_INFO       *InfoTable;
1095     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1096     DT_FIELD                *SubtableStart;
1097 
1098 
1099     while (*PFieldList)
1100     {
1101         SubtableStart = *PFieldList;
1102         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1103                     &Subtable, TRUE);
1104         if (ACPI_FAILURE (Status))
1105         {
1106             return (Status);
1107         }
1108 
1109         ParentTable = DtPeekSubtable ();
1110         DtInsertSubtable (ParentTable, Subtable);
1111         DtPushSubtable (Subtable);
1112 
1113         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1114 
1115         switch (FpdtHeader->Type)
1116         {
1117         case ACPI_FPDT_TYPE_BOOT:
1118 
1119             InfoTable = AcpiDmTableInfoFpdt0;
1120             break;
1121 
1122         case ACPI_FPDT_TYPE_S3PERF:
1123 
1124             InfoTable = AcpiDmTableInfoFpdt1;
1125             break;
1126 
1127         default:
1128 
1129             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1130             return (AE_ERROR);
1131             break;
1132         }
1133 
1134         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1135         if (ACPI_FAILURE (Status))
1136         {
1137             return (Status);
1138         }
1139 
1140         ParentTable = DtPeekSubtable ();
1141         DtInsertSubtable (ParentTable, Subtable);
1142         DtPopSubtable ();
1143     }
1144 
1145     return (AE_OK);
1146 }
1147 
1148 
1149 /******************************************************************************
1150  *
1151  * FUNCTION:    DtCompileHest
1152  *
1153  * PARAMETERS:  List                - Current field list pointer
1154  *
1155  * RETURN:      Status
1156  *
1157  * DESCRIPTION: Compile HEST.
1158  *
1159  *****************************************************************************/
1160 
1161 ACPI_STATUS
1162 DtCompileHest (
1163     void                    **List)
1164 {
1165     ACPI_STATUS             Status;
1166     DT_SUBTABLE             *Subtable;
1167     DT_SUBTABLE             *ParentTable;
1168     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1169     DT_FIELD                *SubtableStart;
1170     ACPI_DMTABLE_INFO       *InfoTable;
1171     UINT16                  Type;
1172     UINT32                  BankCount;
1173 
1174 
1175     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1176                 &Subtable, TRUE);
1177     if (ACPI_FAILURE (Status))
1178     {
1179         return (Status);
1180     }
1181 
1182     ParentTable = DtPeekSubtable ();
1183     DtInsertSubtable (ParentTable, Subtable);
1184 
1185     while (*PFieldList)
1186     {
1187         /* Get subtable type */
1188 
1189         SubtableStart = *PFieldList;
1190         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1191 
1192         switch (Type)
1193         {
1194         case ACPI_HEST_TYPE_IA32_CHECK:
1195 
1196             InfoTable = AcpiDmTableInfoHest0;
1197             break;
1198 
1199         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1200 
1201             InfoTable = AcpiDmTableInfoHest1;
1202             break;
1203 
1204         case ACPI_HEST_TYPE_IA32_NMI:
1205 
1206             InfoTable = AcpiDmTableInfoHest2;
1207             break;
1208 
1209         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1210 
1211             InfoTable = AcpiDmTableInfoHest6;
1212             break;
1213 
1214         case ACPI_HEST_TYPE_AER_ENDPOINT:
1215 
1216             InfoTable = AcpiDmTableInfoHest7;
1217             break;
1218 
1219         case ACPI_HEST_TYPE_AER_BRIDGE:
1220 
1221             InfoTable = AcpiDmTableInfoHest8;
1222             break;
1223 
1224         case ACPI_HEST_TYPE_GENERIC_ERROR:
1225 
1226             InfoTable = AcpiDmTableInfoHest9;
1227             break;
1228 
1229         default:
1230 
1231             /* Cannot continue on unknown type */
1232 
1233             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1234             return (AE_ERROR);
1235         }
1236 
1237         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1238         if (ACPI_FAILURE (Status))
1239         {
1240             return (Status);
1241         }
1242 
1243         DtInsertSubtable (ParentTable, Subtable);
1244 
1245         /*
1246          * Additional subtable data - IA32 Error Bank(s)
1247          */
1248         BankCount = 0;
1249         switch (Type)
1250         {
1251         case ACPI_HEST_TYPE_IA32_CHECK:
1252 
1253             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1254                             Subtable->Buffer))->NumHardwareBanks;
1255             break;
1256 
1257         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1258 
1259             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1260                             Subtable->Buffer))->NumHardwareBanks;
1261             break;
1262 
1263         default:
1264 
1265             break;
1266         }
1267 
1268         while (BankCount)
1269         {
1270             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1271                         &Subtable, TRUE);
1272             if (ACPI_FAILURE (Status))
1273             {
1274                 return (Status);
1275             }
1276 
1277             DtInsertSubtable (ParentTable, Subtable);
1278             BankCount--;
1279         }
1280     }
1281 
1282     return (AE_OK);
1283 }
1284 
1285 
1286 /******************************************************************************
1287  *
1288  * FUNCTION:    DtCompileIvrs
1289  *
1290  * PARAMETERS:  List                - Current field list pointer
1291  *
1292  * RETURN:      Status
1293  *
1294  * DESCRIPTION: Compile IVRS.
1295  *
1296  *****************************************************************************/
1297 
1298 ACPI_STATUS
1299 DtCompileIvrs (
1300     void                    **List)
1301 {
1302     ACPI_STATUS             Status;
1303     DT_SUBTABLE             *Subtable;
1304     DT_SUBTABLE             *ParentTable;
1305     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1306     DT_FIELD                *SubtableStart;
1307     ACPI_DMTABLE_INFO       *InfoTable;
1308     ACPI_IVRS_HEADER        *IvrsHeader;
1309     UINT8                   EntryType;
1310 
1311 
1312     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1313                 &Subtable, TRUE);
1314     if (ACPI_FAILURE (Status))
1315     {
1316         return (Status);
1317     }
1318 
1319     ParentTable = DtPeekSubtable ();
1320     DtInsertSubtable (ParentTable, Subtable);
1321 
1322     while (*PFieldList)
1323     {
1324         SubtableStart = *PFieldList;
1325         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1326                     &Subtable, TRUE);
1327         if (ACPI_FAILURE (Status))
1328         {
1329             return (Status);
1330         }
1331 
1332         ParentTable = DtPeekSubtable ();
1333         DtInsertSubtable (ParentTable, Subtable);
1334         DtPushSubtable (Subtable);
1335 
1336         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1337 
1338         switch (IvrsHeader->Type)
1339         {
1340         case ACPI_IVRS_TYPE_HARDWARE:
1341 
1342             InfoTable = AcpiDmTableInfoIvrs0;
1343             break;
1344 
1345         case ACPI_IVRS_TYPE_MEMORY1:
1346         case ACPI_IVRS_TYPE_MEMORY2:
1347         case ACPI_IVRS_TYPE_MEMORY3:
1348 
1349             InfoTable = AcpiDmTableInfoIvrs1;
1350             break;
1351 
1352         default:
1353 
1354             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1355             return (AE_ERROR);
1356         }
1357 
1358         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1359         if (ACPI_FAILURE (Status))
1360         {
1361             return (Status);
1362         }
1363 
1364         ParentTable = DtPeekSubtable ();
1365         DtInsertSubtable (ParentTable, Subtable);
1366 
1367         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1368         {
1369             while (*PFieldList &&
1370                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1371             {
1372                 SubtableStart = *PFieldList;
1373                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1374 
1375                 switch (EntryType)
1376                 {
1377                 /* 4-byte device entries */
1378 
1379                 case ACPI_IVRS_TYPE_PAD4:
1380                 case ACPI_IVRS_TYPE_ALL:
1381                 case ACPI_IVRS_TYPE_SELECT:
1382                 case ACPI_IVRS_TYPE_START:
1383                 case ACPI_IVRS_TYPE_END:
1384 
1385                     InfoTable = AcpiDmTableInfoIvrs4;
1386                     break;
1387 
1388                 /* 8-byte entries, type A */
1389 
1390                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1391                 case ACPI_IVRS_TYPE_ALIAS_START:
1392 
1393                     InfoTable = AcpiDmTableInfoIvrs8a;
1394                     break;
1395 
1396                 /* 8-byte entries, type B */
1397 
1398                 case ACPI_IVRS_TYPE_PAD8:
1399                 case ACPI_IVRS_TYPE_EXT_SELECT:
1400                 case ACPI_IVRS_TYPE_EXT_START:
1401 
1402                     InfoTable = AcpiDmTableInfoIvrs8b;
1403                     break;
1404 
1405                 /* 8-byte entries, type C */
1406 
1407                 case ACPI_IVRS_TYPE_SPECIAL:
1408 
1409                     InfoTable = AcpiDmTableInfoIvrs8c;
1410                     break;
1411 
1412                 default:
1413 
1414                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1415                         "IVRS Device Entry");
1416                     return (AE_ERROR);
1417                 }
1418 
1419                 Status = DtCompileTable (PFieldList, InfoTable,
1420                             &Subtable, TRUE);
1421                 if (ACPI_FAILURE (Status))
1422                 {
1423                     return (Status);
1424                 }
1425 
1426                 DtInsertSubtable (ParentTable, Subtable);
1427             }
1428         }
1429 
1430         DtPopSubtable ();
1431     }
1432 
1433     return (AE_OK);
1434 }
1435 
1436 
1437 /******************************************************************************
1438  *
1439  * FUNCTION:    DtCompileLpit
1440  *
1441  * PARAMETERS:  List                - Current field list pointer
1442  *
1443  * RETURN:      Status
1444  *
1445  * DESCRIPTION: Compile LPIT.
1446  *
1447  *****************************************************************************/
1448 
1449 ACPI_STATUS
1450 DtCompileLpit (
1451     void                    **List)
1452 {
1453     ACPI_STATUS             Status;
1454     DT_SUBTABLE             *Subtable;
1455     DT_SUBTABLE             *ParentTable;
1456     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1457     DT_FIELD                *SubtableStart;
1458     ACPI_DMTABLE_INFO       *InfoTable;
1459     ACPI_LPIT_HEADER        *LpitHeader;
1460 
1461 
1462     /* Note: Main table consists only of the standard ACPI table header */
1463 
1464     while (*PFieldList)
1465     {
1466         SubtableStart = *PFieldList;
1467 
1468         /* LPIT Subtable header */
1469 
1470         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1471                     &Subtable, TRUE);
1472         if (ACPI_FAILURE (Status))
1473         {
1474             return (Status);
1475         }
1476 
1477         ParentTable = DtPeekSubtable ();
1478         DtInsertSubtable (ParentTable, Subtable);
1479         DtPushSubtable (Subtable);
1480 
1481         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1482 
1483         switch (LpitHeader->Type)
1484         {
1485         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1486 
1487             InfoTable = AcpiDmTableInfoLpit0;
1488             break;
1489 
1490         case ACPI_LPIT_TYPE_SIMPLE_IO:
1491 
1492             InfoTable = AcpiDmTableInfoLpit1;
1493             break;
1494 
1495         default:
1496 
1497             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1498             return (AE_ERROR);
1499         }
1500 
1501         /* LPIT Subtable */
1502 
1503         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1504         if (ACPI_FAILURE (Status))
1505         {
1506             return (Status);
1507         }
1508 
1509         ParentTable = DtPeekSubtable ();
1510         DtInsertSubtable (ParentTable, Subtable);
1511         DtPopSubtable ();
1512     }
1513 
1514     return (AE_OK);
1515 }
1516 
1517 
1518 /******************************************************************************
1519  *
1520  * FUNCTION:    DtCompileMadt
1521  *
1522  * PARAMETERS:  List                - Current field list pointer
1523  *
1524  * RETURN:      Status
1525  *
1526  * DESCRIPTION: Compile MADT.
1527  *
1528  *****************************************************************************/
1529 
1530 ACPI_STATUS
1531 DtCompileMadt (
1532     void                    **List)
1533 {
1534     ACPI_STATUS             Status;
1535     DT_SUBTABLE             *Subtable;
1536     DT_SUBTABLE             *ParentTable;
1537     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1538     DT_FIELD                *SubtableStart;
1539     ACPI_SUBTABLE_HEADER    *MadtHeader;
1540     ACPI_DMTABLE_INFO       *InfoTable;
1541 
1542 
1543     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1544                 &Subtable, TRUE);
1545     if (ACPI_FAILURE (Status))
1546     {
1547         return (Status);
1548     }
1549 
1550     ParentTable = DtPeekSubtable ();
1551     DtInsertSubtable (ParentTable, Subtable);
1552 
1553     while (*PFieldList)
1554     {
1555         SubtableStart = *PFieldList;
1556         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1557                     &Subtable, TRUE);
1558         if (ACPI_FAILURE (Status))
1559         {
1560             return (Status);
1561         }
1562 
1563         ParentTable = DtPeekSubtable ();
1564         DtInsertSubtable (ParentTable, Subtable);
1565         DtPushSubtable (Subtable);
1566 
1567         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1568 
1569         switch (MadtHeader->Type)
1570         {
1571         case ACPI_MADT_TYPE_LOCAL_APIC:
1572 
1573             InfoTable = AcpiDmTableInfoMadt0;
1574             break;
1575 
1576         case ACPI_MADT_TYPE_IO_APIC:
1577 
1578             InfoTable = AcpiDmTableInfoMadt1;
1579             break;
1580 
1581         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1582 
1583             InfoTable = AcpiDmTableInfoMadt2;
1584             break;
1585 
1586         case ACPI_MADT_TYPE_NMI_SOURCE:
1587 
1588             InfoTable = AcpiDmTableInfoMadt3;
1589             break;
1590 
1591         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1592 
1593             InfoTable = AcpiDmTableInfoMadt4;
1594             break;
1595 
1596         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1597 
1598             InfoTable = AcpiDmTableInfoMadt5;
1599             break;
1600 
1601         case ACPI_MADT_TYPE_IO_SAPIC:
1602 
1603             InfoTable = AcpiDmTableInfoMadt6;
1604             break;
1605 
1606         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1607 
1608             InfoTable = AcpiDmTableInfoMadt7;
1609             break;
1610 
1611         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1612 
1613             InfoTable = AcpiDmTableInfoMadt8;
1614             break;
1615 
1616         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1617 
1618             InfoTable = AcpiDmTableInfoMadt9;
1619             break;
1620 
1621         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1622 
1623             InfoTable = AcpiDmTableInfoMadt10;
1624             break;
1625 
1626         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1627 
1628             InfoTable = AcpiDmTableInfoMadt11;
1629             break;
1630 
1631         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1632 
1633             InfoTable = AcpiDmTableInfoMadt12;
1634             break;
1635 
1636         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1637 
1638             InfoTable = AcpiDmTableInfoMadt13;
1639             break;
1640 
1641         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1642 
1643             InfoTable = AcpiDmTableInfoMadt14;
1644             break;
1645 
1646         default:
1647 
1648             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1649             return (AE_ERROR);
1650         }
1651 
1652         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1653         if (ACPI_FAILURE (Status))
1654         {
1655             return (Status);
1656         }
1657 
1658         ParentTable = DtPeekSubtable ();
1659         DtInsertSubtable (ParentTable, Subtable);
1660         DtPopSubtable ();
1661     }
1662 
1663     return (AE_OK);
1664 }
1665 
1666 
1667 /******************************************************************************
1668  *
1669  * FUNCTION:    DtCompileMcfg
1670  *
1671  * PARAMETERS:  List                - Current field list pointer
1672  *
1673  * RETURN:      Status
1674  *
1675  * DESCRIPTION: Compile MCFG.
1676  *
1677  *****************************************************************************/
1678 
1679 ACPI_STATUS
1680 DtCompileMcfg (
1681     void                    **List)
1682 {
1683     ACPI_STATUS             Status;
1684 
1685 
1686     Status = DtCompileTwoSubtables (List,
1687                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1688     return (Status);
1689 }
1690 
1691 
1692 /******************************************************************************
1693  *
1694  * FUNCTION:    DtCompileMpst
1695  *
1696  * PARAMETERS:  List                - Current field list pointer
1697  *
1698  * RETURN:      Status
1699  *
1700  * DESCRIPTION: Compile MPST.
1701  *
1702  *****************************************************************************/
1703 
1704 ACPI_STATUS
1705 DtCompileMpst (
1706     void                    **List)
1707 {
1708     ACPI_STATUS             Status;
1709     DT_SUBTABLE             *Subtable;
1710     DT_SUBTABLE             *ParentTable;
1711     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1712     ACPI_MPST_CHANNEL       *MpstChannelInfo;
1713     ACPI_MPST_POWER_NODE    *MpstPowerNode;
1714     ACPI_MPST_DATA_HDR      *MpstDataHeader;
1715     UINT16                  SubtableCount;
1716     UINT32                  PowerStateCount;
1717     UINT32                  ComponentCount;
1718 
1719 
1720     /* Main table */
1721 
1722     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1723     if (ACPI_FAILURE (Status))
1724     {
1725         return (Status);
1726     }
1727 
1728     ParentTable = DtPeekSubtable ();
1729     DtInsertSubtable (ParentTable, Subtable);
1730     DtPushSubtable (Subtable);
1731 
1732     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1733     SubtableCount = MpstChannelInfo->PowerNodeCount;
1734 
1735     while (*PFieldList && SubtableCount)
1736     {
1737         /* Subtable: Memory Power Node(s) */
1738 
1739         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1740                     &Subtable, TRUE);
1741         if (ACPI_FAILURE (Status))
1742         {
1743             return (Status);
1744         }
1745 
1746         ParentTable = DtPeekSubtable ();
1747         DtInsertSubtable (ParentTable, Subtable);
1748         DtPushSubtable (Subtable);
1749 
1750         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1751         PowerStateCount = MpstPowerNode->NumPowerStates;
1752         ComponentCount = MpstPowerNode->NumPhysicalComponents;
1753 
1754         ParentTable = DtPeekSubtable ();
1755 
1756         /* Sub-subtables - Memory Power State Structure(s) */
1757 
1758         while (*PFieldList && PowerStateCount)
1759         {
1760             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1761                         &Subtable, TRUE);
1762             if (ACPI_FAILURE (Status))
1763             {
1764                 return (Status);
1765             }
1766 
1767             DtInsertSubtable (ParentTable, Subtable);
1768             PowerStateCount--;
1769         }
1770 
1771         /* Sub-subtables - Physical Component ID Structure(s) */
1772 
1773         while (*PFieldList && ComponentCount)
1774         {
1775             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1776                         &Subtable, TRUE);
1777             if (ACPI_FAILURE (Status))
1778             {
1779                 return (Status);
1780             }
1781 
1782             DtInsertSubtable (ParentTable, Subtable);
1783             ComponentCount--;
1784         }
1785 
1786         SubtableCount--;
1787         DtPopSubtable ();
1788     }
1789 
1790     /* Subtable: Count of Memory Power State Characteristic structures */
1791 
1792     DtPopSubtable ();
1793 
1794     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1795     if (ACPI_FAILURE (Status))
1796     {
1797         return (Status);
1798     }
1799 
1800     ParentTable = DtPeekSubtable ();
1801     DtInsertSubtable (ParentTable, Subtable);
1802     DtPushSubtable (Subtable);
1803 
1804     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1805     SubtableCount = MpstDataHeader->CharacteristicsCount;
1806 
1807     ParentTable = DtPeekSubtable ();
1808 
1809     /* Subtable: Memory Power State Characteristics structure(s) */
1810 
1811     while (*PFieldList && SubtableCount)
1812     {
1813         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1814                     &Subtable, TRUE);
1815         if (ACPI_FAILURE (Status))
1816         {
1817             return (Status);
1818         }
1819 
1820         DtInsertSubtable (ParentTable, Subtable);
1821         SubtableCount--;
1822     }
1823 
1824     DtPopSubtable ();
1825     return (AE_OK);
1826 }
1827 
1828 
1829 /******************************************************************************
1830  *
1831  * FUNCTION:    DtCompileMsct
1832  *
1833  * PARAMETERS:  List                - Current field list pointer
1834  *
1835  * RETURN:      Status
1836  *
1837  * DESCRIPTION: Compile MSCT.
1838  *
1839  *****************************************************************************/
1840 
1841 ACPI_STATUS
1842 DtCompileMsct (
1843     void                    **List)
1844 {
1845     ACPI_STATUS             Status;
1846 
1847 
1848     Status = DtCompileTwoSubtables (List,
1849                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1850     return (Status);
1851 }
1852 
1853 
1854 /******************************************************************************
1855  *
1856  * FUNCTION:    DtCompileMtmr
1857  *
1858  * PARAMETERS:  List                - Current field list pointer
1859  *
1860  * RETURN:      Status
1861  *
1862  * DESCRIPTION: Compile MTMR.
1863  *
1864  *****************************************************************************/
1865 
1866 ACPI_STATUS
1867 DtCompileMtmr (
1868     void                    **List)
1869 {
1870     ACPI_STATUS             Status;
1871 
1872 
1873     Status = DtCompileTwoSubtables (List,
1874                  AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1875     return (Status);
1876 }
1877 
1878 
1879 /******************************************************************************
1880  *
1881  * FUNCTION:    DtCompilePcct
1882  *
1883  * PARAMETERS:  List                - Current field list pointer
1884  *
1885  * RETURN:      Status
1886  *
1887  * DESCRIPTION: Compile PCCT.
1888  *
1889  *****************************************************************************/
1890 
1891 ACPI_STATUS
1892 DtCompilePcct (
1893     void                    **List)
1894 {
1895     ACPI_STATUS             Status;
1896     DT_SUBTABLE             *Subtable;
1897     DT_SUBTABLE             *ParentTable;
1898     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1899     DT_FIELD                *SubtableStart;
1900     ACPI_SUBTABLE_HEADER    *PcctHeader;
1901     ACPI_DMTABLE_INFO       *InfoTable;
1902 
1903 
1904     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1905                 &Subtable, TRUE);
1906     if (ACPI_FAILURE (Status))
1907     {
1908         return (Status);
1909     }
1910 
1911     ParentTable = DtPeekSubtable ();
1912     DtInsertSubtable (ParentTable, Subtable);
1913 
1914     while (*PFieldList)
1915     {
1916         SubtableStart = *PFieldList;
1917         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1918                     &Subtable, TRUE);
1919         if (ACPI_FAILURE (Status))
1920         {
1921             return (Status);
1922         }
1923 
1924         ParentTable = DtPeekSubtable ();
1925         DtInsertSubtable (ParentTable, Subtable);
1926         DtPushSubtable (Subtable);
1927 
1928         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1929 
1930         switch (PcctHeader->Type)
1931         {
1932         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1933 
1934             InfoTable = AcpiDmTableInfoPcct0;
1935             break;
1936 
1937         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1938 
1939             InfoTable = AcpiDmTableInfoPcct1;
1940             break;
1941 
1942         default:
1943 
1944             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1945             return (AE_ERROR);
1946         }
1947 
1948         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1949         if (ACPI_FAILURE (Status))
1950         {
1951             return (Status);
1952         }
1953 
1954         ParentTable = DtPeekSubtable ();
1955         DtInsertSubtable (ParentTable, Subtable);
1956         DtPopSubtable ();
1957     }
1958 
1959     return (AE_OK);
1960 }
1961 
1962 
1963 /******************************************************************************
1964  *
1965  * FUNCTION:    DtCompilePmtt
1966  *
1967  * PARAMETERS:  List                - Current field list pointer
1968  *
1969  * RETURN:      Status
1970  *
1971  * DESCRIPTION: Compile PMTT.
1972  *
1973  *****************************************************************************/
1974 
1975 ACPI_STATUS
1976 DtCompilePmtt (
1977     void                    **List)
1978 {
1979     ACPI_STATUS             Status;
1980     DT_SUBTABLE             *Subtable;
1981     DT_SUBTABLE             *ParentTable;
1982     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1983     DT_FIELD                *SubtableStart;
1984     ACPI_PMTT_HEADER        *PmttHeader;
1985     ACPI_PMTT_CONTROLLER    *PmttController;
1986     UINT16                  DomainCount;
1987     UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1988 
1989 
1990     /* Main table */
1991 
1992     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1993     if (ACPI_FAILURE (Status))
1994     {
1995         return (Status);
1996     }
1997 
1998     ParentTable = DtPeekSubtable ();
1999     DtInsertSubtable (ParentTable, Subtable);
2000     DtPushSubtable (Subtable);
2001 
2002     while (*PFieldList)
2003     {
2004         SubtableStart = *PFieldList;
2005         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
2006                     &Subtable, TRUE);
2007         if (ACPI_FAILURE (Status))
2008         {
2009             return (Status);
2010         }
2011 
2012         PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
2013         while (PrevType >= PmttHeader->Type)
2014         {
2015             DtPopSubtable ();
2016 
2017             if (PrevType == ACPI_PMTT_TYPE_SOCKET)
2018             {
2019                 break;
2020             }
2021             PrevType--;
2022         }
2023         PrevType = PmttHeader->Type;
2024 
2025         ParentTable = DtPeekSubtable ();
2026         DtInsertSubtable (ParentTable, Subtable);
2027         DtPushSubtable (Subtable);
2028 
2029         switch (PmttHeader->Type)
2030         {
2031         case ACPI_PMTT_TYPE_SOCKET:
2032 
2033             /* Subtable: Socket Structure */
2034 
2035             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
2036                     &Subtable, TRUE);
2037             if (ACPI_FAILURE (Status))
2038             {
2039                 return (Status);
2040             }
2041 
2042             ParentTable = DtPeekSubtable ();
2043             DtInsertSubtable (ParentTable, Subtable);
2044             break;
2045 
2046         case ACPI_PMTT_TYPE_CONTROLLER:
2047 
2048             /* Subtable: Memory Controller Structure */
2049 
2050             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
2051                     &Subtable, TRUE);
2052             if (ACPI_FAILURE (Status))
2053             {
2054                 return (Status);
2055             }
2056 
2057             ParentTable = DtPeekSubtable ();
2058             DtInsertSubtable (ParentTable, Subtable);
2059 
2060             PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
2061                 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
2062             DomainCount = PmttController->DomainCount;
2063 
2064             while (DomainCount)
2065             {
2066                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
2067                     &Subtable, TRUE);
2068                 if (ACPI_FAILURE (Status))
2069                 {
2070                     return (Status);
2071                 }
2072 
2073                 DtInsertSubtable (ParentTable, Subtable);
2074                 DomainCount--;
2075             }
2076             break;
2077 
2078         case ACPI_PMTT_TYPE_DIMM:
2079 
2080             /* Subtable: Physical Component Structure */
2081 
2082             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
2083                     &Subtable, TRUE);
2084             if (ACPI_FAILURE (Status))
2085             {
2086                 return (Status);
2087             }
2088 
2089             ParentTable = DtPeekSubtable ();
2090             DtInsertSubtable (ParentTable, Subtable);
2091             break;
2092 
2093         default:
2094 
2095             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
2096             return (AE_ERROR);
2097         }
2098     }
2099 
2100     return (Status);
2101 }
2102 
2103 
2104 /******************************************************************************
2105  *
2106  * FUNCTION:    DtCompileRsdt
2107  *
2108  * PARAMETERS:  List                - Current field list pointer
2109  *
2110  * RETURN:      Status
2111  *
2112  * DESCRIPTION: Compile RSDT.
2113  *
2114  *****************************************************************************/
2115 
2116 ACPI_STATUS
2117 DtCompileRsdt (
2118     void                    **List)
2119 {
2120     DT_SUBTABLE             *Subtable;
2121     DT_SUBTABLE             *ParentTable;
2122     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2123     UINT32                  Address;
2124 
2125 
2126     ParentTable = DtPeekSubtable ();
2127 
2128     while (FieldList)
2129     {
2130         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2131 
2132         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2133         DtInsertSubtable (ParentTable, Subtable);
2134         FieldList = FieldList->Next;
2135     }
2136 
2137     return (AE_OK);
2138 }
2139 
2140 
2141 /******************************************************************************
2142  *
2143  * FUNCTION:    DtCompileS3pt
2144  *
2145  * PARAMETERS:  PFieldList          - Current field list pointer
2146  *
2147  * RETURN:      Status
2148  *
2149  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2150  *
2151  *****************************************************************************/
2152 
2153 ACPI_STATUS
2154 DtCompileS3pt (
2155     DT_FIELD                **PFieldList)
2156 {
2157     ACPI_STATUS             Status;
2158     ACPI_S3PT_HEADER        *S3ptHeader;
2159     DT_SUBTABLE             *Subtable;
2160     DT_SUBTABLE             *ParentTable;
2161     ACPI_DMTABLE_INFO       *InfoTable;
2162     DT_FIELD                *SubtableStart;
2163 
2164 
2165     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2166                 &Gbl_RootTable, TRUE);
2167     if (ACPI_FAILURE (Status))
2168     {
2169         return (Status);
2170     }
2171 
2172     DtPushSubtable (Gbl_RootTable);
2173 
2174     while (*PFieldList)
2175     {
2176         SubtableStart = *PFieldList;
2177         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2178                     &Subtable, TRUE);
2179         if (ACPI_FAILURE (Status))
2180         {
2181             return (Status);
2182         }
2183 
2184         ParentTable = DtPeekSubtable ();
2185         DtInsertSubtable (ParentTable, Subtable);
2186         DtPushSubtable (Subtable);
2187 
2188         S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2189 
2190         switch (S3ptHeader->Type)
2191         {
2192         case ACPI_S3PT_TYPE_RESUME:
2193 
2194             InfoTable = AcpiDmTableInfoS3pt0;
2195             break;
2196 
2197         case ACPI_S3PT_TYPE_SUSPEND:
2198 
2199             InfoTable = AcpiDmTableInfoS3pt1;
2200             break;
2201 
2202         default:
2203 
2204             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2205             return (AE_ERROR);
2206         }
2207 
2208         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2209         if (ACPI_FAILURE (Status))
2210         {
2211             return (Status);
2212         }
2213 
2214         ParentTable = DtPeekSubtable ();
2215         DtInsertSubtable (ParentTable, Subtable);
2216         DtPopSubtable ();
2217     }
2218 
2219     return (AE_OK);
2220 }
2221 
2222 
2223 /******************************************************************************
2224  *
2225  * FUNCTION:    DtCompileSlic
2226  *
2227  * PARAMETERS:  List                - Current field list pointer
2228  *
2229  * RETURN:      Status
2230  *
2231  * DESCRIPTION: Compile SLIC.
2232  *
2233  *****************************************************************************/
2234 
2235 ACPI_STATUS
2236 DtCompileSlic (
2237     void                    **List)
2238 {
2239     ACPI_STATUS             Status;
2240     DT_SUBTABLE             *Subtable;
2241     DT_SUBTABLE             *ParentTable;
2242     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2243     DT_FIELD                *SubtableStart;
2244     ACPI_SLIC_HEADER        *SlicHeader;
2245     ACPI_DMTABLE_INFO       *InfoTable;
2246 
2247 
2248     while (*PFieldList)
2249     {
2250         SubtableStart = *PFieldList;
2251         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
2252                     &Subtable, TRUE);
2253         if (ACPI_FAILURE (Status))
2254         {
2255             return (Status);
2256         }
2257 
2258         ParentTable = DtPeekSubtable ();
2259         DtInsertSubtable (ParentTable, Subtable);
2260         DtPushSubtable (Subtable);
2261 
2262         SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
2263 
2264         switch (SlicHeader->Type)
2265         {
2266         case ACPI_SLIC_TYPE_PUBLIC_KEY:
2267 
2268             InfoTable = AcpiDmTableInfoSlic0;
2269             break;
2270 
2271         case ACPI_SLIC_TYPE_WINDOWS_MARKER:
2272 
2273             InfoTable = AcpiDmTableInfoSlic1;
2274             break;
2275 
2276         default:
2277 
2278             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
2279             return (AE_ERROR);
2280         }
2281 
2282         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2283         if (ACPI_FAILURE (Status))
2284         {
2285             return (Status);
2286         }
2287 
2288         ParentTable = DtPeekSubtable ();
2289         DtInsertSubtable (ParentTable, Subtable);
2290         DtPopSubtable ();
2291     }
2292 
2293     return (AE_OK);
2294 }
2295 
2296 
2297 /******************************************************************************
2298  *
2299  * FUNCTION:    DtCompileSlit
2300  *
2301  * PARAMETERS:  List                - Current field list pointer
2302  *
2303  * RETURN:      Status
2304  *
2305  * DESCRIPTION: Compile SLIT.
2306  *
2307  *****************************************************************************/
2308 
2309 ACPI_STATUS
2310 DtCompileSlit (
2311     void                    **List)
2312 {
2313     ACPI_STATUS             Status;
2314     DT_SUBTABLE             *Subtable;
2315     DT_SUBTABLE             *ParentTable;
2316     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2317     DT_FIELD                *FieldList;
2318     UINT32                  Localities;
2319     UINT8                   *LocalityBuffer;
2320 
2321 
2322     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2323                 &Subtable, TRUE);
2324     if (ACPI_FAILURE (Status))
2325     {
2326         return (Status);
2327     }
2328 
2329     ParentTable = DtPeekSubtable ();
2330     DtInsertSubtable (ParentTable, Subtable);
2331 
2332     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2333     LocalityBuffer = UtLocalCalloc (Localities);
2334 
2335     /* Compile each locality buffer */
2336 
2337     FieldList = *PFieldList;
2338     while (FieldList)
2339     {
2340         DtCompileBuffer (LocalityBuffer,
2341             FieldList->Value, FieldList, Localities);
2342 
2343         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2344         DtInsertSubtable (ParentTable, Subtable);
2345         FieldList = FieldList->Next;
2346     }
2347 
2348     ACPI_FREE (LocalityBuffer);
2349     return (AE_OK);
2350 }
2351 
2352 
2353 /******************************************************************************
2354  *
2355  * FUNCTION:    DtCompileSrat
2356  *
2357  * PARAMETERS:  List                - Current field list pointer
2358  *
2359  * RETURN:      Status
2360  *
2361  * DESCRIPTION: Compile SRAT.
2362  *
2363  *****************************************************************************/
2364 
2365 ACPI_STATUS
2366 DtCompileSrat (
2367     void                    **List)
2368 {
2369     ACPI_STATUS             Status;
2370     DT_SUBTABLE             *Subtable;
2371     DT_SUBTABLE             *ParentTable;
2372     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2373     DT_FIELD                *SubtableStart;
2374     ACPI_SUBTABLE_HEADER    *SratHeader;
2375     ACPI_DMTABLE_INFO       *InfoTable;
2376 
2377 
2378     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2379                 &Subtable, TRUE);
2380     if (ACPI_FAILURE (Status))
2381     {
2382         return (Status);
2383     }
2384 
2385     ParentTable = DtPeekSubtable ();
2386     DtInsertSubtable (ParentTable, Subtable);
2387 
2388     while (*PFieldList)
2389     {
2390         SubtableStart = *PFieldList;
2391         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2392                     &Subtable, TRUE);
2393         if (ACPI_FAILURE (Status))
2394         {
2395             return (Status);
2396         }
2397 
2398         ParentTable = DtPeekSubtable ();
2399         DtInsertSubtable (ParentTable, Subtable);
2400         DtPushSubtable (Subtable);
2401 
2402         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2403 
2404         switch (SratHeader->Type)
2405         {
2406         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2407 
2408             InfoTable = AcpiDmTableInfoSrat0;
2409             break;
2410 
2411         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2412 
2413             InfoTable = AcpiDmTableInfoSrat1;
2414             break;
2415 
2416         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2417 
2418             InfoTable = AcpiDmTableInfoSrat2;
2419             break;
2420 
2421         case ACPI_SRAT_TYPE_GICC_AFFINITY:
2422 
2423             InfoTable = AcpiDmTableInfoSrat3;
2424             break;
2425 
2426         default:
2427 
2428             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2429             return (AE_ERROR);
2430         }
2431 
2432         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2433         if (ACPI_FAILURE (Status))
2434         {
2435             return (Status);
2436         }
2437 
2438         ParentTable = DtPeekSubtable ();
2439         DtInsertSubtable (ParentTable, Subtable);
2440         DtPopSubtable ();
2441     }
2442 
2443     return (AE_OK);
2444 }
2445 
2446 
2447 /******************************************************************************
2448  *
2449  * FUNCTION:    DtGetGenericTableInfo
2450  *
2451  * PARAMETERS:  Name                - Generic type name
2452  *
2453  * RETURN:      Info entry
2454  *
2455  * DESCRIPTION: Obtain table info for a generic name entry
2456  *
2457  *****************************************************************************/
2458 
2459 ACPI_DMTABLE_INFO *
2460 DtGetGenericTableInfo (
2461     char                    *Name)
2462 {
2463     ACPI_DMTABLE_INFO       *Info;
2464     UINT32                  i;
2465 
2466 
2467     if (!Name)
2468     {
2469         return (NULL);
2470     }
2471 
2472     /* Search info table for name match */
2473 
2474     for (i = 0; ; i++)
2475     {
2476         Info = AcpiDmTableInfoGeneric[i];
2477         if (Info->Opcode == ACPI_DMT_EXIT)
2478         {
2479             Info = NULL;
2480             break;
2481         }
2482 
2483         /* Use caseless compare for generic keywords */
2484 
2485         if (!AcpiUtStricmp (Name, Info->Name))
2486         {
2487             break;
2488         }
2489     }
2490 
2491     return (Info);
2492 }
2493 
2494 
2495 /******************************************************************************
2496  *
2497  * FUNCTION:    DtCompileUefi
2498  *
2499  * PARAMETERS:  List                - Current field list pointer
2500  *
2501  * RETURN:      Status
2502  *
2503  * DESCRIPTION: Compile UEFI.
2504  *
2505  *****************************************************************************/
2506 
2507 ACPI_STATUS
2508 DtCompileUefi (
2509     void                    **List)
2510 {
2511     ACPI_STATUS             Status;
2512     DT_SUBTABLE             *Subtable;
2513     DT_SUBTABLE             *ParentTable;
2514     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2515     UINT16                  *DataOffset;
2516 
2517 
2518     /* Compile the predefined portion of the UEFI table */
2519 
2520     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2521                 &Subtable, TRUE);
2522     if (ACPI_FAILURE (Status))
2523     {
2524         return (Status);
2525     }
2526 
2527     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2528     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2529 
2530     ParentTable = DtPeekSubtable ();
2531     DtInsertSubtable (ParentTable, Subtable);
2532 
2533     /*
2534      * Compile the "generic" portion of the UEFI table. This
2535      * part of the table is not predefined and any of the generic
2536      * operators may be used.
2537      */
2538 
2539     DtCompileGeneric ((void **) PFieldList);
2540 
2541     return (AE_OK);
2542 }
2543 
2544 
2545 /******************************************************************************
2546  *
2547  * FUNCTION:    DtCompileVrtc
2548  *
2549  * PARAMETERS:  List                - Current field list pointer
2550  *
2551  * RETURN:      Status
2552  *
2553  * DESCRIPTION: Compile VRTC.
2554  *
2555  *****************************************************************************/
2556 
2557 ACPI_STATUS
2558 DtCompileVrtc (
2559     void                    **List)
2560 {
2561     ACPI_STATUS             Status;
2562 
2563 
2564     Status = DtCompileTwoSubtables (List,
2565                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2566     return (Status);
2567 }
2568 
2569 
2570 /******************************************************************************
2571  *
2572  * FUNCTION:    DtCompileWdat
2573  *
2574  * PARAMETERS:  List                - Current field list pointer
2575  *
2576  * RETURN:      Status
2577  *
2578  * DESCRIPTION: Compile WDAT.
2579  *
2580  *****************************************************************************/
2581 
2582 ACPI_STATUS
2583 DtCompileWdat (
2584     void                    **List)
2585 {
2586     ACPI_STATUS             Status;
2587 
2588 
2589     Status = DtCompileTwoSubtables (List,
2590                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2591     return (Status);
2592 }
2593 
2594 
2595 /******************************************************************************
2596  *
2597  * FUNCTION:    DtCompileXsdt
2598  *
2599  * PARAMETERS:  List                - Current field list pointer
2600  *
2601  * RETURN:      Status
2602  *
2603  * DESCRIPTION: Compile XSDT.
2604  *
2605  *****************************************************************************/
2606 
2607 ACPI_STATUS
2608 DtCompileXsdt (
2609     void                    **List)
2610 {
2611     DT_SUBTABLE             *Subtable;
2612     DT_SUBTABLE             *ParentTable;
2613     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2614     UINT64                  Address;
2615 
2616     ParentTable = DtPeekSubtable ();
2617 
2618     while (FieldList)
2619     {
2620         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2621 
2622         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2623         DtInsertSubtable (ParentTable, Subtable);
2624         FieldList = FieldList->Next;
2625     }
2626 
2627     return (AE_OK);
2628 }
2629 
2630 
2631 /******************************************************************************
2632  *
2633  * FUNCTION:    DtCompileGeneric
2634  *
2635  * PARAMETERS:  List                - Current field list pointer
2636  *
2637  * RETURN:      Status
2638  *
2639  * DESCRIPTION: Compile generic unknown table.
2640  *
2641  *****************************************************************************/
2642 
2643 ACPI_STATUS
2644 DtCompileGeneric (
2645     void                    **List)
2646 {
2647     ACPI_STATUS             Status;
2648     DT_SUBTABLE             *Subtable;
2649     DT_SUBTABLE             *ParentTable;
2650     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2651     ACPI_DMTABLE_INFO       *Info;
2652 
2653 
2654     ParentTable = DtPeekSubtable ();
2655 
2656     /*
2657      * Compile the "generic" portion of the table. This
2658      * part of the table is not predefined and any of the generic
2659      * operators may be used.
2660      */
2661 
2662     /* Find any and all labels in the entire generic portion */
2663 
2664     DtDetectAllLabels (*PFieldList);
2665 
2666     /* Now we can actually compile the parse tree */
2667 
2668     while (*PFieldList)
2669     {
2670         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2671         if (!Info)
2672         {
2673             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2674                 (*PFieldList)->Name);
2675             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2676                 (*PFieldList), MsgBuffer);
2677 
2678             *PFieldList = (*PFieldList)->Next;
2679             continue;
2680         }
2681 
2682         Status = DtCompileTable (PFieldList, Info,
2683                     &Subtable, TRUE);
2684         if (ACPI_SUCCESS (Status))
2685         {
2686             DtInsertSubtable (ParentTable, Subtable);
2687         }
2688         else
2689         {
2690             *PFieldList = (*PFieldList)->Next;
2691 
2692             if (Status == AE_NOT_FOUND)
2693             {
2694                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2695                     (*PFieldList)->Name);
2696                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2697                     (*PFieldList), MsgBuffer);
2698             }
2699         }
2700     }
2701 
2702     return (AE_OK);
2703 }
2704