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