dttable.c revision 209746
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
129static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
130{
131    {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
132    {ACPI_DMT_EXIT,     0,               NULL, 0}
133};
134
135static 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
150static ACPI_STATUS
151DtCompileTwoSubtables (
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
172static ACPI_STATUS
173DtCompileTwoSubtables (
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
220ACPI_STATUS
221DtCompileFacs (
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
262ACPI_STATUS
263DtCompileRsdp (
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
320ACPI_STATUS
321DtCompileAsf (
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
480ACPI_STATUS
481DtCompileCpep (
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
505ACPI_STATUS
506DtCompileDmar (
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
639ACPI_STATUS
640DtCompileEinj (
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
664ACPI_STATUS
665DtCompileErst (
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
689ACPI_STATUS
690DtCompileFadt (
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
753ACPI_STATUS
754DtCompileHest (
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
879ACPI_STATUS
880DtCompileIvrs (
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
1026ACPI_STATUS
1027DtCompileMadt (
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
1132ACPI_STATUS
1133DtCompileMcfg (
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
1157ACPI_STATUS
1158DtCompileMsct (
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
1182ACPI_STATUS
1183DtCompileRsdt (
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
1219ACPI_STATUS
1220DtCompileSlit (
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
1281ACPI_STATUS
1282DtCompileSrat (
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
1363ACPI_STATUS
1364DtCompileWdat (
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
1388ACPI_STATUS
1389DtCompileXsdt (
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