dttable2.c revision 1.1.1.18 1 /******************************************************************************
2 *
3 * Module Name: dttable2.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 /* Compile all complex data tables, signatures starting with L-Z */
45
46 #include "aslcompiler.h"
47
48 #define _COMPONENT DT_COMPILER
49 ACPI_MODULE_NAME ("dttable2")
50
51
52 /******************************************************************************
53 *
54 * FUNCTION: DtCompileLpit
55 *
56 * PARAMETERS: List - Current field list pointer
57 *
58 * RETURN: Status
59 *
60 * DESCRIPTION: Compile LPIT.
61 *
62 *****************************************************************************/
63
64 ACPI_STATUS
65 DtCompileLpit (
66 void **List)
67 {
68 ACPI_STATUS Status;
69 DT_SUBTABLE *Subtable;
70 DT_SUBTABLE *ParentTable;
71 DT_FIELD **PFieldList = (DT_FIELD **) List;
72 DT_FIELD *SubtableStart;
73 ACPI_DMTABLE_INFO *InfoTable;
74 ACPI_LPIT_HEADER *LpitHeader;
75
76
77 /* Note: Main table consists only of the standard ACPI table header */
78
79 while (*PFieldList)
80 {
81 SubtableStart = *PFieldList;
82
83 /* LPIT Subtable header */
84
85 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
86 &Subtable);
87 if (ACPI_FAILURE (Status))
88 {
89 return (Status);
90 }
91
92 ParentTable = DtPeekSubtable ();
93 DtInsertSubtable (ParentTable, Subtable);
94 DtPushSubtable (Subtable);
95
96 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
97
98 switch (LpitHeader->Type)
99 {
100 case ACPI_LPIT_TYPE_NATIVE_CSTATE:
101
102 InfoTable = AcpiDmTableInfoLpit0;
103 break;
104
105 default:
106
107 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
108 return (AE_ERROR);
109 }
110
111 /* LPIT Subtable */
112
113 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
114 if (ACPI_FAILURE (Status))
115 {
116 return (Status);
117 }
118
119 ParentTable = DtPeekSubtable ();
120 DtInsertSubtable (ParentTable, Subtable);
121 DtPopSubtable ();
122 }
123
124 return (AE_OK);
125 }
126
127
128 /******************************************************************************
129 *
130 * FUNCTION: DtCompileMadt
131 *
132 * PARAMETERS: List - Current field list pointer
133 *
134 * RETURN: Status
135 *
136 * DESCRIPTION: Compile MADT.
137 *
138 *****************************************************************************/
139
140 ACPI_STATUS
141 DtCompileMadt (
142 void **List)
143 {
144 ACPI_STATUS Status;
145 DT_SUBTABLE *Subtable;
146 DT_SUBTABLE *ParentTable;
147 DT_FIELD **PFieldList = (DT_FIELD **) List;
148 DT_FIELD *SubtableStart;
149 ACPI_TABLE_HEADER *Table;
150 ACPI_SUBTABLE_HEADER *MadtHeader;
151 ACPI_DMTABLE_INFO *InfoTable;
152 UINT8 Revision;
153
154
155 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
156 &Subtable);
157 if (ACPI_FAILURE (Status))
158 {
159 return (Status);
160 }
161
162 ParentTable = DtPeekSubtable ();
163 DtInsertSubtable (ParentTable, Subtable);
164
165 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
166 Revision = Table->Revision;
167
168 while (*PFieldList)
169 {
170 SubtableStart = *PFieldList;
171 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
172 &Subtable);
173 if (ACPI_FAILURE (Status))
174 {
175 return (Status);
176 }
177
178 ParentTable = DtPeekSubtable ();
179 DtInsertSubtable (ParentTable, Subtable);
180 DtPushSubtable (Subtable);
181
182 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
183
184 switch (MadtHeader->Type)
185 {
186 case ACPI_MADT_TYPE_LOCAL_APIC:
187
188 InfoTable = AcpiDmTableInfoMadt0;
189 break;
190
191 case ACPI_MADT_TYPE_IO_APIC:
192
193 InfoTable = AcpiDmTableInfoMadt1;
194 break;
195
196 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
197
198 InfoTable = AcpiDmTableInfoMadt2;
199 break;
200
201 case ACPI_MADT_TYPE_NMI_SOURCE:
202
203 InfoTable = AcpiDmTableInfoMadt3;
204 break;
205
206 case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
207
208 InfoTable = AcpiDmTableInfoMadt4;
209 break;
210
211 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
212
213 InfoTable = AcpiDmTableInfoMadt5;
214 break;
215
216 case ACPI_MADT_TYPE_IO_SAPIC:
217
218 InfoTable = AcpiDmTableInfoMadt6;
219 break;
220
221 case ACPI_MADT_TYPE_LOCAL_SAPIC:
222
223 InfoTable = AcpiDmTableInfoMadt7;
224 break;
225
226 case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
227
228 InfoTable = AcpiDmTableInfoMadt8;
229 break;
230
231 case ACPI_MADT_TYPE_LOCAL_X2APIC:
232
233 InfoTable = AcpiDmTableInfoMadt9;
234 break;
235
236 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
237
238 InfoTable = AcpiDmTableInfoMadt10;
239 break;
240
241 case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
242
243 if (Revision > 6)
244 InfoTable = AcpiDmTableInfoMadt11b;
245 else if (Revision == 6)
246 InfoTable = AcpiDmTableInfoMadt11a;
247 else
248 InfoTable = AcpiDmTableInfoMadt11;
249 break;
250
251 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
252
253 InfoTable = AcpiDmTableInfoMadt12;
254 break;
255
256 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
257
258 InfoTable = AcpiDmTableInfoMadt13;
259 break;
260
261 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
262
263 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt14a
264 : AcpiDmTableInfoMadt14;
265 break;
266
267 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
268
269 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt15a
270 : AcpiDmTableInfoMadt15;
271
272 break;
273
274 case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
275
276 InfoTable = AcpiDmTableInfoMadt16;
277 break;
278
279 case ACPI_MADT_TYPE_CORE_PIC:
280
281 InfoTable = AcpiDmTableInfoMadt17;
282 break;
283
284 case ACPI_MADT_TYPE_LIO_PIC:
285
286 InfoTable = AcpiDmTableInfoMadt18;
287 break;
288
289 case ACPI_MADT_TYPE_HT_PIC:
290
291 InfoTable = AcpiDmTableInfoMadt19;
292 break;
293
294 case ACPI_MADT_TYPE_EIO_PIC:
295
296 InfoTable = AcpiDmTableInfoMadt20;
297 break;
298
299 case ACPI_MADT_TYPE_MSI_PIC:
300
301 InfoTable = AcpiDmTableInfoMadt21;
302 break;
303
304 case ACPI_MADT_TYPE_BIO_PIC:
305
306 InfoTable = AcpiDmTableInfoMadt22;
307 break;
308
309 case ACPI_MADT_TYPE_LPC_PIC:
310
311 InfoTable = AcpiDmTableInfoMadt23;
312 break;
313
314 case ACPI_MADT_TYPE_RINTC:
315
316 InfoTable = AcpiDmTableInfoMadt24;
317 break;
318
319 case ACPI_MADT_TYPE_IMSIC:
320
321 InfoTable = AcpiDmTableInfoMadt25;
322 break;
323
324 case ACPI_MADT_TYPE_APLIC:
325
326 InfoTable = AcpiDmTableInfoMadt26;
327 break;
328
329 case ACPI_MADT_TYPE_PLIC:
330
331 InfoTable = AcpiDmTableInfoMadt27;
332 break;
333
334 default:
335
336 if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED)
337 {
338 InfoTable = AcpiDmTableInfoMadt128;
339 }
340 else
341 {
342 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
343 return (AE_ERROR);
344 }
345
346 break;
347 }
348
349 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
350 if (ACPI_FAILURE (Status))
351 {
352 return (Status);
353 }
354
355 ParentTable = DtPeekSubtable ();
356 DtInsertSubtable (ParentTable, Subtable);
357 DtPopSubtable ();
358 }
359
360 return (AE_OK);
361 }
362
363
364 /******************************************************************************
365 *
366 * FUNCTION: DtCompileMcfg
367 *
368 * PARAMETERS: List - Current field list pointer
369 *
370 * RETURN: Status
371 *
372 * DESCRIPTION: Compile MCFG.
373 *
374 *****************************************************************************/
375
376 ACPI_STATUS
377 DtCompileMcfg (
378 void **List)
379 {
380 ACPI_STATUS Status;
381
382
383 Status = DtCompileTwoSubtables (List,
384 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
385 return (Status);
386 }
387
388 /******************************************************************************
389 *
390 * FUNCTION: DtCompileMpam
391 *
392 * PARAMETERS: List - Current field list pointer
393 *
394 * RETURN: Status
395 *
396 * DESCRIPTION: Compile MPAM.
397 *
398 *****************************************************************************/
399
400 ACPI_STATUS
401 DtCompileMpam (
402 void **List)
403 {
404 ACPI_STATUS Status;
405 DT_SUBTABLE *ParentTable;
406 DT_SUBTABLE *Subtable;
407 DT_FIELD *SubtableStart;
408 DT_FIELD **PFieldList = (DT_FIELD **) List;
409 ACPI_MPAM_MSC_NODE *MpamMscNode;
410 ACPI_MPAM_RESOURCE_NODE *MpamResourceNode;
411 UINT32 FuncDepsCount;
412 UINT32 RisLength;
413 ACPI_DMTABLE_INFO *InfoTable;
414
415 ParentTable = DtPeekSubtable ();
416
417 while (*PFieldList)
418 {
419 SubtableStart = *PFieldList;
420
421 /* Main MSC Node table */
422 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0,
423 &Subtable);
424 if (ACPI_FAILURE (Status))
425 {
426 return (Status);
427 }
428
429 MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer);
430
431 ParentTable = DtPeekSubtable ();
432 DtInsertSubtable (ParentTable, Subtable);
433 DtPushSubtable (Subtable);
434
435 ParentTable = DtPeekSubtable ();
436
437 /*
438 * RIS(es) per MSC node have variable lengths depending on how many RISes there and
439 * any how many functional dependencies per RIS. Calculate it in order
440 * to properly set the overall MSC length.
441 */
442 RisLength = 0;
443
444 /* Iterate over RIS subtables per MSC node */
445 for (UINT32 ris = 0; ris < MpamMscNode->NumResourceNodes; ris++)
446 {
447 /* Compile RIS subtable */
448 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1,
449 &Subtable);
450 if (ACPI_FAILURE (Status))
451 {
452 return (Status);
453 }
454
455 MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer);
456 DtInsertSubtable (ParentTable, Subtable);
457 DtPushSubtable (Subtable);
458
459 ParentTable = DtPeekSubtable ();
460
461 switch (MpamResourceNode->LocatorType)
462 {
463 case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE:
464 InfoTable = AcpiDmTableInfoMpam1A;
465 break;
466 case ACPI_MPAM_LOCATION_TYPE_MEMORY:
467 InfoTable = AcpiDmTableInfoMpam1B;
468 break;
469 case ACPI_MPAM_LOCATION_TYPE_SMMU:
470 InfoTable = AcpiDmTableInfoMpam1C;
471 break;
472 case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE:
473 InfoTable = AcpiDmTableInfoMpam1D;
474 break;
475 case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE:
476 InfoTable = AcpiDmTableInfoMpam1E;
477 break;
478 case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT:
479 InfoTable = AcpiDmTableInfoMpam1F;
480 break;
481 case ACPI_MPAM_LOCATION_TYPE_UNKNOWN:
482 InfoTable = AcpiDmTableInfoMpam1G;
483 default:
484 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type");
485 return (AE_ERROR);
486 }
487
488 /* Compile Resource Locator Table */
489 Status = DtCompileTable (PFieldList, InfoTable,
490 &Subtable);
491
492 if (ACPI_FAILURE (Status))
493 {
494 return (Status);
495 }
496
497 DtInsertSubtable (ParentTable, Subtable);
498
499 /* Compile the number of functional dependencies per RIS */
500 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps,
501 &Subtable);
502
503 if (ACPI_FAILURE (Status))
504 {
505 return (Status);
506 }
507
508 DtInsertSubtable (ParentTable, Subtable);
509 FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
510
511 RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) +
512 FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS);
513
514 /* Iterate over functional dependencies per RIS */
515 for (UINT32 funcDep = 0; funcDep < FuncDepsCount; funcDep++)
516 {
517 /* Compiler functional dependencies table */
518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2,
519 &Subtable);
520
521 if (ACPI_FAILURE (Status))
522 {
523 return (Status);
524 }
525
526 DtInsertSubtable (ParentTable, Subtable);
527 }
528
529 DtPopSubtable ();
530 }
531
532 /* Check if the length of the MSC is correct and override with the correct length */
533 if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength)
534 {
535 MpamMscNode->Length = (UINT16) (sizeof(ACPI_MPAM_MSC_NODE) + RisLength);
536 DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length);
537 }
538
539 DtPopSubtable ();
540 }
541
542 return (AE_OK);
543 }
544
545
546 /******************************************************************************
547 *
548 * FUNCTION: DtCompileMpst
549 *
550 * PARAMETERS: List - Current field list pointer
551 *
552 * RETURN: Status
553 *
554 * DESCRIPTION: Compile MPST.
555 *
556 *****************************************************************************/
557
558 ACPI_STATUS
559 DtCompileMpst (
560 void **List)
561 {
562 ACPI_STATUS Status;
563 DT_SUBTABLE *Subtable;
564 DT_SUBTABLE *ParentTable;
565 DT_FIELD **PFieldList = (DT_FIELD **) List;
566 ACPI_MPST_CHANNEL *MpstChannelInfo;
567 ACPI_MPST_POWER_NODE *MpstPowerNode;
568 ACPI_MPST_DATA_HDR *MpstDataHeader;
569 UINT16 SubtableCount;
570 UINT32 PowerStateCount;
571 UINT32 ComponentCount;
572
573
574 /* Main table */
575
576 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable);
577 if (ACPI_FAILURE (Status))
578 {
579 return (Status);
580 }
581
582 ParentTable = DtPeekSubtable ();
583 DtInsertSubtable (ParentTable, Subtable);
584 DtPushSubtable (Subtable);
585
586 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
587 SubtableCount = MpstChannelInfo->PowerNodeCount;
588
589 while (*PFieldList && SubtableCount)
590 {
591 /* Subtable: Memory Power Node(s) */
592
593 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
594 &Subtable);
595 if (ACPI_FAILURE (Status))
596 {
597 return (Status);
598 }
599
600 ParentTable = DtPeekSubtable ();
601 DtInsertSubtable (ParentTable, Subtable);
602 DtPushSubtable (Subtable);
603
604 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
605 PowerStateCount = MpstPowerNode->NumPowerStates;
606 ComponentCount = MpstPowerNode->NumPhysicalComponents;
607
608 ParentTable = DtPeekSubtable ();
609
610 /* Sub-subtables - Memory Power State Structure(s) */
611
612 while (*PFieldList && PowerStateCount)
613 {
614 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
615 &Subtable);
616 if (ACPI_FAILURE (Status))
617 {
618 return (Status);
619 }
620
621 DtInsertSubtable (ParentTable, Subtable);
622 PowerStateCount--;
623 }
624
625 /* Sub-subtables - Physical Component ID Structure(s) */
626
627 while (*PFieldList && ComponentCount)
628 {
629 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
630 &Subtable);
631 if (ACPI_FAILURE (Status))
632 {
633 return (Status);
634 }
635
636 DtInsertSubtable (ParentTable, Subtable);
637 ComponentCount--;
638 }
639
640 SubtableCount--;
641 DtPopSubtable ();
642 }
643
644 /* Subtable: Count of Memory Power State Characteristic structures */
645
646 DtPopSubtable ();
647
648 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable);
649 if (ACPI_FAILURE (Status))
650 {
651 return (Status);
652 }
653
654 ParentTable = DtPeekSubtable ();
655 DtInsertSubtable (ParentTable, Subtable);
656 DtPushSubtable (Subtable);
657
658 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
659 SubtableCount = MpstDataHeader->CharacteristicsCount;
660
661 ParentTable = DtPeekSubtable ();
662
663 /* Subtable: Memory Power State Characteristics structure(s) */
664
665 while (*PFieldList && SubtableCount)
666 {
667 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
668 &Subtable);
669 if (ACPI_FAILURE (Status))
670 {
671 return (Status);
672 }
673
674 DtInsertSubtable (ParentTable, Subtable);
675 SubtableCount--;
676 }
677
678 DtPopSubtable ();
679 return (AE_OK);
680 }
681
682
683 /******************************************************************************
684 *
685 * FUNCTION: DtCompileMsct
686 *
687 * PARAMETERS: List - Current field list pointer
688 *
689 * RETURN: Status
690 *
691 * DESCRIPTION: Compile MSCT.
692 *
693 *****************************************************************************/
694
695 ACPI_STATUS
696 DtCompileMsct (
697 void **List)
698 {
699 ACPI_STATUS Status;
700
701
702 Status = DtCompileTwoSubtables (List,
703 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
704 return (Status);
705 }
706
707
708 /******************************************************************************
709 *
710 * FUNCTION: DtCompileNfit
711 *
712 * PARAMETERS: List - Current field list pointer
713 *
714 * RETURN: Status
715 *
716 * DESCRIPTION: Compile NFIT.
717 *
718 *****************************************************************************/
719
720 ACPI_STATUS
721 DtCompileNfit (
722 void **List)
723 {
724 ACPI_STATUS Status;
725 DT_SUBTABLE *Subtable;
726 DT_SUBTABLE *ParentTable;
727 DT_FIELD **PFieldList = (DT_FIELD **) List;
728 DT_FIELD *SubtableStart;
729 ACPI_NFIT_HEADER *NfitHeader;
730 ACPI_DMTABLE_INFO *InfoTable;
731 UINT32 Count;
732 ACPI_NFIT_INTERLEAVE *Interleave = NULL;
733 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
734
735
736 /* Main table */
737
738 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
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 /* Subtables */
750
751 while (*PFieldList)
752 {
753 SubtableStart = *PFieldList;
754 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
755 &Subtable);
756 if (ACPI_FAILURE (Status))
757 {
758 return (Status);
759 }
760
761 ParentTable = DtPeekSubtable ();
762 DtInsertSubtable (ParentTable, Subtable);
763 DtPushSubtable (Subtable);
764
765 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
766
767 switch (NfitHeader->Type)
768 {
769 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
770
771 InfoTable = AcpiDmTableInfoNfit0;
772 break;
773
774 case ACPI_NFIT_TYPE_MEMORY_MAP:
775
776 InfoTable = AcpiDmTableInfoNfit1;
777 break;
778
779 case ACPI_NFIT_TYPE_INTERLEAVE:
780
781 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
782 InfoTable = AcpiDmTableInfoNfit2;
783 break;
784
785 case ACPI_NFIT_TYPE_SMBIOS:
786
787 InfoTable = AcpiDmTableInfoNfit3;
788 break;
789
790 case ACPI_NFIT_TYPE_CONTROL_REGION:
791
792 InfoTable = AcpiDmTableInfoNfit4;
793 break;
794
795 case ACPI_NFIT_TYPE_DATA_REGION:
796
797 InfoTable = AcpiDmTableInfoNfit5;
798 break;
799
800 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
801
802 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
803 InfoTable = AcpiDmTableInfoNfit6;
804 break;
805
806 case ACPI_NFIT_TYPE_CAPABILITIES:
807
808 InfoTable = AcpiDmTableInfoNfit7;
809 break;
810
811 default:
812
813 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
814 return (AE_ERROR);
815 }
816
817 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
818 if (ACPI_FAILURE (Status))
819 {
820 return (Status);
821 }
822
823 ParentTable = DtPeekSubtable ();
824 DtInsertSubtable (ParentTable, Subtable);
825 DtPopSubtable ();
826
827 switch (NfitHeader->Type)
828 {
829 case ACPI_NFIT_TYPE_INTERLEAVE:
830
831 Count = 0;
832 DtPushSubtable (Subtable);
833 while (*PFieldList)
834 {
835 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
836 &Subtable);
837 if (ACPI_FAILURE (Status))
838 {
839 return (Status);
840 }
841
842 if (!Subtable)
843 {
844 DtPopSubtable ();
845 break;
846 }
847
848 ParentTable = DtPeekSubtable ();
849 DtInsertSubtable (ParentTable, Subtable);
850 Count++;
851 }
852
853 Interleave->LineCount = Count;
854 break;
855
856 case ACPI_NFIT_TYPE_SMBIOS:
857
858 if (*PFieldList)
859 {
860 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
861 &Subtable);
862 if (ACPI_FAILURE (Status))
863 {
864 return (Status);
865 }
866
867 if (Subtable)
868 {
869 DtInsertSubtable (ParentTable, Subtable);
870 }
871 }
872 break;
873
874 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
875
876 Count = 0;
877 DtPushSubtable (Subtable);
878 while (*PFieldList)
879 {
880 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
881 &Subtable);
882 if (ACPI_FAILURE (Status))
883 {
884 return (Status);
885 }
886
887 if (!Subtable)
888 {
889 DtPopSubtable ();
890 break;
891 }
892
893 ParentTable = DtPeekSubtable ();
894 DtInsertSubtable (ParentTable, Subtable);
895 Count++;
896 }
897
898 Hint->HintCount = (UINT16) Count;
899 break;
900
901 default:
902 break;
903 }
904 }
905
906 return (AE_OK);
907 }
908
909
910 /******************************************************************************
911 *
912 * FUNCTION: DtCompilePcct
913 *
914 * PARAMETERS: List - Current field list pointer
915 *
916 * RETURN: Status
917 *
918 * DESCRIPTION: Compile PCCT.
919 *
920 *****************************************************************************/
921
922 ACPI_STATUS
923 DtCompilePcct (
924 void **List)
925 {
926 ACPI_STATUS Status;
927 DT_SUBTABLE *Subtable;
928 DT_SUBTABLE *ParentTable;
929 DT_FIELD **PFieldList = (DT_FIELD **) List;
930 DT_FIELD *SubtableStart;
931 ACPI_SUBTABLE_HEADER *PcctHeader;
932 ACPI_DMTABLE_INFO *InfoTable;
933
934
935 /* Main table */
936
937 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
938 &Subtable);
939 if (ACPI_FAILURE (Status))
940 {
941 return (Status);
942 }
943
944 ParentTable = DtPeekSubtable ();
945 DtInsertSubtable (ParentTable, Subtable);
946
947 /* Subtables */
948
949 while (*PFieldList)
950 {
951 SubtableStart = *PFieldList;
952 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
953 &Subtable);
954 if (ACPI_FAILURE (Status))
955 {
956 return (Status);
957 }
958
959 ParentTable = DtPeekSubtable ();
960 DtInsertSubtable (ParentTable, Subtable);
961 DtPushSubtable (Subtable);
962
963 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
964
965 switch (PcctHeader->Type)
966 {
967 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
968
969 InfoTable = AcpiDmTableInfoPcct0;
970 break;
971
972 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
973
974 InfoTable = AcpiDmTableInfoPcct1;
975 break;
976
977 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
978
979 InfoTable = AcpiDmTableInfoPcct2;
980 break;
981
982 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
983
984 InfoTable = AcpiDmTableInfoPcct3;
985 break;
986
987 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
988
989 InfoTable = AcpiDmTableInfoPcct4;
990 break;
991
992 case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
993
994 InfoTable = AcpiDmTableInfoPcct5;
995 break;
996
997 default:
998
999 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1000 return (AE_ERROR);
1001 }
1002
1003 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1004 if (ACPI_FAILURE (Status))
1005 {
1006 return (Status);
1007 }
1008
1009 ParentTable = DtPeekSubtable ();
1010 DtInsertSubtable (ParentTable, Subtable);
1011 DtPopSubtable ();
1012 }
1013
1014 return (AE_OK);
1015 }
1016
1017
1018 /******************************************************************************
1019 *
1020 * FUNCTION: DtCompilePdtt
1021 *
1022 * PARAMETERS: List - Current field list pointer
1023 *
1024 * RETURN: Status
1025 *
1026 * DESCRIPTION: Compile PDTT.
1027 *
1028 *****************************************************************************/
1029
1030 ACPI_STATUS
1031 DtCompilePdtt (
1032 void **List)
1033 {
1034 ACPI_STATUS Status;
1035 DT_SUBTABLE *Subtable;
1036 DT_SUBTABLE *ParentTable;
1037 DT_FIELD **PFieldList = (DT_FIELD **) List;
1038 ACPI_TABLE_PDTT *PdttHeader;
1039 UINT32 Count = 0;
1040
1041
1042 /* Main table */
1043
1044 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
1045 if (ACPI_FAILURE (Status))
1046 {
1047 return (Status);
1048 }
1049
1050 ParentTable = DtPeekSubtable ();
1051 DtInsertSubtable (ParentTable, Subtable);
1052
1053 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
1054 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
1055
1056 /* There is only one type of subtable at this time, no need to decode */
1057
1058 while (*PFieldList)
1059 {
1060 /* List of subchannel IDs, each 2 bytes */
1061
1062 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
1063 &Subtable);
1064 if (ACPI_FAILURE (Status))
1065 {
1066 return (Status);
1067 }
1068
1069 DtInsertSubtable (ParentTable, Subtable);
1070 Count++;
1071 }
1072
1073 PdttHeader->TriggerCount = (UINT8) Count;
1074 return (AE_OK);
1075 }
1076
1077
1078 /******************************************************************************
1079 *
1080 * FUNCTION: DtCompilePhat
1081 *
1082 * PARAMETERS: List - Current field list pointer
1083 *
1084 * RETURN: Status
1085 *
1086 * DESCRIPTION: Compile Phat.
1087 *
1088 *****************************************************************************/
1089
1090 ACPI_STATUS
1091 DtCompilePhat (
1092 void **List)
1093 {
1094 ACPI_STATUS Status = AE_OK;
1095 DT_SUBTABLE *Subtable;
1096 DT_SUBTABLE *ParentTable;
1097 DT_FIELD **PFieldList = (DT_FIELD **) List;
1098 ACPI_PHAT_HEADER *PhatHeader;
1099 ACPI_DMTABLE_INFO *Info;
1100 ACPI_PHAT_VERSION_DATA *VersionData;
1101 UINT32 DeviceDataLength;
1102 UINT32 RecordCount;
1103 DT_FIELD *DataOffsetField;
1104 DT_FIELD *DevicePathField;
1105 UINT32 TableOffset = 0;
1106 UINT32 DataOffsetValue;
1107 UINT32 i;
1108
1109
1110 /* The table consists of subtables */
1111
1112 while (*PFieldList)
1113 {
1114 /* Compile the common subtable header */
1115
1116 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
1117 if (ACPI_FAILURE (Status))
1118 {
1119 return (Status);
1120 }
1121
1122 TableOffset += Subtable->Length;
1123 DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length);
1124
1125 ParentTable = DtPeekSubtable ();
1126 DtInsertSubtable (ParentTable, Subtable);
1127 DtPushSubtable (Subtable);
1128
1129 PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
1130
1131 switch (PhatHeader->Type)
1132 {
1133 case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1134
1135 /* Compile the middle portion of the Firmware Version Data */
1136
1137 Info = AcpiDmTableInfoPhat0;
1138 PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
1139 DataOffsetField = NULL;
1140 break;
1141
1142 case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1143
1144 DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n",
1145 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length);
1146
1147 DataOffsetField = *PFieldList;
1148
1149 /* Walk the field list to get to the "Device-specific data Offset" field */
1150
1151 TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA);
1152 for (i = 0; i < 3; i++)
1153 {
1154 DataOffsetField = DataOffsetField->Next;
1155 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n",
1156 TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
1157 }
1158
1159 /* Convert DataOffsetField->Value (a char * string) to an integer value */
1160
1161 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
1162
1163 /*
1164 * Get the next field (Device Path):
1165 * DataOffsetField points to "Device-Specific Offset", next field is
1166 * "Device Path".
1167 */
1168 DevicePathField = DataOffsetField->Next;
1169
1170 /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */
1171
1172 DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2;
1173 TableOffset += DevicePathField->StringLength;
1174
1175 DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n",
1176 TableOffset, Subtable->Length, DevicePathField->StringLength);
1177
1178 /* Set the DataOffsetField to the current TableOffset */
1179 /* Must set the DataOffsetField here (not later) */
1180
1181 if (DataOffsetValue != 0)
1182 {
1183 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset);
1184 }
1185
1186 DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length);
1187
1188 DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: "
1189 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n",
1190 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength,
1191 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset);
1192
1193 /* Compile the middle portion of the Health Data Record */
1194
1195 Info = AcpiDmTableInfoPhat1;
1196 PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
1197 break;
1198
1199 default:
1200
1201 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1202 return (AE_ERROR);
1203 }
1204
1205 /* Compile either the Version Data or the Health Data */
1206
1207 Status = DtCompileTable (PFieldList, Info, &Subtable);
1208 if (ACPI_FAILURE (Status))
1209 {
1210 return (Status);
1211 }
1212
1213 DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n",
1214 TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length);
1215
1216 ParentTable = DtPeekSubtable ();
1217 DtInsertSubtable (ParentTable, Subtable);
1218
1219 switch (PhatHeader->Type)
1220 {
1221 case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1222
1223 VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
1224 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
1225 RecordCount = VersionData->ElementCount;
1226
1227 /* Compile all of the Version Elements */
1228
1229 while (RecordCount)
1230 {
1231 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
1232 &Subtable);
1233 if (ACPI_FAILURE (Status))
1234 {
1235 return (Status);
1236 }
1237
1238 ParentTable = DtPeekSubtable ();
1239 DtInsertSubtable (ParentTable, Subtable);
1240
1241 TableOffset += Subtable->Length;
1242 RecordCount--;
1243 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
1244 }
1245
1246 DtPopSubtable ();
1247 break;
1248
1249 case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1250
1251 /* Compile the Device Path */
1252
1253 DeviceDataLength = Subtable->Length;
1254 TableOffset += Subtable->Length;
1255
1256 DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: "
1257 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength,
1258 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value,
1259 Subtable->Length, TableOffset);
1260
1261 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
1262 if (ACPI_FAILURE (Status))
1263 {
1264 return (Status);
1265 }
1266 ParentTable = DtPeekSubtable ();
1267 DtInsertSubtable (ParentTable, Subtable);
1268
1269 /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */
1270
1271 if (!*PFieldList)
1272 {
1273 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n");
1274 return (AE_OK);
1275 }
1276
1277 DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s"
1278 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n",
1279 DeviceDataLength, (*PFieldList)->Name, TableOffset,
1280 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length);
1281
1282 PhatHeader->Length += (UINT16) Subtable->Length;
1283
1284 /* Convert DataOffsetField->Value (a hex char * string) to an integer value */
1285
1286 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
1287
1288 DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n",
1289 DataOffsetValue, TableOffset);
1290 if (DataOffsetValue != 0)
1291 {
1292 /* Compile Device-Specific Data - only if the Data Offset is non-zero */
1293
1294 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
1295 if (ACPI_FAILURE (Status))
1296 {
1297 return (Status);
1298 }
1299
1300 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n",
1301 Subtable, TableOffset);
1302 if (Subtable)
1303 {
1304 DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: "
1305 "%X FieldName \"%s\" SubtableLength %X\n",
1306 DeviceDataLength, DataOffsetField->Name, Subtable->Length);
1307
1308 DeviceDataLength += Subtable->Length;
1309
1310 ParentTable = DtPeekSubtable ();
1311 DtInsertSubtable (ParentTable, Subtable);
1312
1313 PhatHeader->Length += (UINT16) Subtable->Length;
1314 }
1315 }
1316
1317 DtPopSubtable ();
1318
1319 DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n",
1320 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
1321 break;
1322
1323 default:
1324
1325 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1326 return (AE_ERROR);
1327 }
1328 }
1329
1330 return (Status);
1331 }
1332
1333
1334 /******************************************************************************
1335 *
1336 * FUNCTION: DtCompilePmtt
1337 *
1338 * PARAMETERS: List - Current field list pointer
1339 *
1340 * RETURN: Status
1341 *
1342 * DESCRIPTION: Compile PMTT.
1343 *
1344 *****************************************************************************/
1345
1346 ACPI_STATUS
1347 DtCompilePmtt (
1348 void **List)
1349 {
1350 ACPI_STATUS Status;
1351 DT_SUBTABLE *Subtable;
1352 DT_SUBTABLE *ParentTable;
1353 DT_FIELD **PFieldList = (DT_FIELD **) List;
1354 DT_FIELD *SubtableStart;
1355 UINT16 Type;
1356
1357
1358 /* Main table */
1359
1360 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
1361 if (ACPI_FAILURE (Status))
1362 {
1363 return (Status);
1364 }
1365
1366 ParentTable = DtPeekSubtable ();
1367 DtInsertSubtable (ParentTable, Subtable);
1368 DtPushSubtable (Subtable);
1369
1370 /* Subtables */
1371
1372 while (*PFieldList)
1373 {
1374 SubtableStart = *PFieldList;
1375 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1376
1377 switch (Type)
1378 {
1379 case ACPI_PMTT_TYPE_SOCKET:
1380
1381 /* Subtable: Socket Structure */
1382
1383 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
1384
1385 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1386 &Subtable);
1387 if (ACPI_FAILURE (Status))
1388 {
1389 return (Status);
1390 }
1391
1392 break;
1393
1394 case ACPI_PMTT_TYPE_CONTROLLER:
1395
1396 /* Subtable: Memory Controller Structure */
1397
1398 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
1399
1400 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1401 &Subtable);
1402 if (ACPI_FAILURE (Status))
1403 {
1404 return (Status);
1405 }
1406
1407 break;
1408
1409 case ACPI_PMTT_TYPE_DIMM:
1410
1411 /* Subtable: Physical Component (DIMM) Structure */
1412
1413 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
1414 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1415 &Subtable);
1416 if (ACPI_FAILURE (Status))
1417 {
1418 return (Status);
1419 }
1420
1421 break;
1422
1423 case ACPI_PMTT_TYPE_VENDOR:
1424
1425 /* Subtable: Vendor-specific Structure */
1426
1427 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
1428 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
1429 &Subtable);
1430 if (ACPI_FAILURE (Status))
1431 {
1432 return (Status);
1433 }
1434
1435 break;
1436
1437 default:
1438
1439 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1440 return (AE_ERROR);
1441 }
1442
1443 DtInsertSubtable (ParentTable, Subtable);
1444 }
1445
1446 return (Status);
1447 }
1448
1449
1450 /******************************************************************************
1451 *
1452 * FUNCTION: DtCompilePptt
1453 *
1454 * PARAMETERS: List - Current field list pointer
1455 *
1456 * RETURN: Status
1457 *
1458 * DESCRIPTION: Compile PPTT.
1459 *
1460 *****************************************************************************/
1461
1462 ACPI_STATUS
1463 DtCompilePptt (
1464 void **List)
1465 {
1466 ACPI_STATUS Status;
1467 ACPI_SUBTABLE_HEADER *PpttHeader;
1468 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL;
1469 DT_SUBTABLE *Subtable;
1470 DT_SUBTABLE *ParentTable;
1471 ACPI_DMTABLE_INFO *InfoTable;
1472 DT_FIELD **PFieldList = (DT_FIELD **) List;
1473 DT_FIELD *SubtableStart;
1474 ACPI_TABLE_HEADER *PpttAcpiHeader;
1475
1476
1477 ParentTable = DtPeekSubtable ();
1478 while (*PFieldList)
1479 {
1480 SubtableStart = *PFieldList;
1481
1482 /* Compile PPTT subtable header */
1483
1484 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1485 &Subtable);
1486 if (ACPI_FAILURE (Status))
1487 {
1488 return (Status);
1489 }
1490 DtInsertSubtable (ParentTable, Subtable);
1491 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1492 PpttHeader->Length = (UINT8)(Subtable->Length);
1493
1494 switch (PpttHeader->Type)
1495 {
1496 case ACPI_PPTT_TYPE_PROCESSOR:
1497
1498 InfoTable = AcpiDmTableInfoPptt0;
1499 break;
1500
1501 case ACPI_PPTT_TYPE_CACHE:
1502
1503 InfoTable = AcpiDmTableInfoPptt1;
1504 break;
1505
1506 case ACPI_PPTT_TYPE_ID:
1507
1508 InfoTable = AcpiDmTableInfoPptt2;
1509 break;
1510
1511 default:
1512
1513 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1514 return (AE_ERROR);
1515 }
1516
1517 /* Compile PPTT subtable body */
1518
1519 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1520 if (ACPI_FAILURE (Status))
1521 {
1522 return (Status);
1523 }
1524 DtInsertSubtable (ParentTable, Subtable);
1525 PpttHeader->Length += (UINT8)(Subtable->Length);
1526
1527 /* Compile PPTT subtable additional */
1528
1529 switch (PpttHeader->Type)
1530 {
1531 case ACPI_PPTT_TYPE_PROCESSOR:
1532
1533 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1534 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1535 if (PpttProcessor)
1536 {
1537 /* Compile initiator proximity domain list */
1538
1539 PpttProcessor->NumberOfPrivResources = 0;
1540 while (*PFieldList)
1541 {
1542 Status = DtCompileTable (PFieldList,
1543 AcpiDmTableInfoPptt0a, &Subtable);
1544 if (ACPI_FAILURE (Status))
1545 {
1546 return (Status);
1547 }
1548 if (!Subtable)
1549 {
1550 break;
1551 }
1552
1553 DtInsertSubtable (ParentTable, Subtable);
1554 PpttHeader->Length += (UINT8)(Subtable->Length);
1555 PpttProcessor->NumberOfPrivResources++;
1556 }
1557 }
1558 break;
1559
1560 case ACPI_PPTT_TYPE_CACHE:
1561
1562 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1563 AslGbl_RootTable->Buffer);
1564 if (PpttAcpiHeader->Revision < 3)
1565 {
1566 break;
1567 }
1568 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
1569 &Subtable);
1570 DtInsertSubtable (ParentTable, Subtable);
1571 PpttHeader->Length += (UINT8)(Subtable->Length);
1572 break;
1573
1574 default:
1575
1576 break;
1577 }
1578 }
1579
1580 return (AE_OK);
1581 }
1582
1583
1584 /******************************************************************************
1585 *
1586 * FUNCTION: DtCompilePrmt
1587 *
1588 * PARAMETERS: List - Current field list pointer
1589 *
1590 * RETURN: Status
1591 *
1592 * DESCRIPTION: Compile PRMT.
1593 *
1594 *****************************************************************************/
1595
1596 ACPI_STATUS
1597 DtCompilePrmt (
1598 void **List)
1599 {
1600 ACPI_STATUS Status;
1601 ACPI_TABLE_PRMT_HEADER *PrmtHeader;
1602 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo;
1603 DT_SUBTABLE *Subtable;
1604 DT_SUBTABLE *ParentTable;
1605 DT_FIELD **PFieldList = (DT_FIELD **) List;
1606 UINT32 i, j;
1607
1608 ParentTable = DtPeekSubtable ();
1609
1610 /* Compile PRMT subtable header */
1611
1612 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
1613 &Subtable);
1614 if (ACPI_FAILURE (Status))
1615 {
1616 return (Status);
1617 }
1618 DtInsertSubtable (ParentTable, Subtable);
1619 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
1620
1621 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
1622 {
1623 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
1624 &Subtable);
1625 if (ACPI_FAILURE (Status))
1626 {
1627 return (Status);
1628 }
1629 DtInsertSubtable (ParentTable, Subtable);
1630 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
1631
1632 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
1633 {
1634 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
1635 &Subtable);
1636 if (ACPI_FAILURE (Status))
1637 {
1638 return (Status);
1639 }
1640 DtInsertSubtable (ParentTable, Subtable);
1641 }
1642 }
1643
1644 return (AE_OK);
1645 }
1646
1647
1648 /******************************************************************************
1649 *
1650 * FUNCTION: DtCompileRas2
1651 *
1652 * PARAMETERS: List - Current field list pointer
1653 *
1654 * RETURN: Status
1655 *
1656 * DESCRIPTION: Compile RAS2.
1657 *
1658 *****************************************************************************/
1659
1660 ACPI_STATUS
1661 DtCompileRas2 (
1662 void **List)
1663 {
1664 ACPI_STATUS Status;
1665 DT_SUBTABLE *Subtable;
1666 DT_SUBTABLE *ParentTable;
1667 DT_FIELD **PFieldList = (DT_FIELD **) List;
1668 ACPI_TABLE_RAS2 *Ras2Header;
1669 UINT32 Count = 0;
1670
1671
1672 /* Main table */
1673
1674 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable);
1675 if (ACPI_FAILURE (Status))
1676 {
1677 return (Status);
1678 }
1679
1680 ParentTable = DtPeekSubtable ();
1681 DtInsertSubtable (ParentTable, Subtable);
1682
1683 Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer);
1684
1685 /* There is only one type of subtable at this time, no need to decode */
1686
1687 while (*PFieldList)
1688 {
1689 /* List of RAS2 PCC descriptors, each 8 bytes */
1690
1691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc,
1692 &Subtable);
1693 if (ACPI_FAILURE (Status))
1694 {
1695 return (Status);
1696 }
1697
1698 DtInsertSubtable (ParentTable, Subtable);
1699 Count++;
1700 }
1701
1702 Ras2Header->NumPccDescs = (UINT8) Count;
1703 return (AE_OK);
1704 }
1705
1706
1707 /******************************************************************************
1708 *
1709 * FUNCTION: DtCompileRgrt
1710 *
1711 * PARAMETERS: List - Current field list pointer
1712 *
1713 * RETURN: Status
1714 *
1715 * DESCRIPTION: Compile RGRT.
1716 *
1717 *****************************************************************************/
1718
1719 ACPI_STATUS
1720 DtCompileRgrt (
1721 void **List)
1722 {
1723 ACPI_STATUS Status;
1724 DT_SUBTABLE *Subtable;
1725 DT_SUBTABLE *ParentTable;
1726 DT_FIELD **PFieldList = (DT_FIELD **) List;
1727
1728
1729 /* Compile the main table */
1730
1731 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
1732 &Subtable);
1733 if (ACPI_FAILURE (Status))
1734 {
1735 return (Status);
1736 }
1737
1738 ParentTable = DtPeekSubtable ();
1739 DtInsertSubtable (ParentTable, Subtable);
1740
1741 /* Compile the "Subtable" -- actually just the binary (PNG) image */
1742
1743 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
1744 &Subtable);
1745 if (ACPI_FAILURE (Status))
1746 {
1747 return (Status);
1748 }
1749
1750 DtInsertSubtable (ParentTable, Subtable);
1751 return (AE_OK);
1752 }
1753
1754
1755 /******************************************************************************
1756 *
1757 * FUNCTION: DtCompileRhct
1758 *
1759 * PARAMETERS: List - Current field list pointer
1760 *
1761 * RETURN: Status
1762 *
1763 * DESCRIPTION: Compile RHCT.
1764 *
1765 *****************************************************************************/
1766
1767 ACPI_STATUS
1768 DtCompileRhct (
1769 void **List)
1770 {
1771 ACPI_STATUS Status;
1772 ACPI_RHCT_NODE_HEADER *RhctHeader;
1773 ACPI_RHCT_HART_INFO *RhctHartInfo = NULL;
1774 DT_SUBTABLE *Subtable;
1775 DT_SUBTABLE *ParentTable;
1776 ACPI_DMTABLE_INFO *InfoTable;
1777 DT_FIELD **PFieldList = (DT_FIELD **) List;
1778 DT_FIELD *SubtableStart;
1779
1780
1781 /* Compile the main table */
1782
1783 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct,
1784 &Subtable);
1785 if (ACPI_FAILURE (Status))
1786 {
1787 return (Status);
1788 }
1789
1790 ParentTable = DtPeekSubtable ();
1791 while (*PFieldList)
1792 {
1793 SubtableStart = *PFieldList;
1794
1795 /* Compile RHCT subtable header */
1796
1797 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr,
1798 &Subtable);
1799 if (ACPI_FAILURE (Status))
1800 {
1801 return (Status);
1802 }
1803 DtInsertSubtable (ParentTable, Subtable);
1804 RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer);
1805 RhctHeader->Length = (UINT16)(Subtable->Length);
1806
1807 switch (RhctHeader->Type)
1808 {
1809 case ACPI_RHCT_NODE_TYPE_ISA_STRING:
1810
1811 InfoTable = AcpiDmTableInfoRhctIsa1;
1812 break;
1813
1814 case ACPI_RHCT_NODE_TYPE_HART_INFO:
1815
1816 InfoTable = AcpiDmTableInfoRhctHartInfo1;
1817 break;
1818
1819 case ACPI_RHCT_NODE_TYPE_CMO:
1820
1821 InfoTable = AcpiDmTableInfoRhctCmo1;
1822 break;
1823
1824 case ACPI_RHCT_NODE_TYPE_MMU:
1825
1826 InfoTable = AcpiDmTableInfoRhctMmu1;
1827 break;
1828
1829 default:
1830
1831 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT");
1832 return (AE_ERROR);
1833 }
1834
1835 /* Compile RHCT subtable body */
1836
1837 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1838 if (ACPI_FAILURE (Status))
1839 {
1840 return (Status);
1841 }
1842 DtInsertSubtable (ParentTable, Subtable);
1843 RhctHeader->Length += (UINT16)(Subtable->Length);
1844
1845 /* Compile RHCT subtable additionals */
1846
1847 switch (RhctHeader->Type)
1848 {
1849 case ACPI_RHCT_NODE_TYPE_HART_INFO:
1850
1851 RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO,
1852 Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER));
1853 if (RhctHartInfo)
1854 {
1855
1856 RhctHartInfo->NumOffsets = 0;
1857 while (*PFieldList)
1858 {
1859 Status = DtCompileTable (PFieldList,
1860 AcpiDmTableInfoRhctHartInfo2, &Subtable);
1861 if (ACPI_FAILURE (Status))
1862 {
1863 return (Status);
1864 }
1865 if (!Subtable)
1866 {
1867 break;
1868 }
1869
1870 DtInsertSubtable (ParentTable, Subtable);
1871 RhctHeader->Length += (UINT16)(Subtable->Length);
1872 RhctHartInfo->NumOffsets++;
1873 }
1874 }
1875 break;
1876
1877 default:
1878
1879 break;
1880 }
1881 }
1882
1883 return (AE_OK);
1884 }
1885
1886
1887 /******************************************************************************
1888 *
1889 * FUNCTION: DtCompileRsdt
1890 *
1891 * PARAMETERS: List - Current field list pointer
1892 *
1893 * RETURN: Status
1894 *
1895 * DESCRIPTION: Compile RSDT.
1896 *
1897 *****************************************************************************/
1898
1899 ACPI_STATUS
1900 DtCompileRsdt (
1901 void **List)
1902 {
1903 DT_SUBTABLE *Subtable;
1904 DT_SUBTABLE *ParentTable;
1905 DT_FIELD *FieldList = *(DT_FIELD **) List;
1906 UINT32 Address;
1907
1908
1909 ParentTable = DtPeekSubtable ();
1910
1911 while (FieldList)
1912 {
1913 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
1914
1915 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
1916 DtInsertSubtable (ParentTable, Subtable);
1917 FieldList = FieldList->Next;
1918 }
1919
1920 return (AE_OK);
1921 }
1922
1923
1924 /******************************************************************************
1925 *
1926 * FUNCTION: DtCompileS3pt
1927 *
1928 * PARAMETERS: PFieldList - Current field list pointer
1929 *
1930 * RETURN: Status
1931 *
1932 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
1933 *
1934 *****************************************************************************/
1935
1936 ACPI_STATUS
1937 DtCompileS3pt (
1938 DT_FIELD **PFieldList)
1939 {
1940 ACPI_STATUS Status;
1941 ACPI_FPDT_HEADER *S3ptHeader;
1942 DT_SUBTABLE *Subtable;
1943 DT_SUBTABLE *ParentTable;
1944 ACPI_DMTABLE_INFO *InfoTable;
1945 DT_FIELD *SubtableStart;
1946
1947
1948 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
1949 &AslGbl_RootTable);
1950 if (ACPI_FAILURE (Status))
1951 {
1952 return (Status);
1953 }
1954
1955 DtPushSubtable (AslGbl_RootTable);
1956
1957 while (*PFieldList)
1958 {
1959 SubtableStart = *PFieldList;
1960 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
1961 &Subtable);
1962 if (ACPI_FAILURE (Status))
1963 {
1964 return (Status);
1965 }
1966
1967 ParentTable = DtPeekSubtable ();
1968 DtInsertSubtable (ParentTable, Subtable);
1969 DtPushSubtable (Subtable);
1970
1971 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1972
1973 switch (S3ptHeader->Type)
1974 {
1975 case ACPI_S3PT_TYPE_RESUME:
1976
1977 InfoTable = AcpiDmTableInfoS3pt0;
1978 break;
1979
1980 case ACPI_S3PT_TYPE_SUSPEND:
1981
1982 InfoTable = AcpiDmTableInfoS3pt1;
1983 break;
1984
1985 default:
1986
1987 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
1988 return (AE_ERROR);
1989 }
1990
1991 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1992 if (ACPI_FAILURE (Status))
1993 {
1994 return (Status);
1995 }
1996
1997 ParentTable = DtPeekSubtable ();
1998 DtInsertSubtable (ParentTable, Subtable);
1999 DtPopSubtable ();
2000 }
2001
2002 return (AE_OK);
2003 }
2004
2005
2006 /******************************************************************************
2007 *
2008 * FUNCTION: DtCompileSdev
2009 *
2010 * PARAMETERS: List - Current field list pointer
2011 *
2012 * RETURN: Status
2013 *
2014 * DESCRIPTION: Compile SDEV.
2015 *
2016 *****************************************************************************/
2017
2018 ACPI_STATUS
2019 DtCompileSdev (
2020 void **List)
2021 {
2022 ACPI_STATUS Status;
2023 ACPI_SDEV_HEADER *SdevHeader;
2024 ACPI_SDEV_HEADER *SecureComponentHeader;
2025 DT_SUBTABLE *Subtable;
2026 DT_SUBTABLE *ParentTable;
2027 ACPI_DMTABLE_INFO *InfoTable;
2028 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL;
2029 DT_FIELD **PFieldList = (DT_FIELD **) List;
2030 DT_FIELD *SubtableStart;
2031 ACPI_SDEV_PCIE *Pcie = NULL;
2032 ACPI_SDEV_NAMESPACE *Namesp = NULL;
2033 UINT32 EntryCount;
2034 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL;
2035 UINT16 ComponentLength = 0;
2036
2037
2038 /* Subtables */
2039
2040 while (*PFieldList)
2041 {
2042 /* Compile common SDEV subtable header */
2043
2044 SubtableStart = *PFieldList;
2045 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
2046 &Subtable);
2047 if (ACPI_FAILURE (Status))
2048 {
2049 return (Status);
2050 }
2051
2052 ParentTable = DtPeekSubtable ();
2053 DtInsertSubtable (ParentTable, Subtable);
2054 DtPushSubtable (Subtable);
2055
2056 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2057 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
2058
2059 switch (SdevHeader->Type)
2060 {
2061 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2062
2063 InfoTable = AcpiDmTableInfoSdev0;
2064 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
2065 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2066 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
2067 break;
2068
2069 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2070
2071 InfoTable = AcpiDmTableInfoSdev1;
2072 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
2073 break;
2074
2075 default:
2076
2077 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2078 return (AE_ERROR);
2079 }
2080
2081 /* Compile SDEV subtable body */
2082
2083 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2084 if (ACPI_FAILURE (Status))
2085 {
2086 return (Status);
2087 }
2088
2089 ParentTable = DtPeekSubtable ();
2090 DtInsertSubtable (ParentTable, Subtable);
2091
2092 /* Optional data fields are appended to the main subtable body */
2093
2094 switch (SdevHeader->Type)
2095 {
2096 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2097
2098 /*
2099 * Device Id Offset will be be calculated differently depending on
2100 * the presence of secure access components.
2101 */
2102 Namesp->DeviceIdOffset = 0;
2103 ComponentLength = 0;
2104
2105 /* If the secure access component exists, get the structures */
2106
2107 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2108 {
2109 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
2110 &Subtable);
2111 if (ACPI_FAILURE (Status))
2112 {
2113 return (Status);
2114 }
2115 ParentTable = DtPeekSubtable ();
2116 DtInsertSubtable (ParentTable, Subtable);
2117
2118 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2119
2120 /* Compile a secure access component header */
2121
2122 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
2123 &Subtable);
2124 if (ACPI_FAILURE (Status))
2125 {
2126 return (Status);
2127 }
2128 ParentTable = DtPeekSubtable ();
2129 DtInsertSubtable (ParentTable, Subtable);
2130
2131 /* Compile the secure access component */
2132
2133 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2134 switch (SecureComponentHeader->Type)
2135 {
2136 case ACPI_SDEV_TYPE_ID_COMPONENT:
2137
2138 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2139 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
2140 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
2141 break;
2142
2143 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2144
2145 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2146 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
2147 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
2148 break;
2149
2150 default:
2151
2152 /* Any other secure component types are undefined */
2153
2154 return (AE_ERROR);
2155 }
2156
2157 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
2158 &Subtable);
2159 if (ACPI_FAILURE (Status))
2160 {
2161 return (Status);
2162 }
2163 ParentTable = DtPeekSubtable ();
2164 DtInsertSubtable (ParentTable, Subtable);
2165
2166 SecureComponent->SecureComponentOffset =
2167 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
2168 SecureComponent->SecureComponentLength = ComponentLength;
2169
2170
2171 /*
2172 * Add the secure component to the subtable to be added for the
2173 * the namespace subtable's length
2174 */
2175 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2176 }
2177
2178 /* Append DeviceId namespace string */
2179
2180 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
2181 &Subtable);
2182 if (ACPI_FAILURE (Status))
2183 {
2184 return (Status);
2185 }
2186
2187 if (!Subtable)
2188 {
2189 break;
2190 }
2191
2192 ParentTable = DtPeekSubtable ();
2193 DtInsertSubtable (ParentTable, Subtable);
2194
2195 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
2196
2197 Namesp->DeviceIdLength = (UINT16) Subtable->Length;
2198
2199 /* Append Vendor data */
2200
2201 Namesp->VendorDataLength = 0;
2202 Namesp->VendorDataOffset = 0;
2203
2204 if (*PFieldList)
2205 {
2206 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2207 &Subtable);
2208 if (ACPI_FAILURE (Status))
2209 {
2210 return (Status);
2211 }
2212
2213 if (Subtable)
2214 {
2215 ParentTable = DtPeekSubtable ();
2216 DtInsertSubtable (ParentTable, Subtable);
2217
2218 Namesp->VendorDataOffset =
2219 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2220 Namesp->VendorDataLength =
2221 (UINT16) Subtable->Length;
2222
2223 /* Final size of entire namespace structure */
2224
2225 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
2226 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
2227 }
2228 }
2229
2230 break;
2231
2232 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2233
2234 /* Append the PCIe path info first */
2235
2236 EntryCount = 0;
2237 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
2238 {
2239 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
2240 &Subtable);
2241 if (ACPI_FAILURE (Status))
2242 {
2243 return (Status);
2244 }
2245
2246 if (!Subtable)
2247 {
2248 DtPopSubtable ();
2249 break;
2250 }
2251
2252 ParentTable = DtPeekSubtable ();
2253 DtInsertSubtable (ParentTable, Subtable);
2254 EntryCount++;
2255 }
2256
2257 /* Path offset will point immediately after the main subtable */
2258
2259 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
2260 Pcie->PathLength = (UINT16)
2261 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
2262
2263 /* Append the Vendor Data last */
2264
2265 Pcie->VendorDataLength = 0;
2266 Pcie->VendorDataOffset = 0;
2267
2268 if (*PFieldList)
2269 {
2270 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2271 &Subtable);
2272 if (ACPI_FAILURE (Status))
2273 {
2274 return (Status);
2275 }
2276
2277 if (Subtable)
2278 {
2279 ParentTable = DtPeekSubtable ();
2280 DtInsertSubtable (ParentTable, Subtable);
2281
2282 Pcie->VendorDataOffset =
2283 Pcie->PathOffset + Pcie->PathLength;
2284 Pcie->VendorDataLength = (UINT16)
2285 Subtable->Length;
2286 }
2287 }
2288
2289 SdevHeader->Length =
2290 sizeof (ACPI_SDEV_PCIE) +
2291 Pcie->PathLength + Pcie->VendorDataLength;
2292 break;
2293
2294 default:
2295
2296 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2297 return (AE_ERROR);
2298 }
2299
2300 DtPopSubtable ();
2301 }
2302
2303 return (AE_OK);
2304 }
2305
2306
2307 /******************************************************************************
2308 *
2309 * FUNCTION: DtCompileSlic
2310 *
2311 * PARAMETERS: List - Current field list pointer
2312 *
2313 * RETURN: Status
2314 *
2315 * DESCRIPTION: Compile SLIC.
2316 *
2317 *****************************************************************************/
2318
2319 ACPI_STATUS
2320 DtCompileSlic (
2321 void **List)
2322 {
2323 ACPI_STATUS Status;
2324 DT_SUBTABLE *Subtable;
2325 DT_SUBTABLE *ParentTable;
2326 DT_FIELD **PFieldList = (DT_FIELD **) List;
2327
2328
2329 while (*PFieldList)
2330 {
2331 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2332 &Subtable);
2333 if (ACPI_FAILURE (Status))
2334 {
2335 return (Status);
2336 }
2337
2338 ParentTable = DtPeekSubtable ();
2339 DtInsertSubtable (ParentTable, Subtable);
2340 DtPushSubtable (Subtable);
2341 DtPopSubtable ();
2342 }
2343
2344 return (AE_OK);
2345 }
2346
2347
2348 /******************************************************************************
2349 *
2350 * FUNCTION: DtCompileSlit
2351 *
2352 * PARAMETERS: List - Current field list pointer
2353 *
2354 * RETURN: Status
2355 *
2356 * DESCRIPTION: Compile SLIT.
2357 *
2358 *****************************************************************************/
2359
2360 ACPI_STATUS
2361 DtCompileSlit (
2362 void **List)
2363 {
2364 ACPI_STATUS Status;
2365 DT_SUBTABLE *Subtable;
2366 DT_SUBTABLE *ParentTable;
2367 DT_FIELD **PFieldList = (DT_FIELD **) List;
2368 DT_FIELD *FieldList;
2369 DT_FIELD *EndOfFieldList = NULL;
2370 UINT32 Localities;
2371 UINT32 LocalityListLength;
2372 UINT8 *LocalityBuffer;
2373
2374
2375 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2376 &Subtable);
2377 if (ACPI_FAILURE (Status))
2378 {
2379 return (Status);
2380 }
2381
2382 ParentTable = DtPeekSubtable ();
2383 DtInsertSubtable (ParentTable, Subtable);
2384
2385 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2386 LocalityBuffer = UtLocalCalloc (Localities);
2387 LocalityListLength = 0;
2388
2389 /* Compile each locality buffer */
2390
2391 FieldList = *PFieldList;
2392 while (FieldList)
2393 {
2394 DtCompileBuffer (LocalityBuffer,
2395 FieldList->Value, FieldList, Localities);
2396
2397 LocalityListLength++;
2398 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2399 DtInsertSubtable (ParentTable, Subtable);
2400 EndOfFieldList = FieldList;
2401 FieldList = FieldList->Next;
2402 }
2403
2404 if (LocalityListLength != Localities)
2405 {
2406 sprintf(AslGbl_MsgBuffer,
2407 "Found %u entries, must match LocalityCount: %u",
2408 LocalityListLength, Localities);
2409 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
2410 ACPI_FREE (LocalityBuffer);
2411 return (AE_LIMIT);
2412 }
2413
2414 ACPI_FREE (LocalityBuffer);
2415 return (AE_OK);
2416 }
2417
2418
2419 /******************************************************************************
2420 *
2421 * FUNCTION: DtCompileSrat
2422 *
2423 * PARAMETERS: List - Current field list pointer
2424 *
2425 * RETURN: Status
2426 *
2427 * DESCRIPTION: Compile SRAT.
2428 *
2429 *****************************************************************************/
2430
2431 ACPI_STATUS
2432 DtCompileSrat (
2433 void **List)
2434 {
2435 ACPI_STATUS Status;
2436 DT_SUBTABLE *Subtable;
2437 DT_SUBTABLE *ParentTable;
2438 DT_FIELD **PFieldList = (DT_FIELD **) List;
2439 DT_FIELD *SubtableStart;
2440 ACPI_SUBTABLE_HEADER *SratHeader;
2441 ACPI_DMTABLE_INFO *InfoTable;
2442
2443
2444 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2445 &Subtable);
2446 if (ACPI_FAILURE (Status))
2447 {
2448 return (Status);
2449 }
2450
2451 ParentTable = DtPeekSubtable ();
2452 DtInsertSubtable (ParentTable, Subtable);
2453
2454 while (*PFieldList)
2455 {
2456 SubtableStart = *PFieldList;
2457 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2458 &Subtable);
2459 if (ACPI_FAILURE (Status))
2460 {
2461 return (Status);
2462 }
2463
2464 ParentTable = DtPeekSubtable ();
2465 DtInsertSubtable (ParentTable, Subtable);
2466 DtPushSubtable (Subtable);
2467
2468 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2469
2470 switch (SratHeader->Type)
2471 {
2472 case ACPI_SRAT_TYPE_CPU_AFFINITY:
2473
2474 InfoTable = AcpiDmTableInfoSrat0;
2475 break;
2476
2477 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2478
2479 InfoTable = AcpiDmTableInfoSrat1;
2480 break;
2481
2482 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2483
2484 InfoTable = AcpiDmTableInfoSrat2;
2485 break;
2486
2487 case ACPI_SRAT_TYPE_GICC_AFFINITY:
2488
2489 InfoTable = AcpiDmTableInfoSrat3;
2490 break;
2491
2492 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
2493
2494 InfoTable = AcpiDmTableInfoSrat4;
2495 break;
2496
2497 case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
2498
2499 InfoTable = AcpiDmTableInfoSrat5;
2500 break;
2501
2502 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
2503
2504 InfoTable = AcpiDmTableInfoSrat6;
2505 break;
2506
2507 case ACPI_SRAT_TYPE_RINTC_AFFINITY:
2508
2509 InfoTable = AcpiDmTableInfoSrat7;
2510 break;
2511
2512 default:
2513
2514 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2515 return (AE_ERROR);
2516 }
2517
2518 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2519 if (ACPI_FAILURE (Status))
2520 {
2521 return (Status);
2522 }
2523
2524 ParentTable = DtPeekSubtable ();
2525 DtInsertSubtable (ParentTable, Subtable);
2526 DtPopSubtable ();
2527 }
2528
2529 return (AE_OK);
2530 }
2531
2532
2533 /******************************************************************************
2534 *
2535 * FUNCTION: DtCompileStao
2536 *
2537 * PARAMETERS: PFieldList - Current field list pointer
2538 *
2539 * RETURN: Status
2540 *
2541 * DESCRIPTION: Compile STAO.
2542 *
2543 *****************************************************************************/
2544
2545 ACPI_STATUS
2546 DtCompileStao (
2547 void **List)
2548 {
2549 DT_FIELD **PFieldList = (DT_FIELD **) List;
2550 DT_SUBTABLE *Subtable;
2551 DT_SUBTABLE *ParentTable;
2552 ACPI_STATUS Status;
2553
2554
2555 /* Compile the main table */
2556
2557 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
2558 &Subtable);
2559 if (ACPI_FAILURE (Status))
2560 {
2561 return (Status);
2562 }
2563
2564 ParentTable = DtPeekSubtable ();
2565 DtInsertSubtable (ParentTable, Subtable);
2566
2567 /* Compile each ASCII namestring as a subtable */
2568
2569 while (*PFieldList)
2570 {
2571 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
2572 &Subtable);
2573 if (ACPI_FAILURE (Status))
2574 {
2575 return (Status);
2576 }
2577
2578 ParentTable = DtPeekSubtable ();
2579 DtInsertSubtable (ParentTable, Subtable);
2580 }
2581
2582 return (AE_OK);
2583 }
2584
2585
2586 /******************************************************************************
2587 *
2588 * FUNCTION: DtCompileSvkl
2589 *
2590 * PARAMETERS: PFieldList - Current field list pointer
2591 *
2592 * RETURN: Status
2593 *
2594 * DESCRIPTION: Compile SVKL.
2595 *
2596 * NOTES: SVKL is essentially a flat table, with a small main table and
2597 * a variable number of a single type of subtable.
2598 *
2599 *****************************************************************************/
2600
2601 ACPI_STATUS
2602 DtCompileSvkl (
2603 void **List)
2604 {
2605 DT_FIELD **PFieldList = (DT_FIELD **) List;
2606 DT_SUBTABLE *Subtable;
2607 DT_SUBTABLE *ParentTable;
2608 ACPI_STATUS Status;
2609
2610
2611 /* Compile the main table */
2612
2613 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
2614 &Subtable);
2615 if (ACPI_FAILURE (Status))
2616 {
2617 return (Status);
2618 }
2619
2620 ParentTable = DtPeekSubtable ();
2621 DtInsertSubtable (ParentTable, Subtable);
2622
2623 /* Compile each subtable */
2624
2625 while (*PFieldList)
2626 {
2627 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
2628 &Subtable);
2629 if (ACPI_FAILURE (Status))
2630 {
2631 return (Status);
2632 }
2633
2634 ParentTable = DtPeekSubtable ();
2635 DtInsertSubtable (ParentTable, Subtable);
2636 }
2637
2638 return (AE_OK);
2639 }
2640
2641
2642 /******************************************************************************
2643 *
2644 * FUNCTION: DtCompileTcpa
2645 *
2646 * PARAMETERS: PFieldList - Current field list pointer
2647 *
2648 * RETURN: Status
2649 *
2650 * DESCRIPTION: Compile TCPA.
2651 *
2652 *****************************************************************************/
2653
2654 ACPI_STATUS
2655 DtCompileTcpa (
2656 void **List)
2657 {
2658 DT_FIELD **PFieldList = (DT_FIELD **) List;
2659 DT_SUBTABLE *Subtable;
2660 ACPI_TABLE_TCPA_HDR *TcpaHeader;
2661 DT_SUBTABLE *ParentTable;
2662 ACPI_STATUS Status;
2663
2664
2665 /* Compile the main table */
2666
2667 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
2668 &Subtable);
2669 if (ACPI_FAILURE (Status))
2670 {
2671 return (Status);
2672 }
2673
2674 ParentTable = DtPeekSubtable ();
2675 DtInsertSubtable (ParentTable, Subtable);
2676
2677 /*
2678 * Examine the PlatformClass field to determine the table type.
2679 * Either a client or server table. Only one.
2680 */
2681 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
2682
2683 switch (TcpaHeader->PlatformClass)
2684 {
2685 case ACPI_TCPA_CLIENT_TABLE:
2686
2687 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
2688 &Subtable);
2689 break;
2690
2691 case ACPI_TCPA_SERVER_TABLE:
2692
2693 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
2694 &Subtable);
2695 break;
2696
2697 default:
2698
2699 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
2700 TcpaHeader->PlatformClass);
2701 Status = AE_ERROR;
2702 break;
2703 }
2704
2705 ParentTable = DtPeekSubtable ();
2706 DtInsertSubtable (ParentTable, Subtable);
2707 return (Status);
2708 }
2709
2710
2711 /******************************************************************************
2712 *
2713 * FUNCTION: DtCompileTpm2Rev3
2714 *
2715 * PARAMETERS: PFieldList - Current field list pointer
2716 *
2717 * RETURN: Status
2718 *
2719 * DESCRIPTION: Compile TPM2 revision 3
2720 *
2721 *****************************************************************************/
2722 static ACPI_STATUS
2723 DtCompileTpm2Rev3 (
2724 void **List)
2725 {
2726 DT_FIELD **PFieldList = (DT_FIELD **) List;
2727 DT_SUBTABLE *Subtable;
2728 ACPI_TABLE_TPM23 *Tpm23Header;
2729 DT_SUBTABLE *ParentTable;
2730 ACPI_STATUS Status = AE_OK;
2731
2732
2733 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
2734 &Subtable);
2735
2736 ParentTable = DtPeekSubtable ();
2737 DtInsertSubtable (ParentTable, Subtable);
2738 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
2739
2740 /* Subtable type depends on the StartMethod */
2741
2742 switch (Tpm23Header->StartMethod)
2743 {
2744 case ACPI_TPM23_ACPI_START_METHOD:
2745
2746 /* Subtable specific to to ARM_SMC */
2747
2748 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
2749 &Subtable);
2750 if (ACPI_FAILURE (Status))
2751 {
2752 return (Status);
2753 }
2754
2755 ParentTable = DtPeekSubtable ();
2756 DtInsertSubtable (ParentTable, Subtable);
2757 break;
2758
2759 default:
2760 break;
2761 }
2762
2763 return (Status);
2764 }
2765
2766
2767 /******************************************************************************
2768 *
2769 * FUNCTION: DtCompileTpm2
2770 *
2771 * PARAMETERS: PFieldList - Current field list pointer
2772 *
2773 * RETURN: Status
2774 *
2775 * DESCRIPTION: Compile TPM2.
2776 *
2777 *****************************************************************************/
2778
2779 ACPI_STATUS
2780 DtCompileTpm2 (
2781 void **List)
2782 {
2783 DT_FIELD **PFieldList = (DT_FIELD **) List;
2784 DT_SUBTABLE *Subtable;
2785 ACPI_TABLE_TPM2 *Tpm2Header;
2786 DT_SUBTABLE *ParentTable;
2787 ACPI_STATUS Status = AE_OK;
2788 ACPI_TABLE_HEADER *Header;
2789
2790
2791 ParentTable = DtPeekSubtable ();
2792
2793 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2794
2795 if (Header->Revision == 3)
2796 {
2797 return (DtCompileTpm2Rev3 (List));
2798 }
2799
2800 /* Compile the main table */
2801
2802 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
2803 &Subtable);
2804 if (ACPI_FAILURE (Status))
2805 {
2806 return (Status);
2807 }
2808
2809 ParentTable = DtPeekSubtable ();
2810 DtInsertSubtable (ParentTable, Subtable);
2811
2812 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
2813
2814 /* Method parameters */
2815 /* Optional: Log area minimum length */
2816 /* Optional: Log area start address */
2817 /* TBD: Optional fields above not fully implemented (not optional at this time) */
2818
2819 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
2820 &Subtable);
2821 if (ACPI_FAILURE (Status))
2822 {
2823 return (Status);
2824 }
2825
2826 ParentTable = DtPeekSubtable ();
2827 DtInsertSubtable (ParentTable, Subtable);
2828
2829
2830 /* Subtable type depends on the StartMethod */
2831
2832 switch (Tpm2Header->StartMethod)
2833 {
2834 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
2835
2836 /* Subtable specific to to ARM_SMC */
2837
2838 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
2839 &Subtable);
2840 if (ACPI_FAILURE (Status))
2841 {
2842 return (Status);
2843 }
2844
2845 ParentTable = DtPeekSubtable ();
2846 DtInsertSubtable (ParentTable, Subtable);
2847 break;
2848
2849 case ACPI_TPM2_START_METHOD:
2850 case ACPI_TPM2_MEMORY_MAPPED:
2851 case ACPI_TPM2_COMMAND_BUFFER:
2852 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
2853 break;
2854
2855 case ACPI_TPM2_RESERVED1:
2856 case ACPI_TPM2_RESERVED3:
2857 case ACPI_TPM2_RESERVED4:
2858 case ACPI_TPM2_RESERVED5:
2859 case ACPI_TPM2_RESERVED9:
2860 case ACPI_TPM2_RESERVED10:
2861
2862 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
2863 Tpm2Header->StartMethod);
2864 Status = AE_ERROR;
2865 break;
2866
2867 case ACPI_TPM2_NOT_ALLOWED:
2868 default:
2869
2870 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
2871 Tpm2Header->StartMethod);
2872 Status = AE_ERROR;
2873 break;
2874 }
2875
2876 return (Status);
2877 }
2878
2879
2880 /******************************************************************************
2881 *
2882 * FUNCTION: DtGetGenericTableInfo
2883 *
2884 * PARAMETERS: Name - Generic type name
2885 *
2886 * RETURN: Info entry
2887 *
2888 * DESCRIPTION: Obtain table info for a generic name entry
2889 *
2890 *****************************************************************************/
2891
2892 ACPI_DMTABLE_INFO *
2893 DtGetGenericTableInfo (
2894 char *Name)
2895 {
2896 ACPI_DMTABLE_INFO *Info;
2897 UINT32 i;
2898
2899
2900 if (!Name)
2901 {
2902 return (NULL);
2903 }
2904
2905 /* Search info table for name match */
2906
2907 for (i = 0; ; i++)
2908 {
2909 Info = AcpiDmTableInfoGeneric[i];
2910 if (Info->Opcode == ACPI_DMT_EXIT)
2911 {
2912 Info = NULL;
2913 break;
2914 }
2915
2916 /* Use caseless compare for generic keywords */
2917
2918 if (!AcpiUtStricmp (Name, Info->Name))
2919 {
2920 break;
2921 }
2922 }
2923
2924 return (Info);
2925 }
2926
2927
2928 /******************************************************************************
2929 *
2930 * FUNCTION: DtCompileUefi
2931 *
2932 * PARAMETERS: List - Current field list pointer
2933 *
2934 * RETURN: Status
2935 *
2936 * DESCRIPTION: Compile UEFI.
2937 *
2938 *****************************************************************************/
2939
2940 ACPI_STATUS
2941 DtCompileUefi (
2942 void **List)
2943 {
2944 ACPI_STATUS Status;
2945 DT_SUBTABLE *Subtable;
2946 DT_SUBTABLE *ParentTable;
2947 DT_FIELD **PFieldList = (DT_FIELD **) List;
2948 UINT16 *DataOffset;
2949
2950
2951 /* Compile the predefined portion of the UEFI table */
2952
2953 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2954 &Subtable);
2955 if (ACPI_FAILURE (Status))
2956 {
2957 return (Status);
2958 }
2959
2960 DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2961 *DataOffset = sizeof (ACPI_TABLE_UEFI);
2962
2963 ParentTable = DtPeekSubtable ();
2964 DtInsertSubtable (ParentTable, Subtable);
2965
2966 /*
2967 * Compile the "generic" portion of the UEFI table. This
2968 * part of the table is not predefined and any of the generic
2969 * operators may be used.
2970 */
2971 DtCompileGeneric ((void **) PFieldList, NULL, NULL);
2972 return (AE_OK);
2973 }
2974
2975
2976 /******************************************************************************
2977 *
2978 * FUNCTION: DtCompileViot
2979 *
2980 * PARAMETERS: List - Current field list pointer
2981 *
2982 * RETURN: Status
2983 *
2984 * DESCRIPTION: Compile VIOT.
2985 *
2986 *****************************************************************************/
2987
2988 ACPI_STATUS
2989 DtCompileViot (
2990 void **List)
2991 {
2992 ACPI_STATUS Status;
2993 DT_SUBTABLE *Subtable;
2994 DT_SUBTABLE *ParentTable;
2995 DT_FIELD **PFieldList = (DT_FIELD **) List;
2996 DT_FIELD *SubtableStart;
2997 ACPI_TABLE_VIOT *Viot;
2998 ACPI_VIOT_HEADER *ViotHeader;
2999 ACPI_DMTABLE_INFO *InfoTable;
3000 UINT16 NodeCount;
3001
3002 ParentTable = DtPeekSubtable ();
3003
3004 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
3005 if (ACPI_FAILURE (Status))
3006 {
3007 return (Status);
3008 }
3009 DtInsertSubtable (ParentTable, Subtable);
3010
3011 /*
3012 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
3013 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
3014 */
3015 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
3016 sizeof (ACPI_TABLE_HEADER));
3017
3018 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
3019
3020 NodeCount = 0;
3021 while (*PFieldList) {
3022 SubtableStart = *PFieldList;
3023 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
3024 &Subtable);
3025 if (ACPI_FAILURE (Status))
3026 {
3027 return (Status);
3028 }
3029
3030 ParentTable = DtPeekSubtable ();
3031 DtInsertSubtable (ParentTable, Subtable);
3032 DtPushSubtable (Subtable);
3033
3034 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
3035
3036 switch (ViotHeader->Type)
3037 {
3038 case ACPI_VIOT_NODE_PCI_RANGE:
3039
3040 InfoTable = AcpiDmTableInfoViot1;
3041 break;
3042
3043 case ACPI_VIOT_NODE_MMIO:
3044
3045 InfoTable = AcpiDmTableInfoViot2;
3046 break;
3047
3048 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
3049
3050 InfoTable = AcpiDmTableInfoViot3;
3051 break;
3052
3053 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
3054
3055 InfoTable = AcpiDmTableInfoViot4;
3056 break;
3057
3058 default:
3059
3060 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
3061 return (AE_ERROR);
3062 }
3063
3064 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
3065 if (ACPI_FAILURE (Status))
3066 {
3067 return (Status);
3068 }
3069
3070 ParentTable = DtPeekSubtable ();
3071 DtInsertSubtable (ParentTable, Subtable);
3072 DtPopSubtable ();
3073 NodeCount++;
3074 }
3075
3076 Viot->NodeCount = NodeCount;
3077 return (AE_OK);
3078 }
3079
3080
3081 /******************************************************************************
3082 *
3083 * FUNCTION: DtCompileWdat
3084 *
3085 * PARAMETERS: List - Current field list pointer
3086 *
3087 * RETURN: Status
3088 *
3089 * DESCRIPTION: Compile WDAT.
3090 *
3091 *****************************************************************************/
3092
3093 ACPI_STATUS
3094 DtCompileWdat (
3095 void **List)
3096 {
3097 ACPI_STATUS Status;
3098
3099
3100 Status = DtCompileTwoSubtables (List,
3101 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3102 return (Status);
3103 }
3104
3105
3106 /******************************************************************************
3107 *
3108 * FUNCTION: DtCompileWpbt
3109 *
3110 * PARAMETERS: List - Current field list pointer
3111 *
3112 * RETURN: Status
3113 *
3114 * DESCRIPTION: Compile WPBT.
3115 *
3116 *****************************************************************************/
3117
3118 ACPI_STATUS
3119 DtCompileWpbt (
3120 void **List)
3121 {
3122 DT_FIELD **PFieldList = (DT_FIELD **) List;
3123 DT_SUBTABLE *Subtable;
3124 DT_SUBTABLE *ParentTable;
3125 ACPI_TABLE_WPBT *Table;
3126 ACPI_STATUS Status;
3127
3128
3129 /* Compile the main table */
3130
3131 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
3132 if (ACPI_FAILURE (Status))
3133 {
3134 return (Status);
3135 }
3136
3137 ParentTable = DtPeekSubtable ();
3138 DtInsertSubtable (ParentTable, Subtable);
3139 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3140
3141 /*
3142 * Exit now if there are no arguments specified. This is indicated by:
3143 * The "Command-line Arguments" field has not been specified (if specified,
3144 * it will be the last field in the field list -- after the main table).
3145 * Set the Argument Length in the main table to zero.
3146 */
3147 if (!*PFieldList)
3148 {
3149 Table->ArgumentsLength = 0;
3150 return (AE_OK);
3151 }
3152
3153 /* Compile the argument list subtable */
3154
3155 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
3156 if (ACPI_FAILURE (Status))
3157 {
3158 return (Status);
3159 }
3160
3161 /* Extract the length of the Arguments buffer, insert into main table */
3162
3163 Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
3164 DtInsertSubtable (ParentTable, Subtable);
3165 return (AE_OK);
3166 }
3167
3168
3169 /******************************************************************************
3170 *
3171 * FUNCTION: DtCompileXsdt
3172 *
3173 * PARAMETERS: List - Current field list pointer
3174 *
3175 * RETURN: Status
3176 *
3177 * DESCRIPTION: Compile XSDT.
3178 *
3179 *****************************************************************************/
3180
3181 ACPI_STATUS
3182 DtCompileXsdt (
3183 void **List)
3184 {
3185 DT_SUBTABLE *Subtable;
3186 DT_SUBTABLE *ParentTable;
3187 DT_FIELD *FieldList = *(DT_FIELD **) List;
3188 UINT64 Address;
3189
3190
3191 ParentTable = DtPeekSubtable ();
3192
3193 while (FieldList)
3194 {
3195 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3196
3197 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3198 DtInsertSubtable (ParentTable, Subtable);
3199 FieldList = FieldList->Next;
3200 }
3201
3202 return (AE_OK);
3203 }
3204
3205
3206 /******************************************************************************
3207 *
3208 * FUNCTION: DtCompileGeneric
3209 *
3210 * PARAMETERS: List - Current field list pointer
3211 * Name - Field name to end generic compiling
3212 * Length - Compiled table length to return
3213 *
3214 * RETURN: Status
3215 *
3216 * DESCRIPTION: Compile generic unknown table.
3217 *
3218 *****************************************************************************/
3219
3220 ACPI_STATUS
3221 DtCompileGeneric (
3222 void **List,
3223 char *Name,
3224 UINT32 *Length)
3225 {
3226 ACPI_STATUS Status;
3227 DT_SUBTABLE *Subtable;
3228 DT_SUBTABLE *ParentTable;
3229 DT_FIELD **PFieldList = (DT_FIELD **) List;
3230 ACPI_DMTABLE_INFO *Info;
3231
3232
3233 ParentTable = DtPeekSubtable ();
3234
3235 /*
3236 * Compile the "generic" portion of the table. This
3237 * part of the table is not predefined and any of the generic
3238 * operators may be used.
3239 */
3240
3241 /* Find any and all labels in the entire generic portion */
3242
3243 DtDetectAllLabels (*PFieldList);
3244
3245 /* Now we can actually compile the parse tree */
3246
3247 if (Length && *Length)
3248 {
3249 *Length = 0;
3250 }
3251 while (*PFieldList)
3252 {
3253 if (Name && !strcmp ((*PFieldList)->Name, Name))
3254 {
3255 break;
3256 }
3257
3258 Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3259 if (!Info)
3260 {
3261 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3262 (*PFieldList)->Name);
3263 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3264 (*PFieldList), AslGbl_MsgBuffer);
3265
3266 *PFieldList = (*PFieldList)->Next;
3267 continue;
3268 }
3269
3270 Status = DtCompileTable (PFieldList, Info,
3271 &Subtable);
3272 if (ACPI_SUCCESS (Status))
3273 {
3274 DtInsertSubtable (ParentTable, Subtable);
3275 if (Length)
3276 {
3277 *Length += Subtable->Length;
3278 }
3279 }
3280 else
3281 {
3282 *PFieldList = (*PFieldList)->Next;
3283
3284 if (Status == AE_NOT_FOUND)
3285 {
3286 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3287 (*PFieldList)->Name);
3288 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3289 (*PFieldList), AslGbl_MsgBuffer);
3290 }
3291 }
3292 }
3293
3294 return (AE_OK);
3295 }
3296