xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/dttable2.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /******************************************************************************
2  *
3  * Module Name: dttable2.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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 L-Z */
45 
46 #include "aslcompiler.h"
47 
48 #define _COMPONENT          DT_COMPILER
49         ACPI_MODULE_NAME    ("dttable2")
50 
51 
52 /******************************************************************************
53  *
54  * FUNCTION:    DtCompileLpit
55  *
56  * PARAMETERS:  List                - Current field list pointer
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: Compile LPIT.
61  *
62  *****************************************************************************/
63 
64 ACPI_STATUS
65 DtCompileLpit (
66     void                    **List)
67 {
68     ACPI_STATUS             Status;
69     DT_SUBTABLE             *Subtable;
70     DT_SUBTABLE             *ParentTable;
71     DT_FIELD                **PFieldList = (DT_FIELD **) List;
72     DT_FIELD                *SubtableStart;
73     ACPI_DMTABLE_INFO       *InfoTable;
74     ACPI_LPIT_HEADER        *LpitHeader;
75 
76 
77     /* Note: Main table consists only of the standard ACPI table header */
78 
79     while (*PFieldList)
80     {
81         SubtableStart = *PFieldList;
82 
83         /* LPIT Subtable header */
84 
85         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
86             &Subtable);
87         if (ACPI_FAILURE (Status))
88         {
89             return (Status);
90         }
91 
92         ParentTable = DtPeekSubtable ();
93         DtInsertSubtable (ParentTable, Subtable);
94         DtPushSubtable (Subtable);
95 
96         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
97 
98         switch (LpitHeader->Type)
99         {
100         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
101 
102             InfoTable = AcpiDmTableInfoLpit0;
103             break;
104 
105         default:
106 
107             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
108             return (AE_ERROR);
109         }
110 
111         /* LPIT Subtable */
112 
113         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
114         if (ACPI_FAILURE (Status))
115         {
116             return (Status);
117         }
118 
119         ParentTable = DtPeekSubtable ();
120         DtInsertSubtable (ParentTable, Subtable);
121         DtPopSubtable ();
122     }
123 
124     return (AE_OK);
125 }
126 
127 
128 /******************************************************************************
129  *
130  * FUNCTION:    DtCompileMadt
131  *
132  * PARAMETERS:  List                - Current field list pointer
133  *
134  * RETURN:      Status
135  *
136  * DESCRIPTION: Compile MADT.
137  *
138  *****************************************************************************/
139 
140 ACPI_STATUS
141 DtCompileMadt (
142     void                    **List)
143 {
144     ACPI_STATUS             Status;
145     DT_SUBTABLE             *Subtable;
146     DT_SUBTABLE             *ParentTable;
147     DT_FIELD                **PFieldList = (DT_FIELD **) List;
148     DT_FIELD                *SubtableStart;
149     ACPI_SUBTABLE_HEADER    *MadtHeader;
150     ACPI_DMTABLE_INFO       *InfoTable;
151 
152 
153     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
154         &Subtable);
155     if (ACPI_FAILURE (Status))
156     {
157         return (Status);
158     }
159 
160     ParentTable = DtPeekSubtable ();
161     DtInsertSubtable (ParentTable, Subtable);
162 
163     while (*PFieldList)
164     {
165         SubtableStart = *PFieldList;
166         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
167             &Subtable);
168         if (ACPI_FAILURE (Status))
169         {
170             return (Status);
171         }
172 
173         ParentTable = DtPeekSubtable ();
174         DtInsertSubtable (ParentTable, Subtable);
175         DtPushSubtable (Subtable);
176 
177         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
178 
179         switch (MadtHeader->Type)
180         {
181         case ACPI_MADT_TYPE_LOCAL_APIC:
182 
183             InfoTable = AcpiDmTableInfoMadt0;
184             break;
185 
186         case ACPI_MADT_TYPE_IO_APIC:
187 
188             InfoTable = AcpiDmTableInfoMadt1;
189             break;
190 
191         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
192 
193             InfoTable = AcpiDmTableInfoMadt2;
194             break;
195 
196         case ACPI_MADT_TYPE_NMI_SOURCE:
197 
198             InfoTable = AcpiDmTableInfoMadt3;
199             break;
200 
201         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
202 
203             InfoTable = AcpiDmTableInfoMadt4;
204             break;
205 
206         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
207 
208             InfoTable = AcpiDmTableInfoMadt5;
209             break;
210 
211         case ACPI_MADT_TYPE_IO_SAPIC:
212 
213             InfoTable = AcpiDmTableInfoMadt6;
214             break;
215 
216         case ACPI_MADT_TYPE_LOCAL_SAPIC:
217 
218             InfoTable = AcpiDmTableInfoMadt7;
219             break;
220 
221         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
222 
223             InfoTable = AcpiDmTableInfoMadt8;
224             break;
225 
226         case ACPI_MADT_TYPE_LOCAL_X2APIC:
227 
228             InfoTable = AcpiDmTableInfoMadt9;
229             break;
230 
231         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
232 
233             InfoTable = AcpiDmTableInfoMadt10;
234             break;
235 
236         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
237 
238             InfoTable = AcpiDmTableInfoMadt11;
239             break;
240 
241         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
242 
243             InfoTable = AcpiDmTableInfoMadt12;
244             break;
245 
246         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
247 
248             InfoTable = AcpiDmTableInfoMadt13;
249             break;
250 
251         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
252 
253             InfoTable = AcpiDmTableInfoMadt14;
254             break;
255 
256         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
257 
258             InfoTable = AcpiDmTableInfoMadt15;
259             break;
260 
261         case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
262 
263             InfoTable = AcpiDmTableInfoMadt16;
264             break;
265 
266         default:
267 
268             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
269             return (AE_ERROR);
270         }
271 
272         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
273         if (ACPI_FAILURE (Status))
274         {
275             return (Status);
276         }
277 
278         ParentTable = DtPeekSubtable ();
279         DtInsertSubtable (ParentTable, Subtable);
280         DtPopSubtable ();
281     }
282 
283     return (AE_OK);
284 }
285 
286 
287 /******************************************************************************
288  *
289  * FUNCTION:    DtCompileMcfg
290  *
291  * PARAMETERS:  List                - Current field list pointer
292  *
293  * RETURN:      Status
294  *
295  * DESCRIPTION: Compile MCFG.
296  *
297  *****************************************************************************/
298 
299 ACPI_STATUS
300 DtCompileMcfg (
301     void                    **List)
302 {
303     ACPI_STATUS             Status;
304 
305 
306     Status = DtCompileTwoSubtables (List,
307         AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
308     return (Status);
309 }
310 
311 
312 /******************************************************************************
313  *
314  * FUNCTION:    DtCompileMpst
315  *
316  * PARAMETERS:  List                - Current field list pointer
317  *
318  * RETURN:      Status
319  *
320  * DESCRIPTION: Compile MPST.
321  *
322  *****************************************************************************/
323 
324 ACPI_STATUS
325 DtCompileMpst (
326     void                    **List)
327 {
328     ACPI_STATUS             Status;
329     DT_SUBTABLE             *Subtable;
330     DT_SUBTABLE             *ParentTable;
331     DT_FIELD                **PFieldList = (DT_FIELD **) List;
332     ACPI_MPST_CHANNEL       *MpstChannelInfo;
333     ACPI_MPST_POWER_NODE    *MpstPowerNode;
334     ACPI_MPST_DATA_HDR      *MpstDataHeader;
335     UINT16                  SubtableCount;
336     UINT32                  PowerStateCount;
337     UINT32                  ComponentCount;
338 
339 
340     /* Main table */
341 
342     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable);
343     if (ACPI_FAILURE (Status))
344     {
345         return (Status);
346     }
347 
348     ParentTable = DtPeekSubtable ();
349     DtInsertSubtable (ParentTable, Subtable);
350     DtPushSubtable (Subtable);
351 
352     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
353     SubtableCount = MpstChannelInfo->PowerNodeCount;
354 
355     while (*PFieldList && SubtableCount)
356     {
357         /* Subtable: Memory Power Node(s) */
358 
359         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
360             &Subtable);
361         if (ACPI_FAILURE (Status))
362         {
363             return (Status);
364         }
365 
366         ParentTable = DtPeekSubtable ();
367         DtInsertSubtable (ParentTable, Subtable);
368         DtPushSubtable (Subtable);
369 
370         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
371         PowerStateCount = MpstPowerNode->NumPowerStates;
372         ComponentCount = MpstPowerNode->NumPhysicalComponents;
373 
374         ParentTable = DtPeekSubtable ();
375 
376         /* Sub-subtables - Memory Power State Structure(s) */
377 
378         while (*PFieldList && PowerStateCount)
379         {
380             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
381                 &Subtable);
382             if (ACPI_FAILURE (Status))
383             {
384                 return (Status);
385             }
386 
387             DtInsertSubtable (ParentTable, Subtable);
388             PowerStateCount--;
389         }
390 
391         /* Sub-subtables - Physical Component ID Structure(s) */
392 
393         while (*PFieldList && ComponentCount)
394         {
395             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
396                 &Subtable);
397             if (ACPI_FAILURE (Status))
398             {
399                 return (Status);
400             }
401 
402             DtInsertSubtable (ParentTable, Subtable);
403             ComponentCount--;
404         }
405 
406         SubtableCount--;
407         DtPopSubtable ();
408     }
409 
410     /* Subtable: Count of Memory Power State Characteristic structures */
411 
412     DtPopSubtable ();
413 
414     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable);
415     if (ACPI_FAILURE (Status))
416     {
417         return (Status);
418     }
419 
420     ParentTable = DtPeekSubtable ();
421     DtInsertSubtable (ParentTable, Subtable);
422     DtPushSubtable (Subtable);
423 
424     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
425     SubtableCount = MpstDataHeader->CharacteristicsCount;
426 
427     ParentTable = DtPeekSubtable ();
428 
429     /* Subtable: Memory Power State Characteristics structure(s) */
430 
431     while (*PFieldList && SubtableCount)
432     {
433         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
434             &Subtable);
435         if (ACPI_FAILURE (Status))
436         {
437             return (Status);
438         }
439 
440         DtInsertSubtable (ParentTable, Subtable);
441         SubtableCount--;
442     }
443 
444     DtPopSubtable ();
445     return (AE_OK);
446 }
447 
448 
449 /******************************************************************************
450  *
451  * FUNCTION:    DtCompileMsct
452  *
453  * PARAMETERS:  List                - Current field list pointer
454  *
455  * RETURN:      Status
456  *
457  * DESCRIPTION: Compile MSCT.
458  *
459  *****************************************************************************/
460 
461 ACPI_STATUS
462 DtCompileMsct (
463     void                    **List)
464 {
465     ACPI_STATUS             Status;
466 
467 
468     Status = DtCompileTwoSubtables (List,
469         AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
470     return (Status);
471 }
472 
473 
474 /******************************************************************************
475  *
476  * FUNCTION:    DtCompileNfit
477  *
478  * PARAMETERS:  List                - Current field list pointer
479  *
480  * RETURN:      Status
481  *
482  * DESCRIPTION: Compile NFIT.
483  *
484  *****************************************************************************/
485 
486 ACPI_STATUS
487 DtCompileNfit (
488     void                    **List)
489 {
490     ACPI_STATUS             Status;
491     DT_SUBTABLE             *Subtable;
492     DT_SUBTABLE             *ParentTable;
493     DT_FIELD                **PFieldList = (DT_FIELD **) List;
494     DT_FIELD                *SubtableStart;
495     ACPI_NFIT_HEADER        *NfitHeader;
496     ACPI_DMTABLE_INFO       *InfoTable;
497     UINT32                  Count;
498     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
499     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
500 
501 
502     /* Main table */
503 
504     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
505         &Subtable);
506     if (ACPI_FAILURE (Status))
507     {
508         return (Status);
509     }
510 
511     ParentTable = DtPeekSubtable ();
512     DtInsertSubtable (ParentTable, Subtable);
513     DtPushSubtable (Subtable);
514 
515     /* Subtables */
516 
517     while (*PFieldList)
518     {
519         SubtableStart = *PFieldList;
520         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
521             &Subtable);
522         if (ACPI_FAILURE (Status))
523         {
524             return (Status);
525         }
526 
527         ParentTable = DtPeekSubtable ();
528         DtInsertSubtable (ParentTable, Subtable);
529         DtPushSubtable (Subtable);
530 
531         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
532 
533         switch (NfitHeader->Type)
534         {
535         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
536 
537             InfoTable = AcpiDmTableInfoNfit0;
538             break;
539 
540         case ACPI_NFIT_TYPE_MEMORY_MAP:
541 
542             InfoTable = AcpiDmTableInfoNfit1;
543             break;
544 
545         case ACPI_NFIT_TYPE_INTERLEAVE:
546 
547             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
548             InfoTable = AcpiDmTableInfoNfit2;
549             break;
550 
551         case ACPI_NFIT_TYPE_SMBIOS:
552 
553             InfoTable = AcpiDmTableInfoNfit3;
554             break;
555 
556         case ACPI_NFIT_TYPE_CONTROL_REGION:
557 
558             InfoTable = AcpiDmTableInfoNfit4;
559             break;
560 
561         case ACPI_NFIT_TYPE_DATA_REGION:
562 
563             InfoTable = AcpiDmTableInfoNfit5;
564             break;
565 
566         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
567 
568             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
569             InfoTable = AcpiDmTableInfoNfit6;
570             break;
571 
572         case ACPI_NFIT_TYPE_CAPABILITIES:
573 
574             InfoTable = AcpiDmTableInfoNfit7;
575             break;
576 
577         default:
578 
579             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
580             return (AE_ERROR);
581         }
582 
583         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
584         if (ACPI_FAILURE (Status))
585         {
586             return (Status);
587         }
588 
589         ParentTable = DtPeekSubtable ();
590         DtInsertSubtable (ParentTable, Subtable);
591         DtPopSubtable ();
592 
593         switch (NfitHeader->Type)
594         {
595         case ACPI_NFIT_TYPE_INTERLEAVE:
596 
597             Count = 0;
598             DtPushSubtable (Subtable);
599             while (*PFieldList)
600             {
601                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
602                     &Subtable);
603                 if (ACPI_FAILURE (Status))
604                 {
605                     return (Status);
606                 }
607 
608                 if (!Subtable)
609                 {
610                     DtPopSubtable ();
611                     break;
612                 }
613 
614                 ParentTable = DtPeekSubtable ();
615                 DtInsertSubtable (ParentTable, Subtable);
616                 Count++;
617             }
618 
619             Interleave->LineCount = Count;
620             break;
621 
622         case ACPI_NFIT_TYPE_SMBIOS:
623 
624             if (*PFieldList)
625             {
626                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
627                     &Subtable);
628                 if (ACPI_FAILURE (Status))
629                 {
630                     return (Status);
631                 }
632 
633                 if (Subtable)
634                 {
635                     DtInsertSubtable (ParentTable, Subtable);
636                 }
637             }
638             break;
639 
640         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
641 
642             Count = 0;
643             DtPushSubtable (Subtable);
644             while (*PFieldList)
645             {
646                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
647                     &Subtable);
648                 if (ACPI_FAILURE (Status))
649                 {
650                     return (Status);
651                 }
652 
653                 if (!Subtable)
654                 {
655                     DtPopSubtable ();
656                     break;
657                 }
658 
659                 ParentTable = DtPeekSubtable ();
660                 DtInsertSubtable (ParentTable, Subtable);
661                 Count++;
662             }
663 
664             Hint->HintCount = (UINT16) Count;
665             break;
666 
667         default:
668             break;
669         }
670     }
671 
672     return (AE_OK);
673 }
674 
675 
676 /******************************************************************************
677  *
678  * FUNCTION:    DtCompilePcct
679  *
680  * PARAMETERS:  List                - Current field list pointer
681  *
682  * RETURN:      Status
683  *
684  * DESCRIPTION: Compile PCCT.
685  *
686  *****************************************************************************/
687 
688 ACPI_STATUS
689 DtCompilePcct (
690     void                    **List)
691 {
692     ACPI_STATUS             Status;
693     DT_SUBTABLE             *Subtable;
694     DT_SUBTABLE             *ParentTable;
695     DT_FIELD                **PFieldList = (DT_FIELD **) List;
696     DT_FIELD                *SubtableStart;
697     ACPI_SUBTABLE_HEADER    *PcctHeader;
698     ACPI_DMTABLE_INFO       *InfoTable;
699 
700 
701     /* Main table */
702 
703     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
704         &Subtable);
705     if (ACPI_FAILURE (Status))
706     {
707         return (Status);
708     }
709 
710     ParentTable = DtPeekSubtable ();
711     DtInsertSubtable (ParentTable, Subtable);
712 
713     /* Subtables */
714 
715     while (*PFieldList)
716     {
717         SubtableStart = *PFieldList;
718         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
719             &Subtable);
720         if (ACPI_FAILURE (Status))
721         {
722             return (Status);
723         }
724 
725         ParentTable = DtPeekSubtable ();
726         DtInsertSubtable (ParentTable, Subtable);
727         DtPushSubtable (Subtable);
728 
729         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
730 
731         switch (PcctHeader->Type)
732         {
733         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
734 
735             InfoTable = AcpiDmTableInfoPcct0;
736             break;
737 
738         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
739 
740             InfoTable = AcpiDmTableInfoPcct1;
741             break;
742 
743         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
744 
745             InfoTable = AcpiDmTableInfoPcct2;
746             break;
747 
748         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
749 
750             InfoTable = AcpiDmTableInfoPcct3;
751             break;
752 
753         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
754 
755             InfoTable = AcpiDmTableInfoPcct4;
756             break;
757 
758         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
759 
760             InfoTable = AcpiDmTableInfoPcct5;
761             break;
762 
763         default:
764 
765             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
766             return (AE_ERROR);
767         }
768 
769         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
770         if (ACPI_FAILURE (Status))
771         {
772             return (Status);
773         }
774 
775         ParentTable = DtPeekSubtable ();
776         DtInsertSubtable (ParentTable, Subtable);
777         DtPopSubtable ();
778     }
779 
780     return (AE_OK);
781 }
782 
783 
784 /******************************************************************************
785  *
786  * FUNCTION:    DtCompilePdtt
787  *
788  * PARAMETERS:  List                - Current field list pointer
789  *
790  * RETURN:      Status
791  *
792  * DESCRIPTION: Compile PDTT.
793  *
794  *****************************************************************************/
795 
796 ACPI_STATUS
797 DtCompilePdtt (
798     void                    **List)
799 {
800     ACPI_STATUS             Status;
801     DT_SUBTABLE             *Subtable;
802     DT_SUBTABLE             *ParentTable;
803     DT_FIELD                **PFieldList = (DT_FIELD **) List;
804     ACPI_TABLE_PDTT         *PdttHeader;
805     UINT32                  Count = 0;
806 
807 
808     /* Main table */
809 
810     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
811     if (ACPI_FAILURE (Status))
812     {
813         return (Status);
814     }
815 
816     ParentTable = DtPeekSubtable ();
817     DtInsertSubtable (ParentTable, Subtable);
818 
819     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
820     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
821 
822     /* There is only one type of subtable at this time, no need to decode */
823 
824     while (*PFieldList)
825     {
826         /* List of subchannel IDs, each 2 bytes */
827 
828         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
829             &Subtable);
830         if (ACPI_FAILURE (Status))
831         {
832             return (Status);
833         }
834 
835         DtInsertSubtable (ParentTable, Subtable);
836         Count++;
837     }
838 
839     PdttHeader->TriggerCount = (UINT8) Count;
840     return (AE_OK);
841 }
842 
843 
844 /******************************************************************************
845  *
846  * FUNCTION:    DtCompilePhat
847  *
848  * PARAMETERS:  List                - Current field list pointer
849  *
850  * RETURN:      Status
851  *
852  * DESCRIPTION: Compile Phat.
853  *
854  *****************************************************************************/
855 
856 ACPI_STATUS
857 DtCompilePhat (
858     void                    **List)
859 {
860     ACPI_STATUS             Status = AE_OK;
861     DT_SUBTABLE             *Subtable;
862     DT_SUBTABLE             *ParentTable;
863     DT_FIELD                **PFieldList = (DT_FIELD **) List;
864     ACPI_PHAT_HEADER        *PhatHeader;
865     ACPI_DMTABLE_INFO       *Info;
866     ACPI_PHAT_VERSION_DATA  *VersionData;
867     UINT32                  RecordCount;
868 
869 
870     /* The table consist of subtables */
871 
872     while (*PFieldList)
873     {
874         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
875         if (ACPI_FAILURE (Status))
876         {
877             return (Status);
878         }
879 
880         ParentTable = DtPeekSubtable ();
881         DtInsertSubtable (ParentTable, Subtable);
882         DtPushSubtable (Subtable);
883 
884         PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
885 
886         switch (PhatHeader->Type)
887         {
888         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
889 
890             Info = AcpiDmTableInfoPhat0;
891             PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
892             break;
893 
894         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
895 
896             Info = AcpiDmTableInfoPhat1;
897             PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
898             break;
899 
900         default:
901 
902             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
903             return (AE_ERROR);
904 
905             break;
906         }
907 
908         Status = DtCompileTable (PFieldList, Info, &Subtable);
909         if (ACPI_FAILURE (Status))
910         {
911             return (Status);
912         }
913 
914         ParentTable = DtPeekSubtable ();
915         DtInsertSubtable (ParentTable, Subtable);
916 
917         switch (PhatHeader->Type)
918         {
919         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
920 
921             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
922                 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
923             RecordCount = VersionData->ElementCount;
924 
925             while (RecordCount)
926             {
927                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
928                     &Subtable);
929                 if (ACPI_FAILURE (Status))
930                 {
931                     return (Status);
932                 }
933                 ParentTable = DtPeekSubtable ();
934                 DtInsertSubtable (ParentTable, Subtable);
935 
936                 RecordCount--;
937                 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
938             }
939             break;
940 
941         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
942 
943             /* Compile device path */
944 
945             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
946             if (ACPI_FAILURE (Status))
947             {
948                 return (Status);
949             }
950             ParentTable = DtPeekSubtable ();
951             DtInsertSubtable (ParentTable, Subtable);
952 
953             PhatHeader->Length += (UINT16) Subtable->Length;
954 
955             /* Compile vendor specific data */
956 
957             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
958             if (ACPI_FAILURE (Status))
959             {
960                 return (Status);
961             }
962             ParentTable = DtPeekSubtable ();
963             DtInsertSubtable (ParentTable, Subtable);
964 
965             PhatHeader->Length += (UINT16) Subtable->Length;
966 
967             break;
968 
969         default:
970 
971             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
972             return (AE_ERROR);
973         }
974     }
975 
976     return (Status);
977 }
978 
979 
980 /******************************************************************************
981  *
982  * FUNCTION:    DtCompilePmtt
983  *
984  * PARAMETERS:  List                - Current field list pointer
985  *
986  * RETURN:      Status
987  *
988  * DESCRIPTION: Compile PMTT.
989  *
990  *****************************************************************************/
991 
992 ACPI_STATUS
993 DtCompilePmtt (
994     void                    **List)
995 {
996     ACPI_STATUS             Status;
997     DT_SUBTABLE             *Subtable;
998     DT_SUBTABLE             *ParentTable;
999     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1000     DT_FIELD                *SubtableStart;
1001     UINT16                  Type;
1002 
1003 
1004     /* Main table */
1005 
1006     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
1007     if (ACPI_FAILURE (Status))
1008     {
1009         return (Status);
1010     }
1011 
1012     ParentTable = DtPeekSubtable ();
1013     DtInsertSubtable (ParentTable, Subtable);
1014     DtPushSubtable (Subtable);
1015 
1016     /* Subtables */
1017 
1018     while (*PFieldList)
1019     {
1020         SubtableStart = *PFieldList;
1021         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1022 
1023         switch (Type)
1024         {
1025         case ACPI_PMTT_TYPE_SOCKET:
1026 
1027             /* Subtable: Socket Structure */
1028 
1029             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
1030 
1031             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1032                 &Subtable);
1033             if (ACPI_FAILURE (Status))
1034             {
1035                 return (Status);
1036             }
1037 
1038             break;
1039 
1040         case ACPI_PMTT_TYPE_CONTROLLER:
1041 
1042             /* Subtable: Memory Controller Structure */
1043 
1044             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
1045 
1046             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1047                 &Subtable);
1048             if (ACPI_FAILURE (Status))
1049             {
1050                 return (Status);
1051             }
1052 
1053             break;
1054 
1055         case ACPI_PMTT_TYPE_DIMM:
1056 
1057             /* Subtable: Physical Component (DIMM) Structure */
1058 
1059             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
1060             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1061                 &Subtable);
1062             if (ACPI_FAILURE (Status))
1063             {
1064                 return (Status);
1065             }
1066 
1067             break;
1068 
1069         case ACPI_PMTT_TYPE_VENDOR:
1070 
1071             /* Subtable: Vendor-specific Structure */
1072 
1073             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
1074             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
1075                 &Subtable);
1076             if (ACPI_FAILURE (Status))
1077             {
1078                 return (Status);
1079             }
1080 
1081             break;
1082 
1083         default:
1084 
1085             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1086             return (AE_ERROR);
1087         }
1088 
1089         DtInsertSubtable (ParentTable, Subtable);
1090     }
1091 
1092     return (Status);
1093 }
1094 
1095 
1096 /******************************************************************************
1097  *
1098  * FUNCTION:    DtCompilePptt
1099  *
1100  * PARAMETERS:  List                - Current field list pointer
1101  *
1102  * RETURN:      Status
1103  *
1104  * DESCRIPTION: Compile PPTT.
1105  *
1106  *****************************************************************************/
1107 
1108 ACPI_STATUS
1109 DtCompilePptt (
1110     void                    **List)
1111 {
1112     ACPI_STATUS             Status;
1113     ACPI_SUBTABLE_HEADER    *PpttHeader;
1114     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
1115     DT_SUBTABLE             *Subtable;
1116     DT_SUBTABLE             *ParentTable;
1117     ACPI_DMTABLE_INFO       *InfoTable;
1118     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1119     DT_FIELD                *SubtableStart;
1120     ACPI_TABLE_HEADER       *PpttAcpiHeader;
1121 
1122 
1123     ParentTable = DtPeekSubtable ();
1124     while (*PFieldList)
1125     {
1126         SubtableStart = *PFieldList;
1127 
1128         /* Compile PPTT subtable header */
1129 
1130         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1131             &Subtable);
1132         if (ACPI_FAILURE (Status))
1133         {
1134             return (Status);
1135         }
1136         DtInsertSubtable (ParentTable, Subtable);
1137         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1138         PpttHeader->Length = (UINT8)(Subtable->Length);
1139 
1140         switch (PpttHeader->Type)
1141         {
1142         case ACPI_PPTT_TYPE_PROCESSOR:
1143 
1144             InfoTable = AcpiDmTableInfoPptt0;
1145             break;
1146 
1147         case ACPI_PPTT_TYPE_CACHE:
1148 
1149             InfoTable = AcpiDmTableInfoPptt1;
1150             break;
1151 
1152         case ACPI_PPTT_TYPE_ID:
1153 
1154             InfoTable = AcpiDmTableInfoPptt2;
1155             break;
1156 
1157         default:
1158 
1159             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1160             return (AE_ERROR);
1161         }
1162 
1163         /* Compile PPTT subtable body */
1164 
1165         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1166         if (ACPI_FAILURE (Status))
1167         {
1168             return (Status);
1169         }
1170         DtInsertSubtable (ParentTable, Subtable);
1171         PpttHeader->Length += (UINT8)(Subtable->Length);
1172 
1173         /* Compile PPTT subtable additionals */
1174 
1175         switch (PpttHeader->Type)
1176         {
1177         case ACPI_PPTT_TYPE_PROCESSOR:
1178 
1179             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1180                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1181             if (PpttProcessor)
1182             {
1183                 /* Compile initiator proximity domain list */
1184 
1185                 PpttProcessor->NumberOfPrivResources = 0;
1186                 while (*PFieldList)
1187                 {
1188                     Status = DtCompileTable (PFieldList,
1189                         AcpiDmTableInfoPptt0a, &Subtable);
1190                     if (ACPI_FAILURE (Status))
1191                     {
1192                         return (Status);
1193                     }
1194                     if (!Subtable)
1195                     {
1196                         break;
1197                     }
1198 
1199                     DtInsertSubtable (ParentTable, Subtable);
1200                     PpttHeader->Length += (UINT8)(Subtable->Length);
1201                     PpttProcessor->NumberOfPrivResources++;
1202                 }
1203             }
1204             break;
1205 
1206         case ACPI_PPTT_TYPE_CACHE:
1207 
1208             PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1209                 AslGbl_RootTable->Buffer);
1210             if (PpttAcpiHeader->Revision < 3)
1211             {
1212                 break;
1213             }
1214             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
1215                 &Subtable);
1216             DtInsertSubtable (ParentTable, Subtable);
1217             PpttHeader->Length += (UINT8)(Subtable->Length);
1218             break;
1219 
1220         default:
1221 
1222             break;
1223         }
1224     }
1225 
1226     return (AE_OK);
1227 }
1228 
1229 
1230 /******************************************************************************
1231  *
1232  * FUNCTION:    DtCompileRsdt
1233  *
1234  * PARAMETERS:  List                - Current field list pointer
1235  *
1236  * RETURN:      Status
1237  *
1238  * DESCRIPTION: Compile RSDT.
1239  *
1240  *****************************************************************************/
1241 
1242 ACPI_STATUS
1243 DtCompileRsdt (
1244     void                    **List)
1245 {
1246     DT_SUBTABLE             *Subtable;
1247     DT_SUBTABLE             *ParentTable;
1248     DT_FIELD                *FieldList = *(DT_FIELD **) List;
1249     UINT32                  Address;
1250 
1251 
1252     ParentTable = DtPeekSubtable ();
1253 
1254     while (FieldList)
1255     {
1256         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1257 
1258         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1259         DtInsertSubtable (ParentTable, Subtable);
1260         FieldList = FieldList->Next;
1261     }
1262 
1263     return (AE_OK);
1264 }
1265 
1266 
1267 /******************************************************************************
1268  *
1269  * FUNCTION:    DtCompileS3pt
1270  *
1271  * PARAMETERS:  PFieldList          - Current field list pointer
1272  *
1273  * RETURN:      Status
1274  *
1275  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1276  *
1277  *****************************************************************************/
1278 
1279 ACPI_STATUS
1280 DtCompileS3pt (
1281     DT_FIELD                **PFieldList)
1282 {
1283     ACPI_STATUS             Status;
1284     ACPI_FPDT_HEADER        *S3ptHeader;
1285     DT_SUBTABLE             *Subtable;
1286     DT_SUBTABLE             *ParentTable;
1287     ACPI_DMTABLE_INFO       *InfoTable;
1288     DT_FIELD                *SubtableStart;
1289 
1290 
1291     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1292         &AslGbl_RootTable);
1293     if (ACPI_FAILURE (Status))
1294     {
1295         return (Status);
1296     }
1297 
1298     DtPushSubtable (AslGbl_RootTable);
1299 
1300     while (*PFieldList)
1301     {
1302         SubtableStart = *PFieldList;
1303         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1304             &Subtable);
1305         if (ACPI_FAILURE (Status))
1306         {
1307             return (Status);
1308         }
1309 
1310         ParentTable = DtPeekSubtable ();
1311         DtInsertSubtable (ParentTable, Subtable);
1312         DtPushSubtable (Subtable);
1313 
1314         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1315 
1316         switch (S3ptHeader->Type)
1317         {
1318         case ACPI_S3PT_TYPE_RESUME:
1319 
1320             InfoTable = AcpiDmTableInfoS3pt0;
1321             break;
1322 
1323         case ACPI_S3PT_TYPE_SUSPEND:
1324 
1325             InfoTable = AcpiDmTableInfoS3pt1;
1326             break;
1327 
1328         default:
1329 
1330             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1331             return (AE_ERROR);
1332         }
1333 
1334         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1335         if (ACPI_FAILURE (Status))
1336         {
1337             return (Status);
1338         }
1339 
1340         ParentTable = DtPeekSubtable ();
1341         DtInsertSubtable (ParentTable, Subtable);
1342         DtPopSubtable ();
1343     }
1344 
1345     return (AE_OK);
1346 }
1347 
1348 
1349 /******************************************************************************
1350  *
1351  * FUNCTION:    DtCompileSdev
1352  *
1353  * PARAMETERS:  List                - Current field list pointer
1354  *
1355  * RETURN:      Status
1356  *
1357  * DESCRIPTION: Compile SDEV.
1358  *
1359  *****************************************************************************/
1360 
1361 ACPI_STATUS
1362 DtCompileSdev (
1363     void                    **List)
1364 {
1365     ACPI_STATUS                 Status;
1366     ACPI_SDEV_HEADER            *SdevHeader;
1367     ACPI_SDEV_HEADER            *SecureComponentHeader;
1368     DT_SUBTABLE                 *Subtable;
1369     DT_SUBTABLE                 *ParentTable;
1370     ACPI_DMTABLE_INFO           *InfoTable;
1371     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
1372     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
1373     DT_FIELD                    *SubtableStart;
1374     ACPI_SDEV_PCIE              *Pcie = NULL;
1375     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
1376     UINT32                      EntryCount;
1377     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
1378     UINT16                      ComponentLength = 0;
1379 
1380 
1381     /* Subtables */
1382 
1383     while (*PFieldList)
1384     {
1385         /* Compile common SDEV subtable header */
1386 
1387         SubtableStart = *PFieldList;
1388         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
1389             &Subtable);
1390         if (ACPI_FAILURE (Status))
1391         {
1392             return (Status);
1393         }
1394 
1395         ParentTable = DtPeekSubtable ();
1396         DtInsertSubtable (ParentTable, Subtable);
1397         DtPushSubtable (Subtable);
1398 
1399         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1400         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
1401 
1402         switch (SdevHeader->Type)
1403         {
1404         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1405 
1406             InfoTable = AcpiDmTableInfoSdev0;
1407             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
1408             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
1409                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
1410             break;
1411 
1412         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1413 
1414             InfoTable = AcpiDmTableInfoSdev1;
1415             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
1416             break;
1417 
1418         default:
1419 
1420             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1421             return (AE_ERROR);
1422         }
1423 
1424         /* Compile SDEV subtable body */
1425 
1426         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1427         if (ACPI_FAILURE (Status))
1428         {
1429             return (Status);
1430         }
1431 
1432         ParentTable = DtPeekSubtable ();
1433         DtInsertSubtable (ParentTable, Subtable);
1434 
1435         /* Optional data fields are appended to the main subtable body */
1436 
1437         switch (SdevHeader->Type)
1438         {
1439         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1440 
1441             /*
1442              * Device Id Offset will be be calculated differently depending on
1443              * the presence of secure access components.
1444              */
1445             Namesp->DeviceIdOffset = 0;
1446             ComponentLength = 0;
1447 
1448             /* If the secure access component exists, get the structures */
1449 
1450             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
1451             {
1452                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
1453                     &Subtable);
1454                 if (ACPI_FAILURE (Status))
1455                 {
1456                     return (Status);
1457                 }
1458                 ParentTable = DtPeekSubtable ();
1459                 DtInsertSubtable (ParentTable, Subtable);
1460 
1461                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
1462 
1463                 /* Compile a secure access component header */
1464 
1465                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
1466                     &Subtable);
1467                 if (ACPI_FAILURE (Status))
1468                 {
1469                     return (Status);
1470                 }
1471                 ParentTable = DtPeekSubtable ();
1472                 DtInsertSubtable (ParentTable, Subtable);
1473 
1474                 /* Compile the secure access component */
1475 
1476                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1477                 switch (SecureComponentHeader->Type)
1478                 {
1479                 case ACPI_SDEV_TYPE_ID_COMPONENT:
1480 
1481                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
1482                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
1483                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
1484                     break;
1485 
1486                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
1487 
1488                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
1489                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
1490                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
1491                     break;
1492 
1493                 default:
1494 
1495                     /* Any other secure component types are undefined */
1496 
1497                     return (AE_ERROR);
1498                 }
1499 
1500                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
1501                     &Subtable);
1502                 if (ACPI_FAILURE (Status))
1503                 {
1504                     return (Status);
1505                 }
1506                 ParentTable = DtPeekSubtable ();
1507                 DtInsertSubtable (ParentTable, Subtable);
1508 
1509                 SecureComponent->SecureComponentOffset =
1510                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
1511                 SecureComponent->SecureComponentLength = ComponentLength;
1512 
1513 
1514                 /*
1515                  * Add the secure component to the subtable to be added for the
1516                  * the namespace subtable's length
1517                  */
1518                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
1519             }
1520 
1521             /* Append DeviceId namespace string */
1522 
1523             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
1524                 &Subtable);
1525             if (ACPI_FAILURE (Status))
1526             {
1527                 return (Status);
1528             }
1529 
1530             if (!Subtable)
1531             {
1532                 break;
1533             }
1534 
1535             ParentTable = DtPeekSubtable ();
1536             DtInsertSubtable (ParentTable, Subtable);
1537 
1538             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
1539 
1540             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
1541 
1542             /* Append Vendor data */
1543 
1544             Namesp->VendorDataLength = 0;
1545             Namesp->VendorDataOffset = 0;
1546 
1547             if (*PFieldList)
1548             {
1549                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1550                     &Subtable);
1551                 if (ACPI_FAILURE (Status))
1552                 {
1553                     return (Status);
1554                 }
1555 
1556                 if (Subtable)
1557                 {
1558                     ParentTable = DtPeekSubtable ();
1559                     DtInsertSubtable (ParentTable, Subtable);
1560 
1561                     Namesp->VendorDataOffset =
1562                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
1563                     Namesp->VendorDataLength =
1564                         (UINT16) Subtable->Length;
1565 
1566                     /* Final size of entire namespace structure */
1567 
1568                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
1569                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
1570                 }
1571             }
1572 
1573             break;
1574 
1575         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1576 
1577             /* Append the PCIe path info first */
1578 
1579             EntryCount = 0;
1580             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
1581             {
1582                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
1583                     &Subtable);
1584                 if (ACPI_FAILURE (Status))
1585                 {
1586                     return (Status);
1587                 }
1588 
1589                 if (!Subtable)
1590                 {
1591                     DtPopSubtable ();
1592                     break;
1593                 }
1594 
1595                 ParentTable = DtPeekSubtable ();
1596                 DtInsertSubtable (ParentTable, Subtable);
1597                 EntryCount++;
1598             }
1599 
1600             /* Path offset will point immediately after the main subtable */
1601 
1602             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
1603             Pcie->PathLength = (UINT16)
1604                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
1605 
1606             /* Append the Vendor Data last */
1607 
1608             Pcie->VendorDataLength = 0;
1609             Pcie->VendorDataOffset = 0;
1610 
1611             if (*PFieldList)
1612             {
1613                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1614                     &Subtable);
1615                 if (ACPI_FAILURE (Status))
1616                 {
1617                     return (Status);
1618                 }
1619 
1620                 if (Subtable)
1621                 {
1622                     ParentTable = DtPeekSubtable ();
1623                     DtInsertSubtable (ParentTable, Subtable);
1624 
1625                     Pcie->VendorDataOffset =
1626                         Pcie->PathOffset + Pcie->PathLength;
1627                     Pcie->VendorDataLength = (UINT16)
1628                         Subtable->Length;
1629                 }
1630             }
1631 
1632             SdevHeader->Length =
1633                 sizeof (ACPI_SDEV_PCIE) +
1634                 Pcie->PathLength + Pcie->VendorDataLength;
1635             break;
1636 
1637         default:
1638 
1639             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1640             return (AE_ERROR);
1641         }
1642 
1643         DtPopSubtable ();
1644     }
1645 
1646     return (AE_OK);
1647 }
1648 
1649 
1650 /******************************************************************************
1651  *
1652  * FUNCTION:    DtCompileSlic
1653  *
1654  * PARAMETERS:  List                - Current field list pointer
1655  *
1656  * RETURN:      Status
1657  *
1658  * DESCRIPTION: Compile SLIC.
1659  *
1660  *****************************************************************************/
1661 
1662 ACPI_STATUS
1663 DtCompileSlic (
1664     void                    **List)
1665 {
1666     ACPI_STATUS             Status;
1667     DT_SUBTABLE             *Subtable;
1668     DT_SUBTABLE             *ParentTable;
1669     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1670 
1671 
1672     while (*PFieldList)
1673     {
1674         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
1675             &Subtable);
1676         if (ACPI_FAILURE (Status))
1677         {
1678             return (Status);
1679         }
1680 
1681         ParentTable = DtPeekSubtable ();
1682         DtInsertSubtable (ParentTable, Subtable);
1683         DtPushSubtable (Subtable);
1684         DtPopSubtable ();
1685     }
1686 
1687     return (AE_OK);
1688 }
1689 
1690 
1691 /******************************************************************************
1692  *
1693  * FUNCTION:    DtCompileSlit
1694  *
1695  * PARAMETERS:  List                - Current field list pointer
1696  *
1697  * RETURN:      Status
1698  *
1699  * DESCRIPTION: Compile SLIT.
1700  *
1701  *****************************************************************************/
1702 
1703 ACPI_STATUS
1704 DtCompileSlit (
1705     void                    **List)
1706 {
1707     ACPI_STATUS             Status;
1708     DT_SUBTABLE             *Subtable;
1709     DT_SUBTABLE             *ParentTable;
1710     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1711     DT_FIELD                *FieldList;
1712     DT_FIELD                *EndOfFieldList = NULL;
1713     UINT32                  Localities;
1714     UINT32                  LocalityListLength;
1715     UINT8                   *LocalityBuffer;
1716 
1717 
1718     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1719         &Subtable);
1720     if (ACPI_FAILURE (Status))
1721     {
1722         return (Status);
1723     }
1724 
1725     ParentTable = DtPeekSubtable ();
1726     DtInsertSubtable (ParentTable, Subtable);
1727 
1728     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1729     LocalityBuffer = UtLocalCalloc (Localities);
1730     LocalityListLength = 0;
1731 
1732     /* Compile each locality buffer */
1733 
1734     FieldList = *PFieldList;
1735     while (FieldList)
1736     {
1737         DtCompileBuffer (LocalityBuffer,
1738             FieldList->Value, FieldList, Localities);
1739 
1740         LocalityListLength++;
1741         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1742         DtInsertSubtable (ParentTable, Subtable);
1743         EndOfFieldList = FieldList;
1744         FieldList = FieldList->Next;
1745     }
1746 
1747     if (LocalityListLength != Localities)
1748     {
1749         sprintf(AslGbl_MsgBuffer,
1750             "Found %u entries, must match LocalityCount: %u",
1751             LocalityListLength, Localities);
1752         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
1753         ACPI_FREE (LocalityBuffer);
1754         return (AE_LIMIT);
1755     }
1756 
1757     ACPI_FREE (LocalityBuffer);
1758     return (AE_OK);
1759 }
1760 
1761 
1762 /******************************************************************************
1763  *
1764  * FUNCTION:    DtCompileSrat
1765  *
1766  * PARAMETERS:  List                - Current field list pointer
1767  *
1768  * RETURN:      Status
1769  *
1770  * DESCRIPTION: Compile SRAT.
1771  *
1772  *****************************************************************************/
1773 
1774 ACPI_STATUS
1775 DtCompileSrat (
1776     void                    **List)
1777 {
1778     ACPI_STATUS             Status;
1779     DT_SUBTABLE             *Subtable;
1780     DT_SUBTABLE             *ParentTable;
1781     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1782     DT_FIELD                *SubtableStart;
1783     ACPI_SUBTABLE_HEADER    *SratHeader;
1784     ACPI_DMTABLE_INFO       *InfoTable;
1785 
1786 
1787     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1788         &Subtable);
1789     if (ACPI_FAILURE (Status))
1790     {
1791         return (Status);
1792     }
1793 
1794     ParentTable = DtPeekSubtable ();
1795     DtInsertSubtable (ParentTable, Subtable);
1796 
1797     while (*PFieldList)
1798     {
1799         SubtableStart = *PFieldList;
1800         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1801             &Subtable);
1802         if (ACPI_FAILURE (Status))
1803         {
1804             return (Status);
1805         }
1806 
1807         ParentTable = DtPeekSubtable ();
1808         DtInsertSubtable (ParentTable, Subtable);
1809         DtPushSubtable (Subtable);
1810 
1811         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1812 
1813         switch (SratHeader->Type)
1814         {
1815         case ACPI_SRAT_TYPE_CPU_AFFINITY:
1816 
1817             InfoTable = AcpiDmTableInfoSrat0;
1818             break;
1819 
1820         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1821 
1822             InfoTable = AcpiDmTableInfoSrat1;
1823             break;
1824 
1825         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1826 
1827             InfoTable = AcpiDmTableInfoSrat2;
1828             break;
1829 
1830         case ACPI_SRAT_TYPE_GICC_AFFINITY:
1831 
1832             InfoTable = AcpiDmTableInfoSrat3;
1833             break;
1834 
1835         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
1836 
1837             InfoTable = AcpiDmTableInfoSrat4;
1838             break;
1839 
1840         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
1841 
1842             InfoTable = AcpiDmTableInfoSrat5;
1843             break;
1844 
1845         default:
1846 
1847             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1848             return (AE_ERROR);
1849         }
1850 
1851         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1852         if (ACPI_FAILURE (Status))
1853         {
1854             return (Status);
1855         }
1856 
1857         ParentTable = DtPeekSubtable ();
1858         DtInsertSubtable (ParentTable, Subtable);
1859         DtPopSubtable ();
1860     }
1861 
1862     return (AE_OK);
1863 }
1864 
1865 
1866 /******************************************************************************
1867  *
1868  * FUNCTION:    DtCompileStao
1869  *
1870  * PARAMETERS:  PFieldList          - Current field list pointer
1871  *
1872  * RETURN:      Status
1873  *
1874  * DESCRIPTION: Compile STAO.
1875  *
1876  *****************************************************************************/
1877 
1878 ACPI_STATUS
1879 DtCompileStao (
1880     void                    **List)
1881 {
1882     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1883     DT_SUBTABLE             *Subtable;
1884     DT_SUBTABLE             *ParentTable;
1885     ACPI_STATUS             Status;
1886 
1887 
1888     /* Compile the main table */
1889 
1890     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
1891         &Subtable);
1892     if (ACPI_FAILURE (Status))
1893     {
1894         return (Status);
1895     }
1896 
1897     ParentTable = DtPeekSubtable ();
1898     DtInsertSubtable (ParentTable, Subtable);
1899 
1900     /* Compile each ASCII namestring as a subtable */
1901 
1902     while (*PFieldList)
1903     {
1904         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
1905             &Subtable);
1906         if (ACPI_FAILURE (Status))
1907         {
1908             return (Status);
1909         }
1910 
1911         ParentTable = DtPeekSubtable ();
1912         DtInsertSubtable (ParentTable, Subtable);
1913     }
1914 
1915     return (AE_OK);
1916 }
1917 
1918 
1919 /******************************************************************************
1920  *
1921  * FUNCTION:    DtCompileTcpa
1922  *
1923  * PARAMETERS:  PFieldList          - Current field list pointer
1924  *
1925  * RETURN:      Status
1926  *
1927  * DESCRIPTION: Compile TCPA.
1928  *
1929  *****************************************************************************/
1930 
1931 ACPI_STATUS
1932 DtCompileTcpa (
1933     void                    **List)
1934 {
1935     DT_FIELD                **PFieldList = (DT_FIELD **) List;
1936     DT_SUBTABLE             *Subtable;
1937     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
1938     DT_SUBTABLE             *ParentTable;
1939     ACPI_STATUS             Status;
1940 
1941 
1942     /* Compile the main table */
1943 
1944     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
1945         &Subtable);
1946     if (ACPI_FAILURE (Status))
1947     {
1948         return (Status);
1949     }
1950 
1951     ParentTable = DtPeekSubtable ();
1952     DtInsertSubtable (ParentTable, Subtable);
1953 
1954     /*
1955      * Examine the PlatformClass field to determine the table type.
1956      * Either a client or server table. Only one.
1957      */
1958     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
1959 
1960     switch (TcpaHeader->PlatformClass)
1961     {
1962     case ACPI_TCPA_CLIENT_TABLE:
1963 
1964         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
1965             &Subtable);
1966         break;
1967 
1968     case ACPI_TCPA_SERVER_TABLE:
1969 
1970         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
1971             &Subtable);
1972         break;
1973 
1974     default:
1975 
1976         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
1977             TcpaHeader->PlatformClass);
1978         Status = AE_ERROR;
1979         break;
1980     }
1981 
1982     ParentTable = DtPeekSubtable ();
1983     DtInsertSubtable (ParentTable, Subtable);
1984     return (Status);
1985 }
1986 
1987 
1988 /******************************************************************************
1989  *
1990  * FUNCTION:    DtCompileTpm2Rev3
1991  *
1992  * PARAMETERS:  PFieldList          - Current field list pointer
1993  *
1994  * RETURN:      Status
1995  *
1996  * DESCRIPTION: Compile TPM2 revision 3
1997  *
1998  *****************************************************************************/
1999 static ACPI_STATUS
2000 DtCompileTpm2Rev3 (
2001     void                    **List)
2002 {
2003     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2004     DT_SUBTABLE             *Subtable;
2005     ACPI_TABLE_TPM23        *Tpm23Header;
2006     DT_SUBTABLE             *ParentTable;
2007     ACPI_STATUS             Status = AE_OK;
2008 
2009 
2010     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
2011         &Subtable);
2012 
2013     ParentTable = DtPeekSubtable ();
2014     DtInsertSubtable (ParentTable, Subtable);
2015     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
2016 
2017     /* Subtable type depends on the StartMethod */
2018 
2019     switch (Tpm23Header->StartMethod)
2020     {
2021     case ACPI_TPM23_ACPI_START_METHOD:
2022 
2023         /* Subtable specific to to ARM_SMC */
2024 
2025         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
2026             &Subtable);
2027         if (ACPI_FAILURE (Status))
2028         {
2029             return (Status);
2030         }
2031 
2032         ParentTable = DtPeekSubtable ();
2033         DtInsertSubtable (ParentTable, Subtable);
2034         break;
2035 
2036     default:
2037         break;
2038     }
2039 
2040     return (Status);
2041 }
2042 
2043 
2044 /******************************************************************************
2045  *
2046  * FUNCTION:    DtCompileTpm2
2047  *
2048  * PARAMETERS:  PFieldList          - Current field list pointer
2049  *
2050  * RETURN:      Status
2051  *
2052  * DESCRIPTION: Compile TPM2.
2053  *
2054  *****************************************************************************/
2055 
2056 ACPI_STATUS
2057 DtCompileTpm2 (
2058     void                    **List)
2059 {
2060     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2061     DT_SUBTABLE             *Subtable;
2062     ACPI_TABLE_TPM2         *Tpm2Header;
2063     DT_SUBTABLE             *ParentTable;
2064     ACPI_STATUS             Status = AE_OK;
2065     ACPI_TABLE_HEADER       *Header;
2066 
2067 
2068     ParentTable = DtPeekSubtable ();
2069 
2070     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2071 
2072     if (Header->Revision == 3)
2073     {
2074         return (DtCompileTpm2Rev3 (List));
2075     }
2076 
2077     /* Compile the main table */
2078 
2079     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
2080         &Subtable);
2081     if (ACPI_FAILURE (Status))
2082     {
2083         return (Status);
2084     }
2085 
2086     ParentTable = DtPeekSubtable ();
2087     DtInsertSubtable (ParentTable, Subtable);
2088 
2089     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
2090 
2091     /* Method parameters */
2092     /* Optional: Log area minimum length */
2093     /* Optional: Log area start address */
2094     /* TBD: Optional fields above not fully implemented (not optional at this time) */
2095 
2096     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
2097         &Subtable);
2098     if (ACPI_FAILURE (Status))
2099     {
2100         return (Status);
2101     }
2102 
2103     ParentTable = DtPeekSubtable ();
2104     DtInsertSubtable (ParentTable, Subtable);
2105 
2106 
2107     /* Subtable type depends on the StartMethod */
2108 
2109     switch (Tpm2Header->StartMethod)
2110     {
2111     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
2112 
2113         /* Subtable specific to to ARM_SMC */
2114 
2115         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
2116             &Subtable);
2117         if (ACPI_FAILURE (Status))
2118         {
2119             return (Status);
2120         }
2121 
2122         ParentTable = DtPeekSubtable ();
2123         DtInsertSubtable (ParentTable, Subtable);
2124         break;
2125 
2126     case ACPI_TPM2_START_METHOD:
2127     case ACPI_TPM2_MEMORY_MAPPED:
2128     case ACPI_TPM2_COMMAND_BUFFER:
2129     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
2130         break;
2131 
2132     case ACPI_TPM2_RESERVED1:
2133     case ACPI_TPM2_RESERVED3:
2134     case ACPI_TPM2_RESERVED4:
2135     case ACPI_TPM2_RESERVED5:
2136     case ACPI_TPM2_RESERVED9:
2137     case ACPI_TPM2_RESERVED10:
2138 
2139         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
2140             Tpm2Header->StartMethod);
2141         Status = AE_ERROR;
2142         break;
2143 
2144     case ACPI_TPM2_NOT_ALLOWED:
2145     default:
2146 
2147         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
2148             Tpm2Header->StartMethod);
2149         Status = AE_ERROR;
2150         break;
2151     }
2152 
2153     return (Status);
2154 }
2155 
2156 
2157 /******************************************************************************
2158  *
2159  * FUNCTION:    DtGetGenericTableInfo
2160  *
2161  * PARAMETERS:  Name                - Generic type name
2162  *
2163  * RETURN:      Info entry
2164  *
2165  * DESCRIPTION: Obtain table info for a generic name entry
2166  *
2167  *****************************************************************************/
2168 
2169 ACPI_DMTABLE_INFO *
2170 DtGetGenericTableInfo (
2171     char                    *Name)
2172 {
2173     ACPI_DMTABLE_INFO       *Info;
2174     UINT32                  i;
2175 
2176 
2177     if (!Name)
2178     {
2179         return (NULL);
2180     }
2181 
2182     /* Search info table for name match */
2183 
2184     for (i = 0; ; i++)
2185     {
2186         Info = AcpiDmTableInfoGeneric[i];
2187         if (Info->Opcode == ACPI_DMT_EXIT)
2188         {
2189             Info = NULL;
2190             break;
2191         }
2192 
2193         /* Use caseless compare for generic keywords */
2194 
2195         if (!AcpiUtStricmp (Name, Info->Name))
2196         {
2197             break;
2198         }
2199     }
2200 
2201     return (Info);
2202 }
2203 
2204 
2205 /******************************************************************************
2206  *
2207  * FUNCTION:    DtCompileUefi
2208  *
2209  * PARAMETERS:  List                - Current field list pointer
2210  *
2211  * RETURN:      Status
2212  *
2213  * DESCRIPTION: Compile UEFI.
2214  *
2215  *****************************************************************************/
2216 
2217 ACPI_STATUS
2218 DtCompileUefi (
2219     void                    **List)
2220 {
2221     ACPI_STATUS             Status;
2222     DT_SUBTABLE             *Subtable;
2223     DT_SUBTABLE             *ParentTable;
2224     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2225     UINT16                  *DataOffset;
2226 
2227 
2228     /* Compile the predefined portion of the UEFI table */
2229 
2230     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2231         &Subtable);
2232     if (ACPI_FAILURE (Status))
2233     {
2234         return (Status);
2235     }
2236 
2237     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2238     *DataOffset = sizeof (ACPI_TABLE_UEFI);
2239 
2240     ParentTable = DtPeekSubtable ();
2241     DtInsertSubtable (ParentTable, Subtable);
2242 
2243     /*
2244      * Compile the "generic" portion of the UEFI table. This
2245      * part of the table is not predefined and any of the generic
2246      * operators may be used.
2247      */
2248     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
2249     return (AE_OK);
2250 }
2251 
2252 
2253 /******************************************************************************
2254  *
2255  * FUNCTION:    DtCompileViot
2256  *
2257  * PARAMETERS:  List                - Current field list pointer
2258  *
2259  * RETURN:      Status
2260  *
2261  * DESCRIPTION: Compile VIOT.
2262  *
2263  *****************************************************************************/
2264 
2265 ACPI_STATUS
2266 DtCompileViot (
2267     void                    **List)
2268 {
2269     ACPI_STATUS             Status;
2270     DT_SUBTABLE             *Subtable;
2271     DT_SUBTABLE             *ParentTable;
2272     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2273     DT_FIELD                *SubtableStart;
2274     ACPI_TABLE_VIOT         *Viot;
2275     ACPI_VIOT_HEADER        *ViotHeader;
2276     ACPI_DMTABLE_INFO       *InfoTable;
2277     UINT16                  NodeCount;
2278 
2279     ParentTable = DtPeekSubtable ();
2280 
2281     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
2282     if (ACPI_FAILURE (Status))
2283     {
2284         return (Status);
2285     }
2286     DtInsertSubtable (ParentTable, Subtable);
2287 
2288     /*
2289      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2290      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2291      */
2292     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
2293         sizeof (ACPI_TABLE_HEADER));
2294 
2295     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
2296 
2297     NodeCount = 0;
2298     while (*PFieldList) {
2299         SubtableStart = *PFieldList;
2300         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
2301             &Subtable);
2302         if (ACPI_FAILURE (Status))
2303         {
2304             return (Status);
2305         }
2306 
2307         ParentTable = DtPeekSubtable ();
2308         DtInsertSubtable (ParentTable, Subtable);
2309         DtPushSubtable (Subtable);
2310 
2311         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
2312 
2313         switch (ViotHeader->Type)
2314         {
2315         case ACPI_VIOT_NODE_PCI_RANGE:
2316 
2317             InfoTable = AcpiDmTableInfoViot1;
2318             break;
2319 
2320         case ACPI_VIOT_NODE_MMIO:
2321 
2322             InfoTable = AcpiDmTableInfoViot2;
2323             break;
2324 
2325         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
2326 
2327             InfoTable = AcpiDmTableInfoViot3;
2328             break;
2329 
2330         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
2331 
2332             InfoTable = AcpiDmTableInfoViot4;
2333             break;
2334 
2335         default:
2336 
2337             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
2338             return (AE_ERROR);
2339         }
2340 
2341         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2342         if (ACPI_FAILURE (Status))
2343         {
2344             return (Status);
2345         }
2346 
2347         ParentTable = DtPeekSubtable ();
2348         DtInsertSubtable (ParentTable, Subtable);
2349         DtPopSubtable ();
2350         NodeCount++;
2351     }
2352 
2353     Viot->NodeCount = NodeCount;
2354     return (AE_OK);
2355 }
2356 
2357 
2358 /******************************************************************************
2359  *
2360  * FUNCTION:    DtCompileWdat
2361  *
2362  * PARAMETERS:  List                - Current field list pointer
2363  *
2364  * RETURN:      Status
2365  *
2366  * DESCRIPTION: Compile WDAT.
2367  *
2368  *****************************************************************************/
2369 
2370 ACPI_STATUS
2371 DtCompileWdat (
2372     void                    **List)
2373 {
2374     ACPI_STATUS             Status;
2375 
2376 
2377     Status = DtCompileTwoSubtables (List,
2378         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2379     return (Status);
2380 }
2381 
2382 
2383 /******************************************************************************
2384  *
2385  * FUNCTION:    DtCompileWpbt
2386  *
2387  * PARAMETERS:  List                - Current field list pointer
2388  *
2389  * RETURN:      Status
2390  *
2391  * DESCRIPTION: Compile WPBT.
2392  *
2393  *****************************************************************************/
2394 
2395 ACPI_STATUS
2396 DtCompileWpbt (
2397     void                    **List)
2398 {
2399     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2400     DT_SUBTABLE             *Subtable;
2401     DT_SUBTABLE             *ParentTable;
2402     ACPI_TABLE_WPBT         *Table;
2403     ACPI_STATUS             Status;
2404     UINT16                  Length;
2405 
2406 
2407     /* Compile the main table */
2408 
2409     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
2410         &Subtable);
2411     if (ACPI_FAILURE (Status))
2412     {
2413         return (Status);
2414     }
2415 
2416     ParentTable = DtPeekSubtable ();
2417     DtInsertSubtable (ParentTable, Subtable);
2418 
2419     /* Compile the argument list subtable */
2420 
2421     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
2422         &Subtable);
2423     if (ACPI_FAILURE (Status))
2424     {
2425         return (Status);
2426     }
2427 
2428     /* Extract the length of the Arguments buffer, insert into main table */
2429 
2430     Length = (UINT16) Subtable->TotalLength;
2431     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
2432     Table->ArgumentsLength = Length;
2433 
2434     ParentTable = DtPeekSubtable ();
2435     DtInsertSubtable (ParentTable, Subtable);
2436     return (AE_OK);
2437 }
2438 
2439 
2440 /******************************************************************************
2441  *
2442  * FUNCTION:    DtCompileXsdt
2443  *
2444  * PARAMETERS:  List                - Current field list pointer
2445  *
2446  * RETURN:      Status
2447  *
2448  * DESCRIPTION: Compile XSDT.
2449  *
2450  *****************************************************************************/
2451 
2452 ACPI_STATUS
2453 DtCompileXsdt (
2454     void                    **List)
2455 {
2456     DT_SUBTABLE             *Subtable;
2457     DT_SUBTABLE             *ParentTable;
2458     DT_FIELD                *FieldList = *(DT_FIELD **) List;
2459     UINT64                  Address;
2460 
2461 
2462     ParentTable = DtPeekSubtable ();
2463 
2464     while (FieldList)
2465     {
2466         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2467 
2468         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2469         DtInsertSubtable (ParentTable, Subtable);
2470         FieldList = FieldList->Next;
2471     }
2472 
2473     return (AE_OK);
2474 }
2475 
2476 
2477 /******************************************************************************
2478  *
2479  * FUNCTION:    DtCompileGeneric
2480  *
2481  * PARAMETERS:  List                - Current field list pointer
2482  *              Name                - Field name to end generic compiling
2483  *              Length              - Compiled table length to return
2484  *
2485  * RETURN:      Status
2486  *
2487  * DESCRIPTION: Compile generic unknown table.
2488  *
2489  *****************************************************************************/
2490 
2491 ACPI_STATUS
2492 DtCompileGeneric (
2493     void                    **List,
2494     char                    *Name,
2495     UINT32                  *Length)
2496 {
2497     ACPI_STATUS             Status;
2498     DT_SUBTABLE             *Subtable;
2499     DT_SUBTABLE             *ParentTable;
2500     DT_FIELD                **PFieldList = (DT_FIELD **) List;
2501     ACPI_DMTABLE_INFO       *Info;
2502 
2503 
2504     ParentTable = DtPeekSubtable ();
2505 
2506     /*
2507      * Compile the "generic" portion of the table. This
2508      * part of the table is not predefined and any of the generic
2509      * operators may be used.
2510      */
2511 
2512     /* Find any and all labels in the entire generic portion */
2513 
2514     DtDetectAllLabels (*PFieldList);
2515 
2516     /* Now we can actually compile the parse tree */
2517 
2518     if (Length && *Length)
2519     {
2520         *Length = 0;
2521     }
2522     while (*PFieldList)
2523     {
2524         if (Name && !strcmp ((*PFieldList)->Name, Name))
2525         {
2526             break;
2527         }
2528 
2529         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2530         if (!Info)
2531         {
2532             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
2533                 (*PFieldList)->Name);
2534             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2535                 (*PFieldList), AslGbl_MsgBuffer);
2536 
2537             *PFieldList = (*PFieldList)->Next;
2538             continue;
2539         }
2540 
2541         Status = DtCompileTable (PFieldList, Info,
2542             &Subtable);
2543         if (ACPI_SUCCESS (Status))
2544         {
2545             DtInsertSubtable (ParentTable, Subtable);
2546             if (Length)
2547             {
2548                 *Length += Subtable->Length;
2549             }
2550         }
2551         else
2552         {
2553             *PFieldList = (*PFieldList)->Next;
2554 
2555             if (Status == AE_NOT_FOUND)
2556             {
2557                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
2558                     (*PFieldList)->Name);
2559                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2560                     (*PFieldList), AslGbl_MsgBuffer);
2561             }
2562         }
2563     }
2564 
2565     return (AE_OK);
2566 }
2567