dttable.c revision 284583
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/* Local prototypes */
69
70static ACPI_STATUS
71DtCompileTwoSubtables (
72    void                    **List,
73    ACPI_DMTABLE_INFO       *TableInfo1,
74    ACPI_DMTABLE_INFO       *TableInfo2);
75
76
77/******************************************************************************
78 *
79 * FUNCTION:    DtCompileTwoSubtables
80 *
81 * PARAMETERS:  List                - Current field list pointer
82 *              TableInfo1          - Info table 1
83 *              TableInfo1          - Info table 2
84 *
85 * RETURN:      Status
86 *
87 * DESCRIPTION: Compile tables with a header and one or more same subtables.
88 *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
89 *
90 *****************************************************************************/
91
92static ACPI_STATUS
93DtCompileTwoSubtables (
94    void                    **List,
95    ACPI_DMTABLE_INFO       *TableInfo1,
96    ACPI_DMTABLE_INFO       *TableInfo2)
97{
98    ACPI_STATUS             Status;
99    DT_SUBTABLE             *Subtable;
100    DT_SUBTABLE             *ParentTable;
101    DT_FIELD                **PFieldList = (DT_FIELD **) List;
102
103
104    Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
105    if (ACPI_FAILURE (Status))
106    {
107        return (Status);
108    }
109
110    ParentTable = DtPeekSubtable ();
111    DtInsertSubtable (ParentTable, Subtable);
112
113    while (*PFieldList)
114    {
115        Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
116        if (ACPI_FAILURE (Status))
117        {
118            return (Status);
119        }
120
121        DtInsertSubtable (ParentTable, Subtable);
122    }
123
124    return (AE_OK);
125}
126
127
128/******************************************************************************
129 *
130 * FUNCTION:    DtCompileFacs
131 *
132 * PARAMETERS:  PFieldList          - Current field list pointer
133 *
134 * RETURN:      Status
135 *
136 * DESCRIPTION: Compile FACS.
137 *
138 *****************************************************************************/
139
140ACPI_STATUS
141DtCompileFacs (
142    DT_FIELD                **PFieldList)
143{
144    DT_SUBTABLE             *Subtable;
145    UINT8                   *ReservedBuffer;
146    ACPI_STATUS             Status;
147    UINT32                  ReservedSize;
148
149
150    Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
151                &Gbl_RootTable, TRUE);
152    if (ACPI_FAILURE (Status))
153    {
154        return (Status);
155    }
156
157    /* Large FACS reserved area at the end of the table */
158
159    ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
160    ReservedBuffer = UtLocalCalloc (ReservedSize);
161
162    DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
163
164    ACPI_FREE (ReservedBuffer);
165    DtInsertSubtable (Gbl_RootTable, Subtable);
166    return (AE_OK);
167}
168
169
170/******************************************************************************
171 *
172 * FUNCTION:    DtCompileRsdp
173 *
174 * PARAMETERS:  PFieldList          - Current field list pointer
175 *
176 * RETURN:      Status
177 *
178 * DESCRIPTION: Compile RSDP.
179 *
180 *****************************************************************************/
181
182ACPI_STATUS
183DtCompileRsdp (
184    DT_FIELD                **PFieldList)
185{
186    DT_SUBTABLE             *Subtable;
187    ACPI_TABLE_RSDP         *Rsdp;
188    ACPI_RSDP_EXTENSION     *RsdpExtension;
189    ACPI_STATUS             Status;
190
191
192    /* Compile the "common" RSDP (ACPI 1.0) */
193
194    Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
195                &Gbl_RootTable, TRUE);
196    if (ACPI_FAILURE (Status))
197    {
198        return (Status);
199    }
200
201    Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
202    DtSetTableChecksum (&Rsdp->Checksum);
203
204    if (Rsdp->Revision > 0)
205    {
206        /* Compile the "extended" part of the RSDP as a subtable */
207
208        Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
209                    &Subtable, TRUE);
210        if (ACPI_FAILURE (Status))
211        {
212            return (Status);
213        }
214
215        DtInsertSubtable (Gbl_RootTable, Subtable);
216
217        /* Set length and extended checksum for entire RSDP */
218
219        RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
220        RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
221        DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
222    }
223
224    return (AE_OK);
225}
226
227
228/******************************************************************************
229 *
230 * FUNCTION:    DtCompileAsf
231 *
232 * PARAMETERS:  List                - Current field list pointer
233 *
234 * RETURN:      Status
235 *
236 * DESCRIPTION: Compile ASF!.
237 *
238 *****************************************************************************/
239
240ACPI_STATUS
241DtCompileAsf (
242    void                    **List)
243{
244    ACPI_ASF_INFO           *AsfTable;
245    DT_SUBTABLE             *Subtable;
246    DT_SUBTABLE             *ParentTable;
247    ACPI_DMTABLE_INFO       *InfoTable;
248    ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
249    UINT32                  DataCount = 0;
250    ACPI_STATUS             Status;
251    UINT32                  i;
252    DT_FIELD                **PFieldList = (DT_FIELD **) List;
253    DT_FIELD                *SubtableStart;
254
255
256    while (*PFieldList)
257    {
258        SubtableStart = *PFieldList;
259        Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
260                    &Subtable, TRUE);
261        if (ACPI_FAILURE (Status))
262        {
263            return (Status);
264        }
265
266        ParentTable = DtPeekSubtable ();
267        DtInsertSubtable (ParentTable, Subtable);
268        DtPushSubtable (Subtable);
269
270        AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
271
272        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
273        {
274        case ACPI_ASF_TYPE_INFO:
275
276            InfoTable = AcpiDmTableInfoAsf0;
277            break;
278
279        case ACPI_ASF_TYPE_ALERT:
280
281            InfoTable = AcpiDmTableInfoAsf1;
282            break;
283
284        case ACPI_ASF_TYPE_CONTROL:
285
286            InfoTable = AcpiDmTableInfoAsf2;
287            break;
288
289        case ACPI_ASF_TYPE_BOOT:
290
291            InfoTable = AcpiDmTableInfoAsf3;
292            break;
293
294        case ACPI_ASF_TYPE_ADDRESS:
295
296            InfoTable = AcpiDmTableInfoAsf4;
297            break;
298
299        default:
300
301            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
302            return (AE_ERROR);
303        }
304
305        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
306        if (ACPI_FAILURE (Status))
307        {
308            return (Status);
309        }
310
311        ParentTable = DtPeekSubtable ();
312        DtInsertSubtable (ParentTable, Subtable);
313
314        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
315        {
316        case ACPI_ASF_TYPE_INFO:
317
318            DataInfoTable = NULL;
319            break;
320
321        case ACPI_ASF_TYPE_ALERT:
322
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
331            DataInfoTable = AcpiDmTableInfoAsf2a;
332            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
333                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
334                            sizeof (ACPI_ASF_HEADER)))->Controls;
335            break;
336
337        case ACPI_ASF_TYPE_BOOT:
338
339            DataInfoTable = NULL;
340            break;
341
342        case ACPI_ASF_TYPE_ADDRESS:
343
344            DataInfoTable = TableInfoAsfAddress;
345            DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
346                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
347                            sizeof (ACPI_ASF_HEADER)))->Devices;
348            break;
349
350        default:
351
352            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
353            return (AE_ERROR);
354        }
355
356        if (DataInfoTable)
357        {
358            switch (AsfTable->Header.Type & 0x7F)
359            {
360            case ACPI_ASF_TYPE_ADDRESS:
361
362                while (DataCount > 0)
363                {
364                    Status = DtCompileTable (PFieldList, DataInfoTable,
365                                &Subtable, TRUE);
366                    if (ACPI_FAILURE (Status))
367                    {
368                        return (Status);
369                    }
370
371                    DtInsertSubtable (ParentTable, Subtable);
372                    DataCount = DataCount - Subtable->Length;
373                }
374                break;
375
376            default:
377
378                for (i = 0; i < DataCount; i++)
379                {
380                    Status = DtCompileTable (PFieldList, DataInfoTable,
381                                &Subtable, TRUE);
382                    if (ACPI_FAILURE (Status))
383                    {
384                        return (Status);
385                    }
386
387                    DtInsertSubtable (ParentTable, Subtable);
388                }
389                break;
390            }
391        }
392
393        DtPopSubtable ();
394    }
395
396    return (AE_OK);
397}
398
399
400/******************************************************************************
401 *
402 * FUNCTION:    DtCompileCpep
403 *
404 * PARAMETERS:  List                - Current field list pointer
405 *
406 * RETURN:      Status
407 *
408 * DESCRIPTION: Compile CPEP.
409 *
410 *****************************************************************************/
411
412ACPI_STATUS
413DtCompileCpep (
414    void                    **List)
415{
416    ACPI_STATUS             Status;
417
418
419    Status = DtCompileTwoSubtables (List,
420                 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
421    return (Status);
422}
423
424
425/******************************************************************************
426 *
427 * FUNCTION:    DtCompileCsrt
428 *
429 * PARAMETERS:  List                - Current field list pointer
430 *
431 * RETURN:      Status
432 *
433 * DESCRIPTION: Compile CSRT.
434 *
435 *****************************************************************************/
436
437ACPI_STATUS
438DtCompileCsrt (
439    void                    **List)
440{
441    ACPI_STATUS             Status = AE_OK;
442    DT_SUBTABLE             *Subtable;
443    DT_SUBTABLE             *ParentTable;
444    DT_FIELD                **PFieldList = (DT_FIELD **) List;
445    UINT32                  DescriptorCount;
446    UINT32                  GroupLength;
447
448
449    /* Subtables (Resource Groups) */
450
451    ParentTable = DtPeekSubtable ();
452    while (*PFieldList)
453    {
454        /* Resource group subtable */
455
456        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
457                    &Subtable, TRUE);
458        if (ACPI_FAILURE (Status))
459        {
460            return (Status);
461        }
462
463        /* Compute the number of resource descriptors */
464
465        GroupLength =
466            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
467                Subtable->Buffer))->Length -
468            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
469                Subtable->Buffer))->SharedInfoLength -
470            sizeof (ACPI_CSRT_GROUP);
471
472        DescriptorCount = (GroupLength  /
473            sizeof (ACPI_CSRT_DESCRIPTOR));
474
475        DtInsertSubtable (ParentTable, Subtable);
476        DtPushSubtable (Subtable);
477        ParentTable = DtPeekSubtable ();
478
479        /* Shared info subtable (One per resource group) */
480
481        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
482                    &Subtable, TRUE);
483        if (ACPI_FAILURE (Status))
484        {
485            return (Status);
486        }
487
488        DtInsertSubtable (ParentTable, Subtable);
489
490        /* Sub-Subtables (Resource Descriptors) */
491
492        while (*PFieldList && DescriptorCount)
493        {
494
495            Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
496                        &Subtable, TRUE);
497            if (ACPI_FAILURE (Status))
498            {
499                return (Status);
500            }
501            DtInsertSubtable (ParentTable, Subtable);
502
503            DtPushSubtable (Subtable);
504            ParentTable = DtPeekSubtable ();
505            if (*PFieldList)
506            {
507                Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
508                            &Subtable, TRUE);
509                if (ACPI_FAILURE (Status))
510                {
511                    return (Status);
512                }
513                if (Subtable)
514                {
515                    DtInsertSubtable (ParentTable, Subtable);
516                }
517            }
518            DtPopSubtable ();
519            ParentTable = DtPeekSubtable ();
520
521            DescriptorCount--;
522        }
523
524        DtPopSubtable ();
525        ParentTable = DtPeekSubtable ();
526    }
527
528    return (Status);
529}
530
531
532/******************************************************************************
533 *
534 * FUNCTION:    DtCompileDbg2
535 *
536 * PARAMETERS:  List                - Current field list pointer
537 *
538 * RETURN:      Status
539 *
540 * DESCRIPTION: Compile DBG2.
541 *
542 *****************************************************************************/
543
544ACPI_STATUS
545DtCompileDbg2 (
546    void                    **List)
547{
548    ACPI_STATUS             Status;
549    DT_SUBTABLE             *Subtable;
550    DT_SUBTABLE             *ParentTable;
551    DT_FIELD                **PFieldList = (DT_FIELD **) List;
552    UINT32                  SubtableCount;
553    ACPI_DBG2_HEADER        *Dbg2Header;
554    ACPI_DBG2_DEVICE        *DeviceInfo;
555    UINT16                  CurrentOffset;
556    UINT32                  i;
557
558
559    /* Main table */
560
561    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
562    if (ACPI_FAILURE (Status))
563    {
564        return (Status);
565    }
566
567    ParentTable = DtPeekSubtable ();
568    DtInsertSubtable (ParentTable, Subtable);
569
570    /* Main table fields */
571
572    Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
573    Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
574        ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
575
576    SubtableCount = Dbg2Header->InfoCount;
577    DtPushSubtable (Subtable);
578
579    /* Process all Device Information subtables (Count = InfoCount) */
580
581    while (*PFieldList && SubtableCount)
582    {
583        /* Subtable: Debug Device Information */
584
585        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
586                    &Subtable, TRUE);
587        if (ACPI_FAILURE (Status))
588        {
589            return (Status);
590        }
591
592        DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
593        CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
594
595        ParentTable = DtPeekSubtable ();
596        DtInsertSubtable (ParentTable, Subtable);
597        DtPushSubtable (Subtable);
598
599        ParentTable = DtPeekSubtable ();
600
601        /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
602
603        DeviceInfo->BaseAddressOffset = CurrentOffset;
604        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
605        {
606            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
607                        &Subtable, TRUE);
608            if (ACPI_FAILURE (Status))
609            {
610                return (Status);
611            }
612
613            CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
614            DtInsertSubtable (ParentTable, Subtable);
615        }
616
617        /* AddressSize array (Required, size = RegisterCount) */
618
619        DeviceInfo->AddressSizeOffset = CurrentOffset;
620        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
621        {
622            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
623                        &Subtable, TRUE);
624            if (ACPI_FAILURE (Status))
625            {
626                return (Status);
627            }
628
629            CurrentOffset += (UINT16) sizeof (UINT32);
630            DtInsertSubtable (ParentTable, Subtable);
631        }
632
633        /* NamespaceString device identifier (Required, size = NamePathLength) */
634
635        DeviceInfo->NamepathOffset = CurrentOffset;
636        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
637                    &Subtable, TRUE);
638        if (ACPI_FAILURE (Status))
639        {
640            return (Status);
641        }
642
643        /* Update the device info header */
644
645        DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
646        CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
647        DtInsertSubtable (ParentTable, Subtable);
648
649        /* OemData - Variable-length data (Optional, size = OemDataLength) */
650
651        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
652                    &Subtable, TRUE);
653        if (ACPI_FAILURE (Status))
654        {
655            return (Status);
656        }
657
658        /* Update the device info header (zeros if no OEM data present) */
659
660        DeviceInfo->OemDataOffset = 0;
661        DeviceInfo->OemDataLength = 0;
662
663        /* Optional subtable (OemData) */
664
665        if (Subtable && Subtable->Length)
666        {
667            DeviceInfo->OemDataOffset = CurrentOffset;
668            DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
669
670            DtInsertSubtable (ParentTable, Subtable);
671        }
672
673        SubtableCount--;
674        DtPopSubtable (); /* Get next Device Information subtable */
675    }
676
677    DtPopSubtable ();
678    return (AE_OK);
679}
680
681
682/******************************************************************************
683 *
684 * FUNCTION:    DtCompileDmar
685 *
686 * PARAMETERS:  List                - Current field list pointer
687 *
688 * RETURN:      Status
689 *
690 * DESCRIPTION: Compile DMAR.
691 *
692 *****************************************************************************/
693
694ACPI_STATUS
695DtCompileDmar (
696    void                    **List)
697{
698    ACPI_STATUS             Status;
699    DT_SUBTABLE             *Subtable;
700    DT_SUBTABLE             *ParentTable;
701    DT_FIELD                **PFieldList = (DT_FIELD **) List;
702    DT_FIELD                *SubtableStart;
703    ACPI_DMTABLE_INFO       *InfoTable;
704    ACPI_DMAR_HEADER        *DmarHeader;
705    ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
706    UINT32                  DeviceScopeLength;
707    UINT32                  PciPathLength;
708
709
710    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &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    while (*PFieldList)
721    {
722        /* DMAR Header */
723
724        SubtableStart = *PFieldList;
725        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
726                    &Subtable, TRUE);
727        if (ACPI_FAILURE (Status))
728        {
729            return (Status);
730        }
731
732        ParentTable = DtPeekSubtable ();
733        DtInsertSubtable (ParentTable, Subtable);
734        DtPushSubtable (Subtable);
735
736        DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
737
738        switch (DmarHeader->Type)
739        {
740        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
741
742            InfoTable = AcpiDmTableInfoDmar0;
743            break;
744
745        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
746
747            InfoTable = AcpiDmTableInfoDmar1;
748            break;
749
750        case ACPI_DMAR_TYPE_ROOT_ATS:
751
752            InfoTable = AcpiDmTableInfoDmar2;
753            break;
754
755        case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
756
757            InfoTable = AcpiDmTableInfoDmar3;
758            break;
759
760        case ACPI_DMAR_TYPE_NAMESPACE:
761
762            InfoTable = AcpiDmTableInfoDmar4;
763            break;
764
765        default:
766
767            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
768            return (AE_ERROR);
769        }
770
771        /* DMAR Subtable */
772
773        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
774        if (ACPI_FAILURE (Status))
775        {
776            return (Status);
777        }
778
779        ParentTable = DtPeekSubtable ();
780        DtInsertSubtable (ParentTable, Subtable);
781
782        /*
783         * Optional Device Scope subtables
784         */
785        if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
786            (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
787        {
788            /* These types do not support device scopes */
789
790            DtPopSubtable ();
791            continue;
792        }
793
794        DtPushSubtable (Subtable);
795        DeviceScopeLength = DmarHeader->Length - Subtable->Length -
796            ParentTable->Length;
797        while (DeviceScopeLength)
798        {
799            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
800                        &Subtable, FALSE);
801            if (Status == AE_NOT_FOUND)
802            {
803                break;
804            }
805
806            ParentTable = DtPeekSubtable ();
807            DtInsertSubtable (ParentTable, Subtable);
808            DtPushSubtable (Subtable);
809
810            DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
811
812            /* Optional PCI Paths */
813
814            PciPathLength = DmarDeviceScope->Length - Subtable->Length;
815            while (PciPathLength)
816            {
817                Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
818                            &Subtable, FALSE);
819                if (Status == AE_NOT_FOUND)
820                {
821                    DtPopSubtable ();
822                    break;
823                }
824
825                ParentTable = DtPeekSubtable ();
826                DtInsertSubtable (ParentTable, Subtable);
827                PciPathLength -= Subtable->Length;
828            }
829
830            DtPopSubtable ();
831            DeviceScopeLength -= DmarDeviceScope->Length;
832        }
833
834        DtPopSubtable ();
835        DtPopSubtable ();
836    }
837
838    return (AE_OK);
839}
840
841
842/******************************************************************************
843 *
844 * FUNCTION:    DtCompileDrtm
845 *
846 * PARAMETERS:  List                - Current field list pointer
847 *
848 * RETURN:      Status
849 *
850 * DESCRIPTION: Compile DRTM.
851 *
852 *****************************************************************************/
853
854ACPI_STATUS
855DtCompileDrtm (
856    void                    **List)
857{
858    ACPI_STATUS             Status;
859    DT_SUBTABLE             *Subtable;
860    DT_SUBTABLE             *ParentTable;
861    DT_FIELD                **PFieldList = (DT_FIELD **) List;
862    UINT32                  Count;
863    /* ACPI_TABLE_DRTM         *Drtm; */
864    ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
865    ACPI_DRTM_RESOURCE_LIST *DrtmRl;
866    /* ACPI_DRTM_DPS_ID        *DrtmDps; */
867
868
869    ParentTable = DtPeekSubtable ();
870
871    /* Compile DRTM header */
872
873    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
874                &Subtable, TRUE);
875    if (ACPI_FAILURE (Status))
876    {
877        return (Status);
878    }
879    DtInsertSubtable (ParentTable, Subtable);
880
881    /*
882     * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
883     * should be taken to avoid accessing ACPI_TABLE_HADER fields.
884     */
885#if 0
886    Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
887                    Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
888#endif
889    /* Compile VTL */
890
891    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
892                &Subtable, TRUE);
893    if (ACPI_FAILURE (Status))
894    {
895        return (Status);
896    }
897    DtInsertSubtable (ParentTable, Subtable);
898    DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
899
900    DtPushSubtable (Subtable);
901    ParentTable = DtPeekSubtable ();
902    Count = 0;
903    while (*PFieldList)
904    {
905        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
906                    &Subtable, TRUE);
907        if (ACPI_FAILURE (Status))
908        {
909            return (Status);
910        }
911        if (!Subtable)
912        {
913            break;
914        }
915        DtInsertSubtable (ParentTable, Subtable);
916        Count++;
917    }
918    DrtmVtl->ValidatedTableCount = Count;
919    DtPopSubtable ();
920    ParentTable = DtPeekSubtable ();
921
922    /* Compile RL */
923
924    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
925                &Subtable, TRUE);
926    if (ACPI_FAILURE (Status))
927    {
928        return (Status);
929    }
930    DtInsertSubtable (ParentTable, Subtable);
931    DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
932
933    DtPushSubtable (Subtable);
934    ParentTable = DtPeekSubtable ();
935    Count = 0;
936    while (*PFieldList)
937    {
938        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
939                    &Subtable, TRUE);
940        if (ACPI_FAILURE (Status))
941        {
942            return (Status);
943        }
944        if (!Subtable)
945        {
946            break;
947        }
948        DtInsertSubtable (ParentTable, Subtable);
949        Count++;
950    }
951    DrtmRl->ResourceCount = Count;
952    DtPopSubtable ();
953    ParentTable = DtPeekSubtable ();
954
955    /* Compile DPS */
956
957    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
958                &Subtable, TRUE);
959    if (ACPI_FAILURE (Status))
960    {
961        return (Status);
962    }
963    DtInsertSubtable (ParentTable, Subtable);
964    /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
965
966
967    return (AE_OK);
968}
969
970
971/******************************************************************************
972 *
973 * FUNCTION:    DtCompileEinj
974 *
975 * PARAMETERS:  List                - Current field list pointer
976 *
977 * RETURN:      Status
978 *
979 * DESCRIPTION: Compile EINJ.
980 *
981 *****************************************************************************/
982
983ACPI_STATUS
984DtCompileEinj (
985    void                    **List)
986{
987    ACPI_STATUS             Status;
988
989
990    Status = DtCompileTwoSubtables (List,
991                 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
992    return (Status);
993}
994
995
996/******************************************************************************
997 *
998 * FUNCTION:    DtCompileErst
999 *
1000 * PARAMETERS:  List                - Current field list pointer
1001 *
1002 * RETURN:      Status
1003 *
1004 * DESCRIPTION: Compile ERST.
1005 *
1006 *****************************************************************************/
1007
1008ACPI_STATUS
1009DtCompileErst (
1010    void                    **List)
1011{
1012    ACPI_STATUS             Status;
1013
1014
1015    Status = DtCompileTwoSubtables (List,
1016                 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1017    return (Status);
1018}
1019
1020
1021/******************************************************************************
1022 *
1023 * FUNCTION:    DtCompileFadt
1024 *
1025 * PARAMETERS:  List                - Current field list pointer
1026 *
1027 * RETURN:      Status
1028 *
1029 * DESCRIPTION: Compile FADT.
1030 *
1031 *****************************************************************************/
1032
1033ACPI_STATUS
1034DtCompileFadt (
1035    void                    **List)
1036{
1037    ACPI_STATUS             Status;
1038    DT_SUBTABLE             *Subtable;
1039    DT_SUBTABLE             *ParentTable;
1040    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1041    ACPI_TABLE_HEADER       *Table;
1042    UINT8                   Revision;
1043
1044
1045    Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
1046                &Subtable, TRUE);
1047    if (ACPI_FAILURE (Status))
1048    {
1049        return (Status);
1050    }
1051
1052    ParentTable = DtPeekSubtable ();
1053    DtInsertSubtable (ParentTable, Subtable);
1054
1055    Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1056    Revision = Table->Revision;
1057
1058    if (Revision == 2)
1059    {
1060        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
1061                    &Subtable, TRUE);
1062        if (ACPI_FAILURE (Status))
1063        {
1064            return (Status);
1065        }
1066
1067        DtInsertSubtable (ParentTable, Subtable);
1068    }
1069    else if (Revision >= 2)
1070    {
1071        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
1072                    &Subtable, TRUE);
1073        if (ACPI_FAILURE (Status))
1074        {
1075            return (Status);
1076        }
1077
1078        DtInsertSubtable (ParentTable, Subtable);
1079
1080        if (Revision >= 5)
1081        {
1082            Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
1083                        &Subtable, TRUE);
1084            if (ACPI_FAILURE (Status))
1085            {
1086                return (Status);
1087            }
1088
1089            DtInsertSubtable (ParentTable, Subtable);
1090        }
1091
1092        if (Revision >= 6)
1093        {
1094            Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt6,
1095                        &Subtable, TRUE);
1096            if (ACPI_FAILURE (Status))
1097            {
1098                return (Status);
1099            }
1100
1101            DtInsertSubtable (ParentTable, Subtable);
1102        }
1103    }
1104
1105    return (AE_OK);
1106}
1107
1108/******************************************************************************
1109 *
1110 * FUNCTION:    DtCompileGtdt
1111 *
1112 * PARAMETERS:  List                - Current field list pointer
1113 *
1114 * RETURN:      Status
1115 *
1116 * DESCRIPTION: Compile GTDT.
1117 *
1118 *****************************************************************************/
1119
1120ACPI_STATUS
1121DtCompileGtdt (
1122    void                    **List)
1123{
1124    ACPI_STATUS             Status;
1125    DT_SUBTABLE             *Subtable;
1126    DT_SUBTABLE             *ParentTable;
1127    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1128    DT_FIELD                *SubtableStart;
1129    ACPI_SUBTABLE_HEADER    *GtdtHeader;
1130    ACPI_DMTABLE_INFO       *InfoTable;
1131    UINT32                  GtCount;
1132
1133
1134    Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1135                &Subtable, TRUE);
1136    if (ACPI_FAILURE (Status))
1137    {
1138        return (Status);
1139    }
1140
1141    ParentTable = DtPeekSubtable ();
1142    DtInsertSubtable (ParentTable, Subtable);
1143
1144    while (*PFieldList)
1145    {
1146        SubtableStart = *PFieldList;
1147        Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1148                    &Subtable, TRUE);
1149        if (ACPI_FAILURE (Status))
1150        {
1151            return (Status);
1152        }
1153
1154        ParentTable = DtPeekSubtable ();
1155        DtInsertSubtable (ParentTable, Subtable);
1156        DtPushSubtable (Subtable);
1157
1158        GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1159
1160        switch (GtdtHeader->Type)
1161        {
1162        case ACPI_GTDT_TYPE_TIMER_BLOCK:
1163
1164            InfoTable = AcpiDmTableInfoGtdt0;
1165            break;
1166
1167        case ACPI_GTDT_TYPE_WATCHDOG:
1168
1169            InfoTable = AcpiDmTableInfoGtdt1;
1170            break;
1171
1172        default:
1173
1174            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1175            return (AE_ERROR);
1176        }
1177
1178        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1179        if (ACPI_FAILURE (Status))
1180        {
1181            return (Status);
1182        }
1183
1184        ParentTable = DtPeekSubtable ();
1185        DtInsertSubtable (ParentTable, Subtable);
1186
1187        /*
1188         * Additional GT block subtable data
1189         */
1190
1191        switch (GtdtHeader->Type)
1192        {
1193        case ACPI_GTDT_TYPE_TIMER_BLOCK:
1194
1195            DtPushSubtable (Subtable);
1196            ParentTable = DtPeekSubtable ();
1197
1198            GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1199                Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1200            while (GtCount)
1201            {
1202                Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1203                            &Subtable, TRUE);
1204                if (ACPI_FAILURE (Status))
1205                {
1206                    return (Status);
1207                }
1208
1209
1210                DtInsertSubtable (ParentTable, Subtable);
1211                GtCount--;
1212            }
1213            DtPopSubtable ();
1214            break;
1215
1216        default:
1217
1218            break;
1219        }
1220
1221        DtPopSubtable ();
1222    }
1223
1224    return (AE_OK);
1225}
1226
1227
1228/******************************************************************************
1229 *
1230 * FUNCTION:    DtCompileFpdt
1231 *
1232 * PARAMETERS:  List                - Current field list pointer
1233 *
1234 * RETURN:      Status
1235 *
1236 * DESCRIPTION: Compile FPDT.
1237 *
1238 *****************************************************************************/
1239
1240ACPI_STATUS
1241DtCompileFpdt (
1242    void                    **List)
1243{
1244    ACPI_STATUS             Status;
1245    ACPI_FPDT_HEADER        *FpdtHeader;
1246    DT_SUBTABLE             *Subtable;
1247    DT_SUBTABLE             *ParentTable;
1248    ACPI_DMTABLE_INFO       *InfoTable;
1249    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1250    DT_FIELD                *SubtableStart;
1251
1252
1253    while (*PFieldList)
1254    {
1255        SubtableStart = *PFieldList;
1256        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1257                    &Subtable, TRUE);
1258        if (ACPI_FAILURE (Status))
1259        {
1260            return (Status);
1261        }
1262
1263        ParentTable = DtPeekSubtable ();
1264        DtInsertSubtable (ParentTable, Subtable);
1265        DtPushSubtable (Subtable);
1266
1267        FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1268
1269        switch (FpdtHeader->Type)
1270        {
1271        case ACPI_FPDT_TYPE_BOOT:
1272
1273            InfoTable = AcpiDmTableInfoFpdt0;
1274            break;
1275
1276        case ACPI_FPDT_TYPE_S3PERF:
1277
1278            InfoTable = AcpiDmTableInfoFpdt1;
1279            break;
1280
1281        default:
1282
1283            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1284            return (AE_ERROR);
1285            break;
1286        }
1287
1288        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1289        if (ACPI_FAILURE (Status))
1290        {
1291            return (Status);
1292        }
1293
1294        ParentTable = DtPeekSubtable ();
1295        DtInsertSubtable (ParentTable, Subtable);
1296        DtPopSubtable ();
1297    }
1298
1299    return (AE_OK);
1300}
1301
1302
1303/******************************************************************************
1304 *
1305 * FUNCTION:    DtCompileHest
1306 *
1307 * PARAMETERS:  List                - Current field list pointer
1308 *
1309 * RETURN:      Status
1310 *
1311 * DESCRIPTION: Compile HEST.
1312 *
1313 *****************************************************************************/
1314
1315ACPI_STATUS
1316DtCompileHest (
1317    void                    **List)
1318{
1319    ACPI_STATUS             Status;
1320    DT_SUBTABLE             *Subtable;
1321    DT_SUBTABLE             *ParentTable;
1322    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1323    DT_FIELD                *SubtableStart;
1324    ACPI_DMTABLE_INFO       *InfoTable;
1325    UINT16                  Type;
1326    UINT32                  BankCount;
1327
1328
1329    Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1330                &Subtable, TRUE);
1331    if (ACPI_FAILURE (Status))
1332    {
1333        return (Status);
1334    }
1335
1336    ParentTable = DtPeekSubtable ();
1337    DtInsertSubtable (ParentTable, Subtable);
1338
1339    while (*PFieldList)
1340    {
1341        /* Get subtable type */
1342
1343        SubtableStart = *PFieldList;
1344        DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1345
1346        switch (Type)
1347        {
1348        case ACPI_HEST_TYPE_IA32_CHECK:
1349
1350            InfoTable = AcpiDmTableInfoHest0;
1351            break;
1352
1353        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1354
1355            InfoTable = AcpiDmTableInfoHest1;
1356            break;
1357
1358        case ACPI_HEST_TYPE_IA32_NMI:
1359
1360            InfoTable = AcpiDmTableInfoHest2;
1361            break;
1362
1363        case ACPI_HEST_TYPE_AER_ROOT_PORT:
1364
1365            InfoTable = AcpiDmTableInfoHest6;
1366            break;
1367
1368        case ACPI_HEST_TYPE_AER_ENDPOINT:
1369
1370            InfoTable = AcpiDmTableInfoHest7;
1371            break;
1372
1373        case ACPI_HEST_TYPE_AER_BRIDGE:
1374
1375            InfoTable = AcpiDmTableInfoHest8;
1376            break;
1377
1378        case ACPI_HEST_TYPE_GENERIC_ERROR:
1379
1380            InfoTable = AcpiDmTableInfoHest9;
1381            break;
1382
1383        default:
1384
1385            /* Cannot continue on unknown type */
1386
1387            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1388            return (AE_ERROR);
1389        }
1390
1391        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1392        if (ACPI_FAILURE (Status))
1393        {
1394            return (Status);
1395        }
1396
1397        DtInsertSubtable (ParentTable, Subtable);
1398
1399        /*
1400         * Additional subtable data - IA32 Error Bank(s)
1401         */
1402        BankCount = 0;
1403        switch (Type)
1404        {
1405        case ACPI_HEST_TYPE_IA32_CHECK:
1406
1407            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1408                            Subtable->Buffer))->NumHardwareBanks;
1409            break;
1410
1411        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1412
1413            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1414                            Subtable->Buffer))->NumHardwareBanks;
1415            break;
1416
1417        default:
1418
1419            break;
1420        }
1421
1422        while (BankCount)
1423        {
1424            Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1425                        &Subtable, TRUE);
1426            if (ACPI_FAILURE (Status))
1427            {
1428                return (Status);
1429            }
1430
1431            DtInsertSubtable (ParentTable, Subtable);
1432            BankCount--;
1433        }
1434    }
1435
1436    return (AE_OK);
1437}
1438
1439
1440/******************************************************************************
1441 *
1442 * FUNCTION:    DtCompileIort
1443 *
1444 * PARAMETERS:  List                - Current field list pointer
1445 *
1446 * RETURN:      Status
1447 *
1448 * DESCRIPTION: Compile IORT.
1449 *
1450 *****************************************************************************/
1451
1452ACPI_STATUS
1453DtCompileIort (
1454    void                    **List)
1455{
1456    ACPI_STATUS             Status;
1457    DT_SUBTABLE             *Subtable;
1458    DT_SUBTABLE             *ParentTable;
1459    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1460    DT_FIELD                *SubtableStart;
1461    ACPI_TABLE_IORT         *Iort;
1462    ACPI_IORT_NODE          *IortNode;
1463    ACPI_IORT_ITS_GROUP     *IortItsGroup;
1464    ACPI_IORT_SMMU          *IortSmmu;
1465    UINT32                  NodeNumber;
1466    UINT32                  NodeLength;
1467    UINT32                  IdMappingNumber;
1468    UINT32                  ItsNumber;
1469    UINT32                  ContextIrptNumber;
1470    UINT32                  PmuIrptNumber;
1471    UINT32                  PaddingLength;
1472
1473
1474    ParentTable = DtPeekSubtable ();
1475
1476    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1477                &Subtable, TRUE);
1478    if (ACPI_FAILURE (Status))
1479    {
1480        return (Status);
1481    }
1482    DtInsertSubtable (ParentTable, Subtable);
1483
1484    /*
1485     * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
1486     * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1487     */
1488    Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1489                    Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1490
1491    /*
1492     * OptionalPadding - Variable-length data
1493     * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1494     * Optionally allows the generic data types to be used for filling
1495     * this field.
1496     */
1497    Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1498    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1499                    &Subtable, TRUE);
1500    if (ACPI_FAILURE (Status))
1501    {
1502        return (Status);
1503    }
1504    if (Subtable)
1505    {
1506        DtInsertSubtable (ParentTable, Subtable);
1507        Iort->NodeOffset += Subtable->Length;
1508    }
1509    else
1510    {
1511        Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1512                    AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1513        if (ACPI_FAILURE (Status))
1514        {
1515            return (Status);
1516        }
1517        Iort->NodeOffset += PaddingLength;
1518    }
1519
1520    NodeNumber = 0;
1521    while (*PFieldList)
1522    {
1523        SubtableStart = *PFieldList;
1524        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1525                    &Subtable, TRUE);
1526        if (ACPI_FAILURE (Status))
1527        {
1528            return (Status);
1529        }
1530        DtInsertSubtable (ParentTable, Subtable);
1531        IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1532        NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1533
1534        DtPushSubtable (Subtable);
1535        ParentTable = DtPeekSubtable ();
1536
1537        switch (IortNode->Type)
1538        {
1539        case ACPI_IORT_NODE_ITS_GROUP:
1540
1541            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1542                        &Subtable, TRUE);
1543            if (ACPI_FAILURE (Status))
1544            {
1545                return (Status);
1546            }
1547            DtInsertSubtable (ParentTable, Subtable);
1548            IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1549            NodeLength += Subtable->Length;
1550
1551            ItsNumber = 0;
1552            while (*PFieldList)
1553            {
1554                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1555                            &Subtable, TRUE);
1556                if (ACPI_FAILURE (Status))
1557                {
1558                    return (Status);
1559                }
1560                if (!Subtable)
1561                {
1562                    break;
1563                }
1564                DtInsertSubtable (ParentTable, Subtable);
1565                NodeLength += Subtable->Length;
1566                ItsNumber++;
1567            }
1568
1569            IortItsGroup->ItsCount = ItsNumber;
1570            break;
1571
1572        case ACPI_IORT_NODE_NAMED_COMPONENT:
1573
1574            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1575                        &Subtable, TRUE);
1576            if (ACPI_FAILURE (Status))
1577            {
1578                return (Status);
1579            }
1580            DtInsertSubtable (ParentTable, Subtable);
1581            NodeLength += Subtable->Length;
1582
1583            /*
1584             * Padding - Variable-length data
1585             * Optionally allows the offset of the ID mappings to be used
1586             * for filling this field.
1587             */
1588            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1589                            &Subtable, TRUE);
1590            if (ACPI_FAILURE (Status))
1591            {
1592                return (Status);
1593            }
1594            if (Subtable)
1595            {
1596                DtInsertSubtable (ParentTable, Subtable);
1597                NodeLength += Subtable->Length;
1598            }
1599            else
1600            {
1601                if (NodeLength > IortNode->MappingOffset)
1602                {
1603                    return (AE_BAD_DATA);
1604                }
1605                if (NodeLength < IortNode->MappingOffset)
1606                {
1607                    Status = DtCompilePadding (
1608                                IortNode->MappingOffset - NodeLength,
1609                                &Subtable);
1610                    if (ACPI_FAILURE (Status))
1611                    {
1612                        return (Status);
1613                    }
1614                    DtInsertSubtable (ParentTable, Subtable);
1615                    NodeLength = IortNode->MappingOffset;
1616                }
1617            }
1618            break;
1619
1620        case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1621
1622            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1623                        &Subtable, TRUE);
1624            if (ACPI_FAILURE (Status))
1625            {
1626                return (Status);
1627            }
1628            DtInsertSubtable (ParentTable, Subtable);
1629            NodeLength += Subtable->Length;
1630            break;
1631
1632        case ACPI_IORT_NODE_SMMU:
1633
1634            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1635                        &Subtable, TRUE);
1636            if (ACPI_FAILURE (Status))
1637            {
1638                return (Status);
1639            }
1640            DtInsertSubtable (ParentTable, Subtable);
1641            IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1642            NodeLength += Subtable->Length;
1643
1644            /* Compile global interrupt array */
1645
1646            IortSmmu->GlobalInterruptOffset = NodeLength;
1647            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1648                        &Subtable, TRUE);
1649            if (ACPI_FAILURE (Status))
1650            {
1651                return (Status);
1652            }
1653            DtInsertSubtable (ParentTable, Subtable);
1654            NodeLength += Subtable->Length;
1655
1656            /* Compile context interrupt array */
1657
1658            ContextIrptNumber = 0;
1659            IortSmmu->ContextInterruptOffset = NodeLength;
1660            while (*PFieldList)
1661            {
1662                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1663                            &Subtable, TRUE);
1664                if (ACPI_FAILURE (Status))
1665                {
1666                    return (Status);
1667                }
1668                if (!Subtable)
1669                {
1670                    break;
1671                }
1672                DtInsertSubtable (ParentTable, Subtable);
1673                NodeLength += Subtable->Length;
1674                ContextIrptNumber++;
1675            }
1676            IortSmmu->ContextInterruptCount = ContextIrptNumber;
1677
1678            /* Compile PMU interrupt array */
1679
1680            PmuIrptNumber = 0;
1681            IortSmmu->PmuInterruptOffset = NodeLength;
1682            while (*PFieldList)
1683            {
1684                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1685                            &Subtable, TRUE);
1686                if (ACPI_FAILURE (Status))
1687                {
1688                    return (Status);
1689                }
1690                if (!Subtable)
1691                {
1692                    break;
1693                }
1694                DtInsertSubtable (ParentTable, Subtable);
1695                NodeLength += Subtable->Length;
1696                PmuIrptNumber++;
1697            }
1698            IortSmmu->PmuInterruptCount = PmuIrptNumber;
1699            break;
1700
1701        default:
1702
1703            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1704            return (AE_ERROR);
1705        }
1706
1707        /* Compile Array of ID mappings */
1708
1709        IortNode->MappingOffset = NodeLength;
1710        IdMappingNumber = 0;
1711        while (*PFieldList)
1712        {
1713            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1714                        &Subtable, TRUE);
1715            if (ACPI_FAILURE (Status))
1716            {
1717                return (Status);
1718            }
1719            if (!Subtable)
1720            {
1721                break;
1722            }
1723            DtInsertSubtable (ParentTable, Subtable);
1724            NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1725            IdMappingNumber++;
1726        }
1727        IortNode->MappingCount = IdMappingNumber;
1728
1729        /*
1730         * Node length can be determined by DT_LENGTH option
1731         * IortNode->Length = NodeLength;
1732         */
1733        DtPopSubtable ();
1734        ParentTable = DtPeekSubtable ();
1735        NodeNumber++;
1736    }
1737    Iort->NodeCount = NodeNumber;
1738
1739    return (AE_OK);
1740}
1741
1742
1743/******************************************************************************
1744 *
1745 * FUNCTION:    DtCompileIvrs
1746 *
1747 * PARAMETERS:  List                - Current field list pointer
1748 *
1749 * RETURN:      Status
1750 *
1751 * DESCRIPTION: Compile IVRS.
1752 *
1753 *****************************************************************************/
1754
1755ACPI_STATUS
1756DtCompileIvrs (
1757    void                    **List)
1758{
1759    ACPI_STATUS             Status;
1760    DT_SUBTABLE             *Subtable;
1761    DT_SUBTABLE             *ParentTable;
1762    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1763    DT_FIELD                *SubtableStart;
1764    ACPI_DMTABLE_INFO       *InfoTable;
1765    ACPI_IVRS_HEADER        *IvrsHeader;
1766    UINT8                   EntryType;
1767
1768
1769    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1770                &Subtable, TRUE);
1771    if (ACPI_FAILURE (Status))
1772    {
1773        return (Status);
1774    }
1775
1776    ParentTable = DtPeekSubtable ();
1777    DtInsertSubtable (ParentTable, Subtable);
1778
1779    while (*PFieldList)
1780    {
1781        SubtableStart = *PFieldList;
1782        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1783                    &Subtable, TRUE);
1784        if (ACPI_FAILURE (Status))
1785        {
1786            return (Status);
1787        }
1788
1789        ParentTable = DtPeekSubtable ();
1790        DtInsertSubtable (ParentTable, Subtable);
1791        DtPushSubtable (Subtable);
1792
1793        IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1794
1795        switch (IvrsHeader->Type)
1796        {
1797        case ACPI_IVRS_TYPE_HARDWARE:
1798
1799            InfoTable = AcpiDmTableInfoIvrs0;
1800            break;
1801
1802        case ACPI_IVRS_TYPE_MEMORY1:
1803        case ACPI_IVRS_TYPE_MEMORY2:
1804        case ACPI_IVRS_TYPE_MEMORY3:
1805
1806            InfoTable = AcpiDmTableInfoIvrs1;
1807            break;
1808
1809        default:
1810
1811            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1812            return (AE_ERROR);
1813        }
1814
1815        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1816        if (ACPI_FAILURE (Status))
1817        {
1818            return (Status);
1819        }
1820
1821        ParentTable = DtPeekSubtable ();
1822        DtInsertSubtable (ParentTable, Subtable);
1823
1824        if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1825        {
1826            while (*PFieldList &&
1827                    !strcmp ((*PFieldList)->Name, "Entry Type"))
1828            {
1829                SubtableStart = *PFieldList;
1830                DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1831
1832                switch (EntryType)
1833                {
1834                /* 4-byte device entries */
1835
1836                case ACPI_IVRS_TYPE_PAD4:
1837                case ACPI_IVRS_TYPE_ALL:
1838                case ACPI_IVRS_TYPE_SELECT:
1839                case ACPI_IVRS_TYPE_START:
1840                case ACPI_IVRS_TYPE_END:
1841
1842                    InfoTable = AcpiDmTableInfoIvrs4;
1843                    break;
1844
1845                /* 8-byte entries, type A */
1846
1847                case ACPI_IVRS_TYPE_ALIAS_SELECT:
1848                case ACPI_IVRS_TYPE_ALIAS_START:
1849
1850                    InfoTable = AcpiDmTableInfoIvrs8a;
1851                    break;
1852
1853                /* 8-byte entries, type B */
1854
1855                case ACPI_IVRS_TYPE_PAD8:
1856                case ACPI_IVRS_TYPE_EXT_SELECT:
1857                case ACPI_IVRS_TYPE_EXT_START:
1858
1859                    InfoTable = AcpiDmTableInfoIvrs8b;
1860                    break;
1861
1862                /* 8-byte entries, type C */
1863
1864                case ACPI_IVRS_TYPE_SPECIAL:
1865
1866                    InfoTable = AcpiDmTableInfoIvrs8c;
1867                    break;
1868
1869                default:
1870
1871                    DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1872                        "IVRS Device Entry");
1873                    return (AE_ERROR);
1874                }
1875
1876                Status = DtCompileTable (PFieldList, InfoTable,
1877                            &Subtable, TRUE);
1878                if (ACPI_FAILURE (Status))
1879                {
1880                    return (Status);
1881                }
1882
1883                DtInsertSubtable (ParentTable, Subtable);
1884            }
1885        }
1886
1887        DtPopSubtable ();
1888    }
1889
1890    return (AE_OK);
1891}
1892
1893
1894/******************************************************************************
1895 *
1896 * FUNCTION:    DtCompileLpit
1897 *
1898 * PARAMETERS:  List                - Current field list pointer
1899 *
1900 * RETURN:      Status
1901 *
1902 * DESCRIPTION: Compile LPIT.
1903 *
1904 *****************************************************************************/
1905
1906ACPI_STATUS
1907DtCompileLpit (
1908    void                    **List)
1909{
1910    ACPI_STATUS             Status;
1911    DT_SUBTABLE             *Subtable;
1912    DT_SUBTABLE             *ParentTable;
1913    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1914    DT_FIELD                *SubtableStart;
1915    ACPI_DMTABLE_INFO       *InfoTable;
1916    ACPI_LPIT_HEADER        *LpitHeader;
1917
1918
1919    /* Note: Main table consists only of the standard ACPI table header */
1920
1921    while (*PFieldList)
1922    {
1923        SubtableStart = *PFieldList;
1924
1925        /* LPIT Subtable header */
1926
1927        Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1928                    &Subtable, TRUE);
1929        if (ACPI_FAILURE (Status))
1930        {
1931            return (Status);
1932        }
1933
1934        ParentTable = DtPeekSubtable ();
1935        DtInsertSubtable (ParentTable, Subtable);
1936        DtPushSubtable (Subtable);
1937
1938        LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1939
1940        switch (LpitHeader->Type)
1941        {
1942        case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1943
1944            InfoTable = AcpiDmTableInfoLpit0;
1945            break;
1946
1947        default:
1948
1949            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1950            return (AE_ERROR);
1951        }
1952
1953        /* LPIT Subtable */
1954
1955        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1956        if (ACPI_FAILURE (Status))
1957        {
1958            return (Status);
1959        }
1960
1961        ParentTable = DtPeekSubtable ();
1962        DtInsertSubtable (ParentTable, Subtable);
1963        DtPopSubtable ();
1964    }
1965
1966    return (AE_OK);
1967}
1968
1969
1970/******************************************************************************
1971 *
1972 * FUNCTION:    DtCompileMadt
1973 *
1974 * PARAMETERS:  List                - Current field list pointer
1975 *
1976 * RETURN:      Status
1977 *
1978 * DESCRIPTION: Compile MADT.
1979 *
1980 *****************************************************************************/
1981
1982ACPI_STATUS
1983DtCompileMadt (
1984    void                    **List)
1985{
1986    ACPI_STATUS             Status;
1987    DT_SUBTABLE             *Subtable;
1988    DT_SUBTABLE             *ParentTable;
1989    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1990    DT_FIELD                *SubtableStart;
1991    ACPI_SUBTABLE_HEADER    *MadtHeader;
1992    ACPI_DMTABLE_INFO       *InfoTable;
1993
1994
1995    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1996                &Subtable, TRUE);
1997    if (ACPI_FAILURE (Status))
1998    {
1999        return (Status);
2000    }
2001
2002    ParentTable = DtPeekSubtable ();
2003    DtInsertSubtable (ParentTable, Subtable);
2004
2005    while (*PFieldList)
2006    {
2007        SubtableStart = *PFieldList;
2008        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
2009                    &Subtable, TRUE);
2010        if (ACPI_FAILURE (Status))
2011        {
2012            return (Status);
2013        }
2014
2015        ParentTable = DtPeekSubtable ();
2016        DtInsertSubtable (ParentTable, Subtable);
2017        DtPushSubtable (Subtable);
2018
2019        MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2020
2021        switch (MadtHeader->Type)
2022        {
2023        case ACPI_MADT_TYPE_LOCAL_APIC:
2024
2025            InfoTable = AcpiDmTableInfoMadt0;
2026            break;
2027
2028        case ACPI_MADT_TYPE_IO_APIC:
2029
2030            InfoTable = AcpiDmTableInfoMadt1;
2031            break;
2032
2033        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
2034
2035            InfoTable = AcpiDmTableInfoMadt2;
2036            break;
2037
2038        case ACPI_MADT_TYPE_NMI_SOURCE:
2039
2040            InfoTable = AcpiDmTableInfoMadt3;
2041            break;
2042
2043        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
2044
2045            InfoTable = AcpiDmTableInfoMadt4;
2046            break;
2047
2048        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
2049
2050            InfoTable = AcpiDmTableInfoMadt5;
2051            break;
2052
2053        case ACPI_MADT_TYPE_IO_SAPIC:
2054
2055            InfoTable = AcpiDmTableInfoMadt6;
2056            break;
2057
2058        case ACPI_MADT_TYPE_LOCAL_SAPIC:
2059
2060            InfoTable = AcpiDmTableInfoMadt7;
2061            break;
2062
2063        case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
2064
2065            InfoTable = AcpiDmTableInfoMadt8;
2066            break;
2067
2068        case ACPI_MADT_TYPE_LOCAL_X2APIC:
2069
2070            InfoTable = AcpiDmTableInfoMadt9;
2071            break;
2072
2073        case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
2074
2075            InfoTable = AcpiDmTableInfoMadt10;
2076            break;
2077
2078        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
2079
2080            InfoTable = AcpiDmTableInfoMadt11;
2081            break;
2082
2083        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
2084
2085            InfoTable = AcpiDmTableInfoMadt12;
2086            break;
2087
2088        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
2089
2090            InfoTable = AcpiDmTableInfoMadt13;
2091            break;
2092
2093        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
2094
2095            InfoTable = AcpiDmTableInfoMadt14;
2096            break;
2097
2098        case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
2099
2100            InfoTable = AcpiDmTableInfoMadt15;
2101            break;
2102
2103        default:
2104
2105            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
2106            return (AE_ERROR);
2107        }
2108
2109        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2110        if (ACPI_FAILURE (Status))
2111        {
2112            return (Status);
2113        }
2114
2115        ParentTable = DtPeekSubtable ();
2116        DtInsertSubtable (ParentTable, Subtable);
2117        DtPopSubtable ();
2118    }
2119
2120    return (AE_OK);
2121}
2122
2123
2124/******************************************************************************
2125 *
2126 * FUNCTION:    DtCompileMcfg
2127 *
2128 * PARAMETERS:  List                - Current field list pointer
2129 *
2130 * RETURN:      Status
2131 *
2132 * DESCRIPTION: Compile MCFG.
2133 *
2134 *****************************************************************************/
2135
2136ACPI_STATUS
2137DtCompileMcfg (
2138    void                    **List)
2139{
2140    ACPI_STATUS             Status;
2141
2142
2143    Status = DtCompileTwoSubtables (List,
2144                 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
2145    return (Status);
2146}
2147
2148
2149/******************************************************************************
2150 *
2151 * FUNCTION:    DtCompileMpst
2152 *
2153 * PARAMETERS:  List                - Current field list pointer
2154 *
2155 * RETURN:      Status
2156 *
2157 * DESCRIPTION: Compile MPST.
2158 *
2159 *****************************************************************************/
2160
2161ACPI_STATUS
2162DtCompileMpst (
2163    void                    **List)
2164{
2165    ACPI_STATUS             Status;
2166    DT_SUBTABLE             *Subtable;
2167    DT_SUBTABLE             *ParentTable;
2168    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2169    ACPI_MPST_CHANNEL       *MpstChannelInfo;
2170    ACPI_MPST_POWER_NODE    *MpstPowerNode;
2171    ACPI_MPST_DATA_HDR      *MpstDataHeader;
2172    UINT16                  SubtableCount;
2173    UINT32                  PowerStateCount;
2174    UINT32                  ComponentCount;
2175
2176
2177    /* Main table */
2178
2179    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
2180    if (ACPI_FAILURE (Status))
2181    {
2182        return (Status);
2183    }
2184
2185    ParentTable = DtPeekSubtable ();
2186    DtInsertSubtable (ParentTable, Subtable);
2187    DtPushSubtable (Subtable);
2188
2189    MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
2190    SubtableCount = MpstChannelInfo->PowerNodeCount;
2191
2192    while (*PFieldList && SubtableCount)
2193    {
2194        /* Subtable: Memory Power Node(s) */
2195
2196        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
2197                    &Subtable, TRUE);
2198        if (ACPI_FAILURE (Status))
2199        {
2200            return (Status);
2201        }
2202
2203        ParentTable = DtPeekSubtable ();
2204        DtInsertSubtable (ParentTable, Subtable);
2205        DtPushSubtable (Subtable);
2206
2207        MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
2208        PowerStateCount = MpstPowerNode->NumPowerStates;
2209        ComponentCount = MpstPowerNode->NumPhysicalComponents;
2210
2211        ParentTable = DtPeekSubtable ();
2212
2213        /* Sub-subtables - Memory Power State Structure(s) */
2214
2215        while (*PFieldList && PowerStateCount)
2216        {
2217            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
2218                        &Subtable, TRUE);
2219            if (ACPI_FAILURE (Status))
2220            {
2221                return (Status);
2222            }
2223
2224            DtInsertSubtable (ParentTable, Subtable);
2225            PowerStateCount--;
2226        }
2227
2228        /* Sub-subtables - Physical Component ID Structure(s) */
2229
2230        while (*PFieldList && ComponentCount)
2231        {
2232            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
2233                        &Subtable, TRUE);
2234            if (ACPI_FAILURE (Status))
2235            {
2236                return (Status);
2237            }
2238
2239            DtInsertSubtable (ParentTable, Subtable);
2240            ComponentCount--;
2241        }
2242
2243        SubtableCount--;
2244        DtPopSubtable ();
2245    }
2246
2247    /* Subtable: Count of Memory Power State Characteristic structures */
2248
2249    DtPopSubtable ();
2250
2251    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
2252    if (ACPI_FAILURE (Status))
2253    {
2254        return (Status);
2255    }
2256
2257    ParentTable = DtPeekSubtable ();
2258    DtInsertSubtable (ParentTable, Subtable);
2259    DtPushSubtable (Subtable);
2260
2261    MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
2262    SubtableCount = MpstDataHeader->CharacteristicsCount;
2263
2264    ParentTable = DtPeekSubtable ();
2265
2266    /* Subtable: Memory Power State Characteristics structure(s) */
2267
2268    while (*PFieldList && SubtableCount)
2269    {
2270        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
2271                    &Subtable, TRUE);
2272        if (ACPI_FAILURE (Status))
2273        {
2274            return (Status);
2275        }
2276
2277        DtInsertSubtable (ParentTable, Subtable);
2278        SubtableCount--;
2279    }
2280
2281    DtPopSubtable ();
2282    return (AE_OK);
2283}
2284
2285
2286/******************************************************************************
2287 *
2288 * FUNCTION:    DtCompileMsct
2289 *
2290 * PARAMETERS:  List                - Current field list pointer
2291 *
2292 * RETURN:      Status
2293 *
2294 * DESCRIPTION: Compile MSCT.
2295 *
2296 *****************************************************************************/
2297
2298ACPI_STATUS
2299DtCompileMsct (
2300    void                    **List)
2301{
2302    ACPI_STATUS             Status;
2303
2304
2305    Status = DtCompileTwoSubtables (List,
2306                 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
2307    return (Status);
2308}
2309
2310
2311/******************************************************************************
2312 *
2313 * FUNCTION:    DtCompileMtmr
2314 *
2315 * PARAMETERS:  List                - Current field list pointer
2316 *
2317 * RETURN:      Status
2318 *
2319 * DESCRIPTION: Compile MTMR.
2320 *
2321 *****************************************************************************/
2322
2323ACPI_STATUS
2324DtCompileMtmr (
2325    void                    **List)
2326{
2327    ACPI_STATUS             Status;
2328
2329
2330    Status = DtCompileTwoSubtables (List,
2331                 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
2332    return (Status);
2333}
2334
2335
2336/******************************************************************************
2337 *
2338 * FUNCTION:    DtCompileNfit
2339 *
2340 * PARAMETERS:  List                - Current field list pointer
2341 *
2342 * RETURN:      Status
2343 *
2344 * DESCRIPTION: Compile NFIT.
2345 *
2346 *****************************************************************************/
2347
2348ACPI_STATUS
2349DtCompileNfit (
2350    void                    **List)
2351{
2352    ACPI_STATUS             Status;
2353    DT_SUBTABLE             *Subtable;
2354    DT_SUBTABLE             *ParentTable;
2355    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2356    DT_FIELD                *SubtableStart;
2357    ACPI_NFIT_HEADER        *NfitHeader;
2358    ACPI_DMTABLE_INFO       *InfoTable;
2359    UINT32                  Count;
2360    ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
2361    ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
2362
2363    /* Main table */
2364
2365    Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
2366                &Subtable, TRUE);
2367    if (ACPI_FAILURE (Status))
2368    {
2369        return (Status);
2370    }
2371
2372    ParentTable = DtPeekSubtable ();
2373    DtInsertSubtable (ParentTable, Subtable);
2374    DtPushSubtable (Subtable);
2375
2376    /* Subtables */
2377
2378    while (*PFieldList)
2379    {
2380        SubtableStart = *PFieldList;
2381        Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
2382                    &Subtable, TRUE);
2383        if (ACPI_FAILURE (Status))
2384        {
2385            return (Status);
2386        }
2387
2388        ParentTable = DtPeekSubtable ();
2389        DtInsertSubtable (ParentTable, Subtable);
2390        DtPushSubtable (Subtable);
2391
2392        NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
2393
2394        switch (NfitHeader->Type)
2395        {
2396        case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2397
2398            InfoTable = AcpiDmTableInfoNfit0;
2399            break;
2400
2401        case ACPI_NFIT_TYPE_MEMORY_MAP:
2402
2403            InfoTable = AcpiDmTableInfoNfit1;
2404            break;
2405
2406        case ACPI_NFIT_TYPE_INTERLEAVE:
2407
2408            Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
2409            InfoTable = AcpiDmTableInfoNfit2;
2410            break;
2411
2412        case ACPI_NFIT_TYPE_SMBIOS:
2413
2414            InfoTable = AcpiDmTableInfoNfit3;
2415            break;
2416
2417        case ACPI_NFIT_TYPE_CONTROL_REGION:
2418
2419            InfoTable = AcpiDmTableInfoNfit4;
2420            break;
2421
2422        case ACPI_NFIT_TYPE_DATA_REGION:
2423
2424            InfoTable = AcpiDmTableInfoNfit5;
2425            break;
2426
2427        case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2428
2429            Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
2430            InfoTable = AcpiDmTableInfoNfit6;
2431            break;
2432
2433        default:
2434
2435            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
2436            return (AE_ERROR);
2437        }
2438
2439        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2440        if (ACPI_FAILURE (Status))
2441        {
2442            return (Status);
2443        }
2444
2445        ParentTable = DtPeekSubtable ();
2446        DtInsertSubtable (ParentTable, Subtable);
2447        DtPopSubtable ();
2448
2449        switch (NfitHeader->Type)
2450        {
2451        case ACPI_NFIT_TYPE_INTERLEAVE:
2452
2453            Count = 0;
2454            DtPushSubtable (Subtable);
2455            while (*PFieldList)
2456            {
2457                Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
2458                            &Subtable, FALSE);
2459                if (ACPI_FAILURE (Status))
2460                {
2461                    return (Status);
2462                }
2463                if (!Subtable)
2464                {
2465                    DtPopSubtable ();
2466                    break;
2467                }
2468
2469                ParentTable = DtPeekSubtable ();
2470                DtInsertSubtable (ParentTable, Subtable);
2471                Count++;
2472            }
2473
2474            Interleave->LineCount = Count;
2475            DtPopSubtable ();
2476            break;
2477
2478        case ACPI_NFIT_TYPE_SMBIOS:
2479
2480            if (*PFieldList)
2481            {
2482                Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
2483                            &Subtable, TRUE);
2484                if (ACPI_FAILURE (Status))
2485                {
2486                    return (Status);
2487                }
2488                if (Subtable)
2489                {
2490                    DtInsertSubtable (ParentTable, Subtable);
2491                }
2492            }
2493            break;
2494
2495        case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2496
2497            Count = 0;
2498            DtPushSubtable (Subtable);
2499            while (*PFieldList)
2500            {
2501                Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
2502                            &Subtable, FALSE);
2503                if (ACPI_FAILURE (Status))
2504                {
2505                    return (Status);
2506                }
2507                if (!Subtable)
2508                {
2509                    DtPopSubtable ();
2510                    break;
2511                }
2512
2513                ParentTable = DtPeekSubtable ();
2514                DtInsertSubtable (ParentTable, Subtable);
2515                Count++;
2516            }
2517
2518            Hint->HintCount = (UINT16) Count;
2519            DtPopSubtable ();
2520            break;
2521
2522        default:
2523            break;
2524        }
2525    }
2526
2527    return (AE_OK);
2528}
2529
2530
2531/******************************************************************************
2532 *
2533 * FUNCTION:    DtCompilePcct
2534 *
2535 * PARAMETERS:  List                - Current field list pointer
2536 *
2537 * RETURN:      Status
2538 *
2539 * DESCRIPTION: Compile PCCT.
2540 *
2541 *****************************************************************************/
2542
2543ACPI_STATUS
2544DtCompilePcct (
2545    void                    **List)
2546{
2547    ACPI_STATUS             Status;
2548    DT_SUBTABLE             *Subtable;
2549    DT_SUBTABLE             *ParentTable;
2550    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2551    DT_FIELD                *SubtableStart;
2552    ACPI_SUBTABLE_HEADER    *PcctHeader;
2553    ACPI_DMTABLE_INFO       *InfoTable;
2554
2555
2556    /* Main table */
2557
2558    Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
2559                &Subtable, TRUE);
2560    if (ACPI_FAILURE (Status))
2561    {
2562        return (Status);
2563    }
2564
2565    ParentTable = DtPeekSubtable ();
2566    DtInsertSubtable (ParentTable, Subtable);
2567
2568    /* Subtables */
2569
2570    while (*PFieldList)
2571    {
2572        SubtableStart = *PFieldList;
2573        Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
2574                    &Subtable, TRUE);
2575        if (ACPI_FAILURE (Status))
2576        {
2577            return (Status);
2578        }
2579
2580        ParentTable = DtPeekSubtable ();
2581        DtInsertSubtable (ParentTable, Subtable);
2582        DtPushSubtable (Subtable);
2583
2584        PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2585
2586        switch (PcctHeader->Type)
2587        {
2588        case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
2589
2590            InfoTable = AcpiDmTableInfoPcct0;
2591            break;
2592
2593        case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
2594
2595            InfoTable = AcpiDmTableInfoPcct1;
2596            break;
2597
2598        default:
2599
2600            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
2601            return (AE_ERROR);
2602        }
2603
2604        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2605        if (ACPI_FAILURE (Status))
2606        {
2607            return (Status);
2608        }
2609
2610        ParentTable = DtPeekSubtable ();
2611        DtInsertSubtable (ParentTable, Subtable);
2612        DtPopSubtable ();
2613    }
2614
2615    return (AE_OK);
2616}
2617
2618
2619/******************************************************************************
2620 *
2621 * FUNCTION:    DtCompilePmtt
2622 *
2623 * PARAMETERS:  List                - Current field list pointer
2624 *
2625 * RETURN:      Status
2626 *
2627 * DESCRIPTION: Compile PMTT.
2628 *
2629 *****************************************************************************/
2630
2631ACPI_STATUS
2632DtCompilePmtt (
2633    void                    **List)
2634{
2635    ACPI_STATUS             Status;
2636    DT_SUBTABLE             *Subtable;
2637    DT_SUBTABLE             *ParentTable;
2638    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2639    DT_FIELD                *SubtableStart;
2640    ACPI_PMTT_HEADER        *PmttHeader;
2641    ACPI_PMTT_CONTROLLER    *PmttController;
2642    UINT16                  DomainCount;
2643    UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET;
2644
2645
2646    /* Main table */
2647
2648    Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
2649    if (ACPI_FAILURE (Status))
2650    {
2651        return (Status);
2652    }
2653
2654    ParentTable = DtPeekSubtable ();
2655    DtInsertSubtable (ParentTable, Subtable);
2656    DtPushSubtable (Subtable);
2657
2658    while (*PFieldList)
2659    {
2660        SubtableStart = *PFieldList;
2661        Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
2662                    &Subtable, TRUE);
2663        if (ACPI_FAILURE (Status))
2664        {
2665            return (Status);
2666        }
2667
2668        PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
2669        while (PrevType >= PmttHeader->Type)
2670        {
2671            DtPopSubtable ();
2672
2673            if (PrevType == ACPI_PMTT_TYPE_SOCKET)
2674            {
2675                break;
2676            }
2677            PrevType--;
2678        }
2679        PrevType = PmttHeader->Type;
2680
2681        ParentTable = DtPeekSubtable ();
2682        DtInsertSubtable (ParentTable, Subtable);
2683        DtPushSubtable (Subtable);
2684
2685        switch (PmttHeader->Type)
2686        {
2687        case ACPI_PMTT_TYPE_SOCKET:
2688
2689            /* Subtable: Socket Structure */
2690
2691            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
2692                    &Subtable, TRUE);
2693            if (ACPI_FAILURE (Status))
2694            {
2695                return (Status);
2696            }
2697
2698            ParentTable = DtPeekSubtable ();
2699            DtInsertSubtable (ParentTable, Subtable);
2700            break;
2701
2702        case ACPI_PMTT_TYPE_CONTROLLER:
2703
2704            /* Subtable: Memory Controller Structure */
2705
2706            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
2707                    &Subtable, TRUE);
2708            if (ACPI_FAILURE (Status))
2709            {
2710                return (Status);
2711            }
2712
2713            ParentTable = DtPeekSubtable ();
2714            DtInsertSubtable (ParentTable, Subtable);
2715
2716            PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
2717                (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
2718            DomainCount = PmttController->DomainCount;
2719
2720            while (DomainCount)
2721            {
2722                Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
2723                    &Subtable, TRUE);
2724                if (ACPI_FAILURE (Status))
2725                {
2726                    return (Status);
2727                }
2728
2729                DtInsertSubtable (ParentTable, Subtable);
2730                DomainCount--;
2731            }
2732            break;
2733
2734        case ACPI_PMTT_TYPE_DIMM:
2735
2736            /* Subtable: Physical Component Structure */
2737
2738            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
2739                    &Subtable, TRUE);
2740            if (ACPI_FAILURE (Status))
2741            {
2742                return (Status);
2743            }
2744
2745            ParentTable = DtPeekSubtable ();
2746            DtInsertSubtable (ParentTable, Subtable);
2747            break;
2748
2749        default:
2750
2751            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
2752            return (AE_ERROR);
2753        }
2754    }
2755
2756    return (Status);
2757}
2758
2759
2760/******************************************************************************
2761 *
2762 * FUNCTION:    DtCompileRsdt
2763 *
2764 * PARAMETERS:  List                - Current field list pointer
2765 *
2766 * RETURN:      Status
2767 *
2768 * DESCRIPTION: Compile RSDT.
2769 *
2770 *****************************************************************************/
2771
2772ACPI_STATUS
2773DtCompileRsdt (
2774    void                    **List)
2775{
2776    DT_SUBTABLE             *Subtable;
2777    DT_SUBTABLE             *ParentTable;
2778    DT_FIELD                *FieldList = *(DT_FIELD **) List;
2779    UINT32                  Address;
2780
2781
2782    ParentTable = DtPeekSubtable ();
2783
2784    while (FieldList)
2785    {
2786        DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2787
2788        DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2789        DtInsertSubtable (ParentTable, Subtable);
2790        FieldList = FieldList->Next;
2791    }
2792
2793    return (AE_OK);
2794}
2795
2796
2797/******************************************************************************
2798 *
2799 * FUNCTION:    DtCompileS3pt
2800 *
2801 * PARAMETERS:  PFieldList          - Current field list pointer
2802 *
2803 * RETURN:      Status
2804 *
2805 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2806 *
2807 *****************************************************************************/
2808
2809ACPI_STATUS
2810DtCompileS3pt (
2811    DT_FIELD                **PFieldList)
2812{
2813    ACPI_STATUS             Status;
2814    ACPI_S3PT_HEADER        *S3ptHeader;
2815    DT_SUBTABLE             *Subtable;
2816    DT_SUBTABLE             *ParentTable;
2817    ACPI_DMTABLE_INFO       *InfoTable;
2818    DT_FIELD                *SubtableStart;
2819
2820
2821    Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2822                &Gbl_RootTable, TRUE);
2823    if (ACPI_FAILURE (Status))
2824    {
2825        return (Status);
2826    }
2827
2828    DtPushSubtable (Gbl_RootTable);
2829
2830    while (*PFieldList)
2831    {
2832        SubtableStart = *PFieldList;
2833        Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2834                    &Subtable, TRUE);
2835        if (ACPI_FAILURE (Status))
2836        {
2837            return (Status);
2838        }
2839
2840        ParentTable = DtPeekSubtable ();
2841        DtInsertSubtable (ParentTable, Subtable);
2842        DtPushSubtable (Subtable);
2843
2844        S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2845
2846        switch (S3ptHeader->Type)
2847        {
2848        case ACPI_S3PT_TYPE_RESUME:
2849
2850            InfoTable = AcpiDmTableInfoS3pt0;
2851            break;
2852
2853        case ACPI_S3PT_TYPE_SUSPEND:
2854
2855            InfoTable = AcpiDmTableInfoS3pt1;
2856            break;
2857
2858        default:
2859
2860            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2861            return (AE_ERROR);
2862        }
2863
2864        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2865        if (ACPI_FAILURE (Status))
2866        {
2867            return (Status);
2868        }
2869
2870        ParentTable = DtPeekSubtable ();
2871        DtInsertSubtable (ParentTable, Subtable);
2872        DtPopSubtable ();
2873    }
2874
2875    return (AE_OK);
2876}
2877
2878
2879/******************************************************************************
2880 *
2881 * FUNCTION:    DtCompileSlic
2882 *
2883 * PARAMETERS:  List                - Current field list pointer
2884 *
2885 * RETURN:      Status
2886 *
2887 * DESCRIPTION: Compile SLIC.
2888 *
2889 *****************************************************************************/
2890
2891ACPI_STATUS
2892DtCompileSlic (
2893    void                    **List)
2894{
2895    ACPI_STATUS             Status;
2896    DT_SUBTABLE             *Subtable;
2897    DT_SUBTABLE             *ParentTable;
2898    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2899
2900
2901    while (*PFieldList)
2902    {
2903        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2904                    &Subtable, TRUE);
2905        if (ACPI_FAILURE (Status))
2906        {
2907            return (Status);
2908        }
2909
2910        ParentTable = DtPeekSubtable ();
2911        DtInsertSubtable (ParentTable, Subtable);
2912        DtPushSubtable (Subtable);
2913        DtPopSubtable ();
2914    }
2915
2916    return (AE_OK);
2917}
2918
2919
2920/******************************************************************************
2921 *
2922 * FUNCTION:    DtCompileSlit
2923 *
2924 * PARAMETERS:  List                - Current field list pointer
2925 *
2926 * RETURN:      Status
2927 *
2928 * DESCRIPTION: Compile SLIT.
2929 *
2930 *****************************************************************************/
2931
2932ACPI_STATUS
2933DtCompileSlit (
2934    void                    **List)
2935{
2936    ACPI_STATUS             Status;
2937    DT_SUBTABLE             *Subtable;
2938    DT_SUBTABLE             *ParentTable;
2939    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2940    DT_FIELD                *FieldList;
2941    UINT32                  Localities;
2942    UINT8                   *LocalityBuffer;
2943
2944
2945    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2946                &Subtable, TRUE);
2947    if (ACPI_FAILURE (Status))
2948    {
2949        return (Status);
2950    }
2951
2952    ParentTable = DtPeekSubtable ();
2953    DtInsertSubtable (ParentTable, Subtable);
2954
2955    Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2956    LocalityBuffer = UtLocalCalloc (Localities);
2957
2958    /* Compile each locality buffer */
2959
2960    FieldList = *PFieldList;
2961    while (FieldList)
2962    {
2963        DtCompileBuffer (LocalityBuffer,
2964            FieldList->Value, FieldList, Localities);
2965
2966        DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2967        DtInsertSubtable (ParentTable, Subtable);
2968        FieldList = FieldList->Next;
2969    }
2970
2971    ACPI_FREE (LocalityBuffer);
2972    return (AE_OK);
2973}
2974
2975
2976/******************************************************************************
2977 *
2978 * FUNCTION:    DtCompileSrat
2979 *
2980 * PARAMETERS:  List                - Current field list pointer
2981 *
2982 * RETURN:      Status
2983 *
2984 * DESCRIPTION: Compile SRAT.
2985 *
2986 *****************************************************************************/
2987
2988ACPI_STATUS
2989DtCompileSrat (
2990    void                    **List)
2991{
2992    ACPI_STATUS             Status;
2993    DT_SUBTABLE             *Subtable;
2994    DT_SUBTABLE             *ParentTable;
2995    DT_FIELD                **PFieldList = (DT_FIELD **) List;
2996    DT_FIELD                *SubtableStart;
2997    ACPI_SUBTABLE_HEADER    *SratHeader;
2998    ACPI_DMTABLE_INFO       *InfoTable;
2999
3000
3001    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
3002                &Subtable, TRUE);
3003    if (ACPI_FAILURE (Status))
3004    {
3005        return (Status);
3006    }
3007
3008    ParentTable = DtPeekSubtable ();
3009    DtInsertSubtable (ParentTable, Subtable);
3010
3011    while (*PFieldList)
3012    {
3013        SubtableStart = *PFieldList;
3014        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
3015                    &Subtable, TRUE);
3016        if (ACPI_FAILURE (Status))
3017        {
3018            return (Status);
3019        }
3020
3021        ParentTable = DtPeekSubtable ();
3022        DtInsertSubtable (ParentTable, Subtable);
3023        DtPushSubtable (Subtable);
3024
3025        SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
3026
3027        switch (SratHeader->Type)
3028        {
3029        case ACPI_SRAT_TYPE_CPU_AFFINITY:
3030
3031            InfoTable = AcpiDmTableInfoSrat0;
3032            break;
3033
3034        case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
3035
3036            InfoTable = AcpiDmTableInfoSrat1;
3037            break;
3038
3039        case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
3040
3041            InfoTable = AcpiDmTableInfoSrat2;
3042            break;
3043
3044        case ACPI_SRAT_TYPE_GICC_AFFINITY:
3045
3046            InfoTable = AcpiDmTableInfoSrat3;
3047            break;
3048
3049        default:
3050
3051            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
3052            return (AE_ERROR);
3053        }
3054
3055        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
3056        if (ACPI_FAILURE (Status))
3057        {
3058            return (Status);
3059        }
3060
3061        ParentTable = DtPeekSubtable ();
3062        DtInsertSubtable (ParentTable, Subtable);
3063        DtPopSubtable ();
3064    }
3065
3066    return (AE_OK);
3067}
3068
3069
3070/******************************************************************************
3071 *
3072 * FUNCTION:    DtCompileStao
3073 *
3074 * PARAMETERS:  PFieldList          - Current field list pointer
3075 *
3076 * RETURN:      Status
3077 *
3078 * DESCRIPTION: Compile STAO.
3079 *
3080 *****************************************************************************/
3081
3082ACPI_STATUS
3083DtCompileStao (
3084    void                    **List)
3085{
3086    DT_FIELD                **PFieldList = (DT_FIELD **) List;
3087    DT_SUBTABLE             *Subtable;
3088    DT_SUBTABLE             *ParentTable;
3089    ACPI_STATUS             Status;
3090
3091
3092    /* Compile the main table */
3093
3094    Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
3095                &Subtable, TRUE);
3096    if (ACPI_FAILURE (Status))
3097    {
3098        return (Status);
3099    }
3100
3101    ParentTable = DtPeekSubtable ();
3102    DtInsertSubtable (ParentTable, Subtable);
3103
3104    /* Compile each ASCII namestring as a subtable */
3105
3106    while (*PFieldList)
3107    {
3108        Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
3109                    &Subtable, TRUE);
3110        if (ACPI_FAILURE (Status))
3111        {
3112            return (Status);
3113        }
3114
3115        ParentTable = DtPeekSubtable ();
3116        DtInsertSubtable (ParentTable, Subtable);
3117    }
3118
3119    return (AE_OK);
3120}
3121
3122
3123/******************************************************************************
3124 *
3125 * FUNCTION:    DtGetGenericTableInfo
3126 *
3127 * PARAMETERS:  Name                - Generic type name
3128 *
3129 * RETURN:      Info entry
3130 *
3131 * DESCRIPTION: Obtain table info for a generic name entry
3132 *
3133 *****************************************************************************/
3134
3135ACPI_DMTABLE_INFO *
3136DtGetGenericTableInfo (
3137    char                    *Name)
3138{
3139    ACPI_DMTABLE_INFO       *Info;
3140    UINT32                  i;
3141
3142
3143    if (!Name)
3144    {
3145        return (NULL);
3146    }
3147
3148    /* Search info table for name match */
3149
3150    for (i = 0; ; i++)
3151    {
3152        Info = AcpiDmTableInfoGeneric[i];
3153        if (Info->Opcode == ACPI_DMT_EXIT)
3154        {
3155            Info = NULL;
3156            break;
3157        }
3158
3159        /* Use caseless compare for generic keywords */
3160
3161        if (!AcpiUtStricmp (Name, Info->Name))
3162        {
3163            break;
3164        }
3165    }
3166
3167    return (Info);
3168}
3169
3170
3171/******************************************************************************
3172 *
3173 * FUNCTION:    DtCompileUefi
3174 *
3175 * PARAMETERS:  List                - Current field list pointer
3176 *
3177 * RETURN:      Status
3178 *
3179 * DESCRIPTION: Compile UEFI.
3180 *
3181 *****************************************************************************/
3182
3183ACPI_STATUS
3184DtCompileUefi (
3185    void                    **List)
3186{
3187    ACPI_STATUS             Status;
3188    DT_SUBTABLE             *Subtable;
3189    DT_SUBTABLE             *ParentTable;
3190    DT_FIELD                **PFieldList = (DT_FIELD **) List;
3191    UINT16                  *DataOffset;
3192
3193
3194    /* Compile the predefined portion of the UEFI table */
3195
3196    Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
3197                &Subtable, TRUE);
3198    if (ACPI_FAILURE (Status))
3199    {
3200        return (Status);
3201    }
3202
3203    DataOffset = (UINT16 *) (Subtable->Buffer + 16);
3204    *DataOffset = sizeof (ACPI_TABLE_UEFI);
3205
3206    ParentTable = DtPeekSubtable ();
3207    DtInsertSubtable (ParentTable, Subtable);
3208
3209    /*
3210     * Compile the "generic" portion of the UEFI table. This
3211     * part of the table is not predefined and any of the generic
3212     * operators may be used.
3213     */
3214
3215    DtCompileGeneric ((void **) PFieldList, NULL, NULL);
3216
3217    return (AE_OK);
3218}
3219
3220
3221/******************************************************************************
3222 *
3223 * FUNCTION:    DtCompileVrtc
3224 *
3225 * PARAMETERS:  List                - Current field list pointer
3226 *
3227 * RETURN:      Status
3228 *
3229 * DESCRIPTION: Compile VRTC.
3230 *
3231 *****************************************************************************/
3232
3233ACPI_STATUS
3234DtCompileVrtc (
3235    void                    **List)
3236{
3237    ACPI_STATUS             Status;
3238
3239
3240    Status = DtCompileTwoSubtables (List,
3241                 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
3242    return (Status);
3243}
3244
3245
3246/******************************************************************************
3247 *
3248 * FUNCTION:    DtCompileWdat
3249 *
3250 * PARAMETERS:  List                - Current field list pointer
3251 *
3252 * RETURN:      Status
3253 *
3254 * DESCRIPTION: Compile WDAT.
3255 *
3256 *****************************************************************************/
3257
3258ACPI_STATUS
3259DtCompileWdat (
3260    void                    **List)
3261{
3262    ACPI_STATUS             Status;
3263
3264
3265    Status = DtCompileTwoSubtables (List,
3266                 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3267    return (Status);
3268}
3269
3270
3271/******************************************************************************
3272 *
3273 * FUNCTION:    DtCompileWpbt
3274 *
3275 * PARAMETERS:  List                - Current field list pointer
3276 *
3277 * RETURN:      Status
3278 *
3279 * DESCRIPTION: Compile WPBT.
3280 *
3281 *****************************************************************************/
3282
3283ACPI_STATUS
3284DtCompileWpbt (
3285    void                    **List)
3286{
3287    DT_FIELD                **PFieldList = (DT_FIELD **) List;
3288    DT_SUBTABLE             *Subtable;
3289    DT_SUBTABLE             *ParentTable;
3290    ACPI_TABLE_WPBT         *Table;
3291    ACPI_STATUS             Status;
3292    UINT16                  Length;
3293
3294
3295    /* Compile the main table */
3296
3297    Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
3298                &Subtable, TRUE);
3299    if (ACPI_FAILURE (Status))
3300    {
3301        return (Status);
3302    }
3303
3304    ParentTable = DtPeekSubtable ();
3305    DtInsertSubtable (ParentTable, Subtable);
3306
3307    /* Compile the argument list subtable */
3308
3309    Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
3310                &Subtable, TRUE);
3311    if (ACPI_FAILURE (Status))
3312    {
3313        return (Status);
3314    }
3315
3316    /* Extract the length of the Arguments buffer, insert into main table */
3317
3318    Length = (UINT16) Subtable->TotalLength;
3319    Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3320    Table->ArgumentsLength = Length;
3321
3322    ParentTable = DtPeekSubtable ();
3323    DtInsertSubtable (ParentTable, Subtable);
3324    return (AE_OK);
3325}
3326
3327
3328/******************************************************************************
3329 *
3330 * FUNCTION:    DtCompileXsdt
3331 *
3332 * PARAMETERS:  List                - Current field list pointer
3333 *
3334 * RETURN:      Status
3335 *
3336 * DESCRIPTION: Compile XSDT.
3337 *
3338 *****************************************************************************/
3339
3340ACPI_STATUS
3341DtCompileXsdt (
3342    void                    **List)
3343{
3344    DT_SUBTABLE             *Subtable;
3345    DT_SUBTABLE             *ParentTable;
3346    DT_FIELD                *FieldList = *(DT_FIELD **) List;
3347    UINT64                  Address;
3348
3349
3350    ParentTable = DtPeekSubtable ();
3351
3352    while (FieldList)
3353    {
3354        DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3355
3356        DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3357        DtInsertSubtable (ParentTable, Subtable);
3358        FieldList = FieldList->Next;
3359    }
3360
3361    return (AE_OK);
3362}
3363
3364
3365/******************************************************************************
3366 *
3367 * FUNCTION:    DtCompileGeneric
3368 *
3369 * PARAMETERS:  List                - Current field list pointer
3370 *              Name                - Field name to end generic compiling
3371 *              Length              - Compiled table length to return
3372 *
3373 * RETURN:      Status
3374 *
3375 * DESCRIPTION: Compile generic unknown table.
3376 *
3377 *****************************************************************************/
3378
3379ACPI_STATUS
3380DtCompileGeneric (
3381    void                    **List,
3382    char                    *Name,
3383    UINT32                  *Length)
3384{
3385    ACPI_STATUS             Status;
3386    DT_SUBTABLE             *Subtable;
3387    DT_SUBTABLE             *ParentTable;
3388    DT_FIELD                **PFieldList = (DT_FIELD **) List;
3389    ACPI_DMTABLE_INFO       *Info;
3390
3391
3392    ParentTable = DtPeekSubtable ();
3393
3394    /*
3395     * Compile the "generic" portion of the table. This
3396     * part of the table is not predefined and any of the generic
3397     * operators may be used.
3398     */
3399
3400    /* Find any and all labels in the entire generic portion */
3401
3402    DtDetectAllLabels (*PFieldList);
3403
3404    /* Now we can actually compile the parse tree */
3405
3406    if (Length && *Length)
3407    {
3408        *Length = 0;
3409    }
3410    while (*PFieldList)
3411    {
3412        if (Name && !strcmp ((*PFieldList)->Name, Name))
3413        {
3414            break;
3415        }
3416        Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3417        if (!Info)
3418        {
3419            sprintf (MsgBuffer, "Generic data type \"%s\" not found",
3420                (*PFieldList)->Name);
3421            DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3422                (*PFieldList), MsgBuffer);
3423
3424            *PFieldList = (*PFieldList)->Next;
3425            continue;
3426        }
3427
3428        Status = DtCompileTable (PFieldList, Info,
3429                    &Subtable, TRUE);
3430        if (ACPI_SUCCESS (Status))
3431        {
3432            DtInsertSubtable (ParentTable, Subtable);
3433            if (Length)
3434            {
3435                *Length += Subtable->Length;
3436            }
3437        }
3438        else
3439        {
3440            *PFieldList = (*PFieldList)->Next;
3441
3442            if (Status == AE_NOT_FOUND)
3443            {
3444                sprintf (MsgBuffer, "Generic data type \"%s\" not found",
3445                    (*PFieldList)->Name);
3446                DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3447                    (*PFieldList), MsgBuffer);
3448            }
3449        }
3450    }
3451
3452    return (AE_OK);
3453}
3454