1291333Sjkim/******************************************************************************
2291333Sjkim *
3291333Sjkim * Module Name: dttable1.c - handling for specific ACPI tables
4291333Sjkim *
5291333Sjkim *****************************************************************************/
6291333Sjkim
7291333Sjkim/*
8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9291333Sjkim * All rights reserved.
10291333Sjkim *
11291333Sjkim * Redistribution and use in source and binary forms, with or without
12291333Sjkim * modification, are permitted provided that the following conditions
13291333Sjkim * are met:
14291333Sjkim * 1. Redistributions of source code must retain the above copyright
15291333Sjkim *    notice, this list of conditions, and the following disclaimer,
16291333Sjkim *    without modification.
17291333Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18291333Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19291333Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20291333Sjkim *    including a substantially similar Disclaimer requirement for further
21291333Sjkim *    binary redistribution.
22291333Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23291333Sjkim *    of any contributors may be used to endorse or promote products derived
24291333Sjkim *    from this software without specific prior written permission.
25291333Sjkim *
26291333Sjkim * Alternatively, this software may be distributed under the terms of the
27291333Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28291333Sjkim * Software Foundation.
29291333Sjkim *
30291333Sjkim * NO WARRANTY
31291333Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32291333Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33291333Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34291333Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35291333Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36291333Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37291333Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38291333Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39291333Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40291333Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41291333Sjkim * POSSIBILITY OF SUCH DAMAGES.
42291333Sjkim */
43291333Sjkim
44291333Sjkim/* Compile all complex data tables, signatures starting with A-I */
45291333Sjkim
46298714Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47298714Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
48291333Sjkim
49291333Sjkim#define _COMPONENT          DT_COMPILER
50291333Sjkim        ACPI_MODULE_NAME    ("dttable1")
51291333Sjkim
52291333Sjkim
53291333Sjkimstatic ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
54291333Sjkim{
55291333Sjkim    {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
56291333Sjkim    {ACPI_DMT_EXIT,     0,               NULL, 0}
57291333Sjkim};
58291333Sjkim
59291333Sjkimstatic ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
60291333Sjkim{
61291333Sjkim    {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
62291333Sjkim    {ACPI_DMT_EXIT,     0,               NULL, 0}
63291333Sjkim};
64291333Sjkim
65291333Sjkim
66291333Sjkim/******************************************************************************
67291333Sjkim *
68291333Sjkim * FUNCTION:    DtCompileAsf
69291333Sjkim *
70291333Sjkim * PARAMETERS:  List                - Current field list pointer
71291333Sjkim *
72291333Sjkim * RETURN:      Status
73291333Sjkim *
74291333Sjkim * DESCRIPTION: Compile ASF!.
75291333Sjkim *
76291333Sjkim *****************************************************************************/
77291333Sjkim
78291333SjkimACPI_STATUS
79291333SjkimDtCompileAsf (
80291333Sjkim    void                    **List)
81291333Sjkim{
82291333Sjkim    ACPI_ASF_INFO           *AsfTable;
83291333Sjkim    DT_SUBTABLE             *Subtable;
84291333Sjkim    DT_SUBTABLE             *ParentTable;
85291333Sjkim    ACPI_DMTABLE_INFO       *InfoTable;
86291333Sjkim    ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
87291333Sjkim    UINT32                  DataCount = 0;
88291333Sjkim    ACPI_STATUS             Status;
89291333Sjkim    UINT32                  i;
90291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
91291333Sjkim    DT_FIELD                *SubtableStart;
92291333Sjkim
93291333Sjkim
94291333Sjkim    while (*PFieldList)
95291333Sjkim    {
96291333Sjkim        SubtableStart = *PFieldList;
97291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
98291333Sjkim            &Subtable, TRUE);
99291333Sjkim        if (ACPI_FAILURE (Status))
100291333Sjkim        {
101291333Sjkim            return (Status);
102291333Sjkim        }
103291333Sjkim
104291333Sjkim        ParentTable = DtPeekSubtable ();
105291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
106291333Sjkim        DtPushSubtable (Subtable);
107291333Sjkim
108291333Sjkim        AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
109291333Sjkim
110291333Sjkim        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
111291333Sjkim        {
112291333Sjkim        case ACPI_ASF_TYPE_INFO:
113291333Sjkim
114291333Sjkim            InfoTable = AcpiDmTableInfoAsf0;
115291333Sjkim            break;
116291333Sjkim
117291333Sjkim        case ACPI_ASF_TYPE_ALERT:
118291333Sjkim
119291333Sjkim            InfoTable = AcpiDmTableInfoAsf1;
120291333Sjkim            break;
121291333Sjkim
122291333Sjkim        case ACPI_ASF_TYPE_CONTROL:
123291333Sjkim
124291333Sjkim            InfoTable = AcpiDmTableInfoAsf2;
125291333Sjkim            break;
126291333Sjkim
127291333Sjkim        case ACPI_ASF_TYPE_BOOT:
128291333Sjkim
129291333Sjkim            InfoTable = AcpiDmTableInfoAsf3;
130291333Sjkim            break;
131291333Sjkim
132291333Sjkim        case ACPI_ASF_TYPE_ADDRESS:
133291333Sjkim
134291333Sjkim            InfoTable = AcpiDmTableInfoAsf4;
135291333Sjkim            break;
136291333Sjkim
137291333Sjkim        default:
138291333Sjkim
139291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
140291333Sjkim            return (AE_ERROR);
141291333Sjkim        }
142291333Sjkim
143291333Sjkim        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
144291333Sjkim        if (ACPI_FAILURE (Status))
145291333Sjkim        {
146291333Sjkim            return (Status);
147291333Sjkim        }
148291333Sjkim
149291333Sjkim        ParentTable = DtPeekSubtable ();
150291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
151291333Sjkim
152291333Sjkim        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
153291333Sjkim        {
154291333Sjkim        case ACPI_ASF_TYPE_INFO:
155291333Sjkim
156291333Sjkim            DataInfoTable = NULL;
157291333Sjkim            break;
158291333Sjkim
159291333Sjkim        case ACPI_ASF_TYPE_ALERT:
160291333Sjkim
161291333Sjkim            DataInfoTable = AcpiDmTableInfoAsf1a;
162291333Sjkim            DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
163291333Sjkim                ACPI_SUB_PTR (UINT8, Subtable->Buffer,
164291333Sjkim                    sizeof (ACPI_ASF_HEADER)))->Alerts;
165291333Sjkim            break;
166291333Sjkim
167291333Sjkim        case ACPI_ASF_TYPE_CONTROL:
168291333Sjkim
169291333Sjkim            DataInfoTable = AcpiDmTableInfoAsf2a;
170291333Sjkim            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
171291333Sjkim                ACPI_SUB_PTR (UINT8, Subtable->Buffer,
172291333Sjkim                    sizeof (ACPI_ASF_HEADER)))->Controls;
173291333Sjkim            break;
174291333Sjkim
175291333Sjkim        case ACPI_ASF_TYPE_BOOT:
176291333Sjkim
177291333Sjkim            DataInfoTable = NULL;
178291333Sjkim            break;
179291333Sjkim
180291333Sjkim        case ACPI_ASF_TYPE_ADDRESS:
181291333Sjkim
182291333Sjkim            DataInfoTable = TableInfoAsfAddress;
183291333Sjkim            DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
184291333Sjkim                ACPI_SUB_PTR (UINT8, Subtable->Buffer,
185291333Sjkim                    sizeof (ACPI_ASF_HEADER)))->Devices;
186291333Sjkim            break;
187291333Sjkim
188291333Sjkim        default:
189291333Sjkim
190291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
191291333Sjkim            return (AE_ERROR);
192291333Sjkim        }
193291333Sjkim
194291333Sjkim        if (DataInfoTable)
195291333Sjkim        {
196291333Sjkim            switch (AsfTable->Header.Type & 0x7F)
197291333Sjkim            {
198291333Sjkim            case ACPI_ASF_TYPE_ADDRESS:
199291333Sjkim
200291333Sjkim                while (DataCount > 0)
201291333Sjkim                {
202291333Sjkim                    Status = DtCompileTable (PFieldList, DataInfoTable,
203291333Sjkim                        &Subtable, TRUE);
204291333Sjkim                    if (ACPI_FAILURE (Status))
205291333Sjkim                    {
206291333Sjkim                        return (Status);
207291333Sjkim                    }
208291333Sjkim
209291333Sjkim                    DtInsertSubtable (ParentTable, Subtable);
210291333Sjkim                    DataCount = DataCount - Subtable->Length;
211291333Sjkim                }
212291333Sjkim                break;
213291333Sjkim
214291333Sjkim            default:
215291333Sjkim
216291333Sjkim                for (i = 0; i < DataCount; i++)
217291333Sjkim                {
218291333Sjkim                    Status = DtCompileTable (PFieldList, DataInfoTable,
219291333Sjkim                        &Subtable, TRUE);
220291333Sjkim                    if (ACPI_FAILURE (Status))
221291333Sjkim                    {
222291333Sjkim                        return (Status);
223291333Sjkim                    }
224291333Sjkim
225291333Sjkim                    DtInsertSubtable (ParentTable, Subtable);
226291333Sjkim                }
227291333Sjkim                break;
228291333Sjkim            }
229291333Sjkim        }
230291333Sjkim
231291333Sjkim        DtPopSubtable ();
232291333Sjkim    }
233291333Sjkim
234291333Sjkim    return (AE_OK);
235291333Sjkim}
236291333Sjkim
237291333Sjkim
238291333Sjkim/******************************************************************************
239291333Sjkim *
240291333Sjkim * FUNCTION:    DtCompileCpep
241291333Sjkim *
242291333Sjkim * PARAMETERS:  List                - Current field list pointer
243291333Sjkim *
244291333Sjkim * RETURN:      Status
245291333Sjkim *
246291333Sjkim * DESCRIPTION: Compile CPEP.
247291333Sjkim *
248291333Sjkim *****************************************************************************/
249291333Sjkim
250291333SjkimACPI_STATUS
251291333SjkimDtCompileCpep (
252291333Sjkim    void                    **List)
253291333Sjkim{
254291333Sjkim    ACPI_STATUS             Status;
255291333Sjkim
256291333Sjkim
257291333Sjkim    Status = DtCompileTwoSubtables (List,
258291333Sjkim        AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
259291333Sjkim    return (Status);
260291333Sjkim}
261291333Sjkim
262291333Sjkim
263291333Sjkim/******************************************************************************
264291333Sjkim *
265291333Sjkim * FUNCTION:    DtCompileCsrt
266291333Sjkim *
267291333Sjkim * PARAMETERS:  List                - Current field list pointer
268291333Sjkim *
269291333Sjkim * RETURN:      Status
270291333Sjkim *
271291333Sjkim * DESCRIPTION: Compile CSRT.
272291333Sjkim *
273291333Sjkim *****************************************************************************/
274291333Sjkim
275291333SjkimACPI_STATUS
276291333SjkimDtCompileCsrt (
277291333Sjkim    void                    **List)
278291333Sjkim{
279291333Sjkim    ACPI_STATUS             Status = AE_OK;
280291333Sjkim    DT_SUBTABLE             *Subtable;
281291333Sjkim    DT_SUBTABLE             *ParentTable;
282291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
283291333Sjkim    UINT32                  DescriptorCount;
284291333Sjkim    UINT32                  GroupLength;
285291333Sjkim
286291333Sjkim
287291333Sjkim    /* Subtables (Resource Groups) */
288291333Sjkim
289291333Sjkim    ParentTable = DtPeekSubtable ();
290291333Sjkim    while (*PFieldList)
291291333Sjkim    {
292291333Sjkim        /* Resource group subtable */
293291333Sjkim
294291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
295291333Sjkim            &Subtable, TRUE);
296291333Sjkim        if (ACPI_FAILURE (Status))
297291333Sjkim        {
298291333Sjkim            return (Status);
299291333Sjkim        }
300291333Sjkim
301291333Sjkim        /* Compute the number of resource descriptors */
302291333Sjkim
303291333Sjkim        GroupLength =
304291333Sjkim            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
305291333Sjkim                Subtable->Buffer))->Length -
306291333Sjkim            (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
307291333Sjkim                Subtable->Buffer))->SharedInfoLength -
308291333Sjkim            sizeof (ACPI_CSRT_GROUP);
309291333Sjkim
310291333Sjkim        DescriptorCount = (GroupLength  /
311291333Sjkim            sizeof (ACPI_CSRT_DESCRIPTOR));
312291333Sjkim
313291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
314291333Sjkim        DtPushSubtable (Subtable);
315291333Sjkim        ParentTable = DtPeekSubtable ();
316291333Sjkim
317291333Sjkim        /* Shared info subtable (One per resource group) */
318291333Sjkim
319291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
320291333Sjkim            &Subtable, TRUE);
321291333Sjkim        if (ACPI_FAILURE (Status))
322291333Sjkim        {
323291333Sjkim            return (Status);
324291333Sjkim        }
325291333Sjkim
326291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
327291333Sjkim
328291333Sjkim        /* Sub-Subtables (Resource Descriptors) */
329291333Sjkim
330291333Sjkim        while (*PFieldList && DescriptorCount)
331291333Sjkim        {
332291333Sjkim
333291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
334291333Sjkim                &Subtable, TRUE);
335291333Sjkim            if (ACPI_FAILURE (Status))
336291333Sjkim            {
337291333Sjkim                return (Status);
338291333Sjkim            }
339291333Sjkim
340291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
341291333Sjkim
342291333Sjkim            DtPushSubtable (Subtable);
343291333Sjkim            ParentTable = DtPeekSubtable ();
344291333Sjkim            if (*PFieldList)
345291333Sjkim            {
346291333Sjkim                Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
347291333Sjkim                    &Subtable, TRUE);
348291333Sjkim                if (ACPI_FAILURE (Status))
349291333Sjkim                {
350291333Sjkim                    return (Status);
351291333Sjkim                }
352291333Sjkim                if (Subtable)
353291333Sjkim                {
354291333Sjkim                    DtInsertSubtable (ParentTable, Subtable);
355291333Sjkim                }
356291333Sjkim            }
357291333Sjkim
358291333Sjkim            DtPopSubtable ();
359291333Sjkim            ParentTable = DtPeekSubtable ();
360291333Sjkim            DescriptorCount--;
361291333Sjkim        }
362291333Sjkim
363291333Sjkim        DtPopSubtable ();
364291333Sjkim        ParentTable = DtPeekSubtable ();
365291333Sjkim    }
366291333Sjkim
367291333Sjkim    return (Status);
368291333Sjkim}
369291333Sjkim
370291333Sjkim
371291333Sjkim/******************************************************************************
372291333Sjkim *
373291333Sjkim * FUNCTION:    DtCompileDbg2
374291333Sjkim *
375291333Sjkim * PARAMETERS:  List                - Current field list pointer
376291333Sjkim *
377291333Sjkim * RETURN:      Status
378291333Sjkim *
379291333Sjkim * DESCRIPTION: Compile DBG2.
380291333Sjkim *
381291333Sjkim *****************************************************************************/
382291333Sjkim
383291333SjkimACPI_STATUS
384291333SjkimDtCompileDbg2 (
385291333Sjkim    void                    **List)
386291333Sjkim{
387291333Sjkim    ACPI_STATUS             Status;
388291333Sjkim    DT_SUBTABLE             *Subtable;
389291333Sjkim    DT_SUBTABLE             *ParentTable;
390291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
391291333Sjkim    UINT32                  SubtableCount;
392291333Sjkim    ACPI_DBG2_HEADER        *Dbg2Header;
393291333Sjkim    ACPI_DBG2_DEVICE        *DeviceInfo;
394291333Sjkim    UINT16                  CurrentOffset;
395291333Sjkim    UINT32                  i;
396291333Sjkim
397291333Sjkim
398291333Sjkim    /* Main table */
399291333Sjkim
400291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
401291333Sjkim    if (ACPI_FAILURE (Status))
402291333Sjkim    {
403291333Sjkim        return (Status);
404291333Sjkim    }
405291333Sjkim
406291333Sjkim    ParentTable = DtPeekSubtable ();
407291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
408291333Sjkim
409291333Sjkim    /* Main table fields */
410291333Sjkim
411291333Sjkim    Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
412291333Sjkim    Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
413291333Sjkim        ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
414291333Sjkim
415291333Sjkim    SubtableCount = Dbg2Header->InfoCount;
416291333Sjkim    DtPushSubtable (Subtable);
417291333Sjkim
418291333Sjkim    /* Process all Device Information subtables (Count = InfoCount) */
419291333Sjkim
420291333Sjkim    while (*PFieldList && SubtableCount)
421291333Sjkim    {
422291333Sjkim        /* Subtable: Debug Device Information */
423291333Sjkim
424291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
425291333Sjkim            &Subtable, TRUE);
426291333Sjkim        if (ACPI_FAILURE (Status))
427291333Sjkim        {
428291333Sjkim            return (Status);
429291333Sjkim        }
430291333Sjkim
431291333Sjkim        DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
432291333Sjkim        CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
433291333Sjkim
434291333Sjkim        ParentTable = DtPeekSubtable ();
435291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
436291333Sjkim        DtPushSubtable (Subtable);
437291333Sjkim
438291333Sjkim        ParentTable = DtPeekSubtable ();
439291333Sjkim
440291333Sjkim        /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
441291333Sjkim
442291333Sjkim        DeviceInfo->BaseAddressOffset = CurrentOffset;
443291333Sjkim        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
444291333Sjkim        {
445291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
446291333Sjkim                &Subtable, TRUE);
447291333Sjkim            if (ACPI_FAILURE (Status))
448291333Sjkim            {
449291333Sjkim                return (Status);
450291333Sjkim            }
451291333Sjkim
452291333Sjkim            CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
453291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
454291333Sjkim        }
455291333Sjkim
456291333Sjkim        /* AddressSize array (Required, size = RegisterCount) */
457291333Sjkim
458291333Sjkim        DeviceInfo->AddressSizeOffset = CurrentOffset;
459291333Sjkim        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
460291333Sjkim        {
461291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
462291333Sjkim                &Subtable, TRUE);
463291333Sjkim            if (ACPI_FAILURE (Status))
464291333Sjkim            {
465291333Sjkim                return (Status);
466291333Sjkim            }
467291333Sjkim
468291333Sjkim            CurrentOffset += (UINT16) sizeof (UINT32);
469291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
470291333Sjkim        }
471291333Sjkim
472291333Sjkim        /* NamespaceString device identifier (Required, size = NamePathLength) */
473291333Sjkim
474291333Sjkim        DeviceInfo->NamepathOffset = CurrentOffset;
475291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
476291333Sjkim            &Subtable, TRUE);
477291333Sjkim        if (ACPI_FAILURE (Status))
478291333Sjkim        {
479291333Sjkim            return (Status);
480291333Sjkim        }
481291333Sjkim
482291333Sjkim        /* Update the device info header */
483291333Sjkim
484291333Sjkim        DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
485291333Sjkim        CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
486291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
487291333Sjkim
488291333Sjkim        /* OemData - Variable-length data (Optional, size = OemDataLength) */
489291333Sjkim
490291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
491291333Sjkim            &Subtable, TRUE);
492291333Sjkim        if (ACPI_FAILURE (Status))
493291333Sjkim        {
494291333Sjkim            return (Status);
495291333Sjkim        }
496291333Sjkim
497291333Sjkim        /* Update the device info header (zeros if no OEM data present) */
498291333Sjkim
499291333Sjkim        DeviceInfo->OemDataOffset = 0;
500291333Sjkim        DeviceInfo->OemDataLength = 0;
501291333Sjkim
502291333Sjkim        /* Optional subtable (OemData) */
503291333Sjkim
504291333Sjkim        if (Subtable && Subtable->Length)
505291333Sjkim        {
506291333Sjkim            DeviceInfo->OemDataOffset = CurrentOffset;
507291333Sjkim            DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
508291333Sjkim
509291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
510291333Sjkim        }
511291333Sjkim
512291333Sjkim        SubtableCount--;
513291333Sjkim        DtPopSubtable (); /* Get next Device Information subtable */
514291333Sjkim    }
515291333Sjkim
516291333Sjkim    DtPopSubtable ();
517291333Sjkim    return (AE_OK);
518291333Sjkim}
519291333Sjkim
520291333Sjkim
521291333Sjkim/******************************************************************************
522291333Sjkim *
523291333Sjkim * FUNCTION:    DtCompileDmar
524291333Sjkim *
525291333Sjkim * PARAMETERS:  List                - Current field list pointer
526291333Sjkim *
527291333Sjkim * RETURN:      Status
528291333Sjkim *
529291333Sjkim * DESCRIPTION: Compile DMAR.
530291333Sjkim *
531291333Sjkim *****************************************************************************/
532291333Sjkim
533291333SjkimACPI_STATUS
534291333SjkimDtCompileDmar (
535291333Sjkim    void                    **List)
536291333Sjkim{
537291333Sjkim    ACPI_STATUS             Status;
538291333Sjkim    DT_SUBTABLE             *Subtable;
539291333Sjkim    DT_SUBTABLE             *ParentTable;
540291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
541291333Sjkim    DT_FIELD                *SubtableStart;
542291333Sjkim    ACPI_DMTABLE_INFO       *InfoTable;
543291333Sjkim    ACPI_DMAR_HEADER        *DmarHeader;
544291333Sjkim    ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
545291333Sjkim    UINT32                  DeviceScopeLength;
546291333Sjkim    UINT32                  PciPathLength;
547291333Sjkim
548291333Sjkim
549291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
550291333Sjkim    if (ACPI_FAILURE (Status))
551291333Sjkim    {
552291333Sjkim        return (Status);
553291333Sjkim    }
554291333Sjkim
555291333Sjkim    ParentTable = DtPeekSubtable ();
556291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
557291333Sjkim    DtPushSubtable (Subtable);
558291333Sjkim
559291333Sjkim    while (*PFieldList)
560291333Sjkim    {
561291333Sjkim        /* DMAR Header */
562291333Sjkim
563291333Sjkim        SubtableStart = *PFieldList;
564291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
565291333Sjkim            &Subtable, TRUE);
566291333Sjkim        if (ACPI_FAILURE (Status))
567291333Sjkim        {
568291333Sjkim            return (Status);
569291333Sjkim        }
570291333Sjkim
571291333Sjkim        ParentTable = DtPeekSubtable ();
572291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
573291333Sjkim        DtPushSubtable (Subtable);
574291333Sjkim
575291333Sjkim        DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
576291333Sjkim
577291333Sjkim        switch (DmarHeader->Type)
578291333Sjkim        {
579291333Sjkim        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
580291333Sjkim
581291333Sjkim            InfoTable = AcpiDmTableInfoDmar0;
582291333Sjkim            break;
583291333Sjkim
584291333Sjkim        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
585291333Sjkim
586291333Sjkim            InfoTable = AcpiDmTableInfoDmar1;
587291333Sjkim            break;
588291333Sjkim
589291333Sjkim        case ACPI_DMAR_TYPE_ROOT_ATS:
590291333Sjkim
591291333Sjkim            InfoTable = AcpiDmTableInfoDmar2;
592291333Sjkim            break;
593291333Sjkim
594291333Sjkim        case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
595291333Sjkim
596291333Sjkim            InfoTable = AcpiDmTableInfoDmar3;
597291333Sjkim            break;
598291333Sjkim
599291333Sjkim        case ACPI_DMAR_TYPE_NAMESPACE:
600291333Sjkim
601291333Sjkim            InfoTable = AcpiDmTableInfoDmar4;
602291333Sjkim            break;
603291333Sjkim
604291333Sjkim        default:
605291333Sjkim
606291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
607291333Sjkim            return (AE_ERROR);
608291333Sjkim        }
609291333Sjkim
610291333Sjkim        /* DMAR Subtable */
611291333Sjkim
612291333Sjkim        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
613291333Sjkim        if (ACPI_FAILURE (Status))
614291333Sjkim        {
615291333Sjkim            return (Status);
616291333Sjkim        }
617291333Sjkim
618291333Sjkim        ParentTable = DtPeekSubtable ();
619291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
620291333Sjkim
621291333Sjkim        /*
622291333Sjkim         * Optional Device Scope subtables
623291333Sjkim         */
624291333Sjkim        if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
625291333Sjkim            (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
626291333Sjkim        {
627291333Sjkim            /* These types do not support device scopes */
628291333Sjkim
629291333Sjkim            DtPopSubtable ();
630291333Sjkim            continue;
631291333Sjkim        }
632291333Sjkim
633291333Sjkim        DtPushSubtable (Subtable);
634291333Sjkim        DeviceScopeLength = DmarHeader->Length - Subtable->Length -
635291333Sjkim            ParentTable->Length;
636291333Sjkim        while (DeviceScopeLength)
637291333Sjkim        {
638291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
639291333Sjkim                &Subtable, FALSE);
640291333Sjkim            if (Status == AE_NOT_FOUND)
641291333Sjkim            {
642291333Sjkim                break;
643291333Sjkim            }
644291333Sjkim
645291333Sjkim            ParentTable = DtPeekSubtable ();
646291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
647291333Sjkim            DtPushSubtable (Subtable);
648291333Sjkim
649291333Sjkim            DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
650291333Sjkim
651291333Sjkim            /* Optional PCI Paths */
652291333Sjkim
653291333Sjkim            PciPathLength = DmarDeviceScope->Length - Subtable->Length;
654291333Sjkim            while (PciPathLength)
655291333Sjkim            {
656291333Sjkim                Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
657291333Sjkim                    &Subtable, FALSE);
658291333Sjkim                if (Status == AE_NOT_FOUND)
659291333Sjkim                {
660291333Sjkim                    DtPopSubtable ();
661291333Sjkim                    break;
662291333Sjkim                }
663291333Sjkim
664291333Sjkim                ParentTable = DtPeekSubtable ();
665291333Sjkim                DtInsertSubtable (ParentTable, Subtable);
666291333Sjkim                PciPathLength -= Subtable->Length;
667291333Sjkim            }
668291333Sjkim
669291333Sjkim            DtPopSubtable ();
670291333Sjkim            DeviceScopeLength -= DmarDeviceScope->Length;
671291333Sjkim        }
672291333Sjkim
673291333Sjkim        DtPopSubtable ();
674291333Sjkim        DtPopSubtable ();
675291333Sjkim    }
676291333Sjkim
677291333Sjkim    return (AE_OK);
678291333Sjkim}
679291333Sjkim
680291333Sjkim
681291333Sjkim/******************************************************************************
682291333Sjkim *
683291333Sjkim * FUNCTION:    DtCompileDrtm
684291333Sjkim *
685291333Sjkim * PARAMETERS:  List                - Current field list pointer
686291333Sjkim *
687291333Sjkim * RETURN:      Status
688291333Sjkim *
689291333Sjkim * DESCRIPTION: Compile DRTM.
690291333Sjkim *
691291333Sjkim *****************************************************************************/
692291333Sjkim
693291333SjkimACPI_STATUS
694291333SjkimDtCompileDrtm (
695291333Sjkim    void                    **List)
696291333Sjkim{
697291333Sjkim    ACPI_STATUS             Status;
698291333Sjkim    DT_SUBTABLE             *Subtable;
699291333Sjkim    DT_SUBTABLE             *ParentTable;
700291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
701291333Sjkim    UINT32                  Count;
702291333Sjkim    /* ACPI_TABLE_DRTM         *Drtm; */
703291333Sjkim    ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
704291333Sjkim    ACPI_DRTM_RESOURCE_LIST *DrtmRl;
705291333Sjkim    /* ACPI_DRTM_DPS_ID        *DrtmDps; */
706291333Sjkim
707291333Sjkim
708291333Sjkim    ParentTable = DtPeekSubtable ();
709291333Sjkim
710291333Sjkim    /* Compile DRTM header */
711291333Sjkim
712291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
713291333Sjkim        &Subtable, TRUE);
714291333Sjkim    if (ACPI_FAILURE (Status))
715291333Sjkim    {
716291333Sjkim        return (Status);
717291333Sjkim    }
718291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
719291333Sjkim
720291333Sjkim    /*
721291333Sjkim     * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
722291333Sjkim     * should be taken to avoid accessing ACPI_TABLE_HADER fields.
723291333Sjkim     */
724291333Sjkim#if 0
725291333Sjkim    Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
726291333Sjkim        Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
727291333Sjkim#endif
728291333Sjkim    /* Compile VTL */
729291333Sjkim
730291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
731291333Sjkim        &Subtable, TRUE);
732291333Sjkim    if (ACPI_FAILURE (Status))
733291333Sjkim    {
734291333Sjkim        return (Status);
735291333Sjkim    }
736291333Sjkim
737291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
738291333Sjkim    DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
739291333Sjkim
740291333Sjkim    DtPushSubtable (Subtable);
741291333Sjkim    ParentTable = DtPeekSubtable ();
742291333Sjkim    Count = 0;
743291333Sjkim
744291333Sjkim    while (*PFieldList)
745291333Sjkim    {
746291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
747291333Sjkim            &Subtable, TRUE);
748291333Sjkim        if (ACPI_FAILURE (Status))
749291333Sjkim        {
750291333Sjkim            return (Status);
751291333Sjkim        }
752291333Sjkim        if (!Subtable)
753291333Sjkim        {
754291333Sjkim            break;
755291333Sjkim        }
756291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
757291333Sjkim        Count++;
758291333Sjkim    }
759291333Sjkim
760291333Sjkim    DrtmVtl->ValidatedTableCount = Count;
761291333Sjkim    DtPopSubtable ();
762291333Sjkim    ParentTable = DtPeekSubtable ();
763291333Sjkim
764291333Sjkim    /* Compile RL */
765291333Sjkim
766291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
767291333Sjkim        &Subtable, TRUE);
768291333Sjkim    if (ACPI_FAILURE (Status))
769291333Sjkim    {
770291333Sjkim        return (Status);
771291333Sjkim    }
772291333Sjkim
773291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
774291333Sjkim    DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
775291333Sjkim
776291333Sjkim    DtPushSubtable (Subtable);
777291333Sjkim    ParentTable = DtPeekSubtable ();
778291333Sjkim    Count = 0;
779291333Sjkim
780291333Sjkim    while (*PFieldList)
781291333Sjkim    {
782291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
783291333Sjkim            &Subtable, TRUE);
784291333Sjkim        if (ACPI_FAILURE (Status))
785291333Sjkim        {
786291333Sjkim            return (Status);
787291333Sjkim        }
788291333Sjkim
789291333Sjkim        if (!Subtable)
790291333Sjkim        {
791291333Sjkim            break;
792291333Sjkim        }
793291333Sjkim
794291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
795291333Sjkim        Count++;
796291333Sjkim    }
797291333Sjkim
798291333Sjkim    DrtmRl->ResourceCount = Count;
799291333Sjkim    DtPopSubtable ();
800291333Sjkim    ParentTable = DtPeekSubtable ();
801291333Sjkim
802291333Sjkim    /* Compile DPS */
803291333Sjkim
804291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
805291333Sjkim        &Subtable, TRUE);
806291333Sjkim    if (ACPI_FAILURE (Status))
807291333Sjkim    {
808291333Sjkim        return (Status);
809291333Sjkim    }
810291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
811291333Sjkim    /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
812291333Sjkim
813291333Sjkim
814291333Sjkim    return (AE_OK);
815291333Sjkim}
816291333Sjkim
817291333Sjkim
818291333Sjkim/******************************************************************************
819291333Sjkim *
820291333Sjkim * FUNCTION:    DtCompileEinj
821291333Sjkim *
822291333Sjkim * PARAMETERS:  List                - Current field list pointer
823291333Sjkim *
824291333Sjkim * RETURN:      Status
825291333Sjkim *
826291333Sjkim * DESCRIPTION: Compile EINJ.
827291333Sjkim *
828291333Sjkim *****************************************************************************/
829291333Sjkim
830291333SjkimACPI_STATUS
831291333SjkimDtCompileEinj (
832291333Sjkim    void                    **List)
833291333Sjkim{
834291333Sjkim    ACPI_STATUS             Status;
835291333Sjkim
836291333Sjkim
837291333Sjkim    Status = DtCompileTwoSubtables (List,
838291333Sjkim        AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
839291333Sjkim    return (Status);
840291333Sjkim}
841291333Sjkim
842291333Sjkim
843291333Sjkim/******************************************************************************
844291333Sjkim *
845291333Sjkim * FUNCTION:    DtCompileErst
846291333Sjkim *
847291333Sjkim * PARAMETERS:  List                - Current field list pointer
848291333Sjkim *
849291333Sjkim * RETURN:      Status
850291333Sjkim *
851291333Sjkim * DESCRIPTION: Compile ERST.
852291333Sjkim *
853291333Sjkim *****************************************************************************/
854291333Sjkim
855291333SjkimACPI_STATUS
856291333SjkimDtCompileErst (
857291333Sjkim    void                    **List)
858291333Sjkim{
859291333Sjkim    ACPI_STATUS             Status;
860291333Sjkim
861291333Sjkim
862291333Sjkim    Status = DtCompileTwoSubtables (List,
863291333Sjkim        AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
864291333Sjkim    return (Status);
865291333Sjkim}
866291333Sjkim
867291333Sjkim
868291333Sjkim/******************************************************************************
869291333Sjkim *
870291333Sjkim * FUNCTION:    DtCompileGtdt
871291333Sjkim *
872291333Sjkim * PARAMETERS:  List                - Current field list pointer
873291333Sjkim *
874291333Sjkim * RETURN:      Status
875291333Sjkim *
876291333Sjkim * DESCRIPTION: Compile GTDT.
877291333Sjkim *
878291333Sjkim *****************************************************************************/
879291333Sjkim
880291333SjkimACPI_STATUS
881291333SjkimDtCompileGtdt (
882291333Sjkim    void                    **List)
883291333Sjkim{
884291333Sjkim    ACPI_STATUS             Status;
885291333Sjkim    DT_SUBTABLE             *Subtable;
886291333Sjkim    DT_SUBTABLE             *ParentTable;
887291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
888291333Sjkim    DT_FIELD                *SubtableStart;
889291333Sjkim    ACPI_SUBTABLE_HEADER    *GtdtHeader;
890291333Sjkim    ACPI_DMTABLE_INFO       *InfoTable;
891291333Sjkim    UINT32                  GtCount;
892291333Sjkim
893291333Sjkim
894291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
895291333Sjkim        &Subtable, TRUE);
896291333Sjkim    if (ACPI_FAILURE (Status))
897291333Sjkim    {
898291333Sjkim        return (Status);
899291333Sjkim    }
900291333Sjkim
901291333Sjkim    ParentTable = DtPeekSubtable ();
902291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
903291333Sjkim
904291333Sjkim    while (*PFieldList)
905291333Sjkim    {
906291333Sjkim        SubtableStart = *PFieldList;
907291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
908291333Sjkim            &Subtable, TRUE);
909291333Sjkim        if (ACPI_FAILURE (Status))
910291333Sjkim        {
911291333Sjkim            return (Status);
912291333Sjkim        }
913291333Sjkim
914291333Sjkim        ParentTable = DtPeekSubtable ();
915291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
916291333Sjkim        DtPushSubtable (Subtable);
917291333Sjkim
918291333Sjkim        GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
919291333Sjkim
920291333Sjkim        switch (GtdtHeader->Type)
921291333Sjkim        {
922291333Sjkim        case ACPI_GTDT_TYPE_TIMER_BLOCK:
923291333Sjkim
924291333Sjkim            InfoTable = AcpiDmTableInfoGtdt0;
925291333Sjkim            break;
926291333Sjkim
927291333Sjkim        case ACPI_GTDT_TYPE_WATCHDOG:
928291333Sjkim
929291333Sjkim            InfoTable = AcpiDmTableInfoGtdt1;
930291333Sjkim            break;
931291333Sjkim
932291333Sjkim        default:
933291333Sjkim
934291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
935291333Sjkim            return (AE_ERROR);
936291333Sjkim        }
937291333Sjkim
938291333Sjkim        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
939291333Sjkim        if (ACPI_FAILURE (Status))
940291333Sjkim        {
941291333Sjkim            return (Status);
942291333Sjkim        }
943291333Sjkim
944291333Sjkim        ParentTable = DtPeekSubtable ();
945291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
946291333Sjkim
947291333Sjkim        /*
948291333Sjkim         * Additional GT block subtable data
949291333Sjkim         */
950291333Sjkim
951291333Sjkim        switch (GtdtHeader->Type)
952291333Sjkim        {
953291333Sjkim        case ACPI_GTDT_TYPE_TIMER_BLOCK:
954291333Sjkim
955291333Sjkim            DtPushSubtable (Subtable);
956291333Sjkim            ParentTable = DtPeekSubtable ();
957291333Sjkim
958291333Sjkim            GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
959291333Sjkim                Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
960291333Sjkim
961291333Sjkim            while (GtCount)
962291333Sjkim            {
963291333Sjkim                Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
964291333Sjkim                    &Subtable, TRUE);
965291333Sjkim                if (ACPI_FAILURE (Status))
966291333Sjkim                {
967291333Sjkim                    return (Status);
968291333Sjkim                }
969291333Sjkim
970291333Sjkim                DtInsertSubtable (ParentTable, Subtable);
971291333Sjkim                GtCount--;
972291333Sjkim            }
973291333Sjkim
974291333Sjkim            DtPopSubtable ();
975291333Sjkim            break;
976291333Sjkim
977291333Sjkim        default:
978291333Sjkim
979291333Sjkim            break;
980291333Sjkim        }
981291333Sjkim
982291333Sjkim        DtPopSubtable ();
983291333Sjkim    }
984291333Sjkim
985291333Sjkim    return (AE_OK);
986291333Sjkim}
987291333Sjkim
988291333Sjkim
989291333Sjkim/******************************************************************************
990291333Sjkim *
991291333Sjkim * FUNCTION:    DtCompileFpdt
992291333Sjkim *
993291333Sjkim * PARAMETERS:  List                - Current field list pointer
994291333Sjkim *
995291333Sjkim * RETURN:      Status
996291333Sjkim *
997291333Sjkim * DESCRIPTION: Compile FPDT.
998291333Sjkim *
999291333Sjkim *****************************************************************************/
1000291333Sjkim
1001291333SjkimACPI_STATUS
1002291333SjkimDtCompileFpdt (
1003291333Sjkim    void                    **List)
1004291333Sjkim{
1005291333Sjkim    ACPI_STATUS             Status;
1006291333Sjkim    ACPI_FPDT_HEADER        *FpdtHeader;
1007291333Sjkim    DT_SUBTABLE             *Subtable;
1008291333Sjkim    DT_SUBTABLE             *ParentTable;
1009291333Sjkim    ACPI_DMTABLE_INFO       *InfoTable;
1010291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1011291333Sjkim    DT_FIELD                *SubtableStart;
1012291333Sjkim
1013291333Sjkim
1014291333Sjkim    while (*PFieldList)
1015291333Sjkim    {
1016291333Sjkim        SubtableStart = *PFieldList;
1017291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1018291333Sjkim            &Subtable, TRUE);
1019291333Sjkim        if (ACPI_FAILURE (Status))
1020291333Sjkim        {
1021291333Sjkim            return (Status);
1022291333Sjkim        }
1023291333Sjkim
1024291333Sjkim        ParentTable = DtPeekSubtable ();
1025291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
1026291333Sjkim        DtPushSubtable (Subtable);
1027291333Sjkim
1028291333Sjkim        FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1029291333Sjkim
1030291333Sjkim        switch (FpdtHeader->Type)
1031291333Sjkim        {
1032291333Sjkim        case ACPI_FPDT_TYPE_BOOT:
1033291333Sjkim
1034291333Sjkim            InfoTable = AcpiDmTableInfoFpdt0;
1035291333Sjkim            break;
1036291333Sjkim
1037291333Sjkim        case ACPI_FPDT_TYPE_S3PERF:
1038291333Sjkim
1039291333Sjkim            InfoTable = AcpiDmTableInfoFpdt1;
1040291333Sjkim            break;
1041291333Sjkim
1042291333Sjkim        default:
1043291333Sjkim
1044291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1045291333Sjkim            return (AE_ERROR);
1046291333Sjkim            break;
1047291333Sjkim        }
1048291333Sjkim
1049291333Sjkim        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1050291333Sjkim        if (ACPI_FAILURE (Status))
1051291333Sjkim        {
1052291333Sjkim            return (Status);
1053291333Sjkim        }
1054291333Sjkim
1055291333Sjkim        ParentTable = DtPeekSubtable ();
1056291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
1057291333Sjkim        DtPopSubtable ();
1058291333Sjkim    }
1059291333Sjkim
1060291333Sjkim    return (AE_OK);
1061291333Sjkim}
1062291333Sjkim
1063291333Sjkim
1064291333Sjkim/******************************************************************************
1065291333Sjkim *
1066291333Sjkim * FUNCTION:    DtCompileHest
1067291333Sjkim *
1068291333Sjkim * PARAMETERS:  List                - Current field list pointer
1069291333Sjkim *
1070291333Sjkim * RETURN:      Status
1071291333Sjkim *
1072291333Sjkim * DESCRIPTION: Compile HEST.
1073291333Sjkim *
1074291333Sjkim *****************************************************************************/
1075291333Sjkim
1076291333SjkimACPI_STATUS
1077291333SjkimDtCompileHest (
1078291333Sjkim    void                    **List)
1079291333Sjkim{
1080291333Sjkim    ACPI_STATUS             Status;
1081291333Sjkim    DT_SUBTABLE             *Subtable;
1082291333Sjkim    DT_SUBTABLE             *ParentTable;
1083291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1084291333Sjkim    DT_FIELD                *SubtableStart;
1085291333Sjkim    ACPI_DMTABLE_INFO       *InfoTable;
1086291333Sjkim    UINT16                  Type;
1087291333Sjkim    UINT32                  BankCount;
1088291333Sjkim
1089291333Sjkim
1090291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1091291333Sjkim        &Subtable, TRUE);
1092291333Sjkim    if (ACPI_FAILURE (Status))
1093291333Sjkim    {
1094291333Sjkim        return (Status);
1095291333Sjkim    }
1096291333Sjkim
1097291333Sjkim    ParentTable = DtPeekSubtable ();
1098291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
1099291333Sjkim
1100291333Sjkim    while (*PFieldList)
1101291333Sjkim    {
1102291333Sjkim        /* Get subtable type */
1103291333Sjkim
1104291333Sjkim        SubtableStart = *PFieldList;
1105291333Sjkim        DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1106291333Sjkim
1107291333Sjkim        switch (Type)
1108291333Sjkim        {
1109291333Sjkim        case ACPI_HEST_TYPE_IA32_CHECK:
1110291333Sjkim
1111291333Sjkim            InfoTable = AcpiDmTableInfoHest0;
1112291333Sjkim            break;
1113291333Sjkim
1114291333Sjkim        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1115291333Sjkim
1116291333Sjkim            InfoTable = AcpiDmTableInfoHest1;
1117291333Sjkim            break;
1118291333Sjkim
1119291333Sjkim        case ACPI_HEST_TYPE_IA32_NMI:
1120291333Sjkim
1121291333Sjkim            InfoTable = AcpiDmTableInfoHest2;
1122291333Sjkim            break;
1123291333Sjkim
1124291333Sjkim        case ACPI_HEST_TYPE_AER_ROOT_PORT:
1125291333Sjkim
1126291333Sjkim            InfoTable = AcpiDmTableInfoHest6;
1127291333Sjkim            break;
1128291333Sjkim
1129291333Sjkim        case ACPI_HEST_TYPE_AER_ENDPOINT:
1130291333Sjkim
1131291333Sjkim            InfoTable = AcpiDmTableInfoHest7;
1132291333Sjkim            break;
1133291333Sjkim
1134291333Sjkim        case ACPI_HEST_TYPE_AER_BRIDGE:
1135291333Sjkim
1136291333Sjkim            InfoTable = AcpiDmTableInfoHest8;
1137291333Sjkim            break;
1138291333Sjkim
1139291333Sjkim        case ACPI_HEST_TYPE_GENERIC_ERROR:
1140291333Sjkim
1141291333Sjkim            InfoTable = AcpiDmTableInfoHest9;
1142291333Sjkim            break;
1143291333Sjkim
1144291333Sjkim        default:
1145291333Sjkim
1146291333Sjkim            /* Cannot continue on unknown type */
1147291333Sjkim
1148291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1149291333Sjkim            return (AE_ERROR);
1150291333Sjkim        }
1151291333Sjkim
1152291333Sjkim        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1153291333Sjkim        if (ACPI_FAILURE (Status))
1154291333Sjkim        {
1155291333Sjkim            return (Status);
1156291333Sjkim        }
1157291333Sjkim
1158291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
1159291333Sjkim
1160291333Sjkim        /*
1161291333Sjkim         * Additional subtable data - IA32 Error Bank(s)
1162291333Sjkim         */
1163291333Sjkim        BankCount = 0;
1164291333Sjkim        switch (Type)
1165291333Sjkim        {
1166291333Sjkim        case ACPI_HEST_TYPE_IA32_CHECK:
1167291333Sjkim
1168291333Sjkim            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1169291333Sjkim                Subtable->Buffer))->NumHardwareBanks;
1170291333Sjkim            break;
1171291333Sjkim
1172291333Sjkim        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1173291333Sjkim
1174291333Sjkim            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1175291333Sjkim                Subtable->Buffer))->NumHardwareBanks;
1176291333Sjkim            break;
1177291333Sjkim
1178291333Sjkim        default:
1179291333Sjkim
1180291333Sjkim            break;
1181291333Sjkim        }
1182291333Sjkim
1183291333Sjkim        while (BankCount)
1184291333Sjkim        {
1185291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1186291333Sjkim                &Subtable, TRUE);
1187291333Sjkim            if (ACPI_FAILURE (Status))
1188291333Sjkim            {
1189291333Sjkim                return (Status);
1190291333Sjkim            }
1191291333Sjkim
1192291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
1193291333Sjkim            BankCount--;
1194291333Sjkim        }
1195291333Sjkim    }
1196291333Sjkim
1197291333Sjkim    return (AE_OK);
1198291333Sjkim}
1199291333Sjkim
1200291333Sjkim
1201291333Sjkim/******************************************************************************
1202291333Sjkim *
1203291333Sjkim * FUNCTION:    DtCompileIort
1204291333Sjkim *
1205291333Sjkim * PARAMETERS:  List                - Current field list pointer
1206291333Sjkim *
1207291333Sjkim * RETURN:      Status
1208291333Sjkim *
1209291333Sjkim * DESCRIPTION: Compile IORT.
1210291333Sjkim *
1211291333Sjkim *****************************************************************************/
1212291333Sjkim
1213291333SjkimACPI_STATUS
1214291333SjkimDtCompileIort (
1215291333Sjkim    void                    **List)
1216291333Sjkim{
1217291333Sjkim    ACPI_STATUS             Status;
1218291333Sjkim    DT_SUBTABLE             *Subtable;
1219291333Sjkim    DT_SUBTABLE             *ParentTable;
1220291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1221291333Sjkim    DT_FIELD                *SubtableStart;
1222291333Sjkim    ACPI_TABLE_IORT         *Iort;
1223291333Sjkim    ACPI_IORT_NODE          *IortNode;
1224291333Sjkim    ACPI_IORT_ITS_GROUP     *IortItsGroup;
1225291333Sjkim    ACPI_IORT_SMMU          *IortSmmu;
1226291333Sjkim    UINT32                  NodeNumber;
1227291333Sjkim    UINT32                  NodeLength;
1228291333Sjkim    UINT32                  IdMappingNumber;
1229291333Sjkim    UINT32                  ItsNumber;
1230291333Sjkim    UINT32                  ContextIrptNumber;
1231291333Sjkim    UINT32                  PmuIrptNumber;
1232291333Sjkim    UINT32                  PaddingLength;
1233291333Sjkim
1234291333Sjkim
1235291333Sjkim    ParentTable = DtPeekSubtable ();
1236291333Sjkim
1237291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1238291333Sjkim        &Subtable, TRUE);
1239291333Sjkim    if (ACPI_FAILURE (Status))
1240291333Sjkim    {
1241291333Sjkim        return (Status);
1242291333Sjkim    }
1243291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
1244291333Sjkim
1245291333Sjkim    /*
1246298714Sjkim     * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1247298714Sjkim     * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
1248291333Sjkim     */
1249291333Sjkim    Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1250291333Sjkim        Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1251291333Sjkim
1252291333Sjkim    /*
1253291333Sjkim     * OptionalPadding - Variable-length data
1254291333Sjkim     * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1255291333Sjkim     * Optionally allows the generic data types to be used for filling
1256291333Sjkim     * this field.
1257291333Sjkim     */
1258291333Sjkim    Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1259291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1260291333Sjkim        &Subtable, TRUE);
1261291333Sjkim    if (ACPI_FAILURE (Status))
1262291333Sjkim    {
1263291333Sjkim        return (Status);
1264291333Sjkim    }
1265291333Sjkim    if (Subtable)
1266291333Sjkim    {
1267291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
1268291333Sjkim        Iort->NodeOffset += Subtable->Length;
1269291333Sjkim    }
1270291333Sjkim    else
1271291333Sjkim    {
1272291333Sjkim        Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1273291333Sjkim            AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1274291333Sjkim        if (ACPI_FAILURE (Status))
1275291333Sjkim        {
1276291333Sjkim            return (Status);
1277291333Sjkim        }
1278291333Sjkim        Iort->NodeOffset += PaddingLength;
1279291333Sjkim    }
1280291333Sjkim
1281291333Sjkim    NodeNumber = 0;
1282291333Sjkim    while (*PFieldList)
1283291333Sjkim    {
1284291333Sjkim        SubtableStart = *PFieldList;
1285291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1286291333Sjkim            &Subtable, TRUE);
1287291333Sjkim        if (ACPI_FAILURE (Status))
1288291333Sjkim        {
1289291333Sjkim            return (Status);
1290291333Sjkim        }
1291291333Sjkim
1292291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
1293291333Sjkim        IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1294291333Sjkim        NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1295291333Sjkim
1296291333Sjkim        DtPushSubtable (Subtable);
1297291333Sjkim        ParentTable = DtPeekSubtable ();
1298291333Sjkim
1299291333Sjkim        switch (IortNode->Type)
1300291333Sjkim        {
1301291333Sjkim        case ACPI_IORT_NODE_ITS_GROUP:
1302291333Sjkim
1303291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1304291333Sjkim                &Subtable, TRUE);
1305291333Sjkim            if (ACPI_FAILURE (Status))
1306291333Sjkim            {
1307291333Sjkim                return (Status);
1308291333Sjkim            }
1309291333Sjkim
1310291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
1311291333Sjkim            IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1312291333Sjkim            NodeLength += Subtable->Length;
1313291333Sjkim
1314291333Sjkim            ItsNumber = 0;
1315291333Sjkim            while (*PFieldList)
1316291333Sjkim            {
1317291333Sjkim                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1318291333Sjkim                    &Subtable, TRUE);
1319291333Sjkim                if (ACPI_FAILURE (Status))
1320291333Sjkim                {
1321291333Sjkim                    return (Status);
1322291333Sjkim                }
1323291333Sjkim                if (!Subtable)
1324291333Sjkim                {
1325291333Sjkim                    break;
1326291333Sjkim                }
1327291333Sjkim
1328291333Sjkim                DtInsertSubtable (ParentTable, Subtable);
1329291333Sjkim                NodeLength += Subtable->Length;
1330291333Sjkim                ItsNumber++;
1331291333Sjkim            }
1332291333Sjkim
1333291333Sjkim            IortItsGroup->ItsCount = ItsNumber;
1334291333Sjkim            break;
1335291333Sjkim
1336291333Sjkim        case ACPI_IORT_NODE_NAMED_COMPONENT:
1337291333Sjkim
1338291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1339291333Sjkim                &Subtable, TRUE);
1340291333Sjkim            if (ACPI_FAILURE (Status))
1341291333Sjkim            {
1342291333Sjkim                return (Status);
1343291333Sjkim            }
1344291333Sjkim
1345291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
1346291333Sjkim            NodeLength += Subtable->Length;
1347291333Sjkim
1348291333Sjkim            /*
1349291333Sjkim             * Padding - Variable-length data
1350291333Sjkim             * Optionally allows the offset of the ID mappings to be used
1351291333Sjkim             * for filling this field.
1352291333Sjkim             */
1353291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1354291333Sjkim                &Subtable, TRUE);
1355291333Sjkim            if (ACPI_FAILURE (Status))
1356291333Sjkim            {
1357291333Sjkim                return (Status);
1358291333Sjkim            }
1359291333Sjkim
1360291333Sjkim            if (Subtable)
1361291333Sjkim            {
1362291333Sjkim                DtInsertSubtable (ParentTable, Subtable);
1363291333Sjkim                NodeLength += Subtable->Length;
1364291333Sjkim            }
1365291333Sjkim            else
1366291333Sjkim            {
1367291333Sjkim                if (NodeLength > IortNode->MappingOffset)
1368291333Sjkim                {
1369291333Sjkim                    return (AE_BAD_DATA);
1370291333Sjkim                }
1371291333Sjkim
1372291333Sjkim                if (NodeLength < IortNode->MappingOffset)
1373291333Sjkim                {
1374291333Sjkim                    Status = DtCompilePadding (
1375291333Sjkim                        IortNode->MappingOffset - NodeLength,
1376291333Sjkim                        &Subtable);
1377291333Sjkim                    if (ACPI_FAILURE (Status))
1378291333Sjkim                    {
1379291333Sjkim                        return (Status);
1380291333Sjkim                    }
1381291333Sjkim
1382291333Sjkim                    DtInsertSubtable (ParentTable, Subtable);
1383291333Sjkim                    NodeLength = IortNode->MappingOffset;
1384291333Sjkim                }
1385291333Sjkim            }
1386291333Sjkim            break;
1387291333Sjkim
1388291333Sjkim        case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1389291333Sjkim
1390291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1391291333Sjkim                &Subtable, TRUE);
1392291333Sjkim            if (ACPI_FAILURE (Status))
1393291333Sjkim            {
1394291333Sjkim                return (Status);
1395291333Sjkim            }
1396291333Sjkim
1397291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
1398291333Sjkim            NodeLength += Subtable->Length;
1399291333Sjkim            break;
1400291333Sjkim
1401291333Sjkim        case ACPI_IORT_NODE_SMMU:
1402291333Sjkim
1403291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1404291333Sjkim                &Subtable, TRUE);
1405291333Sjkim            if (ACPI_FAILURE (Status))
1406291333Sjkim            {
1407291333Sjkim                return (Status);
1408291333Sjkim            }
1409291333Sjkim
1410291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
1411291333Sjkim            IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1412291333Sjkim            NodeLength += Subtable->Length;
1413291333Sjkim
1414291333Sjkim            /* Compile global interrupt array */
1415291333Sjkim
1416291333Sjkim            IortSmmu->GlobalInterruptOffset = NodeLength;
1417291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1418291333Sjkim                &Subtable, TRUE);
1419291333Sjkim            if (ACPI_FAILURE (Status))
1420291333Sjkim            {
1421291333Sjkim                return (Status);
1422291333Sjkim            }
1423291333Sjkim
1424291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
1425291333Sjkim            NodeLength += Subtable->Length;
1426291333Sjkim
1427291333Sjkim            /* Compile context interrupt array */
1428291333Sjkim
1429291333Sjkim            ContextIrptNumber = 0;
1430291333Sjkim            IortSmmu->ContextInterruptOffset = NodeLength;
1431291333Sjkim            while (*PFieldList)
1432291333Sjkim            {
1433291333Sjkim                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1434291333Sjkim                    &Subtable, TRUE);
1435291333Sjkim                if (ACPI_FAILURE (Status))
1436291333Sjkim                {
1437291333Sjkim                    return (Status);
1438291333Sjkim                }
1439291333Sjkim
1440291333Sjkim                if (!Subtable)
1441291333Sjkim                {
1442291333Sjkim                    break;
1443291333Sjkim                }
1444291333Sjkim
1445291333Sjkim                DtInsertSubtable (ParentTable, Subtable);
1446291333Sjkim                NodeLength += Subtable->Length;
1447291333Sjkim                ContextIrptNumber++;
1448291333Sjkim            }
1449291333Sjkim
1450291333Sjkim            IortSmmu->ContextInterruptCount = ContextIrptNumber;
1451291333Sjkim
1452291333Sjkim            /* Compile PMU interrupt array */
1453291333Sjkim
1454291333Sjkim            PmuIrptNumber = 0;
1455291333Sjkim            IortSmmu->PmuInterruptOffset = NodeLength;
1456291333Sjkim            while (*PFieldList)
1457291333Sjkim            {
1458291333Sjkim                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1459291333Sjkim                    &Subtable, TRUE);
1460291333Sjkim                if (ACPI_FAILURE (Status))
1461291333Sjkim                {
1462291333Sjkim                    return (Status);
1463291333Sjkim                }
1464291333Sjkim
1465291333Sjkim                if (!Subtable)
1466291333Sjkim                {
1467291333Sjkim                    break;
1468291333Sjkim                }
1469291333Sjkim
1470291333Sjkim                DtInsertSubtable (ParentTable, Subtable);
1471291333Sjkim                NodeLength += Subtable->Length;
1472291333Sjkim                PmuIrptNumber++;
1473291333Sjkim            }
1474291333Sjkim
1475291333Sjkim            IortSmmu->PmuInterruptCount = PmuIrptNumber;
1476291333Sjkim            break;
1477291333Sjkim
1478298714Sjkim        case ACPI_IORT_NODE_SMMU_V3:
1479298714Sjkim
1480298714Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
1481298714Sjkim                &Subtable, TRUE);
1482298714Sjkim            if (ACPI_FAILURE (Status))
1483298714Sjkim            {
1484298714Sjkim                return (Status);
1485298714Sjkim            }
1486298714Sjkim
1487298714Sjkim            DtInsertSubtable (ParentTable, Subtable);
1488298714Sjkim            NodeLength += Subtable->Length;
1489298714Sjkim            break;
1490298714Sjkim
1491291333Sjkim        default:
1492291333Sjkim
1493291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1494291333Sjkim            return (AE_ERROR);
1495291333Sjkim        }
1496291333Sjkim
1497291333Sjkim        /* Compile Array of ID mappings */
1498291333Sjkim
1499291333Sjkim        IortNode->MappingOffset = NodeLength;
1500291333Sjkim        IdMappingNumber = 0;
1501291333Sjkim        while (*PFieldList)
1502291333Sjkim        {
1503291333Sjkim            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1504291333Sjkim                &Subtable, TRUE);
1505291333Sjkim            if (ACPI_FAILURE (Status))
1506291333Sjkim            {
1507291333Sjkim                return (Status);
1508291333Sjkim            }
1509291333Sjkim
1510291333Sjkim            if (!Subtable)
1511291333Sjkim            {
1512291333Sjkim                break;
1513291333Sjkim            }
1514291333Sjkim
1515291333Sjkim            DtInsertSubtable (ParentTable, Subtable);
1516291333Sjkim            NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1517291333Sjkim            IdMappingNumber++;
1518291333Sjkim        }
1519291333Sjkim
1520291333Sjkim        IortNode->MappingCount = IdMappingNumber;
1521291333Sjkim
1522291333Sjkim        /*
1523291333Sjkim         * Node length can be determined by DT_LENGTH option
1524291333Sjkim         * IortNode->Length = NodeLength;
1525291333Sjkim         */
1526291333Sjkim        DtPopSubtable ();
1527291333Sjkim        ParentTable = DtPeekSubtable ();
1528291333Sjkim        NodeNumber++;
1529291333Sjkim    }
1530291333Sjkim
1531291333Sjkim    Iort->NodeCount = NodeNumber;
1532291333Sjkim    return (AE_OK);
1533291333Sjkim}
1534291333Sjkim
1535291333Sjkim
1536291333Sjkim/******************************************************************************
1537291333Sjkim *
1538291333Sjkim * FUNCTION:    DtCompileIvrs
1539291333Sjkim *
1540291333Sjkim * PARAMETERS:  List                - Current field list pointer
1541291333Sjkim *
1542291333Sjkim * RETURN:      Status
1543291333Sjkim *
1544291333Sjkim * DESCRIPTION: Compile IVRS.
1545291333Sjkim *
1546291333Sjkim *****************************************************************************/
1547291333Sjkim
1548291333SjkimACPI_STATUS
1549291333SjkimDtCompileIvrs (
1550291333Sjkim    void                    **List)
1551291333Sjkim{
1552291333Sjkim    ACPI_STATUS             Status;
1553291333Sjkim    DT_SUBTABLE             *Subtable;
1554291333Sjkim    DT_SUBTABLE             *ParentTable;
1555291333Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
1556291333Sjkim    DT_FIELD                *SubtableStart;
1557291333Sjkim    ACPI_DMTABLE_INFO       *InfoTable;
1558291333Sjkim    ACPI_IVRS_HEADER        *IvrsHeader;
1559291333Sjkim    UINT8                   EntryType;
1560291333Sjkim
1561291333Sjkim
1562291333Sjkim    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1563291333Sjkim        &Subtable, TRUE);
1564291333Sjkim    if (ACPI_FAILURE (Status))
1565291333Sjkim    {
1566291333Sjkim        return (Status);
1567291333Sjkim    }
1568291333Sjkim
1569291333Sjkim    ParentTable = DtPeekSubtable ();
1570291333Sjkim    DtInsertSubtable (ParentTable, Subtable);
1571291333Sjkim
1572291333Sjkim    while (*PFieldList)
1573291333Sjkim    {
1574291333Sjkim        SubtableStart = *PFieldList;
1575291333Sjkim        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1576291333Sjkim            &Subtable, TRUE);
1577291333Sjkim        if (ACPI_FAILURE (Status))
1578291333Sjkim        {
1579291333Sjkim            return (Status);
1580291333Sjkim        }
1581291333Sjkim
1582291333Sjkim        ParentTable = DtPeekSubtable ();
1583291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
1584291333Sjkim        DtPushSubtable (Subtable);
1585291333Sjkim
1586291333Sjkim        IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1587291333Sjkim
1588291333Sjkim        switch (IvrsHeader->Type)
1589291333Sjkim        {
1590291333Sjkim        case ACPI_IVRS_TYPE_HARDWARE:
1591291333Sjkim
1592291333Sjkim            InfoTable = AcpiDmTableInfoIvrs0;
1593291333Sjkim            break;
1594291333Sjkim
1595291333Sjkim        case ACPI_IVRS_TYPE_MEMORY1:
1596291333Sjkim        case ACPI_IVRS_TYPE_MEMORY2:
1597291333Sjkim        case ACPI_IVRS_TYPE_MEMORY3:
1598291333Sjkim
1599291333Sjkim            InfoTable = AcpiDmTableInfoIvrs1;
1600291333Sjkim            break;
1601291333Sjkim
1602291333Sjkim        default:
1603291333Sjkim
1604291333Sjkim            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1605291333Sjkim            return (AE_ERROR);
1606291333Sjkim        }
1607291333Sjkim
1608291333Sjkim        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1609291333Sjkim        if (ACPI_FAILURE (Status))
1610291333Sjkim        {
1611291333Sjkim            return (Status);
1612291333Sjkim        }
1613291333Sjkim
1614291333Sjkim        ParentTable = DtPeekSubtable ();
1615291333Sjkim        DtInsertSubtable (ParentTable, Subtable);
1616291333Sjkim
1617291333Sjkim        if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1618291333Sjkim        {
1619291333Sjkim            while (*PFieldList &&
1620291333Sjkim                !strcmp ((*PFieldList)->Name, "Entry Type"))
1621291333Sjkim            {
1622291333Sjkim                SubtableStart = *PFieldList;
1623291333Sjkim                DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1624291333Sjkim
1625291333Sjkim                switch (EntryType)
1626291333Sjkim                {
1627291333Sjkim                /* 4-byte device entries */
1628291333Sjkim
1629291333Sjkim                case ACPI_IVRS_TYPE_PAD4:
1630291333Sjkim                case ACPI_IVRS_TYPE_ALL:
1631291333Sjkim                case ACPI_IVRS_TYPE_SELECT:
1632291333Sjkim                case ACPI_IVRS_TYPE_START:
1633291333Sjkim                case ACPI_IVRS_TYPE_END:
1634291333Sjkim
1635291333Sjkim                    InfoTable = AcpiDmTableInfoIvrs4;
1636291333Sjkim                    break;
1637291333Sjkim
1638291333Sjkim                /* 8-byte entries, type A */
1639291333Sjkim
1640291333Sjkim                case ACPI_IVRS_TYPE_ALIAS_SELECT:
1641291333Sjkim                case ACPI_IVRS_TYPE_ALIAS_START:
1642291333Sjkim
1643291333Sjkim                    InfoTable = AcpiDmTableInfoIvrs8a;
1644291333Sjkim                    break;
1645291333Sjkim
1646291333Sjkim                /* 8-byte entries, type B */
1647291333Sjkim
1648291333Sjkim                case ACPI_IVRS_TYPE_PAD8:
1649291333Sjkim                case ACPI_IVRS_TYPE_EXT_SELECT:
1650291333Sjkim                case ACPI_IVRS_TYPE_EXT_START:
1651291333Sjkim
1652291333Sjkim                    InfoTable = AcpiDmTableInfoIvrs8b;
1653291333Sjkim                    break;
1654291333Sjkim
1655291333Sjkim                /* 8-byte entries, type C */
1656291333Sjkim
1657291333Sjkim                case ACPI_IVRS_TYPE_SPECIAL:
1658291333Sjkim
1659291333Sjkim                    InfoTable = AcpiDmTableInfoIvrs8c;
1660291333Sjkim                    break;
1661291333Sjkim
1662291333Sjkim                default:
1663291333Sjkim
1664291333Sjkim                    DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1665291333Sjkim                        "IVRS Device Entry");
1666291333Sjkim                    return (AE_ERROR);
1667291333Sjkim                }
1668291333Sjkim
1669291333Sjkim                Status = DtCompileTable (PFieldList, InfoTable,
1670291333Sjkim                    &Subtable, TRUE);
1671291333Sjkim                if (ACPI_FAILURE (Status))
1672291333Sjkim                {
1673291333Sjkim                    return (Status);
1674291333Sjkim                }
1675291333Sjkim
1676291333Sjkim                DtInsertSubtable (ParentTable, Subtable);
1677291333Sjkim            }
1678291333Sjkim        }
1679291333Sjkim
1680291333Sjkim        DtPopSubtable ();
1681291333Sjkim    }
1682291333Sjkim
1683291333Sjkim    return (AE_OK);
1684291333Sjkim}
1685