xref: /freebsd/sys/contrib/dev/acpica/compiler/dttable.c (revision 8f861da99cb9865b2f1ef6098ad074150f368c23)
1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2011, 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 #define __DTTABLE_C__
45 
46 /* Compile all complex data tables */
47 
48 #include <contrib/dev/acpica/compiler/aslcompiler.h>
49 #include <contrib/dev/acpica/compiler/dtcompiler.h>
50 
51 #define _COMPONENT          DT_COMPILER
52         ACPI_MODULE_NAME    ("dttable")
53 
54 
55 /* TBD: merge these into dmtbinfo.c? */
56 
57 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
58 {
59     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
60     {ACPI_DMT_EXIT,     0,               NULL, 0}
61 };
62 
63 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
64 {
65     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
66     {ACPI_DMT_EXIT,     0,               NULL, 0}
67 };
68 
69 
70 /* TBD: move to acmacros.h */
71 
72 #define ACPI_SUB_PTR(t, a, b) \
73     ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
74 
75 
76 /* Local prototypes */
77 
78 static ACPI_STATUS
79 DtCompileTwoSubtables (
80     void                    **List,
81     ACPI_DMTABLE_INFO       *TableInfo1,
82     ACPI_DMTABLE_INFO       *TableInfo2);
83 
84 
85 /******************************************************************************
86  *
87  * FUNCTION:    DtCompileTwoSubtables
88  *
89  * PARAMETERS:  List                - Current field list pointer
90  *              TableInfo1          - Info table 1
91  *              TableInfo1          - Info table 2
92  *
93  * RETURN:      Status
94  *
95  * DESCRIPTION: Compile tables with a header and one or more same subtables.
96  *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
97  *
98  *****************************************************************************/
99 
100 static ACPI_STATUS
101 DtCompileTwoSubtables (
102     void                    **List,
103     ACPI_DMTABLE_INFO       *TableInfo1,
104     ACPI_DMTABLE_INFO       *TableInfo2)
105 {
106     ACPI_STATUS             Status;
107     DT_SUBTABLE             *Subtable;
108     DT_SUBTABLE             *ParentTable;
109     DT_FIELD                **PFieldList = (DT_FIELD **) List;
110 
111 
112     Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
113     if (ACPI_FAILURE (Status))
114     {
115         return (Status);
116     }
117 
118     ParentTable = DtPeekSubtable ();
119     DtInsertSubtable (ParentTable, Subtable);
120 
121     while (*PFieldList)
122     {
123         Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
124         if (ACPI_FAILURE (Status))
125         {
126             return (Status);
127         }
128 
129         DtInsertSubtable (ParentTable, Subtable);
130     }
131 
132     return (AE_OK);
133 }
134 
135 
136 /******************************************************************************
137  *
138  * FUNCTION:    DtCompileFacs
139  *
140  * PARAMETERS:  PFieldList          - Current field list pointer
141  *
142  * RETURN:      Status
143  *
144  * DESCRIPTION: Compile FACS.
145  *
146  *****************************************************************************/
147 
148 ACPI_STATUS
149 DtCompileFacs (
150     DT_FIELD                **PFieldList)
151 {
152     DT_SUBTABLE             *Subtable;
153     UINT8                   *ReservedBuffer;
154     ACPI_STATUS             Status;
155     UINT32                  ReservedSize;
156 
157 
158     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
159                 &Gbl_RootTable, TRUE);
160     if (ACPI_FAILURE (Status))
161     {
162         return (Status);
163     }
164 
165     /* Large FACS reserved area at the end of the table */
166 
167     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
168     ReservedBuffer = UtLocalCalloc (ReservedSize);
169 
170     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
171 
172     ACPI_FREE (ReservedBuffer);
173     DtInsertSubtable (Gbl_RootTable, Subtable);
174     return (AE_OK);
175 }
176 
177 
178 /******************************************************************************
179  *
180  * FUNCTION:    DtCompileRsdp
181  *
182  * PARAMETERS:  PFieldList          - Current field list pointer
183  *
184  * RETURN:      Status
185  *
186  * DESCRIPTION: Compile RSDP.
187  *
188  *****************************************************************************/
189 
190 ACPI_STATUS
191 DtCompileRsdp (
192     DT_FIELD                **PFieldList)
193 {
194     DT_SUBTABLE             *Subtable;
195     ACPI_TABLE_RSDP         *Rsdp;
196     ACPI_RSDP_EXTENSION     *RsdpExtension;
197     ACPI_STATUS             Status;
198 
199 
200     /* Compile the "common" RSDP (ACPI 1.0) */
201 
202     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
203                 &Gbl_RootTable, TRUE);
204     if (ACPI_FAILURE (Status))
205     {
206         return (Status);
207     }
208 
209     Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
210     DtSetTableChecksum (&Rsdp->Checksum);
211 
212     if (Rsdp->Revision > 0)
213     {
214         /* Compile the "extended" part of the RSDP as a subtable */
215 
216         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
217                     &Subtable, TRUE);
218         if (ACPI_FAILURE (Status))
219         {
220             return (Status);
221         }
222 
223         DtInsertSubtable (Gbl_RootTable, Subtable);
224 
225         /* Set length and extended checksum for entire RSDP */
226 
227         RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
228         RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
229         DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
230     }
231 
232     return (AE_OK);
233 }
234 
235 
236 /******************************************************************************
237  *
238  * FUNCTION:    DtCompileAsf
239  *
240  * PARAMETERS:  List                - Current field list pointer
241  *
242  * RETURN:      Status
243  *
244  * DESCRIPTION: Compile ASF!.
245  *
246  *****************************************************************************/
247 
248 ACPI_STATUS
249 DtCompileAsf (
250     void                    **List)
251 {
252     ACPI_ASF_INFO           *AsfTable;
253     DT_SUBTABLE             *Subtable;
254     DT_SUBTABLE             *ParentTable;
255     ACPI_DMTABLE_INFO       *InfoTable;
256     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
257     UINT32                  DataCount = 0;
258     ACPI_STATUS             Status;
259     UINT32                  i;
260     DT_FIELD                **PFieldList = (DT_FIELD **) List;
261     DT_FIELD                *SubtableStart;
262 
263 
264     while (*PFieldList)
265     {
266         SubtableStart = *PFieldList;
267         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
268                     &Subtable, TRUE);
269         if (ACPI_FAILURE (Status))
270         {
271             return (Status);
272         }
273 
274         ParentTable = DtPeekSubtable ();
275         DtInsertSubtable (ParentTable, Subtable);
276         DtPushSubtable (Subtable);
277 
278         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
279 
280         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
281         {
282         case ACPI_ASF_TYPE_INFO:
283             InfoTable = AcpiDmTableInfoAsf0;
284             break;
285 
286         case ACPI_ASF_TYPE_ALERT:
287             InfoTable = AcpiDmTableInfoAsf1;
288             break;
289 
290         case ACPI_ASF_TYPE_CONTROL:
291             InfoTable = AcpiDmTableInfoAsf2;
292             break;
293 
294         case ACPI_ASF_TYPE_BOOT:
295             InfoTable = AcpiDmTableInfoAsf3;
296             break;
297 
298         case ACPI_ASF_TYPE_ADDRESS:
299             InfoTable = AcpiDmTableInfoAsf4;
300             break;
301 
302         default:
303             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
304             return (AE_ERROR);
305         }
306 
307         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
308         if (ACPI_FAILURE (Status))
309         {
310             return (Status);
311         }
312 
313         ParentTable = DtPeekSubtable ();
314         DtInsertSubtable (ParentTable, Subtable);
315 
316         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
317         {
318         case ACPI_ASF_TYPE_INFO:
319             DataInfoTable = NULL;
320             break;
321 
322         case ACPI_ASF_TYPE_ALERT:
323             DataInfoTable = AcpiDmTableInfoAsf1a;
324             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
325                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
326                             sizeof (ACPI_ASF_HEADER)))->Alerts;
327             break;
328 
329         case ACPI_ASF_TYPE_CONTROL:
330             DataInfoTable = AcpiDmTableInfoAsf2a;
331             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
332                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
333                             sizeof (ACPI_ASF_HEADER)))->Controls;
334             break;
335 
336         case ACPI_ASF_TYPE_BOOT:
337             DataInfoTable = NULL;
338             break;
339 
340         case ACPI_ASF_TYPE_ADDRESS:
341             DataInfoTable = TableInfoAsfAddress;
342             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
343                         ACPI_SUB_PTR (UINT8, Subtable->Buffer,
344                             sizeof (ACPI_ASF_HEADER)))->Devices;
345             break;
346 
347         default:
348             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
349             return (AE_ERROR);
350         }
351 
352         if (DataInfoTable)
353         {
354             switch (AsfTable->Header.Type & 0x7F)
355             {
356             case ACPI_ASF_TYPE_ADDRESS:
357 
358                 while (DataCount > 0)
359                 {
360                     Status = DtCompileTable (PFieldList, DataInfoTable,
361                                 &Subtable, TRUE);
362                     if (ACPI_FAILURE (Status))
363                     {
364                         return (Status);
365                     }
366 
367                     DtInsertSubtable (ParentTable, Subtable);
368                     DataCount = DataCount - Subtable->Length;
369                 }
370                 break;
371 
372             default:
373 
374                 for (i = 0; i < DataCount; i++)
375                 {
376                     Status = DtCompileTable (PFieldList, DataInfoTable,
377                                 &Subtable, TRUE);
378                     if (ACPI_FAILURE (Status))
379                     {
380                         return (Status);
381                     }
382 
383                     DtInsertSubtable (ParentTable, Subtable);
384                 }
385                 break;
386             }
387         }
388 
389         DtPopSubtable ();
390     }
391 
392     return (AE_OK);
393 }
394 
395 
396 /******************************************************************************
397  *
398  * FUNCTION:    DtCompileCpep
399  *
400  * PARAMETERS:  List                - Current field list pointer
401  *
402  * RETURN:      Status
403  *
404  * DESCRIPTION: Compile CPEP.
405  *
406  *****************************************************************************/
407 
408 ACPI_STATUS
409 DtCompileCpep (
410     void                    **List)
411 {
412     ACPI_STATUS             Status;
413 
414 
415     Status = DtCompileTwoSubtables (List,
416                  AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
417     return (Status);
418 }
419 
420 
421 /******************************************************************************
422  *
423  * FUNCTION:    DtCompileDmar
424  *
425  * PARAMETERS:  List                - Current field list pointer
426  *
427  * RETURN:      Status
428  *
429  * DESCRIPTION: Compile DMAR.
430  *
431  *****************************************************************************/
432 
433 ACPI_STATUS
434 DtCompileDmar (
435     void                    **List)
436 {
437     ACPI_STATUS             Status;
438     DT_SUBTABLE             *Subtable;
439     DT_SUBTABLE             *ParentTable;
440     DT_FIELD                **PFieldList = (DT_FIELD **) List;
441     DT_FIELD                *SubtableStart;
442     ACPI_DMTABLE_INFO       *InfoTable;
443     ACPI_DMAR_HEADER        *DmarHeader;
444     UINT8                   *ReservedBuffer;
445     UINT32                  ReservedSize;
446 
447 
448     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
449     if (ACPI_FAILURE (Status))
450     {
451         return (Status);
452     }
453 
454     ParentTable = DtPeekSubtable ();
455     DtInsertSubtable (ParentTable, Subtable);
456 
457     /* DMAR Reserved area */
458 
459     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved);
460     ReservedBuffer = UtLocalCalloc (ReservedSize);
461 
462     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
463 
464     ACPI_FREE (ReservedBuffer);
465     ParentTable = DtPeekSubtable ();
466     DtInsertSubtable (ParentTable, Subtable);
467 
468     while (*PFieldList)
469     {
470         /* DMAR Header */
471 
472         SubtableStart = *PFieldList;
473         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
474                     &Subtable, TRUE);
475         if (ACPI_FAILURE (Status))
476         {
477             return (Status);
478         }
479 
480         ParentTable = DtPeekSubtable ();
481         DtInsertSubtable (ParentTable, Subtable);
482         DtPushSubtable (Subtable);
483 
484         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
485 
486         switch (DmarHeader->Type)
487         {
488         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
489             InfoTable = AcpiDmTableInfoDmar0;
490             break;
491         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
492             InfoTable = AcpiDmTableInfoDmar1;
493             break;
494         case ACPI_DMAR_TYPE_ATSR:
495             InfoTable = AcpiDmTableInfoDmar2;
496             break;
497         case ACPI_DMAR_HARDWARE_AFFINITY:
498             InfoTable = AcpiDmTableInfoDmar3;
499             break;
500         default:
501             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
502             return (AE_ERROR);
503         }
504 
505         /* DMAR Subtable */
506 
507         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
508         if (ACPI_FAILURE (Status))
509         {
510             return (Status);
511         }
512 
513         ParentTable = DtPeekSubtable ();
514         DtInsertSubtable (ParentTable, Subtable);
515 
516         /* Optional Device Scope subtables */
517 
518         while (*PFieldList)
519         {
520             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
521                         &Subtable, FALSE);
522             if (Status == AE_NOT_FOUND)
523             {
524                 break;
525             }
526 
527             ParentTable = DtPeekSubtable ();
528             DtInsertSubtable (ParentTable, Subtable);
529             DtPushSubtable (Subtable);
530 
531             /* Optional PCI Paths */
532 
533             while (*PFieldList)
534             {
535                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
536                             &Subtable, FALSE);
537                 if (Status == AE_NOT_FOUND)
538                 {
539                     DtPopSubtable ();
540                     break;
541                 }
542 
543                 ParentTable = DtPeekSubtable ();
544                 DtInsertSubtable (ParentTable, Subtable);
545             }
546         }
547 
548         DtPopSubtable ();
549     }
550 
551     return (AE_OK);
552 }
553 
554 
555 /******************************************************************************
556  *
557  * FUNCTION:    DtCompileEinj
558  *
559  * PARAMETERS:  List                - Current field list pointer
560  *
561  * RETURN:      Status
562  *
563  * DESCRIPTION: Compile EINJ.
564  *
565  *****************************************************************************/
566 
567 ACPI_STATUS
568 DtCompileEinj (
569     void                    **List)
570 {
571     ACPI_STATUS             Status;
572 
573 
574     Status = DtCompileTwoSubtables (List,
575                  AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
576     return (Status);
577 }
578 
579 
580 /******************************************************************************
581  *
582  * FUNCTION:    DtCompileErst
583  *
584  * PARAMETERS:  List                - Current field list pointer
585  *
586  * RETURN:      Status
587  *
588  * DESCRIPTION: Compile ERST.
589  *
590  *****************************************************************************/
591 
592 ACPI_STATUS
593 DtCompileErst (
594     void                    **List)
595 {
596     ACPI_STATUS             Status;
597 
598 
599     Status = DtCompileTwoSubtables (List,
600                  AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
601     return (Status);
602 }
603 
604 
605 /******************************************************************************
606  *
607  * FUNCTION:    DtCompileFadt
608  *
609  * PARAMETERS:  List                - Current field list pointer
610  *
611  * RETURN:      Status
612  *
613  * DESCRIPTION: Compile FADT.
614  *
615  *****************************************************************************/
616 
617 ACPI_STATUS
618 DtCompileFadt (
619     void                    **List)
620 {
621     ACPI_STATUS             Status;
622     DT_SUBTABLE             *Subtable;
623     DT_SUBTABLE             *ParentTable;
624     DT_FIELD                **PFieldList = (DT_FIELD **) List;
625     ACPI_TABLE_HEADER       *Table;
626     UINT8                   Revision;
627 
628 
629     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
630                 &Subtable, TRUE);
631     if (ACPI_FAILURE (Status))
632     {
633         return (Status);
634     }
635 
636     ParentTable = DtPeekSubtable ();
637     DtInsertSubtable (ParentTable, Subtable);
638 
639     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
640     Revision = Table->Revision;
641 
642     if (Revision == 2)
643     {
644         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
645                     &Subtable, TRUE);
646         if (ACPI_FAILURE (Status))
647         {
648             return (Status);
649         }
650 
651         DtInsertSubtable (ParentTable, Subtable);
652     }
653     else if (Revision >= 2)
654     {
655         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
656                     &Subtable, TRUE);
657         if (ACPI_FAILURE (Status))
658         {
659             return (Status);
660         }
661 
662         DtInsertSubtable (ParentTable, Subtable);
663     }
664 
665     return (AE_OK);
666 }
667 
668 
669 /******************************************************************************
670  *
671  * FUNCTION:    DtCompileHest
672  *
673  * PARAMETERS:  List                - Current field list pointer
674  *
675  * RETURN:      Status
676  *
677  * DESCRIPTION: Compile HEST.
678  *
679  *****************************************************************************/
680 
681 ACPI_STATUS
682 DtCompileHest (
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     UINT16                  Type;
692     UINT32                  BankCount;
693 
694 
695     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
696                 &Subtable, TRUE);
697     if (ACPI_FAILURE (Status))
698     {
699         return (Status);
700     }
701 
702     ParentTable = DtPeekSubtable ();
703     DtInsertSubtable (ParentTable, Subtable);
704 
705     while (*PFieldList)
706     {
707         /* Get subtable type */
708 
709         SubtableStart = *PFieldList;
710         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
711 
712         switch (Type)
713         {
714         case ACPI_HEST_TYPE_IA32_CHECK:
715             InfoTable = AcpiDmTableInfoHest0;
716             break;
717 
718         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
719             InfoTable = AcpiDmTableInfoHest1;
720             break;
721 
722         case ACPI_HEST_TYPE_IA32_NMI:
723             InfoTable = AcpiDmTableInfoHest2;
724             break;
725 
726         case ACPI_HEST_TYPE_AER_ROOT_PORT:
727             InfoTable = AcpiDmTableInfoHest6;
728             break;
729 
730         case ACPI_HEST_TYPE_AER_ENDPOINT:
731             InfoTable = AcpiDmTableInfoHest7;
732             break;
733 
734         case ACPI_HEST_TYPE_AER_BRIDGE:
735             InfoTable = AcpiDmTableInfoHest8;
736             break;
737 
738         case ACPI_HEST_TYPE_GENERIC_ERROR:
739             InfoTable = AcpiDmTableInfoHest9;
740             break;
741 
742         default:
743             /* Cannot continue on unknown type */
744 
745             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
746             return (AE_ERROR);
747         }
748 
749         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
750         if (ACPI_FAILURE (Status))
751         {
752             return (Status);
753         }
754 
755         DtInsertSubtable (ParentTable, Subtable);
756 
757         /*
758          * Additional subtable data - IA32 Error Bank(s)
759          */
760         BankCount = 0;
761         switch (Type)
762         {
763         case ACPI_HEST_TYPE_IA32_CHECK:
764             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
765                             Subtable->Buffer))->NumHardwareBanks;
766             break;
767 
768         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
769             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
770                             Subtable->Buffer))->NumHardwareBanks;
771             break;
772 
773         default:
774             break;
775         }
776 
777         while (BankCount)
778         {
779             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
780                         &Subtable, TRUE);
781             if (ACPI_FAILURE (Status))
782             {
783                 return (Status);
784             }
785 
786             DtInsertSubtable (ParentTable, Subtable);
787             BankCount--;
788         }
789     }
790 
791     return AE_OK;
792 }
793 
794 
795 /******************************************************************************
796  *
797  * FUNCTION:    DtCompileIvrs
798  *
799  * PARAMETERS:  List                - Current field list pointer
800  *
801  * RETURN:      Status
802  *
803  * DESCRIPTION: Compile IVRS.
804  *
805  *****************************************************************************/
806 
807 ACPI_STATUS
808 DtCompileIvrs (
809     void                    **List)
810 {
811     ACPI_STATUS             Status;
812     DT_SUBTABLE             *Subtable;
813     DT_SUBTABLE             *ParentTable;
814     DT_FIELD                **PFieldList = (DT_FIELD **) List;
815     DT_FIELD                *SubtableStart;
816     ACPI_DMTABLE_INFO       *InfoTable;
817     ACPI_IVRS_HEADER        *IvrsHeader;
818     UINT8                   EntryType;
819 
820 
821     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
822                 &Subtable, TRUE);
823     if (ACPI_FAILURE (Status))
824     {
825         return (Status);
826     }
827 
828     ParentTable = DtPeekSubtable ();
829     DtInsertSubtable (ParentTable, Subtable);
830 
831     while (*PFieldList)
832     {
833         SubtableStart = *PFieldList;
834         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
835                     &Subtable, TRUE);
836         if (ACPI_FAILURE (Status))
837         {
838             return (Status);
839         }
840 
841         ParentTable = DtPeekSubtable ();
842         DtInsertSubtable (ParentTable, Subtable);
843         DtPushSubtable (Subtable);
844 
845         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
846 
847         switch (IvrsHeader->Type)
848         {
849         case ACPI_IVRS_TYPE_HARDWARE:
850             InfoTable = AcpiDmTableInfoIvrs0;
851             break;
852 
853         case ACPI_IVRS_TYPE_MEMORY1:
854         case ACPI_IVRS_TYPE_MEMORY2:
855         case ACPI_IVRS_TYPE_MEMORY3:
856             InfoTable = AcpiDmTableInfoIvrs1;
857             break;
858 
859         default:
860             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
861             return (AE_ERROR);
862         }
863 
864         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
865         if (ACPI_FAILURE (Status))
866         {
867             return (Status);
868         }
869 
870         ParentTable = DtPeekSubtable ();
871         DtInsertSubtable (ParentTable, Subtable);
872 
873         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
874         {
875             while (*PFieldList &&
876                     !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
877             {
878                 SubtableStart = *PFieldList;
879                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
880 
881                 switch (EntryType)
882                 {
883                 /* 4-byte device entries */
884 
885                 case ACPI_IVRS_TYPE_PAD4:
886                 case ACPI_IVRS_TYPE_ALL:
887                 case ACPI_IVRS_TYPE_SELECT:
888                 case ACPI_IVRS_TYPE_START:
889                 case ACPI_IVRS_TYPE_END:
890 
891                     InfoTable = AcpiDmTableInfoIvrs4;
892                     break;
893 
894                 /* 8-byte entries, type A */
895 
896                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
897                 case ACPI_IVRS_TYPE_ALIAS_START:
898 
899                     InfoTable = AcpiDmTableInfoIvrs8a;
900                     break;
901 
902                 /* 8-byte entries, type B */
903 
904                 case ACPI_IVRS_TYPE_PAD8:
905                 case ACPI_IVRS_TYPE_EXT_SELECT:
906                 case ACPI_IVRS_TYPE_EXT_START:
907 
908                     InfoTable = AcpiDmTableInfoIvrs8b;
909                     break;
910 
911                 /* 8-byte entries, type C */
912 
913                 case ACPI_IVRS_TYPE_SPECIAL:
914 
915                     InfoTable = AcpiDmTableInfoIvrs8c;
916                     break;
917 
918                 default:
919                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
920                         "IVRS Device Entry");
921                     return (AE_ERROR);
922                 }
923 
924                 Status = DtCompileTable (PFieldList, InfoTable,
925                             &Subtable, TRUE);
926                 if (ACPI_FAILURE (Status))
927                 {
928                     return (Status);
929                 }
930 
931                 DtInsertSubtable (ParentTable, Subtable);
932             }
933         }
934 
935         DtPopSubtable ();
936     }
937 
938     return (AE_OK);
939 }
940 
941 
942 /******************************************************************************
943  *
944  * FUNCTION:    DtCompileMadt
945  *
946  * PARAMETERS:  List                - Current field list pointer
947  *
948  * RETURN:      Status
949  *
950  * DESCRIPTION: Compile MADT.
951  *
952  *****************************************************************************/
953 
954 ACPI_STATUS
955 DtCompileMadt (
956     void                    **List)
957 {
958     ACPI_STATUS             Status;
959     DT_SUBTABLE             *Subtable;
960     DT_SUBTABLE             *ParentTable;
961     DT_FIELD                **PFieldList = (DT_FIELD **) List;
962     DT_FIELD                *SubtableStart;
963     ACPI_SUBTABLE_HEADER    *MadtHeader;
964     ACPI_DMTABLE_INFO       *InfoTable;
965 
966 
967     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
968                 &Subtable, TRUE);
969     if (ACPI_FAILURE (Status))
970     {
971         return (Status);
972     }
973 
974     ParentTable = DtPeekSubtable ();
975     DtInsertSubtable (ParentTable, Subtable);
976 
977     while (*PFieldList)
978     {
979         SubtableStart = *PFieldList;
980         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
981                     &Subtable, TRUE);
982         if (ACPI_FAILURE (Status))
983         {
984             return (Status);
985         }
986 
987         ParentTable = DtPeekSubtable ();
988         DtInsertSubtable (ParentTable, Subtable);
989         DtPushSubtable (Subtable);
990 
991         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
992 
993         switch (MadtHeader->Type)
994         {
995         case ACPI_MADT_TYPE_LOCAL_APIC:
996             InfoTable = AcpiDmTableInfoMadt0;
997             break;
998         case ACPI_MADT_TYPE_IO_APIC:
999             InfoTable = AcpiDmTableInfoMadt1;
1000             break;
1001         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1002             InfoTable = AcpiDmTableInfoMadt2;
1003             break;
1004         case ACPI_MADT_TYPE_NMI_SOURCE:
1005             InfoTable = AcpiDmTableInfoMadt3;
1006             break;
1007         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1008             InfoTable = AcpiDmTableInfoMadt4;
1009             break;
1010         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1011             InfoTable = AcpiDmTableInfoMadt5;
1012             break;
1013         case ACPI_MADT_TYPE_IO_SAPIC:
1014             InfoTable = AcpiDmTableInfoMadt6;
1015             break;
1016         case ACPI_MADT_TYPE_LOCAL_SAPIC:
1017             InfoTable = AcpiDmTableInfoMadt7;
1018             break;
1019         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1020             InfoTable = AcpiDmTableInfoMadt8;
1021             break;
1022         case ACPI_MADT_TYPE_LOCAL_X2APIC:
1023             InfoTable = AcpiDmTableInfoMadt9;
1024             break;
1025         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1026             InfoTable = AcpiDmTableInfoMadt10;
1027             break;
1028         default:
1029             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1030             return (AE_ERROR);
1031         }
1032 
1033         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1034         if (ACPI_FAILURE (Status))
1035         {
1036             return (Status);
1037         }
1038 
1039         ParentTable = DtPeekSubtable ();
1040         DtInsertSubtable (ParentTable, Subtable);
1041         DtPopSubtable ();
1042     }
1043 
1044     return (AE_OK);
1045 }
1046 
1047 
1048 /******************************************************************************
1049  *
1050  * FUNCTION:    DtCompileMcfg
1051  *
1052  * PARAMETERS:  List                - Current field list pointer
1053  *
1054  * RETURN:      Status
1055  *
1056  * DESCRIPTION: Compile MCFG.
1057  *
1058  *****************************************************************************/
1059 
1060 ACPI_STATUS
1061 DtCompileMcfg (
1062     void                    **List)
1063 {
1064     ACPI_STATUS             Status;
1065 
1066 
1067     Status = DtCompileTwoSubtables (List,
1068                  AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1069     return (Status);
1070 }
1071 
1072 
1073 /******************************************************************************
1074  *
1075  * FUNCTION:    DtCompileMsct
1076  *
1077  * PARAMETERS:  List                - Current field list pointer
1078  *
1079  * RETURN:      Status
1080  *
1081  * DESCRIPTION: Compile MSCT.
1082  *
1083  *****************************************************************************/
1084 
1085 ACPI_STATUS
1086 DtCompileMsct (
1087     void                    **List)
1088 {
1089     ACPI_STATUS             Status;
1090 
1091 
1092     Status = DtCompileTwoSubtables (List,
1093                  AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1094     return (Status);
1095 }
1096 
1097 
1098 /******************************************************************************
1099  *
1100  * FUNCTION:    DtCompileRsdt
1101  *
1102  * PARAMETERS:  List                - Current field list pointer
1103  *
1104  * RETURN:      Status
1105  *
1106  * DESCRIPTION: Compile RSDT.
1107  *
1108  *****************************************************************************/
1109 
1110 ACPI_STATUS
1111 DtCompileRsdt (
1112     void                    **List)
1113 {
1114     DT_SUBTABLE             *Subtable;
1115     DT_SUBTABLE             *ParentTable;
1116     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1117     UINT32                  Address;
1118 
1119 
1120     ParentTable = DtPeekSubtable ();
1121 
1122     while (FieldList)
1123     {
1124         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1125 
1126         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1127         DtInsertSubtable (ParentTable, Subtable);
1128         FieldList = FieldList->Next;
1129     }
1130 
1131     return (AE_OK);
1132 }
1133 
1134 
1135 /******************************************************************************
1136  *
1137  * FUNCTION:    DtCompileSlit
1138  *
1139  * PARAMETERS:  List                - Current field list pointer
1140  *
1141  * RETURN:      Status
1142  *
1143  * DESCRIPTION: Compile SLIT.
1144  *
1145  *****************************************************************************/
1146 
1147 ACPI_STATUS
1148 DtCompileSlit (
1149     void                    **List)
1150 {
1151     ACPI_STATUS             Status;
1152     DT_SUBTABLE             *Subtable;
1153     DT_SUBTABLE             *ParentTable;
1154     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1155     DT_FIELD                *FieldList;
1156     UINT32                  Localities;
1157     UINT8                   *LocalityBuffer;
1158     UINT32                  RemainingData;
1159 
1160 
1161     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1162                 &Subtable, TRUE);
1163     if (ACPI_FAILURE (Status))
1164     {
1165         return (Status);
1166     }
1167 
1168     ParentTable = DtPeekSubtable ();
1169     DtInsertSubtable (ParentTable, Subtable);
1170 
1171     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1172     LocalityBuffer = UtLocalCalloc (Localities);
1173 
1174     FieldList = *PFieldList;
1175     while (FieldList)
1176     {
1177         /* Handle multiple-line buffer */
1178 
1179         RemainingData = Localities;
1180         while (RemainingData && FieldList)
1181         {
1182             RemainingData = DtCompileBuffer (
1183                 LocalityBuffer + (Localities - RemainingData),
1184                 FieldList->Value, FieldList, RemainingData);
1185             FieldList = FieldList->Next;
1186         }
1187 
1188         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1189         DtInsertSubtable (ParentTable, Subtable);
1190     }
1191 
1192     ACPI_FREE (LocalityBuffer);
1193     return (AE_OK);
1194 }
1195 
1196 
1197 /******************************************************************************
1198  *
1199  * FUNCTION:    DtCompileSrat
1200  *
1201  * PARAMETERS:  List                - Current field list pointer
1202  *
1203  * RETURN:      Status
1204  *
1205  * DESCRIPTION: Compile SRAT.
1206  *
1207  *****************************************************************************/
1208 
1209 ACPI_STATUS
1210 DtCompileSrat (
1211     void                    **List)
1212 {
1213     ACPI_STATUS             Status;
1214     DT_SUBTABLE             *Subtable;
1215     DT_SUBTABLE             *ParentTable;
1216     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1217     DT_FIELD                *SubtableStart;
1218     ACPI_SUBTABLE_HEADER    *SratHeader;
1219     ACPI_DMTABLE_INFO       *InfoTable;
1220 
1221 
1222     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1223                 &Subtable, TRUE);
1224     if (ACPI_FAILURE (Status))
1225     {
1226         return (Status);
1227     }
1228 
1229     ParentTable = DtPeekSubtable ();
1230     DtInsertSubtable (ParentTable, Subtable);
1231 
1232     while (*PFieldList)
1233     {
1234         SubtableStart = *PFieldList;
1235         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1236                     &Subtable, TRUE);
1237         if (ACPI_FAILURE (Status))
1238         {
1239             return (Status);
1240         }
1241 
1242         ParentTable = DtPeekSubtable ();
1243         DtInsertSubtable (ParentTable, Subtable);
1244         DtPushSubtable (Subtable);
1245 
1246         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1247 
1248         switch (SratHeader->Type)
1249         {
1250         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1251             InfoTable = AcpiDmTableInfoSrat0;
1252             break;
1253         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1254             InfoTable = AcpiDmTableInfoSrat1;
1255             break;
1256         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1257             InfoTable = AcpiDmTableInfoSrat2;
1258             break;
1259         default:
1260             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1261             return (AE_ERROR);
1262         }
1263 
1264         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1265         if (ACPI_FAILURE (Status))
1266         {
1267             return (Status);
1268         }
1269 
1270         ParentTable = DtPeekSubtable ();
1271         DtInsertSubtable (ParentTable, Subtable);
1272         DtPopSubtable ();
1273     }
1274 
1275     return (AE_OK);
1276 }
1277 
1278 
1279 /******************************************************************************
1280  *
1281  * FUNCTION:    DtTableInfoGeneric
1282  *
1283  * PARAMETERS:  Name                - Generic type name
1284  *
1285  * RETURN:      Info entry
1286  *
1287  * DESCRIPTION: Obtain table info for a generic name entry
1288  *
1289  *****************************************************************************/
1290 
1291 static ACPI_DMTABLE_INFO *
1292 DtTableInfoGeneric (
1293     char                    *Name)
1294 {
1295     ACPI_DMTABLE_INFO       *Info;
1296     UINT32                  i;
1297 
1298 
1299     if (!Name)
1300     {
1301         return (NULL);
1302     }
1303 
1304     /* Search info table for name match */
1305 
1306     for (i = 0; ; i++)
1307     {
1308         Info = AcpiDmTableInfoGeneric[i];
1309         if (Info->Opcode == ACPI_DMT_EXIT)
1310         {
1311             Info = NULL;
1312             break;
1313         }
1314 
1315         if (!ACPI_STRCMP (Name, Info->Name))
1316         {
1317             break;
1318         }
1319     }
1320 
1321     return (Info);
1322 }
1323 
1324 
1325 /******************************************************************************
1326  *
1327  * FUNCTION:    DtCompileUefi
1328  *
1329  * PARAMETERS:  List                - Current field list pointer
1330  *
1331  * RETURN:      Status
1332  *
1333  * DESCRIPTION: Compile UEFI.
1334  *
1335  *****************************************************************************/
1336 
1337 ACPI_STATUS
1338 DtCompileUefi (
1339     void                    **List)
1340 {
1341     ACPI_STATUS             Status;
1342     DT_SUBTABLE             *Subtable;
1343     DT_SUBTABLE             *ParentTable;
1344     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1345     ACPI_DMTABLE_INFO       *Info;
1346     UINT16                  *DataOffset;
1347 
1348 
1349     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1350                 &Subtable, TRUE);
1351     if (ACPI_FAILURE (Status))
1352     {
1353         return (Status);
1354     }
1355 
1356     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1357     *DataOffset = sizeof (ACPI_TABLE_UEFI);
1358 
1359     ParentTable = DtPeekSubtable ();
1360     DtInsertSubtable (ParentTable, Subtable);
1361 
1362     while (*PFieldList)
1363     {
1364         Info = DtTableInfoGeneric ((*PFieldList)->Name);
1365         if (!Info)
1366         {
1367             sprintf (MsgBuffer, "Generic data type \"%s\" not found",
1368                 (*PFieldList)->Name);
1369             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
1370                 (*PFieldList), MsgBuffer);
1371 
1372             *PFieldList = (*PFieldList)->Next;
1373             continue;
1374         }
1375 
1376         Status = DtCompileTable (PFieldList, Info,
1377                     &Subtable, TRUE);
1378         if (ACPI_SUCCESS (Status))
1379         {
1380             DtInsertSubtable (ParentTable, Subtable);
1381         }
1382         else
1383         {
1384             *PFieldList = (*PFieldList)->Next;
1385 
1386             if (Status == AE_NOT_FOUND)
1387             {
1388                 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
1389                     (*PFieldList)->Name);
1390                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
1391                     (*PFieldList), MsgBuffer);
1392             }
1393         }
1394     }
1395 
1396     return (AE_OK);
1397 }
1398 
1399 
1400 /******************************************************************************
1401  *
1402  * FUNCTION:    DtCompileWdat
1403  *
1404  * PARAMETERS:  List                - Current field list pointer
1405  *
1406  * RETURN:      Status
1407  *
1408  * DESCRIPTION: Compile WDAT.
1409  *
1410  *****************************************************************************/
1411 
1412 ACPI_STATUS
1413 DtCompileWdat (
1414     void                    **List)
1415 {
1416     ACPI_STATUS             Status;
1417 
1418 
1419     Status = DtCompileTwoSubtables (List,
1420                  AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
1421     return (Status);
1422 }
1423 
1424 
1425 /******************************************************************************
1426  *
1427  * FUNCTION:    DtCompileXsdt
1428  *
1429  * PARAMETERS:  List                - Current field list pointer
1430  *
1431  * RETURN:      Status
1432  *
1433  * DESCRIPTION: Compile XSDT.
1434  *
1435  *****************************************************************************/
1436 
1437 ACPI_STATUS
1438 DtCompileXsdt (
1439     void                    **List)
1440 {
1441     DT_SUBTABLE             *Subtable;
1442     DT_SUBTABLE             *ParentTable;
1443     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1444     UINT64                  Address;
1445 
1446     ParentTable = DtPeekSubtable ();
1447 
1448     while (FieldList)
1449     {
1450         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
1451 
1452         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
1453         DtInsertSubtable (ParentTable, Subtable);
1454         FieldList = FieldList->Next;
1455     }
1456 
1457     return (AE_OK);
1458 }
1459