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