dttable.c revision 245582
1/******************************************************************************
2 *
3 * Module Name: dttable.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, 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
57static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
58{
59    {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
60    {ACPI_DMT_EXIT,     0,               NULL, 0}
61};
62
63static 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
78static ACPI_STATUS
79DtCompileTwoSubtables (
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
100static ACPI_STATUS
101DtCompileTwoSubtables (
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
148ACPI_STATUS
149DtCompileFacs (
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
190ACPI_STATUS
191DtCompileRsdp (
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
248ACPI_STATUS
249DtCompileAsf (
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
408ACPI_STATUS
409DtCompileCpep (
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:    DtCompileCsrt
424 *
425 * PARAMETERS:  List                - Current field list pointer
426 *
427 * RETURN:      Status
428 *
429 * DESCRIPTION: Compile CSRT.
430 *
431 *****************************************************************************/
432
433ACPI_STATUS
434DtCompileCsrt (
435    void                    **List)
436{
437    ACPI_STATUS             Status = AE_OK;
438    DT_SUBTABLE             *Subtable;
439    DT_SUBTABLE             *ParentTable;
440    DT_FIELD                **PFieldList = (DT_FIELD **) List;
441    UINT32                  DescriptorCount;
442    UINT32                  GroupLength;
443
444
445    /* Sub-tables (Resource Groups) */
446
447    while (*PFieldList)
448    {
449        /* Resource group subtable */
450
451        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
452                    &Subtable, TRUE);
453        if (ACPI_FAILURE (Status))
454        {
455            return (Status);
456        }
457
458        /* Compute the number of resource descriptors */
459
460        GroupLength =
461            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
462                Subtable->Buffer))->Length -
463            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
464                Subtable->Buffer))->SharedInfoLength -
465            sizeof (ACPI_CSRT_GROUP);
466
467        DescriptorCount = (GroupLength  /
468            sizeof (ACPI_CSRT_DESCRIPTOR));
469
470        ParentTable = DtPeekSubtable ();
471        DtInsertSubtable (ParentTable, Subtable);
472        DtPushSubtable (Subtable);
473
474        /* Shared info subtable (One per resource group) */
475
476        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
477                    &Subtable, TRUE);
478        if (ACPI_FAILURE (Status))
479        {
480            return (Status);
481        }
482
483        ParentTable = DtPeekSubtable ();
484        DtInsertSubtable (ParentTable, Subtable);
485
486        /* Sub-Subtables (Resource Descriptors) */
487
488        while (*PFieldList && DescriptorCount)
489        {
490            Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
491                        &Subtable, TRUE);
492            if (ACPI_FAILURE (Status))
493            {
494                return (Status);
495            }
496
497            ParentTable = DtPeekSubtable ();
498            DtInsertSubtable (ParentTable, Subtable);
499            DescriptorCount--;
500        }
501
502        DtPopSubtable ();
503    }
504
505    return (Status);
506}
507
508
509/******************************************************************************
510 *
511 * FUNCTION:    DtCompileDmar
512 *
513 * PARAMETERS:  List                - Current field list pointer
514 *
515 * RETURN:      Status
516 *
517 * DESCRIPTION: Compile DMAR.
518 *
519 *****************************************************************************/
520
521ACPI_STATUS
522DtCompileDmar (
523    void                    **List)
524{
525    ACPI_STATUS             Status;
526    DT_SUBTABLE             *Subtable;
527    DT_SUBTABLE             *ParentTable;
528    DT_FIELD                **PFieldList = (DT_FIELD **) List;
529    DT_FIELD                *SubtableStart;
530    ACPI_DMTABLE_INFO       *InfoTable;
531    ACPI_DMAR_HEADER        *DmarHeader;
532    UINT8                   *ReservedBuffer;
533    UINT32                  ReservedSize;
534
535
536    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
537    if (ACPI_FAILURE (Status))
538    {
539        return (Status);
540    }
541
542    ParentTable = DtPeekSubtable ();
543    DtInsertSubtable (ParentTable, Subtable);
544
545    /* DMAR Reserved area */
546
547    ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved);
548    ReservedBuffer = UtLocalCalloc (ReservedSize);
549
550    DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
551
552    ACPI_FREE (ReservedBuffer);
553    ParentTable = DtPeekSubtable ();
554    DtInsertSubtable (ParentTable, Subtable);
555
556    while (*PFieldList)
557    {
558        /* DMAR Header */
559
560        SubtableStart = *PFieldList;
561        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
562                    &Subtable, TRUE);
563        if (ACPI_FAILURE (Status))
564        {
565            return (Status);
566        }
567
568        ParentTable = DtPeekSubtable ();
569        DtInsertSubtable (ParentTable, Subtable);
570        DtPushSubtable (Subtable);
571
572        DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
573
574        switch (DmarHeader->Type)
575        {
576        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
577            InfoTable = AcpiDmTableInfoDmar0;
578            break;
579        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
580            InfoTable = AcpiDmTableInfoDmar1;
581            break;
582        case ACPI_DMAR_TYPE_ATSR:
583            InfoTable = AcpiDmTableInfoDmar2;
584            break;
585        case ACPI_DMAR_HARDWARE_AFFINITY:
586            InfoTable = AcpiDmTableInfoDmar3;
587            break;
588        default:
589            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
590            return (AE_ERROR);
591        }
592
593        /* DMAR Subtable */
594
595        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
596        if (ACPI_FAILURE (Status))
597        {
598            return (Status);
599        }
600
601        ParentTable = DtPeekSubtable ();
602        DtInsertSubtable (ParentTable, Subtable);
603
604        /* Optional Device Scope subtables */
605
606        while (*PFieldList)
607        {
608            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
609                        &Subtable, FALSE);
610            if (Status == AE_NOT_FOUND)
611            {
612                break;
613            }
614
615            ParentTable = DtPeekSubtable ();
616            DtInsertSubtable (ParentTable, Subtable);
617            DtPushSubtable (Subtable);
618
619            /* Optional PCI Paths */
620
621            while (*PFieldList)
622            {
623                Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
624                            &Subtable, FALSE);
625                if (Status == AE_NOT_FOUND)
626                {
627                    DtPopSubtable ();
628                    break;
629                }
630
631                ParentTable = DtPeekSubtable ();
632                DtInsertSubtable (ParentTable, Subtable);
633            }
634        }
635
636        DtPopSubtable ();
637    }
638
639    return (AE_OK);
640}
641
642
643/******************************************************************************
644 *
645 * FUNCTION:    DtCompileEinj
646 *
647 * PARAMETERS:  List                - Current field list pointer
648 *
649 * RETURN:      Status
650 *
651 * DESCRIPTION: Compile EINJ.
652 *
653 *****************************************************************************/
654
655ACPI_STATUS
656DtCompileEinj (
657    void                    **List)
658{
659    ACPI_STATUS             Status;
660
661
662    Status = DtCompileTwoSubtables (List,
663                 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
664    return (Status);
665}
666
667
668/******************************************************************************
669 *
670 * FUNCTION:    DtCompileErst
671 *
672 * PARAMETERS:  List                - Current field list pointer
673 *
674 * RETURN:      Status
675 *
676 * DESCRIPTION: Compile ERST.
677 *
678 *****************************************************************************/
679
680ACPI_STATUS
681DtCompileErst (
682    void                    **List)
683{
684    ACPI_STATUS             Status;
685
686
687    Status = DtCompileTwoSubtables (List,
688                 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
689    return (Status);
690}
691
692
693/******************************************************************************
694 *
695 * FUNCTION:    DtCompileFadt
696 *
697 * PARAMETERS:  List                - Current field list pointer
698 *
699 * RETURN:      Status
700 *
701 * DESCRIPTION: Compile FADT.
702 *
703 *****************************************************************************/
704
705ACPI_STATUS
706DtCompileFadt (
707    void                    **List)
708{
709    ACPI_STATUS             Status;
710    DT_SUBTABLE             *Subtable;
711    DT_SUBTABLE             *ParentTable;
712    DT_FIELD                **PFieldList = (DT_FIELD **) List;
713    ACPI_TABLE_HEADER       *Table;
714    UINT8                   Revision;
715
716
717    Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
718                &Subtable, TRUE);
719    if (ACPI_FAILURE (Status))
720    {
721        return (Status);
722    }
723
724    ParentTable = DtPeekSubtable ();
725    DtInsertSubtable (ParentTable, Subtable);
726
727    Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
728    Revision = Table->Revision;
729
730    if (Revision == 2)
731    {
732        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
733                    &Subtable, TRUE);
734        if (ACPI_FAILURE (Status))
735        {
736            return (Status);
737        }
738
739        DtInsertSubtable (ParentTable, Subtable);
740    }
741    else if (Revision >= 2)
742    {
743        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
744                    &Subtable, TRUE);
745        if (ACPI_FAILURE (Status))
746        {
747            return (Status);
748        }
749
750        DtInsertSubtable (ParentTable, Subtable);
751
752        if (Revision >= 5)
753        {
754            Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
755                        &Subtable, TRUE);
756            if (ACPI_FAILURE (Status))
757            {
758                return (Status);
759            }
760
761            DtInsertSubtable (ParentTable, Subtable);
762        }
763    }
764
765    return (AE_OK);
766}
767
768
769/******************************************************************************
770 *
771 * FUNCTION:    DtCompileFpdt
772 *
773 * PARAMETERS:  List                - Current field list pointer
774 *
775 * RETURN:      Status
776 *
777 * DESCRIPTION: Compile FPDT.
778 *
779 *****************************************************************************/
780
781ACPI_STATUS
782DtCompileFpdt (
783    void                    **List)
784{
785    ACPI_STATUS             Status;
786    ACPI_FPDT_HEADER        *FpdtHeader;
787    DT_SUBTABLE             *Subtable;
788    DT_SUBTABLE             *ParentTable;
789    ACPI_DMTABLE_INFO       *InfoTable;
790    DT_FIELD                **PFieldList = (DT_FIELD **) List;
791    DT_FIELD                *SubtableStart;
792
793
794    while (*PFieldList)
795    {
796        SubtableStart = *PFieldList;
797        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
798                    &Subtable, TRUE);
799        if (ACPI_FAILURE (Status))
800        {
801            return (Status);
802        }
803
804        ParentTable = DtPeekSubtable ();
805        DtInsertSubtable (ParentTable, Subtable);
806        DtPushSubtable (Subtable);
807
808        FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
809
810        switch (FpdtHeader->Type)
811        {
812        case ACPI_FPDT_TYPE_BOOT:
813            InfoTable = AcpiDmTableInfoFpdt0;
814            break;
815
816        case ACPI_FPDT_TYPE_S3PERF:
817            InfoTable = AcpiDmTableInfoFpdt1;
818            break;
819
820        default:
821            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
822            return (AE_ERROR);
823            break;
824        }
825
826        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
827        if (ACPI_FAILURE (Status))
828        {
829            return (Status);
830        }
831
832        ParentTable = DtPeekSubtable ();
833        DtInsertSubtable (ParentTable, Subtable);
834        DtPopSubtable ();
835    }
836
837    return (AE_OK);
838}
839
840
841/******************************************************************************
842 *
843 * FUNCTION:    DtCompileHest
844 *
845 * PARAMETERS:  List                - Current field list pointer
846 *
847 * RETURN:      Status
848 *
849 * DESCRIPTION: Compile HEST.
850 *
851 *****************************************************************************/
852
853ACPI_STATUS
854DtCompileHest (
855    void                    **List)
856{
857    ACPI_STATUS             Status;
858    DT_SUBTABLE             *Subtable;
859    DT_SUBTABLE             *ParentTable;
860    DT_FIELD                **PFieldList = (DT_FIELD **) List;
861    DT_FIELD                *SubtableStart;
862    ACPI_DMTABLE_INFO       *InfoTable;
863    UINT16                  Type;
864    UINT32                  BankCount;
865
866
867    Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
868                &Subtable, TRUE);
869    if (ACPI_FAILURE (Status))
870    {
871        return (Status);
872    }
873
874    ParentTable = DtPeekSubtable ();
875    DtInsertSubtable (ParentTable, Subtable);
876
877    while (*PFieldList)
878    {
879        /* Get subtable type */
880
881        SubtableStart = *PFieldList;
882        DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
883
884        switch (Type)
885        {
886        case ACPI_HEST_TYPE_IA32_CHECK:
887            InfoTable = AcpiDmTableInfoHest0;
888            break;
889
890        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
891            InfoTable = AcpiDmTableInfoHest1;
892            break;
893
894        case ACPI_HEST_TYPE_IA32_NMI:
895            InfoTable = AcpiDmTableInfoHest2;
896            break;
897
898        case ACPI_HEST_TYPE_AER_ROOT_PORT:
899            InfoTable = AcpiDmTableInfoHest6;
900            break;
901
902        case ACPI_HEST_TYPE_AER_ENDPOINT:
903            InfoTable = AcpiDmTableInfoHest7;
904            break;
905
906        case ACPI_HEST_TYPE_AER_BRIDGE:
907            InfoTable = AcpiDmTableInfoHest8;
908            break;
909
910        case ACPI_HEST_TYPE_GENERIC_ERROR:
911            InfoTable = AcpiDmTableInfoHest9;
912            break;
913
914        default:
915            /* Cannot continue on unknown type */
916
917            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
918            return (AE_ERROR);
919        }
920
921        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
922        if (ACPI_FAILURE (Status))
923        {
924            return (Status);
925        }
926
927        DtInsertSubtable (ParentTable, Subtable);
928
929        /*
930         * Additional subtable data - IA32 Error Bank(s)
931         */
932        BankCount = 0;
933        switch (Type)
934        {
935        case ACPI_HEST_TYPE_IA32_CHECK:
936            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
937                            Subtable->Buffer))->NumHardwareBanks;
938            break;
939
940        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
941            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
942                            Subtable->Buffer))->NumHardwareBanks;
943            break;
944
945        default:
946            break;
947        }
948
949        while (BankCount)
950        {
951            Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
952                        &Subtable, TRUE);
953            if (ACPI_FAILURE (Status))
954            {
955                return (Status);
956            }
957
958            DtInsertSubtable (ParentTable, Subtable);
959            BankCount--;
960        }
961    }
962
963    return (AE_OK);
964}
965
966
967/******************************************************************************
968 *
969 * FUNCTION:    DtCompileIvrs
970 *
971 * PARAMETERS:  List                - Current field list pointer
972 *
973 * RETURN:      Status
974 *
975 * DESCRIPTION: Compile IVRS.
976 *
977 *****************************************************************************/
978
979ACPI_STATUS
980DtCompileIvrs (
981    void                    **List)
982{
983    ACPI_STATUS             Status;
984    DT_SUBTABLE             *Subtable;
985    DT_SUBTABLE             *ParentTable;
986    DT_FIELD                **PFieldList = (DT_FIELD **) List;
987    DT_FIELD                *SubtableStart;
988    ACPI_DMTABLE_INFO       *InfoTable;
989    ACPI_IVRS_HEADER        *IvrsHeader;
990    UINT8                   EntryType;
991
992
993    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
994                &Subtable, TRUE);
995    if (ACPI_FAILURE (Status))
996    {
997        return (Status);
998    }
999
1000    ParentTable = DtPeekSubtable ();
1001    DtInsertSubtable (ParentTable, Subtable);
1002
1003    while (*PFieldList)
1004    {
1005        SubtableStart = *PFieldList;
1006        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1007                    &Subtable, TRUE);
1008        if (ACPI_FAILURE (Status))
1009        {
1010            return (Status);
1011        }
1012
1013        ParentTable = DtPeekSubtable ();
1014        DtInsertSubtable (ParentTable, Subtable);
1015        DtPushSubtable (Subtable);
1016
1017        IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1018
1019        switch (IvrsHeader->Type)
1020        {
1021        case ACPI_IVRS_TYPE_HARDWARE:
1022            InfoTable = AcpiDmTableInfoIvrs0;
1023            break;
1024
1025        case ACPI_IVRS_TYPE_MEMORY1:
1026        case ACPI_IVRS_TYPE_MEMORY2:
1027        case ACPI_IVRS_TYPE_MEMORY3:
1028            InfoTable = AcpiDmTableInfoIvrs1;
1029            break;
1030
1031        default:
1032            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1033            return (AE_ERROR);
1034        }
1035
1036        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1037        if (ACPI_FAILURE (Status))
1038        {
1039            return (Status);
1040        }
1041
1042        ParentTable = DtPeekSubtable ();
1043        DtInsertSubtable (ParentTable, Subtable);
1044
1045        if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1046        {
1047            while (*PFieldList &&
1048                    !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1049            {
1050                SubtableStart = *PFieldList;
1051                DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1052
1053                switch (EntryType)
1054                {
1055                /* 4-byte device entries */
1056
1057                case ACPI_IVRS_TYPE_PAD4:
1058                case ACPI_IVRS_TYPE_ALL:
1059                case ACPI_IVRS_TYPE_SELECT:
1060                case ACPI_IVRS_TYPE_START:
1061                case ACPI_IVRS_TYPE_END:
1062
1063                    InfoTable = AcpiDmTableInfoIvrs4;
1064                    break;
1065
1066                /* 8-byte entries, type A */
1067
1068                case ACPI_IVRS_TYPE_ALIAS_SELECT:
1069                case ACPI_IVRS_TYPE_ALIAS_START:
1070
1071                    InfoTable = AcpiDmTableInfoIvrs8a;
1072                    break;
1073
1074                /* 8-byte entries, type B */
1075
1076                case ACPI_IVRS_TYPE_PAD8:
1077                case ACPI_IVRS_TYPE_EXT_SELECT:
1078                case ACPI_IVRS_TYPE_EXT_START:
1079
1080                    InfoTable = AcpiDmTableInfoIvrs8b;
1081                    break;
1082
1083                /* 8-byte entries, type C */
1084
1085                case ACPI_IVRS_TYPE_SPECIAL:
1086
1087                    InfoTable = AcpiDmTableInfoIvrs8c;
1088                    break;
1089
1090                default:
1091                    DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1092                        "IVRS Device Entry");
1093                    return (AE_ERROR);
1094                }
1095
1096                Status = DtCompileTable (PFieldList, InfoTable,
1097                            &Subtable, TRUE);
1098                if (ACPI_FAILURE (Status))
1099                {
1100                    return (Status);
1101                }
1102
1103                DtInsertSubtable (ParentTable, Subtable);
1104            }
1105        }
1106
1107        DtPopSubtable ();
1108    }
1109
1110    return (AE_OK);
1111}
1112
1113
1114/******************************************************************************
1115 *
1116 * FUNCTION:    DtCompileMadt
1117 *
1118 * PARAMETERS:  List                - Current field list pointer
1119 *
1120 * RETURN:      Status
1121 *
1122 * DESCRIPTION: Compile MADT.
1123 *
1124 *****************************************************************************/
1125
1126ACPI_STATUS
1127DtCompileMadt (
1128    void                    **List)
1129{
1130    ACPI_STATUS             Status;
1131    DT_SUBTABLE             *Subtable;
1132    DT_SUBTABLE             *ParentTable;
1133    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1134    DT_FIELD                *SubtableStart;
1135    ACPI_SUBTABLE_HEADER    *MadtHeader;
1136    ACPI_DMTABLE_INFO       *InfoTable;
1137
1138
1139    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1140                &Subtable, TRUE);
1141    if (ACPI_FAILURE (Status))
1142    {
1143        return (Status);
1144    }
1145
1146    ParentTable = DtPeekSubtable ();
1147    DtInsertSubtable (ParentTable, Subtable);
1148
1149    while (*PFieldList)
1150    {
1151        SubtableStart = *PFieldList;
1152        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1153                    &Subtable, TRUE);
1154        if (ACPI_FAILURE (Status))
1155        {
1156            return (Status);
1157        }
1158
1159        ParentTable = DtPeekSubtable ();
1160        DtInsertSubtable (ParentTable, Subtable);
1161        DtPushSubtable (Subtable);
1162
1163        MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1164
1165        switch (MadtHeader->Type)
1166        {
1167        case ACPI_MADT_TYPE_LOCAL_APIC:
1168            InfoTable = AcpiDmTableInfoMadt0;
1169            break;
1170        case ACPI_MADT_TYPE_IO_APIC:
1171            InfoTable = AcpiDmTableInfoMadt1;
1172            break;
1173        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1174            InfoTable = AcpiDmTableInfoMadt2;
1175            break;
1176        case ACPI_MADT_TYPE_NMI_SOURCE:
1177            InfoTable = AcpiDmTableInfoMadt3;
1178            break;
1179        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1180            InfoTable = AcpiDmTableInfoMadt4;
1181            break;
1182        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1183            InfoTable = AcpiDmTableInfoMadt5;
1184            break;
1185        case ACPI_MADT_TYPE_IO_SAPIC:
1186            InfoTable = AcpiDmTableInfoMadt6;
1187            break;
1188        case ACPI_MADT_TYPE_LOCAL_SAPIC:
1189            InfoTable = AcpiDmTableInfoMadt7;
1190            break;
1191        case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1192            InfoTable = AcpiDmTableInfoMadt8;
1193            break;
1194        case ACPI_MADT_TYPE_LOCAL_X2APIC:
1195            InfoTable = AcpiDmTableInfoMadt9;
1196            break;
1197        case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1198            InfoTable = AcpiDmTableInfoMadt10;
1199            break;
1200        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1201            InfoTable = AcpiDmTableInfoMadt11;
1202            break;
1203        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1204            InfoTable = AcpiDmTableInfoMadt12;
1205            break;
1206        default:
1207            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1208            return (AE_ERROR);
1209        }
1210
1211        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1212        if (ACPI_FAILURE (Status))
1213        {
1214            return (Status);
1215        }
1216
1217        ParentTable = DtPeekSubtable ();
1218        DtInsertSubtable (ParentTable, Subtable);
1219        DtPopSubtable ();
1220    }
1221
1222    return (AE_OK);
1223}
1224
1225
1226/******************************************************************************
1227 *
1228 * FUNCTION:    DtCompileMcfg
1229 *
1230 * PARAMETERS:  List                - Current field list pointer
1231 *
1232 * RETURN:      Status
1233 *
1234 * DESCRIPTION: Compile MCFG.
1235 *
1236 *****************************************************************************/
1237
1238ACPI_STATUS
1239DtCompileMcfg (
1240    void                    **List)
1241{
1242    ACPI_STATUS             Status;
1243
1244
1245    Status = DtCompileTwoSubtables (List,
1246                 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1247    return (Status);
1248}
1249
1250
1251/******************************************************************************
1252 *
1253 * FUNCTION:    DtCompileMpst
1254 *
1255 * PARAMETERS:  List                - Current field list pointer
1256 *
1257 * RETURN:      Status
1258 *
1259 * DESCRIPTION: Compile MPST.
1260 *
1261 *****************************************************************************/
1262
1263ACPI_STATUS
1264DtCompileMpst (
1265    void                    **List)
1266{
1267    ACPI_STATUS             Status;
1268    DT_SUBTABLE             *Subtable;
1269    DT_SUBTABLE             *ParentTable;
1270    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1271    ACPI_MPST_CHANNEL       *MpstChannelInfo;
1272    ACPI_MPST_POWER_NODE    *MpstPowerNode;
1273    ACPI_MPST_DATA_HDR      *MpstDataHeader;
1274    UINT16                  SubtableCount;
1275    UINT32                  PowerStateCount;
1276    UINT32                  ComponentCount;
1277
1278
1279    /* Main table */
1280
1281    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1282    if (ACPI_FAILURE (Status))
1283    {
1284        return (Status);
1285    }
1286
1287    ParentTable = DtPeekSubtable ();
1288    DtInsertSubtable (ParentTable, Subtable);
1289    DtPushSubtable (Subtable);
1290
1291    MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1292    SubtableCount = MpstChannelInfo->PowerNodeCount;
1293
1294    while (*PFieldList && SubtableCount)
1295    {
1296        /* Subtable: Memory Power Node(s) */
1297
1298        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1299                    &Subtable, TRUE);
1300        if (ACPI_FAILURE (Status))
1301        {
1302            return (Status);
1303        }
1304
1305        ParentTable = DtPeekSubtable ();
1306        DtInsertSubtable (ParentTable, Subtable);
1307        DtPushSubtable (Subtable);
1308
1309        MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1310        PowerStateCount = MpstPowerNode->NumPowerStates;
1311        ComponentCount = MpstPowerNode->NumPhysicalComponents;
1312
1313        ParentTable = DtPeekSubtable ();
1314
1315        /* Sub-subtables - Memory Power State Structure(s) */
1316
1317        while (*PFieldList && PowerStateCount)
1318        {
1319            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1320                        &Subtable, TRUE);
1321            if (ACPI_FAILURE (Status))
1322            {
1323                return (Status);
1324            }
1325
1326            DtInsertSubtable (ParentTable, Subtable);
1327            PowerStateCount--;
1328        }
1329
1330        /* Sub-subtables - Physical Component ID Structure(s) */
1331
1332        while (*PFieldList && ComponentCount)
1333        {
1334            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1335                        &Subtable, TRUE);
1336            if (ACPI_FAILURE (Status))
1337            {
1338                return (Status);
1339            }
1340
1341            DtInsertSubtable (ParentTable, Subtable);
1342            ComponentCount--;
1343        }
1344
1345        SubtableCount--;
1346        DtPopSubtable ();
1347    }
1348
1349    /* Subtable: Count of Memory Power State Characteristic structures */
1350
1351    DtPopSubtable ();
1352
1353    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1354    if (ACPI_FAILURE (Status))
1355    {
1356        return (Status);
1357    }
1358
1359    ParentTable = DtPeekSubtable ();
1360    DtInsertSubtable (ParentTable, Subtable);
1361    DtPushSubtable (Subtable);
1362
1363    MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1364    SubtableCount = MpstDataHeader->CharacteristicsCount;
1365
1366    ParentTable = DtPeekSubtable ();
1367
1368    /* Subtable: Memory Power State Characteristics structure(s) */
1369
1370    while (*PFieldList && SubtableCount)
1371    {
1372        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1373                    &Subtable, TRUE);
1374        if (ACPI_FAILURE (Status))
1375        {
1376            return (Status);
1377        }
1378
1379        DtInsertSubtable (ParentTable, Subtable);
1380        SubtableCount--;
1381    }
1382
1383    DtPopSubtable ();
1384    return (AE_OK);
1385}
1386
1387
1388/******************************************************************************
1389 *
1390 * FUNCTION:    DtCompileMsct
1391 *
1392 * PARAMETERS:  List                - Current field list pointer
1393 *
1394 * RETURN:      Status
1395 *
1396 * DESCRIPTION: Compile MSCT.
1397 *
1398 *****************************************************************************/
1399
1400ACPI_STATUS
1401DtCompileMsct (
1402    void                    **List)
1403{
1404    ACPI_STATUS             Status;
1405
1406
1407    Status = DtCompileTwoSubtables (List,
1408                 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1409    return (Status);
1410}
1411
1412
1413/******************************************************************************
1414 *
1415 * FUNCTION:    DtCompilePmtt
1416 *
1417 * PARAMETERS:  List                - Current field list pointer
1418 *
1419 * RETURN:      Status
1420 *
1421 * DESCRIPTION: Compile PMTT.
1422 *
1423 *****************************************************************************/
1424
1425ACPI_STATUS
1426DtCompilePmtt (
1427    void                    **List)
1428{
1429    ACPI_STATUS             Status;
1430    DT_SUBTABLE             *Subtable;
1431    DT_SUBTABLE             *ParentTable;
1432    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1433    DT_FIELD                *SubtableStart;
1434    ACPI_PMTT_HEADER        *PmttHeader;
1435    ACPI_PMTT_CONTROLLER    *PmttController;
1436    UINT16                  DomainCount;
1437    UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1438
1439
1440    /* Main table */
1441
1442    Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1443    if (ACPI_FAILURE (Status))
1444    {
1445        return (Status);
1446    }
1447
1448    ParentTable = DtPeekSubtable ();
1449    DtInsertSubtable (ParentTable, Subtable);
1450    DtPushSubtable (Subtable);
1451
1452    while (*PFieldList)
1453    {
1454        SubtableStart = *PFieldList;
1455        Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
1456                    &Subtable, TRUE);
1457        if (ACPI_FAILURE (Status))
1458        {
1459            return (Status);
1460        }
1461
1462        PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
1463        while (PrevType >= PmttHeader->Type)
1464        {
1465            DtPopSubtable ();
1466
1467            if (PrevType == ACPI_PMTT_TYPE_SOCKET)
1468            {
1469                break;
1470            }
1471            PrevType--;
1472        }
1473        PrevType = PmttHeader->Type;
1474
1475        ParentTable = DtPeekSubtable ();
1476        DtInsertSubtable (ParentTable, Subtable);
1477        DtPushSubtable (Subtable);
1478
1479        switch (PmttHeader->Type)
1480        {
1481        case ACPI_PMTT_TYPE_SOCKET:
1482
1483            /* Subtable: Socket Structure */
1484
1485            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1486                    &Subtable, TRUE);
1487            if (ACPI_FAILURE (Status))
1488            {
1489                return (Status);
1490            }
1491
1492            ParentTable = DtPeekSubtable ();
1493            DtInsertSubtable (ParentTable, Subtable);
1494            break;
1495
1496        case ACPI_PMTT_TYPE_CONTROLLER:
1497
1498            /* Subtable: Memory Controller Structure */
1499
1500            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1501                    &Subtable, TRUE);
1502            if (ACPI_FAILURE (Status))
1503            {
1504                return (Status);
1505            }
1506
1507            ParentTable = DtPeekSubtable ();
1508            DtInsertSubtable (ParentTable, Subtable);
1509
1510            PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
1511                (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
1512            DomainCount = PmttController->DomainCount;
1513
1514            while (DomainCount)
1515            {
1516                Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
1517                    &Subtable, TRUE);
1518                if (ACPI_FAILURE (Status))
1519                {
1520                    return (Status);
1521                }
1522
1523                DtInsertSubtable (ParentTable, Subtable);
1524                DomainCount--;
1525            }
1526            break;
1527
1528        case ACPI_PMTT_TYPE_DIMM:
1529
1530            /* Subtable: Physical Component Structure */
1531
1532            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1533                    &Subtable, TRUE);
1534            if (ACPI_FAILURE (Status))
1535            {
1536                return (Status);
1537            }
1538
1539            ParentTable = DtPeekSubtable ();
1540            DtInsertSubtable (ParentTable, Subtable);
1541            break;
1542
1543        default:
1544
1545            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1546            return (AE_ERROR);
1547        }
1548    }
1549
1550    return (Status);
1551}
1552
1553
1554/******************************************************************************
1555 *
1556 * FUNCTION:    DtCompileRsdt
1557 *
1558 * PARAMETERS:  List                - Current field list pointer
1559 *
1560 * RETURN:      Status
1561 *
1562 * DESCRIPTION: Compile RSDT.
1563 *
1564 *****************************************************************************/
1565
1566ACPI_STATUS
1567DtCompileRsdt (
1568    void                    **List)
1569{
1570    DT_SUBTABLE             *Subtable;
1571    DT_SUBTABLE             *ParentTable;
1572    DT_FIELD                *FieldList = *(DT_FIELD **) List;
1573    UINT32                  Address;
1574
1575
1576    ParentTable = DtPeekSubtable ();
1577
1578    while (FieldList)
1579    {
1580        DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1581
1582        DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1583        DtInsertSubtable (ParentTable, Subtable);
1584        FieldList = FieldList->Next;
1585    }
1586
1587    return (AE_OK);
1588}
1589
1590
1591/******************************************************************************
1592 *
1593 * FUNCTION:    DtCompileS3pt
1594 *
1595 * PARAMETERS:  PFieldList          - Current field list pointer
1596 *
1597 * RETURN:      Status
1598 *
1599 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1600 *
1601 *****************************************************************************/
1602
1603ACPI_STATUS
1604DtCompileS3pt (
1605    DT_FIELD                **PFieldList)
1606{
1607    ACPI_STATUS             Status;
1608    ACPI_S3PT_HEADER        *S3ptHeader;
1609    DT_SUBTABLE             *Subtable;
1610    DT_SUBTABLE             *ParentTable;
1611    ACPI_DMTABLE_INFO       *InfoTable;
1612    DT_FIELD                *SubtableStart;
1613
1614
1615    Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1616                &Gbl_RootTable, TRUE);
1617    if (ACPI_FAILURE (Status))
1618    {
1619        return (Status);
1620    }
1621
1622    DtPushSubtable (Gbl_RootTable);
1623
1624    while (*PFieldList)
1625    {
1626        SubtableStart = *PFieldList;
1627        Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1628                    &Subtable, TRUE);
1629        if (ACPI_FAILURE (Status))
1630        {
1631            return (Status);
1632        }
1633
1634        ParentTable = DtPeekSubtable ();
1635        DtInsertSubtable (ParentTable, Subtable);
1636        DtPushSubtable (Subtable);
1637
1638        S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
1639
1640        switch (S3ptHeader->Type)
1641        {
1642        case ACPI_S3PT_TYPE_RESUME:
1643            InfoTable = AcpiDmTableInfoS3pt0;
1644            break;
1645
1646        case ACPI_S3PT_TYPE_SUSPEND:
1647            InfoTable = AcpiDmTableInfoS3pt1;
1648            break;
1649
1650        default:
1651            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1652            return (AE_ERROR);
1653        }
1654
1655        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1656        if (ACPI_FAILURE (Status))
1657        {
1658            return (Status);
1659        }
1660
1661        ParentTable = DtPeekSubtable ();
1662        DtInsertSubtable (ParentTable, Subtable);
1663        DtPopSubtable ();
1664    }
1665
1666    return (AE_OK);
1667}
1668
1669
1670/******************************************************************************
1671 *
1672 * FUNCTION:    DtCompileSlic
1673 *
1674 * PARAMETERS:  List                - Current field list pointer
1675 *
1676 * RETURN:      Status
1677 *
1678 * DESCRIPTION: Compile SLIC.
1679 *
1680 *****************************************************************************/
1681
1682ACPI_STATUS
1683DtCompileSlic (
1684    void                    **List)
1685{
1686    ACPI_STATUS             Status;
1687    DT_SUBTABLE             *Subtable;
1688    DT_SUBTABLE             *ParentTable;
1689    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1690    DT_FIELD                *SubtableStart;
1691    ACPI_SLIC_HEADER        *SlicHeader;
1692    ACPI_DMTABLE_INFO       *InfoTable;
1693
1694
1695    while (*PFieldList)
1696    {
1697        SubtableStart = *PFieldList;
1698        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
1699                    &Subtable, TRUE);
1700        if (ACPI_FAILURE (Status))
1701        {
1702            return (Status);
1703        }
1704
1705        ParentTable = DtPeekSubtable ();
1706        DtInsertSubtable (ParentTable, Subtable);
1707        DtPushSubtable (Subtable);
1708
1709        SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
1710
1711        switch (SlicHeader->Type)
1712        {
1713        case ACPI_SLIC_TYPE_PUBLIC_KEY:
1714            InfoTable = AcpiDmTableInfoSlic0;
1715            break;
1716        case ACPI_SLIC_TYPE_WINDOWS_MARKER:
1717            InfoTable = AcpiDmTableInfoSlic1;
1718            break;
1719        default:
1720            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
1721            return (AE_ERROR);
1722        }
1723
1724        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1725        if (ACPI_FAILURE (Status))
1726        {
1727            return (Status);
1728        }
1729
1730        ParentTable = DtPeekSubtable ();
1731        DtInsertSubtable (ParentTable, Subtable);
1732        DtPopSubtable ();
1733    }
1734
1735    return (AE_OK);
1736}
1737
1738
1739/******************************************************************************
1740 *
1741 * FUNCTION:    DtCompileSlit
1742 *
1743 * PARAMETERS:  List                - Current field list pointer
1744 *
1745 * RETURN:      Status
1746 *
1747 * DESCRIPTION: Compile SLIT.
1748 *
1749 *****************************************************************************/
1750
1751ACPI_STATUS
1752DtCompileSlit (
1753    void                    **List)
1754{
1755    ACPI_STATUS             Status;
1756    DT_SUBTABLE             *Subtable;
1757    DT_SUBTABLE             *ParentTable;
1758    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1759    DT_FIELD                *FieldList;
1760    UINT32                  Localities;
1761    UINT8                   *LocalityBuffer;
1762
1763
1764    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1765                &Subtable, TRUE);
1766    if (ACPI_FAILURE (Status))
1767    {
1768        return (Status);
1769    }
1770
1771    ParentTable = DtPeekSubtable ();
1772    DtInsertSubtable (ParentTable, Subtable);
1773
1774    Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1775    LocalityBuffer = UtLocalCalloc (Localities);
1776
1777    /* Compile each locality buffer */
1778
1779    FieldList = *PFieldList;
1780    while (FieldList)
1781    {
1782        DtCompileBuffer (LocalityBuffer,
1783            FieldList->Value, FieldList, Localities);
1784
1785        DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1786        DtInsertSubtable (ParentTable, Subtable);
1787        FieldList = FieldList->Next;
1788    }
1789
1790    ACPI_FREE (LocalityBuffer);
1791    return (AE_OK);
1792}
1793
1794
1795/******************************************************************************
1796 *
1797 * FUNCTION:    DtCompileSrat
1798 *
1799 * PARAMETERS:  List                - Current field list pointer
1800 *
1801 * RETURN:      Status
1802 *
1803 * DESCRIPTION: Compile SRAT.
1804 *
1805 *****************************************************************************/
1806
1807ACPI_STATUS
1808DtCompileSrat (
1809    void                    **List)
1810{
1811    ACPI_STATUS             Status;
1812    DT_SUBTABLE             *Subtable;
1813    DT_SUBTABLE             *ParentTable;
1814    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1815    DT_FIELD                *SubtableStart;
1816    ACPI_SUBTABLE_HEADER    *SratHeader;
1817    ACPI_DMTABLE_INFO       *InfoTable;
1818
1819
1820    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1821                &Subtable, TRUE);
1822    if (ACPI_FAILURE (Status))
1823    {
1824        return (Status);
1825    }
1826
1827    ParentTable = DtPeekSubtable ();
1828    DtInsertSubtable (ParentTable, Subtable);
1829
1830    while (*PFieldList)
1831    {
1832        SubtableStart = *PFieldList;
1833        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1834                    &Subtable, TRUE);
1835        if (ACPI_FAILURE (Status))
1836        {
1837            return (Status);
1838        }
1839
1840        ParentTable = DtPeekSubtable ();
1841        DtInsertSubtable (ParentTable, Subtable);
1842        DtPushSubtable (Subtable);
1843
1844        SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1845
1846        switch (SratHeader->Type)
1847        {
1848        case ACPI_SRAT_TYPE_CPU_AFFINITY:
1849            InfoTable = AcpiDmTableInfoSrat0;
1850            break;
1851        case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1852            InfoTable = AcpiDmTableInfoSrat1;
1853            break;
1854        case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1855            InfoTable = AcpiDmTableInfoSrat2;
1856            break;
1857        default:
1858            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1859            return (AE_ERROR);
1860        }
1861
1862        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1863        if (ACPI_FAILURE (Status))
1864        {
1865            return (Status);
1866        }
1867
1868        ParentTable = DtPeekSubtable ();
1869        DtInsertSubtable (ParentTable, Subtable);
1870        DtPopSubtable ();
1871    }
1872
1873    return (AE_OK);
1874}
1875
1876
1877/******************************************************************************
1878 *
1879 * FUNCTION:    DtGetGenericTableInfo
1880 *
1881 * PARAMETERS:  Name                - Generic type name
1882 *
1883 * RETURN:      Info entry
1884 *
1885 * DESCRIPTION: Obtain table info for a generic name entry
1886 *
1887 *****************************************************************************/
1888
1889ACPI_DMTABLE_INFO *
1890DtGetGenericTableInfo (
1891    char                    *Name)
1892{
1893    ACPI_DMTABLE_INFO       *Info;
1894    UINT32                  i;
1895
1896
1897    if (!Name)
1898    {
1899        return (NULL);
1900    }
1901
1902    /* Search info table for name match */
1903
1904    for (i = 0; ; i++)
1905    {
1906        Info = AcpiDmTableInfoGeneric[i];
1907        if (Info->Opcode == ACPI_DMT_EXIT)
1908        {
1909            Info = NULL;
1910            break;
1911        }
1912
1913        /* Use caseless compare for generic keywords */
1914
1915        if (!AcpiUtStricmp (Name, Info->Name))
1916        {
1917            break;
1918        }
1919    }
1920
1921    return (Info);
1922}
1923
1924
1925/******************************************************************************
1926 *
1927 * FUNCTION:    DtCompileUefi
1928 *
1929 * PARAMETERS:  List                - Current field list pointer
1930 *
1931 * RETURN:      Status
1932 *
1933 * DESCRIPTION: Compile UEFI.
1934 *
1935 *****************************************************************************/
1936
1937ACPI_STATUS
1938DtCompileUefi (
1939    void                    **List)
1940{
1941    ACPI_STATUS             Status;
1942    DT_SUBTABLE             *Subtable;
1943    DT_SUBTABLE             *ParentTable;
1944    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1945    UINT16                  *DataOffset;
1946
1947
1948    /* Compile the predefined portion of the UEFI table */
1949
1950    Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1951                &Subtable, TRUE);
1952    if (ACPI_FAILURE (Status))
1953    {
1954        return (Status);
1955    }
1956
1957    DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1958    *DataOffset = sizeof (ACPI_TABLE_UEFI);
1959
1960    ParentTable = DtPeekSubtable ();
1961    DtInsertSubtable (ParentTable, Subtable);
1962
1963    /*
1964     * Compile the "generic" portion of the UEFI table. This
1965     * part of the table is not predefined and any of the generic
1966     * operators may be used.
1967     */
1968
1969    DtCompileGeneric ((void **) PFieldList);
1970
1971    return (AE_OK);
1972}
1973
1974
1975/******************************************************************************
1976 *
1977 * FUNCTION:    DtCompileWdat
1978 *
1979 * PARAMETERS:  List                - Current field list pointer
1980 *
1981 * RETURN:      Status
1982 *
1983 * DESCRIPTION: Compile WDAT.
1984 *
1985 *****************************************************************************/
1986
1987ACPI_STATUS
1988DtCompileWdat (
1989    void                    **List)
1990{
1991    ACPI_STATUS             Status;
1992
1993
1994    Status = DtCompileTwoSubtables (List,
1995                 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
1996    return (Status);
1997}
1998
1999
2000/******************************************************************************
2001 *
2002 * FUNCTION:    DtCompileXsdt
2003 *
2004 * PARAMETERS:  List                - Current field list pointer
2005 *
2006 * RETURN:      Status
2007 *
2008 * DESCRIPTION: Compile XSDT.
2009 *
2010 *****************************************************************************/
2011
2012ACPI_STATUS
2013DtCompileXsdt (
2014    void                    **List)
2015{
2016    DT_SUBTABLE             *Subtable;
2017    DT_SUBTABLE             *ParentTable;
2018    DT_FIELD                *FieldList = *(DT_FIELD **) List;
2019    UINT64                  Address;
2020
2021    ParentTable = DtPeekSubtable ();
2022
2023    while (FieldList)
2024    {
2025        DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2026
2027        DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2028        DtInsertSubtable (ParentTable, Subtable);
2029        FieldList = FieldList->Next;
2030    }
2031
2032    return (AE_OK);
2033}
2034
2035
2036/******************************************************************************
2037 *
2038 * FUNCTION:    DtCompileGeneric
2039 *
2040 * PARAMETERS:  List                - Current field list pointer
2041 *
2042 * RETURN:      Status
2043 *
2044 * DESCRIPTION: Compile generic unknown table.
2045 *
2046 *****************************************************************************/
2047
2048ACPI_STATUS
2049DtCompileGeneric (
2050    void                    **List)
2051{
2052    ACPI_STATUS             Status;
2053    DT_SUBTABLE             *Subtable;
2054    DT_SUBTABLE             *ParentTable;
2055    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2056    ACPI_DMTABLE_INFO       *Info;
2057
2058
2059    ParentTable = DtPeekSubtable ();
2060
2061    /*
2062     * Compile the "generic" portion of the table. This
2063     * part of the table is not predefined and any of the generic
2064     * operators may be used.
2065     */
2066
2067    /* Find any and all labels in the entire generic portion */
2068
2069    DtDetectAllLabels (*PFieldList);
2070
2071    /* Now we can actually compile the parse tree */
2072
2073    while (*PFieldList)
2074    {
2075        Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2076        if (!Info)
2077        {
2078            sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2079                (*PFieldList)->Name);
2080            DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2081                (*PFieldList), MsgBuffer);
2082
2083            *PFieldList = (*PFieldList)->Next;
2084            continue;
2085        }
2086
2087        Status = DtCompileTable (PFieldList, Info,
2088                    &Subtable, TRUE);
2089        if (ACPI_SUCCESS (Status))
2090        {
2091            DtInsertSubtable (ParentTable, Subtable);
2092        }
2093        else
2094        {
2095            *PFieldList = (*PFieldList)->Next;
2096
2097            if (Status == AE_NOT_FOUND)
2098            {
2099                sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2100                    (*PFieldList)->Name);
2101                DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2102                    (*PFieldList), MsgBuffer);
2103            }
2104        }
2105    }
2106
2107    return (AE_OK);
2108}
2109