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 while (*PFieldList)
1638 {
1639 SubtableStart = *PFieldList;
1640
1641 /* Compile PPTT subtable header */
1642
1643 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1644 &Subtable);
1645 if (ACPI_FAILURE (Status))
1646 {
1647 return (Status);
1648 }
1649 DtInsertSubtable (ParentTable, Subtable);
1650 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1651 PpttHeader->Length = (UINT8)(Subtable->Length);
1652
1653 switch (PpttHeader->Type)
1654 {
1655 case ACPI_PPTT_TYPE_PROCESSOR:
1656
1657 InfoTable = AcpiDmTableInfoPptt0;
1658 break;
1659
1660 case ACPI_PPTT_TYPE_CACHE:
1661
1662 InfoTable = AcpiDmTableInfoPptt1;
1663 break;
1664
1665 case ACPI_PPTT_TYPE_ID:
1666
1667 InfoTable = AcpiDmTableInfoPptt2;
1668 break;
1669
1670 default:
1671
1672 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1673 return (AE_ERROR);
1674 }
1675
1676 /* Compile PPTT subtable body */
1677
1678 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1679 if (ACPI_FAILURE (Status))
1680 {
1681 return (Status);
1682 }
1683 DtInsertSubtable (ParentTable, Subtable);
1684 PpttHeader->Length += (UINT8)(Subtable->Length);
1685
1686 /* Compile PPTT subtable additional */
1687
1688 switch (PpttHeader->Type)
1689 {
1690 case ACPI_PPTT_TYPE_PROCESSOR:
1691
1692 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1693 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1694 if (PpttProcessor)
1695 {
1696 /* Compile initiator proximity domain list */
1697
1698 PpttProcessor->NumberOfPrivResources = 0;
1699 while (*PFieldList)
1700 {
1701 Status = DtCompileTable (PFieldList,
1702 AcpiDmTableInfoPptt0a, &Subtable);
1703 if (ACPI_FAILURE (Status))
1704 {
1705 return (Status);
1706 }
1707 if (!Subtable)
1708 {
1709 break;
1710 }
1711
1712 DtInsertSubtable (ParentTable, Subtable);
1713 PpttHeader->Length += (UINT8)(Subtable->Length);
1714 PpttProcessor->NumberOfPrivResources++;
1715 }
1716 }
1717 break;
1718
1719 case ACPI_PPTT_TYPE_CACHE:
1720
1721 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1722 AslGbl_RootTable->Buffer);
1723 if (PpttAcpiHeader->Revision < 3)
1724 {
1725 break;
1726 }
1727 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
1728 &Subtable);
1729 DtInsertSubtable (ParentTable, Subtable);
1730 PpttHeader->Length += (UINT8)(Subtable->Length);
1731 break;
1732
1733 default:
1734
1735 break;
1736 }
1737 }
1738
1739 return (AE_OK);
1740 }
1741
1742
1743 /******************************************************************************
1744 *
1745 * FUNCTION: DtCompilePrmt
1746 *
1747 * PARAMETERS: List - Current field list pointer
1748 *
1749 * RETURN: Status
1750 *
1751 * DESCRIPTION: Compile PRMT.
1752 *
1753 *****************************************************************************/
1754
1755 ACPI_STATUS
DtCompilePrmt(void ** List)1756 DtCompilePrmt (
1757 void **List)
1758 {
1759 ACPI_STATUS Status;
1760 ACPI_TABLE_PRMT_HEADER *PrmtHeader;
1761 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo;
1762 DT_SUBTABLE *Subtable;
1763 DT_SUBTABLE *ParentTable;
1764 DT_FIELD **PFieldList = (DT_FIELD **) List;
1765 UINT32 i, j;
1766
1767 ParentTable = DtPeekSubtable ();
1768
1769 /* Compile PRMT subtable header */
1770
1771 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
1772 &Subtable);
1773 if (ACPI_FAILURE (Status))
1774 {
1775 return (Status);
1776 }
1777 DtInsertSubtable (ParentTable, Subtable);
1778 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
1779
1780 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
1781 {
1782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
1783 &Subtable);
1784 if (ACPI_FAILURE (Status))
1785 {
1786 return (Status);
1787 }
1788 DtInsertSubtable (ParentTable, Subtable);
1789 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
1790
1791 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
1792 {
1793 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
1794 &Subtable);
1795 if (ACPI_FAILURE (Status))
1796 {
1797 return (Status);
1798 }
1799 DtInsertSubtable (ParentTable, Subtable);
1800 }
1801 }
1802
1803 return (AE_OK);
1804 }
1805
1806
1807 /******************************************************************************
1808 *
1809 * FUNCTION: DtCompileRas2
1810 *
1811 * PARAMETERS: List - Current field list pointer
1812 *
1813 * RETURN: Status
1814 *
1815 * DESCRIPTION: Compile RAS2.
1816 *
1817 *****************************************************************************/
1818
1819 ACPI_STATUS
DtCompileRas2(void ** List)1820 DtCompileRas2 (
1821 void **List)
1822 {
1823 ACPI_STATUS Status;
1824 DT_SUBTABLE *Subtable;
1825 DT_SUBTABLE *ParentTable;
1826 DT_FIELD **PFieldList = (DT_FIELD **) List;
1827 ACPI_TABLE_RAS2 *Ras2Header;
1828 UINT32 Count = 0;
1829
1830
1831 /* Main table */
1832
1833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable);
1834 if (ACPI_FAILURE (Status))
1835 {
1836 return (Status);
1837 }
1838
1839 ParentTable = DtPeekSubtable ();
1840 DtInsertSubtable (ParentTable, Subtable);
1841
1842 Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer);
1843
1844 /* There is only one type of subtable at this time, no need to decode */
1845
1846 while (*PFieldList)
1847 {
1848 /* List of RAS2 PCC descriptors, each 8 bytes */
1849
1850 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc,
1851 &Subtable);
1852 if (ACPI_FAILURE (Status))
1853 {
1854 return (Status);
1855 }
1856
1857 DtInsertSubtable (ParentTable, Subtable);
1858 Count++;
1859 }
1860
1861 Ras2Header->NumPccDescs = (UINT8) Count;
1862 return (AE_OK);
1863 }
1864
1865
1866 /******************************************************************************
1867 *
1868 * FUNCTION: DtCompileRgrt
1869 *
1870 * PARAMETERS: List - Current field list pointer
1871 *
1872 * RETURN: Status
1873 *
1874 * DESCRIPTION: Compile RGRT.
1875 *
1876 *****************************************************************************/
1877
1878 ACPI_STATUS
DtCompileRgrt(void ** List)1879 DtCompileRgrt (
1880 void **List)
1881 {
1882 ACPI_STATUS Status;
1883 DT_SUBTABLE *Subtable;
1884 DT_SUBTABLE *ParentTable;
1885 DT_FIELD **PFieldList = (DT_FIELD **) List;
1886
1887
1888 /* Compile the main table */
1889
1890 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
1891 &Subtable);
1892 if (ACPI_FAILURE (Status))
1893 {
1894 return (Status);
1895 }
1896
1897 ParentTable = DtPeekSubtable ();
1898 DtInsertSubtable (ParentTable, Subtable);
1899
1900 /* Compile the "Subtable" -- actually just the binary (PNG) image */
1901
1902 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
1903 &Subtable);
1904 if (ACPI_FAILURE (Status))
1905 {
1906 return (Status);
1907 }
1908
1909 DtInsertSubtable (ParentTable, Subtable);
1910 return (AE_OK);
1911 }
1912
1913
1914 /******************************************************************************
1915 *
1916 * FUNCTION: DtCompileRhct
1917 *
1918 * PARAMETERS: List - Current field list pointer
1919 *
1920 * RETURN: Status
1921 *
1922 * DESCRIPTION: Compile RHCT.
1923 *
1924 *****************************************************************************/
1925
1926 ACPI_STATUS
DtCompileRhct(void ** List)1927 DtCompileRhct (
1928 void **List)
1929 {
1930 ACPI_STATUS Status;
1931 ACPI_RHCT_NODE_HEADER *RhctHeader;
1932 ACPI_RHCT_HART_INFO *RhctHartInfo;
1933 DT_SUBTABLE *Subtable;
1934 DT_SUBTABLE *ParentTable;
1935 ACPI_DMTABLE_INFO *InfoTable;
1936 DT_FIELD **PFieldList = (DT_FIELD **) List;
1937 DT_FIELD *SubtableStart;
1938 ACPI_TABLE_RHCT *Table;
1939 BOOLEAN FirstNode = TRUE;
1940
1941
1942 /* Compile the main table */
1943
1944 ParentTable = DtPeekSubtable ();
1945 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct,
1946 &Subtable);
1947 if (ACPI_FAILURE (Status))
1948 {
1949 return (Status);
1950 }
1951 DtInsertSubtable (ParentTable, Subtable);
1952 Table = ACPI_CAST_PTR (ACPI_TABLE_RHCT, ParentTable->Buffer);
1953 Table->NodeCount = 0;
1954 Table->NodeOffset = sizeof (ACPI_TABLE_RHCT);
1955
1956 while (*PFieldList)
1957 {
1958 SubtableStart = *PFieldList;
1959
1960 /* Compile RHCT subtable header */
1961
1962 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr,
1963 &Subtable);
1964 if (ACPI_FAILURE (Status))
1965 {
1966 return (Status);
1967 }
1968 DtInsertSubtable (ParentTable, Subtable);
1969 RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer);
1970
1971 DtPushSubtable (Subtable);
1972 ParentTable = DtPeekSubtable ();
1973 Table->NodeCount++;
1974
1975 switch (RhctHeader->Type)
1976 {
1977 case ACPI_RHCT_NODE_TYPE_ISA_STRING:
1978
1979 InfoTable = AcpiDmTableInfoRhctIsa1;
1980 break;
1981
1982 case ACPI_RHCT_NODE_TYPE_HART_INFO:
1983
1984 InfoTable = AcpiDmTableInfoRhctHartInfo1;
1985 break;
1986
1987 case ACPI_RHCT_NODE_TYPE_CMO:
1988
1989 InfoTable = AcpiDmTableInfoRhctCmo1;
1990 break;
1991
1992 case ACPI_RHCT_NODE_TYPE_MMU:
1993
1994 InfoTable = AcpiDmTableInfoRhctMmu1;
1995 break;
1996
1997 default:
1998
1999 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT");
2000 return (AE_ERROR);
2001 }
2002
2003 /* Compile RHCT subtable body */
2004
2005 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2006 if (ACPI_FAILURE (Status))
2007 {
2008 return (Status);
2009 }
2010 DtInsertSubtable (ParentTable, Subtable);
2011 if (FirstNode)
2012 {
2013 Table->NodeOffset = ACPI_PTR_DIFF(ParentTable->Buffer, Table);
2014 FirstNode = FALSE;
2015 }
2016
2017 /* Compile RHCT subtable additionals */
2018
2019 switch (RhctHeader->Type)
2020 {
2021 case ACPI_RHCT_NODE_TYPE_ISA_STRING:
2022
2023 /*
2024 * Padding - Variable-length data
2025 * Optionally allows the padding of the ISA string to be used
2026 * for filling this field.
2027 */
2028 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctIsaPad,
2029 &Subtable);
2030 if (ACPI_FAILURE (Status))
2031 {
2032 return (Status);
2033 }
2034 if (Subtable)
2035 {
2036 DtInsertSubtable (ParentTable, Subtable);
2037 }
2038 break;
2039
2040 case ACPI_RHCT_NODE_TYPE_HART_INFO:
2041
2042 RhctHartInfo = ACPI_CAST_PTR (ACPI_RHCT_HART_INFO,
2043 Subtable->Buffer);
2044 RhctHartInfo->NumOffsets = 0;
2045 while (*PFieldList)
2046 {
2047 Status = DtCompileTable (PFieldList,
2048 AcpiDmTableInfoRhctHartInfo2, &Subtable);
2049 if (ACPI_FAILURE (Status))
2050 {
2051 return (Status);
2052 }
2053 if (!Subtable)
2054 {
2055 break;
2056 }
2057 DtInsertSubtable (ParentTable, Subtable);
2058 RhctHartInfo->NumOffsets++;
2059 }
2060 break;
2061
2062 default:
2063
2064 break;
2065 }
2066
2067 DtPopSubtable ();
2068 ParentTable = DtPeekSubtable ();
2069 }
2070
2071 return (AE_OK);
2072 }
2073
2074
2075 /******************************************************************************
2076 *
2077 * FUNCTION: DtCompileRsdt
2078 *
2079 * PARAMETERS: List - Current field list pointer
2080 *
2081 * RETURN: Status
2082 *
2083 * DESCRIPTION: Compile RSDT.
2084 *
2085 *****************************************************************************/
2086
2087 ACPI_STATUS
DtCompileRsdt(void ** List)2088 DtCompileRsdt (
2089 void **List)
2090 {
2091 DT_SUBTABLE *Subtable;
2092 DT_SUBTABLE *ParentTable;
2093 DT_FIELD *FieldList = *(DT_FIELD **) List;
2094 UINT32 Address;
2095
2096
2097 ParentTable = DtPeekSubtable ();
2098
2099 while (FieldList)
2100 {
2101 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2102
2103 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2104 DtInsertSubtable (ParentTable, Subtable);
2105 FieldList = FieldList->Next;
2106 }
2107
2108 return (AE_OK);
2109 }
2110
2111
2112 /******************************************************************************
2113 *
2114 * FUNCTION: DtCompileS3pt
2115 *
2116 * PARAMETERS: PFieldList - Current field list pointer
2117 *
2118 * RETURN: Status
2119 *
2120 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2121 *
2122 *****************************************************************************/
2123
2124 ACPI_STATUS
DtCompileS3pt(DT_FIELD ** PFieldList)2125 DtCompileS3pt (
2126 DT_FIELD **PFieldList)
2127 {
2128 ACPI_STATUS Status;
2129 ACPI_FPDT_HEADER *S3ptHeader;
2130 DT_SUBTABLE *Subtable;
2131 DT_SUBTABLE *ParentTable;
2132 ACPI_DMTABLE_INFO *InfoTable;
2133 DT_FIELD *SubtableStart;
2134
2135
2136 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2137 &AslGbl_RootTable);
2138 if (ACPI_FAILURE (Status))
2139 {
2140 return (Status);
2141 }
2142
2143 DtPushSubtable (AslGbl_RootTable);
2144
2145 while (*PFieldList)
2146 {
2147 SubtableStart = *PFieldList;
2148 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2149 &Subtable);
2150 if (ACPI_FAILURE (Status))
2151 {
2152 return (Status);
2153 }
2154
2155 ParentTable = DtPeekSubtable ();
2156 DtInsertSubtable (ParentTable, Subtable);
2157 DtPushSubtable (Subtable);
2158
2159 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
2160
2161 switch (S3ptHeader->Type)
2162 {
2163 case ACPI_S3PT_TYPE_RESUME:
2164
2165 InfoTable = AcpiDmTableInfoS3pt0;
2166 break;
2167
2168 case ACPI_S3PT_TYPE_SUSPEND:
2169
2170 InfoTable = AcpiDmTableInfoS3pt1;
2171 break;
2172
2173 default:
2174
2175 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2176 return (AE_ERROR);
2177 }
2178
2179 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2180 if (ACPI_FAILURE (Status))
2181 {
2182 return (Status);
2183 }
2184
2185 ParentTable = DtPeekSubtable ();
2186 DtInsertSubtable (ParentTable, Subtable);
2187 DtPopSubtable ();
2188 }
2189
2190 return (AE_OK);
2191 }
2192
2193
2194 /******************************************************************************
2195 *
2196 * FUNCTION: DtCompileSdev
2197 *
2198 * PARAMETERS: List - Current field list pointer
2199 *
2200 * RETURN: Status
2201 *
2202 * DESCRIPTION: Compile SDEV.
2203 *
2204 *****************************************************************************/
2205
2206 ACPI_STATUS
DtCompileSdev(void ** List)2207 DtCompileSdev (
2208 void **List)
2209 {
2210 ACPI_STATUS Status;
2211 ACPI_SDEV_HEADER *SdevHeader;
2212 ACPI_SDEV_HEADER *SecureComponentHeader;
2213 DT_SUBTABLE *Subtable;
2214 DT_SUBTABLE *ParentTable;
2215 ACPI_DMTABLE_INFO *InfoTable;
2216 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL;
2217 DT_FIELD **PFieldList = (DT_FIELD **) List;
2218 DT_FIELD *SubtableStart;
2219 ACPI_SDEV_PCIE *Pcie = NULL;
2220 ACPI_SDEV_NAMESPACE *Namesp = NULL;
2221 UINT32 EntryCount;
2222 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL;
2223 UINT16 ComponentLength = 0;
2224
2225
2226 /* Subtables */
2227
2228 while (*PFieldList)
2229 {
2230 /* Compile common SDEV subtable header */
2231
2232 SubtableStart = *PFieldList;
2233 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
2234 &Subtable);
2235 if (ACPI_FAILURE (Status))
2236 {
2237 return (Status);
2238 }
2239
2240 ParentTable = DtPeekSubtable ();
2241 DtInsertSubtable (ParentTable, Subtable);
2242 DtPushSubtable (Subtable);
2243
2244 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2245 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
2246
2247 switch (SdevHeader->Type)
2248 {
2249 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2250
2251 InfoTable = AcpiDmTableInfoSdev0;
2252 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
2253 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2254 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
2255 break;
2256
2257 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2258
2259 InfoTable = AcpiDmTableInfoSdev1;
2260 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
2261 break;
2262
2263 default:
2264
2265 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2266 return (AE_ERROR);
2267 }
2268
2269 /* Compile SDEV subtable body */
2270
2271 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2272 if (ACPI_FAILURE (Status))
2273 {
2274 return (Status);
2275 }
2276
2277 ParentTable = DtPeekSubtable ();
2278 DtInsertSubtable (ParentTable, Subtable);
2279
2280 /* Optional data fields are appended to the main subtable body */
2281
2282 switch (SdevHeader->Type)
2283 {
2284 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2285
2286 /*
2287 * Device Id Offset will be be calculated differently depending on
2288 * the presence of secure access components.
2289 */
2290 Namesp->DeviceIdOffset = 0;
2291 ComponentLength = 0;
2292
2293 /* If the secure access component exists, get the structures */
2294
2295 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2296 {
2297 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
2298 &Subtable);
2299 if (ACPI_FAILURE (Status))
2300 {
2301 return (Status);
2302 }
2303 ParentTable = DtPeekSubtable ();
2304 DtInsertSubtable (ParentTable, Subtable);
2305
2306 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2307
2308 /* Compile a secure access component header */
2309
2310 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
2311 &Subtable);
2312 if (ACPI_FAILURE (Status))
2313 {
2314 return (Status);
2315 }
2316 ParentTable = DtPeekSubtable ();
2317 DtInsertSubtable (ParentTable, Subtable);
2318
2319 /* Compile the secure access component */
2320
2321 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2322 switch (SecureComponentHeader->Type)
2323 {
2324 case ACPI_SDEV_TYPE_ID_COMPONENT:
2325
2326 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2327 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
2328 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
2329 break;
2330
2331 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2332
2333 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2334 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
2335 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
2336 break;
2337
2338 default:
2339
2340 /* Any other secure component types are undefined */
2341
2342 return (AE_ERROR);
2343 }
2344
2345 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
2346 &Subtable);
2347 if (ACPI_FAILURE (Status))
2348 {
2349 return (Status);
2350 }
2351 ParentTable = DtPeekSubtable ();
2352 DtInsertSubtable (ParentTable, Subtable);
2353
2354 SecureComponent->SecureComponentOffset =
2355 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
2356 SecureComponent->SecureComponentLength = ComponentLength;
2357
2358
2359 /*
2360 * Add the secure component to the subtable to be added for the
2361 * the namespace subtable's length
2362 */
2363 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2364 }
2365
2366 /* Append DeviceId namespace string */
2367
2368 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
2369 &Subtable);
2370 if (ACPI_FAILURE (Status))
2371 {
2372 return (Status);
2373 }
2374
2375 if (!Subtable)
2376 {
2377 break;
2378 }
2379
2380 ParentTable = DtPeekSubtable ();
2381 DtInsertSubtable (ParentTable, Subtable);
2382
2383 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
2384
2385 Namesp->DeviceIdLength = (UINT16) Subtable->Length;
2386
2387 /* Append Vendor data */
2388
2389 Namesp->VendorDataLength = 0;
2390 Namesp->VendorDataOffset = 0;
2391
2392 if (*PFieldList)
2393 {
2394 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2395 &Subtable);
2396 if (ACPI_FAILURE (Status))
2397 {
2398 return (Status);
2399 }
2400
2401 if (Subtable)
2402 {
2403 ParentTable = DtPeekSubtable ();
2404 DtInsertSubtable (ParentTable, Subtable);
2405
2406 Namesp->VendorDataOffset =
2407 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2408 Namesp->VendorDataLength =
2409 (UINT16) Subtable->Length;
2410
2411 /* Final size of entire namespace structure */
2412
2413 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
2414 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
2415 }
2416 }
2417
2418 break;
2419
2420 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2421
2422 /* Append the PCIe path info first */
2423
2424 EntryCount = 0;
2425 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
2426 {
2427 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
2428 &Subtable);
2429 if (ACPI_FAILURE (Status))
2430 {
2431 return (Status);
2432 }
2433
2434 if (!Subtable)
2435 {
2436 DtPopSubtable ();
2437 break;
2438 }
2439
2440 ParentTable = DtPeekSubtable ();
2441 DtInsertSubtable (ParentTable, Subtable);
2442 EntryCount++;
2443 }
2444
2445 /* Path offset will point immediately after the main subtable */
2446
2447 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
2448 Pcie->PathLength = (UINT16)
2449 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
2450
2451 /* Append the Vendor Data last */
2452
2453 Pcie->VendorDataLength = 0;
2454 Pcie->VendorDataOffset = 0;
2455
2456 if (*PFieldList)
2457 {
2458 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2459 &Subtable);
2460 if (ACPI_FAILURE (Status))
2461 {
2462 return (Status);
2463 }
2464
2465 if (Subtable)
2466 {
2467 ParentTable = DtPeekSubtable ();
2468 DtInsertSubtable (ParentTable, Subtable);
2469
2470 Pcie->VendorDataOffset =
2471 Pcie->PathOffset + Pcie->PathLength;
2472 Pcie->VendorDataLength = (UINT16)
2473 Subtable->Length;
2474 }
2475 }
2476
2477 SdevHeader->Length =
2478 sizeof (ACPI_SDEV_PCIE) +
2479 Pcie->PathLength + Pcie->VendorDataLength;
2480 break;
2481
2482 default:
2483
2484 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2485 return (AE_ERROR);
2486 }
2487
2488 DtPopSubtable ();
2489 }
2490
2491 return (AE_OK);
2492 }
2493
2494
2495 /******************************************************************************
2496 *
2497 * FUNCTION: DtCompileSlic
2498 *
2499 * PARAMETERS: List - Current field list pointer
2500 *
2501 * RETURN: Status
2502 *
2503 * DESCRIPTION: Compile SLIC.
2504 *
2505 *****************************************************************************/
2506
2507 ACPI_STATUS
DtCompileSlic(void ** List)2508 DtCompileSlic (
2509 void **List)
2510 {
2511 ACPI_STATUS Status;
2512 DT_SUBTABLE *Subtable;
2513 DT_SUBTABLE *ParentTable;
2514 DT_FIELD **PFieldList = (DT_FIELD **) List;
2515
2516
2517 while (*PFieldList)
2518 {
2519 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2520 &Subtable);
2521 if (ACPI_FAILURE (Status))
2522 {
2523 return (Status);
2524 }
2525
2526 ParentTable = DtPeekSubtable ();
2527 DtInsertSubtable (ParentTable, Subtable);
2528 DtPushSubtable (Subtable);
2529 DtPopSubtable ();
2530 }
2531
2532 return (AE_OK);
2533 }
2534
2535
2536 /******************************************************************************
2537 *
2538 * FUNCTION: DtCompileSlit
2539 *
2540 * PARAMETERS: List - Current field list pointer
2541 *
2542 * RETURN: Status
2543 *
2544 * DESCRIPTION: Compile SLIT.
2545 *
2546 *****************************************************************************/
2547
2548 ACPI_STATUS
DtCompileSlit(void ** List)2549 DtCompileSlit (
2550 void **List)
2551 {
2552 ACPI_STATUS Status;
2553 DT_SUBTABLE *Subtable;
2554 DT_SUBTABLE *ParentTable;
2555 DT_FIELD **PFieldList = (DT_FIELD **) List;
2556 DT_FIELD *FieldList;
2557 DT_FIELD *EndOfFieldList = NULL;
2558 UINT32 Localities;
2559 UINT32 LocalityListLength;
2560 UINT8 *LocalityBuffer;
2561
2562
2563 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2564 &Subtable);
2565 if (ACPI_FAILURE (Status))
2566 {
2567 return (Status);
2568 }
2569
2570 ParentTable = DtPeekSubtable ();
2571 DtInsertSubtable (ParentTable, Subtable);
2572
2573 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2574 LocalityBuffer = UtLocalCalloc (Localities);
2575 LocalityListLength = 0;
2576
2577 /* Compile each locality buffer */
2578
2579 FieldList = *PFieldList;
2580 while (FieldList)
2581 {
2582 DtCompileBuffer (LocalityBuffer,
2583 FieldList->Value, FieldList, Localities);
2584
2585 LocalityListLength++;
2586 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2587 DtInsertSubtable (ParentTable, Subtable);
2588 EndOfFieldList = FieldList;
2589 FieldList = FieldList->Next;
2590 }
2591
2592 if (LocalityListLength != Localities)
2593 {
2594 sprintf(AslGbl_MsgBuffer,
2595 "Found %u entries, must match LocalityCount: %u",
2596 LocalityListLength, Localities);
2597 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
2598 ACPI_FREE (LocalityBuffer);
2599 return (AE_LIMIT);
2600 }
2601
2602 ACPI_FREE (LocalityBuffer);
2603 return (AE_OK);
2604 }
2605
2606
2607 /******************************************************************************
2608 *
2609 * FUNCTION: DtCompileSrat
2610 *
2611 * PARAMETERS: List - Current field list pointer
2612 *
2613 * RETURN: Status
2614 *
2615 * DESCRIPTION: Compile SRAT.
2616 *
2617 *****************************************************************************/
2618
2619 ACPI_STATUS
DtCompileSrat(void ** List)2620 DtCompileSrat (
2621 void **List)
2622 {
2623 ACPI_STATUS Status;
2624 DT_SUBTABLE *Subtable;
2625 DT_SUBTABLE *ParentTable;
2626 DT_FIELD **PFieldList = (DT_FIELD **) List;
2627 DT_FIELD *SubtableStart;
2628 ACPI_SUBTABLE_HEADER *SratHeader;
2629 ACPI_DMTABLE_INFO *InfoTable;
2630
2631
2632 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2633 &Subtable);
2634 if (ACPI_FAILURE (Status))
2635 {
2636 return (Status);
2637 }
2638
2639 ParentTable = DtPeekSubtable ();
2640 DtInsertSubtable (ParentTable, Subtable);
2641
2642 while (*PFieldList)
2643 {
2644 SubtableStart = *PFieldList;
2645 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2646 &Subtable);
2647 if (ACPI_FAILURE (Status))
2648 {
2649 return (Status);
2650 }
2651
2652 ParentTable = DtPeekSubtable ();
2653 DtInsertSubtable (ParentTable, Subtable);
2654 DtPushSubtable (Subtable);
2655
2656 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2657
2658 switch (SratHeader->Type)
2659 {
2660 case ACPI_SRAT_TYPE_CPU_AFFINITY:
2661
2662 InfoTable = AcpiDmTableInfoSrat0;
2663 break;
2664
2665 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2666
2667 InfoTable = AcpiDmTableInfoSrat1;
2668 break;
2669
2670 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2671
2672 InfoTable = AcpiDmTableInfoSrat2;
2673 break;
2674
2675 case ACPI_SRAT_TYPE_GICC_AFFINITY:
2676
2677 InfoTable = AcpiDmTableInfoSrat3;
2678 break;
2679
2680 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
2681
2682 InfoTable = AcpiDmTableInfoSrat4;
2683 break;
2684
2685 case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
2686
2687 InfoTable = AcpiDmTableInfoSrat5;
2688 break;
2689
2690 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
2691
2692 InfoTable = AcpiDmTableInfoSrat6;
2693 break;
2694
2695 case ACPI_SRAT_TYPE_RINTC_AFFINITY:
2696
2697 InfoTable = AcpiDmTableInfoSrat7;
2698 break;
2699
2700 default:
2701
2702 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2703 return (AE_ERROR);
2704 }
2705
2706 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2707 if (ACPI_FAILURE (Status))
2708 {
2709 return (Status);
2710 }
2711
2712 ParentTable = DtPeekSubtable ();
2713 DtInsertSubtable (ParentTable, Subtable);
2714 DtPopSubtable ();
2715 }
2716
2717 return (AE_OK);
2718 }
2719
2720
2721 /******************************************************************************
2722 *
2723 * FUNCTION: DtCompileStao
2724 *
2725 * PARAMETERS: PFieldList - Current field list pointer
2726 *
2727 * RETURN: Status
2728 *
2729 * DESCRIPTION: Compile STAO.
2730 *
2731 *****************************************************************************/
2732
2733 ACPI_STATUS
DtCompileStao(void ** List)2734 DtCompileStao (
2735 void **List)
2736 {
2737 DT_FIELD **PFieldList = (DT_FIELD **) List;
2738 DT_SUBTABLE *Subtable;
2739 DT_SUBTABLE *ParentTable;
2740 ACPI_STATUS Status;
2741
2742
2743 /* Compile the main table */
2744
2745 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
2746 &Subtable);
2747 if (ACPI_FAILURE (Status))
2748 {
2749 return (Status);
2750 }
2751
2752 ParentTable = DtPeekSubtable ();
2753 DtInsertSubtable (ParentTable, Subtable);
2754
2755 /* Compile each ASCII namestring as a subtable */
2756
2757 while (*PFieldList)
2758 {
2759 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
2760 &Subtable);
2761 if (ACPI_FAILURE (Status))
2762 {
2763 return (Status);
2764 }
2765
2766 ParentTable = DtPeekSubtable ();
2767 DtInsertSubtable (ParentTable, Subtable);
2768 }
2769
2770 return (AE_OK);
2771 }
2772
2773
2774 /******************************************************************************
2775 *
2776 * FUNCTION: DtCompileSvkl
2777 *
2778 * PARAMETERS: PFieldList - Current field list pointer
2779 *
2780 * RETURN: Status
2781 *
2782 * DESCRIPTION: Compile SVKL.
2783 *
2784 * NOTES: SVKL is essentially a flat table, with a small main table and
2785 * a variable number of a single type of subtable.
2786 *
2787 *****************************************************************************/
2788
2789 ACPI_STATUS
DtCompileSvkl(void ** List)2790 DtCompileSvkl (
2791 void **List)
2792 {
2793 DT_FIELD **PFieldList = (DT_FIELD **) List;
2794 DT_SUBTABLE *Subtable;
2795 DT_SUBTABLE *ParentTable;
2796 ACPI_STATUS Status;
2797
2798
2799 /* Compile the main table */
2800
2801 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
2802 &Subtable);
2803 if (ACPI_FAILURE (Status))
2804 {
2805 return (Status);
2806 }
2807
2808 ParentTable = DtPeekSubtable ();
2809 DtInsertSubtable (ParentTable, Subtable);
2810
2811 /* Compile each subtable */
2812
2813 while (*PFieldList)
2814 {
2815 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
2816 &Subtable);
2817 if (ACPI_FAILURE (Status))
2818 {
2819 return (Status);
2820 }
2821
2822 ParentTable = DtPeekSubtable ();
2823 DtInsertSubtable (ParentTable, Subtable);
2824 }
2825
2826 return (AE_OK);
2827 }
2828
2829
2830 /******************************************************************************
2831 *
2832 * FUNCTION: DtCompileTcpa
2833 *
2834 * PARAMETERS: PFieldList - Current field list pointer
2835 *
2836 * RETURN: Status
2837 *
2838 * DESCRIPTION: Compile TCPA.
2839 *
2840 *****************************************************************************/
2841
2842 ACPI_STATUS
DtCompileTcpa(void ** List)2843 DtCompileTcpa (
2844 void **List)
2845 {
2846 DT_FIELD **PFieldList = (DT_FIELD **) List;
2847 DT_SUBTABLE *Subtable;
2848 ACPI_TABLE_TCPA_HDR *TcpaHeader;
2849 DT_SUBTABLE *ParentTable;
2850 ACPI_STATUS Status;
2851
2852
2853 /* Compile the main table */
2854
2855 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
2856 &Subtable);
2857 if (ACPI_FAILURE (Status))
2858 {
2859 return (Status);
2860 }
2861
2862 ParentTable = DtPeekSubtable ();
2863 DtInsertSubtable (ParentTable, Subtable);
2864
2865 /*
2866 * Examine the PlatformClass field to determine the table type.
2867 * Either a client or server table. Only one.
2868 */
2869 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
2870
2871 switch (TcpaHeader->PlatformClass)
2872 {
2873 case ACPI_TCPA_CLIENT_TABLE:
2874
2875 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
2876 &Subtable);
2877 break;
2878
2879 case ACPI_TCPA_SERVER_TABLE:
2880
2881 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
2882 &Subtable);
2883 break;
2884
2885 default:
2886
2887 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
2888 TcpaHeader->PlatformClass);
2889 Status = AE_ERROR;
2890 break;
2891 }
2892
2893 ParentTable = DtPeekSubtable ();
2894 DtInsertSubtable (ParentTable, Subtable);
2895 return (Status);
2896 }
2897
2898
2899 /******************************************************************************
2900 *
2901 * FUNCTION: DtCompileTpm2Rev3
2902 *
2903 * PARAMETERS: PFieldList - Current field list pointer
2904 *
2905 * RETURN: Status
2906 *
2907 * DESCRIPTION: Compile TPM2 revision 3
2908 *
2909 *****************************************************************************/
2910 static ACPI_STATUS
DtCompileTpm2Rev3(void ** List)2911 DtCompileTpm2Rev3 (
2912 void **List)
2913 {
2914 DT_FIELD **PFieldList = (DT_FIELD **) List;
2915 DT_SUBTABLE *Subtable;
2916 ACPI_TABLE_TPM23 *Tpm23Header;
2917 DT_SUBTABLE *ParentTable;
2918 ACPI_STATUS Status = AE_OK;
2919
2920
2921 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
2922 &Subtable);
2923
2924 ParentTable = DtPeekSubtable ();
2925 DtInsertSubtable (ParentTable, Subtable);
2926 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
2927
2928 /* Subtable type depends on the StartMethod */
2929
2930 switch (Tpm23Header->StartMethod)
2931 {
2932 case ACPI_TPM23_ACPI_START_METHOD:
2933
2934 /* Subtable specific to to ARM_SMC */
2935
2936 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
2937 &Subtable);
2938 if (ACPI_FAILURE (Status))
2939 {
2940 return (Status);
2941 }
2942
2943 ParentTable = DtPeekSubtable ();
2944 DtInsertSubtable (ParentTable, Subtable);
2945 break;
2946
2947 default:
2948 break;
2949 }
2950
2951 return (Status);
2952 }
2953
2954
2955 /******************************************************************************
2956 *
2957 * FUNCTION: DtCompileTpm2
2958 *
2959 * PARAMETERS: PFieldList - Current field list pointer
2960 *
2961 * RETURN: Status
2962 *
2963 * DESCRIPTION: Compile TPM2.
2964 *
2965 *****************************************************************************/
2966
2967 ACPI_STATUS
DtCompileTpm2(void ** List)2968 DtCompileTpm2 (
2969 void **List)
2970 {
2971 DT_FIELD **PFieldList = (DT_FIELD **) List;
2972 DT_SUBTABLE *Subtable;
2973 ACPI_TABLE_TPM2 *Tpm2Header;
2974 DT_SUBTABLE *ParentTable;
2975 ACPI_STATUS Status = AE_OK;
2976 ACPI_TABLE_HEADER *Header;
2977
2978
2979 ParentTable = DtPeekSubtable ();
2980
2981 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2982
2983 if (Header->Revision == 3)
2984 {
2985 return (DtCompileTpm2Rev3 (List));
2986 }
2987
2988 /* Compile the main table */
2989
2990 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
2991 &Subtable);
2992 if (ACPI_FAILURE (Status))
2993 {
2994 return (Status);
2995 }
2996
2997 ParentTable = DtPeekSubtable ();
2998 DtInsertSubtable (ParentTable, Subtable);
2999
3000 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
3001
3002 /* Method parameters */
3003 /* Optional: Log area minimum length */
3004 /* Optional: Log area start address */
3005 /* TBD: Optional fields above not fully implemented (not optional at this time) */
3006
3007 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
3008 &Subtable);
3009 if (ACPI_FAILURE (Status))
3010 {
3011 return (Status);
3012 }
3013
3014 ParentTable = DtPeekSubtable ();
3015 DtInsertSubtable (ParentTable, Subtable);
3016
3017
3018 /* Subtable type depends on the StartMethod */
3019
3020 switch (Tpm2Header->StartMethod)
3021 {
3022 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
3023
3024 /* Subtable specific to to ARM_SMC */
3025
3026 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
3027 &Subtable);
3028 if (ACPI_FAILURE (Status))
3029 {
3030 return (Status);
3031 }
3032
3033 ParentTable = DtPeekSubtable ();
3034 DtInsertSubtable (ParentTable, Subtable);
3035 break;
3036
3037 case ACPI_TPM2_START_METHOD:
3038 case ACPI_TPM2_MEMORY_MAPPED:
3039 case ACPI_TPM2_COMMAND_BUFFER:
3040 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
3041 break;
3042
3043 case ACPI_TPM2_RESERVED1:
3044 case ACPI_TPM2_RESERVED3:
3045 case ACPI_TPM2_RESERVED4:
3046 case ACPI_TPM2_RESERVED5:
3047 case ACPI_TPM2_RESERVED9:
3048 case ACPI_TPM2_RESERVED10:
3049
3050 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
3051 Tpm2Header->StartMethod);
3052 Status = AE_ERROR;
3053 break;
3054
3055 case ACPI_TPM2_NOT_ALLOWED:
3056 default:
3057
3058 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
3059 Tpm2Header->StartMethod);
3060 Status = AE_ERROR;
3061 break;
3062 }
3063
3064 return (Status);
3065 }
3066
3067
3068 /******************************************************************************
3069 *
3070 * FUNCTION: DtGetGenericTableInfo
3071 *
3072 * PARAMETERS: Name - Generic type name
3073 *
3074 * RETURN: Info entry
3075 *
3076 * DESCRIPTION: Obtain table info for a generic name entry
3077 *
3078 *****************************************************************************/
3079
3080 ACPI_DMTABLE_INFO *
DtGetGenericTableInfo(char * Name)3081 DtGetGenericTableInfo (
3082 char *Name)
3083 {
3084 ACPI_DMTABLE_INFO *Info;
3085 UINT32 i;
3086
3087
3088 if (!Name)
3089 {
3090 return (NULL);
3091 }
3092
3093 /* Search info table for name match */
3094
3095 for (i = 0; ; i++)
3096 {
3097 Info = AcpiDmTableInfoGeneric[i];
3098 if (Info->Opcode == ACPI_DMT_EXIT)
3099 {
3100 Info = NULL;
3101 break;
3102 }
3103
3104 /* Use caseless compare for generic keywords */
3105
3106 if (!AcpiUtStricmp (Name, Info->Name))
3107 {
3108 break;
3109 }
3110 }
3111
3112 return (Info);
3113 }
3114
3115
3116 /******************************************************************************
3117 *
3118 * FUNCTION: DtCompileUefi
3119 *
3120 * PARAMETERS: List - Current field list pointer
3121 *
3122 * RETURN: Status
3123 *
3124 * DESCRIPTION: Compile UEFI.
3125 *
3126 *****************************************************************************/
3127
3128 ACPI_STATUS
DtCompileUefi(void ** List)3129 DtCompileUefi (
3130 void **List)
3131 {
3132 ACPI_STATUS Status;
3133 DT_SUBTABLE *Subtable;
3134 DT_SUBTABLE *ParentTable;
3135 DT_FIELD **PFieldList = (DT_FIELD **) List;
3136 UINT16 *DataOffset;
3137
3138
3139 /* Compile the predefined portion of the UEFI table */
3140
3141 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
3142 &Subtable);
3143 if (ACPI_FAILURE (Status))
3144 {
3145 return (Status);
3146 }
3147
3148 DataOffset = (UINT16 *) (Subtable->Buffer + 16);
3149 *DataOffset = sizeof (ACPI_TABLE_UEFI);
3150
3151 ParentTable = DtPeekSubtable ();
3152 DtInsertSubtable (ParentTable, Subtable);
3153
3154 /*
3155 * Compile the "generic" portion of the UEFI table. This
3156 * part of the table is not predefined and any of the generic
3157 * operators may be used.
3158 */
3159 DtCompileGeneric ((void **) PFieldList, NULL, NULL);
3160 return (AE_OK);
3161 }
3162
3163
3164 /******************************************************************************
3165 *
3166 * FUNCTION: DtCompileViot
3167 *
3168 * PARAMETERS: List - Current field list pointer
3169 *
3170 * RETURN: Status
3171 *
3172 * DESCRIPTION: Compile VIOT.
3173 *
3174 *****************************************************************************/
3175
3176 ACPI_STATUS
DtCompileViot(void ** List)3177 DtCompileViot (
3178 void **List)
3179 {
3180 ACPI_STATUS Status;
3181 DT_SUBTABLE *Subtable;
3182 DT_SUBTABLE *ParentTable;
3183 DT_FIELD **PFieldList = (DT_FIELD **) List;
3184 DT_FIELD *SubtableStart;
3185 ACPI_TABLE_VIOT *Viot;
3186 ACPI_VIOT_HEADER *ViotHeader;
3187 ACPI_DMTABLE_INFO *InfoTable;
3188 UINT16 NodeCount;
3189
3190 ParentTable = DtPeekSubtable ();
3191
3192 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
3193 if (ACPI_FAILURE (Status))
3194 {
3195 return (Status);
3196 }
3197 DtInsertSubtable (ParentTable, Subtable);
3198
3199 /*
3200 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
3201 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
3202 */
3203 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
3204 sizeof (ACPI_TABLE_HEADER));
3205
3206 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
3207
3208 NodeCount = 0;
3209 while (*PFieldList) {
3210 SubtableStart = *PFieldList;
3211 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
3212 &Subtable);
3213 if (ACPI_FAILURE (Status))
3214 {
3215 return (Status);
3216 }
3217
3218 ParentTable = DtPeekSubtable ();
3219 DtInsertSubtable (ParentTable, Subtable);
3220 DtPushSubtable (Subtable);
3221
3222 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
3223
3224 switch (ViotHeader->Type)
3225 {
3226 case ACPI_VIOT_NODE_PCI_RANGE:
3227
3228 InfoTable = AcpiDmTableInfoViot1;
3229 break;
3230
3231 case ACPI_VIOT_NODE_MMIO:
3232
3233 InfoTable = AcpiDmTableInfoViot2;
3234 break;
3235
3236 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
3237
3238 InfoTable = AcpiDmTableInfoViot3;
3239 break;
3240
3241 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
3242
3243 InfoTable = AcpiDmTableInfoViot4;
3244 break;
3245
3246 default:
3247
3248 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
3249 return (AE_ERROR);
3250 }
3251
3252 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
3253 if (ACPI_FAILURE (Status))
3254 {
3255 return (Status);
3256 }
3257
3258 ParentTable = DtPeekSubtable ();
3259 DtInsertSubtable (ParentTable, Subtable);
3260 DtPopSubtable ();
3261 NodeCount++;
3262 }
3263
3264 Viot->NodeCount = NodeCount;
3265 return (AE_OK);
3266 }
3267
3268
3269 /******************************************************************************
3270 *
3271 * FUNCTION: DtCompileWdat
3272 *
3273 * PARAMETERS: List - Current field list pointer
3274 *
3275 * RETURN: Status
3276 *
3277 * DESCRIPTION: Compile WDAT.
3278 *
3279 *****************************************************************************/
3280
3281 ACPI_STATUS
DtCompileWdat(void ** List)3282 DtCompileWdat (
3283 void **List)
3284 {
3285 ACPI_STATUS Status;
3286
3287
3288 Status = DtCompileTwoSubtables (List,
3289 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3290 return (Status);
3291 }
3292
3293
3294 /******************************************************************************
3295 *
3296 * FUNCTION: DtCompileWpbt
3297 *
3298 * PARAMETERS: List - Current field list pointer
3299 *
3300 * RETURN: Status
3301 *
3302 * DESCRIPTION: Compile WPBT.
3303 *
3304 *****************************************************************************/
3305
3306 ACPI_STATUS
DtCompileWpbt(void ** List)3307 DtCompileWpbt (
3308 void **List)
3309 {
3310 DT_FIELD **PFieldList = (DT_FIELD **) List;
3311 DT_SUBTABLE *Subtable;
3312 DT_SUBTABLE *ParentTable;
3313 ACPI_TABLE_WPBT *Table;
3314 ACPI_STATUS Status;
3315
3316
3317 /* Compile the main table */
3318
3319 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
3320 if (ACPI_FAILURE (Status))
3321 {
3322 return (Status);
3323 }
3324
3325 ParentTable = DtPeekSubtable ();
3326 DtInsertSubtable (ParentTable, Subtable);
3327 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3328
3329 /*
3330 * Exit now if there are no arguments specified. This is indicated by:
3331 * The "Command-line Arguments" field has not been specified (if specified,
3332 * it will be the last field in the field list -- after the main table).
3333 * Set the Argument Length in the main table to zero.
3334 */
3335 if (!*PFieldList)
3336 {
3337 Table->ArgumentsLength = 0;
3338 return (AE_OK);
3339 }
3340
3341 /* Compile the argument list subtable */
3342
3343 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
3344 if (ACPI_FAILURE (Status))
3345 {
3346 return (Status);
3347 }
3348
3349 /* Extract the length of the Arguments buffer, insert into main table */
3350
3351 Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
3352 DtInsertSubtable (ParentTable, Subtable);
3353 return (AE_OK);
3354 }
3355
3356
3357 /******************************************************************************
3358 *
3359 * FUNCTION: DtCompileXsdt
3360 *
3361 * PARAMETERS: List - Current field list pointer
3362 *
3363 * RETURN: Status
3364 *
3365 * DESCRIPTION: Compile XSDT.
3366 *
3367 *****************************************************************************/
3368
3369 ACPI_STATUS
DtCompileXsdt(void ** List)3370 DtCompileXsdt (
3371 void **List)
3372 {
3373 DT_SUBTABLE *Subtable;
3374 DT_SUBTABLE *ParentTable;
3375 DT_FIELD *FieldList = *(DT_FIELD **) List;
3376 UINT64 Address;
3377
3378
3379 ParentTable = DtPeekSubtable ();
3380
3381 while (FieldList)
3382 {
3383 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3384
3385 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3386 DtInsertSubtable (ParentTable, Subtable);
3387 FieldList = FieldList->Next;
3388 }
3389
3390 return (AE_OK);
3391 }
3392
3393
3394 /******************************************************************************
3395 *
3396 * FUNCTION: DtCompileGeneric
3397 *
3398 * PARAMETERS: List - Current field list pointer
3399 * Name - Field name to end generic compiling
3400 * Length - Compiled table length to return
3401 *
3402 * RETURN: Status
3403 *
3404 * DESCRIPTION: Compile generic unknown table.
3405 *
3406 *****************************************************************************/
3407
3408 ACPI_STATUS
DtCompileGeneric(void ** List,char * Name,UINT32 * Length)3409 DtCompileGeneric (
3410 void **List,
3411 char *Name,
3412 UINT32 *Length)
3413 {
3414 ACPI_STATUS Status;
3415 DT_SUBTABLE *Subtable;
3416 DT_SUBTABLE *ParentTable;
3417 DT_FIELD **PFieldList = (DT_FIELD **) List;
3418 ACPI_DMTABLE_INFO *Info;
3419
3420
3421 ParentTable = DtPeekSubtable ();
3422
3423 /*
3424 * Compile the "generic" portion of the table. This
3425 * part of the table is not predefined and any of the generic
3426 * operators may be used.
3427 */
3428
3429 /* Find any and all labels in the entire generic portion */
3430
3431 DtDetectAllLabels (*PFieldList);
3432
3433 /* Now we can actually compile the parse tree */
3434
3435 if (Length && *Length)
3436 {
3437 *Length = 0;
3438 }
3439 while (*PFieldList)
3440 {
3441 if (Name && !strcmp ((*PFieldList)->Name, Name))
3442 {
3443 break;
3444 }
3445
3446 Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3447 if (!Info)
3448 {
3449 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3450 (*PFieldList)->Name);
3451 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3452 (*PFieldList), AslGbl_MsgBuffer);
3453
3454 *PFieldList = (*PFieldList)->Next;
3455 continue;
3456 }
3457
3458 Status = DtCompileTable (PFieldList, Info,
3459 &Subtable);
3460 if (ACPI_SUCCESS (Status))
3461 {
3462 DtInsertSubtable (ParentTable, Subtable);
3463 if (Length)
3464 {
3465 *Length += Subtable->Length;
3466 }
3467 }
3468 else
3469 {
3470 *PFieldList = (*PFieldList)->Next;
3471
3472 if (Status == AE_NOT_FOUND)
3473 {
3474 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3475 (*PFieldList)->Name);
3476 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3477 (*PFieldList), AslGbl_MsgBuffer);
3478 }
3479 }
3480 }
3481
3482 return (AE_OK);
3483 }
3484