dttable.c revision 219707
1/******************************************************************************
2 *
3 * Module Name: dttable.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#define __DTTABLE_C__
45
46/* Compile all complex data tables */
47
48#include <contrib/dev/acpica/compiler/aslcompiler.h>
49#include <contrib/dev/acpica/compiler/dtcompiler.h>
50
51#define _COMPONENT          DT_COMPILER
52        ACPI_MODULE_NAME    ("dttable")
53
54
55/* TBD: merge these into dmtbinfo.c? */
56
57static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
58{
59    {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
60    {ACPI_DMT_EXIT,     0,               NULL, 0}
61};
62
63static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
64{
65    {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
66    {ACPI_DMT_EXIT,     0,               NULL, 0}
67};
68
69
70/* TBD: move to acmacros.h */
71
72#define ACPI_SUB_PTR(t, a, b) \
73    ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
74
75
76/* Local prototypes */
77
78static ACPI_STATUS
79DtCompileTwoSubtables (
80    void                    **List,
81    ACPI_DMTABLE_INFO       *TableInfo1,
82    ACPI_DMTABLE_INFO       *TableInfo2);
83
84
85/******************************************************************************
86 *
87 * FUNCTION:    DtCompileTwoSubtables
88 *
89 * PARAMETERS:  List                - Current field list pointer
90 *              TableInfo1          - Info table 1
91 *              TableInfo1          - Info table 2
92 *
93 * RETURN:      Status
94 *
95 * DESCRIPTION: Compile tables with a header and one or more same subtables.
96 *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
97 *
98 *****************************************************************************/
99
100static ACPI_STATUS
101DtCompileTwoSubtables (
102    void                    **List,
103    ACPI_DMTABLE_INFO       *TableInfo1,
104    ACPI_DMTABLE_INFO       *TableInfo2)
105{
106    ACPI_STATUS             Status;
107    DT_SUBTABLE             *Subtable;
108    DT_SUBTABLE             *ParentTable;
109    DT_FIELD                **PFieldList = (DT_FIELD **) List;
110
111
112    Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
113    if (ACPI_FAILURE (Status))
114    {
115        return (Status);
116    }
117
118    ParentTable = DtPeekSubtable ();
119    DtInsertSubtable (ParentTable, Subtable);
120
121    while (*PFieldList)
122    {
123        Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
124        if (ACPI_FAILURE (Status))
125        {
126            return (Status);
127        }
128
129        DtInsertSubtable (ParentTable, Subtable);
130    }
131
132    return (AE_OK);
133}
134
135
136/******************************************************************************
137 *
138 * FUNCTION:    DtCompileFacs
139 *
140 * PARAMETERS:  PFieldList          - Current field list pointer
141 *
142 * RETURN:      Status
143 *
144 * DESCRIPTION: Compile FACS.
145 *
146 *****************************************************************************/
147
148ACPI_STATUS
149DtCompileFacs (
150    DT_FIELD                **PFieldList)
151{
152    DT_SUBTABLE             *Subtable;
153    UINT8                   *ReservedBuffer;
154    ACPI_STATUS             Status;
155    UINT32                  ReservedSize;
156
157
158    Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
159                &Gbl_RootTable, TRUE);
160    if (ACPI_FAILURE (Status))
161    {
162        return (Status);
163    }
164
165    /* Large FACS reserved area at the end of the table */
166
167    ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
168    ReservedBuffer = UtLocalCalloc (ReservedSize);
169
170    DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
171
172    ACPI_FREE (ReservedBuffer);
173    DtInsertSubtable (Gbl_RootTable, Subtable);
174    return (AE_OK);
175}
176
177
178/******************************************************************************
179 *
180 * FUNCTION:    DtCompileRsdp
181 *
182 * PARAMETERS:  PFieldList          - Current field list pointer
183 *
184 * RETURN:      Status
185 *
186 * DESCRIPTION: Compile RSDP.
187 *
188 *****************************************************************************/
189
190ACPI_STATUS
191DtCompileRsdp (
192    DT_FIELD                **PFieldList)
193{
194    DT_SUBTABLE             *Subtable;
195    ACPI_TABLE_RSDP         *Rsdp;
196    ACPI_RSDP_EXTENSION     *RsdpExtension;
197    ACPI_STATUS             Status;
198
199
200    /* Compile the "common" RSDP (ACPI 1.0) */
201
202    Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
203                &Gbl_RootTable, TRUE);
204    if (ACPI_FAILURE (Status))
205    {
206        return (Status);
207    }
208
209    Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
210    DtSetTableChecksum (&Rsdp->Checksum);
211
212    if (Rsdp->Revision > 0)
213    {
214        /* Compile the "extended" part of the RSDP as a subtable */
215
216        Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
217                    &Subtable, TRUE);
218        if (ACPI_FAILURE (Status))
219        {
220            return (Status);
221        }
222
223        DtInsertSubtable (Gbl_RootTable, Subtable);
224
225        /* Set length and extended checksum for entire RSDP */
226
227        RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
228        RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
229        DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
230    }
231
232    return (AE_OK);
233}
234
235
236/******************************************************************************
237 *
238 * FUNCTION:    DtCompileAsf
239 *
240 * PARAMETERS:  List                - Current field list pointer
241 *
242 * RETURN:      Status
243 *
244 * DESCRIPTION: Compile ASF!.
245 *
246 *****************************************************************************/
247
248ACPI_STATUS
249DtCompileAsf (
250    void                    **List)
251{
252    ACPI_ASF_INFO           *AsfTable;
253    DT_SUBTABLE             *Subtable;
254    DT_SUBTABLE             *ParentTable;
255    ACPI_DMTABLE_INFO       *InfoTable;
256    ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
257    UINT32                  DataCount = 0;
258    ACPI_STATUS             Status;
259    UINT32                  i;
260    DT_FIELD                **PFieldList = (DT_FIELD **) List;
261    DT_FIELD                *SubtableStart;
262
263
264    while (*PFieldList)
265    {
266        SubtableStart = *PFieldList;
267        Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
268                    &Subtable, TRUE);
269        if (ACPI_FAILURE (Status))
270        {
271            return (Status);
272        }
273
274        ParentTable = DtPeekSubtable ();
275        DtInsertSubtable (ParentTable, Subtable);
276        DtPushSubtable (Subtable);
277
278        AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
279
280        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
281        {
282        case ACPI_ASF_TYPE_INFO:
283            InfoTable = AcpiDmTableInfoAsf0;
284            break;
285
286        case ACPI_ASF_TYPE_ALERT:
287            InfoTable = AcpiDmTableInfoAsf1;
288            break;
289
290        case ACPI_ASF_TYPE_CONTROL:
291            InfoTable = AcpiDmTableInfoAsf2;
292            break;
293
294        case ACPI_ASF_TYPE_BOOT:
295            InfoTable = AcpiDmTableInfoAsf3;
296            break;
297
298        case ACPI_ASF_TYPE_ADDRESS:
299            InfoTable = AcpiDmTableInfoAsf4;
300            break;
301
302        default:
303            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
304            return (AE_ERROR);
305        }
306
307        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
308        if (ACPI_FAILURE (Status))
309        {
310            return (Status);
311        }
312
313        ParentTable = DtPeekSubtable ();
314        DtInsertSubtable (ParentTable, Subtable);
315
316        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
317        {
318        case ACPI_ASF_TYPE_INFO:
319            DataInfoTable = NULL;
320            break;
321
322        case ACPI_ASF_TYPE_ALERT:
323            DataInfoTable = AcpiDmTableInfoAsf1a;
324            DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
325                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
326                            sizeof (ACPI_ASF_HEADER)))->Alerts;
327            break;
328
329        case ACPI_ASF_TYPE_CONTROL:
330            DataInfoTable = AcpiDmTableInfoAsf2a;
331            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
332                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
333                            sizeof (ACPI_ASF_HEADER)))->Controls;
334            break;
335
336        case ACPI_ASF_TYPE_BOOT:
337            DataInfoTable = NULL;
338            break;
339
340        case ACPI_ASF_TYPE_ADDRESS:
341            DataInfoTable = TableInfoAsfAddress;
342            DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
343                        ACPI_SUB_PTR (UINT8, Subtable->Buffer,
344                            sizeof (ACPI_ASF_HEADER)))->Devices;
345            break;
346
347        default:
348            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
349            return (AE_ERROR);
350        }
351
352        if (DataInfoTable)
353        {
354            switch (AsfTable->Header.Type & 0x7F)
355            {
356            case ACPI_ASF_TYPE_ADDRESS:
357
358                while (DataCount > 0)
359                {
360                    Status = DtCompileTable (PFieldList, DataInfoTable,
361                                &Subtable, TRUE);
362                    if (ACPI_FAILURE (Status))
363                    {
364                        return (Status);
365                    }
366
367                    DtInsertSubtable (ParentTable, Subtable);
368                    DataCount = DataCount - Subtable->Length;
369                }
370                break;
371
372            default:
373
374                for (i = 0; i < DataCount; i++)
375                {
376                    Status = DtCompileTable (PFieldList, DataInfoTable,
377                                &Subtable, TRUE);
378                    if (ACPI_FAILURE (Status))
379                    {
380                        return (Status);
381                    }
382
383                    DtInsertSubtable (ParentTable, Subtable);
384                }
385                break;
386            }
387        }
388
389        DtPopSubtable ();
390    }
391
392    return (AE_OK);
393}
394
395
396/******************************************************************************
397 *
398 * FUNCTION:    DtCompileCpep
399 *
400 * PARAMETERS:  List                - Current field list pointer
401 *
402 * RETURN:      Status
403 *
404 * DESCRIPTION: Compile CPEP.
405 *
406 *****************************************************************************/
407
408ACPI_STATUS
409DtCompileCpep (
410    void                    **List)
411{
412    ACPI_STATUS             Status;
413
414
415    Status = DtCompileTwoSubtables (List,
416                 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
417    return (Status);
418}
419
420
421/******************************************************************************
422 *
423 * FUNCTION:    DtCompileDmar
424 *
425 * PARAMETERS:  List                - Current field list pointer
426 *
427 * RETURN:      Status
428 *
429 * DESCRIPTION: Compile DMAR.
430 *
431 *****************************************************************************/
432
433ACPI_STATUS
434DtCompileDmar (
435    void                    **List)
436{
437    ACPI_STATUS             Status;
438    DT_SUBTABLE             *Subtable;
439    DT_SUBTABLE             *ParentTable;
440    DT_FIELD                **PFieldList = (DT_FIELD **) List;
441    DT_FIELD                *SubtableStart;
442    ACPI_DMTABLE_INFO       *InfoTable;
443    ACPI_DMAR_HEADER        *DmarHeader;
444    UINT8                   *ReservedBuffer;
445    UINT32                  ReservedSize;
446
447
448    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
449    if (ACPI_FAILURE (Status))
450    {
451        return (Status);
452    }
453
454    ParentTable = DtPeekSubtable ();
455    DtInsertSubtable (ParentTable, Subtable);
456
457    /* DMAR Reserved area */
458
459    ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved);
460    ReservedBuffer = UtLocalCalloc (ReservedSize);
461
462    DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
463
464    ACPI_FREE (ReservedBuffer);
465    ParentTable = DtPeekSubtable ();
466    DtInsertSubtable (ParentTable, Subtable);
467
468    while (*PFieldList)
469    {
470        /* DMAR Header */
471
472        SubtableStart = *PFieldList;
473        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
474                    &Subtable, TRUE);
475        if (ACPI_FAILURE (Status))
476        {
477            return (Status);
478        }
479
480        ParentTable = DtPeekSubtable ();
481        DtInsertSubtable (ParentTable, Subtable);
482        DtPushSubtable (Subtable);
483
484        DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
485
486        switch (DmarHeader->Type)
487        {
488        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
489            InfoTable = AcpiDmTableInfoDmar0;
490            break;
491        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
492            InfoTable = AcpiDmTableInfoDmar1;
493            break;
494        case ACPI_DMAR_TYPE_ATSR:
495            InfoTable = AcpiDmTableInfoDmar2;
496            break;
497        case ACPI_DMAR_HARDWARE_AFFINITY:
498            InfoTable = AcpiDmTableInfoDmar3;
499            break;
500        default:
501            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
502            return (AE_ERROR);
503        }
504
505        /* DMAR Subtable */
506
507        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
508        if (ACPI_FAILURE (Status))
509        {
510            return (Status);
511        }
512
513        ParentTable = DtPeekSubtable ();
514        DtInsertSubtable (ParentTable, Subtable);
515
516        /* Optional Device Scope subtables */
517
518        while (*PFieldList)
519        {
520            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
521                        &Subtable, FALSE);
522            if (Status == AE_NOT_FOUND)
523            {
524                break;
525            }
526
527            ParentTable = DtPeekSubtable ();
528            DtInsertSubtable (ParentTable, Subtable);
529            DtPushSubtable (Subtable);
530
531            /* Optional PCI Paths */
532
533            while (*PFieldList)
534            {
535                Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
536                            &Subtable, FALSE);
537                if (Status == AE_NOT_FOUND)
538                {
539                    DtPopSubtable ();
540                    break;
541                }
542
543                ParentTable = DtPeekSubtable ();
544                DtInsertSubtable (ParentTable, Subtable);
545            }
546        }
547
548        DtPopSubtable ();
549    }
550
551    return (AE_OK);
552}
553
554
555/******************************************************************************
556 *
557 * FUNCTION:    DtCompileEinj
558 *
559 * PARAMETERS:  List                - Current field list pointer
560 *
561 * RETURN:      Status
562 *
563 * DESCRIPTION: Compile EINJ.
564 *
565 *****************************************************************************/
566
567ACPI_STATUS
568DtCompileEinj (
569    void                    **List)
570{
571    ACPI_STATUS             Status;
572
573
574    Status = DtCompileTwoSubtables (List,
575                 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
576    return (Status);
577}
578
579
580/******************************************************************************
581 *
582 * FUNCTION:    DtCompileErst
583 *
584 * PARAMETERS:  List                - Current field list pointer
585 *
586 * RETURN:      Status
587 *
588 * DESCRIPTION: Compile ERST.
589 *
590 *****************************************************************************/
591
592ACPI_STATUS
593DtCompileErst (
594    void                    **List)
595{
596    ACPI_STATUS             Status;
597
598
599    Status = DtCompileTwoSubtables (List,
600                 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
601    return (Status);
602}
603
604
605/******************************************************************************
606 *
607 * FUNCTION:    DtCompileFadt
608 *
609 * PARAMETERS:  List                - Current field list pointer
610 *
611 * RETURN:      Status
612 *
613 * DESCRIPTION: Compile FADT.
614 *
615 *****************************************************************************/
616
617ACPI_STATUS
618DtCompileFadt (
619    void                    **List)
620{
621    ACPI_STATUS             Status;
622    DT_SUBTABLE             *Subtable;
623    DT_SUBTABLE             *ParentTable;
624    DT_FIELD                **PFieldList = (DT_FIELD **) List;
625    ACPI_TABLE_HEADER       *Table;
626    UINT8                   Revision;
627
628
629    Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
630                &Subtable, TRUE);
631    if (ACPI_FAILURE (Status))
632    {
633        return (Status);
634    }
635
636    ParentTable = DtPeekSubtable ();
637    DtInsertSubtable (ParentTable, Subtable);
638
639    Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
640    Revision = Table->Revision;
641
642    if (Revision == 2)
643    {
644        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
645                    &Subtable, TRUE);
646        if (ACPI_FAILURE (Status))
647        {
648            return (Status);
649        }
650
651        DtInsertSubtable (ParentTable, Subtable);
652    }
653    else if (Revision >= 2)
654    {
655        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
656                    &Subtable, TRUE);
657        if (ACPI_FAILURE (Status))
658        {
659            return (Status);
660        }
661
662        DtInsertSubtable (ParentTable, Subtable);
663    }
664
665    return (AE_OK);
666}
667
668
669/******************************************************************************
670 *
671 * FUNCTION:    DtCompileHest
672 *
673 * PARAMETERS:  List                - Current field list pointer
674 *
675 * RETURN:      Status
676 *
677 * DESCRIPTION: Compile HEST.
678 *
679 *****************************************************************************/
680
681ACPI_STATUS
682DtCompileHest (
683    void                    **List)
684{
685    ACPI_STATUS             Status;
686    DT_SUBTABLE             *Subtable;
687    DT_SUBTABLE             *ParentTable;
688    DT_FIELD                **PFieldList = (DT_FIELD **) List;
689    DT_FIELD                *SubtableStart;
690    ACPI_DMTABLE_INFO       *InfoTable;
691    UINT16                  Type;
692    UINT32                  BankCount;
693
694
695    Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
696                &Subtable, TRUE);
697    if (ACPI_FAILURE (Status))
698    {
699        return (Status);
700    }
701
702    ParentTable = DtPeekSubtable ();
703    DtInsertSubtable (ParentTable, Subtable);
704
705    while (*PFieldList)
706    {
707        /* Get subtable type */
708
709        SubtableStart = *PFieldList;
710        DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
711
712        switch (Type)
713        {
714        case ACPI_HEST_TYPE_IA32_CHECK:
715            InfoTable = AcpiDmTableInfoHest0;
716            break;
717
718        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
719            InfoTable = AcpiDmTableInfoHest1;
720            break;
721
722        case ACPI_HEST_TYPE_IA32_NMI:
723            InfoTable = AcpiDmTableInfoHest2;
724            break;
725
726        case ACPI_HEST_TYPE_AER_ROOT_PORT:
727            InfoTable = AcpiDmTableInfoHest6;
728            break;
729
730        case ACPI_HEST_TYPE_AER_ENDPOINT:
731            InfoTable = AcpiDmTableInfoHest7;
732            break;
733
734        case ACPI_HEST_TYPE_AER_BRIDGE:
735            InfoTable = AcpiDmTableInfoHest8;
736            break;
737
738        case ACPI_HEST_TYPE_GENERIC_ERROR:
739            InfoTable = AcpiDmTableInfoHest9;
740            break;
741
742        default:
743            /* Cannot continue on unknown type */
744
745            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
746            return (AE_ERROR);
747        }
748
749        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
750        if (ACPI_FAILURE (Status))
751        {
752            return (Status);
753        }
754
755        DtInsertSubtable (ParentTable, Subtable);
756
757        /*
758         * Additional subtable data - IA32 Error Bank(s)
759         */
760        BankCount = 0;
761        switch (Type)
762        {
763        case ACPI_HEST_TYPE_IA32_CHECK:
764            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
765                            Subtable->Buffer))->NumHardwareBanks;
766            break;
767
768        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
769            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
770                            Subtable->Buffer))->NumHardwareBanks;
771            break;
772
773        default:
774            break;
775        }
776
777        while (BankCount)
778        {
779            Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
780                        &Subtable, TRUE);
781            if (ACPI_FAILURE (Status))
782            {
783                return (Status);
784            }
785
786            DtInsertSubtable (ParentTable, Subtable);
787            BankCount--;
788        }
789    }
790
791    return AE_OK;
792}
793
794
795/******************************************************************************
796 *
797 * FUNCTION:    DtCompileIvrs
798 *
799 * PARAMETERS:  List                - Current field list pointer
800 *
801 * RETURN:      Status
802 *
803 * DESCRIPTION: Compile IVRS.
804 *
805 *****************************************************************************/
806
807ACPI_STATUS
808DtCompileIvrs (
809    void                    **List)
810{
811    ACPI_STATUS             Status;
812    DT_SUBTABLE             *Subtable;
813    DT_SUBTABLE             *ParentTable;
814    DT_FIELD                **PFieldList = (DT_FIELD **) List;
815    DT_FIELD                *SubtableStart;
816    ACPI_DMTABLE_INFO       *InfoTable;
817    ACPI_IVRS_HEADER        *IvrsHeader;
818    UINT8                   EntryType;
819
820
821    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
822                &Subtable, TRUE);
823    if (ACPI_FAILURE (Status))
824    {
825        return (Status);
826    }
827
828    ParentTable = DtPeekSubtable ();
829    DtInsertSubtable (ParentTable, Subtable);
830
831    while (*PFieldList)
832    {
833        SubtableStart = *PFieldList;
834        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
835                    &Subtable, TRUE);
836        if (ACPI_FAILURE (Status))
837        {
838            return (Status);
839        }
840
841        ParentTable = DtPeekSubtable ();
842        DtInsertSubtable (ParentTable, Subtable);
843        DtPushSubtable (Subtable);
844
845        IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
846
847        switch (IvrsHeader->Type)
848        {
849        case ACPI_IVRS_TYPE_HARDWARE:
850            InfoTable = AcpiDmTableInfoIvrs0;
851            break;
852
853        case ACPI_IVRS_TYPE_MEMORY1:
854        case ACPI_IVRS_TYPE_MEMORY2:
855        case ACPI_IVRS_TYPE_MEMORY3:
856            InfoTable = AcpiDmTableInfoIvrs1;
857            break;
858
859        default:
860            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
861            return (AE_ERROR);
862        }
863
864        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
865        if (ACPI_FAILURE (Status))
866        {
867            return (Status);
868        }
869
870        ParentTable = DtPeekSubtable ();
871        DtInsertSubtable (ParentTable, Subtable);
872
873        if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
874        {
875            while (*PFieldList &&
876                    !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
877            {
878                SubtableStart = *PFieldList;
879                DtCompileInteger (&EntryType, *PFieldList, 1, 0);
880
881                switch (EntryType)
882                {
883                /* 4-byte device entries */
884
885                case ACPI_IVRS_TYPE_PAD4:
886                case ACPI_IVRS_TYPE_ALL:
887                case ACPI_IVRS_TYPE_SELECT:
888                case ACPI_IVRS_TYPE_START:
889                case ACPI_IVRS_TYPE_END:
890
891                    InfoTable = AcpiDmTableInfoIvrs4;
892                    break;
893
894                /* 8-byte entries, type A */
895
896                case ACPI_IVRS_TYPE_ALIAS_SELECT:
897                case ACPI_IVRS_TYPE_ALIAS_START:
898
899                    InfoTable = AcpiDmTableInfoIvrs8a;
900                    break;
901
902                /* 8-byte entries, type B */
903
904                case ACPI_IVRS_TYPE_PAD8:
905                case ACPI_IVRS_TYPE_EXT_SELECT:
906                case ACPI_IVRS_TYPE_EXT_START:
907
908                    InfoTable = AcpiDmTableInfoIvrs8b;
909                    break;
910
911                /* 8-byte entries, type C */
912
913                case ACPI_IVRS_TYPE_SPECIAL:
914
915                    InfoTable = AcpiDmTableInfoIvrs8c;
916                    break;
917
918                default:
919                    DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
920                        "IVRS Device Entry");
921                    return (AE_ERROR);
922                }
923
924                Status = DtCompileTable (PFieldList, InfoTable,
925                            &Subtable, TRUE);
926                if (ACPI_FAILURE (Status))
927                {
928                    return (Status);
929                }
930
931                DtInsertSubtable (ParentTable, Subtable);
932            }
933        }
934
935        DtPopSubtable ();
936    }
937
938    return (AE_OK);
939}
940
941
942/******************************************************************************
943 *
944 * FUNCTION:    DtCompileMadt
945 *
946 * PARAMETERS:  List                - Current field list pointer
947 *
948 * RETURN:      Status
949 *
950 * DESCRIPTION: Compile MADT.
951 *
952 *****************************************************************************/
953
954ACPI_STATUS
955DtCompileMadt (
956    void                    **List)
957{
958    ACPI_STATUS             Status;
959    DT_SUBTABLE             *Subtable;
960    DT_SUBTABLE             *ParentTable;
961    DT_FIELD                **PFieldList = (DT_FIELD **) List;
962    DT_FIELD                *SubtableStart;
963    ACPI_SUBTABLE_HEADER    *MadtHeader;
964    ACPI_DMTABLE_INFO       *InfoTable;
965
966
967    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
968                &Subtable, TRUE);
969    if (ACPI_FAILURE (Status))
970    {
971        return (Status);
972    }
973
974    ParentTable = DtPeekSubtable ();
975    DtInsertSubtable (ParentTable, Subtable);
976
977    while (*PFieldList)
978    {
979        SubtableStart = *PFieldList;
980        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
981                    &Subtable, TRUE);
982        if (ACPI_FAILURE (Status))
983        {
984            return (Status);
985        }
986
987        ParentTable = DtPeekSubtable ();
988        DtInsertSubtable (ParentTable, Subtable);
989        DtPushSubtable (Subtable);
990
991        MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
992
993        switch (MadtHeader->Type)
994        {
995        case ACPI_MADT_TYPE_LOCAL_APIC:
996            InfoTable = AcpiDmTableInfoMadt0;
997            break;
998        case ACPI_MADT_TYPE_IO_APIC:
999            InfoTable = AcpiDmTableInfoMadt1;
1000            break;
1001        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1002            InfoTable = AcpiDmTableInfoMadt2;
1003            break;
1004        case ACPI_MADT_TYPE_NMI_SOURCE:
1005            InfoTable = AcpiDmTableInfoMadt3;
1006            break;
1007        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1008            InfoTable = AcpiDmTableInfoMadt4;
1009            break;
1010        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1011            InfoTable = AcpiDmTableInfoMadt5;
1012            break;
1013        case ACPI_MADT_TYPE_IO_SAPIC:
1014            InfoTable = AcpiDmTableInfoMadt6;
1015            break;
1016        case ACPI_MADT_TYPE_LOCAL_SAPIC:
1017            InfoTable = AcpiDmTableInfoMadt7;
1018            break;
1019        case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1020            InfoTable = AcpiDmTableInfoMadt8;
1021            break;
1022        case ACPI_MADT_TYPE_LOCAL_X2APIC:
1023            InfoTable = AcpiDmTableInfoMadt9;
1024            break;
1025        case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1026            InfoTable = AcpiDmTableInfoMadt10;
1027            break;
1028        default:
1029            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1030            return (AE_ERROR);
1031        }
1032
1033        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1034        if (ACPI_FAILURE (Status))
1035        {
1036            return (Status);
1037        }
1038
1039        ParentTable = DtPeekSubtable ();
1040        DtInsertSubtable (ParentTable, Subtable);
1041        DtPopSubtable ();
1042    }
1043
1044    return (AE_OK);
1045}
1046
1047
1048/******************************************************************************
1049 *
1050 * FUNCTION:    DtCompileMcfg
1051 *
1052 * PARAMETERS:  List                - Current field list pointer
1053 *
1054 * RETURN:      Status
1055 *
1056 * DESCRIPTION: Compile MCFG.
1057 *
1058 *****************************************************************************/
1059
1060ACPI_STATUS
1061DtCompileMcfg (
1062    void                    **List)
1063{
1064    ACPI_STATUS             Status;
1065
1066
1067    Status = DtCompileTwoSubtables (List,
1068                 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1069    return (Status);
1070}
1071
1072
1073/******************************************************************************
1074 *
1075 * FUNCTION:    DtCompileMsct
1076 *
1077 * PARAMETERS:  List                - Current field list pointer
1078 *
1079 * RETURN:      Status
1080 *
1081 * DESCRIPTION: Compile MSCT.
1082 *
1083 *****************************************************************************/
1084
1085ACPI_STATUS
1086DtCompileMsct (
1087    void                    **List)
1088{
1089    ACPI_STATUS             Status;
1090
1091
1092    Status = DtCompileTwoSubtables (List,
1093                 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1094    return (Status);
1095}
1096
1097
1098/******************************************************************************
1099 *
1100 * FUNCTION:    DtCompileRsdt
1101 *
1102 * PARAMETERS:  List                - Current field list pointer
1103 *
1104 * RETURN:      Status
1105 *
1106 * DESCRIPTION: Compile RSDT.
1107 *
1108 *****************************************************************************/
1109
1110ACPI_STATUS
1111DtCompileRsdt (
1112    void                    **List)
1113{
1114    DT_SUBTABLE             *Subtable;
1115    DT_SUBTABLE             *ParentTable;
1116    DT_FIELD                *FieldList = *(DT_FIELD **) List;
1117    UINT32                  Address;
1118
1119
1120    ParentTable = DtPeekSubtable ();
1121
1122    while (FieldList)
1123    {
1124        DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1125
1126        DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1127        DtInsertSubtable (ParentTable, Subtable);
1128        FieldList = FieldList->Next;
1129    }
1130
1131    return (AE_OK);
1132}
1133
1134
1135/******************************************************************************
1136 *
1137 * FUNCTION:    DtCompileSlic
1138 *
1139 * PARAMETERS:  List                - Current field list pointer
1140 *
1141 * RETURN:      Status
1142 *
1143 * DESCRIPTION: Compile SLIC.
1144 *
1145 *****************************************************************************/
1146
1147ACPI_STATUS
1148DtCompileSlic (
1149    void                    **List)
1150{
1151    ACPI_STATUS             Status;
1152    DT_SUBTABLE             *Subtable;
1153    DT_SUBTABLE             *ParentTable;
1154    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1155    DT_FIELD                *SubtableStart;
1156    ACPI_SLIC_HEADER        *SlicHeader;
1157    ACPI_DMTABLE_INFO       *InfoTable;
1158
1159
1160    while (*PFieldList)
1161    {
1162        SubtableStart = *PFieldList;
1163        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlicHdr,
1164                    &Subtable, TRUE);
1165        if (ACPI_FAILURE (Status))
1166        {
1167            return (Status);
1168        }
1169
1170        ParentTable = DtPeekSubtable ();
1171        DtInsertSubtable (ParentTable, Subtable);
1172        DtPushSubtable (Subtable);
1173
1174        SlicHeader = ACPI_CAST_PTR (ACPI_SLIC_HEADER, Subtable->Buffer);
1175
1176        switch (SlicHeader->Type)
1177        {
1178        case ACPI_SLIC_TYPE_PUBLIC_KEY:
1179            InfoTable = AcpiDmTableInfoSlic0;
1180            break;
1181        case ACPI_SLIC_TYPE_WINDOWS_MARKER:
1182            InfoTable = AcpiDmTableInfoSlic1;
1183            break;
1184        default:
1185            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SLIC");
1186            return (AE_ERROR);
1187        }
1188
1189        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1190        if (ACPI_FAILURE (Status))
1191        {
1192            return (Status);
1193        }
1194
1195        ParentTable = DtPeekSubtable ();
1196        DtInsertSubtable (ParentTable, Subtable);
1197        DtPopSubtable ();
1198    }
1199
1200    return (AE_OK);
1201}
1202
1203
1204/******************************************************************************
1205 *
1206 * FUNCTION:    DtCompileSlit
1207 *
1208 * PARAMETERS:  List                - Current field list pointer
1209 *
1210 * RETURN:      Status
1211 *
1212 * DESCRIPTION: Compile SLIT.
1213 *
1214 *****************************************************************************/
1215
1216ACPI_STATUS
1217DtCompileSlit (
1218    void                    **List)
1219{
1220    ACPI_STATUS             Status;
1221    DT_SUBTABLE             *Subtable;
1222    DT_SUBTABLE             *ParentTable;
1223    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1224    DT_FIELD                *FieldList;
1225    UINT32                  Localities;
1226    UINT8                   *LocalityBuffer;
1227    UINT32                  RemainingData;
1228
1229
1230    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1231                &Subtable, TRUE);
1232    if (ACPI_FAILURE (Status))
1233    {
1234        return (Status);
1235    }
1236
1237    ParentTable = DtPeekSubtable ();
1238    DtInsertSubtable (ParentTable, Subtable);
1239
1240    Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1241    LocalityBuffer = UtLocalCalloc (Localities);
1242
1243    FieldList = *PFieldList;
1244    while (FieldList)
1245    {
1246        /* Handle multiple-line buffer */
1247
1248        RemainingData = Localities;
1249        while (RemainingData && FieldList)
1250        {
1251            RemainingData = DtCompileBuffer (
1252                LocalityBuffer + (Localities - RemainingData),
1253                FieldList->Value, FieldList, RemainingData);
1254            FieldList = FieldList->Next;
1255        }
1256
1257        DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1258        DtInsertSubtable (ParentTable, Subtable);
1259    }
1260
1261    ACPI_FREE (LocalityBuffer);
1262    return (AE_OK);
1263}
1264
1265
1266/******************************************************************************
1267 *
1268 * FUNCTION:    DtCompileSrat
1269 *
1270 * PARAMETERS:  List                - Current field list pointer
1271 *
1272 * RETURN:      Status
1273 *
1274 * DESCRIPTION: Compile SRAT.
1275 *
1276 *****************************************************************************/
1277
1278ACPI_STATUS
1279DtCompileSrat (
1280    void                    **List)
1281{
1282    ACPI_STATUS             Status;
1283    DT_SUBTABLE             *Subtable;
1284    DT_SUBTABLE             *ParentTable;
1285    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1286    DT_FIELD                *SubtableStart;
1287    ACPI_SUBTABLE_HEADER    *SratHeader;
1288    ACPI_DMTABLE_INFO       *InfoTable;
1289
1290
1291    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1292                &Subtable, TRUE);
1293    if (ACPI_FAILURE (Status))
1294    {
1295        return (Status);
1296    }
1297
1298    ParentTable = DtPeekSubtable ();
1299    DtInsertSubtable (ParentTable, Subtable);
1300
1301    while (*PFieldList)
1302    {
1303        SubtableStart = *PFieldList;
1304        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1305                    &Subtable, TRUE);
1306        if (ACPI_FAILURE (Status))
1307        {
1308            return (Status);
1309        }
1310
1311        ParentTable = DtPeekSubtable ();
1312        DtInsertSubtable (ParentTable, Subtable);
1313        DtPushSubtable (Subtable);
1314
1315        SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1316
1317        switch (SratHeader->Type)
1318        {
1319        case ACPI_SRAT_TYPE_CPU_AFFINITY:
1320            InfoTable = AcpiDmTableInfoSrat0;
1321            break;
1322        case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1323            InfoTable = AcpiDmTableInfoSrat1;
1324            break;
1325        case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1326            InfoTable = AcpiDmTableInfoSrat2;
1327            break;
1328        default:
1329            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1330            return (AE_ERROR);
1331        }
1332
1333        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1334        if (ACPI_FAILURE (Status))
1335        {
1336            return (Status);
1337        }
1338
1339        ParentTable = DtPeekSubtable ();
1340        DtInsertSubtable (ParentTable, Subtable);
1341        DtPopSubtable ();
1342    }
1343
1344    return (AE_OK);
1345}
1346
1347
1348/******************************************************************************
1349 *
1350 * FUNCTION:    DtGetGenericTableInfo
1351 *
1352 * PARAMETERS:  Name                - Generic type name
1353 *
1354 * RETURN:      Info entry
1355 *
1356 * DESCRIPTION: Obtain table info for a generic name entry
1357 *
1358 *****************************************************************************/
1359
1360ACPI_DMTABLE_INFO *
1361DtGetGenericTableInfo (
1362    char                    *Name)
1363{
1364    ACPI_DMTABLE_INFO       *Info;
1365    UINT32                  i;
1366
1367
1368    if (!Name)
1369    {
1370        return (NULL);
1371    }
1372
1373    /* Search info table for name match */
1374
1375    for (i = 0; ; i++)
1376    {
1377        Info = AcpiDmTableInfoGeneric[i];
1378        if (Info->Opcode == ACPI_DMT_EXIT)
1379        {
1380            Info = NULL;
1381            break;
1382        }
1383
1384        if (!ACPI_STRCMP (Name, Info->Name))
1385        {
1386            break;
1387        }
1388    }
1389
1390    return (Info);
1391}
1392
1393
1394/******************************************************************************
1395 *
1396 * FUNCTION:    DtCompileUefi
1397 *
1398 * PARAMETERS:  List                - Current field list pointer
1399 *
1400 * RETURN:      Status
1401 *
1402 * DESCRIPTION: Compile UEFI.
1403 *
1404 *****************************************************************************/
1405
1406ACPI_STATUS
1407DtCompileUefi (
1408    void                    **List)
1409{
1410    ACPI_STATUS             Status;
1411    DT_SUBTABLE             *Subtable;
1412    DT_SUBTABLE             *ParentTable;
1413    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1414    ACPI_DMTABLE_INFO       *Info;
1415    UINT16                  *DataOffset;
1416
1417
1418    /* Compile the predefined portion of the UEFI table */
1419
1420    Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1421                &Subtable, TRUE);
1422    if (ACPI_FAILURE (Status))
1423    {
1424        return (Status);
1425    }
1426
1427    DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1428    *DataOffset = sizeof (ACPI_TABLE_UEFI);
1429
1430    ParentTable = DtPeekSubtable ();
1431    DtInsertSubtable (ParentTable, Subtable);
1432
1433    /*
1434     * Compile the "generic" portion of the UEFI table. This
1435     * part of the table is not predefined and any of the generic
1436     * operators may be used.
1437     */
1438
1439    /* Find any and all labels in the entire generic portion */
1440
1441    DtDetectAllLabels (*PFieldList);
1442
1443    /* Now we can actually compile the parse tree */
1444
1445    while (*PFieldList)
1446    {
1447        Info = DtGetGenericTableInfo ((*PFieldList)->Name);
1448        if (!Info)
1449        {
1450            sprintf (MsgBuffer, "Generic data type \"%s\" not found",
1451                (*PFieldList)->Name);
1452            DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
1453                (*PFieldList), MsgBuffer);
1454
1455            *PFieldList = (*PFieldList)->Next;
1456            continue;
1457        }
1458
1459        Status = DtCompileTable (PFieldList, Info,
1460                    &Subtable, TRUE);
1461        if (ACPI_SUCCESS (Status))
1462        {
1463            DtInsertSubtable (ParentTable, Subtable);
1464        }
1465        else
1466        {
1467            *PFieldList = (*PFieldList)->Next;
1468
1469            if (Status == AE_NOT_FOUND)
1470            {
1471                sprintf (MsgBuffer, "Generic data type \"%s\" not found",
1472                    (*PFieldList)->Name);
1473                DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
1474                    (*PFieldList), MsgBuffer);
1475            }
1476        }
1477    }
1478
1479    return (AE_OK);
1480}
1481
1482
1483/******************************************************************************
1484 *
1485 * FUNCTION:    DtCompileWdat
1486 *
1487 * PARAMETERS:  List                - Current field list pointer
1488 *
1489 * RETURN:      Status
1490 *
1491 * DESCRIPTION: Compile WDAT.
1492 *
1493 *****************************************************************************/
1494
1495ACPI_STATUS
1496DtCompileWdat (
1497    void                    **List)
1498{
1499    ACPI_STATUS             Status;
1500
1501
1502    Status = DtCompileTwoSubtables (List,
1503                 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
1504    return (Status);
1505}
1506
1507
1508/******************************************************************************
1509 *
1510 * FUNCTION:    DtCompileXsdt
1511 *
1512 * PARAMETERS:  List                - Current field list pointer
1513 *
1514 * RETURN:      Status
1515 *
1516 * DESCRIPTION: Compile XSDT.
1517 *
1518 *****************************************************************************/
1519
1520ACPI_STATUS
1521DtCompileXsdt (
1522    void                    **List)
1523{
1524    DT_SUBTABLE             *Subtable;
1525    DT_SUBTABLE             *ParentTable;
1526    DT_FIELD                *FieldList = *(DT_FIELD **) List;
1527    UINT64                  Address;
1528
1529    ParentTable = DtPeekSubtable ();
1530
1531    while (FieldList)
1532    {
1533        DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
1534
1535        DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
1536        DtInsertSubtable (ParentTable, Subtable);
1537        FieldList = FieldList->Next;
1538    }
1539
1540    return (AE_OK);
1541}
1542