]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/compiler/dttable1.c
Checkpoint initial integration work
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / compiler / dttable1.c
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
53 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
54 {
55     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
56     {ACPI_DMT_EXIT,     0,               NULL, 0}
57 };
58
59 static 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
78 ACPI_STATUS
79 DtCompileAsf (
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
250 ACPI_STATUS
251 DtCompileCpep (
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
275 ACPI_STATUS
276 DtCompileCsrt (
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
383 ACPI_STATUS
384 DtCompileDbg2 (
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
533 ACPI_STATUS
534 DtCompileDmar (
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
693 ACPI_STATUS
694 DtCompileDrtm (
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
830 ACPI_STATUS
831 DtCompileEinj (
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
855 ACPI_STATUS
856 DtCompileErst (
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
880 ACPI_STATUS
881 DtCompileGtdt (
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
1001 ACPI_STATUS
1002 DtCompileFpdt (
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
1076 ACPI_STATUS
1077 DtCompileHest (
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
1213 ACPI_STATUS
1214 DtCompileIort (
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
1548 ACPI_STATUS
1549 DtCompileIvrs (
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 }