dttable.c revision 281075
1/******************************************************************************
2 *
3 * Module Name: dttable.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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/* Compile all complex data tables */
45
46#include <contrib/dev/acpica/compiler/aslcompiler.h>
47#include <contrib/dev/acpica/compiler/dtcompiler.h>
48
49#define _COMPONENT          DT_COMPILER
50        ACPI_MODULE_NAME    ("dttable")
51
52
53/* TBD: merge these into dmtbinfo.c? */
54
55static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
56{
57    {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
58    {ACPI_DMT_EXIT,     0,               NULL, 0}
59};
60
61static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
62{
63    {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
64    {ACPI_DMT_EXIT,     0,               NULL, 0}
65};
66
67
68/* TBD: move to acmacros.h */
69
70#define ACPI_SUB_PTR(t, a, b) \
71    ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
72
73
74/* Local prototypes */
75
76static ACPI_STATUS
77DtCompileTwoSubtables (
78    void                    **List,
79    ACPI_DMTABLE_INFO       *TableInfo1,
80    ACPI_DMTABLE_INFO       *TableInfo2);
81
82
83/******************************************************************************
84 *
85 * FUNCTION:    DtCompileTwoSubtables
86 *
87 * PARAMETERS:  List                - Current field list pointer
88 *              TableInfo1          - Info table 1
89 *              TableInfo1          - Info table 2
90 *
91 * RETURN:      Status
92 *
93 * DESCRIPTION: Compile tables with a header and one or more same subtables.
94 *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
95 *
96 *****************************************************************************/
97
98static ACPI_STATUS
99DtCompileTwoSubtables (
100    void                    **List,
101    ACPI_DMTABLE_INFO       *TableInfo1,
102    ACPI_DMTABLE_INFO       *TableInfo2)
103{
104    ACPI_STATUS             Status;
105    DT_SUBTABLE             *Subtable;
106    DT_SUBTABLE             *ParentTable;
107    DT_FIELD                **PFieldList = (DT_FIELD **) List;
108
109
110    Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
111    if (ACPI_FAILURE (Status))
112    {
113        return (Status);
114    }
115
116    ParentTable = DtPeekSubtable ();
117    DtInsertSubtable (ParentTable, Subtable);
118
119    while (*PFieldList)
120    {
121        Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
122        if (ACPI_FAILURE (Status))
123        {
124            return (Status);
125        }
126
127        DtInsertSubtable (ParentTable, Subtable);
128    }
129
130    return (AE_OK);
131}
132
133
134/******************************************************************************
135 *
136 * FUNCTION:    DtCompileFacs
137 *
138 * PARAMETERS:  PFieldList          - Current field list pointer
139 *
140 * RETURN:      Status
141 *
142 * DESCRIPTION: Compile FACS.
143 *
144 *****************************************************************************/
145
146ACPI_STATUS
147DtCompileFacs (
148    DT_FIELD                **PFieldList)
149{
150    DT_SUBTABLE             *Subtable;
151    UINT8                   *ReservedBuffer;
152    ACPI_STATUS             Status;
153    UINT32                  ReservedSize;
154
155
156    Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
157                &Gbl_RootTable, TRUE);
158    if (ACPI_FAILURE (Status))
159    {
160        return (Status);
161    }
162
163    /* Large FACS reserved area at the end of the table */
164
165    ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
166    ReservedBuffer = UtLocalCalloc (ReservedSize);
167
168    DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
169
170    ACPI_FREE (ReservedBuffer);
171    DtInsertSubtable (Gbl_RootTable, Subtable);
172    return (AE_OK);
173}
174
175
176/******************************************************************************
177 *
178 * FUNCTION:    DtCompileRsdp
179 *
180 * PARAMETERS:  PFieldList          - Current field list pointer
181 *
182 * RETURN:      Status
183 *
184 * DESCRIPTION: Compile RSDP.
185 *
186 *****************************************************************************/
187
188ACPI_STATUS
189DtCompileRsdp (
190    DT_FIELD                **PFieldList)
191{
192    DT_SUBTABLE             *Subtable;
193    ACPI_TABLE_RSDP         *Rsdp;
194    ACPI_RSDP_EXTENSION     *RsdpExtension;
195    ACPI_STATUS             Status;
196
197
198    /* Compile the "common" RSDP (ACPI 1.0) */
199
200    Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
201                &Gbl_RootTable, TRUE);
202    if (ACPI_FAILURE (Status))
203    {
204        return (Status);
205    }
206
207    Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
208    DtSetTableChecksum (&Rsdp->Checksum);
209
210    if (Rsdp->Revision > 0)
211    {
212        /* Compile the "extended" part of the RSDP as a subtable */
213
214        Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
215                    &Subtable, TRUE);
216        if (ACPI_FAILURE (Status))
217        {
218            return (Status);
219        }
220
221        DtInsertSubtable (Gbl_RootTable, Subtable);
222
223        /* Set length and extended checksum for entire RSDP */
224
225        RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
226        RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
227        DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
228    }
229
230    return (AE_OK);
231}
232
233
234/******************************************************************************
235 *
236 * FUNCTION:    DtCompileAsf
237 *
238 * PARAMETERS:  List                - Current field list pointer
239 *
240 * RETURN:      Status
241 *
242 * DESCRIPTION: Compile ASF!.
243 *
244 *****************************************************************************/
245
246ACPI_STATUS
247DtCompileAsf (
248    void                    **List)
249{
250    ACPI_ASF_INFO           *AsfTable;
251    DT_SUBTABLE             *Subtable;
252    DT_SUBTABLE             *ParentTable;
253    ACPI_DMTABLE_INFO       *InfoTable;
254    ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
255    UINT32                  DataCount = 0;
256    ACPI_STATUS             Status;
257    UINT32                  i;
258    DT_FIELD                **PFieldList = (DT_FIELD **) List;
259    DT_FIELD                *SubtableStart;
260
261
262    while (*PFieldList)
263    {
264        SubtableStart = *PFieldList;
265        Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
266                    &Subtable, TRUE);
267        if (ACPI_FAILURE (Status))
268        {
269            return (Status);
270        }
271
272        ParentTable = DtPeekSubtable ();
273        DtInsertSubtable (ParentTable, Subtable);
274        DtPushSubtable (Subtable);
275
276        AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
277
278        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
279        {
280        case ACPI_ASF_TYPE_INFO:
281
282            InfoTable = AcpiDmTableInfoAsf0;
283            break;
284
285        case ACPI_ASF_TYPE_ALERT:
286
287            InfoTable = AcpiDmTableInfoAsf1;
288            break;
289
290        case ACPI_ASF_TYPE_CONTROL:
291
292            InfoTable = AcpiDmTableInfoAsf2;
293            break;
294
295        case ACPI_ASF_TYPE_BOOT:
296
297            InfoTable = AcpiDmTableInfoAsf3;
298            break;
299
300        case ACPI_ASF_TYPE_ADDRESS:
301
302            InfoTable = AcpiDmTableInfoAsf4;
303            break;
304
305        default:
306
307            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
308            return (AE_ERROR);
309        }
310
311        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
312        if (ACPI_FAILURE (Status))
313        {
314            return (Status);
315        }
316
317        ParentTable = DtPeekSubtable ();
318        DtInsertSubtable (ParentTable, Subtable);
319
320        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
321        {
322        case ACPI_ASF_TYPE_INFO:
323
324            DataInfoTable = NULL;
325            break;
326
327        case ACPI_ASF_TYPE_ALERT:
328
329            DataInfoTable = AcpiDmTableInfoAsf1a;
330            DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
331                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
332                            sizeof (ACPI_ASF_HEADER)))->Alerts;
333            break;
334
335        case ACPI_ASF_TYPE_CONTROL:
336
337            DataInfoTable = AcpiDmTableInfoAsf2a;
338            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
339                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
340                            sizeof (ACPI_ASF_HEADER)))->Controls;
341            break;
342
343        case ACPI_ASF_TYPE_BOOT:
344
345            DataInfoTable = NULL;
346            break;
347
348        case ACPI_ASF_TYPE_ADDRESS:
349
350            DataInfoTable = TableInfoAsfAddress;
351            DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
352                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
353                            sizeof (ACPI_ASF_HEADER)))->Devices;
354            break;
355
356        default:
357
358            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
359            return (AE_ERROR);
360        }
361
362        if (DataInfoTable)
363        {
364            switch (AsfTable->Header.Type & 0x7F)
365            {
366            case ACPI_ASF_TYPE_ADDRESS:
367
368                while (DataCount > 0)
369                {
370                    Status = DtCompileTable (PFieldList, DataInfoTable,
371                                &Subtable, TRUE);
372                    if (ACPI_FAILURE (Status))
373                    {
374                        return (Status);
375                    }
376
377                    DtInsertSubtable (ParentTable, Subtable);
378                    DataCount = DataCount - Subtable->Length;
379                }
380                break;
381
382            default:
383
384                for (i = 0; i < DataCount; i++)
385                {
386                    Status = DtCompileTable (PFieldList, DataInfoTable,
387                                &Subtable, TRUE);
388                    if (ACPI_FAILURE (Status))
389                    {
390                        return (Status);
391                    }
392
393                    DtInsertSubtable (ParentTable, Subtable);
394                }
395                break;
396            }
397        }
398
399        DtPopSubtable ();
400    }
401
402    return (AE_OK);
403}
404
405
406/******************************************************************************
407 *
408 * FUNCTION:    DtCompileCpep
409 *
410 * PARAMETERS:  List                - Current field list pointer
411 *
412 * RETURN:      Status
413 *
414 * DESCRIPTION: Compile CPEP.
415 *
416 *****************************************************************************/
417
418ACPI_STATUS
419DtCompileCpep (
420    void                    **List)
421{
422    ACPI_STATUS             Status;
423
424
425    Status = DtCompileTwoSubtables (List,
426                 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
427    return (Status);
428}
429
430
431/******************************************************************************
432 *
433 * FUNCTION:    DtCompileCsrt
434 *
435 * PARAMETERS:  List                - Current field list pointer
436 *
437 * RETURN:      Status
438 *
439 * DESCRIPTION: Compile CSRT.
440 *
441 *****************************************************************************/
442
443ACPI_STATUS
444DtCompileCsrt (
445    void                    **List)
446{
447    ACPI_STATUS             Status = AE_OK;
448    DT_SUBTABLE             *Subtable;
449    DT_SUBTABLE             *ParentTable;
450    DT_FIELD                **PFieldList = (DT_FIELD **) List;
451    UINT32                  DescriptorCount;
452    UINT32                  GroupLength;
453
454
455    /* Subtables (Resource Groups) */
456
457    while (*PFieldList)
458    {
459        /* Resource group subtable */
460
461        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
462                    &Subtable, TRUE);
463        if (ACPI_FAILURE (Status))
464        {
465            return (Status);
466        }
467
468        /* Compute the number of resource descriptors */
469
470        GroupLength =
471            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
472                Subtable->Buffer))->Length -
473            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
474                Subtable->Buffer))->SharedInfoLength -
475            sizeof (ACPI_CSRT_GROUP);
476
477        DescriptorCount = (GroupLength  /
478            sizeof (ACPI_CSRT_DESCRIPTOR));
479
480        ParentTable = DtPeekSubtable ();
481        DtInsertSubtable (ParentTable, Subtable);
482        DtPushSubtable (Subtable);
483
484        /* Shared info subtable (One per resource group) */
485
486        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
487                    &Subtable, TRUE);
488        if (ACPI_FAILURE (Status))
489        {
490            return (Status);
491        }
492
493        ParentTable = DtPeekSubtable ();
494        DtInsertSubtable (ParentTable, Subtable);
495
496        /* Sub-Subtables (Resource Descriptors) */
497
498        while (*PFieldList && DescriptorCount)
499        {
500            Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
501                        &Subtable, TRUE);
502            if (ACPI_FAILURE (Status))
503            {
504                return (Status);
505            }
506
507            ParentTable = DtPeekSubtable ();
508            DtInsertSubtable (ParentTable, Subtable);
509            DescriptorCount--;
510        }
511
512        DtPopSubtable ();
513    }
514
515    return (Status);
516}
517
518
519/******************************************************************************
520 *
521 * FUNCTION:    DtCompileDbg2
522 *
523 * PARAMETERS:  List                - Current field list pointer
524 *
525 * RETURN:      Status
526 *
527 * DESCRIPTION: Compile DBG2.
528 *
529 *****************************************************************************/
530
531ACPI_STATUS
532DtCompileDbg2 (
533    void                    **List)
534{
535    ACPI_STATUS             Status;
536    DT_SUBTABLE             *Subtable;
537    DT_SUBTABLE             *ParentTable;
538    DT_FIELD                **PFieldList = (DT_FIELD **) List;
539    UINT32                  SubtableCount;
540    ACPI_DBG2_HEADER        *Dbg2Header;
541    ACPI_DBG2_DEVICE        *DeviceInfo;
542    UINT16                  CurrentOffset;
543    UINT32                  i;
544
545
546    /* Main table */
547
548    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
549    if (ACPI_FAILURE (Status))
550    {
551        return (Status);
552    }
553
554    ParentTable = DtPeekSubtable ();
555    DtInsertSubtable (ParentTable, Subtable);
556
557    /* Main table fields */
558
559    Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
560    Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
561        ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
562
563    SubtableCount = Dbg2Header->InfoCount;
564    DtPushSubtable (Subtable);
565
566    /* Process all Device Information subtables (Count = InfoCount) */
567
568    while (*PFieldList && SubtableCount)
569    {
570        /* Subtable: Debug Device Information */
571
572        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
573                    &Subtable, TRUE);
574        if (ACPI_FAILURE (Status))
575        {
576            return (Status);
577        }
578
579        DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
580        CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
581
582        ParentTable = DtPeekSubtable ();
583        DtInsertSubtable (ParentTable, Subtable);
584        DtPushSubtable (Subtable);
585
586        ParentTable = DtPeekSubtable ();
587
588        /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
589
590        DeviceInfo->BaseAddressOffset = CurrentOffset;
591        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
592        {
593            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
594                        &Subtable, TRUE);
595            if (ACPI_FAILURE (Status))
596            {
597                return (Status);
598            }
599
600            CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
601            DtInsertSubtable (ParentTable, Subtable);
602        }
603
604        /* AddressSize array (Required, size = RegisterCount) */
605
606        DeviceInfo->AddressSizeOffset = CurrentOffset;
607        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
608        {
609            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
610                        &Subtable, TRUE);
611            if (ACPI_FAILURE (Status))
612            {
613                return (Status);
614            }
615
616            CurrentOffset += (UINT16) sizeof (UINT32);
617            DtInsertSubtable (ParentTable, Subtable);
618        }
619
620        /* NamespaceString device identifier (Required, size = NamePathLength) */
621
622        DeviceInfo->NamepathOffset = CurrentOffset;
623        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
624                    &Subtable, TRUE);
625        if (ACPI_FAILURE (Status))
626        {
627            return (Status);
628        }
629
630        /* Update the device info header */
631
632        DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
633        CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
634        DtInsertSubtable (ParentTable, Subtable);
635
636        /* OemData - Variable-length data (Optional, size = OemDataLength) */
637
638        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
639                    &Subtable, TRUE);
640        if (ACPI_FAILURE (Status))
641        {
642            return (Status);
643        }
644
645        /* Update the device info header (zeros if no OEM data present) */
646
647        DeviceInfo->OemDataOffset = 0;
648        DeviceInfo->OemDataLength = 0;
649
650        /* Optional subtable (OemData) */
651
652        if (Subtable && Subtable->Length)
653        {
654            DeviceInfo->OemDataOffset = CurrentOffset;
655            DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
656
657            DtInsertSubtable (ParentTable, Subtable);
658        }
659
660        SubtableCount--;
661        DtPopSubtable (); /* Get next Device Information subtable */
662    }
663
664    DtPopSubtable ();
665    return (AE_OK);
666}
667
668
669/******************************************************************************
670 *
671 * FUNCTION:    DtCompileDmar
672 *
673 * PARAMETERS:  List                - Current field list pointer
674 *
675 * RETURN:      Status
676 *
677 * DESCRIPTION: Compile DMAR.
678 *
679 *****************************************************************************/
680
681ACPI_STATUS
682DtCompileDmar (
683    void                    **List)
684{
685    ACPI_STATUS             Status;
686    DT_SUBTABLE             *Subtable;
687    DT_SUBTABLE             *ParentTable;
688    DT_FIELD                **PFieldList = (DT_FIELD **) List;
689    DT_FIELD                *SubtableStart;
690    ACPI_DMTABLE_INFO       *InfoTable;
691    ACPI_DMAR_HEADER        *DmarHeader;
692    ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
693    UINT32                  DeviceScopeLength;
694    UINT32                  PciPathLength;
695
696
697    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
698    if (ACPI_FAILURE (Status))
699    {
700        return (Status);
701    }
702
703    ParentTable = DtPeekSubtable ();
704    DtInsertSubtable (ParentTable, Subtable);
705    DtPushSubtable (Subtable);
706
707    while (*PFieldList)
708    {
709        /* DMAR Header */
710
711        SubtableStart = *PFieldList;
712        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
713                    &Subtable, TRUE);
714        if (ACPI_FAILURE (Status))
715        {
716            return (Status);
717        }
718
719        ParentTable = DtPeekSubtable ();
720        DtInsertSubtable (ParentTable, Subtable);
721        DtPushSubtable (Subtable);
722
723        DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
724
725        switch (DmarHeader->Type)
726        {
727        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
728
729            InfoTable = AcpiDmTableInfoDmar0;
730            break;
731
732        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
733
734            InfoTable = AcpiDmTableInfoDmar1;
735            break;
736
737        case ACPI_DMAR_TYPE_ROOT_ATS:
738
739            InfoTable = AcpiDmTableInfoDmar2;
740            break;
741
742        case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
743
744            InfoTable = AcpiDmTableInfoDmar3;
745            break;
746
747        case ACPI_DMAR_TYPE_NAMESPACE:
748
749            InfoTable = AcpiDmTableInfoDmar4;
750            break;
751
752        default:
753
754            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
755            return (AE_ERROR);
756        }
757
758        /* DMAR Subtable */
759
760        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
761        if (ACPI_FAILURE (Status))
762        {
763            return (Status);
764        }
765
766        ParentTable = DtPeekSubtable ();
767        DtInsertSubtable (ParentTable, Subtable);
768
769        /*
770         * Optional Device Scope subtables
771         */
772        if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
773            (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
774        {
775            /* These types do not support device scopes */
776
777            DtPopSubtable ();
778            continue;
779        }
780
781        DtPushSubtable (Subtable);
782        DeviceScopeLength = DmarHeader->Length - Subtable->Length -
783            ParentTable->Length;
784        while (DeviceScopeLength)
785        {
786            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
787                        &Subtable, FALSE);
788            if (Status == AE_NOT_FOUND)
789            {
790                break;
791            }
792
793            ParentTable = DtPeekSubtable ();
794            DtInsertSubtable (ParentTable, Subtable);
795            DtPushSubtable (Subtable);
796
797            DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
798
799            /* Optional PCI Paths */
800
801            PciPathLength = DmarDeviceScope->Length - Subtable->Length;
802            while (PciPathLength)
803            {
804                Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
805                            &Subtable, FALSE);
806                if (Status == AE_NOT_FOUND)
807                {
808                    DtPopSubtable ();
809                    break;
810                }
811
812                ParentTable = DtPeekSubtable ();
813                DtInsertSubtable (ParentTable, Subtable);
814                PciPathLength -= Subtable->Length;
815            }
816
817            DtPopSubtable ();
818            DeviceScopeLength -= DmarDeviceScope->Length;
819        }
820
821        DtPopSubtable ();
822        DtPopSubtable ();
823    }
824
825    return (AE_OK);
826}
827
828
829/******************************************************************************
830 *
831 * FUNCTION:    DtCompileEinj
832 *
833 * PARAMETERS:  List                - Current field list pointer
834 *
835 * RETURN:      Status
836 *
837 * DESCRIPTION: Compile EINJ.
838 *
839 *****************************************************************************/
840
841ACPI_STATUS
842DtCompileEinj (
843    void                    **List)
844{
845    ACPI_STATUS             Status;
846
847
848    Status = DtCompileTwoSubtables (List,
849                 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
850    return (Status);
851}
852
853
854/******************************************************************************
855 *
856 * FUNCTION:    DtCompileErst
857 *
858 * PARAMETERS:  List                - Current field list pointer
859 *
860 * RETURN:      Status
861 *
862 * DESCRIPTION: Compile ERST.
863 *
864 *****************************************************************************/
865
866ACPI_STATUS
867DtCompileErst (
868    void                    **List)
869{
870    ACPI_STATUS             Status;
871
872
873    Status = DtCompileTwoSubtables (List,
874                 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
875    return (Status);
876}
877
878
879/******************************************************************************
880 *
881 * FUNCTION:    DtCompileFadt
882 *
883 * PARAMETERS:  List                - Current field list pointer
884 *
885 * RETURN:      Status
886 *
887 * DESCRIPTION: Compile FADT.
888 *
889 *****************************************************************************/
890
891ACPI_STATUS
892DtCompileFadt (
893    void                    **List)
894{
895    ACPI_STATUS             Status;
896    DT_SUBTABLE             *Subtable;
897    DT_SUBTABLE             *ParentTable;
898    DT_FIELD                **PFieldList = (DT_FIELD **) List;
899    ACPI_TABLE_HEADER       *Table;
900    UINT8                   Revision;
901
902
903    Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
904                &Subtable, TRUE);
905    if (ACPI_FAILURE (Status))
906    {
907        return (Status);
908    }
909
910    ParentTable = DtPeekSubtable ();
911    DtInsertSubtable (ParentTable, Subtable);
912
913    Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
914    Revision = Table->Revision;
915
916    if (Revision == 2)
917    {
918        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
919                    &Subtable, TRUE);
920        if (ACPI_FAILURE (Status))
921        {
922            return (Status);
923        }
924
925        DtInsertSubtable (ParentTable, Subtable);
926    }
927    else if (Revision >= 2)
928    {
929        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
930                    &Subtable, TRUE);
931        if (ACPI_FAILURE (Status))
932        {
933            return (Status);
934        }
935
936        DtInsertSubtable (ParentTable, Subtable);
937
938        if (Revision >= 5)
939        {
940            Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
941                        &Subtable, TRUE);
942            if (ACPI_FAILURE (Status))
943            {
944                return (Status);
945            }
946
947            DtInsertSubtable (ParentTable, Subtable);
948        }
949    }
950
951    return (AE_OK);
952}
953
954/******************************************************************************
955 *
956 * FUNCTION:    DtCompileGtdt
957 *
958 * PARAMETERS:  List                - Current field list pointer
959 *
960 * RETURN:      Status
961 *
962 * DESCRIPTION: Compile GTDT.
963 *
964 *****************************************************************************/
965
966ACPI_STATUS
967DtCompileGtdt (
968    void                    **List)
969{
970    ACPI_STATUS             Status;
971    DT_SUBTABLE             *Subtable;
972    DT_SUBTABLE             *ParentTable;
973    DT_FIELD                **PFieldList = (DT_FIELD **) List;
974    DT_FIELD                *SubtableStart;
975    ACPI_SUBTABLE_HEADER    *GtdtHeader;
976    ACPI_DMTABLE_INFO       *InfoTable;
977    UINT32                  GtCount;
978
979
980    Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
981                &Subtable, TRUE);
982    if (ACPI_FAILURE (Status))
983    {
984        return (Status);
985    }
986
987    ParentTable = DtPeekSubtable ();
988    DtInsertSubtable (ParentTable, Subtable);
989
990    while (*PFieldList)
991    {
992        SubtableStart = *PFieldList;
993        Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
994                    &Subtable, TRUE);
995        if (ACPI_FAILURE (Status))
996        {
997            return (Status);
998        }
999
1000        ParentTable = DtPeekSubtable ();
1001        DtInsertSubtable (ParentTable, Subtable);
1002        DtPushSubtable (Subtable);
1003
1004        GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1005
1006        switch (GtdtHeader->Type)
1007        {
1008        case ACPI_GTDT_TYPE_TIMER_BLOCK:
1009
1010            InfoTable = AcpiDmTableInfoGtdt0;
1011            break;
1012
1013        case ACPI_GTDT_TYPE_WATCHDOG:
1014
1015            InfoTable = AcpiDmTableInfoGtdt1;
1016            break;
1017
1018        default:
1019
1020            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1021            return (AE_ERROR);
1022        }
1023
1024        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1025        if (ACPI_FAILURE (Status))
1026        {
1027            return (Status);
1028        }
1029
1030        ParentTable = DtPeekSubtable ();
1031        DtInsertSubtable (ParentTable, Subtable);
1032
1033        /*
1034         * Additional GT block subtable data
1035         */
1036
1037        switch (GtdtHeader->Type)
1038        {
1039        case ACPI_GTDT_TYPE_TIMER_BLOCK:
1040
1041            DtPushSubtable (Subtable);
1042            ParentTable = DtPeekSubtable ();
1043
1044            GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1045                Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1046            while (GtCount)
1047            {
1048                Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1049                            &Subtable, TRUE);
1050                if (ACPI_FAILURE (Status))
1051                {
1052                    return (Status);
1053                }
1054
1055
1056                DtInsertSubtable (ParentTable, Subtable);
1057                GtCount--;
1058            }
1059            DtPopSubtable ();
1060            break;
1061
1062        default:
1063
1064            break;
1065        }
1066
1067        DtPopSubtable ();
1068    }
1069
1070    return (AE_OK);
1071}
1072
1073
1074/******************************************************************************
1075 *
1076 * FUNCTION:    DtCompileFpdt
1077 *
1078 * PARAMETERS:  List                - Current field list pointer
1079 *
1080 * RETURN:      Status
1081 *
1082 * DESCRIPTION: Compile FPDT.
1083 *
1084 *****************************************************************************/
1085
1086ACPI_STATUS
1087DtCompileFpdt (
1088    void                    **List)
1089{
1090    ACPI_STATUS             Status;
1091    ACPI_FPDT_HEADER        *FpdtHeader;
1092    DT_SUBTABLE             *Subtable;
1093    DT_SUBTABLE             *ParentTable;
1094    ACPI_DMTABLE_INFO       *InfoTable;
1095    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1096    DT_FIELD                *SubtableStart;
1097
1098
1099    while (*PFieldList)
1100    {
1101        SubtableStart = *PFieldList;
1102        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1103                    &Subtable, TRUE);
1104        if (ACPI_FAILURE (Status))
1105        {
1106            return (Status);
1107        }
1108
1109        ParentTable = DtPeekSubtable ();
1110        DtInsertSubtable (ParentTable, Subtable);
1111        DtPushSubtable (Subtable);
1112
1113        FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1114
1115        switch (FpdtHeader->Type)
1116        {
1117        case ACPI_FPDT_TYPE_BOOT:
1118
1119            InfoTable = AcpiDmTableInfoFpdt0;
1120            break;
1121
1122        case ACPI_FPDT_TYPE_S3PERF:
1123
1124            InfoTable = AcpiDmTableInfoFpdt1;
1125            break;
1126
1127        default:
1128
1129            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1130            return (AE_ERROR);
1131            break;
1132        }
1133
1134        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1135        if (ACPI_FAILURE (Status))
1136        {
1137            return (Status);
1138        }
1139
1140        ParentTable = DtPeekSubtable ();
1141        DtInsertSubtable (ParentTable, Subtable);
1142        DtPopSubtable ();
1143    }
1144
1145    return (AE_OK);
1146}
1147
1148
1149/******************************************************************************
1150 *
1151 * FUNCTION:    DtCompileHest
1152 *
1153 * PARAMETERS:  List                - Current field list pointer
1154 *
1155 * RETURN:      Status
1156 *
1157 * DESCRIPTION: Compile HEST.
1158 *
1159 *****************************************************************************/
1160
1161ACPI_STATUS
1162DtCompileHest (
1163    void                    **List)
1164{
1165    ACPI_STATUS             Status;
1166    DT_SUBTABLE             *Subtable;
1167    DT_SUBTABLE             *ParentTable;
1168    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1169    DT_FIELD                *SubtableStart;
1170    ACPI_DMTABLE_INFO       *InfoTable;
1171    UINT16                  Type;
1172    UINT32                  BankCount;
1173
1174
1175    Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1176                &Subtable, TRUE);
1177    if (ACPI_FAILURE (Status))
1178    {
1179        return (Status);
1180    }
1181
1182    ParentTable = DtPeekSubtable ();
1183    DtInsertSubtable (ParentTable, Subtable);
1184
1185    while (*PFieldList)
1186    {
1187        /* Get subtable type */
1188
1189        SubtableStart = *PFieldList;
1190        DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1191
1192        switch (Type)
1193        {
1194        case ACPI_HEST_TYPE_IA32_CHECK:
1195
1196            InfoTable = AcpiDmTableInfoHest0;
1197            break;
1198
1199        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1200
1201            InfoTable = AcpiDmTableInfoHest1;
1202            break;
1203
1204        case ACPI_HEST_TYPE_IA32_NMI:
1205
1206            InfoTable = AcpiDmTableInfoHest2;
1207            break;
1208
1209        case ACPI_HEST_TYPE_AER_ROOT_PORT:
1210
1211            InfoTable = AcpiDmTableInfoHest6;
1212            break;
1213
1214        case ACPI_HEST_TYPE_AER_ENDPOINT:
1215
1216            InfoTable = AcpiDmTableInfoHest7;
1217            break;
1218
1219        case ACPI_HEST_TYPE_AER_BRIDGE:
1220
1221            InfoTable = AcpiDmTableInfoHest8;
1222            break;
1223
1224        case ACPI_HEST_TYPE_GENERIC_ERROR:
1225
1226            InfoTable = AcpiDmTableInfoHest9;
1227            break;
1228
1229        default:
1230
1231            /* Cannot continue on unknown type */
1232
1233            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1234            return (AE_ERROR);
1235        }
1236
1237        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1238        if (ACPI_FAILURE (Status))
1239        {
1240            return (Status);
1241        }
1242
1243        DtInsertSubtable (ParentTable, Subtable);
1244
1245        /*
1246         * Additional subtable data - IA32 Error Bank(s)
1247         */
1248        BankCount = 0;
1249        switch (Type)
1250        {
1251        case ACPI_HEST_TYPE_IA32_CHECK:
1252
1253            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1254                            Subtable->Buffer))->NumHardwareBanks;
1255            break;
1256
1257        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1258
1259            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1260                            Subtable->Buffer))->NumHardwareBanks;
1261            break;
1262
1263        default:
1264
1265            break;
1266        }
1267
1268        while (BankCount)
1269        {
1270            Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1271                        &Subtable, TRUE);
1272            if (ACPI_FAILURE (Status))
1273            {
1274                return (Status);
1275            }
1276
1277            DtInsertSubtable (ParentTable, Subtable);
1278            BankCount--;
1279        }
1280    }
1281
1282    return (AE_OK);
1283}
1284
1285
1286/******************************************************************************
1287 *
1288 * FUNCTION:    DtCompileIvrs
1289 *
1290 * PARAMETERS:  List                - Current field list pointer
1291 *
1292 * RETURN:      Status
1293 *
1294 * DESCRIPTION: Compile IVRS.
1295 *
1296 *****************************************************************************/
1297
1298ACPI_STATUS
1299DtCompileIvrs (
1300    void                    **List)
1301{
1302    ACPI_STATUS             Status;
1303    DT_SUBTABLE             *Subtable;
1304    DT_SUBTABLE             *ParentTable;
1305    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1306    DT_FIELD                *SubtableStart;
1307    ACPI_DMTABLE_INFO       *InfoTable;
1308    ACPI_IVRS_HEADER        *IvrsHeader;
1309    UINT8                   EntryType;
1310
1311
1312    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1313                &Subtable, TRUE);
1314    if (ACPI_FAILURE (Status))
1315    {
1316        return (Status);
1317    }
1318
1319    ParentTable = DtPeekSubtable ();
1320    DtInsertSubtable (ParentTable, Subtable);
1321
1322    while (*PFieldList)
1323    {
1324        SubtableStart = *PFieldList;
1325        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1326                    &Subtable, TRUE);
1327        if (ACPI_FAILURE (Status))
1328        {
1329            return (Status);
1330        }
1331
1332        ParentTable = DtPeekSubtable ();
1333        DtInsertSubtable (ParentTable, Subtable);
1334        DtPushSubtable (Subtable);
1335
1336        IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1337
1338        switch (IvrsHeader->Type)
1339        {
1340        case ACPI_IVRS_TYPE_HARDWARE:
1341
1342            InfoTable = AcpiDmTableInfoIvrs0;
1343            break;
1344
1345        case ACPI_IVRS_TYPE_MEMORY1:
1346        case ACPI_IVRS_TYPE_MEMORY2:
1347        case ACPI_IVRS_TYPE_MEMORY3:
1348
1349            InfoTable = AcpiDmTableInfoIvrs1;
1350            break;
1351
1352        default:
1353
1354            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1355            return (AE_ERROR);
1356        }
1357
1358        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1359        if (ACPI_FAILURE (Status))
1360        {
1361            return (Status);
1362        }
1363
1364        ParentTable = DtPeekSubtable ();
1365        DtInsertSubtable (ParentTable, Subtable);
1366
1367        if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1368        {
1369            while (*PFieldList &&
1370                    !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1371            {
1372                SubtableStart = *PFieldList;
1373                DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1374
1375                switch (EntryType)
1376                {
1377                /* 4-byte device entries */
1378
1379                case ACPI_IVRS_TYPE_PAD4:
1380                case ACPI_IVRS_TYPE_ALL:
1381                case ACPI_IVRS_TYPE_SELECT:
1382                case ACPI_IVRS_TYPE_START:
1383                case ACPI_IVRS_TYPE_END:
1384
1385                    InfoTable = AcpiDmTableInfoIvrs4;
1386                    break;
1387
1388                /* 8-byte entries, type A */
1389
1390                case ACPI_IVRS_TYPE_ALIAS_SELECT:
1391                case ACPI_IVRS_TYPE_ALIAS_START:
1392
1393                    InfoTable = AcpiDmTableInfoIvrs8a;
1394                    break;
1395
1396                /* 8-byte entries, type B */
1397
1398                case ACPI_IVRS_TYPE_PAD8:
1399                case ACPI_IVRS_TYPE_EXT_SELECT:
1400                case ACPI_IVRS_TYPE_EXT_START:
1401
1402                    InfoTable = AcpiDmTableInfoIvrs8b;
1403                    break;
1404
1405                /* 8-byte entries, type C */
1406
1407                case ACPI_IVRS_TYPE_SPECIAL:
1408
1409                    InfoTable = AcpiDmTableInfoIvrs8c;
1410                    break;
1411
1412                default:
1413
1414                    DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1415                        "IVRS Device Entry");
1416                    return (AE_ERROR);
1417                }
1418
1419                Status = DtCompileTable (PFieldList, InfoTable,
1420                            &Subtable, TRUE);
1421                if (ACPI_FAILURE (Status))
1422                {
1423                    return (Status);
1424                }
1425
1426                DtInsertSubtable (ParentTable, Subtable);
1427            }
1428        }
1429
1430        DtPopSubtable ();
1431    }
1432
1433    return (AE_OK);
1434}
1435
1436
1437/******************************************************************************
1438 *
1439 * FUNCTION:    DtCompileLpit
1440 *
1441 * PARAMETERS:  List                - Current field list pointer
1442 *
1443 * RETURN:      Status
1444 *
1445 * DESCRIPTION: Compile LPIT.
1446 *
1447 *****************************************************************************/
1448
1449ACPI_STATUS
1450DtCompileLpit (
1451    void                    **List)
1452{
1453    ACPI_STATUS             Status;
1454    DT_SUBTABLE             *Subtable;
1455    DT_SUBTABLE             *ParentTable;
1456    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1457    DT_FIELD                *SubtableStart;
1458    ACPI_DMTABLE_INFO       *InfoTable;
1459    ACPI_LPIT_HEADER        *LpitHeader;
1460
1461
1462    /* Note: Main table consists only of the standard ACPI table header */
1463
1464    while (*PFieldList)
1465    {
1466        SubtableStart = *PFieldList;
1467
1468        /* LPIT Subtable header */
1469
1470        Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1471                    &Subtable, TRUE);
1472        if (ACPI_FAILURE (Status))
1473        {
1474            return (Status);
1475        }
1476
1477        ParentTable = DtPeekSubtable ();
1478        DtInsertSubtable (ParentTable, Subtable);
1479        DtPushSubtable (Subtable);
1480
1481        LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1482
1483        switch (LpitHeader->Type)
1484        {
1485        case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1486
1487            InfoTable = AcpiDmTableInfoLpit0;
1488            break;
1489
1490        case ACPI_LPIT_TYPE_SIMPLE_IO:
1491
1492            InfoTable = AcpiDmTableInfoLpit1;
1493            break;
1494
1495        default:
1496
1497            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1498            return (AE_ERROR);
1499        }
1500
1501        /* LPIT Subtable */
1502
1503        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1504        if (ACPI_FAILURE (Status))
1505        {
1506            return (Status);
1507        }
1508
1509        ParentTable = DtPeekSubtable ();
1510        DtInsertSubtable (ParentTable, Subtable);
1511        DtPopSubtable ();
1512    }
1513
1514    return (AE_OK);
1515}
1516
1517
1518/******************************************************************************
1519 *
1520 * FUNCTION:    DtCompileMadt
1521 *
1522 * PARAMETERS:  List                - Current field list pointer
1523 *
1524 * RETURN:      Status
1525 *
1526 * DESCRIPTION: Compile MADT.
1527 *
1528 *****************************************************************************/
1529
1530ACPI_STATUS
1531DtCompileMadt (
1532    void                    **List)
1533{
1534    ACPI_STATUS             Status;
1535    DT_SUBTABLE             *Subtable;
1536    DT_SUBTABLE             *ParentTable;
1537    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1538    DT_FIELD                *SubtableStart;
1539    ACPI_SUBTABLE_HEADER    *MadtHeader;
1540    ACPI_DMTABLE_INFO       *InfoTable;
1541
1542
1543    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1544                &Subtable, TRUE);
1545    if (ACPI_FAILURE (Status))
1546    {
1547        return (Status);
1548    }
1549
1550    ParentTable = DtPeekSubtable ();
1551    DtInsertSubtable (ParentTable, Subtable);
1552
1553    while (*PFieldList)
1554    {
1555        SubtableStart = *PFieldList;
1556        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1557                    &Subtable, TRUE);
1558        if (ACPI_FAILURE (Status))
1559        {
1560            return (Status);
1561        }
1562
1563        ParentTable = DtPeekSubtable ();
1564        DtInsertSubtable (ParentTable, Subtable);
1565        DtPushSubtable (Subtable);
1566
1567        MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1568
1569        switch (MadtHeader->Type)
1570        {
1571        case ACPI_MADT_TYPE_LOCAL_APIC:
1572
1573            InfoTable = AcpiDmTableInfoMadt0;
1574            break;
1575
1576        case ACPI_MADT_TYPE_IO_APIC:
1577
1578            InfoTable = AcpiDmTableInfoMadt1;
1579            break;
1580
1581        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1582
1583            InfoTable = AcpiDmTableInfoMadt2;
1584            break;
1585
1586        case ACPI_MADT_TYPE_NMI_SOURCE:
1587
1588            InfoTable = AcpiDmTableInfoMadt3;
1589            break;
1590
1591        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1592
1593            InfoTable = AcpiDmTableInfoMadt4;
1594            break;
1595
1596        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1597
1598            InfoTable = AcpiDmTableInfoMadt5;
1599            break;
1600
1601        case ACPI_MADT_TYPE_IO_SAPIC:
1602
1603            InfoTable = AcpiDmTableInfoMadt6;
1604            break;
1605
1606        case ACPI_MADT_TYPE_LOCAL_SAPIC:
1607
1608            InfoTable = AcpiDmTableInfoMadt7;
1609            break;
1610
1611        case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1612
1613            InfoTable = AcpiDmTableInfoMadt8;
1614            break;
1615
1616        case ACPI_MADT_TYPE_LOCAL_X2APIC:
1617
1618            InfoTable = AcpiDmTableInfoMadt9;
1619            break;
1620
1621        case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1622
1623            InfoTable = AcpiDmTableInfoMadt10;
1624            break;
1625
1626        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1627
1628            InfoTable = AcpiDmTableInfoMadt11;
1629            break;
1630
1631        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1632
1633            InfoTable = AcpiDmTableInfoMadt12;
1634            break;
1635
1636        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1637
1638            InfoTable = AcpiDmTableInfoMadt13;
1639            break;
1640
1641        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1642
1643            InfoTable = AcpiDmTableInfoMadt14;
1644            break;
1645
1646        default:
1647
1648            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1649            return (AE_ERROR);
1650        }
1651
1652        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1653        if (ACPI_FAILURE (Status))
1654        {
1655            return (Status);
1656        }
1657
1658        ParentTable = DtPeekSubtable ();
1659        DtInsertSubtable (ParentTable, Subtable);
1660        DtPopSubtable ();
1661    }
1662
1663    return (AE_OK);
1664}
1665
1666
1667/******************************************************************************
1668 *
1669 * FUNCTION:    DtCompileMcfg
1670 *
1671 * PARAMETERS:  List                - Current field list pointer
1672 *
1673 * RETURN:      Status
1674 *
1675 * DESCRIPTION: Compile MCFG.
1676 *
1677 *****************************************************************************/
1678
1679ACPI_STATUS
1680DtCompileMcfg (
1681    void                    **List)
1682{
1683    ACPI_STATUS             Status;
1684
1685
1686    Status = DtCompileTwoSubtables (List,
1687                 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1688    return (Status);
1689}
1690
1691
1692/******************************************************************************
1693 *
1694 * FUNCTION:    DtCompileMpst
1695 *
1696 * PARAMETERS:  List                - Current field list pointer
1697 *
1698 * RETURN:      Status
1699 *
1700 * DESCRIPTION: Compile MPST.
1701 *
1702 *****************************************************************************/
1703
1704ACPI_STATUS
1705DtCompileMpst (
1706    void                    **List)
1707{
1708    ACPI_STATUS             Status;
1709    DT_SUBTABLE             *Subtable;
1710    DT_SUBTABLE             *ParentTable;
1711    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1712    ACPI_MPST_CHANNEL       *MpstChannelInfo;
1713    ACPI_MPST_POWER_NODE    *MpstPowerNode;
1714    ACPI_MPST_DATA_HDR      *MpstDataHeader;
1715    UINT16                  SubtableCount;
1716    UINT32                  PowerStateCount;
1717    UINT32                  ComponentCount;
1718
1719
1720    /* Main table */
1721
1722    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1723    if (ACPI_FAILURE (Status))
1724    {
1725        return (Status);
1726    }
1727
1728    ParentTable = DtPeekSubtable ();
1729    DtInsertSubtable (ParentTable, Subtable);
1730    DtPushSubtable (Subtable);
1731
1732    MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1733    SubtableCount = MpstChannelInfo->PowerNodeCount;
1734
1735    while (*PFieldList && SubtableCount)
1736    {
1737        /* Subtable: Memory Power Node(s) */
1738
1739        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1740                    &Subtable, TRUE);
1741        if (ACPI_FAILURE (Status))
1742        {
1743            return (Status);
1744        }
1745
1746        ParentTable = DtPeekSubtable ();
1747        DtInsertSubtable (ParentTable, Subtable);
1748        DtPushSubtable (Subtable);
1749
1750        MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1751        PowerStateCount = MpstPowerNode->NumPowerStates;
1752        ComponentCount = MpstPowerNode->NumPhysicalComponents;
1753
1754        ParentTable = DtPeekSubtable ();
1755
1756        /* Sub-subtables - Memory Power State Structure(s) */
1757
1758        while (*PFieldList && PowerStateCount)
1759        {
1760            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1761                        &Subtable, TRUE);
1762            if (ACPI_FAILURE (Status))
1763            {
1764                return (Status);
1765            }
1766
1767            DtInsertSubtable (ParentTable, Subtable);
1768            PowerStateCount--;
1769        }
1770
1771        /* Sub-subtables - Physical Component ID Structure(s) */
1772
1773        while (*PFieldList && ComponentCount)
1774        {
1775            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1776                        &Subtable, TRUE);
1777            if (ACPI_FAILURE (Status))
1778            {
1779                return (Status);
1780            }
1781
1782            DtInsertSubtable (ParentTable, Subtable);
1783            ComponentCount--;
1784        }
1785
1786        SubtableCount--;
1787        DtPopSubtable ();
1788    }
1789
1790    /* Subtable: Count of Memory Power State Characteristic structures */
1791
1792    DtPopSubtable ();
1793
1794    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1795    if (ACPI_FAILURE (Status))
1796    {
1797        return (Status);
1798    }
1799
1800    ParentTable = DtPeekSubtable ();
1801    DtInsertSubtable (ParentTable, Subtable);
1802    DtPushSubtable (Subtable);
1803
1804    MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1805    SubtableCount = MpstDataHeader->CharacteristicsCount;
1806
1807    ParentTable = DtPeekSubtable ();
1808
1809    /* Subtable: Memory Power State Characteristics structure(s) */
1810
1811    while (*PFieldList && SubtableCount)
1812    {
1813        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1814                    &Subtable, TRUE);
1815        if (ACPI_FAILURE (Status))
1816        {
1817            return (Status);
1818        }
1819
1820        DtInsertSubtable (ParentTable, Subtable);
1821        SubtableCount--;
1822    }
1823
1824    DtPopSubtable ();
1825    return (AE_OK);
1826}
1827
1828
1829/******************************************************************************
1830 *
1831 * FUNCTION:    DtCompileMsct
1832 *
1833 * PARAMETERS:  List                - Current field list pointer
1834 *
1835 * RETURN:      Status
1836 *
1837 * DESCRIPTION: Compile MSCT.
1838 *
1839 *****************************************************************************/
1840
1841ACPI_STATUS
1842DtCompileMsct (
1843    void                    **List)
1844{
1845    ACPI_STATUS             Status;
1846
1847
1848    Status = DtCompileTwoSubtables (List,
1849                 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1850    return (Status);
1851}
1852
1853
1854/******************************************************************************
1855 *
1856 * FUNCTION:    DtCompileMtmr
1857 *
1858 * PARAMETERS:  List                - Current field list pointer
1859 *
1860 * RETURN:      Status
1861 *
1862 * DESCRIPTION: Compile MTMR.
1863 *
1864 *****************************************************************************/
1865
1866ACPI_STATUS
1867DtCompileMtmr (
1868    void                    **List)
1869{
1870    ACPI_STATUS             Status;
1871
1872
1873    Status = DtCompileTwoSubtables (List,
1874                 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1875    return (Status);
1876}
1877
1878
1879/******************************************************************************
1880 *
1881 * FUNCTION:    DtCompilePcct
1882 *
1883 * PARAMETERS:  List                - Current field list pointer
1884 *
1885 * RETURN:      Status
1886 *
1887 * DESCRIPTION: Compile PCCT.
1888 *
1889 *****************************************************************************/
1890
1891ACPI_STATUS
1892DtCompilePcct (
1893    void                    **List)
1894{
1895    ACPI_STATUS             Status;
1896    DT_SUBTABLE             *Subtable;
1897    DT_SUBTABLE             *ParentTable;
1898    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1899    DT_FIELD                *SubtableStart;
1900    ACPI_SUBTABLE_HEADER    *PcctHeader;
1901    ACPI_DMTABLE_INFO       *InfoTable;
1902
1903
1904    Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1905                &Subtable, TRUE);
1906    if (ACPI_FAILURE (Status))
1907    {
1908        return (Status);
1909    }
1910
1911    ParentTable = DtPeekSubtable ();
1912    DtInsertSubtable (ParentTable, Subtable);
1913
1914    while (*PFieldList)
1915    {
1916        SubtableStart = *PFieldList;
1917        Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1918                    &Subtable, TRUE);
1919        if (ACPI_FAILURE (Status))
1920        {
1921            return (Status);
1922        }
1923
1924        ParentTable = DtPeekSubtable ();
1925        DtInsertSubtable (ParentTable, Subtable);
1926        DtPushSubtable (Subtable);
1927
1928        PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1929
1930        switch (PcctHeader->Type)
1931        {
1932        case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1933
1934            InfoTable = AcpiDmTableInfoPcct0;
1935            break;
1936
1937        case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1938
1939            InfoTable = AcpiDmTableInfoPcct1;
1940            break;
1941
1942        default:
1943
1944            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1945            return (AE_ERROR);
1946        }
1947
1948        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1949        if (ACPI_FAILURE (Status))
1950        {
1951            return (Status);
1952        }
1953
1954        ParentTable = DtPeekSubtable ();
1955        DtInsertSubtable (ParentTable, Subtable);
1956        DtPopSubtable ();
1957    }
1958
1959    return (AE_OK);
1960}
1961
1962
1963/******************************************************************************
1964 *
1965 * FUNCTION:    DtCompilePmtt
1966 *
1967 * PARAMETERS:  List                - Current field list pointer
1968 *
1969 * RETURN:      Status
1970 *
1971 * DESCRIPTION: Compile PMTT.
1972 *
1973 *****************************************************************************/
1974
1975ACPI_STATUS
1976DtCompilePmtt (
1977    void                    **List)
1978{
1979    ACPI_STATUS             Status;
1980    DT_SUBTABLE             *Subtable;
1981    DT_SUBTABLE             *ParentTable;
1982    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1983    DT_FIELD                *SubtableStart;
1984    ACPI_PMTT_HEADER        *PmttHeader;
1985    ACPI_PMTT_CONTROLLER    *PmttController;
1986    UINT16                  DomainCount;
1987    UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
1988
1989
1990    /* Main table */
1991
1992    Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1993    if (ACPI_FAILURE (Status))
1994    {
1995        return (Status);
1996    }
1997
1998    ParentTable = DtPeekSubtable ();
1999    DtInsertSubtable (ParentTable, Subtable);
2000    DtPushSubtable (Subtable);
2001
2002    while (*PFieldList)
2003    {
2004        SubtableStart = *PFieldList;
2005        Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
2006                    &Subtable, TRUE);
2007        if (ACPI_FAILURE (Status))
2008        {
2009            return (Status);
2010        }
2011
2012        PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
2013        while (PrevType >= PmttHeader->Type)
2014        {
2015            DtPopSubtable ();
2016
2017            if (PrevType == ACPI_PMTT_TYPE_SOCKET)
2018            {
2019                break;
2020            }
2021            PrevType--;
2022        }
2023        PrevType = PmttHeader->Type;
2024
2025        ParentTable = DtPeekSubtable ();
2026        DtInsertSubtable (ParentTable, Subtable);
2027        DtPushSubtable (Subtable);
2028
2029        switch (PmttHeader->Type)
2030        {
2031        case ACPI_PMTT_TYPE_SOCKET:
2032
2033            /* Subtable: Socket Structure */
2034
2035            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
2036                    &Subtable, TRUE);
2037            if (ACPI_FAILURE (Status))
2038            {
2039                return (Status);
2040            }
2041
2042            ParentTable = DtPeekSubtable ();
2043            DtInsertSubtable (ParentTable, Subtable);
2044            break;
2045
2046        case ACPI_PMTT_TYPE_CONTROLLER:
2047
2048            /* Subtable: Memory Controller Structure */
2049
2050            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
2051                    &Subtable, TRUE);
2052            if (ACPI_FAILURE (Status))
2053            {
2054                return (Status);
2055            }
2056
2057            ParentTable = DtPeekSubtable ();
2058            DtInsertSubtable (ParentTable, Subtable);
2059
2060            PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
2061                (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
2062            DomainCount = PmttController->DomainCount;
2063
2064            while (DomainCount)
2065            {
2066                Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
2067                    &Subtable, TRUE);
2068                if (ACPI_FAILURE (Status))
2069                {
2070                    return (Status);
2071                }
2072
2073                DtInsertSubtable (ParentTable, Subtable);
2074                DomainCount--;
2075            }
2076            break;
2077
2078        case ACPI_PMTT_TYPE_DIMM:
2079
2080            /* Subtable: Physical Component Structure */
2081
2082            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
2083                    &Subtable, TRUE);
2084            if (ACPI_FAILURE (Status))
2085            {
2086                return (Status);
2087            }
2088
2089            ParentTable = DtPeekSubtable ();
2090            DtInsertSubtable (ParentTable, Subtable);
2091            break;
2092
2093        default:
2094
2095            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
2096            return (AE_ERROR);
2097        }
2098    }
2099
2100    return (Status);
2101}
2102
2103
2104/******************************************************************************
2105 *
2106 * FUNCTION:    DtCompileRsdt
2107 *
2108 * PARAMETERS:  List                - Current field list pointer
2109 *
2110 * RETURN:      Status
2111 *
2112 * DESCRIPTION: Compile RSDT.
2113 *
2114 *****************************************************************************/
2115
2116ACPI_STATUS
2117DtCompileRsdt (
2118    void                    **List)
2119{
2120    DT_SUBTABLE             *Subtable;
2121    DT_SUBTABLE             *ParentTable;
2122    DT_FIELD                *FieldList = *(DT_FIELD **) List;
2123    UINT32                  Address;
2124
2125
2126    ParentTable = DtPeekSubtable ();
2127
2128    while (FieldList)
2129    {
2130        DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2131
2132        DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2133        DtInsertSubtable (ParentTable, Subtable);
2134        FieldList = FieldList->Next;
2135    }
2136
2137    return (AE_OK);
2138}
2139
2140
2141/******************************************************************************
2142 *
2143 * FUNCTION:    DtCompileS3pt
2144 *
2145 * PARAMETERS:  PFieldList          - Current field list pointer
2146 *
2147 * RETURN:      Status
2148 *
2149 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2150 *
2151 *****************************************************************************/
2152
2153ACPI_STATUS
2154DtCompileS3pt (
2155    DT_FIELD                **PFieldList)
2156{
2157    ACPI_STATUS             Status;
2158    ACPI_S3PT_HEADER        *S3ptHeader;
2159    DT_SUBTABLE             *Subtable;
2160    DT_SUBTABLE             *ParentTable;
2161    ACPI_DMTABLE_INFO       *InfoTable;
2162    DT_FIELD                *SubtableStart;
2163
2164
2165    Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2166                &Gbl_RootTable, TRUE);
2167    if (ACPI_FAILURE (Status))
2168    {
2169        return (Status);
2170    }
2171
2172    DtPushSubtable (Gbl_RootTable);
2173
2174    while (*PFieldList)
2175    {
2176        SubtableStart = *PFieldList;
2177        Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2178                    &Subtable, TRUE);
2179        if (ACPI_FAILURE (Status))
2180        {
2181            return (Status);
2182        }
2183
2184        ParentTable = DtPeekSubtable ();
2185        DtInsertSubtable (ParentTable, Subtable);
2186        DtPushSubtable (Subtable);
2187
2188        S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2189
2190        switch (S3ptHeader->Type)
2191        {
2192        case ACPI_S3PT_TYPE_RESUME:
2193
2194            InfoTable = AcpiDmTableInfoS3pt0;
2195            break;
2196
2197        case ACPI_S3PT_TYPE_SUSPEND:
2198
2199            InfoTable = AcpiDmTableInfoS3pt1;
2200            break;
2201
2202        default:
2203
2204            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2205            return (AE_ERROR);
2206        }
2207
2208        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2209        if (ACPI_FAILURE (Status))
2210        {
2211            return (Status);
2212        }
2213
2214        ParentTable = DtPeekSubtable ();
2215        DtInsertSubtable (ParentTable, Subtable);
2216        DtPopSubtable ();
2217    }
2218
2219    return (AE_OK);
2220}
2221
2222
2223/******************************************************************************
2224 *
2225 * FUNCTION:    DtCompileSlic
2226 *
2227 * PARAMETERS:  List                - Current field list pointer
2228 *
2229 * RETURN:      Status
2230 *
2231 * DESCRIPTION: Compile SLIC.
2232 *
2233 *****************************************************************************/
2234
2235ACPI_STATUS
2236DtCompileSlic (
2237    void                    **List)
2238{
2239    ACPI_STATUS             Status;
2240    DT_SUBTABLE             *Subtable;
2241    DT_SUBTABLE             *ParentTable;
2242    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2243    DT_FIELD                *SubtableStart;
2244    ACPI_SLIC_HEADER        *SlicHeader;
2245    ACPI_DMTABLE_INFO       *InfoTable;
2246
2247
2248    while (*PFieldList)
2249    {
2250        SubtableStart = *PFieldList;
2251        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
2252                    &Subtable, TRUE);
2253        if (ACPI_FAILURE (Status))
2254        {
2255            return (Status);
2256        }
2257
2258        ParentTable = DtPeekSubtable ();
2259        DtInsertSubtable (ParentTable, Subtable);
2260        DtPushSubtable (Subtable);
2261
2262        SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
2263
2264        switch (SlicHeader->Type)
2265        {
2266        case ACPI_SLIC_TYPE_PUBLIC_KEY:
2267
2268            InfoTable = AcpiDmTableInfoSlic0;
2269            break;
2270
2271        case ACPI_SLIC_TYPE_WINDOWS_MARKER:
2272
2273            InfoTable = AcpiDmTableInfoSlic1;
2274            break;
2275
2276        default:
2277
2278            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
2279            return (AE_ERROR);
2280        }
2281
2282        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2283        if (ACPI_FAILURE (Status))
2284        {
2285            return (Status);
2286        }
2287
2288        ParentTable = DtPeekSubtable ();
2289        DtInsertSubtable (ParentTable, Subtable);
2290        DtPopSubtable ();
2291    }
2292
2293    return (AE_OK);
2294}
2295
2296
2297/******************************************************************************
2298 *
2299 * FUNCTION:    DtCompileSlit
2300 *
2301 * PARAMETERS:  List                - Current field list pointer
2302 *
2303 * RETURN:      Status
2304 *
2305 * DESCRIPTION: Compile SLIT.
2306 *
2307 *****************************************************************************/
2308
2309ACPI_STATUS
2310DtCompileSlit (
2311    void                    **List)
2312{
2313    ACPI_STATUS             Status;
2314    DT_SUBTABLE             *Subtable;
2315    DT_SUBTABLE             *ParentTable;
2316    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2317    DT_FIELD                *FieldList;
2318    UINT32                  Localities;
2319    UINT8                   *LocalityBuffer;
2320
2321
2322    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2323                &Subtable, TRUE);
2324    if (ACPI_FAILURE (Status))
2325    {
2326        return (Status);
2327    }
2328
2329    ParentTable = DtPeekSubtable ();
2330    DtInsertSubtable (ParentTable, Subtable);
2331
2332    Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2333    LocalityBuffer = UtLocalCalloc (Localities);
2334
2335    /* Compile each locality buffer */
2336
2337    FieldList = *PFieldList;
2338    while (FieldList)
2339    {
2340        DtCompileBuffer (LocalityBuffer,
2341            FieldList->Value, FieldList, Localities);
2342
2343        DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2344        DtInsertSubtable (ParentTable, Subtable);
2345        FieldList = FieldList->Next;
2346    }
2347
2348    ACPI_FREE (LocalityBuffer);
2349    return (AE_OK);
2350}
2351
2352
2353/******************************************************************************
2354 *
2355 * FUNCTION:    DtCompileSrat
2356 *
2357 * PARAMETERS:  List                - Current field list pointer
2358 *
2359 * RETURN:      Status
2360 *
2361 * DESCRIPTION: Compile SRAT.
2362 *
2363 *****************************************************************************/
2364
2365ACPI_STATUS
2366DtCompileSrat (
2367    void                    **List)
2368{
2369    ACPI_STATUS             Status;
2370    DT_SUBTABLE             *Subtable;
2371    DT_SUBTABLE             *ParentTable;
2372    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2373    DT_FIELD                *SubtableStart;
2374    ACPI_SUBTABLE_HEADER    *SratHeader;
2375    ACPI_DMTABLE_INFO       *InfoTable;
2376
2377
2378    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2379                &Subtable, TRUE);
2380    if (ACPI_FAILURE (Status))
2381    {
2382        return (Status);
2383    }
2384
2385    ParentTable = DtPeekSubtable ();
2386    DtInsertSubtable (ParentTable, Subtable);
2387
2388    while (*PFieldList)
2389    {
2390        SubtableStart = *PFieldList;
2391        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2392                    &Subtable, TRUE);
2393        if (ACPI_FAILURE (Status))
2394        {
2395            return (Status);
2396        }
2397
2398        ParentTable = DtPeekSubtable ();
2399        DtInsertSubtable (ParentTable, Subtable);
2400        DtPushSubtable (Subtable);
2401
2402        SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2403
2404        switch (SratHeader->Type)
2405        {
2406        case ACPI_SRAT_TYPE_CPU_AFFINITY:
2407
2408            InfoTable = AcpiDmTableInfoSrat0;
2409            break;
2410
2411        case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2412
2413            InfoTable = AcpiDmTableInfoSrat1;
2414            break;
2415
2416        case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2417
2418            InfoTable = AcpiDmTableInfoSrat2;
2419            break;
2420
2421        case ACPI_SRAT_TYPE_GICC_AFFINITY:
2422
2423            InfoTable = AcpiDmTableInfoSrat3;
2424            break;
2425
2426        default:
2427
2428            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2429            return (AE_ERROR);
2430        }
2431
2432        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2433        if (ACPI_FAILURE (Status))
2434        {
2435            return (Status);
2436        }
2437
2438        ParentTable = DtPeekSubtable ();
2439        DtInsertSubtable (ParentTable, Subtable);
2440        DtPopSubtable ();
2441    }
2442
2443    return (AE_OK);
2444}
2445
2446
2447/******************************************************************************
2448 *
2449 * FUNCTION:    DtGetGenericTableInfo
2450 *
2451 * PARAMETERS:  Name                - Generic type name
2452 *
2453 * RETURN:      Info entry
2454 *
2455 * DESCRIPTION: Obtain table info for a generic name entry
2456 *
2457 *****************************************************************************/
2458
2459ACPI_DMTABLE_INFO *
2460DtGetGenericTableInfo (
2461    char                    *Name)
2462{
2463    ACPI_DMTABLE_INFO       *Info;
2464    UINT32                  i;
2465
2466
2467    if (!Name)
2468    {
2469        return (NULL);
2470    }
2471
2472    /* Search info table for name match */
2473
2474    for (i = 0; ; i++)
2475    {
2476        Info = AcpiDmTableInfoGeneric[i];
2477        if (Info->Opcode == ACPI_DMT_EXIT)
2478        {
2479            Info = NULL;
2480            break;
2481        }
2482
2483        /* Use caseless compare for generic keywords */
2484
2485        if (!AcpiUtStricmp (Name, Info->Name))
2486        {
2487            break;
2488        }
2489    }
2490
2491    return (Info);
2492}
2493
2494
2495/******************************************************************************
2496 *
2497 * FUNCTION:    DtCompileUefi
2498 *
2499 * PARAMETERS:  List                - Current field list pointer
2500 *
2501 * RETURN:      Status
2502 *
2503 * DESCRIPTION: Compile UEFI.
2504 *
2505 *****************************************************************************/
2506
2507ACPI_STATUS
2508DtCompileUefi (
2509    void                    **List)
2510{
2511    ACPI_STATUS             Status;
2512    DT_SUBTABLE             *Subtable;
2513    DT_SUBTABLE             *ParentTable;
2514    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2515    UINT16                  *DataOffset;
2516
2517
2518    /* Compile the predefined portion of the UEFI table */
2519
2520    Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2521                &Subtable, TRUE);
2522    if (ACPI_FAILURE (Status))
2523    {
2524        return (Status);
2525    }
2526
2527    DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2528    *DataOffset = sizeof (ACPI_TABLE_UEFI);
2529
2530    ParentTable = DtPeekSubtable ();
2531    DtInsertSubtable (ParentTable, Subtable);
2532
2533    /*
2534     * Compile the "generic" portion of the UEFI table. This
2535     * part of the table is not predefined and any of the generic
2536     * operators may be used.
2537     */
2538
2539    DtCompileGeneric ((void **) PFieldList);
2540
2541    return (AE_OK);
2542}
2543
2544
2545/******************************************************************************
2546 *
2547 * FUNCTION:    DtCompileVrtc
2548 *
2549 * PARAMETERS:  List                - Current field list pointer
2550 *
2551 * RETURN:      Status
2552 *
2553 * DESCRIPTION: Compile VRTC.
2554 *
2555 *****************************************************************************/
2556
2557ACPI_STATUS
2558DtCompileVrtc (
2559    void                    **List)
2560{
2561    ACPI_STATUS             Status;
2562
2563
2564    Status = DtCompileTwoSubtables (List,
2565                 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2566    return (Status);
2567}
2568
2569
2570/******************************************************************************
2571 *
2572 * FUNCTION:    DtCompileWdat
2573 *
2574 * PARAMETERS:  List                - Current field list pointer
2575 *
2576 * RETURN:      Status
2577 *
2578 * DESCRIPTION: Compile WDAT.
2579 *
2580 *****************************************************************************/
2581
2582ACPI_STATUS
2583DtCompileWdat (
2584    void                    **List)
2585{
2586    ACPI_STATUS             Status;
2587
2588
2589    Status = DtCompileTwoSubtables (List,
2590                 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2591    return (Status);
2592}
2593
2594
2595/******************************************************************************
2596 *
2597 * FUNCTION:    DtCompileXsdt
2598 *
2599 * PARAMETERS:  List                - Current field list pointer
2600 *
2601 * RETURN:      Status
2602 *
2603 * DESCRIPTION: Compile XSDT.
2604 *
2605 *****************************************************************************/
2606
2607ACPI_STATUS
2608DtCompileXsdt (
2609    void                    **List)
2610{
2611    DT_SUBTABLE             *Subtable;
2612    DT_SUBTABLE             *ParentTable;
2613    DT_FIELD                *FieldList = *(DT_FIELD **) List;
2614    UINT64                  Address;
2615
2616    ParentTable = DtPeekSubtable ();
2617
2618    while (FieldList)
2619    {
2620        DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2621
2622        DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2623        DtInsertSubtable (ParentTable, Subtable);
2624        FieldList = FieldList->Next;
2625    }
2626
2627    return (AE_OK);
2628}
2629
2630
2631/******************************************************************************
2632 *
2633 * FUNCTION:    DtCompileGeneric
2634 *
2635 * PARAMETERS:  List                - Current field list pointer
2636 *
2637 * RETURN:      Status
2638 *
2639 * DESCRIPTION: Compile generic unknown table.
2640 *
2641 *****************************************************************************/
2642
2643ACPI_STATUS
2644DtCompileGeneric (
2645    void                    **List)
2646{
2647    ACPI_STATUS             Status;
2648    DT_SUBTABLE             *Subtable;
2649    DT_SUBTABLE             *ParentTable;
2650    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2651    ACPI_DMTABLE_INFO       *Info;
2652
2653
2654    ParentTable = DtPeekSubtable ();
2655
2656    /*
2657     * Compile the "generic" portion of the table. This
2658     * part of the table is not predefined and any of the generic
2659     * operators may be used.
2660     */
2661
2662    /* Find any and all labels in the entire generic portion */
2663
2664    DtDetectAllLabels (*PFieldList);
2665
2666    /* Now we can actually compile the parse tree */
2667
2668    while (*PFieldList)
2669    {
2670        Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2671        if (!Info)
2672        {
2673            sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2674                (*PFieldList)->Name);
2675            DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2676                (*PFieldList), MsgBuffer);
2677
2678            *PFieldList = (*PFieldList)->Next;
2679            continue;
2680        }
2681
2682        Status = DtCompileTable (PFieldList, Info,
2683                    &Subtable, TRUE);
2684        if (ACPI_SUCCESS (Status))
2685        {
2686            DtInsertSubtable (ParentTable, Subtable);
2687        }
2688        else
2689        {
2690            *PFieldList = (*PFieldList)->Next;
2691
2692            if (Status == AE_NOT_FOUND)
2693            {
2694                sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2695                    (*PFieldList)->Name);
2696                DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2697                    (*PFieldList), MsgBuffer);
2698            }
2699        }
2700    }
2701
2702    return (AE_OK);
2703}
2704