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