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