Merge branch 'vendor/GCC50'
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / dttable.c
1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2015, 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
2244
2245     while (*PFieldList)
2246     {
2247         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2248                     &Subtable, TRUE);
2249         if (ACPI_FAILURE (Status))
2250         {
2251             return (Status);
2252         }
2253
2254         ParentTable = DtPeekSubtable ();
2255         DtInsertSubtable (ParentTable, Subtable);
2256         DtPushSubtable (Subtable);
2257         DtPopSubtable ();
2258     }
2259
2260     return (AE_OK);
2261 }
2262
2263
2264 /******************************************************************************
2265  *
2266  * FUNCTION:    DtCompileSlit
2267  *
2268  * PARAMETERS:  List                - Current field list pointer
2269  *
2270  * RETURN:      Status
2271  *
2272  * DESCRIPTION: Compile SLIT.
2273  *
2274  *****************************************************************************/
2275
2276 ACPI_STATUS
2277 DtCompileSlit (
2278     void                    **List)
2279 {
2280     ACPI_STATUS             Status;
2281     DT_SUBTABLE             *Subtable;
2282     DT_SUBTABLE             *ParentTable;
2283     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2284     DT_FIELD                *FieldList;
2285     UINT32                  Localities;
2286     UINT8                   *LocalityBuffer;
2287
2288
2289     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2290                 &Subtable, TRUE);
2291     if (ACPI_FAILURE (Status))
2292     {
2293         return (Status);
2294     }
2295
2296     ParentTable = DtPeekSubtable ();
2297     DtInsertSubtable (ParentTable, Subtable);
2298
2299     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2300     LocalityBuffer = UtLocalCalloc (Localities);
2301
2302     /* Compile each locality buffer */
2303
2304     FieldList = *PFieldList;
2305     while (FieldList)
2306     {
2307         DtCompileBuffer (LocalityBuffer,
2308             FieldList->Value, FieldList, Localities);
2309
2310         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2311         DtInsertSubtable (ParentTable, Subtable);
2312         FieldList = FieldList->Next;
2313     }
2314
2315     ACPI_FREE (LocalityBuffer);
2316     return (AE_OK);
2317 }
2318
2319
2320 /******************************************************************************
2321  *
2322  * FUNCTION:    DtCompileSrat
2323  *
2324  * PARAMETERS:  List                - Current field list pointer
2325  *
2326  * RETURN:      Status
2327  *
2328  * DESCRIPTION: Compile SRAT.
2329  *
2330  *****************************************************************************/
2331
2332 ACPI_STATUS
2333 DtCompileSrat (
2334     void                    **List)
2335 {
2336     ACPI_STATUS             Status;
2337     DT_SUBTABLE             *Subtable;
2338     DT_SUBTABLE             *ParentTable;
2339     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2340     DT_FIELD                *SubtableStart;
2341     ACPI_SUBTABLE_HEADER    *SratHeader;
2342     ACPI_DMTABLE_INFO       *InfoTable;
2343
2344
2345     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2346                 &Subtable, TRUE);
2347     if (ACPI_FAILURE (Status))
2348     {
2349         return (Status);
2350     }
2351
2352     ParentTable = DtPeekSubtable ();
2353     DtInsertSubtable (ParentTable, Subtable);
2354
2355     while (*PFieldList)
2356     {
2357         SubtableStart = *PFieldList;
2358         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2359                     &Subtable, TRUE);
2360         if (ACPI_FAILURE (Status))
2361         {
2362             return (Status);
2363         }
2364
2365         ParentTable = DtPeekSubtable ();
2366         DtInsertSubtable (ParentTable, Subtable);
2367         DtPushSubtable (Subtable);
2368
2369         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2370
2371         switch (SratHeader->Type)
2372         {
2373         case ACPI_SRAT_TYPE_CPU_AFFINITY:
2374
2375             InfoTable = AcpiDmTableInfoSrat0;
2376             break;
2377
2378         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2379
2380             InfoTable = AcpiDmTableInfoSrat1;
2381             break;
2382
2383         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2384
2385             InfoTable = AcpiDmTableInfoSrat2;
2386             break;
2387
2388         case ACPI_SRAT_TYPE_GICC_AFFINITY:
2389
2390             InfoTable = AcpiDmTableInfoSrat3;
2391             break;
2392
2393         default:
2394
2395             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2396             return (AE_ERROR);
2397         }
2398
2399         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2400         if (ACPI_FAILURE (Status))
2401         {
2402             return (Status);
2403         }
2404
2405         ParentTable = DtPeekSubtable ();
2406         DtInsertSubtable (ParentTable, Subtable);
2407         DtPopSubtable ();
2408     }
2409
2410     return (AE_OK);
2411 }
2412
2413
2414 /******************************************************************************
2415  *
2416  * FUNCTION:    DtGetGenericTableInfo
2417  *
2418  * PARAMETERS:  Name                - Generic type name
2419  *
2420  * RETURN:      Info entry
2421  *
2422  * DESCRIPTION: Obtain table info for a generic name entry
2423  *
2424  *****************************************************************************/
2425
2426 ACPI_DMTABLE_INFO *
2427 DtGetGenericTableInfo (
2428     char                    *Name)
2429 {
2430     ACPI_DMTABLE_INFO       *Info;
2431     UINT32                  i;
2432
2433
2434     if (!Name)
2435     {
2436         return (NULL);
2437     }
2438
2439     /* Search info table for name match */
2440
2441     for (i = 0; ; i++)
2442     {
2443         Info = AcpiDmTableInfoGeneric[i];
2444         if (Info->Opcode == ACPI_DMT_EXIT)
2445         {
2446             Info = NULL;
2447             break;
2448         }
2449
2450         /* Use caseless compare for generic keywords */
2451
2452         if (!AcpiUtStricmp (Name, Info->Name))
2453         {
2454             break;
2455         }
2456     }
2457
2458     return (Info);
2459 }
2460
2461
2462 /******************************************************************************
2463  *
2464  * FUNCTION:    DtCompileUefi
2465  *
2466  * PARAMETERS:  List                - Current field list pointer
2467  *
2468  * RETURN:      Status
2469  *
2470  * DESCRIPTION: Compile UEFI.
2471  *
2472  *****************************************************************************/
2473
2474 ACPI_STATUS
2475 DtCompileUefi (
2476     void                    **List)
2477 {
2478     ACPI_STATUS             Status;
2479     DT_SUBTABLE             *Subtable;
2480     DT_SUBTABLE             *ParentTable;
2481     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2482     UINT16                  *DataOffset;
2483
2484
2485     /* Compile the predefined portion of the UEFI table */
2486
2487     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2488                 &Subtable, TRUE);
2489     if (ACPI_FAILURE (Status))
2490     {
2491         return (Status);
2492     }
2493
2494     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2495     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2496
2497     ParentTable = DtPeekSubtable ();
2498     DtInsertSubtable (ParentTable, Subtable);
2499
2500     /*
2501      * Compile the "generic" portion of the UEFI table. This
2502      * part of the table is not predefined and any of the generic
2503      * operators may be used.
2504      */
2505
2506     DtCompileGeneric ((void **) PFieldList);
2507
2508     return (AE_OK);
2509 }
2510
2511
2512 /******************************************************************************
2513  *
2514  * FUNCTION:    DtCompileVrtc
2515  *
2516  * PARAMETERS:  List                - Current field list pointer
2517  *
2518  * RETURN:      Status
2519  *
2520  * DESCRIPTION: Compile VRTC.
2521  *
2522  *****************************************************************************/
2523
2524 ACPI_STATUS
2525 DtCompileVrtc (
2526     void                    **List)
2527 {
2528     ACPI_STATUS             Status;
2529
2530
2531     Status = DtCompileTwoSubtables (List,
2532                  AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2533     return (Status);
2534 }
2535
2536
2537 /******************************************************************************
2538  *
2539  * FUNCTION:    DtCompileWdat
2540  *
2541  * PARAMETERS:  List                - Current field list pointer
2542  *
2543  * RETURN:      Status
2544  *
2545  * DESCRIPTION: Compile WDAT.
2546  *
2547  *****************************************************************************/
2548
2549 ACPI_STATUS
2550 DtCompileWdat (
2551     void                    **List)
2552 {
2553     ACPI_STATUS             Status;
2554
2555
2556     Status = DtCompileTwoSubtables (List,
2557                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2558     return (Status);
2559 }
2560
2561
2562 /******************************************************************************
2563  *
2564  * FUNCTION:    DtCompileXsdt
2565  *
2566  * PARAMETERS:  List                - Current field list pointer
2567  *
2568  * RETURN:      Status
2569  *
2570  * DESCRIPTION: Compile XSDT.
2571  *
2572  *****************************************************************************/
2573
2574 ACPI_STATUS
2575 DtCompileXsdt (
2576     void                    **List)
2577 {
2578     DT_SUBTABLE             *Subtable;
2579     DT_SUBTABLE             *ParentTable;
2580     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2581     UINT64                  Address;
2582
2583     ParentTable = DtPeekSubtable ();
2584
2585     while (FieldList)
2586     {
2587         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2588
2589         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2590         DtInsertSubtable (ParentTable, Subtable);
2591         FieldList = FieldList->Next;
2592     }
2593
2594     return (AE_OK);
2595 }
2596
2597
2598 /******************************************************************************
2599  *
2600  * FUNCTION:    DtCompileGeneric
2601  *
2602  * PARAMETERS:  List                - Current field list pointer
2603  *
2604  * RETURN:      Status
2605  *
2606  * DESCRIPTION: Compile generic unknown table.
2607  *
2608  *****************************************************************************/
2609
2610 ACPI_STATUS
2611 DtCompileGeneric (
2612     void                    **List)
2613 {
2614     ACPI_STATUS             Status;
2615     DT_SUBTABLE             *Subtable;
2616     DT_SUBTABLE             *ParentTable;
2617     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2618     ACPI_DMTABLE_INFO       *Info;
2619
2620
2621     ParentTable = DtPeekSubtable ();
2622
2623     /*
2624      * Compile the "generic" portion of the table. This
2625      * part of the table is not predefined and any of the generic
2626      * operators may be used.
2627      */
2628
2629     /* Find any and all labels in the entire generic portion */
2630
2631     DtDetectAllLabels (*PFieldList);
2632
2633     /* Now we can actually compile the parse tree */
2634
2635     while (*PFieldList)
2636     {
2637         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2638         if (!Info)
2639         {
2640             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2641                 (*PFieldList)->Name);
2642             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2643                 (*PFieldList), MsgBuffer);
2644
2645             *PFieldList = (*PFieldList)->Next;
2646             continue;
2647         }
2648
2649         Status = DtCompileTable (PFieldList, Info,
2650                     &Subtable, TRUE);
2651         if (ACPI_SUCCESS (Status))
2652         {
2653             DtInsertSubtable (ParentTable, Subtable);
2654         }
2655         else
2656         {
2657             *PFieldList = (*PFieldList)->Next;
2658
2659             if (Status == AE_NOT_FOUND)
2660             {
2661                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2662                     (*PFieldList)->Name);
2663                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2664                     (*PFieldList), MsgBuffer);
2665             }
2666         }
2667     }
2668
2669     return (AE_OK);
2670 }