dttable2.c revision 1.1.1.9 1 /******************************************************************************
2 *
3 * Module Name: dttable2.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2019, 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 &AslGbl_RootTable);
1184 if (ACPI_FAILURE (Status))
1185 {
1186 return (Status);
1187 }
1188
1189 DtPushSubtable (AslGbl_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 /* Final size of entire namespace structure */
1371
1372 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
1373 Subtable->Length + Namesp->DeviceIdLength);
1374 }
1375 }
1376
1377 break;
1378
1379 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
1380
1381 /* Append the PCIe path info first */
1382
1383 EntryCount = 0;
1384 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
1385 {
1386 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
1387 &Subtable);
1388 if (ACPI_FAILURE (Status))
1389 {
1390 return (Status);
1391 }
1392
1393 if (!Subtable)
1394 {
1395 DtPopSubtable ();
1396 break;
1397 }
1398
1399 ParentTable = DtPeekSubtable ();
1400 DtInsertSubtable (ParentTable, Subtable);
1401 EntryCount++;
1402 }
1403
1404 /* Path offset will point immediately after the main subtable */
1405
1406 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
1407 Pcie->PathLength = (UINT16)
1408 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
1409
1410 /* Append the Vendor Data last */
1411
1412 Pcie->VendorDataLength = 0;
1413 Pcie->VendorDataOffset = 0;
1414
1415 if (*PFieldList)
1416 {
1417 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
1418 &Subtable);
1419 if (ACPI_FAILURE (Status))
1420 {
1421 return (Status);
1422 }
1423
1424 if (Subtable)
1425 {
1426 ParentTable = DtPeekSubtable ();
1427 DtInsertSubtable (ParentTable, Subtable);
1428
1429 Pcie->VendorDataOffset =
1430 Pcie->PathOffset + Pcie->PathLength;
1431 Pcie->VendorDataLength = (UINT16)
1432 Subtable->Length;
1433 }
1434 }
1435
1436 SdevHeader->Length =
1437 sizeof (ACPI_SDEV_PCIE) +
1438 Pcie->PathLength + Pcie->VendorDataLength;
1439 break;
1440
1441 default:
1442
1443 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
1444 return (AE_ERROR);
1445 }
1446
1447 DtPopSubtable ();
1448 }
1449
1450 return (AE_OK);
1451 }
1452
1453
1454 /******************************************************************************
1455 *
1456 * FUNCTION: DtCompileSlic
1457 *
1458 * PARAMETERS: List - Current field list pointer
1459 *
1460 * RETURN: Status
1461 *
1462 * DESCRIPTION: Compile SLIC.
1463 *
1464 *****************************************************************************/
1465
1466 ACPI_STATUS
1467 DtCompileSlic (
1468 void **List)
1469 {
1470 ACPI_STATUS Status;
1471 DT_SUBTABLE *Subtable;
1472 DT_SUBTABLE *ParentTable;
1473 DT_FIELD **PFieldList = (DT_FIELD **) List;
1474
1475
1476 while (*PFieldList)
1477 {
1478 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
1479 &Subtable);
1480 if (ACPI_FAILURE (Status))
1481 {
1482 return (Status);
1483 }
1484
1485 ParentTable = DtPeekSubtable ();
1486 DtInsertSubtable (ParentTable, Subtable);
1487 DtPushSubtable (Subtable);
1488 DtPopSubtable ();
1489 }
1490
1491 return (AE_OK);
1492 }
1493
1494
1495 /******************************************************************************
1496 *
1497 * FUNCTION: DtCompileSlit
1498 *
1499 * PARAMETERS: List - Current field list pointer
1500 *
1501 * RETURN: Status
1502 *
1503 * DESCRIPTION: Compile SLIT.
1504 *
1505 *****************************************************************************/
1506
1507 ACPI_STATUS
1508 DtCompileSlit (
1509 void **List)
1510 {
1511 ACPI_STATUS Status;
1512 DT_SUBTABLE *Subtable;
1513 DT_SUBTABLE *ParentTable;
1514 DT_FIELD **PFieldList = (DT_FIELD **) List;
1515 DT_FIELD *FieldList;
1516 DT_FIELD *EndOfFieldList = NULL;
1517 UINT32 Localities;
1518 UINT32 LocalityListLength;
1519 UINT8 *LocalityBuffer;
1520
1521
1522 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
1523 &Subtable);
1524 if (ACPI_FAILURE (Status))
1525 {
1526 return (Status);
1527 }
1528
1529 ParentTable = DtPeekSubtable ();
1530 DtInsertSubtable (ParentTable, Subtable);
1531
1532 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
1533 LocalityBuffer = UtLocalCalloc (Localities);
1534 LocalityListLength = 0;
1535
1536 /* Compile each locality buffer */
1537
1538 FieldList = *PFieldList;
1539 while (FieldList)
1540 {
1541 DtCompileBuffer (LocalityBuffer,
1542 FieldList->Value, FieldList, Localities);
1543
1544 LocalityListLength++;
1545 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
1546 DtInsertSubtable (ParentTable, Subtable);
1547 EndOfFieldList = FieldList;
1548 FieldList = FieldList->Next;
1549 }
1550
1551 if (LocalityListLength != Localities)
1552 {
1553 sprintf(AslGbl_MsgBuffer,
1554 "Found %u entries, must match LocalityCount: %u",
1555 LocalityListLength, Localities);
1556 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
1557 ACPI_FREE (LocalityBuffer);
1558 return (AE_LIMIT);
1559 }
1560
1561 ACPI_FREE (LocalityBuffer);
1562 return (AE_OK);
1563 }
1564
1565
1566 /******************************************************************************
1567 *
1568 * FUNCTION: DtCompileSrat
1569 *
1570 * PARAMETERS: List - Current field list pointer
1571 *
1572 * RETURN: Status
1573 *
1574 * DESCRIPTION: Compile SRAT.
1575 *
1576 *****************************************************************************/
1577
1578 ACPI_STATUS
1579 DtCompileSrat (
1580 void **List)
1581 {
1582 ACPI_STATUS Status;
1583 DT_SUBTABLE *Subtable;
1584 DT_SUBTABLE *ParentTable;
1585 DT_FIELD **PFieldList = (DT_FIELD **) List;
1586 DT_FIELD *SubtableStart;
1587 ACPI_SUBTABLE_HEADER *SratHeader;
1588 ACPI_DMTABLE_INFO *InfoTable;
1589
1590
1591 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
1592 &Subtable);
1593 if (ACPI_FAILURE (Status))
1594 {
1595 return (Status);
1596 }
1597
1598 ParentTable = DtPeekSubtable ();
1599 DtInsertSubtable (ParentTable, Subtable);
1600
1601 while (*PFieldList)
1602 {
1603 SubtableStart = *PFieldList;
1604 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
1605 &Subtable);
1606 if (ACPI_FAILURE (Status))
1607 {
1608 return (Status);
1609 }
1610
1611 ParentTable = DtPeekSubtable ();
1612 DtInsertSubtable (ParentTable, Subtable);
1613 DtPushSubtable (Subtable);
1614
1615 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1616
1617 switch (SratHeader->Type)
1618 {
1619 case ACPI_SRAT_TYPE_CPU_AFFINITY:
1620
1621 InfoTable = AcpiDmTableInfoSrat0;
1622 break;
1623
1624 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1625
1626 InfoTable = AcpiDmTableInfoSrat1;
1627 break;
1628
1629 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1630
1631 InfoTable = AcpiDmTableInfoSrat2;
1632 break;
1633
1634 case ACPI_SRAT_TYPE_GICC_AFFINITY:
1635
1636 InfoTable = AcpiDmTableInfoSrat3;
1637 break;
1638
1639 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
1640
1641 InfoTable = AcpiDmTableInfoSrat4;
1642 break;
1643
1644 case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
1645
1646 InfoTable = AcpiDmTableInfoSrat5;
1647 break;
1648
1649 default:
1650
1651 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
1652 return (AE_ERROR);
1653 }
1654
1655 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1656 if (ACPI_FAILURE (Status))
1657 {
1658 return (Status);
1659 }
1660
1661 ParentTable = DtPeekSubtable ();
1662 DtInsertSubtable (ParentTable, Subtable);
1663 DtPopSubtable ();
1664 }
1665
1666 return (AE_OK);
1667 }
1668
1669
1670 /******************************************************************************
1671 *
1672 * FUNCTION: DtCompileStao
1673 *
1674 * PARAMETERS: PFieldList - Current field list pointer
1675 *
1676 * RETURN: Status
1677 *
1678 * DESCRIPTION: Compile STAO.
1679 *
1680 *****************************************************************************/
1681
1682 ACPI_STATUS
1683 DtCompileStao (
1684 void **List)
1685 {
1686 DT_FIELD **PFieldList = (DT_FIELD **) List;
1687 DT_SUBTABLE *Subtable;
1688 DT_SUBTABLE *ParentTable;
1689 ACPI_STATUS Status;
1690
1691
1692 /* Compile the main table */
1693
1694 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
1695 &Subtable);
1696 if (ACPI_FAILURE (Status))
1697 {
1698 return (Status);
1699 }
1700
1701 ParentTable = DtPeekSubtable ();
1702 DtInsertSubtable (ParentTable, Subtable);
1703
1704 /* Compile each ASCII namestring as a subtable */
1705
1706 while (*PFieldList)
1707 {
1708 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
1709 &Subtable);
1710 if (ACPI_FAILURE (Status))
1711 {
1712 return (Status);
1713 }
1714
1715 ParentTable = DtPeekSubtable ();
1716 DtInsertSubtable (ParentTable, Subtable);
1717 }
1718
1719 return (AE_OK);
1720 }
1721
1722
1723 /******************************************************************************
1724 *
1725 * FUNCTION: DtCompileTcpa
1726 *
1727 * PARAMETERS: PFieldList - Current field list pointer
1728 *
1729 * RETURN: Status
1730 *
1731 * DESCRIPTION: Compile TCPA.
1732 *
1733 *****************************************************************************/
1734
1735 ACPI_STATUS
1736 DtCompileTcpa (
1737 void **List)
1738 {
1739 DT_FIELD **PFieldList = (DT_FIELD **) List;
1740 DT_SUBTABLE *Subtable;
1741 ACPI_TABLE_TCPA_HDR *TcpaHeader;
1742 DT_SUBTABLE *ParentTable;
1743 ACPI_STATUS Status;
1744
1745
1746 /* Compile the main table */
1747
1748 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
1749 &Subtable);
1750 if (ACPI_FAILURE (Status))
1751 {
1752 return (Status);
1753 }
1754
1755 ParentTable = DtPeekSubtable ();
1756 DtInsertSubtable (ParentTable, Subtable);
1757
1758 /*
1759 * Examine the PlatformClass field to determine the table type.
1760 * Either a client or server table. Only one.
1761 */
1762 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
1763
1764 switch (TcpaHeader->PlatformClass)
1765 {
1766 case ACPI_TCPA_CLIENT_TABLE:
1767
1768 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
1769 &Subtable);
1770 break;
1771
1772 case ACPI_TCPA_SERVER_TABLE:
1773
1774 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
1775 &Subtable);
1776 break;
1777
1778 default:
1779
1780 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
1781 TcpaHeader->PlatformClass);
1782 Status = AE_ERROR;
1783 break;
1784 }
1785
1786 ParentTable = DtPeekSubtable ();
1787 DtInsertSubtable (ParentTable, Subtable);
1788 return (Status);
1789 }
1790
1791
1792 /******************************************************************************
1793 *
1794 * FUNCTION: DtCompileTpm2Rev3
1795 *
1796 * PARAMETERS: PFieldList - Current field list pointer
1797 *
1798 * RETURN: Status
1799 *
1800 * DESCRIPTION: Compile TPM2 revision 3
1801 *
1802 *****************************************************************************/
1803 static ACPI_STATUS
1804 DtCompileTpm2Rev3 (
1805 void **List)
1806 {
1807 DT_FIELD **PFieldList = (DT_FIELD **) List;
1808 DT_SUBTABLE *Subtable;
1809 ACPI_TABLE_TPM23 *Tpm23Header;
1810 DT_SUBTABLE *ParentTable;
1811 ACPI_STATUS Status = AE_OK;
1812
1813
1814 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
1815 &Subtable);
1816
1817 ParentTable = DtPeekSubtable ();
1818 DtInsertSubtable (ParentTable, Subtable);
1819 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
1820
1821 /* Subtable type depends on the StartMethod */
1822
1823 switch (Tpm23Header->StartMethod)
1824 {
1825 case ACPI_TPM23_ACPI_START_METHOD:
1826
1827 /* Subtable specific to to ARM_SMC */
1828
1829 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
1830 &Subtable);
1831 if (ACPI_FAILURE (Status))
1832 {
1833 return (Status);
1834 }
1835
1836 ParentTable = DtPeekSubtable ();
1837 DtInsertSubtable (ParentTable, Subtable);
1838 break;
1839
1840 default:
1841 break;
1842 }
1843
1844 return (Status);
1845 }
1846
1847
1848 /******************************************************************************
1849 *
1850 * FUNCTION: DtCompileTpm2
1851 *
1852 * PARAMETERS: PFieldList - Current field list pointer
1853 *
1854 * RETURN: Status
1855 *
1856 * DESCRIPTION: Compile TPM2.
1857 *
1858 *****************************************************************************/
1859
1860 ACPI_STATUS
1861 DtCompileTpm2 (
1862 void **List)
1863 {
1864 DT_FIELD **PFieldList = (DT_FIELD **) List;
1865 DT_SUBTABLE *Subtable;
1866 ACPI_TABLE_TPM2 *Tpm2Header;
1867 DT_SUBTABLE *ParentTable;
1868 ACPI_STATUS Status = AE_OK;
1869 ACPI_TABLE_HEADER *Header;
1870
1871
1872 ParentTable = DtPeekSubtable ();
1873
1874 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1875
1876 if (Header->Revision == 3)
1877 {
1878 return (DtCompileTpm2Rev3 (List));
1879 }
1880
1881 /* Compile the main table */
1882
1883 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
1884 &Subtable);
1885 if (ACPI_FAILURE (Status))
1886 {
1887 return (Status);
1888 }
1889
1890 ParentTable = DtPeekSubtable ();
1891 DtInsertSubtable (ParentTable, Subtable);
1892
1893 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
1894
1895 /* Method parameters */
1896 /* Optional: Log area minimum length */
1897 /* Optional: Log area start address */
1898 /* TBD: Optional fields above not fully implemented (not optional at this time) */
1899
1900 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
1901 &Subtable);
1902 if (ACPI_FAILURE (Status))
1903 {
1904 return (Status);
1905 }
1906
1907 ParentTable = DtPeekSubtable ();
1908 DtInsertSubtable (ParentTable, Subtable);
1909
1910
1911 /* Subtable type depends on the StartMethod */
1912
1913 switch (Tpm2Header->StartMethod)
1914 {
1915 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
1916
1917 /* Subtable specific to to ARM_SMC */
1918
1919 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
1920 &Subtable);
1921 if (ACPI_FAILURE (Status))
1922 {
1923 return (Status);
1924 }
1925
1926 ParentTable = DtPeekSubtable ();
1927 DtInsertSubtable (ParentTable, Subtable);
1928 break;
1929
1930 case ACPI_TPM2_START_METHOD:
1931 case ACPI_TPM2_MEMORY_MAPPED:
1932 case ACPI_TPM2_COMMAND_BUFFER:
1933 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
1934 break;
1935
1936 case ACPI_TPM2_RESERVED1:
1937 case ACPI_TPM2_RESERVED3:
1938 case ACPI_TPM2_RESERVED4:
1939 case ACPI_TPM2_RESERVED5:
1940 case ACPI_TPM2_RESERVED9:
1941 case ACPI_TPM2_RESERVED10:
1942
1943 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
1944 Tpm2Header->StartMethod);
1945 Status = AE_ERROR;
1946 break;
1947
1948 case ACPI_TPM2_NOT_ALLOWED:
1949 default:
1950
1951 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
1952 Tpm2Header->StartMethod);
1953 Status = AE_ERROR;
1954 break;
1955 }
1956
1957 return (Status);
1958 }
1959
1960
1961 /******************************************************************************
1962 *
1963 * FUNCTION: DtGetGenericTableInfo
1964 *
1965 * PARAMETERS: Name - Generic type name
1966 *
1967 * RETURN: Info entry
1968 *
1969 * DESCRIPTION: Obtain table info for a generic name entry
1970 *
1971 *****************************************************************************/
1972
1973 ACPI_DMTABLE_INFO *
1974 DtGetGenericTableInfo (
1975 char *Name)
1976 {
1977 ACPI_DMTABLE_INFO *Info;
1978 UINT32 i;
1979
1980
1981 if (!Name)
1982 {
1983 return (NULL);
1984 }
1985
1986 /* Search info table for name match */
1987
1988 for (i = 0; ; i++)
1989 {
1990 Info = AcpiDmTableInfoGeneric[i];
1991 if (Info->Opcode == ACPI_DMT_EXIT)
1992 {
1993 Info = NULL;
1994 break;
1995 }
1996
1997 /* Use caseless compare for generic keywords */
1998
1999 if (!AcpiUtStricmp (Name, Info->Name))
2000 {
2001 break;
2002 }
2003 }
2004
2005 return (Info);
2006 }
2007
2008
2009 /******************************************************************************
2010 *
2011 * FUNCTION: DtCompileUefi
2012 *
2013 * PARAMETERS: List - Current field list pointer
2014 *
2015 * RETURN: Status
2016 *
2017 * DESCRIPTION: Compile UEFI.
2018 *
2019 *****************************************************************************/
2020
2021 ACPI_STATUS
2022 DtCompileUefi (
2023 void **List)
2024 {
2025 ACPI_STATUS Status;
2026 DT_SUBTABLE *Subtable;
2027 DT_SUBTABLE *ParentTable;
2028 DT_FIELD **PFieldList = (DT_FIELD **) List;
2029 UINT16 *DataOffset;
2030
2031
2032 /* Compile the predefined portion of the UEFI table */
2033
2034 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2035 &Subtable);
2036 if (ACPI_FAILURE (Status))
2037 {
2038 return (Status);
2039 }
2040
2041 DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2042 *DataOffset = sizeof (ACPI_TABLE_UEFI);
2043
2044 ParentTable = DtPeekSubtable ();
2045 DtInsertSubtable (ParentTable, Subtable);
2046
2047 /*
2048 * Compile the "generic" portion of the UEFI table. This
2049 * part of the table is not predefined and any of the generic
2050 * operators may be used.
2051 */
2052 DtCompileGeneric ((void **) PFieldList, NULL, NULL);
2053 return (AE_OK);
2054 }
2055
2056
2057 /******************************************************************************
2058 *
2059 * FUNCTION: DtCompileVrtc
2060 *
2061 * PARAMETERS: List - Current field list pointer
2062 *
2063 * RETURN: Status
2064 *
2065 * DESCRIPTION: Compile VRTC.
2066 *
2067 *****************************************************************************/
2068
2069 ACPI_STATUS
2070 DtCompileVrtc (
2071 void **List)
2072 {
2073 ACPI_STATUS Status;
2074
2075
2076 Status = DtCompileTwoSubtables (List,
2077 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2078 return (Status);
2079 }
2080
2081
2082 /******************************************************************************
2083 *
2084 * FUNCTION: DtCompileWdat
2085 *
2086 * PARAMETERS: List - Current field list pointer
2087 *
2088 * RETURN: Status
2089 *
2090 * DESCRIPTION: Compile WDAT.
2091 *
2092 *****************************************************************************/
2093
2094 ACPI_STATUS
2095 DtCompileWdat (
2096 void **List)
2097 {
2098 ACPI_STATUS Status;
2099
2100
2101 Status = DtCompileTwoSubtables (List,
2102 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2103 return (Status);
2104 }
2105
2106
2107 /******************************************************************************
2108 *
2109 * FUNCTION: DtCompileWpbt
2110 *
2111 * PARAMETERS: List - Current field list pointer
2112 *
2113 * RETURN: Status
2114 *
2115 * DESCRIPTION: Compile WPBT.
2116 *
2117 *****************************************************************************/
2118
2119 ACPI_STATUS
2120 DtCompileWpbt (
2121 void **List)
2122 {
2123 DT_FIELD **PFieldList = (DT_FIELD **) List;
2124 DT_SUBTABLE *Subtable;
2125 DT_SUBTABLE *ParentTable;
2126 ACPI_TABLE_WPBT *Table;
2127 ACPI_STATUS Status;
2128 UINT16 Length;
2129
2130
2131 /* Compile the main table */
2132
2133 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
2134 &Subtable);
2135 if (ACPI_FAILURE (Status))
2136 {
2137 return (Status);
2138 }
2139
2140 ParentTable = DtPeekSubtable ();
2141 DtInsertSubtable (ParentTable, Subtable);
2142
2143 /* Compile the argument list subtable */
2144
2145 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
2146 &Subtable);
2147 if (ACPI_FAILURE (Status))
2148 {
2149 return (Status);
2150 }
2151
2152 /* Extract the length of the Arguments buffer, insert into main table */
2153
2154 Length = (UINT16) Subtable->TotalLength;
2155 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
2156 Table->ArgumentsLength = Length;
2157
2158 ParentTable = DtPeekSubtable ();
2159 DtInsertSubtable (ParentTable, Subtable);
2160 return (AE_OK);
2161 }
2162
2163
2164 /******************************************************************************
2165 *
2166 * FUNCTION: DtCompileXsdt
2167 *
2168 * PARAMETERS: List - Current field list pointer
2169 *
2170 * RETURN: Status
2171 *
2172 * DESCRIPTION: Compile XSDT.
2173 *
2174 *****************************************************************************/
2175
2176 ACPI_STATUS
2177 DtCompileXsdt (
2178 void **List)
2179 {
2180 DT_SUBTABLE *Subtable;
2181 DT_SUBTABLE *ParentTable;
2182 DT_FIELD *FieldList = *(DT_FIELD **) List;
2183 UINT64 Address;
2184
2185
2186 ParentTable = DtPeekSubtable ();
2187
2188 while (FieldList)
2189 {
2190 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2191
2192 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2193 DtInsertSubtable (ParentTable, Subtable);
2194 FieldList = FieldList->Next;
2195 }
2196
2197 return (AE_OK);
2198 }
2199
2200
2201 /******************************************************************************
2202 *
2203 * FUNCTION: DtCompileGeneric
2204 *
2205 * PARAMETERS: List - Current field list pointer
2206 * Name - Field name to end generic compiling
2207 * Length - Compiled table length to return
2208 *
2209 * RETURN: Status
2210 *
2211 * DESCRIPTION: Compile generic unknown table.
2212 *
2213 *****************************************************************************/
2214
2215 ACPI_STATUS
2216 DtCompileGeneric (
2217 void **List,
2218 char *Name,
2219 UINT32 *Length)
2220 {
2221 ACPI_STATUS Status;
2222 DT_SUBTABLE *Subtable;
2223 DT_SUBTABLE *ParentTable;
2224 DT_FIELD **PFieldList = (DT_FIELD **) List;
2225 ACPI_DMTABLE_INFO *Info;
2226
2227
2228 ParentTable = DtPeekSubtable ();
2229
2230 /*
2231 * Compile the "generic" portion of the table. This
2232 * part of the table is not predefined and any of the generic
2233 * operators may be used.
2234 */
2235
2236 /* Find any and all labels in the entire generic portion */
2237
2238 DtDetectAllLabels (*PFieldList);
2239
2240 /* Now we can actually compile the parse tree */
2241
2242 if (Length && *Length)
2243 {
2244 *Length = 0;
2245 }
2246 while (*PFieldList)
2247 {
2248 if (Name && !strcmp ((*PFieldList)->Name, Name))
2249 {
2250 break;
2251 }
2252
2253 Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2254 if (!Info)
2255 {
2256 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
2257 (*PFieldList)->Name);
2258 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2259 (*PFieldList), AslGbl_MsgBuffer);
2260
2261 *PFieldList = (*PFieldList)->Next;
2262 continue;
2263 }
2264
2265 Status = DtCompileTable (PFieldList, Info,
2266 &Subtable);
2267 if (ACPI_SUCCESS (Status))
2268 {
2269 DtInsertSubtable (ParentTable, Subtable);
2270 if (Length)
2271 {
2272 *Length += Subtable->Length;
2273 }
2274 }
2275 else
2276 {
2277 *PFieldList = (*PFieldList)->Next;
2278
2279 if (Status == AE_NOT_FOUND)
2280 {
2281 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
2282 (*PFieldList)->Name);
2283 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2284 (*PFieldList), AslGbl_MsgBuffer);
2285 }
2286 }
2287 }
2288
2289 return (AE_OK);
2290 }
2291