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