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