dttable2.c revision 1.1.1.11 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