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