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