dttable1.c revision 306536
1/******************************************************************************
2 *
3 * Module Name: dttable1.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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, signatures starting with A-I */
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    ("dttable1")
51
52
53static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
54{
55    {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
56    {ACPI_DMT_EXIT,     0,               NULL, 0}
57};
58
59static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
60{
61    {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
62    {ACPI_DMT_EXIT,     0,               NULL, 0}
63};
64
65
66/******************************************************************************
67 *
68 * FUNCTION:    DtCompileAsf
69 *
70 * PARAMETERS:  List                - Current field list pointer
71 *
72 * RETURN:      Status
73 *
74 * DESCRIPTION: Compile ASF!.
75 *
76 *****************************************************************************/
77
78ACPI_STATUS
79DtCompileAsf (
80    void                    **List)
81{
82    ACPI_ASF_INFO           *AsfTable;
83    DT_SUBTABLE             *Subtable;
84    DT_SUBTABLE             *ParentTable;
85    ACPI_DMTABLE_INFO       *InfoTable;
86    ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
87    UINT32                  DataCount = 0;
88    ACPI_STATUS             Status;
89    UINT32                  i;
90    DT_FIELD                **PFieldList = (DT_FIELD **) List;
91    DT_FIELD                *SubtableStart;
92
93
94    while (*PFieldList)
95    {
96        SubtableStart = *PFieldList;
97        Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
98            &Subtable, TRUE);
99        if (ACPI_FAILURE (Status))
100        {
101            return (Status);
102        }
103
104        ParentTable = DtPeekSubtable ();
105        DtInsertSubtable (ParentTable, Subtable);
106        DtPushSubtable (Subtable);
107
108        AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
109
110        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
111        {
112        case ACPI_ASF_TYPE_INFO:
113
114            InfoTable = AcpiDmTableInfoAsf0;
115            break;
116
117        case ACPI_ASF_TYPE_ALERT:
118
119            InfoTable = AcpiDmTableInfoAsf1;
120            break;
121
122        case ACPI_ASF_TYPE_CONTROL:
123
124            InfoTable = AcpiDmTableInfoAsf2;
125            break;
126
127        case ACPI_ASF_TYPE_BOOT:
128
129            InfoTable = AcpiDmTableInfoAsf3;
130            break;
131
132        case ACPI_ASF_TYPE_ADDRESS:
133
134            InfoTable = AcpiDmTableInfoAsf4;
135            break;
136
137        default:
138
139            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
140            return (AE_ERROR);
141        }
142
143        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
144        if (ACPI_FAILURE (Status))
145        {
146            return (Status);
147        }
148
149        ParentTable = DtPeekSubtable ();
150        DtInsertSubtable (ParentTable, Subtable);
151
152        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
153        {
154        case ACPI_ASF_TYPE_INFO:
155
156            DataInfoTable = NULL;
157            break;
158
159        case ACPI_ASF_TYPE_ALERT:
160
161            DataInfoTable = AcpiDmTableInfoAsf1a;
162            DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
163                ACPI_SUB_PTR (UINT8, Subtable->Buffer,
164                    sizeof (ACPI_ASF_HEADER)))->Alerts;
165            break;
166
167        case ACPI_ASF_TYPE_CONTROL:
168
169            DataInfoTable = AcpiDmTableInfoAsf2a;
170            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
171                ACPI_SUB_PTR (UINT8, Subtable->Buffer,
172                    sizeof (ACPI_ASF_HEADER)))->Controls;
173            break;
174
175        case ACPI_ASF_TYPE_BOOT:
176
177            DataInfoTable = NULL;
178            break;
179
180        case ACPI_ASF_TYPE_ADDRESS:
181
182            DataInfoTable = TableInfoAsfAddress;
183            DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
184                ACPI_SUB_PTR (UINT8, Subtable->Buffer,
185                    sizeof (ACPI_ASF_HEADER)))->Devices;
186            break;
187
188        default:
189
190            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
191            return (AE_ERROR);
192        }
193
194        if (DataInfoTable)
195        {
196            switch (AsfTable->Header.Type & 0x7F)
197            {
198            case ACPI_ASF_TYPE_ADDRESS:
199
200                while (DataCount > 0)
201                {
202                    Status = DtCompileTable (PFieldList, DataInfoTable,
203                        &Subtable, TRUE);
204                    if (ACPI_FAILURE (Status))
205                    {
206                        return (Status);
207                    }
208
209                    DtInsertSubtable (ParentTable, Subtable);
210                    DataCount = DataCount - Subtable->Length;
211                }
212                break;
213
214            default:
215
216                for (i = 0; i < DataCount; i++)
217                {
218                    Status = DtCompileTable (PFieldList, DataInfoTable,
219                        &Subtable, TRUE);
220                    if (ACPI_FAILURE (Status))
221                    {
222                        return (Status);
223                    }
224
225                    DtInsertSubtable (ParentTable, Subtable);
226                }
227                break;
228            }
229        }
230
231        DtPopSubtable ();
232    }
233
234    return (AE_OK);
235}
236
237
238/******************************************************************************
239 *
240 * FUNCTION:    DtCompileCpep
241 *
242 * PARAMETERS:  List                - Current field list pointer
243 *
244 * RETURN:      Status
245 *
246 * DESCRIPTION: Compile CPEP.
247 *
248 *****************************************************************************/
249
250ACPI_STATUS
251DtCompileCpep (
252    void                    **List)
253{
254    ACPI_STATUS             Status;
255
256
257    Status = DtCompileTwoSubtables (List,
258        AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
259    return (Status);
260}
261
262
263/******************************************************************************
264 *
265 * FUNCTION:    DtCompileCsrt
266 *
267 * PARAMETERS:  List                - Current field list pointer
268 *
269 * RETURN:      Status
270 *
271 * DESCRIPTION: Compile CSRT.
272 *
273 *****************************************************************************/
274
275ACPI_STATUS
276DtCompileCsrt (
277    void                    **List)
278{
279    ACPI_STATUS             Status = AE_OK;
280    DT_SUBTABLE             *Subtable;
281    DT_SUBTABLE             *ParentTable;
282    DT_FIELD                **PFieldList = (DT_FIELD **) List;
283    UINT32                  DescriptorCount;
284    UINT32                  GroupLength;
285
286
287    /* Subtables (Resource Groups) */
288
289    ParentTable = DtPeekSubtable ();
290    while (*PFieldList)
291    {
292        /* Resource group subtable */
293
294        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
295            &Subtable, TRUE);
296        if (ACPI_FAILURE (Status))
297        {
298            return (Status);
299        }
300
301        /* Compute the number of resource descriptors */
302
303        GroupLength =
304            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
305                Subtable->Buffer))->Length -
306            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
307                Subtable->Buffer))->SharedInfoLength -
308            sizeof (ACPI_CSRT_GROUP);
309
310        DescriptorCount = (GroupLength  /
311            sizeof (ACPI_CSRT_DESCRIPTOR));
312
313        DtInsertSubtable (ParentTable, Subtable);
314        DtPushSubtable (Subtable);
315        ParentTable = DtPeekSubtable ();
316
317        /* Shared info subtable (One per resource group) */
318
319        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
320            &Subtable, TRUE);
321        if (ACPI_FAILURE (Status))
322        {
323            return (Status);
324        }
325
326        DtInsertSubtable (ParentTable, Subtable);
327
328        /* Sub-Subtables (Resource Descriptors) */
329
330        while (*PFieldList && DescriptorCount)
331        {
332
333            Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
334                &Subtable, TRUE);
335            if (ACPI_FAILURE (Status))
336            {
337                return (Status);
338            }
339
340            DtInsertSubtable (ParentTable, Subtable);
341
342            DtPushSubtable (Subtable);
343            ParentTable = DtPeekSubtable ();
344            if (*PFieldList)
345            {
346                Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
347                    &Subtable, TRUE);
348                if (ACPI_FAILURE (Status))
349                {
350                    return (Status);
351                }
352                if (Subtable)
353                {
354                    DtInsertSubtable (ParentTable, Subtable);
355                }
356            }
357
358            DtPopSubtable ();
359            ParentTable = DtPeekSubtable ();
360            DescriptorCount--;
361        }
362
363        DtPopSubtable ();
364        ParentTable = DtPeekSubtable ();
365    }
366
367    return (Status);
368}
369
370
371/******************************************************************************
372 *
373 * FUNCTION:    DtCompileDbg2
374 *
375 * PARAMETERS:  List                - Current field list pointer
376 *
377 * RETURN:      Status
378 *
379 * DESCRIPTION: Compile DBG2.
380 *
381 *****************************************************************************/
382
383ACPI_STATUS
384DtCompileDbg2 (
385    void                    **List)
386{
387    ACPI_STATUS             Status;
388    DT_SUBTABLE             *Subtable;
389    DT_SUBTABLE             *ParentTable;
390    DT_FIELD                **PFieldList = (DT_FIELD **) List;
391    UINT32                  SubtableCount;
392    ACPI_DBG2_HEADER        *Dbg2Header;
393    ACPI_DBG2_DEVICE        *DeviceInfo;
394    UINT16                  CurrentOffset;
395    UINT32                  i;
396
397
398    /* Main table */
399
400    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
401    if (ACPI_FAILURE (Status))
402    {
403        return (Status);
404    }
405
406    ParentTable = DtPeekSubtable ();
407    DtInsertSubtable (ParentTable, Subtable);
408
409    /* Main table fields */
410
411    Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
412    Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
413        ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
414
415    SubtableCount = Dbg2Header->InfoCount;
416    DtPushSubtable (Subtable);
417
418    /* Process all Device Information subtables (Count = InfoCount) */
419
420    while (*PFieldList && SubtableCount)
421    {
422        /* Subtable: Debug Device Information */
423
424        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
425            &Subtable, TRUE);
426        if (ACPI_FAILURE (Status))
427        {
428            return (Status);
429        }
430
431        DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
432        CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
433
434        ParentTable = DtPeekSubtable ();
435        DtInsertSubtable (ParentTable, Subtable);
436        DtPushSubtable (Subtable);
437
438        ParentTable = DtPeekSubtable ();
439
440        /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
441
442        DeviceInfo->BaseAddressOffset = CurrentOffset;
443        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
444        {
445            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
446                &Subtable, TRUE);
447            if (ACPI_FAILURE (Status))
448            {
449                return (Status);
450            }
451
452            CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
453            DtInsertSubtable (ParentTable, Subtable);
454        }
455
456        /* AddressSize array (Required, size = RegisterCount) */
457
458        DeviceInfo->AddressSizeOffset = CurrentOffset;
459        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
460        {
461            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
462                &Subtable, TRUE);
463            if (ACPI_FAILURE (Status))
464            {
465                return (Status);
466            }
467
468            CurrentOffset += (UINT16) sizeof (UINT32);
469            DtInsertSubtable (ParentTable, Subtable);
470        }
471
472        /* NamespaceString device identifier (Required, size = NamePathLength) */
473
474        DeviceInfo->NamepathOffset = CurrentOffset;
475        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
476            &Subtable, TRUE);
477        if (ACPI_FAILURE (Status))
478        {
479            return (Status);
480        }
481
482        /* Update the device info header */
483
484        DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
485        CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
486        DtInsertSubtable (ParentTable, Subtable);
487
488        /* OemData - Variable-length data (Optional, size = OemDataLength) */
489
490        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
491            &Subtable, TRUE);
492        if (ACPI_FAILURE (Status))
493        {
494            return (Status);
495        }
496
497        /* Update the device info header (zeros if no OEM data present) */
498
499        DeviceInfo->OemDataOffset = 0;
500        DeviceInfo->OemDataLength = 0;
501
502        /* Optional subtable (OemData) */
503
504        if (Subtable && Subtable->Length)
505        {
506            DeviceInfo->OemDataOffset = CurrentOffset;
507            DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
508
509            DtInsertSubtable (ParentTable, Subtable);
510        }
511
512        SubtableCount--;
513        DtPopSubtable (); /* Get next Device Information subtable */
514    }
515
516    DtPopSubtable ();
517    return (AE_OK);
518}
519
520
521/******************************************************************************
522 *
523 * FUNCTION:    DtCompileDmar
524 *
525 * PARAMETERS:  List                - Current field list pointer
526 *
527 * RETURN:      Status
528 *
529 * DESCRIPTION: Compile DMAR.
530 *
531 *****************************************************************************/
532
533ACPI_STATUS
534DtCompileDmar (
535    void                    **List)
536{
537    ACPI_STATUS             Status;
538    DT_SUBTABLE             *Subtable;
539    DT_SUBTABLE             *ParentTable;
540    DT_FIELD                **PFieldList = (DT_FIELD **) List;
541    DT_FIELD                *SubtableStart;
542    ACPI_DMTABLE_INFO       *InfoTable;
543    ACPI_DMAR_HEADER        *DmarHeader;
544    ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
545    UINT32                  DeviceScopeLength;
546    UINT32                  PciPathLength;
547
548
549    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
550    if (ACPI_FAILURE (Status))
551    {
552        return (Status);
553    }
554
555    ParentTable = DtPeekSubtable ();
556    DtInsertSubtable (ParentTable, Subtable);
557    DtPushSubtable (Subtable);
558
559    while (*PFieldList)
560    {
561        /* DMAR Header */
562
563        SubtableStart = *PFieldList;
564        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
565            &Subtable, TRUE);
566        if (ACPI_FAILURE (Status))
567        {
568            return (Status);
569        }
570
571        ParentTable = DtPeekSubtable ();
572        DtInsertSubtable (ParentTable, Subtable);
573        DtPushSubtable (Subtable);
574
575        DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
576
577        switch (DmarHeader->Type)
578        {
579        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
580
581            InfoTable = AcpiDmTableInfoDmar0;
582            break;
583
584        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
585
586            InfoTable = AcpiDmTableInfoDmar1;
587            break;
588
589        case ACPI_DMAR_TYPE_ROOT_ATS:
590
591            InfoTable = AcpiDmTableInfoDmar2;
592            break;
593
594        case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
595
596            InfoTable = AcpiDmTableInfoDmar3;
597            break;
598
599        case ACPI_DMAR_TYPE_NAMESPACE:
600
601            InfoTable = AcpiDmTableInfoDmar4;
602            break;
603
604        default:
605
606            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
607            return (AE_ERROR);
608        }
609
610        /* DMAR Subtable */
611
612        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
613        if (ACPI_FAILURE (Status))
614        {
615            return (Status);
616        }
617
618        ParentTable = DtPeekSubtable ();
619        DtInsertSubtable (ParentTable, Subtable);
620
621        /*
622         * Optional Device Scope subtables
623         */
624        if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
625            (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
626        {
627            /* These types do not support device scopes */
628
629            DtPopSubtable ();
630            continue;
631        }
632
633        DtPushSubtable (Subtable);
634        DeviceScopeLength = DmarHeader->Length - Subtable->Length -
635            ParentTable->Length;
636        while (DeviceScopeLength)
637        {
638            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
639                &Subtable, FALSE);
640            if (Status == AE_NOT_FOUND)
641            {
642                break;
643            }
644
645            ParentTable = DtPeekSubtable ();
646            DtInsertSubtable (ParentTable, Subtable);
647            DtPushSubtable (Subtable);
648
649            DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
650
651            /* Optional PCI Paths */
652
653            PciPathLength = DmarDeviceScope->Length - Subtable->Length;
654            while (PciPathLength)
655            {
656                Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
657                    &Subtable, FALSE);
658                if (Status == AE_NOT_FOUND)
659                {
660                    DtPopSubtable ();
661                    break;
662                }
663
664                ParentTable = DtPeekSubtable ();
665                DtInsertSubtable (ParentTable, Subtable);
666                PciPathLength -= Subtable->Length;
667            }
668
669            DtPopSubtable ();
670            DeviceScopeLength -= DmarDeviceScope->Length;
671        }
672
673        DtPopSubtable ();
674        DtPopSubtable ();
675    }
676
677    return (AE_OK);
678}
679
680
681/******************************************************************************
682 *
683 * FUNCTION:    DtCompileDrtm
684 *
685 * PARAMETERS:  List                - Current field list pointer
686 *
687 * RETURN:      Status
688 *
689 * DESCRIPTION: Compile DRTM.
690 *
691 *****************************************************************************/
692
693ACPI_STATUS
694DtCompileDrtm (
695    void                    **List)
696{
697    ACPI_STATUS             Status;
698    DT_SUBTABLE             *Subtable;
699    DT_SUBTABLE             *ParentTable;
700    DT_FIELD                **PFieldList = (DT_FIELD **) List;
701    UINT32                  Count;
702    /* ACPI_TABLE_DRTM         *Drtm; */
703    ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
704    ACPI_DRTM_RESOURCE_LIST *DrtmRl;
705    /* ACPI_DRTM_DPS_ID        *DrtmDps; */
706
707
708    ParentTable = DtPeekSubtable ();
709
710    /* Compile DRTM header */
711
712    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
713        &Subtable, TRUE);
714    if (ACPI_FAILURE (Status))
715    {
716        return (Status);
717    }
718    DtInsertSubtable (ParentTable, Subtable);
719
720    /*
721     * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
722     * should be taken to avoid accessing ACPI_TABLE_HADER fields.
723     */
724#if 0
725    Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
726        Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
727#endif
728    /* Compile VTL */
729
730    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
731        &Subtable, TRUE);
732    if (ACPI_FAILURE (Status))
733    {
734        return (Status);
735    }
736
737    DtInsertSubtable (ParentTable, Subtable);
738    DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
739
740    DtPushSubtable (Subtable);
741    ParentTable = DtPeekSubtable ();
742    Count = 0;
743
744    while (*PFieldList)
745    {
746        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
747            &Subtable, TRUE);
748        if (ACPI_FAILURE (Status))
749        {
750            return (Status);
751        }
752        if (!Subtable)
753        {
754            break;
755        }
756        DtInsertSubtable (ParentTable, Subtable);
757        Count++;
758    }
759
760    DrtmVtl->ValidatedTableCount = Count;
761    DtPopSubtable ();
762    ParentTable = DtPeekSubtable ();
763
764    /* Compile RL */
765
766    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
767        &Subtable, TRUE);
768    if (ACPI_FAILURE (Status))
769    {
770        return (Status);
771    }
772
773    DtInsertSubtable (ParentTable, Subtable);
774    DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
775
776    DtPushSubtable (Subtable);
777    ParentTable = DtPeekSubtable ();
778    Count = 0;
779
780    while (*PFieldList)
781    {
782        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
783            &Subtable, TRUE);
784        if (ACPI_FAILURE (Status))
785        {
786            return (Status);
787        }
788
789        if (!Subtable)
790        {
791            break;
792        }
793
794        DtInsertSubtable (ParentTable, Subtable);
795        Count++;
796    }
797
798    DrtmRl->ResourceCount = Count;
799    DtPopSubtable ();
800    ParentTable = DtPeekSubtable ();
801
802    /* Compile DPS */
803
804    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
805        &Subtable, TRUE);
806    if (ACPI_FAILURE (Status))
807    {
808        return (Status);
809    }
810    DtInsertSubtable (ParentTable, Subtable);
811    /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
812
813
814    return (AE_OK);
815}
816
817
818/******************************************************************************
819 *
820 * FUNCTION:    DtCompileEinj
821 *
822 * PARAMETERS:  List                - Current field list pointer
823 *
824 * RETURN:      Status
825 *
826 * DESCRIPTION: Compile EINJ.
827 *
828 *****************************************************************************/
829
830ACPI_STATUS
831DtCompileEinj (
832    void                    **List)
833{
834    ACPI_STATUS             Status;
835
836
837    Status = DtCompileTwoSubtables (List,
838        AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
839    return (Status);
840}
841
842
843/******************************************************************************
844 *
845 * FUNCTION:    DtCompileErst
846 *
847 * PARAMETERS:  List                - Current field list pointer
848 *
849 * RETURN:      Status
850 *
851 * DESCRIPTION: Compile ERST.
852 *
853 *****************************************************************************/
854
855ACPI_STATUS
856DtCompileErst (
857    void                    **List)
858{
859    ACPI_STATUS             Status;
860
861
862    Status = DtCompileTwoSubtables (List,
863        AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
864    return (Status);
865}
866
867
868/******************************************************************************
869 *
870 * FUNCTION:    DtCompileGtdt
871 *
872 * PARAMETERS:  List                - Current field list pointer
873 *
874 * RETURN:      Status
875 *
876 * DESCRIPTION: Compile GTDT.
877 *
878 *****************************************************************************/
879
880ACPI_STATUS
881DtCompileGtdt (
882    void                    **List)
883{
884    ACPI_STATUS             Status;
885    DT_SUBTABLE             *Subtable;
886    DT_SUBTABLE             *ParentTable;
887    DT_FIELD                **PFieldList = (DT_FIELD **) List;
888    DT_FIELD                *SubtableStart;
889    ACPI_SUBTABLE_HEADER    *GtdtHeader;
890    ACPI_DMTABLE_INFO       *InfoTable;
891    UINT32                  GtCount;
892
893
894    Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
895        &Subtable, TRUE);
896    if (ACPI_FAILURE (Status))
897    {
898        return (Status);
899    }
900
901    ParentTable = DtPeekSubtable ();
902    DtInsertSubtable (ParentTable, Subtable);
903
904    while (*PFieldList)
905    {
906        SubtableStart = *PFieldList;
907        Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
908            &Subtable, TRUE);
909        if (ACPI_FAILURE (Status))
910        {
911            return (Status);
912        }
913
914        ParentTable = DtPeekSubtable ();
915        DtInsertSubtable (ParentTable, Subtable);
916        DtPushSubtable (Subtable);
917
918        GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
919
920        switch (GtdtHeader->Type)
921        {
922        case ACPI_GTDT_TYPE_TIMER_BLOCK:
923
924            InfoTable = AcpiDmTableInfoGtdt0;
925            break;
926
927        case ACPI_GTDT_TYPE_WATCHDOG:
928
929            InfoTable = AcpiDmTableInfoGtdt1;
930            break;
931
932        default:
933
934            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
935            return (AE_ERROR);
936        }
937
938        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
939        if (ACPI_FAILURE (Status))
940        {
941            return (Status);
942        }
943
944        ParentTable = DtPeekSubtable ();
945        DtInsertSubtable (ParentTable, Subtable);
946
947        /*
948         * Additional GT block subtable data
949         */
950
951        switch (GtdtHeader->Type)
952        {
953        case ACPI_GTDT_TYPE_TIMER_BLOCK:
954
955            DtPushSubtable (Subtable);
956            ParentTable = DtPeekSubtable ();
957
958            GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
959                Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
960
961            while (GtCount)
962            {
963                Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
964                    &Subtable, TRUE);
965                if (ACPI_FAILURE (Status))
966                {
967                    return (Status);
968                }
969
970                DtInsertSubtable (ParentTable, Subtable);
971                GtCount--;
972            }
973
974            DtPopSubtable ();
975            break;
976
977        default:
978
979            break;
980        }
981
982        DtPopSubtable ();
983    }
984
985    return (AE_OK);
986}
987
988
989/******************************************************************************
990 *
991 * FUNCTION:    DtCompileFpdt
992 *
993 * PARAMETERS:  List                - Current field list pointer
994 *
995 * RETURN:      Status
996 *
997 * DESCRIPTION: Compile FPDT.
998 *
999 *****************************************************************************/
1000
1001ACPI_STATUS
1002DtCompileFpdt (
1003    void                    **List)
1004{
1005    ACPI_STATUS             Status;
1006    ACPI_FPDT_HEADER        *FpdtHeader;
1007    DT_SUBTABLE             *Subtable;
1008    DT_SUBTABLE             *ParentTable;
1009    ACPI_DMTABLE_INFO       *InfoTable;
1010    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1011    DT_FIELD                *SubtableStart;
1012
1013
1014    while (*PFieldList)
1015    {
1016        SubtableStart = *PFieldList;
1017        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1018            &Subtable, TRUE);
1019        if (ACPI_FAILURE (Status))
1020        {
1021            return (Status);
1022        }
1023
1024        ParentTable = DtPeekSubtable ();
1025        DtInsertSubtable (ParentTable, Subtable);
1026        DtPushSubtable (Subtable);
1027
1028        FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1029
1030        switch (FpdtHeader->Type)
1031        {
1032        case ACPI_FPDT_TYPE_BOOT:
1033
1034            InfoTable = AcpiDmTableInfoFpdt0;
1035            break;
1036
1037        case ACPI_FPDT_TYPE_S3PERF:
1038
1039            InfoTable = AcpiDmTableInfoFpdt1;
1040            break;
1041
1042        default:
1043
1044            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1045            return (AE_ERROR);
1046            break;
1047        }
1048
1049        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1050        if (ACPI_FAILURE (Status))
1051        {
1052            return (Status);
1053        }
1054
1055        ParentTable = DtPeekSubtable ();
1056        DtInsertSubtable (ParentTable, Subtable);
1057        DtPopSubtable ();
1058    }
1059
1060    return (AE_OK);
1061}
1062
1063
1064/******************************************************************************
1065 *
1066 * FUNCTION:    DtCompileHest
1067 *
1068 * PARAMETERS:  List                - Current field list pointer
1069 *
1070 * RETURN:      Status
1071 *
1072 * DESCRIPTION: Compile HEST.
1073 *
1074 *****************************************************************************/
1075
1076ACPI_STATUS
1077DtCompileHest (
1078    void                    **List)
1079{
1080    ACPI_STATUS             Status;
1081    DT_SUBTABLE             *Subtable;
1082    DT_SUBTABLE             *ParentTable;
1083    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1084    DT_FIELD                *SubtableStart;
1085    ACPI_DMTABLE_INFO       *InfoTable;
1086    UINT16                  Type;
1087    UINT32                  BankCount;
1088
1089
1090    Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1091        &Subtable, TRUE);
1092    if (ACPI_FAILURE (Status))
1093    {
1094        return (Status);
1095    }
1096
1097    ParentTable = DtPeekSubtable ();
1098    DtInsertSubtable (ParentTable, Subtable);
1099
1100    while (*PFieldList)
1101    {
1102        /* Get subtable type */
1103
1104        SubtableStart = *PFieldList;
1105        DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1106
1107        switch (Type)
1108        {
1109        case ACPI_HEST_TYPE_IA32_CHECK:
1110
1111            InfoTable = AcpiDmTableInfoHest0;
1112            break;
1113
1114        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1115
1116            InfoTable = AcpiDmTableInfoHest1;
1117            break;
1118
1119        case ACPI_HEST_TYPE_IA32_NMI:
1120
1121            InfoTable = AcpiDmTableInfoHest2;
1122            break;
1123
1124        case ACPI_HEST_TYPE_AER_ROOT_PORT:
1125
1126            InfoTable = AcpiDmTableInfoHest6;
1127            break;
1128
1129        case ACPI_HEST_TYPE_AER_ENDPOINT:
1130
1131            InfoTable = AcpiDmTableInfoHest7;
1132            break;
1133
1134        case ACPI_HEST_TYPE_AER_BRIDGE:
1135
1136            InfoTable = AcpiDmTableInfoHest8;
1137            break;
1138
1139        case ACPI_HEST_TYPE_GENERIC_ERROR:
1140
1141            InfoTable = AcpiDmTableInfoHest9;
1142            break;
1143
1144        default:
1145
1146            /* Cannot continue on unknown type */
1147
1148            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1149            return (AE_ERROR);
1150        }
1151
1152        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1153        if (ACPI_FAILURE (Status))
1154        {
1155            return (Status);
1156        }
1157
1158        DtInsertSubtable (ParentTable, Subtable);
1159
1160        /*
1161         * Additional subtable data - IA32 Error Bank(s)
1162         */
1163        BankCount = 0;
1164        switch (Type)
1165        {
1166        case ACPI_HEST_TYPE_IA32_CHECK:
1167
1168            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1169                Subtable->Buffer))->NumHardwareBanks;
1170            break;
1171
1172        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1173
1174            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1175                Subtable->Buffer))->NumHardwareBanks;
1176            break;
1177
1178        default:
1179
1180            break;
1181        }
1182
1183        while (BankCount)
1184        {
1185            Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1186                &Subtable, TRUE);
1187            if (ACPI_FAILURE (Status))
1188            {
1189                return (Status);
1190            }
1191
1192            DtInsertSubtable (ParentTable, Subtable);
1193            BankCount--;
1194        }
1195    }
1196
1197    return (AE_OK);
1198}
1199
1200
1201/******************************************************************************
1202 *
1203 * FUNCTION:    DtCompileIort
1204 *
1205 * PARAMETERS:  List                - Current field list pointer
1206 *
1207 * RETURN:      Status
1208 *
1209 * DESCRIPTION: Compile IORT.
1210 *
1211 *****************************************************************************/
1212
1213ACPI_STATUS
1214DtCompileIort (
1215    void                    **List)
1216{
1217    ACPI_STATUS             Status;
1218    DT_SUBTABLE             *Subtable;
1219    DT_SUBTABLE             *ParentTable;
1220    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1221    DT_FIELD                *SubtableStart;
1222    ACPI_TABLE_IORT         *Iort;
1223    ACPI_IORT_NODE          *IortNode;
1224    ACPI_IORT_ITS_GROUP     *IortItsGroup;
1225    ACPI_IORT_SMMU          *IortSmmu;
1226    UINT32                  NodeNumber;
1227    UINT32                  NodeLength;
1228    UINT32                  IdMappingNumber;
1229    UINT32                  ItsNumber;
1230    UINT32                  ContextIrptNumber;
1231    UINT32                  PmuIrptNumber;
1232    UINT32                  PaddingLength;
1233
1234
1235    ParentTable = DtPeekSubtable ();
1236
1237    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1238        &Subtable, TRUE);
1239    if (ACPI_FAILURE (Status))
1240    {
1241        return (Status);
1242    }
1243    DtInsertSubtable (ParentTable, Subtable);
1244
1245    /*
1246     * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1247     * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
1248     */
1249    Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1250        Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1251
1252    /*
1253     * OptionalPadding - Variable-length data
1254     * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1255     * Optionally allows the generic data types to be used for filling
1256     * this field.
1257     */
1258    Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1259    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1260        &Subtable, TRUE);
1261    if (ACPI_FAILURE (Status))
1262    {
1263        return (Status);
1264    }
1265    if (Subtable)
1266    {
1267        DtInsertSubtable (ParentTable, Subtable);
1268        Iort->NodeOffset += Subtable->Length;
1269    }
1270    else
1271    {
1272        Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1273            AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1274        if (ACPI_FAILURE (Status))
1275        {
1276            return (Status);
1277        }
1278        Iort->NodeOffset += PaddingLength;
1279    }
1280
1281    NodeNumber = 0;
1282    while (*PFieldList)
1283    {
1284        SubtableStart = *PFieldList;
1285        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1286            &Subtable, TRUE);
1287        if (ACPI_FAILURE (Status))
1288        {
1289            return (Status);
1290        }
1291
1292        DtInsertSubtable (ParentTable, Subtable);
1293        IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1294        NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1295
1296        DtPushSubtable (Subtable);
1297        ParentTable = DtPeekSubtable ();
1298
1299        switch (IortNode->Type)
1300        {
1301        case ACPI_IORT_NODE_ITS_GROUP:
1302
1303            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1304                &Subtable, TRUE);
1305            if (ACPI_FAILURE (Status))
1306            {
1307                return (Status);
1308            }
1309
1310            DtInsertSubtable (ParentTable, Subtable);
1311            IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1312            NodeLength += Subtable->Length;
1313
1314            ItsNumber = 0;
1315            while (*PFieldList)
1316            {
1317                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1318                    &Subtable, TRUE);
1319                if (ACPI_FAILURE (Status))
1320                {
1321                    return (Status);
1322                }
1323                if (!Subtable)
1324                {
1325                    break;
1326                }
1327
1328                DtInsertSubtable (ParentTable, Subtable);
1329                NodeLength += Subtable->Length;
1330                ItsNumber++;
1331            }
1332
1333            IortItsGroup->ItsCount = ItsNumber;
1334            break;
1335
1336        case ACPI_IORT_NODE_NAMED_COMPONENT:
1337
1338            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1339                &Subtable, TRUE);
1340            if (ACPI_FAILURE (Status))
1341            {
1342                return (Status);
1343            }
1344
1345            DtInsertSubtable (ParentTable, Subtable);
1346            NodeLength += Subtable->Length;
1347
1348            /*
1349             * Padding - Variable-length data
1350             * Optionally allows the offset of the ID mappings to be used
1351             * for filling this field.
1352             */
1353            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1354                &Subtable, TRUE);
1355            if (ACPI_FAILURE (Status))
1356            {
1357                return (Status);
1358            }
1359
1360            if (Subtable)
1361            {
1362                DtInsertSubtable (ParentTable, Subtable);
1363                NodeLength += Subtable->Length;
1364            }
1365            else
1366            {
1367                if (NodeLength > IortNode->MappingOffset)
1368                {
1369                    return (AE_BAD_DATA);
1370                }
1371
1372                if (NodeLength < IortNode->MappingOffset)
1373                {
1374                    Status = DtCompilePadding (
1375                        IortNode->MappingOffset - NodeLength,
1376                        &Subtable);
1377                    if (ACPI_FAILURE (Status))
1378                    {
1379                        return (Status);
1380                    }
1381
1382                    DtInsertSubtable (ParentTable, Subtable);
1383                    NodeLength = IortNode->MappingOffset;
1384                }
1385            }
1386            break;
1387
1388        case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1389
1390            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1391                &Subtable, TRUE);
1392            if (ACPI_FAILURE (Status))
1393            {
1394                return (Status);
1395            }
1396
1397            DtInsertSubtable (ParentTable, Subtable);
1398            NodeLength += Subtable->Length;
1399            break;
1400
1401        case ACPI_IORT_NODE_SMMU:
1402
1403            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1404                &Subtable, TRUE);
1405            if (ACPI_FAILURE (Status))
1406            {
1407                return (Status);
1408            }
1409
1410            DtInsertSubtable (ParentTable, Subtable);
1411            IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1412            NodeLength += Subtable->Length;
1413
1414            /* Compile global interrupt array */
1415
1416            IortSmmu->GlobalInterruptOffset = NodeLength;
1417            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1418                &Subtable, TRUE);
1419            if (ACPI_FAILURE (Status))
1420            {
1421                return (Status);
1422            }
1423
1424            DtInsertSubtable (ParentTable, Subtable);
1425            NodeLength += Subtable->Length;
1426
1427            /* Compile context interrupt array */
1428
1429            ContextIrptNumber = 0;
1430            IortSmmu->ContextInterruptOffset = NodeLength;
1431            while (*PFieldList)
1432            {
1433                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1434                    &Subtable, TRUE);
1435                if (ACPI_FAILURE (Status))
1436                {
1437                    return (Status);
1438                }
1439
1440                if (!Subtable)
1441                {
1442                    break;
1443                }
1444
1445                DtInsertSubtable (ParentTable, Subtable);
1446                NodeLength += Subtable->Length;
1447                ContextIrptNumber++;
1448            }
1449
1450            IortSmmu->ContextInterruptCount = ContextIrptNumber;
1451
1452            /* Compile PMU interrupt array */
1453
1454            PmuIrptNumber = 0;
1455            IortSmmu->PmuInterruptOffset = NodeLength;
1456            while (*PFieldList)
1457            {
1458                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1459                    &Subtable, TRUE);
1460                if (ACPI_FAILURE (Status))
1461                {
1462                    return (Status);
1463                }
1464
1465                if (!Subtable)
1466                {
1467                    break;
1468                }
1469
1470                DtInsertSubtable (ParentTable, Subtable);
1471                NodeLength += Subtable->Length;
1472                PmuIrptNumber++;
1473            }
1474
1475            IortSmmu->PmuInterruptCount = PmuIrptNumber;
1476            break;
1477
1478        case ACPI_IORT_NODE_SMMU_V3:
1479
1480            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
1481                &Subtable, TRUE);
1482            if (ACPI_FAILURE (Status))
1483            {
1484                return (Status);
1485            }
1486
1487            DtInsertSubtable (ParentTable, Subtable);
1488            NodeLength += Subtable->Length;
1489            break;
1490
1491        default:
1492
1493            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1494            return (AE_ERROR);
1495        }
1496
1497        /* Compile Array of ID mappings */
1498
1499        IortNode->MappingOffset = NodeLength;
1500        IdMappingNumber = 0;
1501        while (*PFieldList)
1502        {
1503            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1504                &Subtable, TRUE);
1505            if (ACPI_FAILURE (Status))
1506            {
1507                return (Status);
1508            }
1509
1510            if (!Subtable)
1511            {
1512                break;
1513            }
1514
1515            DtInsertSubtable (ParentTable, Subtable);
1516            NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1517            IdMappingNumber++;
1518        }
1519
1520        IortNode->MappingCount = IdMappingNumber;
1521
1522        /*
1523         * Node length can be determined by DT_LENGTH option
1524         * IortNode->Length = NodeLength;
1525         */
1526        DtPopSubtable ();
1527        ParentTable = DtPeekSubtable ();
1528        NodeNumber++;
1529    }
1530
1531    Iort->NodeCount = NodeNumber;
1532    return (AE_OK);
1533}
1534
1535
1536/******************************************************************************
1537 *
1538 * FUNCTION:    DtCompileIvrs
1539 *
1540 * PARAMETERS:  List                - Current field list pointer
1541 *
1542 * RETURN:      Status
1543 *
1544 * DESCRIPTION: Compile IVRS.
1545 *
1546 *****************************************************************************/
1547
1548ACPI_STATUS
1549DtCompileIvrs (
1550    void                    **List)
1551{
1552    ACPI_STATUS             Status;
1553    DT_SUBTABLE             *Subtable;
1554    DT_SUBTABLE             *ParentTable;
1555    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1556    DT_FIELD                *SubtableStart;
1557    ACPI_DMTABLE_INFO       *InfoTable;
1558    ACPI_IVRS_HEADER        *IvrsHeader;
1559    UINT8                   EntryType;
1560
1561
1562    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1563        &Subtable, TRUE);
1564    if (ACPI_FAILURE (Status))
1565    {
1566        return (Status);
1567    }
1568
1569    ParentTable = DtPeekSubtable ();
1570    DtInsertSubtable (ParentTable, Subtable);
1571
1572    while (*PFieldList)
1573    {
1574        SubtableStart = *PFieldList;
1575        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1576            &Subtable, TRUE);
1577        if (ACPI_FAILURE (Status))
1578        {
1579            return (Status);
1580        }
1581
1582        ParentTable = DtPeekSubtable ();
1583        DtInsertSubtable (ParentTable, Subtable);
1584        DtPushSubtable (Subtable);
1585
1586        IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1587
1588        switch (IvrsHeader->Type)
1589        {
1590        case ACPI_IVRS_TYPE_HARDWARE:
1591
1592            InfoTable = AcpiDmTableInfoIvrs0;
1593            break;
1594
1595        case ACPI_IVRS_TYPE_MEMORY1:
1596        case ACPI_IVRS_TYPE_MEMORY2:
1597        case ACPI_IVRS_TYPE_MEMORY3:
1598
1599            InfoTable = AcpiDmTableInfoIvrs1;
1600            break;
1601
1602        default:
1603
1604            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1605            return (AE_ERROR);
1606        }
1607
1608        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1609        if (ACPI_FAILURE (Status))
1610        {
1611            return (Status);
1612        }
1613
1614        ParentTable = DtPeekSubtable ();
1615        DtInsertSubtable (ParentTable, Subtable);
1616
1617        if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1618        {
1619            while (*PFieldList &&
1620                !strcmp ((*PFieldList)->Name, "Entry Type"))
1621            {
1622                SubtableStart = *PFieldList;
1623                DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1624
1625                switch (EntryType)
1626                {
1627                /* 4-byte device entries */
1628
1629                case ACPI_IVRS_TYPE_PAD4:
1630                case ACPI_IVRS_TYPE_ALL:
1631                case ACPI_IVRS_TYPE_SELECT:
1632                case ACPI_IVRS_TYPE_START:
1633                case ACPI_IVRS_TYPE_END:
1634
1635                    InfoTable = AcpiDmTableInfoIvrs4;
1636                    break;
1637
1638                /* 8-byte entries, type A */
1639
1640                case ACPI_IVRS_TYPE_ALIAS_SELECT:
1641                case ACPI_IVRS_TYPE_ALIAS_START:
1642
1643                    InfoTable = AcpiDmTableInfoIvrs8a;
1644                    break;
1645
1646                /* 8-byte entries, type B */
1647
1648                case ACPI_IVRS_TYPE_PAD8:
1649                case ACPI_IVRS_TYPE_EXT_SELECT:
1650                case ACPI_IVRS_TYPE_EXT_START:
1651
1652                    InfoTable = AcpiDmTableInfoIvrs8b;
1653                    break;
1654
1655                /* 8-byte entries, type C */
1656
1657                case ACPI_IVRS_TYPE_SPECIAL:
1658
1659                    InfoTable = AcpiDmTableInfoIvrs8c;
1660                    break;
1661
1662                default:
1663
1664                    DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1665                        "IVRS Device Entry");
1666                    return (AE_ERROR);
1667                }
1668
1669                Status = DtCompileTable (PFieldList, InfoTable,
1670                    &Subtable, TRUE);
1671                if (ACPI_FAILURE (Status))
1672                {
1673                    return (Status);
1674                }
1675
1676                DtInsertSubtable (ParentTable, Subtable);
1677            }
1678        }
1679
1680        DtPopSubtable ();
1681    }
1682
1683    return (AE_OK);
1684}
1685