dttable2.c revision 1.1.1.6 1 /******************************************************************************
2 *
3 * Module Name: dttable2.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 /* Compile all complex data tables, signatures starting with 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 default:
262
263 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
264 return (AE_ERROR);
265 }
266
267 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
268 if (ACPI_FAILURE (Status))
269 {
270 return (Status);
271 }
272
273 ParentTable = DtPeekSubtable ();
274 DtInsertSubtable (ParentTable, Subtable);
275 DtPopSubtable ();
276 }
277
278 return (AE_OK);
279 }
280
281
282 /******************************************************************************
283 *
284 * FUNCTION: DtCompileMcfg
285 *
286 * PARAMETERS: List - Current field list pointer
287 *
288 * RETURN: Status
289 *
290 * DESCRIPTION: Compile MCFG.
291 *
292 *****************************************************************************/
293
294 ACPI_STATUS
295 DtCompileMcfg (
296 void **List)
297 {
298 ACPI_STATUS Status;
299
300
301 Status = DtCompileTwoSubtables (List,
302 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
303 return (Status);
304 }
305
306
307 /******************************************************************************
308 *
309 * FUNCTION: DtCompileMpst
310 *
311 * PARAMETERS: List - Current field list pointer
312 *
313 * RETURN: Status
314 *
315 * DESCRIPTION: Compile MPST.
316 *
317 *****************************************************************************/
318
319 ACPI_STATUS
320 DtCompileMpst (
321 void **List)
322 {
323 ACPI_STATUS Status;
324 DT_SUBTABLE *Subtable;
325 DT_SUBTABLE *ParentTable;
326 DT_FIELD **PFieldList = (DT_FIELD **) List;
327 ACPI_MPST_CHANNEL *MpstChannelInfo;
328 ACPI_MPST_POWER_NODE *MpstPowerNode;
329 ACPI_MPST_DATA_HDR *MpstDataHeader;
330 UINT16 SubtableCount;
331 UINT32 PowerStateCount;
332 UINT32 ComponentCount;
333
334
335 /* Main table */
336
337 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable);
338 if (ACPI_FAILURE (Status))
339 {
340 return (Status);
341 }
342
343 ParentTable = DtPeekSubtable ();
344 DtInsertSubtable (ParentTable, Subtable);
345 DtPushSubtable (Subtable);
346
347 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
348 SubtableCount = MpstChannelInfo->PowerNodeCount;
349
350 while (*PFieldList && SubtableCount)
351 {
352 /* Subtable: Memory Power Node(s) */
353
354 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
355 &Subtable);
356 if (ACPI_FAILURE (Status))
357 {
358 return (Status);
359 }
360
361 ParentTable = DtPeekSubtable ();
362 DtInsertSubtable (ParentTable, Subtable);
363 DtPushSubtable (Subtable);
364
365 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
366 PowerStateCount = MpstPowerNode->NumPowerStates;
367 ComponentCount = MpstPowerNode->NumPhysicalComponents;
368
369 ParentTable = DtPeekSubtable ();
370
371 /* Sub-subtables - Memory Power State Structure(s) */
372
373 while (*PFieldList && PowerStateCount)
374 {
375 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
376 &Subtable);
377 if (ACPI_FAILURE (Status))
378 {
379 return (Status);
380 }
381
382 DtInsertSubtable (ParentTable, Subtable);
383 PowerStateCount--;
384 }
385
386 /* Sub-subtables - Physical Component ID Structure(s) */
387
388 while (*PFieldList && ComponentCount)
389 {
390 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
391 &Subtable);
392 if (ACPI_FAILURE (Status))
393 {
394 return (Status);
395 }
396
397 DtInsertSubtable (ParentTable, Subtable);
398 ComponentCount--;
399 }
400
401 SubtableCount--;
402 DtPopSubtable ();
403 }
404
405 /* Subtable: Count of Memory Power State Characteristic structures */
406
407 DtPopSubtable ();
408
409 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable);
410 if (ACPI_FAILURE (Status))
411 {
412 return (Status);
413 }
414
415 ParentTable = DtPeekSubtable ();
416 DtInsertSubtable (ParentTable, Subtable);
417 DtPushSubtable (Subtable);
418
419 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
420 SubtableCount = MpstDataHeader->CharacteristicsCount;
421
422 ParentTable = DtPeekSubtable ();
423
424 /* Subtable: Memory Power State Characteristics structure(s) */
425
426 while (*PFieldList && SubtableCount)
427 {
428 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
429 &Subtable);
430 if (ACPI_FAILURE (Status))
431 {
432 return (Status);
433 }
434
435 DtInsertSubtable (ParentTable, Subtable);
436 SubtableCount--;
437 }
438
439 DtPopSubtable ();
440 return (AE_OK);
441 }
442
443
444 /******************************************************************************
445 *
446 * FUNCTION: DtCompileMsct
447 *
448 * PARAMETERS: List - Current field list pointer
449 *
450 * RETURN: Status
451 *
452 * DESCRIPTION: Compile MSCT.
453 *
454 *****************************************************************************/
455
456 ACPI_STATUS
457 DtCompileMsct (
458 void **List)
459 {
460 ACPI_STATUS Status;
461
462
463 Status = DtCompileTwoSubtables (List,
464 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
465 return (Status);
466 }
467
468
469 /******************************************************************************
470 *
471 * FUNCTION: DtCompileMtmr
472 *
473 * PARAMETERS: List - Current field list pointer
474 *
475 * RETURN: Status
476 *
477 * DESCRIPTION: Compile MTMR.
478 *
479 *****************************************************************************/
480
481 ACPI_STATUS
482 DtCompileMtmr (
483 void **List)
484 {
485 ACPI_STATUS Status;
486
487
488 Status = DtCompileTwoSubtables (List,
489 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
490 return (Status);
491 }
492
493
494 /******************************************************************************
495 *
496 * FUNCTION: DtCompileNfit
497 *
498 * PARAMETERS: List - Current field list pointer
499 *
500 * RETURN: Status
501 *
502 * DESCRIPTION: Compile NFIT.
503 *
504 *****************************************************************************/
505
506 ACPI_STATUS
507 DtCompileNfit (
508 void **List)
509 {
510 ACPI_STATUS Status;
511 DT_SUBTABLE *Subtable;
512 DT_SUBTABLE *ParentTable;
513 DT_FIELD **PFieldList = (DT_FIELD **) List;
514 DT_FIELD *SubtableStart;
515 ACPI_NFIT_HEADER *NfitHeader;
516 ACPI_DMTABLE_INFO *InfoTable;
517 UINT32 Count;
518 ACPI_NFIT_INTERLEAVE *Interleave = NULL;
519 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
520
521
522 /* Main table */
523
524 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
525 &Subtable);
526 if (ACPI_FAILURE (Status))
527 {
528 return (Status);
529 }
530
531 ParentTable = DtPeekSubtable ();
532 DtInsertSubtable (ParentTable, Subtable);
533 DtPushSubtable (Subtable);
534
535 /* Subtables */
536
537 while (*PFieldList)
538 {
539 SubtableStart = *PFieldList;
540 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
541 &Subtable);
542 if (ACPI_FAILURE (Status))
543 {
544 return (Status);
545 }
546
547 ParentTable = DtPeekSubtable ();
548 DtInsertSubtable (ParentTable, Subtable);
549 DtPushSubtable (Subtable);
550
551 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
552
553 switch (NfitHeader->Type)
554 {
555 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
556
557 InfoTable = AcpiDmTableInfoNfit0;
558 break;
559
560 case ACPI_NFIT_TYPE_MEMORY_MAP:
561
562 InfoTable = AcpiDmTableInfoNfit1;
563 break;
564
565 case ACPI_NFIT_TYPE_INTERLEAVE:
566
567 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
568 InfoTable = AcpiDmTableInfoNfit2;
569 break;
570
571 case ACPI_NFIT_TYPE_SMBIOS:
572
573 InfoTable = AcpiDmTableInfoNfit3;
574 break;
575
576 case ACPI_NFIT_TYPE_CONTROL_REGION:
577
578 InfoTable = AcpiDmTableInfoNfit4;
579 break;
580
581 case ACPI_NFIT_TYPE_DATA_REGION:
582
583 InfoTable = AcpiDmTableInfoNfit5;
584 break;
585
586 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
587
588 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
589 InfoTable = AcpiDmTableInfoNfit6;
590 break;
591
592 case ACPI_NFIT_TYPE_CAPABILITIES:
593
594 InfoTable = AcpiDmTableInfoNfit7;
595 break;
596
597 default:
598
599 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
600 return (AE_ERROR);
601 }
602
603 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
604 if (ACPI_FAILURE (Status))
605 {
606 return (Status);
607 }
608
609 ParentTable = DtPeekSubtable ();
610 DtInsertSubtable (ParentTable, Subtable);
611 DtPopSubtable ();
612
613 switch (NfitHeader->Type)
614 {
615 case ACPI_NFIT_TYPE_INTERLEAVE:
616
617 Count = 0;
618 DtPushSubtable (Subtable);
619 while (*PFieldList)
620 {
621 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
622 &Subtable);
623 if (ACPI_FAILURE (Status))
624 {
625 return (Status);
626 }
627
628 if (!Subtable)
629 {
630 DtPopSubtable ();
631 break;
632 }
633
634 ParentTable = DtPeekSubtable ();
635 DtInsertSubtable (ParentTable, Subtable);
636 Count++;
637 }
638
639 Interleave->LineCount = Count;
640 break;
641
642 case ACPI_NFIT_TYPE_SMBIOS:
643
644 if (*PFieldList)
645 {
646 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
647 &Subtable);
648 if (ACPI_FAILURE (Status))
649 {
650 return (Status);
651 }
652
653 if (Subtable)
654 {
655 DtInsertSubtable (ParentTable, Subtable);
656 }
657 }
658 break;
659
660 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
661
662 Count = 0;
663 DtPushSubtable (Subtable);
664 while (*PFieldList)
665 {
666 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
667 &Subtable);
668 if (ACPI_FAILURE (Status))
669 {
670 return (Status);
671 }
672
673 if (!Subtable)
674 {
675 DtPopSubtable ();
676 break;
677 }
678
679 ParentTable = DtPeekSubtable ();
680 DtInsertSubtable (ParentTable, Subtable);
681 Count++;
682 }
683
684 Hint->HintCount = (UINT16) Count;
685 break;
686
687 default:
688 break;
689 }
690 }
691
692 return (AE_OK);
693 }
694
695
696 /******************************************************************************
697 *
698 * FUNCTION: DtCompilePcct
699 *
700 * PARAMETERS: List - Current field list pointer
701 *
702 * RETURN: Status
703 *
704 * DESCRIPTION: Compile PCCT.
705 *
706 *****************************************************************************/
707
708 ACPI_STATUS
709 DtCompilePcct (
710 void **List)
711 {
712 ACPI_STATUS Status;
713 DT_SUBTABLE *Subtable;
714 DT_SUBTABLE *ParentTable;
715 DT_FIELD **PFieldList = (DT_FIELD **) List;
716 DT_FIELD *SubtableStart;
717 ACPI_SUBTABLE_HEADER *PcctHeader;
718 ACPI_DMTABLE_INFO *InfoTable;
719
720
721 /* Main table */
722
723 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
724 &Subtable);
725 if (ACPI_FAILURE (Status))
726 {
727 return (Status);
728 }
729
730 ParentTable = DtPeekSubtable ();
731 DtInsertSubtable (ParentTable, Subtable);
732
733 /* Subtables */
734
735 while (*PFieldList)
736 {
737 SubtableStart = *PFieldList;
738 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
739 &Subtable);
740 if (ACPI_FAILURE (Status))
741 {
742 return (Status);
743 }
744
745 ParentTable = DtPeekSubtable ();
746 DtInsertSubtable (ParentTable, Subtable);
747 DtPushSubtable (Subtable);
748
749 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
750
751 switch (PcctHeader->Type)
752 {
753 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
754
755 InfoTable = AcpiDmTableInfoPcct0;
756 break;
757
758 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
759
760 InfoTable = AcpiDmTableInfoPcct1;
761 break;
762
763 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
764
765 InfoTable = AcpiDmTableInfoPcct2;
766 break;
767
768 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
769
770 InfoTable = AcpiDmTableInfoPcct3;
771 break;
772
773 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
774
775 InfoTable = AcpiDmTableInfoPcct4;
776 break;
777
778 default:
779
780 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
781 return (AE_ERROR);
782 }
783
784 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
785 if (ACPI_FAILURE (Status))
786 {
787 return (Status);
788 }
789
790 ParentTable = DtPeekSubtable ();
791 DtInsertSubtable (ParentTable, Subtable);
792 DtPopSubtable ();
793 }
794
795 return (AE_OK);
796 }
797
798
799 /******************************************************************************
800 *
801 * FUNCTION: DtCompilePdtt
802 *
803 * PARAMETERS: List - Current field list pointer
804 *
805 * RETURN: Status
806 *
807 * DESCRIPTION: Compile PDTT.
808 *
809 *****************************************************************************/
810
811 ACPI_STATUS
812 DtCompilePdtt (
813 void **List)
814 {
815 ACPI_STATUS Status;
816 DT_SUBTABLE *Subtable;
817 DT_SUBTABLE *ParentTable;
818 DT_FIELD **PFieldList = (DT_FIELD **) List;
819 ACPI_TABLE_PDTT *PdttHeader;
820 UINT32 Count = 0;
821
822
823 /* Main table */
824
825 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
826 if (ACPI_FAILURE (Status))
827 {
828 return (Status);
829 }
830
831 ParentTable = DtPeekSubtable ();
832 DtInsertSubtable (ParentTable, Subtable);
833
834 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
835 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
836
837 /* There is only one type of subtable at this time, no need to decode */
838
839 while (*PFieldList)
840 {
841 /* List of subchannel IDs, each 2 bytes */
842
843 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
844 &Subtable);
845 if (ACPI_FAILURE (Status))
846 {
847 return (Status);
848 }
849
850 DtInsertSubtable (ParentTable, Subtable);
851 Count++;
852 }
853
854 PdttHeader->TriggerCount = (UINT8) Count;
855 return (AE_OK);
856 }
857
858
859 /******************************************************************************
860 *
861 * FUNCTION: DtCompilePmtt
862 *
863 * PARAMETERS: List - Current field list pointer
864 *
865 * RETURN: Status
866 *
867 * DESCRIPTION: Compile PMTT.
868 *
869 *****************************************************************************/
870
871 ACPI_STATUS
872 DtCompilePmtt (
873 void **List)
874 {
875 ACPI_STATUS Status;
876 DT_SUBTABLE *Subtable;
877 DT_SUBTABLE *ParentTable;
878 DT_FIELD **PFieldList = (DT_FIELD **) List;
879 DT_FIELD *SubtableStart;
880 ACPI_PMTT_HEADER *PmttHeader;
881 ACPI_PMTT_CONTROLLER *PmttController;
882 UINT16 DomainCount;
883 UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET;
884
885
886 /* Main table */
887
888 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
889 if (ACPI_FAILURE (Status))
890 {
891 return (Status);
892 }
893
894 ParentTable = DtPeekSubtable ();
895 DtInsertSubtable (ParentTable, Subtable);
896 DtPushSubtable (Subtable);
897
898 while (*PFieldList)
899 {
900 SubtableStart = *PFieldList;
901 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
902 &Subtable);
903 if (ACPI_FAILURE (Status))
904 {
905 return (Status);
906 }
907
908 PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
909 while (PrevType >= PmttHeader->Type)
910 {
911 DtPopSubtable ();
912
913 if (PrevType == ACPI_PMTT_TYPE_SOCKET)
914 {
915 break;
916 }
917
918 PrevType--;
919 }
920
921 PrevType = PmttHeader->Type;
922
923 ParentTable = DtPeekSubtable ();
924 DtInsertSubtable (ParentTable, Subtable);
925 DtPushSubtable (Subtable);
926
927 switch (PmttHeader->Type)
928 {
929 case ACPI_PMTT_TYPE_SOCKET:
930
931 /* Subtable: Socket Structure */
932
933 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
934 &Subtable);
935 if (ACPI_FAILURE (Status))
936 {
937 return (Status);
938 }
939
940 ParentTable = DtPeekSubtable ();
941 DtInsertSubtable (ParentTable, Subtable);
942 break;
943
944 case ACPI_PMTT_TYPE_CONTROLLER:
945
946 /* Subtable: Memory Controller Structure */
947
948 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
949 &Subtable);
950 if (ACPI_FAILURE (Status))
951 {
952 return (Status);
953 }
954
955 ParentTable = DtPeekSubtable ();
956 DtInsertSubtable (ParentTable, Subtable);
957
958 PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
959 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
960 DomainCount = PmttController->DomainCount;
961
962 while (DomainCount)
963 {
964 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
965 &Subtable);
966 if (ACPI_FAILURE (Status))
967 {
968 return (Status);
969 }
970
971 DtInsertSubtable (ParentTable, Subtable);
972 DomainCount--;
973 }
974 break;
975
976 case ACPI_PMTT_TYPE_DIMM:
977
978 /* Subtable: Physical Component Structure */
979
980 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
981 &Subtable);
982 if (ACPI_FAILURE (Status))
983 {
984 return (Status);
985 }
986
987 ParentTable = DtPeekSubtable ();
988 DtInsertSubtable (ParentTable, Subtable);
989 break;
990
991 default:
992
993 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
994 return (AE_ERROR);
995 }
996 }
997
998 return (Status);
999 }
1000
1001
1002 /******************************************************************************
1003 *
1004 * FUNCTION: DtCompilePptt
1005 *
1006 * PARAMETERS: List - Current field list pointer
1007 *
1008 * RETURN: Status
1009 *
1010 * DESCRIPTION: Compile PPTT.
1011 *
1012 *****************************************************************************/
1013
1014 ACPI_STATUS
1015 DtCompilePptt (
1016 void **List)
1017 {
1018 ACPI_STATUS Status;
1019 ACPI_SUBTABLE_HEADER *PpttHeader;
1020 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL;
1021 DT_SUBTABLE *Subtable;
1022 DT_SUBTABLE *ParentTable;
1023 ACPI_DMTABLE_INFO *InfoTable;
1024 DT_FIELD **PFieldList = (DT_FIELD **) List;
1025 DT_FIELD *SubtableStart;
1026
1027
1028 ParentTable = DtPeekSubtable ();
1029 while (*PFieldList)
1030 {
1031 SubtableStart = *PFieldList;
1032
1033 /* Compile PPTT subtable header */
1034
1035 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1036 &Subtable);
1037 if (ACPI_FAILURE (Status))
1038 {
1039 return (Status);
1040 }
1041 DtInsertSubtable (ParentTable, Subtable);
1042 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1043 PpttHeader->Length = (UINT8)(Subtable->Length);
1044
1045 switch (PpttHeader->Type)
1046 {
1047 case ACPI_PPTT_TYPE_PROCESSOR:
1048
1049 InfoTable = AcpiDmTableInfoPptt0;
1050 break;
1051
1052 case ACPI_PPTT_TYPE_CACHE:
1053
1054 InfoTable = AcpiDmTableInfoPptt1;
1055 break;
1056
1057 case ACPI_PPTT_TYPE_ID:
1058
1059 InfoTable = AcpiDmTableInfoPptt2;
1060 break;
1061
1062 default:
1063
1064 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1065 return (AE_ERROR);
1066 }
1067
1068 /* Compile PPTT subtable body */
1069
1070 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1071 if (ACPI_FAILURE (Status))
1072 {
1073 return (Status);
1074 }
1075 DtInsertSubtable (ParentTable, Subtable);
1076 PpttHeader->Length += (UINT8)(Subtable->Length);
1077
1078 /* Compile PPTT subtable additionals */
1079
1080 switch (PpttHeader->Type)
1081 {
1082 case ACPI_PPTT_TYPE_PROCESSOR:
1083
1084 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1085 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1086 if (PpttProcessor)
1087 {
1088 /* Compile initiator proximity domain list */
1089
1090 PpttProcessor->NumberOfPrivResources = 0;
1091 while (*PFieldList)
1092 {
1093 Status = DtCompileTable (PFieldList,
1094 AcpiDmTableInfoPptt0a, &Subtable);
1095 if (ACPI_FAILURE (Status))
1096 {
1097 return (Status);
1098 }
1099 if (!Subtable)
1100 {
1101 break;
1102 }
1103
1104 DtInsertSubtable (ParentTable, Subtable);
1105 PpttHeader->Length += (UINT8)(Subtable->Length);
1106 PpttProcessor->NumberOfPrivResources++;
1107 }
1108 }
1109 break;
1110
1111 default:
1112
1113 break;
1114 }
1115 }
1116
1117 return (AE_OK);
1118 }
1119
1120
1121 /******************************************************************************
1122 *
1123 * FUNCTION: DtCompileRsdt
1124 *
1125 * PARAMETERS: List - Current field list pointer
1126 *
1127 * RETURN: Status
1128 *
1129 * DESCRIPTION: Compile RSDT.
1130 *
1131 *****************************************************************************/
1132
1133 ACPI_STATUS
1134 DtCompileRsdt (
1135 void **List)
1136 {
1137 DT_SUBTABLE *Subtable;
1138 DT_SUBTABLE *ParentTable;
1139 DT_FIELD *FieldList = *(DT_FIELD **) List;
1140 UINT32 Address;
1141
1142
1143 ParentTable = DtPeekSubtable ();
1144
1145 while (FieldList)
1146 {
1147 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1148
1149 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1150 DtInsertSubtable (ParentTable, Subtable);
1151 FieldList = FieldList->Next;
1152 }
1153
1154 return (AE_OK);
1155 }
1156
1157
1158 /******************************************************************************
1159 *
1160 * FUNCTION: DtCompileS3pt
1161 *
1162 * PARAMETERS: PFieldList - Current field list pointer
1163 *
1164 * RETURN: Status
1165 *
1166 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1167 *
1168 *****************************************************************************/
1169
1170 ACPI_STATUS
1171 DtCompileS3pt (
1172 DT_FIELD **PFieldList)
1173 {
1174 ACPI_STATUS Status;
1175 ACPI_FPDT_HEADER *S3ptHeader;
1176 DT_SUBTABLE *Subtable;
1177 DT_SUBTABLE *ParentTable;
1178 ACPI_DMTABLE_INFO *InfoTable;
1179 DT_FIELD *SubtableStart;
1180
1181
1182 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1183 &Gbl_RootTable);
1184 if (ACPI_FAILURE (Status))
1185 {
1186 return (Status);
1187 }
1188
1189 DtPushSubtable (Gbl_RootTable);
1190
1191 while (*PFieldList)
1192 {
1193 SubtableStart = *PFieldList;
1194 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1195 &Subtable);
1196 if (ACPI_FAILURE (Status))
1197 {
1198 return (Status);
1199 }
1200
1201 ParentTable = DtPeekSubtable ();
1202 DtInsertSubtable (ParentTable, Subtable);
1203 DtPushSubtable (Subtable);
1204
1205 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1206
1207 switch (S3ptHeader->Type)
1208 {
1209 case ACPI_S3PT_TYPE_RESUME:
1210
1211 InfoTable = AcpiDmTableInfoS3pt0;
1212 break;
1213
1214 case ACPI_S3PT_TYPE_SUSPEND:
1215
1216 InfoTable = AcpiDmTableInfoS3pt1;
1217 break;
1218
1219 default:
1220
1221 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1222 return (AE_ERROR);
1223 }
1224
1225 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1226 if (ACPI_FAILURE (Status))
1227 {
1228 return (Status);
1229 }
1230
1231 ParentTable = DtPeekSubtable ();
1232 DtInsertSubtable (ParentTable, Subtable);
1233 DtPopSubtable ();
1234 }
1235
1236 return (AE_OK);
1237 }
1238
1239
1240 /******************************************************************************
1241 *
1242 * FUNCTION: DtCompileSdev
1243 *
1244 * PARAMETERS: List - Current field list pointer
1245 *
1246 * RETURN: Status
1247 *
1248 * DESCRIPTION: Compile SDEV.
1249 *
1250 *****************************************************************************/
1251
1252 ACPI_STATUS
1253 DtCompileSdev (
1254 void **List)
1255 {
1256 ACPI_STATUS Status;
1257 ACPI_SDEV_HEADER *SdevHeader;
1258 DT_SUBTABLE *Subtable;
1259 DT_SUBTABLE *ParentTable;
1260 ACPI_DMTABLE_INFO *InfoTable;
1261 DT_FIELD **PFieldList = (DT_FIELD **) List;
1262 DT_FIELD *SubtableStart;
1263 ACPI_SDEV_PCIE *Pcie = NULL;
1264 ACPI_SDEV_NAMESPACE *Namesp = NULL;
1265 UINT32 EntryCount;
1266
1267
1268 /* Subtables */
1269
1270 while (*PFieldList)
1271 {
1272 /* Compile common SDEV subtable header */
1273
1274 SubtableStart = *PFieldList;
1275 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
1276 &Subtable);
1277 if (ACPI_FAILURE (Status))
1278 {
1279 return (Status);
1280 }
1281
1282 ParentTable = DtPeekSubtable ();
1283 DtInsertSubtable (ParentTable, Subtable);
1284 DtPushSubtable (Subtable);
1285
1286 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
1287 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
1288
1289 switch (SdevHeader->Type)
1290 {
1291 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1292
1293 InfoTable = AcpiDmTableInfoSdev0;
1294 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
1295 break;
1296
1297 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1298
1299 InfoTable = AcpiDmTableInfoSdev1;
1300 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
1301 break;
1302
1303 default:
1304
1305 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1306 return (AE_ERROR);
1307 }
1308
1309 /* Compile SDEV subtable body */
1310
1311 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1312 if (ACPI_FAILURE (Status))
1313 {
1314 return (Status);
1315 }
1316
1317 ParentTable = DtPeekSubtable ();
1318 DtInsertSubtable (ParentTable, Subtable);
1319
1320 /* Optional data fields are appended to the main subtable body */
1321
1322 switch (SdevHeader->Type)
1323 {
1324 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
1325
1326 /* Append DeviceId namespace string */
1327
1328 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
1329 &Subtable);
1330 if (ACPI_FAILURE (Status))
1331 {
1332 return (Status);
1333 }
1334
1335 if (!Subtable)
1336 {
1337 break;
1338 }
1339
1340 ParentTable = DtPeekSubtable ();
1341 DtInsertSubtable (ParentTable, Subtable);
1342
1343 Namesp->DeviceIdOffset = sizeof (ACPI_SDEV_NAMESPACE);
1344 Namesp->DeviceIdLength = (UINT16) Subtable->Length;
1345
1346 /* Append Vendor data */
1347
1348 Namesp->VendorDataLength = 0;
1349 Namesp->VendorDataOffset = 0;
1350
1351 if (*PFieldList)
1352 {
1353 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1354 &Subtable);
1355 if (ACPI_FAILURE (Status))
1356 {
1357 return (Status);
1358 }
1359
1360 if (Subtable)
1361 {
1362 ParentTable = DtPeekSubtable ();
1363 DtInsertSubtable (ParentTable, Subtable);
1364
1365 Namesp->VendorDataOffset =
1366 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
1367 Namesp->VendorDataLength =
1368 (UINT16) Subtable->Length;
1369 }
1370 }
1371
1372 /* Final size of entire namespace structure */
1373
1374 SdevHeader->Length = (UINT16) (sizeof (ACPI_SDEV_NAMESPACE) +
1375 Subtable->Length + Namesp->DeviceIdLength);
1376 break;
1377
1378 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1379
1380 /* Append the PCIe path info first */
1381
1382 EntryCount = 0;
1383 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
1384 {
1385 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
1386 &Subtable);
1387 if (ACPI_FAILURE (Status))
1388 {
1389 return (Status);
1390 }
1391
1392 if (!Subtable)
1393 {
1394 DtPopSubtable ();
1395 break;
1396 }
1397
1398 ParentTable = DtPeekSubtable ();
1399 DtInsertSubtable (ParentTable, Subtable);
1400 EntryCount++;
1401 }
1402
1403 /* Path offset will point immediately after the main subtable */
1404
1405 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
1406 Pcie->PathLength = (UINT16)
1407 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
1408
1409 /* Append the Vendor Data last */
1410
1411 Pcie->VendorDataLength = 0;
1412 Pcie->VendorDataOffset = 0;
1413
1414 if (*PFieldList)
1415 {
1416 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1417 &Subtable);
1418 if (ACPI_FAILURE (Status))
1419 {
1420 return (Status);
1421 }
1422
1423 if (Subtable)
1424 {
1425 ParentTable = DtPeekSubtable ();
1426 DtInsertSubtable (ParentTable, Subtable);
1427
1428 Pcie->VendorDataOffset =
1429 Pcie->PathOffset + Pcie->PathLength;
1430 Pcie->VendorDataLength = (UINT16)
1431 Subtable->Length;
1432 }
1433 }
1434
1435 SdevHeader->Length =
1436 sizeof (ACPI_SDEV_PCIE) +
1437 Pcie->PathLength + Pcie->VendorDataLength;
1438 break;
1439
1440 default:
1441
1442 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1443 return (AE_ERROR);
1444 }
1445
1446 DtPopSubtable ();
1447 }
1448
1449 return (AE_OK);
1450 }
1451
1452
1453 /******************************************************************************
1454 *
1455 * FUNCTION: DtCompileSlic
1456 *
1457 * PARAMETERS: List - Current field list pointer
1458 *
1459 * RETURN: Status
1460 *
1461 * DESCRIPTION: Compile SLIC.
1462 *
1463 *****************************************************************************/
1464
1465 ACPI_STATUS
1466 DtCompileSlic (
1467 void **List)
1468 {
1469 ACPI_STATUS Status;
1470 DT_SUBTABLE *Subtable;
1471 DT_SUBTABLE *ParentTable;
1472 DT_FIELD **PFieldList = (DT_FIELD **) List;
1473
1474
1475 while (*PFieldList)
1476 {
1477 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
1478 &Subtable);
1479 if (ACPI_FAILURE (Status))
1480 {
1481 return (Status);
1482 }
1483
1484 ParentTable = DtPeekSubtable ();
1485 DtInsertSubtable (ParentTable, Subtable);
1486 DtPushSubtable (Subtable);
1487 DtPopSubtable ();
1488 }
1489
1490 return (AE_OK);
1491 }
1492
1493
1494 /******************************************************************************
1495 *
1496 * FUNCTION: DtCompileSlit
1497 *
1498 * PARAMETERS: List - Current field list pointer
1499 *
1500 * RETURN: Status
1501 *
1502 * DESCRIPTION: Compile SLIT.
1503 *
1504 *****************************************************************************/
1505
1506 ACPI_STATUS
1507 DtCompileSlit (
1508 void **List)
1509 {
1510 ACPI_STATUS Status;
1511 DT_SUBTABLE *Subtable;
1512 DT_SUBTABLE *ParentTable;
1513 DT_FIELD **PFieldList = (DT_FIELD **) List;
1514 DT_FIELD *FieldList;
1515 UINT32 Localities;
1516 UINT8 *LocalityBuffer;
1517
1518
1519 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1520 &Subtable);
1521 if (ACPI_FAILURE (Status))
1522 {
1523 return (Status);
1524 }
1525
1526 ParentTable = DtPeekSubtable ();
1527 DtInsertSubtable (ParentTable, Subtable);
1528
1529 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1530 LocalityBuffer = UtLocalCalloc (Localities);
1531
1532 /* Compile each locality buffer */
1533
1534 FieldList = *PFieldList;
1535 while (FieldList)
1536 {
1537 DtCompileBuffer (LocalityBuffer,
1538 FieldList->Value, FieldList, Localities);
1539
1540 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1541 DtInsertSubtable (ParentTable, Subtable);
1542 FieldList = FieldList->Next;
1543 }
1544
1545 ACPI_FREE (LocalityBuffer);
1546 return (AE_OK);
1547 }
1548
1549
1550 /******************************************************************************
1551 *
1552 * FUNCTION: DtCompileSrat
1553 *
1554 * PARAMETERS: List - Current field list pointer
1555 *
1556 * RETURN: Status
1557 *
1558 * DESCRIPTION: Compile SRAT.
1559 *
1560 *****************************************************************************/
1561
1562 ACPI_STATUS
1563 DtCompileSrat (
1564 void **List)
1565 {
1566 ACPI_STATUS Status;
1567 DT_SUBTABLE *Subtable;
1568 DT_SUBTABLE *ParentTable;
1569 DT_FIELD **PFieldList = (DT_FIELD **) List;
1570 DT_FIELD *SubtableStart;
1571 ACPI_SUBTABLE_HEADER *SratHeader;
1572 ACPI_DMTABLE_INFO *InfoTable;
1573
1574
1575 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1576 &Subtable);
1577 if (ACPI_FAILURE (Status))
1578 {
1579 return (Status);
1580 }
1581
1582 ParentTable = DtPeekSubtable ();
1583 DtInsertSubtable (ParentTable, Subtable);
1584
1585 while (*PFieldList)
1586 {
1587 SubtableStart = *PFieldList;
1588 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1589 &Subtable);
1590 if (ACPI_FAILURE (Status))
1591 {
1592 return (Status);
1593 }
1594
1595 ParentTable = DtPeekSubtable ();
1596 DtInsertSubtable (ParentTable, Subtable);
1597 DtPushSubtable (Subtable);
1598
1599 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1600
1601 switch (SratHeader->Type)
1602 {
1603 case ACPI_SRAT_TYPE_CPU_AFFINITY:
1604
1605 InfoTable = AcpiDmTableInfoSrat0;
1606 break;
1607
1608 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1609
1610 InfoTable = AcpiDmTableInfoSrat1;
1611 break;
1612
1613 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1614
1615 InfoTable = AcpiDmTableInfoSrat2;
1616 break;
1617
1618 case ACPI_SRAT_TYPE_GICC_AFFINITY:
1619
1620 InfoTable = AcpiDmTableInfoSrat3;
1621 break;
1622
1623 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
1624
1625 InfoTable = AcpiDmTableInfoSrat4;
1626 break;
1627
1628 default:
1629
1630 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1631 return (AE_ERROR);
1632 }
1633
1634 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1635 if (ACPI_FAILURE (Status))
1636 {
1637 return (Status);
1638 }
1639
1640 ParentTable = DtPeekSubtable ();
1641 DtInsertSubtable (ParentTable, Subtable);
1642 DtPopSubtable ();
1643 }
1644
1645 return (AE_OK);
1646 }
1647
1648
1649 /******************************************************************************
1650 *
1651 * FUNCTION: DtCompileStao
1652 *
1653 * PARAMETERS: PFieldList - Current field list pointer
1654 *
1655 * RETURN: Status
1656 *
1657 * DESCRIPTION: Compile STAO.
1658 *
1659 *****************************************************************************/
1660
1661 ACPI_STATUS
1662 DtCompileStao (
1663 void **List)
1664 {
1665 DT_FIELD **PFieldList = (DT_FIELD **) List;
1666 DT_SUBTABLE *Subtable;
1667 DT_SUBTABLE *ParentTable;
1668 ACPI_STATUS Status;
1669
1670
1671 /* Compile the main table */
1672
1673 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
1674 &Subtable);
1675 if (ACPI_FAILURE (Status))
1676 {
1677 return (Status);
1678 }
1679
1680 ParentTable = DtPeekSubtable ();
1681 DtInsertSubtable (ParentTable, Subtable);
1682
1683 /* Compile each ASCII namestring as a subtable */
1684
1685 while (*PFieldList)
1686 {
1687 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
1688 &Subtable);
1689 if (ACPI_FAILURE (Status))
1690 {
1691 return (Status);
1692 }
1693
1694 ParentTable = DtPeekSubtable ();
1695 DtInsertSubtable (ParentTable, Subtable);
1696 }
1697
1698 return (AE_OK);
1699 }
1700
1701
1702 /******************************************************************************
1703 *
1704 * FUNCTION: DtCompileTcpa
1705 *
1706 * PARAMETERS: PFieldList - Current field list pointer
1707 *
1708 * RETURN: Status
1709 *
1710 * DESCRIPTION: Compile TCPA.
1711 *
1712 *****************************************************************************/
1713
1714 ACPI_STATUS
1715 DtCompileTcpa (
1716 void **List)
1717 {
1718 DT_FIELD **PFieldList = (DT_FIELD **) List;
1719 DT_SUBTABLE *Subtable;
1720 ACPI_TABLE_TCPA_HDR *TcpaHeader;
1721 DT_SUBTABLE *ParentTable;
1722 ACPI_STATUS Status;
1723
1724
1725 /* Compile the main table */
1726
1727 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
1728 &Subtable);
1729 if (ACPI_FAILURE (Status))
1730 {
1731 return (Status);
1732 }
1733
1734 ParentTable = DtPeekSubtable ();
1735 DtInsertSubtable (ParentTable, Subtable);
1736
1737 /*
1738 * Examine the PlatformClass field to determine the table type.
1739 * Either a client or server table. Only one.
1740 */
1741 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
1742
1743 switch (TcpaHeader->PlatformClass)
1744 {
1745 case ACPI_TCPA_CLIENT_TABLE:
1746
1747 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
1748 &Subtable);
1749 break;
1750
1751 case ACPI_TCPA_SERVER_TABLE:
1752
1753 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
1754 &Subtable);
1755 break;
1756
1757 default:
1758
1759 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
1760 TcpaHeader->PlatformClass);
1761 Status = AE_ERROR;
1762 break;
1763 }
1764
1765 ParentTable = DtPeekSubtable ();
1766 DtInsertSubtable (ParentTable, Subtable);
1767 return (Status);
1768 }
1769
1770
1771 /******************************************************************************
1772 *
1773 * FUNCTION: DtCompileTpm2
1774 *
1775 * PARAMETERS: PFieldList - Current field list pointer
1776 *
1777 * RETURN: Status
1778 *
1779 * DESCRIPTION: Compile TPM2.
1780 *
1781 *****************************************************************************/
1782
1783 ACPI_STATUS
1784 DtCompileTpm2 (
1785 void **List)
1786 {
1787 DT_FIELD **PFieldList = (DT_FIELD **) List;
1788 DT_SUBTABLE *Subtable;
1789 ACPI_TABLE_TPM2 *Tpm2Header;
1790 DT_SUBTABLE *ParentTable;
1791 ACPI_STATUS Status = AE_OK;
1792
1793
1794 /* Compile the main table */
1795
1796 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
1797 &Subtable);
1798 if (ACPI_FAILURE (Status))
1799 {
1800 return (Status);
1801 }
1802
1803 ParentTable = DtPeekSubtable ();
1804 DtInsertSubtable (ParentTable, Subtable);
1805
1806 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
1807
1808 /* Method parameters */
1809 /* Optional: Log area minimum length */
1810 /* Optional: Log area start address */
1811 /* TBD: Optional fields above not fully implemented (not optional at this time) */
1812
1813 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
1814 &Subtable);
1815 if (ACPI_FAILURE (Status))
1816 {
1817 return (Status);
1818 }
1819
1820 ParentTable = DtPeekSubtable ();
1821 DtInsertSubtable (ParentTable, Subtable);
1822
1823
1824 /* Subtable type depends on the StartMethod */
1825
1826 switch (Tpm2Header->StartMethod)
1827 {
1828 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
1829
1830 /* Subtable specific to to ARM_SMC */
1831
1832 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
1833 &Subtable);
1834 if (ACPI_FAILURE (Status))
1835 {
1836 return (Status);
1837 }
1838
1839 ParentTable = DtPeekSubtable ();
1840 DtInsertSubtable (ParentTable, Subtable);
1841 break;
1842
1843 case ACPI_TPM2_START_METHOD:
1844 case ACPI_TPM2_MEMORY_MAPPED:
1845 case ACPI_TPM2_COMMAND_BUFFER:
1846 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
1847 break;
1848
1849 case ACPI_TPM2_RESERVED1:
1850 case ACPI_TPM2_RESERVED3:
1851 case ACPI_TPM2_RESERVED4:
1852 case ACPI_TPM2_RESERVED5:
1853 case ACPI_TPM2_RESERVED9:
1854 case ACPI_TPM2_RESERVED10:
1855
1856 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
1857 Tpm2Header->StartMethod);
1858 Status = AE_ERROR;
1859 break;
1860
1861 case ACPI_TPM2_NOT_ALLOWED:
1862 default:
1863
1864 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
1865 Tpm2Header->StartMethod);
1866 Status = AE_ERROR;
1867 break;
1868 }
1869
1870 return (Status);
1871 }
1872
1873
1874 /******************************************************************************
1875 *
1876 * FUNCTION: DtGetGenericTableInfo
1877 *
1878 * PARAMETERS: Name - Generic type name
1879 *
1880 * RETURN: Info entry
1881 *
1882 * DESCRIPTION: Obtain table info for a generic name entry
1883 *
1884 *****************************************************************************/
1885
1886 ACPI_DMTABLE_INFO *
1887 DtGetGenericTableInfo (
1888 char *Name)
1889 {
1890 ACPI_DMTABLE_INFO *Info;
1891 UINT32 i;
1892
1893
1894 if (!Name)
1895 {
1896 return (NULL);
1897 }
1898
1899 /* Search info table for name match */
1900
1901 for (i = 0; ; i++)
1902 {
1903 Info = AcpiDmTableInfoGeneric[i];
1904 if (Info->Opcode == ACPI_DMT_EXIT)
1905 {
1906 Info = NULL;
1907 break;
1908 }
1909
1910 /* Use caseless compare for generic keywords */
1911
1912 if (!AcpiUtStricmp (Name, Info->Name))
1913 {
1914 break;
1915 }
1916 }
1917
1918 return (Info);
1919 }
1920
1921
1922 /******************************************************************************
1923 *
1924 * FUNCTION: DtCompileUefi
1925 *
1926 * PARAMETERS: List - Current field list pointer
1927 *
1928 * RETURN: Status
1929 *
1930 * DESCRIPTION: Compile UEFI.
1931 *
1932 *****************************************************************************/
1933
1934 ACPI_STATUS
1935 DtCompileUefi (
1936 void **List)
1937 {
1938 ACPI_STATUS Status;
1939 DT_SUBTABLE *Subtable;
1940 DT_SUBTABLE *ParentTable;
1941 DT_FIELD **PFieldList = (DT_FIELD **) List;
1942 UINT16 *DataOffset;
1943
1944
1945 /* Compile the predefined portion of the UEFI table */
1946
1947 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
1948 &Subtable);
1949 if (ACPI_FAILURE (Status))
1950 {
1951 return (Status);
1952 }
1953
1954 DataOffset = (UINT16 *) (Subtable->Buffer + 16);
1955 *DataOffset = sizeof (ACPI_TABLE_UEFI);
1956
1957 ParentTable = DtPeekSubtable ();
1958 DtInsertSubtable (ParentTable, Subtable);
1959
1960 /*
1961 * Compile the "generic" portion of the UEFI table. This
1962 * part of the table is not predefined and any of the generic
1963 * operators may be used.
1964 */
1965 DtCompileGeneric ((void **) PFieldList, NULL, NULL);
1966 return (AE_OK);
1967 }
1968
1969
1970 /******************************************************************************
1971 *
1972 * FUNCTION: DtCompileVrtc
1973 *
1974 * PARAMETERS: List - Current field list pointer
1975 *
1976 * RETURN: Status
1977 *
1978 * DESCRIPTION: Compile VRTC.
1979 *
1980 *****************************************************************************/
1981
1982 ACPI_STATUS
1983 DtCompileVrtc (
1984 void **List)
1985 {
1986 ACPI_STATUS Status;
1987
1988
1989 Status = DtCompileTwoSubtables (List,
1990 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
1991 return (Status);
1992 }
1993
1994
1995 /******************************************************************************
1996 *
1997 * FUNCTION: DtCompileWdat
1998 *
1999 * PARAMETERS: List - Current field list pointer
2000 *
2001 * RETURN: Status
2002 *
2003 * DESCRIPTION: Compile WDAT.
2004 *
2005 *****************************************************************************/
2006
2007 ACPI_STATUS
2008 DtCompileWdat (
2009 void **List)
2010 {
2011 ACPI_STATUS Status;
2012
2013
2014 Status = DtCompileTwoSubtables (List,
2015 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2016 return (Status);
2017 }
2018
2019
2020 /******************************************************************************
2021 *
2022 * FUNCTION: DtCompileWpbt
2023 *
2024 * PARAMETERS: List - Current field list pointer
2025 *
2026 * RETURN: Status
2027 *
2028 * DESCRIPTION: Compile WPBT.
2029 *
2030 *****************************************************************************/
2031
2032 ACPI_STATUS
2033 DtCompileWpbt (
2034 void **List)
2035 {
2036 DT_FIELD **PFieldList = (DT_FIELD **) List;
2037 DT_SUBTABLE *Subtable;
2038 DT_SUBTABLE *ParentTable;
2039 ACPI_TABLE_WPBT *Table;
2040 ACPI_STATUS Status;
2041 UINT16 Length;
2042
2043
2044 /* Compile the main table */
2045
2046 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
2047 &Subtable);
2048 if (ACPI_FAILURE (Status))
2049 {
2050 return (Status);
2051 }
2052
2053 ParentTable = DtPeekSubtable ();
2054 DtInsertSubtable (ParentTable, Subtable);
2055
2056 /* Compile the argument list subtable */
2057
2058 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
2059 &Subtable);
2060 if (ACPI_FAILURE (Status))
2061 {
2062 return (Status);
2063 }
2064
2065 /* Extract the length of the Arguments buffer, insert into main table */
2066
2067 Length = (UINT16) Subtable->TotalLength;
2068 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
2069 Table->ArgumentsLength = Length;
2070
2071 ParentTable = DtPeekSubtable ();
2072 DtInsertSubtable (ParentTable, Subtable);
2073 return (AE_OK);
2074 }
2075
2076
2077 /******************************************************************************
2078 *
2079 * FUNCTION: DtCompileXsdt
2080 *
2081 * PARAMETERS: List - Current field list pointer
2082 *
2083 * RETURN: Status
2084 *
2085 * DESCRIPTION: Compile XSDT.
2086 *
2087 *****************************************************************************/
2088
2089 ACPI_STATUS
2090 DtCompileXsdt (
2091 void **List)
2092 {
2093 DT_SUBTABLE *Subtable;
2094 DT_SUBTABLE *ParentTable;
2095 DT_FIELD *FieldList = *(DT_FIELD **) List;
2096 UINT64 Address;
2097
2098
2099 ParentTable = DtPeekSubtable ();
2100
2101 while (FieldList)
2102 {
2103 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2104
2105 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2106 DtInsertSubtable (ParentTable, Subtable);
2107 FieldList = FieldList->Next;
2108 }
2109
2110 return (AE_OK);
2111 }
2112
2113
2114 /******************************************************************************
2115 *
2116 * FUNCTION: DtCompileGeneric
2117 *
2118 * PARAMETERS: List - Current field list pointer
2119 * Name - Field name to end generic compiling
2120 * Length - Compiled table length to return
2121 *
2122 * RETURN: Status
2123 *
2124 * DESCRIPTION: Compile generic unknown table.
2125 *
2126 *****************************************************************************/
2127
2128 ACPI_STATUS
2129 DtCompileGeneric (
2130 void **List,
2131 char *Name,
2132 UINT32 *Length)
2133 {
2134 ACPI_STATUS Status;
2135 DT_SUBTABLE *Subtable;
2136 DT_SUBTABLE *ParentTable;
2137 DT_FIELD **PFieldList = (DT_FIELD **) List;
2138 ACPI_DMTABLE_INFO *Info;
2139
2140
2141 ParentTable = DtPeekSubtable ();
2142
2143 /*
2144 * Compile the "generic" portion of the table. This
2145 * part of the table is not predefined and any of the generic
2146 * operators may be used.
2147 */
2148
2149 /* Find any and all labels in the entire generic portion */
2150
2151 DtDetectAllLabels (*PFieldList);
2152
2153 /* Now we can actually compile the parse tree */
2154
2155 if (Length && *Length)
2156 {
2157 *Length = 0;
2158 }
2159 while (*PFieldList)
2160 {
2161 if (Name && !strcmp ((*PFieldList)->Name, Name))
2162 {
2163 break;
2164 }
2165
2166 Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2167 if (!Info)
2168 {
2169 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2170 (*PFieldList)->Name);
2171 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2172 (*PFieldList), MsgBuffer);
2173
2174 *PFieldList = (*PFieldList)->Next;
2175 continue;
2176 }
2177
2178 Status = DtCompileTable (PFieldList, Info,
2179 &Subtable);
2180 if (ACPI_SUCCESS (Status))
2181 {
2182 DtInsertSubtable (ParentTable, Subtable);
2183 if (Length)
2184 {
2185 *Length += Subtable->Length;
2186 }
2187 }
2188 else
2189 {
2190 *PFieldList = (*PFieldList)->Next;
2191
2192 if (Status == AE_NOT_FOUND)
2193 {
2194 sprintf (MsgBuffer, "Generic data type \"%s\" not found",
2195 (*PFieldList)->Name);
2196 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2197 (*PFieldList), MsgBuffer);
2198 }
2199 }
2200 }
2201
2202 return (AE_OK);
2203 }
2204