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 - 2024, 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: DtCompileMsct
794 *
795 * PARAMETERS: List - Current field list pointer
796 *
797 * RETURN: Status
798 *
799 * DESCRIPTION: Compile MSCT.
800 *
801 *****************************************************************************/
802
803 ACPI_STATUS
DtCompileMsct(void ** List)804 DtCompileMsct (
805 void **List)
806 {
807 ACPI_STATUS Status;
808
809
810 Status = DtCompileTwoSubtables (List,
811 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
812 return (Status);
813 }
814
815
816 /******************************************************************************
817 *
818 * FUNCTION: DtCompileNfit
819 *
820 * PARAMETERS: List - Current field list pointer
821 *
822 * RETURN: Status
823 *
824 * DESCRIPTION: Compile NFIT.
825 *
826 *****************************************************************************/
827
828 ACPI_STATUS
DtCompileNfit(void ** List)829 DtCompileNfit (
830 void **List)
831 {
832 ACPI_STATUS Status;
833 DT_SUBTABLE *Subtable;
834 DT_SUBTABLE *ParentTable;
835 DT_FIELD **PFieldList = (DT_FIELD **) List;
836 DT_FIELD *SubtableStart;
837 ACPI_NFIT_HEADER *NfitHeader;
838 ACPI_DMTABLE_INFO *InfoTable;
839 UINT32 Count;
840 ACPI_NFIT_INTERLEAVE *Interleave = NULL;
841 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
842
843
844 /* Main table */
845
846 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
847 &Subtable);
848 if (ACPI_FAILURE (Status))
849 {
850 return (Status);
851 }
852
853 ParentTable = DtPeekSubtable ();
854 DtInsertSubtable (ParentTable, Subtable);
855 DtPushSubtable (Subtable);
856
857 /* Subtables */
858
859 while (*PFieldList)
860 {
861 SubtableStart = *PFieldList;
862 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
863 &Subtable);
864 if (ACPI_FAILURE (Status))
865 {
866 return (Status);
867 }
868
869 ParentTable = DtPeekSubtable ();
870 DtInsertSubtable (ParentTable, Subtable);
871 DtPushSubtable (Subtable);
872
873 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
874
875 switch (NfitHeader->Type)
876 {
877 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
878
879 InfoTable = AcpiDmTableInfoNfit0;
880 break;
881
882 case ACPI_NFIT_TYPE_MEMORY_MAP:
883
884 InfoTable = AcpiDmTableInfoNfit1;
885 break;
886
887 case ACPI_NFIT_TYPE_INTERLEAVE:
888
889 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
890 InfoTable = AcpiDmTableInfoNfit2;
891 break;
892
893 case ACPI_NFIT_TYPE_SMBIOS:
894
895 InfoTable = AcpiDmTableInfoNfit3;
896 break;
897
898 case ACPI_NFIT_TYPE_CONTROL_REGION:
899
900 InfoTable = AcpiDmTableInfoNfit4;
901 break;
902
903 case ACPI_NFIT_TYPE_DATA_REGION:
904
905 InfoTable = AcpiDmTableInfoNfit5;
906 break;
907
908 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
909
910 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
911 InfoTable = AcpiDmTableInfoNfit6;
912 break;
913
914 case ACPI_NFIT_TYPE_CAPABILITIES:
915
916 InfoTable = AcpiDmTableInfoNfit7;
917 break;
918
919 default:
920
921 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
922 return (AE_ERROR);
923 }
924
925 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
926 if (ACPI_FAILURE (Status))
927 {
928 return (Status);
929 }
930
931 ParentTable = DtPeekSubtable ();
932 DtInsertSubtable (ParentTable, Subtable);
933 DtPopSubtable ();
934
935 switch (NfitHeader->Type)
936 {
937 case ACPI_NFIT_TYPE_INTERLEAVE:
938
939 Count = 0;
940 DtPushSubtable (Subtable);
941 while (*PFieldList)
942 {
943 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
944 &Subtable);
945 if (ACPI_FAILURE (Status))
946 {
947 return (Status);
948 }
949
950 if (!Subtable)
951 {
952 DtPopSubtable ();
953 break;
954 }
955
956 ParentTable = DtPeekSubtable ();
957 DtInsertSubtable (ParentTable, Subtable);
958 Count++;
959 }
960
961 Interleave->LineCount = Count;
962 break;
963
964 case ACPI_NFIT_TYPE_SMBIOS:
965
966 if (*PFieldList)
967 {
968 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
969 &Subtable);
970 if (ACPI_FAILURE (Status))
971 {
972 return (Status);
973 }
974
975 if (Subtable)
976 {
977 DtInsertSubtable (ParentTable, Subtable);
978 }
979 }
980 break;
981
982 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
983
984 Count = 0;
985 DtPushSubtable (Subtable);
986 while (*PFieldList)
987 {
988 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
989 &Subtable);
990 if (ACPI_FAILURE (Status))
991 {
992 return (Status);
993 }
994
995 if (!Subtable)
996 {
997 DtPopSubtable ();
998 break;
999 }
1000
1001 ParentTable = DtPeekSubtable ();
1002 DtInsertSubtable (ParentTable, Subtable);
1003 Count++;
1004 }
1005
1006 Hint->HintCount = (UINT16) Count;
1007 break;
1008
1009 default:
1010 break;
1011 }
1012 }
1013
1014 return (AE_OK);
1015 }
1016
1017
1018 /******************************************************************************
1019 *
1020 * FUNCTION: DtCompilePcct
1021 *
1022 * PARAMETERS: List - Current field list pointer
1023 *
1024 * RETURN: Status
1025 *
1026 * DESCRIPTION: Compile PCCT.
1027 *
1028 *****************************************************************************/
1029
1030 ACPI_STATUS
DtCompilePcct(void ** List)1031 DtCompilePcct (
1032 void **List)
1033 {
1034 ACPI_STATUS Status;
1035 DT_SUBTABLE *Subtable;
1036 DT_SUBTABLE *ParentTable;
1037 DT_FIELD **PFieldList = (DT_FIELD **) List;
1038 DT_FIELD *SubtableStart;
1039 ACPI_SUBTABLE_HEADER *PcctHeader;
1040 ACPI_DMTABLE_INFO *InfoTable;
1041
1042
1043 /* Main table */
1044
1045 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1046 &Subtable);
1047 if (ACPI_FAILURE (Status))
1048 {
1049 return (Status);
1050 }
1051
1052 ParentTable = DtPeekSubtable ();
1053 DtInsertSubtable (ParentTable, Subtable);
1054
1055 /* Subtables */
1056
1057 while (*PFieldList)
1058 {
1059 SubtableStart = *PFieldList;
1060 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1061 &Subtable);
1062 if (ACPI_FAILURE (Status))
1063 {
1064 return (Status);
1065 }
1066
1067 ParentTable = DtPeekSubtable ();
1068 DtInsertSubtable (ParentTable, Subtable);
1069 DtPushSubtable (Subtable);
1070
1071 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1072
1073 switch (PcctHeader->Type)
1074 {
1075 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1076
1077 InfoTable = AcpiDmTableInfoPcct0;
1078 break;
1079
1080 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1081
1082 InfoTable = AcpiDmTableInfoPcct1;
1083 break;
1084
1085 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
1086
1087 InfoTable = AcpiDmTableInfoPcct2;
1088 break;
1089
1090 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
1091
1092 InfoTable = AcpiDmTableInfoPcct3;
1093 break;
1094
1095 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
1096
1097 InfoTable = AcpiDmTableInfoPcct4;
1098 break;
1099
1100 case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
1101
1102 InfoTable = AcpiDmTableInfoPcct5;
1103 break;
1104
1105 default:
1106
1107 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1108 return (AE_ERROR);
1109 }
1110
1111 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1112 if (ACPI_FAILURE (Status))
1113 {
1114 return (Status);
1115 }
1116
1117 ParentTable = DtPeekSubtable ();
1118 DtInsertSubtable (ParentTable, Subtable);
1119 DtPopSubtable ();
1120 }
1121
1122 return (AE_OK);
1123 }
1124
1125
1126 /******************************************************************************
1127 *
1128 * FUNCTION: DtCompilePdtt
1129 *
1130 * PARAMETERS: List - Current field list pointer
1131 *
1132 * RETURN: Status
1133 *
1134 * DESCRIPTION: Compile PDTT.
1135 *
1136 *****************************************************************************/
1137
1138 ACPI_STATUS
DtCompilePdtt(void ** List)1139 DtCompilePdtt (
1140 void **List)
1141 {
1142 ACPI_STATUS Status;
1143 DT_SUBTABLE *Subtable;
1144 DT_SUBTABLE *ParentTable;
1145 DT_FIELD **PFieldList = (DT_FIELD **) List;
1146 ACPI_TABLE_PDTT *PdttHeader;
1147 UINT32 Count = 0;
1148
1149
1150 /* Main table */
1151
1152 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
1153 if (ACPI_FAILURE (Status))
1154 {
1155 return (Status);
1156 }
1157
1158 ParentTable = DtPeekSubtable ();
1159 DtInsertSubtable (ParentTable, Subtable);
1160
1161 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
1162 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
1163
1164 /* There is only one type of subtable at this time, no need to decode */
1165
1166 while (*PFieldList)
1167 {
1168 /* List of subchannel IDs, each 2 bytes */
1169
1170 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
1171 &Subtable);
1172 if (ACPI_FAILURE (Status))
1173 {
1174 return (Status);
1175 }
1176
1177 DtInsertSubtable (ParentTable, Subtable);
1178 Count++;
1179 }
1180
1181 PdttHeader->TriggerCount = (UINT8) Count;
1182 return (AE_OK);
1183 }
1184
1185
1186 /******************************************************************************
1187 *
1188 * FUNCTION: DtCompilePhat
1189 *
1190 * PARAMETERS: List - Current field list pointer
1191 *
1192 * RETURN: Status
1193 *
1194 * DESCRIPTION: Compile Phat.
1195 *
1196 *****************************************************************************/
1197
1198 ACPI_STATUS
DtCompilePhat(void ** List)1199 DtCompilePhat (
1200 void **List)
1201 {
1202 ACPI_STATUS Status = AE_OK;
1203 DT_SUBTABLE *Subtable;
1204 DT_SUBTABLE *ParentTable;
1205 DT_FIELD **PFieldList = (DT_FIELD **) List;
1206 ACPI_PHAT_HEADER *PhatHeader;
1207 ACPI_DMTABLE_INFO *Info;
1208 ACPI_PHAT_VERSION_DATA *VersionData;
1209 UINT32 DeviceDataLength;
1210 UINT32 RecordCount;
1211 DT_FIELD *DataOffsetField;
1212 DT_FIELD *DevicePathField;
1213 UINT32 TableOffset = 0;
1214 UINT32 DataOffsetValue;
1215 UINT32 i;
1216
1217
1218 /* The table consists of subtables */
1219
1220 while (*PFieldList)
1221 {
1222 /* Compile the common subtable header */
1223
1224 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
1225 if (ACPI_FAILURE (Status))
1226 {
1227 return (Status);
1228 }
1229
1230 TableOffset += Subtable->Length;
1231 DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length);
1232
1233 ParentTable = DtPeekSubtable ();
1234 DtInsertSubtable (ParentTable, Subtable);
1235 DtPushSubtable (Subtable);
1236
1237 PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
1238
1239 switch (PhatHeader->Type)
1240 {
1241 case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1242
1243 /* Compile the middle portion of the Firmware Version Data */
1244
1245 Info = AcpiDmTableInfoPhat0;
1246 PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
1247 DataOffsetField = NULL;
1248 break;
1249
1250 case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1251
1252 DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n",
1253 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length);
1254
1255 DataOffsetField = *PFieldList;
1256
1257 /* Walk the field list to get to the "Device-specific data Offset" field */
1258
1259 TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA);
1260 for (i = 0; i < 3; i++)
1261 {
1262 DataOffsetField = DataOffsetField->Next;
1263 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n",
1264 TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
1265 }
1266
1267 /* Convert DataOffsetField->Value (a char * string) to an integer value */
1268
1269 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
1270
1271 /*
1272 * Get the next field (Device Path):
1273 * DataOffsetField points to "Device-Specific Offset", next field is
1274 * "Device Path".
1275 */
1276 DevicePathField = DataOffsetField->Next;
1277
1278 /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */
1279
1280 DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2;
1281 TableOffset += DevicePathField->StringLength;
1282
1283 DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n",
1284 TableOffset, Subtable->Length, DevicePathField->StringLength);
1285
1286 /* Set the DataOffsetField to the current TableOffset */
1287 /* Must set the DataOffsetField here (not later) */
1288
1289 if (DataOffsetValue != 0)
1290 {
1291 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset);
1292 }
1293
1294 DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length);
1295
1296 DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: "
1297 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n",
1298 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength,
1299 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset);
1300
1301 /* Compile the middle portion of the Health Data Record */
1302
1303 Info = AcpiDmTableInfoPhat1;
1304 PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
1305 break;
1306
1307 default:
1308
1309 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1310 return (AE_ERROR);
1311 }
1312
1313 /* Compile either the Version Data or the Health Data */
1314
1315 Status = DtCompileTable (PFieldList, Info, &Subtable);
1316 if (ACPI_FAILURE (Status))
1317 {
1318 return (Status);
1319 }
1320
1321 DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n",
1322 TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length);
1323
1324 ParentTable = DtPeekSubtable ();
1325 DtInsertSubtable (ParentTable, Subtable);
1326
1327 switch (PhatHeader->Type)
1328 {
1329 case ACPI_PHAT_TYPE_FW_VERSION_DATA:
1330
1331 VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
1332 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
1333 RecordCount = VersionData->ElementCount;
1334
1335 /* Compile all of the Version Elements */
1336
1337 while (RecordCount)
1338 {
1339 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
1340 &Subtable);
1341 if (ACPI_FAILURE (Status))
1342 {
1343 return (Status);
1344 }
1345
1346 ParentTable = DtPeekSubtable ();
1347 DtInsertSubtable (ParentTable, Subtable);
1348
1349 TableOffset += Subtable->Length;
1350 RecordCount--;
1351 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
1352 }
1353
1354 DtPopSubtable ();
1355 break;
1356
1357 case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
1358
1359 /* Compile the Device Path */
1360
1361 DeviceDataLength = Subtable->Length;
1362 TableOffset += Subtable->Length;
1363
1364 DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: "
1365 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength,
1366 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value,
1367 Subtable->Length, TableOffset);
1368
1369 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
1370 if (ACPI_FAILURE (Status))
1371 {
1372 return (Status);
1373 }
1374 ParentTable = DtPeekSubtable ();
1375 DtInsertSubtable (ParentTable, Subtable);
1376
1377 /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */
1378
1379 if (!*PFieldList)
1380 {
1381 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n");
1382 return (AE_OK);
1383 }
1384
1385 DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s"
1386 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n",
1387 DeviceDataLength, (*PFieldList)->Name, TableOffset,
1388 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length);
1389
1390 PhatHeader->Length += (UINT16) Subtable->Length;
1391
1392 /* Convert DataOffsetField->Value (a hex char * string) to an integer value */
1393
1394 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
1395
1396 DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n",
1397 DataOffsetValue, TableOffset);
1398 if (DataOffsetValue != 0)
1399 {
1400 /* Compile Device-Specific Data - only if the Data Offset is non-zero */
1401
1402 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
1403 if (ACPI_FAILURE (Status))
1404 {
1405 return (Status);
1406 }
1407
1408 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n",
1409 Subtable, TableOffset);
1410 if (Subtable)
1411 {
1412 DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: "
1413 "%X FieldName \"%s\" SubtableLength %X\n",
1414 DeviceDataLength, DataOffsetField->Name, Subtable->Length);
1415
1416 DeviceDataLength += Subtable->Length;
1417
1418 ParentTable = DtPeekSubtable ();
1419 DtInsertSubtable (ParentTable, Subtable);
1420
1421 PhatHeader->Length += (UINT16) Subtable->Length;
1422 }
1423 }
1424
1425 DtPopSubtable ();
1426
1427 DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n",
1428 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
1429 break;
1430
1431 default:
1432
1433 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
1434 return (AE_ERROR);
1435 }
1436 }
1437
1438 return (Status);
1439 }
1440
1441
1442 /******************************************************************************
1443 *
1444 * FUNCTION: DtCompilePmtt
1445 *
1446 * PARAMETERS: List - Current field list pointer
1447 *
1448 * RETURN: Status
1449 *
1450 * DESCRIPTION: Compile PMTT.
1451 *
1452 *****************************************************************************/
1453
1454 ACPI_STATUS
DtCompilePmtt(void ** List)1455 DtCompilePmtt (
1456 void **List)
1457 {
1458 ACPI_STATUS Status;
1459 DT_SUBTABLE *Subtable;
1460 DT_SUBTABLE *ParentTable;
1461 DT_FIELD **PFieldList = (DT_FIELD **) List;
1462 DT_FIELD *SubtableStart;
1463 UINT16 Type;
1464
1465
1466 /* Main table */
1467
1468 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
1469 if (ACPI_FAILURE (Status))
1470 {
1471 return (Status);
1472 }
1473
1474 ParentTable = DtPeekSubtable ();
1475 DtInsertSubtable (ParentTable, Subtable);
1476 DtPushSubtable (Subtable);
1477
1478 /* Subtables */
1479
1480 while (*PFieldList)
1481 {
1482 SubtableStart = *PFieldList;
1483 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1484
1485 switch (Type)
1486 {
1487 case ACPI_PMTT_TYPE_SOCKET:
1488
1489 /* Subtable: Socket Structure */
1490
1491 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
1492
1493 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
1494 &Subtable);
1495 if (ACPI_FAILURE (Status))
1496 {
1497 return (Status);
1498 }
1499
1500 break;
1501
1502 case ACPI_PMTT_TYPE_CONTROLLER:
1503
1504 /* Subtable: Memory Controller Structure */
1505
1506 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
1507
1508 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
1509 &Subtable);
1510 if (ACPI_FAILURE (Status))
1511 {
1512 return (Status);
1513 }
1514
1515 break;
1516
1517 case ACPI_PMTT_TYPE_DIMM:
1518
1519 /* Subtable: Physical Component (DIMM) Structure */
1520
1521 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
1522 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
1523 &Subtable);
1524 if (ACPI_FAILURE (Status))
1525 {
1526 return (Status);
1527 }
1528
1529 break;
1530
1531 case ACPI_PMTT_TYPE_VENDOR:
1532
1533 /* Subtable: Vendor-specific Structure */
1534
1535 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
1536 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
1537 &Subtable);
1538 if (ACPI_FAILURE (Status))
1539 {
1540 return (Status);
1541 }
1542
1543 break;
1544
1545 default:
1546
1547 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
1548 return (AE_ERROR);
1549 }
1550
1551 DtInsertSubtable (ParentTable, Subtable);
1552 }
1553
1554 return (Status);
1555 }
1556
1557
1558 /******************************************************************************
1559 *
1560 * FUNCTION: DtCompilePptt
1561 *
1562 * PARAMETERS: List - Current field list pointer
1563 *
1564 * RETURN: Status
1565 *
1566 * DESCRIPTION: Compile PPTT.
1567 *
1568 *****************************************************************************/
1569
1570 ACPI_STATUS
DtCompilePptt(void ** List)1571 DtCompilePptt (
1572 void **List)
1573 {
1574 ACPI_STATUS Status;
1575 ACPI_SUBTABLE_HEADER *PpttHeader;
1576 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL;
1577 DT_SUBTABLE *Subtable;
1578 DT_SUBTABLE *ParentTable;
1579 ACPI_DMTABLE_INFO *InfoTable;
1580 DT_FIELD **PFieldList = (DT_FIELD **) List;
1581 DT_FIELD *SubtableStart;
1582 ACPI_TABLE_HEADER *PpttAcpiHeader;
1583
1584
1585 ParentTable = DtPeekSubtable ();
1586 while (*PFieldList)
1587 {
1588 SubtableStart = *PFieldList;
1589
1590 /* Compile PPTT subtable header */
1591
1592 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
1593 &Subtable);
1594 if (ACPI_FAILURE (Status))
1595 {
1596 return (Status);
1597 }
1598 DtInsertSubtable (ParentTable, Subtable);
1599 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1600 PpttHeader->Length = (UINT8)(Subtable->Length);
1601
1602 switch (PpttHeader->Type)
1603 {
1604 case ACPI_PPTT_TYPE_PROCESSOR:
1605
1606 InfoTable = AcpiDmTableInfoPptt0;
1607 break;
1608
1609 case ACPI_PPTT_TYPE_CACHE:
1610
1611 InfoTable = AcpiDmTableInfoPptt1;
1612 break;
1613
1614 case ACPI_PPTT_TYPE_ID:
1615
1616 InfoTable = AcpiDmTableInfoPptt2;
1617 break;
1618
1619 default:
1620
1621 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
1622 return (AE_ERROR);
1623 }
1624
1625 /* Compile PPTT subtable body */
1626
1627 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1628 if (ACPI_FAILURE (Status))
1629 {
1630 return (Status);
1631 }
1632 DtInsertSubtable (ParentTable, Subtable);
1633 PpttHeader->Length += (UINT8)(Subtable->Length);
1634
1635 /* Compile PPTT subtable additional */
1636
1637 switch (PpttHeader->Type)
1638 {
1639 case ACPI_PPTT_TYPE_PROCESSOR:
1640
1641 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
1642 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
1643 if (PpttProcessor)
1644 {
1645 /* Compile initiator proximity domain list */
1646
1647 PpttProcessor->NumberOfPrivResources = 0;
1648 while (*PFieldList)
1649 {
1650 Status = DtCompileTable (PFieldList,
1651 AcpiDmTableInfoPptt0a, &Subtable);
1652 if (ACPI_FAILURE (Status))
1653 {
1654 return (Status);
1655 }
1656 if (!Subtable)
1657 {
1658 break;
1659 }
1660
1661 DtInsertSubtable (ParentTable, Subtable);
1662 PpttHeader->Length += (UINT8)(Subtable->Length);
1663 PpttProcessor->NumberOfPrivResources++;
1664 }
1665 }
1666 break;
1667
1668 case ACPI_PPTT_TYPE_CACHE:
1669
1670 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
1671 AslGbl_RootTable->Buffer);
1672 if (PpttAcpiHeader->Revision < 3)
1673 {
1674 break;
1675 }
1676 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
1677 &Subtable);
1678 DtInsertSubtable (ParentTable, Subtable);
1679 PpttHeader->Length += (UINT8)(Subtable->Length);
1680 break;
1681
1682 default:
1683
1684 break;
1685 }
1686 }
1687
1688 return (AE_OK);
1689 }
1690
1691
1692 /******************************************************************************
1693 *
1694 * FUNCTION: DtCompilePrmt
1695 *
1696 * PARAMETERS: List - Current field list pointer
1697 *
1698 * RETURN: Status
1699 *
1700 * DESCRIPTION: Compile PRMT.
1701 *
1702 *****************************************************************************/
1703
1704 ACPI_STATUS
DtCompilePrmt(void ** List)1705 DtCompilePrmt (
1706 void **List)
1707 {
1708 ACPI_STATUS Status;
1709 ACPI_TABLE_PRMT_HEADER *PrmtHeader;
1710 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo;
1711 DT_SUBTABLE *Subtable;
1712 DT_SUBTABLE *ParentTable;
1713 DT_FIELD **PFieldList = (DT_FIELD **) List;
1714 UINT32 i, j;
1715
1716 ParentTable = DtPeekSubtable ();
1717
1718 /* Compile PRMT subtable header */
1719
1720 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
1721 &Subtable);
1722 if (ACPI_FAILURE (Status))
1723 {
1724 return (Status);
1725 }
1726 DtInsertSubtable (ParentTable, Subtable);
1727 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
1728
1729 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
1730 {
1731 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
1732 &Subtable);
1733 if (ACPI_FAILURE (Status))
1734 {
1735 return (Status);
1736 }
1737 DtInsertSubtable (ParentTable, Subtable);
1738 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
1739
1740 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
1741 {
1742 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
1743 &Subtable);
1744 if (ACPI_FAILURE (Status))
1745 {
1746 return (Status);
1747 }
1748 DtInsertSubtable (ParentTable, Subtable);
1749 }
1750 }
1751
1752 return (AE_OK);
1753 }
1754
1755
1756 /******************************************************************************
1757 *
1758 * FUNCTION: DtCompileRas2
1759 *
1760 * PARAMETERS: List - Current field list pointer
1761 *
1762 * RETURN: Status
1763 *
1764 * DESCRIPTION: Compile RAS2.
1765 *
1766 *****************************************************************************/
1767
1768 ACPI_STATUS
DtCompileRas2(void ** List)1769 DtCompileRas2 (
1770 void **List)
1771 {
1772 ACPI_STATUS Status;
1773 DT_SUBTABLE *Subtable;
1774 DT_SUBTABLE *ParentTable;
1775 DT_FIELD **PFieldList = (DT_FIELD **) List;
1776 ACPI_TABLE_RAS2 *Ras2Header;
1777 UINT32 Count = 0;
1778
1779
1780 /* Main table */
1781
1782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable);
1783 if (ACPI_FAILURE (Status))
1784 {
1785 return (Status);
1786 }
1787
1788 ParentTable = DtPeekSubtable ();
1789 DtInsertSubtable (ParentTable, Subtable);
1790
1791 Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer);
1792
1793 /* There is only one type of subtable at this time, no need to decode */
1794
1795 while (*PFieldList)
1796 {
1797 /* List of RAS2 PCC descriptors, each 8 bytes */
1798
1799 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc,
1800 &Subtable);
1801 if (ACPI_FAILURE (Status))
1802 {
1803 return (Status);
1804 }
1805
1806 DtInsertSubtable (ParentTable, Subtable);
1807 Count++;
1808 }
1809
1810 Ras2Header->NumPccDescs = (UINT8) Count;
1811 return (AE_OK);
1812 }
1813
1814
1815 /******************************************************************************
1816 *
1817 * FUNCTION: DtCompileRgrt
1818 *
1819 * PARAMETERS: List - Current field list pointer
1820 *
1821 * RETURN: Status
1822 *
1823 * DESCRIPTION: Compile RGRT.
1824 *
1825 *****************************************************************************/
1826
1827 ACPI_STATUS
DtCompileRgrt(void ** List)1828 DtCompileRgrt (
1829 void **List)
1830 {
1831 ACPI_STATUS Status;
1832 DT_SUBTABLE *Subtable;
1833 DT_SUBTABLE *ParentTable;
1834 DT_FIELD **PFieldList = (DT_FIELD **) List;
1835
1836
1837 /* Compile the main table */
1838
1839 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
1840 &Subtable);
1841 if (ACPI_FAILURE (Status))
1842 {
1843 return (Status);
1844 }
1845
1846 ParentTable = DtPeekSubtable ();
1847 DtInsertSubtable (ParentTable, Subtable);
1848
1849 /* Compile the "Subtable" -- actually just the binary (PNG) image */
1850
1851 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
1852 &Subtable);
1853 if (ACPI_FAILURE (Status))
1854 {
1855 return (Status);
1856 }
1857
1858 DtInsertSubtable (ParentTable, Subtable);
1859 return (AE_OK);
1860 }
1861
1862
1863 /******************************************************************************
1864 *
1865 * FUNCTION: DtCompileRhct
1866 *
1867 * PARAMETERS: List - Current field list pointer
1868 *
1869 * RETURN: Status
1870 *
1871 * DESCRIPTION: Compile RHCT.
1872 *
1873 *****************************************************************************/
1874
1875 ACPI_STATUS
DtCompileRhct(void ** List)1876 DtCompileRhct (
1877 void **List)
1878 {
1879 ACPI_STATUS Status;
1880 ACPI_RHCT_NODE_HEADER *RhctHeader;
1881 ACPI_RHCT_HART_INFO *RhctHartInfo = NULL;
1882 DT_SUBTABLE *Subtable;
1883 DT_SUBTABLE *ParentTable;
1884 ACPI_DMTABLE_INFO *InfoTable;
1885 DT_FIELD **PFieldList = (DT_FIELD **) List;
1886 DT_FIELD *SubtableStart;
1887
1888
1889 /* Compile the main table */
1890
1891 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct,
1892 &Subtable);
1893 if (ACPI_FAILURE (Status))
1894 {
1895 return (Status);
1896 }
1897
1898 ParentTable = DtPeekSubtable ();
1899 while (*PFieldList)
1900 {
1901 SubtableStart = *PFieldList;
1902
1903 /* Compile RHCT subtable header */
1904
1905 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr,
1906 &Subtable);
1907 if (ACPI_FAILURE (Status))
1908 {
1909 return (Status);
1910 }
1911 DtInsertSubtable (ParentTable, Subtable);
1912 RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer);
1913 RhctHeader->Length = (UINT16)(Subtable->Length);
1914
1915 switch (RhctHeader->Type)
1916 {
1917 case ACPI_RHCT_NODE_TYPE_ISA_STRING:
1918
1919 InfoTable = AcpiDmTableInfoRhctIsa1;
1920 break;
1921
1922 case ACPI_RHCT_NODE_TYPE_HART_INFO:
1923
1924 InfoTable = AcpiDmTableInfoRhctHartInfo1;
1925 break;
1926
1927 case ACPI_RHCT_NODE_TYPE_CMO:
1928
1929 InfoTable = AcpiDmTableInfoRhctCmo1;
1930 break;
1931
1932 case ACPI_RHCT_NODE_TYPE_MMU:
1933
1934 InfoTable = AcpiDmTableInfoRhctMmu1;
1935 break;
1936
1937 default:
1938
1939 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT");
1940 return (AE_ERROR);
1941 }
1942
1943 /* Compile RHCT subtable body */
1944
1945 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1946 if (ACPI_FAILURE (Status))
1947 {
1948 return (Status);
1949 }
1950 DtInsertSubtable (ParentTable, Subtable);
1951 RhctHeader->Length += (UINT16)(Subtable->Length);
1952
1953 /* Compile RHCT subtable additionals */
1954
1955 switch (RhctHeader->Type)
1956 {
1957 case ACPI_RHCT_NODE_TYPE_HART_INFO:
1958
1959 RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO,
1960 Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER));
1961 if (RhctHartInfo)
1962 {
1963
1964 RhctHartInfo->NumOffsets = 0;
1965 while (*PFieldList)
1966 {
1967 Status = DtCompileTable (PFieldList,
1968 AcpiDmTableInfoRhctHartInfo2, &Subtable);
1969 if (ACPI_FAILURE (Status))
1970 {
1971 return (Status);
1972 }
1973 if (!Subtable)
1974 {
1975 break;
1976 }
1977
1978 DtInsertSubtable (ParentTable, Subtable);
1979 RhctHeader->Length += (UINT16)(Subtable->Length);
1980 RhctHartInfo->NumOffsets++;
1981 }
1982 }
1983 break;
1984
1985 default:
1986
1987 break;
1988 }
1989 }
1990
1991 return (AE_OK);
1992 }
1993
1994
1995 /******************************************************************************
1996 *
1997 * FUNCTION: DtCompileRsdt
1998 *
1999 * PARAMETERS: List - Current field list pointer
2000 *
2001 * RETURN: Status
2002 *
2003 * DESCRIPTION: Compile RSDT.
2004 *
2005 *****************************************************************************/
2006
2007 ACPI_STATUS
DtCompileRsdt(void ** List)2008 DtCompileRsdt (
2009 void **List)
2010 {
2011 DT_SUBTABLE *Subtable;
2012 DT_SUBTABLE *ParentTable;
2013 DT_FIELD *FieldList = *(DT_FIELD **) List;
2014 UINT32 Address;
2015
2016
2017 ParentTable = DtPeekSubtable ();
2018
2019 while (FieldList)
2020 {
2021 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2022
2023 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2024 DtInsertSubtable (ParentTable, Subtable);
2025 FieldList = FieldList->Next;
2026 }
2027
2028 return (AE_OK);
2029 }
2030
2031
2032 /******************************************************************************
2033 *
2034 * FUNCTION: DtCompileS3pt
2035 *
2036 * PARAMETERS: PFieldList - Current field list pointer
2037 *
2038 * RETURN: Status
2039 *
2040 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2041 *
2042 *****************************************************************************/
2043
2044 ACPI_STATUS
DtCompileS3pt(DT_FIELD ** PFieldList)2045 DtCompileS3pt (
2046 DT_FIELD **PFieldList)
2047 {
2048 ACPI_STATUS Status;
2049 ACPI_FPDT_HEADER *S3ptHeader;
2050 DT_SUBTABLE *Subtable;
2051 DT_SUBTABLE *ParentTable;
2052 ACPI_DMTABLE_INFO *InfoTable;
2053 DT_FIELD *SubtableStart;
2054
2055
2056 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2057 &AslGbl_RootTable);
2058 if (ACPI_FAILURE (Status))
2059 {
2060 return (Status);
2061 }
2062
2063 DtPushSubtable (AslGbl_RootTable);
2064
2065 while (*PFieldList)
2066 {
2067 SubtableStart = *PFieldList;
2068 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2069 &Subtable);
2070 if (ACPI_FAILURE (Status))
2071 {
2072 return (Status);
2073 }
2074
2075 ParentTable = DtPeekSubtable ();
2076 DtInsertSubtable (ParentTable, Subtable);
2077 DtPushSubtable (Subtable);
2078
2079 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
2080
2081 switch (S3ptHeader->Type)
2082 {
2083 case ACPI_S3PT_TYPE_RESUME:
2084
2085 InfoTable = AcpiDmTableInfoS3pt0;
2086 break;
2087
2088 case ACPI_S3PT_TYPE_SUSPEND:
2089
2090 InfoTable = AcpiDmTableInfoS3pt1;
2091 break;
2092
2093 default:
2094
2095 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2096 return (AE_ERROR);
2097 }
2098
2099 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2100 if (ACPI_FAILURE (Status))
2101 {
2102 return (Status);
2103 }
2104
2105 ParentTable = DtPeekSubtable ();
2106 DtInsertSubtable (ParentTable, Subtable);
2107 DtPopSubtable ();
2108 }
2109
2110 return (AE_OK);
2111 }
2112
2113
2114 /******************************************************************************
2115 *
2116 * FUNCTION: DtCompileSdev
2117 *
2118 * PARAMETERS: List - Current field list pointer
2119 *
2120 * RETURN: Status
2121 *
2122 * DESCRIPTION: Compile SDEV.
2123 *
2124 *****************************************************************************/
2125
2126 ACPI_STATUS
DtCompileSdev(void ** List)2127 DtCompileSdev (
2128 void **List)
2129 {
2130 ACPI_STATUS Status;
2131 ACPI_SDEV_HEADER *SdevHeader;
2132 ACPI_SDEV_HEADER *SecureComponentHeader;
2133 DT_SUBTABLE *Subtable;
2134 DT_SUBTABLE *ParentTable;
2135 ACPI_DMTABLE_INFO *InfoTable;
2136 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL;
2137 DT_FIELD **PFieldList = (DT_FIELD **) List;
2138 DT_FIELD *SubtableStart;
2139 ACPI_SDEV_PCIE *Pcie = NULL;
2140 ACPI_SDEV_NAMESPACE *Namesp = NULL;
2141 UINT32 EntryCount;
2142 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL;
2143 UINT16 ComponentLength = 0;
2144
2145
2146 /* Subtables */
2147
2148 while (*PFieldList)
2149 {
2150 /* Compile common SDEV subtable header */
2151
2152 SubtableStart = *PFieldList;
2153 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
2154 &Subtable);
2155 if (ACPI_FAILURE (Status))
2156 {
2157 return (Status);
2158 }
2159
2160 ParentTable = DtPeekSubtable ();
2161 DtInsertSubtable (ParentTable, Subtable);
2162 DtPushSubtable (Subtable);
2163
2164 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2165 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
2166
2167 switch (SdevHeader->Type)
2168 {
2169 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2170
2171 InfoTable = AcpiDmTableInfoSdev0;
2172 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
2173 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2174 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
2175 break;
2176
2177 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2178
2179 InfoTable = AcpiDmTableInfoSdev1;
2180 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
2181 break;
2182
2183 default:
2184
2185 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2186 return (AE_ERROR);
2187 }
2188
2189 /* Compile SDEV subtable body */
2190
2191 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2192 if (ACPI_FAILURE (Status))
2193 {
2194 return (Status);
2195 }
2196
2197 ParentTable = DtPeekSubtable ();
2198 DtInsertSubtable (ParentTable, Subtable);
2199
2200 /* Optional data fields are appended to the main subtable body */
2201
2202 switch (SdevHeader->Type)
2203 {
2204 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2205
2206 /*
2207 * Device Id Offset will be be calculated differently depending on
2208 * the presence of secure access components.
2209 */
2210 Namesp->DeviceIdOffset = 0;
2211 ComponentLength = 0;
2212
2213 /* If the secure access component exists, get the structures */
2214
2215 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2216 {
2217 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
2218 &Subtable);
2219 if (ACPI_FAILURE (Status))
2220 {
2221 return (Status);
2222 }
2223 ParentTable = DtPeekSubtable ();
2224 DtInsertSubtable (ParentTable, Subtable);
2225
2226 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2227
2228 /* Compile a secure access component header */
2229
2230 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
2231 &Subtable);
2232 if (ACPI_FAILURE (Status))
2233 {
2234 return (Status);
2235 }
2236 ParentTable = DtPeekSubtable ();
2237 DtInsertSubtable (ParentTable, Subtable);
2238
2239 /* Compile the secure access component */
2240
2241 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
2242 switch (SecureComponentHeader->Type)
2243 {
2244 case ACPI_SDEV_TYPE_ID_COMPONENT:
2245
2246 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2247 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
2248 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
2249 break;
2250
2251 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2252
2253 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2254 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
2255 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
2256 break;
2257
2258 default:
2259
2260 /* Any other secure component types are undefined */
2261
2262 return (AE_ERROR);
2263 }
2264
2265 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
2266 &Subtable);
2267 if (ACPI_FAILURE (Status))
2268 {
2269 return (Status);
2270 }
2271 ParentTable = DtPeekSubtable ();
2272 DtInsertSubtable (ParentTable, Subtable);
2273
2274 SecureComponent->SecureComponentOffset =
2275 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
2276 SecureComponent->SecureComponentLength = ComponentLength;
2277
2278
2279 /*
2280 * Add the secure component to the subtable to be added for the
2281 * the namespace subtable's length
2282 */
2283 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2284 }
2285
2286 /* Append DeviceId namespace string */
2287
2288 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
2289 &Subtable);
2290 if (ACPI_FAILURE (Status))
2291 {
2292 return (Status);
2293 }
2294
2295 if (!Subtable)
2296 {
2297 break;
2298 }
2299
2300 ParentTable = DtPeekSubtable ();
2301 DtInsertSubtable (ParentTable, Subtable);
2302
2303 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
2304
2305 Namesp->DeviceIdLength = (UINT16) Subtable->Length;
2306
2307 /* Append Vendor data */
2308
2309 Namesp->VendorDataLength = 0;
2310 Namesp->VendorDataOffset = 0;
2311
2312 if (*PFieldList)
2313 {
2314 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2315 &Subtable);
2316 if (ACPI_FAILURE (Status))
2317 {
2318 return (Status);
2319 }
2320
2321 if (Subtable)
2322 {
2323 ParentTable = DtPeekSubtable ();
2324 DtInsertSubtable (ParentTable, Subtable);
2325
2326 Namesp->VendorDataOffset =
2327 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2328 Namesp->VendorDataLength =
2329 (UINT16) Subtable->Length;
2330
2331 /* Final size of entire namespace structure */
2332
2333 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
2334 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
2335 }
2336 }
2337
2338 break;
2339
2340 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2341
2342 /* Append the PCIe path info first */
2343
2344 EntryCount = 0;
2345 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
2346 {
2347 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
2348 &Subtable);
2349 if (ACPI_FAILURE (Status))
2350 {
2351 return (Status);
2352 }
2353
2354 if (!Subtable)
2355 {
2356 DtPopSubtable ();
2357 break;
2358 }
2359
2360 ParentTable = DtPeekSubtable ();
2361 DtInsertSubtable (ParentTable, Subtable);
2362 EntryCount++;
2363 }
2364
2365 /* Path offset will point immediately after the main subtable */
2366
2367 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
2368 Pcie->PathLength = (UINT16)
2369 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
2370
2371 /* Append the Vendor Data last */
2372
2373 Pcie->VendorDataLength = 0;
2374 Pcie->VendorDataOffset = 0;
2375
2376 if (*PFieldList)
2377 {
2378 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
2379 &Subtable);
2380 if (ACPI_FAILURE (Status))
2381 {
2382 return (Status);
2383 }
2384
2385 if (Subtable)
2386 {
2387 ParentTable = DtPeekSubtable ();
2388 DtInsertSubtable (ParentTable, Subtable);
2389
2390 Pcie->VendorDataOffset =
2391 Pcie->PathOffset + Pcie->PathLength;
2392 Pcie->VendorDataLength = (UINT16)
2393 Subtable->Length;
2394 }
2395 }
2396
2397 SdevHeader->Length =
2398 sizeof (ACPI_SDEV_PCIE) +
2399 Pcie->PathLength + Pcie->VendorDataLength;
2400 break;
2401
2402 default:
2403
2404 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
2405 return (AE_ERROR);
2406 }
2407
2408 DtPopSubtable ();
2409 }
2410
2411 return (AE_OK);
2412 }
2413
2414
2415 /******************************************************************************
2416 *
2417 * FUNCTION: DtCompileSlic
2418 *
2419 * PARAMETERS: List - Current field list pointer
2420 *
2421 * RETURN: Status
2422 *
2423 * DESCRIPTION: Compile SLIC.
2424 *
2425 *****************************************************************************/
2426
2427 ACPI_STATUS
DtCompileSlic(void ** List)2428 DtCompileSlic (
2429 void **List)
2430 {
2431 ACPI_STATUS Status;
2432 DT_SUBTABLE *Subtable;
2433 DT_SUBTABLE *ParentTable;
2434 DT_FIELD **PFieldList = (DT_FIELD **) List;
2435
2436
2437 while (*PFieldList)
2438 {
2439 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2440 &Subtable);
2441 if (ACPI_FAILURE (Status))
2442 {
2443 return (Status);
2444 }
2445
2446 ParentTable = DtPeekSubtable ();
2447 DtInsertSubtable (ParentTable, Subtable);
2448 DtPushSubtable (Subtable);
2449 DtPopSubtable ();
2450 }
2451
2452 return (AE_OK);
2453 }
2454
2455
2456 /******************************************************************************
2457 *
2458 * FUNCTION: DtCompileSlit
2459 *
2460 * PARAMETERS: List - Current field list pointer
2461 *
2462 * RETURN: Status
2463 *
2464 * DESCRIPTION: Compile SLIT.
2465 *
2466 *****************************************************************************/
2467
2468 ACPI_STATUS
DtCompileSlit(void ** List)2469 DtCompileSlit (
2470 void **List)
2471 {
2472 ACPI_STATUS Status;
2473 DT_SUBTABLE *Subtable;
2474 DT_SUBTABLE *ParentTable;
2475 DT_FIELD **PFieldList = (DT_FIELD **) List;
2476 DT_FIELD *FieldList;
2477 DT_FIELD *EndOfFieldList = NULL;
2478 UINT32 Localities;
2479 UINT32 LocalityListLength;
2480 UINT8 *LocalityBuffer;
2481
2482
2483 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2484 &Subtable);
2485 if (ACPI_FAILURE (Status))
2486 {
2487 return (Status);
2488 }
2489
2490 ParentTable = DtPeekSubtable ();
2491 DtInsertSubtable (ParentTable, Subtable);
2492
2493 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2494 LocalityBuffer = UtLocalCalloc (Localities);
2495 LocalityListLength = 0;
2496
2497 /* Compile each locality buffer */
2498
2499 FieldList = *PFieldList;
2500 while (FieldList)
2501 {
2502 DtCompileBuffer (LocalityBuffer,
2503 FieldList->Value, FieldList, Localities);
2504
2505 LocalityListLength++;
2506 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2507 DtInsertSubtable (ParentTable, Subtable);
2508 EndOfFieldList = FieldList;
2509 FieldList = FieldList->Next;
2510 }
2511
2512 if (LocalityListLength != Localities)
2513 {
2514 sprintf(AslGbl_MsgBuffer,
2515 "Found %u entries, must match LocalityCount: %u",
2516 LocalityListLength, Localities);
2517 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
2518 ACPI_FREE (LocalityBuffer);
2519 return (AE_LIMIT);
2520 }
2521
2522 ACPI_FREE (LocalityBuffer);
2523 return (AE_OK);
2524 }
2525
2526
2527 /******************************************************************************
2528 *
2529 * FUNCTION: DtCompileSrat
2530 *
2531 * PARAMETERS: List - Current field list pointer
2532 *
2533 * RETURN: Status
2534 *
2535 * DESCRIPTION: Compile SRAT.
2536 *
2537 *****************************************************************************/
2538
2539 ACPI_STATUS
DtCompileSrat(void ** List)2540 DtCompileSrat (
2541 void **List)
2542 {
2543 ACPI_STATUS Status;
2544 DT_SUBTABLE *Subtable;
2545 DT_SUBTABLE *ParentTable;
2546 DT_FIELD **PFieldList = (DT_FIELD **) List;
2547 DT_FIELD *SubtableStart;
2548 ACPI_SUBTABLE_HEADER *SratHeader;
2549 ACPI_DMTABLE_INFO *InfoTable;
2550
2551
2552 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2553 &Subtable);
2554 if (ACPI_FAILURE (Status))
2555 {
2556 return (Status);
2557 }
2558
2559 ParentTable = DtPeekSubtable ();
2560 DtInsertSubtable (ParentTable, Subtable);
2561
2562 while (*PFieldList)
2563 {
2564 SubtableStart = *PFieldList;
2565 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2566 &Subtable);
2567 if (ACPI_FAILURE (Status))
2568 {
2569 return (Status);
2570 }
2571
2572 ParentTable = DtPeekSubtable ();
2573 DtInsertSubtable (ParentTable, Subtable);
2574 DtPushSubtable (Subtable);
2575
2576 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2577
2578 switch (SratHeader->Type)
2579 {
2580 case ACPI_SRAT_TYPE_CPU_AFFINITY:
2581
2582 InfoTable = AcpiDmTableInfoSrat0;
2583 break;
2584
2585 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2586
2587 InfoTable = AcpiDmTableInfoSrat1;
2588 break;
2589
2590 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2591
2592 InfoTable = AcpiDmTableInfoSrat2;
2593 break;
2594
2595 case ACPI_SRAT_TYPE_GICC_AFFINITY:
2596
2597 InfoTable = AcpiDmTableInfoSrat3;
2598 break;
2599
2600 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
2601
2602 InfoTable = AcpiDmTableInfoSrat4;
2603 break;
2604
2605 case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
2606
2607 InfoTable = AcpiDmTableInfoSrat5;
2608 break;
2609
2610 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
2611
2612 InfoTable = AcpiDmTableInfoSrat6;
2613 break;
2614
2615 case ACPI_SRAT_TYPE_RINTC_AFFINITY:
2616
2617 InfoTable = AcpiDmTableInfoSrat7;
2618 break;
2619
2620 default:
2621
2622 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2623 return (AE_ERROR);
2624 }
2625
2626 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2627 if (ACPI_FAILURE (Status))
2628 {
2629 return (Status);
2630 }
2631
2632 ParentTable = DtPeekSubtable ();
2633 DtInsertSubtable (ParentTable, Subtable);
2634 DtPopSubtable ();
2635 }
2636
2637 return (AE_OK);
2638 }
2639
2640
2641 /******************************************************************************
2642 *
2643 * FUNCTION: DtCompileStao
2644 *
2645 * PARAMETERS: PFieldList - Current field list pointer
2646 *
2647 * RETURN: Status
2648 *
2649 * DESCRIPTION: Compile STAO.
2650 *
2651 *****************************************************************************/
2652
2653 ACPI_STATUS
DtCompileStao(void ** List)2654 DtCompileStao (
2655 void **List)
2656 {
2657 DT_FIELD **PFieldList = (DT_FIELD **) List;
2658 DT_SUBTABLE *Subtable;
2659 DT_SUBTABLE *ParentTable;
2660 ACPI_STATUS Status;
2661
2662
2663 /* Compile the main table */
2664
2665 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
2666 &Subtable);
2667 if (ACPI_FAILURE (Status))
2668 {
2669 return (Status);
2670 }
2671
2672 ParentTable = DtPeekSubtable ();
2673 DtInsertSubtable (ParentTable, Subtable);
2674
2675 /* Compile each ASCII namestring as a subtable */
2676
2677 while (*PFieldList)
2678 {
2679 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
2680 &Subtable);
2681 if (ACPI_FAILURE (Status))
2682 {
2683 return (Status);
2684 }
2685
2686 ParentTable = DtPeekSubtable ();
2687 DtInsertSubtable (ParentTable, Subtable);
2688 }
2689
2690 return (AE_OK);
2691 }
2692
2693
2694 /******************************************************************************
2695 *
2696 * FUNCTION: DtCompileSvkl
2697 *
2698 * PARAMETERS: PFieldList - Current field list pointer
2699 *
2700 * RETURN: Status
2701 *
2702 * DESCRIPTION: Compile SVKL.
2703 *
2704 * NOTES: SVKL is essentially a flat table, with a small main table and
2705 * a variable number of a single type of subtable.
2706 *
2707 *****************************************************************************/
2708
2709 ACPI_STATUS
DtCompileSvkl(void ** List)2710 DtCompileSvkl (
2711 void **List)
2712 {
2713 DT_FIELD **PFieldList = (DT_FIELD **) List;
2714 DT_SUBTABLE *Subtable;
2715 DT_SUBTABLE *ParentTable;
2716 ACPI_STATUS Status;
2717
2718
2719 /* Compile the main table */
2720
2721 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
2722 &Subtable);
2723 if (ACPI_FAILURE (Status))
2724 {
2725 return (Status);
2726 }
2727
2728 ParentTable = DtPeekSubtable ();
2729 DtInsertSubtable (ParentTable, Subtable);
2730
2731 /* Compile each subtable */
2732
2733 while (*PFieldList)
2734 {
2735 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
2736 &Subtable);
2737 if (ACPI_FAILURE (Status))
2738 {
2739 return (Status);
2740 }
2741
2742 ParentTable = DtPeekSubtable ();
2743 DtInsertSubtable (ParentTable, Subtable);
2744 }
2745
2746 return (AE_OK);
2747 }
2748
2749
2750 /******************************************************************************
2751 *
2752 * FUNCTION: DtCompileTcpa
2753 *
2754 * PARAMETERS: PFieldList - Current field list pointer
2755 *
2756 * RETURN: Status
2757 *
2758 * DESCRIPTION: Compile TCPA.
2759 *
2760 *****************************************************************************/
2761
2762 ACPI_STATUS
DtCompileTcpa(void ** List)2763 DtCompileTcpa (
2764 void **List)
2765 {
2766 DT_FIELD **PFieldList = (DT_FIELD **) List;
2767 DT_SUBTABLE *Subtable;
2768 ACPI_TABLE_TCPA_HDR *TcpaHeader;
2769 DT_SUBTABLE *ParentTable;
2770 ACPI_STATUS Status;
2771
2772
2773 /* Compile the main table */
2774
2775 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
2776 &Subtable);
2777 if (ACPI_FAILURE (Status))
2778 {
2779 return (Status);
2780 }
2781
2782 ParentTable = DtPeekSubtable ();
2783 DtInsertSubtable (ParentTable, Subtable);
2784
2785 /*
2786 * Examine the PlatformClass field to determine the table type.
2787 * Either a client or server table. Only one.
2788 */
2789 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
2790
2791 switch (TcpaHeader->PlatformClass)
2792 {
2793 case ACPI_TCPA_CLIENT_TABLE:
2794
2795 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
2796 &Subtable);
2797 break;
2798
2799 case ACPI_TCPA_SERVER_TABLE:
2800
2801 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
2802 &Subtable);
2803 break;
2804
2805 default:
2806
2807 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
2808 TcpaHeader->PlatformClass);
2809 Status = AE_ERROR;
2810 break;
2811 }
2812
2813 ParentTable = DtPeekSubtable ();
2814 DtInsertSubtable (ParentTable, Subtable);
2815 return (Status);
2816 }
2817
2818
2819 /******************************************************************************
2820 *
2821 * FUNCTION: DtCompileTpm2Rev3
2822 *
2823 * PARAMETERS: PFieldList - Current field list pointer
2824 *
2825 * RETURN: Status
2826 *
2827 * DESCRIPTION: Compile TPM2 revision 3
2828 *
2829 *****************************************************************************/
2830 static ACPI_STATUS
DtCompileTpm2Rev3(void ** List)2831 DtCompileTpm2Rev3 (
2832 void **List)
2833 {
2834 DT_FIELD **PFieldList = (DT_FIELD **) List;
2835 DT_SUBTABLE *Subtable;
2836 ACPI_TABLE_TPM23 *Tpm23Header;
2837 DT_SUBTABLE *ParentTable;
2838 ACPI_STATUS Status = AE_OK;
2839
2840
2841 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
2842 &Subtable);
2843
2844 ParentTable = DtPeekSubtable ();
2845 DtInsertSubtable (ParentTable, Subtable);
2846 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
2847
2848 /* Subtable type depends on the StartMethod */
2849
2850 switch (Tpm23Header->StartMethod)
2851 {
2852 case ACPI_TPM23_ACPI_START_METHOD:
2853
2854 /* Subtable specific to to ARM_SMC */
2855
2856 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
2857 &Subtable);
2858 if (ACPI_FAILURE (Status))
2859 {
2860 return (Status);
2861 }
2862
2863 ParentTable = DtPeekSubtable ();
2864 DtInsertSubtable (ParentTable, Subtable);
2865 break;
2866
2867 default:
2868 break;
2869 }
2870
2871 return (Status);
2872 }
2873
2874
2875 /******************************************************************************
2876 *
2877 * FUNCTION: DtCompileTpm2
2878 *
2879 * PARAMETERS: PFieldList - Current field list pointer
2880 *
2881 * RETURN: Status
2882 *
2883 * DESCRIPTION: Compile TPM2.
2884 *
2885 *****************************************************************************/
2886
2887 ACPI_STATUS
DtCompileTpm2(void ** List)2888 DtCompileTpm2 (
2889 void **List)
2890 {
2891 DT_FIELD **PFieldList = (DT_FIELD **) List;
2892 DT_SUBTABLE *Subtable;
2893 ACPI_TABLE_TPM2 *Tpm2Header;
2894 DT_SUBTABLE *ParentTable;
2895 ACPI_STATUS Status = AE_OK;
2896 ACPI_TABLE_HEADER *Header;
2897
2898
2899 ParentTable = DtPeekSubtable ();
2900
2901 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2902
2903 if (Header->Revision == 3)
2904 {
2905 return (DtCompileTpm2Rev3 (List));
2906 }
2907
2908 /* Compile the main table */
2909
2910 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
2911 &Subtable);
2912 if (ACPI_FAILURE (Status))
2913 {
2914 return (Status);
2915 }
2916
2917 ParentTable = DtPeekSubtable ();
2918 DtInsertSubtable (ParentTable, Subtable);
2919
2920 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
2921
2922 /* Method parameters */
2923 /* Optional: Log area minimum length */
2924 /* Optional: Log area start address */
2925 /* TBD: Optional fields above not fully implemented (not optional at this time) */
2926
2927 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
2928 &Subtable);
2929 if (ACPI_FAILURE (Status))
2930 {
2931 return (Status);
2932 }
2933
2934 ParentTable = DtPeekSubtable ();
2935 DtInsertSubtable (ParentTable, Subtable);
2936
2937
2938 /* Subtable type depends on the StartMethod */
2939
2940 switch (Tpm2Header->StartMethod)
2941 {
2942 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
2943
2944 /* Subtable specific to to ARM_SMC */
2945
2946 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
2947 &Subtable);
2948 if (ACPI_FAILURE (Status))
2949 {
2950 return (Status);
2951 }
2952
2953 ParentTable = DtPeekSubtable ();
2954 DtInsertSubtable (ParentTable, Subtable);
2955 break;
2956
2957 case ACPI_TPM2_START_METHOD:
2958 case ACPI_TPM2_MEMORY_MAPPED:
2959 case ACPI_TPM2_COMMAND_BUFFER:
2960 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
2961 break;
2962
2963 case ACPI_TPM2_RESERVED1:
2964 case ACPI_TPM2_RESERVED3:
2965 case ACPI_TPM2_RESERVED4:
2966 case ACPI_TPM2_RESERVED5:
2967 case ACPI_TPM2_RESERVED9:
2968 case ACPI_TPM2_RESERVED10:
2969
2970 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
2971 Tpm2Header->StartMethod);
2972 Status = AE_ERROR;
2973 break;
2974
2975 case ACPI_TPM2_NOT_ALLOWED:
2976 default:
2977
2978 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
2979 Tpm2Header->StartMethod);
2980 Status = AE_ERROR;
2981 break;
2982 }
2983
2984 return (Status);
2985 }
2986
2987
2988 /******************************************************************************
2989 *
2990 * FUNCTION: DtGetGenericTableInfo
2991 *
2992 * PARAMETERS: Name - Generic type name
2993 *
2994 * RETURN: Info entry
2995 *
2996 * DESCRIPTION: Obtain table info for a generic name entry
2997 *
2998 *****************************************************************************/
2999
3000 ACPI_DMTABLE_INFO *
DtGetGenericTableInfo(char * Name)3001 DtGetGenericTableInfo (
3002 char *Name)
3003 {
3004 ACPI_DMTABLE_INFO *Info;
3005 UINT32 i;
3006
3007
3008 if (!Name)
3009 {
3010 return (NULL);
3011 }
3012
3013 /* Search info table for name match */
3014
3015 for (i = 0; ; i++)
3016 {
3017 Info = AcpiDmTableInfoGeneric[i];
3018 if (Info->Opcode == ACPI_DMT_EXIT)
3019 {
3020 Info = NULL;
3021 break;
3022 }
3023
3024 /* Use caseless compare for generic keywords */
3025
3026 if (!AcpiUtStricmp (Name, Info->Name))
3027 {
3028 break;
3029 }
3030 }
3031
3032 return (Info);
3033 }
3034
3035
3036 /******************************************************************************
3037 *
3038 * FUNCTION: DtCompileUefi
3039 *
3040 * PARAMETERS: List - Current field list pointer
3041 *
3042 * RETURN: Status
3043 *
3044 * DESCRIPTION: Compile UEFI.
3045 *
3046 *****************************************************************************/
3047
3048 ACPI_STATUS
DtCompileUefi(void ** List)3049 DtCompileUefi (
3050 void **List)
3051 {
3052 ACPI_STATUS Status;
3053 DT_SUBTABLE *Subtable;
3054 DT_SUBTABLE *ParentTable;
3055 DT_FIELD **PFieldList = (DT_FIELD **) List;
3056 UINT16 *DataOffset;
3057
3058
3059 /* Compile the predefined portion of the UEFI table */
3060
3061 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
3062 &Subtable);
3063 if (ACPI_FAILURE (Status))
3064 {
3065 return (Status);
3066 }
3067
3068 DataOffset = (UINT16 *) (Subtable->Buffer + 16);
3069 *DataOffset = sizeof (ACPI_TABLE_UEFI);
3070
3071 ParentTable = DtPeekSubtable ();
3072 DtInsertSubtable (ParentTable, Subtable);
3073
3074 /*
3075 * Compile the "generic" portion of the UEFI table. This
3076 * part of the table is not predefined and any of the generic
3077 * operators may be used.
3078 */
3079 DtCompileGeneric ((void **) PFieldList, NULL, NULL);
3080 return (AE_OK);
3081 }
3082
3083
3084 /******************************************************************************
3085 *
3086 * FUNCTION: DtCompileViot
3087 *
3088 * PARAMETERS: List - Current field list pointer
3089 *
3090 * RETURN: Status
3091 *
3092 * DESCRIPTION: Compile VIOT.
3093 *
3094 *****************************************************************************/
3095
3096 ACPI_STATUS
DtCompileViot(void ** List)3097 DtCompileViot (
3098 void **List)
3099 {
3100 ACPI_STATUS Status;
3101 DT_SUBTABLE *Subtable;
3102 DT_SUBTABLE *ParentTable;
3103 DT_FIELD **PFieldList = (DT_FIELD **) List;
3104 DT_FIELD *SubtableStart;
3105 ACPI_TABLE_VIOT *Viot;
3106 ACPI_VIOT_HEADER *ViotHeader;
3107 ACPI_DMTABLE_INFO *InfoTable;
3108 UINT16 NodeCount;
3109
3110 ParentTable = DtPeekSubtable ();
3111
3112 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
3113 if (ACPI_FAILURE (Status))
3114 {
3115 return (Status);
3116 }
3117 DtInsertSubtable (ParentTable, Subtable);
3118
3119 /*
3120 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
3121 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
3122 */
3123 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
3124 sizeof (ACPI_TABLE_HEADER));
3125
3126 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
3127
3128 NodeCount = 0;
3129 while (*PFieldList) {
3130 SubtableStart = *PFieldList;
3131 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
3132 &Subtable);
3133 if (ACPI_FAILURE (Status))
3134 {
3135 return (Status);
3136 }
3137
3138 ParentTable = DtPeekSubtable ();
3139 DtInsertSubtable (ParentTable, Subtable);
3140 DtPushSubtable (Subtable);
3141
3142 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
3143
3144 switch (ViotHeader->Type)
3145 {
3146 case ACPI_VIOT_NODE_PCI_RANGE:
3147
3148 InfoTable = AcpiDmTableInfoViot1;
3149 break;
3150
3151 case ACPI_VIOT_NODE_MMIO:
3152
3153 InfoTable = AcpiDmTableInfoViot2;
3154 break;
3155
3156 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
3157
3158 InfoTable = AcpiDmTableInfoViot3;
3159 break;
3160
3161 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
3162
3163 InfoTable = AcpiDmTableInfoViot4;
3164 break;
3165
3166 default:
3167
3168 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
3169 return (AE_ERROR);
3170 }
3171
3172 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
3173 if (ACPI_FAILURE (Status))
3174 {
3175 return (Status);
3176 }
3177
3178 ParentTable = DtPeekSubtable ();
3179 DtInsertSubtable (ParentTable, Subtable);
3180 DtPopSubtable ();
3181 NodeCount++;
3182 }
3183
3184 Viot->NodeCount = NodeCount;
3185 return (AE_OK);
3186 }
3187
3188
3189 /******************************************************************************
3190 *
3191 * FUNCTION: DtCompileWdat
3192 *
3193 * PARAMETERS: List - Current field list pointer
3194 *
3195 * RETURN: Status
3196 *
3197 * DESCRIPTION: Compile WDAT.
3198 *
3199 *****************************************************************************/
3200
3201 ACPI_STATUS
DtCompileWdat(void ** List)3202 DtCompileWdat (
3203 void **List)
3204 {
3205 ACPI_STATUS Status;
3206
3207
3208 Status = DtCompileTwoSubtables (List,
3209 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3210 return (Status);
3211 }
3212
3213
3214 /******************************************************************************
3215 *
3216 * FUNCTION: DtCompileWpbt
3217 *
3218 * PARAMETERS: List - Current field list pointer
3219 *
3220 * RETURN: Status
3221 *
3222 * DESCRIPTION: Compile WPBT.
3223 *
3224 *****************************************************************************/
3225
3226 ACPI_STATUS
DtCompileWpbt(void ** List)3227 DtCompileWpbt (
3228 void **List)
3229 {
3230 DT_FIELD **PFieldList = (DT_FIELD **) List;
3231 DT_SUBTABLE *Subtable;
3232 DT_SUBTABLE *ParentTable;
3233 ACPI_TABLE_WPBT *Table;
3234 ACPI_STATUS Status;
3235
3236
3237 /* Compile the main table */
3238
3239 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
3240 if (ACPI_FAILURE (Status))
3241 {
3242 return (Status);
3243 }
3244
3245 ParentTable = DtPeekSubtable ();
3246 DtInsertSubtable (ParentTable, Subtable);
3247 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3248
3249 /*
3250 * Exit now if there are no arguments specified. This is indicated by:
3251 * The "Command-line Arguments" field has not been specified (if specified,
3252 * it will be the last field in the field list -- after the main table).
3253 * Set the Argument Length in the main table to zero.
3254 */
3255 if (!*PFieldList)
3256 {
3257 Table->ArgumentsLength = 0;
3258 return (AE_OK);
3259 }
3260
3261 /* Compile the argument list subtable */
3262
3263 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
3264 if (ACPI_FAILURE (Status))
3265 {
3266 return (Status);
3267 }
3268
3269 /* Extract the length of the Arguments buffer, insert into main table */
3270
3271 Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
3272 DtInsertSubtable (ParentTable, Subtable);
3273 return (AE_OK);
3274 }
3275
3276
3277 /******************************************************************************
3278 *
3279 * FUNCTION: DtCompileXsdt
3280 *
3281 * PARAMETERS: List - Current field list pointer
3282 *
3283 * RETURN: Status
3284 *
3285 * DESCRIPTION: Compile XSDT.
3286 *
3287 *****************************************************************************/
3288
3289 ACPI_STATUS
DtCompileXsdt(void ** List)3290 DtCompileXsdt (
3291 void **List)
3292 {
3293 DT_SUBTABLE *Subtable;
3294 DT_SUBTABLE *ParentTable;
3295 DT_FIELD *FieldList = *(DT_FIELD **) List;
3296 UINT64 Address;
3297
3298
3299 ParentTable = DtPeekSubtable ();
3300
3301 while (FieldList)
3302 {
3303 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3304
3305 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3306 DtInsertSubtable (ParentTable, Subtable);
3307 FieldList = FieldList->Next;
3308 }
3309
3310 return (AE_OK);
3311 }
3312
3313
3314 /******************************************************************************
3315 *
3316 * FUNCTION: DtCompileGeneric
3317 *
3318 * PARAMETERS: List - Current field list pointer
3319 * Name - Field name to end generic compiling
3320 * Length - Compiled table length to return
3321 *
3322 * RETURN: Status
3323 *
3324 * DESCRIPTION: Compile generic unknown table.
3325 *
3326 *****************************************************************************/
3327
3328 ACPI_STATUS
DtCompileGeneric(void ** List,char * Name,UINT32 * Length)3329 DtCompileGeneric (
3330 void **List,
3331 char *Name,
3332 UINT32 *Length)
3333 {
3334 ACPI_STATUS Status;
3335 DT_SUBTABLE *Subtable;
3336 DT_SUBTABLE *ParentTable;
3337 DT_FIELD **PFieldList = (DT_FIELD **) List;
3338 ACPI_DMTABLE_INFO *Info;
3339
3340
3341 ParentTable = DtPeekSubtable ();
3342
3343 /*
3344 * Compile the "generic" portion of the table. This
3345 * part of the table is not predefined and any of the generic
3346 * operators may be used.
3347 */
3348
3349 /* Find any and all labels in the entire generic portion */
3350
3351 DtDetectAllLabels (*PFieldList);
3352
3353 /* Now we can actually compile the parse tree */
3354
3355 if (Length && *Length)
3356 {
3357 *Length = 0;
3358 }
3359 while (*PFieldList)
3360 {
3361 if (Name && !strcmp ((*PFieldList)->Name, Name))
3362 {
3363 break;
3364 }
3365
3366 Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3367 if (!Info)
3368 {
3369 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3370 (*PFieldList)->Name);
3371 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3372 (*PFieldList), AslGbl_MsgBuffer);
3373
3374 *PFieldList = (*PFieldList)->Next;
3375 continue;
3376 }
3377
3378 Status = DtCompileTable (PFieldList, Info,
3379 &Subtable);
3380 if (ACPI_SUCCESS (Status))
3381 {
3382 DtInsertSubtable (ParentTable, Subtable);
3383 if (Length)
3384 {
3385 *Length += Subtable->Length;
3386 }
3387 }
3388 else
3389 {
3390 *PFieldList = (*PFieldList)->Next;
3391
3392 if (Status == AE_NOT_FOUND)
3393 {
3394 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
3395 (*PFieldList)->Name);
3396 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3397 (*PFieldList), AslGbl_MsgBuffer);
3398 }
3399 }
3400 }
3401
3402 return (AE_OK);
3403 }
3404