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