1 /******************************************************************************
2 *
3 * Module Name: dttable1.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 - 2021, 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 A-I */
153
154 #include "aslcompiler.h"
155
156 #define _COMPONENT DT_COMPILER
157 ACPI_MODULE_NAME ("dttable1")
158
159
160 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] =
161 {
162 {ACPI_DMT_BUFFER, 0, "Addresses", 0},
163 {ACPI_DMT_EXIT, 0, NULL, 0}
164 };
165
166 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] =
167 {
168 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0},
169 {ACPI_DMT_EXIT, 0, NULL, 0}
170 };
171
172
173 /******************************************************************************
174 *
175 * FUNCTION: DtCompileAest
176 *
177 * PARAMETERS: List - Current field list pointer
178 *
179 * RETURN: Status
180 *
181 * DESCRIPTION: Compile AEST.
182 *
183 * NOTE: Assumes the following table structure:
184 * For all AEST Error Nodes:
185 * 1) An AEST Error Node, followed immediately by:
186 * 2) Any node-specific data
187 * 3) An Interface Structure (one)
188 * 4) A list (array) of Interrupt Structures, the count as specified
189 * in the NodeInterruptCount field of the Error Node header.
190 *
191 * AEST - ARM Error Source table. Conforms to:
192 * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020
193 *
194 *****************************************************************************/
195
196 ACPI_STATUS
DtCompileAest(void ** List)197 DtCompileAest (
198 void **List)
199 {
200 ACPI_AEST_HEADER *ErrorNodeHeader;
201 ACPI_AEST_PROCESSOR *AestProcessor;
202 DT_SUBTABLE *Subtable;
203 DT_SUBTABLE *ParentTable;
204 ACPI_DMTABLE_INFO *InfoTable;
205 ACPI_STATUS Status;
206 UINT32 i;
207 UINT32 Offset;
208 DT_FIELD **PFieldList = (DT_FIELD **) List;
209
210
211 while (*PFieldList)
212 {
213 /* Compile the common error node header */
214
215 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr,
216 &Subtable);
217 if (ACPI_FAILURE (Status))
218 {
219 return (Status);
220 }
221
222 ParentTable = DtPeekSubtable ();
223 DtInsertSubtable (ParentTable, Subtable);
224
225 /* Everything past the error node header will be a subtable */
226
227 DtPushSubtable (Subtable);
228
229 /*
230 * Compile the node-specific structure (Based on the error
231 * node header Type field)
232 */
233 ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer);
234
235 /* Point past the common error node header */
236
237 Offset = sizeof (ACPI_AEST_HEADER);
238 ErrorNodeHeader->NodeSpecificOffset = Offset;
239
240 /* Decode the error node type */
241
242 switch (ErrorNodeHeader->Type)
243 {
244 case ACPI_AEST_PROCESSOR_ERROR_NODE:
245
246 InfoTable = AcpiDmTableInfoAestProcError;
247 break;
248
249 case ACPI_AEST_MEMORY_ERROR_NODE:
250
251 InfoTable = AcpiDmTableInfoAestMemError;
252 break;
253
254 case ACPI_AEST_SMMU_ERROR_NODE:
255
256 InfoTable = AcpiDmTableInfoAestSmmuError;
257 break;
258
259 case ACPI_AEST_VENDOR_ERROR_NODE:
260
261 InfoTable = AcpiDmTableInfoAestVendorError;
262 break;
263
264 case ACPI_AEST_GIC_ERROR_NODE:
265
266 InfoTable = AcpiDmTableInfoAestGicError;
267 break;
268
269 /* Error case below */
270 default:
271 AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n",
272 ErrorNodeHeader->Type);
273 return (AE_ERROR);
274 }
275
276 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
277 if (ACPI_FAILURE (Status))
278 {
279 return (Status);
280 }
281
282 /* Point past the node-specific structure */
283
284 Offset += Subtable->Length;
285 ErrorNodeHeader->NodeInterfaceOffset = Offset;
286
287 ParentTable = DtPeekSubtable ();
288 DtInsertSubtable (ParentTable, Subtable);
289
290 /* Compile any additional node-specific substructures */
291
292 if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
293 {
294 /*
295 * Special handling for PROCESSOR_ERROR_NODE subtables
296 * (to handle the Resource Substructure via the ResourceType
297 * field).
298 */
299 AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR,
300 Subtable->Buffer);
301
302 switch (AestProcessor->ResourceType)
303 {
304 case ACPI_AEST_CACHE_RESOURCE:
305
306 InfoTable = AcpiDmTableInfoAestCacheRsrc;
307 break;
308
309 case ACPI_AEST_TLB_RESOURCE:
310
311 InfoTable = AcpiDmTableInfoAestTlbRsrc;
312 break;
313
314 case ACPI_AEST_GENERIC_RESOURCE:
315
316 InfoTable = AcpiDmTableInfoAestGenRsrc;
317 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n",
318 AestProcessor->ResourceType);
319 return (AE_ERROR);
320
321 /* Error case below */
322 default:
323 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n",
324 AestProcessor->ResourceType);
325 return (AE_ERROR);
326 }
327
328 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
329 if (ACPI_FAILURE (Status))
330 {
331 return (Status);
332 }
333
334 /* Point past the resource substructure subtable */
335
336 Offset += Subtable->Length;
337 ErrorNodeHeader->NodeInterfaceOffset = Offset;
338
339 ParentTable = DtPeekSubtable ();
340 DtInsertSubtable (ParentTable, Subtable);
341 }
342
343 /* Compile the (required) node interface structure */
344
345 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface,
346 &Subtable);
347 if (ACPI_FAILURE (Status))
348 {
349 return (Status);
350 }
351
352 ErrorNodeHeader->NodeInterruptOffset = 0;
353 ParentTable = DtPeekSubtable ();
354 DtInsertSubtable (ParentTable, Subtable);
355
356 /* Compile each of the node interrupt structures */
357
358 if (ErrorNodeHeader->NodeInterruptCount)
359 {
360 /* Point to the first interrupt structure */
361
362 Offset += Subtable->Length;
363 ErrorNodeHeader->NodeInterruptOffset = Offset;
364 }
365
366 /* Compile each of the interrupt structures */
367
368 for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++)
369 {
370 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt,
371 &Subtable);
372 if (ACPI_FAILURE (Status))
373 {
374 return (Status);
375 }
376
377 ParentTable = DtPeekSubtable ();
378 DtInsertSubtable (ParentTable, Subtable);
379 }
380
381 /* Prepare for the next AEST Error node */
382
383 DtPopSubtable ();
384 }
385
386 return (AE_OK);
387 }
388
389
390 /******************************************************************************
391 *
392 * FUNCTION: DtCompileAsf
393 *
394 * PARAMETERS: List - Current field list pointer
395 *
396 * RETURN: Status
397 *
398 * DESCRIPTION: Compile ASF!.
399 *
400 *****************************************************************************/
401
402 ACPI_STATUS
DtCompileAsf(void ** List)403 DtCompileAsf (
404 void **List)
405 {
406 ACPI_ASF_INFO *AsfTable;
407 DT_SUBTABLE *Subtable;
408 DT_SUBTABLE *ParentTable;
409 ACPI_DMTABLE_INFO *InfoTable;
410 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
411 UINT32 DataCount = 0;
412 ACPI_STATUS Status;
413 UINT32 i;
414 DT_FIELD **PFieldList = (DT_FIELD **) List;
415 DT_FIELD *SubtableStart;
416
417
418 while (*PFieldList)
419 {
420 SubtableStart = *PFieldList;
421 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
422 &Subtable);
423 if (ACPI_FAILURE (Status))
424 {
425 return (Status);
426 }
427
428 ParentTable = DtPeekSubtable ();
429 DtInsertSubtable (ParentTable, Subtable);
430 DtPushSubtable (Subtable);
431
432 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
433
434 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
435 {
436 case ACPI_ASF_TYPE_INFO:
437
438 InfoTable = AcpiDmTableInfoAsf0;
439 break;
440
441 case ACPI_ASF_TYPE_ALERT:
442
443 InfoTable = AcpiDmTableInfoAsf1;
444 break;
445
446 case ACPI_ASF_TYPE_CONTROL:
447
448 InfoTable = AcpiDmTableInfoAsf2;
449 break;
450
451 case ACPI_ASF_TYPE_BOOT:
452
453 InfoTable = AcpiDmTableInfoAsf3;
454 break;
455
456 case ACPI_ASF_TYPE_ADDRESS:
457
458 InfoTable = AcpiDmTableInfoAsf4;
459 break;
460
461 default:
462
463 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
464 return (AE_ERROR);
465 }
466
467 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
468 if (ACPI_FAILURE (Status))
469 {
470 return (Status);
471 }
472
473 ParentTable = DtPeekSubtable ();
474 DtInsertSubtable (ParentTable, Subtable);
475
476 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
477 {
478 case ACPI_ASF_TYPE_INFO:
479
480 DataInfoTable = NULL;
481 break;
482
483 case ACPI_ASF_TYPE_ALERT:
484
485 DataInfoTable = AcpiDmTableInfoAsf1a;
486 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
487 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
488 sizeof (ACPI_ASF_HEADER)))->Alerts;
489 break;
490
491 case ACPI_ASF_TYPE_CONTROL:
492
493 DataInfoTable = AcpiDmTableInfoAsf2a;
494 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
495 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
496 sizeof (ACPI_ASF_HEADER)))->Controls;
497 break;
498
499 case ACPI_ASF_TYPE_BOOT:
500
501 DataInfoTable = NULL;
502 break;
503
504 case ACPI_ASF_TYPE_ADDRESS:
505
506 DataInfoTable = TableInfoAsfAddress;
507 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
508 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
509 sizeof (ACPI_ASF_HEADER)))->Devices;
510 break;
511
512 default:
513
514 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
515 return (AE_ERROR);
516 }
517
518 if (DataInfoTable)
519 {
520 switch (AsfTable->Header.Type & 0x7F)
521 {
522 case ACPI_ASF_TYPE_ADDRESS:
523
524 while (DataCount > 0)
525 {
526 Status = DtCompileTable (PFieldList, DataInfoTable,
527 &Subtable);
528 if (ACPI_FAILURE (Status))
529 {
530 return (Status);
531 }
532
533 DtInsertSubtable (ParentTable, Subtable);
534 DataCount = DataCount - Subtable->Length;
535 }
536 break;
537
538 default:
539
540 for (i = 0; i < DataCount; i++)
541 {
542 Status = DtCompileTable (PFieldList, DataInfoTable,
543 &Subtable);
544 if (ACPI_FAILURE (Status))
545 {
546 return (Status);
547 }
548
549 DtInsertSubtable (ParentTable, Subtable);
550 }
551 break;
552 }
553 }
554
555 DtPopSubtable ();
556 }
557
558 return (AE_OK);
559 }
560
561
562 /******************************************************************************
563 *
564 * FUNCTION: DtCompileCedt
565 *
566 * PARAMETERS: List - Current field list pointer
567 *
568 * RETURN: Status
569 *
570 * DESCRIPTION: Compile CEDT.
571 *
572 *****************************************************************************/
573
574 ACPI_STATUS
DtCompileCedt(void ** List)575 DtCompileCedt (
576 void **List)
577 {
578 ACPI_STATUS Status;
579 DT_SUBTABLE *Subtable;
580 DT_SUBTABLE *ParentTable;
581 DT_FIELD **PFieldList = (DT_FIELD **) List;
582 ACPI_CEDT_HEADER *CedtHeader;
583 DT_FIELD *SubtableStart;
584
585
586 /* Walk the parse tree */
587
588 while (*PFieldList)
589 {
590 SubtableStart = *PFieldList;
591
592 /* CEDT Header */
593
594 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
595 &Subtable);
596 if (ACPI_FAILURE (Status))
597 {
598 return (Status);
599 }
600
601 ParentTable = DtPeekSubtable ();
602 DtInsertSubtable (ParentTable, Subtable);
603 DtPushSubtable (Subtable);
604
605 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
606
607 switch (CedtHeader->Type)
608 {
609 case ACPI_CEDT_TYPE_CHBS:
610
611 break;
612
613 default:
614
615 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
616 return (AE_ERROR);
617 }
618
619 /* CEDT Subtable */
620
621 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
622 if (ACPI_FAILURE (Status))
623 {
624 return (Status);
625 }
626
627 ParentTable = DtPeekSubtable ();
628 DtInsertSubtable (ParentTable, Subtable);
629 DtPopSubtable ();
630 }
631
632 return (AE_OK);
633 }
634
635
636 /******************************************************************************
637 *
638 * FUNCTION: DtCompileCpep
639 *
640 * PARAMETERS: List - Current field list pointer
641 *
642 * RETURN: Status
643 *
644 * DESCRIPTION: Compile CPEP.
645 *
646 *****************************************************************************/
647
648 ACPI_STATUS
DtCompileCpep(void ** List)649 DtCompileCpep (
650 void **List)
651 {
652 ACPI_STATUS Status;
653
654
655 Status = DtCompileTwoSubtables (List,
656 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
657 return (Status);
658 }
659
660
661 /******************************************************************************
662 *
663 * FUNCTION: DtCompileCsrt
664 *
665 * PARAMETERS: List - Current field list pointer
666 *
667 * RETURN: Status
668 *
669 * DESCRIPTION: Compile CSRT.
670 *
671 *****************************************************************************/
672
673 ACPI_STATUS
DtCompileCsrt(void ** List)674 DtCompileCsrt (
675 void **List)
676 {
677 ACPI_STATUS Status = AE_OK;
678 DT_SUBTABLE *Subtable;
679 DT_SUBTABLE *ParentTable;
680 DT_FIELD **PFieldList = (DT_FIELD **) List;
681 UINT32 DescriptorCount;
682 UINT32 GroupLength;
683
684
685 /* Subtables (Resource Groups) */
686
687 ParentTable = DtPeekSubtable ();
688 while (*PFieldList)
689 {
690 /* Resource group subtable */
691
692 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
693 &Subtable);
694 if (ACPI_FAILURE (Status))
695 {
696 return (Status);
697 }
698
699 /* Compute the number of resource descriptors */
700
701 GroupLength =
702 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
703 Subtable->Buffer))->Length -
704 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
705 Subtable->Buffer))->SharedInfoLength -
706 sizeof (ACPI_CSRT_GROUP);
707
708 DescriptorCount = (GroupLength /
709 sizeof (ACPI_CSRT_DESCRIPTOR));
710
711 DtInsertSubtable (ParentTable, Subtable);
712 DtPushSubtable (Subtable);
713 ParentTable = DtPeekSubtable ();
714
715 /* Shared info subtable (One per resource group) */
716
717 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
718 &Subtable);
719 if (ACPI_FAILURE (Status))
720 {
721 return (Status);
722 }
723
724 DtInsertSubtable (ParentTable, Subtable);
725
726 /* Sub-Subtables (Resource Descriptors) */
727
728 while (*PFieldList && DescriptorCount)
729 {
730
731 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
732 &Subtable);
733 if (ACPI_FAILURE (Status))
734 {
735 return (Status);
736 }
737
738 DtInsertSubtable (ParentTable, Subtable);
739
740 DtPushSubtable (Subtable);
741 ParentTable = DtPeekSubtable ();
742 if (*PFieldList)
743 {
744 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
745 &Subtable);
746 if (ACPI_FAILURE (Status))
747 {
748 return (Status);
749 }
750 if (Subtable)
751 {
752 DtInsertSubtable (ParentTable, Subtable);
753 }
754 }
755
756 DtPopSubtable ();
757 ParentTable = DtPeekSubtable ();
758 DescriptorCount--;
759 }
760
761 DtPopSubtable ();
762 ParentTable = DtPeekSubtable ();
763 }
764
765 return (Status);
766 }
767
768
769 /******************************************************************************
770 *
771 * FUNCTION: DtCompileDbg2
772 *
773 * PARAMETERS: List - Current field list pointer
774 *
775 * RETURN: Status
776 *
777 * DESCRIPTION: Compile DBG2.
778 *
779 *****************************************************************************/
780
781 ACPI_STATUS
DtCompileDbg2(void ** List)782 DtCompileDbg2 (
783 void **List)
784 {
785 ACPI_STATUS Status;
786 DT_SUBTABLE *Subtable;
787 DT_SUBTABLE *ParentTable;
788 DT_FIELD **PFieldList = (DT_FIELD **) List;
789 UINT32 SubtableCount;
790 ACPI_DBG2_HEADER *Dbg2Header;
791 ACPI_DBG2_DEVICE *DeviceInfo;
792 UINT16 CurrentOffset;
793 UINT32 i;
794
795
796 /* Main table */
797
798 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
799 if (ACPI_FAILURE (Status))
800 {
801 return (Status);
802 }
803
804 ParentTable = DtPeekSubtable ();
805 DtInsertSubtable (ParentTable, Subtable);
806
807 /* Main table fields */
808
809 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
810 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
811 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
812
813 SubtableCount = Dbg2Header->InfoCount;
814 DtPushSubtable (Subtable);
815
816 /* Process all Device Information subtables (Count = InfoCount) */
817
818 while (*PFieldList && SubtableCount)
819 {
820 /* Subtable: Debug Device Information */
821
822 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
823 &Subtable);
824 if (ACPI_FAILURE (Status))
825 {
826 return (Status);
827 }
828
829 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
830 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
831
832 ParentTable = DtPeekSubtable ();
833 DtInsertSubtable (ParentTable, Subtable);
834 DtPushSubtable (Subtable);
835
836 ParentTable = DtPeekSubtable ();
837
838 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
839
840 DeviceInfo->BaseAddressOffset = CurrentOffset;
841 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
842 {
843 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
844 &Subtable);
845 if (ACPI_FAILURE (Status))
846 {
847 return (Status);
848 }
849
850 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
851 DtInsertSubtable (ParentTable, Subtable);
852 }
853
854 /* AddressSize array (Required, size = RegisterCount) */
855
856 DeviceInfo->AddressSizeOffset = CurrentOffset;
857 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
858 {
859 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
860 &Subtable);
861 if (ACPI_FAILURE (Status))
862 {
863 return (Status);
864 }
865
866 CurrentOffset += (UINT16) sizeof (UINT32);
867 DtInsertSubtable (ParentTable, Subtable);
868 }
869
870 /* NamespaceString device identifier (Required, size = NamePathLength) */
871
872 DeviceInfo->NamepathOffset = CurrentOffset;
873 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
874 &Subtable);
875 if (ACPI_FAILURE (Status))
876 {
877 return (Status);
878 }
879
880 /* Update the device info header */
881
882 DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
883 CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
884 DtInsertSubtable (ParentTable, Subtable);
885
886 /* OemData - Variable-length data (Optional, size = OemDataLength) */
887
888 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
889 &Subtable);
890 if (Status == AE_END_OF_TABLE)
891 {
892 /* optional field was not found and we're at the end of the file */
893
894 goto subtableDone;
895 }
896 else if (ACPI_FAILURE (Status))
897 {
898 return (Status);
899 }
900
901 /* Update the device info header (zeros if no OEM data present) */
902
903 DeviceInfo->OemDataOffset = 0;
904 DeviceInfo->OemDataLength = 0;
905
906 /* Optional subtable (OemData) */
907
908 if (Subtable && Subtable->Length)
909 {
910 DeviceInfo->OemDataOffset = CurrentOffset;
911 DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
912
913 DtInsertSubtable (ParentTable, Subtable);
914 }
915 subtableDone:
916 SubtableCount--;
917 DtPopSubtable (); /* Get next Device Information subtable */
918 }
919
920 DtPopSubtable ();
921 return (AE_OK);
922 }
923
924
925 /******************************************************************************
926 *
927 * FUNCTION: DtCompileDmar
928 *
929 * PARAMETERS: List - Current field list pointer
930 *
931 * RETURN: Status
932 *
933 * DESCRIPTION: Compile DMAR.
934 *
935 *****************************************************************************/
936
937 ACPI_STATUS
DtCompileDmar(void ** List)938 DtCompileDmar (
939 void **List)
940 {
941 ACPI_STATUS Status;
942 DT_SUBTABLE *Subtable;
943 DT_SUBTABLE *ParentTable;
944 DT_FIELD **PFieldList = (DT_FIELD **) List;
945 DT_FIELD *SubtableStart;
946 ACPI_DMTABLE_INFO *InfoTable;
947 ACPI_DMAR_HEADER *DmarHeader;
948 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
949 UINT32 DeviceScopeLength;
950 UINT32 PciPathLength;
951
952
953 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
954 if (ACPI_FAILURE (Status))
955 {
956 return (Status);
957 }
958
959 ParentTable = DtPeekSubtable ();
960 DtInsertSubtable (ParentTable, Subtable);
961 DtPushSubtable (Subtable);
962
963 while (*PFieldList)
964 {
965 /* DMAR Header */
966
967 SubtableStart = *PFieldList;
968 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
969 &Subtable);
970 if (ACPI_FAILURE (Status))
971 {
972 return (Status);
973 }
974
975 ParentTable = DtPeekSubtable ();
976 DtInsertSubtable (ParentTable, Subtable);
977 DtPushSubtable (Subtable);
978
979 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
980
981 switch (DmarHeader->Type)
982 {
983 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
984
985 InfoTable = AcpiDmTableInfoDmar0;
986 break;
987
988 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
989
990 InfoTable = AcpiDmTableInfoDmar1;
991 break;
992
993 case ACPI_DMAR_TYPE_ROOT_ATS:
994
995 InfoTable = AcpiDmTableInfoDmar2;
996 break;
997
998 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
999
1000 InfoTable = AcpiDmTableInfoDmar3;
1001 break;
1002
1003 case ACPI_DMAR_TYPE_NAMESPACE:
1004
1005 InfoTable = AcpiDmTableInfoDmar4;
1006 break;
1007
1008 default:
1009
1010 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
1011 return (AE_ERROR);
1012 }
1013
1014 /* DMAR Subtable */
1015
1016 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1017 if (ACPI_FAILURE (Status))
1018 {
1019 return (Status);
1020 }
1021
1022 ParentTable = DtPeekSubtable ();
1023 DtInsertSubtable (ParentTable, Subtable);
1024
1025 /*
1026 * Optional Device Scope subtables
1027 */
1028 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1029 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
1030 {
1031 /* These types do not support device scopes */
1032
1033 DtPopSubtable ();
1034 continue;
1035 }
1036
1037 DtPushSubtable (Subtable);
1038 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
1039 ParentTable->Length;
1040 while (DeviceScopeLength)
1041 {
1042 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
1043 &Subtable);
1044 if (Status == AE_NOT_FOUND)
1045 {
1046 break;
1047 }
1048
1049 ParentTable = DtPeekSubtable ();
1050 DtInsertSubtable (ParentTable, Subtable);
1051 DtPushSubtable (Subtable);
1052
1053 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
1054
1055 /* Optional PCI Paths */
1056
1057 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
1058 while (PciPathLength)
1059 {
1060 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
1061 &Subtable);
1062 if (Status == AE_NOT_FOUND)
1063 {
1064 DtPopSubtable ();
1065 break;
1066 }
1067
1068 ParentTable = DtPeekSubtable ();
1069 DtInsertSubtable (ParentTable, Subtable);
1070 PciPathLength -= Subtable->Length;
1071 }
1072
1073 DtPopSubtable ();
1074 DeviceScopeLength -= DmarDeviceScope->Length;
1075 }
1076
1077 DtPopSubtable ();
1078 DtPopSubtable ();
1079 }
1080
1081 return (AE_OK);
1082 }
1083
1084
1085 /******************************************************************************
1086 *
1087 * FUNCTION: DtCompileDrtm
1088 *
1089 * PARAMETERS: List - Current field list pointer
1090 *
1091 * RETURN: Status
1092 *
1093 * DESCRIPTION: Compile DRTM.
1094 *
1095 *****************************************************************************/
1096
1097 ACPI_STATUS
DtCompileDrtm(void ** List)1098 DtCompileDrtm (
1099 void **List)
1100 {
1101 ACPI_STATUS Status;
1102 DT_SUBTABLE *Subtable;
1103 DT_SUBTABLE *ParentTable;
1104 DT_FIELD **PFieldList = (DT_FIELD **) List;
1105 UINT32 Count;
1106 /* ACPI_TABLE_DRTM *Drtm; */
1107 ACPI_DRTM_VTABLE_LIST *DrtmVtl;
1108 ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1109 /* ACPI_DRTM_DPS_ID *DrtmDps; */
1110
1111
1112 ParentTable = DtPeekSubtable ();
1113
1114 /* Compile DRTM header */
1115
1116 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
1117 &Subtable);
1118 if (ACPI_FAILURE (Status))
1119 {
1120 return (Status);
1121 }
1122 DtInsertSubtable (ParentTable, Subtable);
1123
1124 /*
1125 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1126 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1127 */
1128 #if 0
1129 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
1130 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1131 #endif
1132 /* Compile VTL */
1133
1134 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
1135 &Subtable);
1136 if (ACPI_FAILURE (Status))
1137 {
1138 return (Status);
1139 }
1140
1141 DtInsertSubtable (ParentTable, Subtable);
1142 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
1143
1144 DtPushSubtable (Subtable);
1145 ParentTable = DtPeekSubtable ();
1146 Count = 0;
1147
1148 while (*PFieldList)
1149 {
1150 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
1151 &Subtable);
1152 if (ACPI_FAILURE (Status))
1153 {
1154 return (Status);
1155 }
1156 if (!Subtable)
1157 {
1158 break;
1159 }
1160 DtInsertSubtable (ParentTable, Subtable);
1161 Count++;
1162 }
1163
1164 DrtmVtl->ValidatedTableCount = Count;
1165 DtPopSubtable ();
1166 ParentTable = DtPeekSubtable ();
1167
1168 /* Compile RL */
1169
1170 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
1171 &Subtable);
1172 if (ACPI_FAILURE (Status))
1173 {
1174 return (Status);
1175 }
1176
1177 DtInsertSubtable (ParentTable, Subtable);
1178 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
1179
1180 DtPushSubtable (Subtable);
1181 ParentTable = DtPeekSubtable ();
1182 Count = 0;
1183
1184 while (*PFieldList)
1185 {
1186 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
1187 &Subtable);
1188 if (ACPI_FAILURE (Status))
1189 {
1190 return (Status);
1191 }
1192
1193 if (!Subtable)
1194 {
1195 break;
1196 }
1197
1198 DtInsertSubtable (ParentTable, Subtable);
1199 Count++;
1200 }
1201
1202 DrtmRl->ResourceCount = Count;
1203 DtPopSubtable ();
1204 ParentTable = DtPeekSubtable ();
1205
1206 /* Compile DPS */
1207
1208 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
1209 &Subtable);
1210 if (ACPI_FAILURE (Status))
1211 {
1212 return (Status);
1213 }
1214 DtInsertSubtable (ParentTable, Subtable);
1215 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
1216
1217
1218 return (AE_OK);
1219 }
1220
1221
1222 /******************************************************************************
1223 *
1224 * FUNCTION: DtCompileEinj
1225 *
1226 * PARAMETERS: List - Current field list pointer
1227 *
1228 * RETURN: Status
1229 *
1230 * DESCRIPTION: Compile EINJ.
1231 *
1232 *****************************************************************************/
1233
1234 ACPI_STATUS
DtCompileEinj(void ** List)1235 DtCompileEinj (
1236 void **List)
1237 {
1238 ACPI_STATUS Status;
1239
1240
1241 Status = DtCompileTwoSubtables (List,
1242 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
1243 return (Status);
1244 }
1245
1246
1247 /******************************************************************************
1248 *
1249 * FUNCTION: DtCompileErst
1250 *
1251 * PARAMETERS: List - Current field list pointer
1252 *
1253 * RETURN: Status
1254 *
1255 * DESCRIPTION: Compile ERST.
1256 *
1257 *****************************************************************************/
1258
1259 ACPI_STATUS
DtCompileErst(void ** List)1260 DtCompileErst (
1261 void **List)
1262 {
1263 ACPI_STATUS Status;
1264
1265
1266 Status = DtCompileTwoSubtables (List,
1267 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1268 return (Status);
1269 }
1270
1271
1272 /******************************************************************************
1273 *
1274 * FUNCTION: DtCompileGtdt
1275 *
1276 * PARAMETERS: List - Current field list pointer
1277 *
1278 * RETURN: Status
1279 *
1280 * DESCRIPTION: Compile GTDT.
1281 *
1282 *****************************************************************************/
1283
1284 ACPI_STATUS
DtCompileGtdt(void ** List)1285 DtCompileGtdt (
1286 void **List)
1287 {
1288 ACPI_STATUS Status;
1289 DT_SUBTABLE *Subtable;
1290 DT_SUBTABLE *ParentTable;
1291 DT_FIELD **PFieldList = (DT_FIELD **) List;
1292 DT_FIELD *SubtableStart;
1293 ACPI_SUBTABLE_HEADER *GtdtHeader;
1294 ACPI_DMTABLE_INFO *InfoTable;
1295 UINT32 GtCount;
1296 ACPI_TABLE_HEADER *Header;
1297
1298
1299 ParentTable = DtPeekSubtable ();
1300
1301 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1302
1303 /* Compile the main table */
1304
1305 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1306 &Subtable);
1307 if (ACPI_FAILURE (Status))
1308 {
1309 return (Status);
1310 }
1311
1312 /* GTDT revision 3 later contains 2 extra fields before subtables */
1313
1314 if (Header->Revision > 2)
1315 {
1316 ParentTable = DtPeekSubtable ();
1317 DtInsertSubtable (ParentTable, Subtable);
1318
1319 Status = DtCompileTable (PFieldList,
1320 AcpiDmTableInfoGtdtEl2, &Subtable);
1321 if (ACPI_FAILURE (Status))
1322 {
1323 return (Status);
1324 }
1325 }
1326
1327 ParentTable = DtPeekSubtable ();
1328 DtInsertSubtable (ParentTable, Subtable);
1329
1330 while (*PFieldList)
1331 {
1332 SubtableStart = *PFieldList;
1333 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1334 &Subtable);
1335 if (ACPI_FAILURE (Status))
1336 {
1337 return (Status);
1338 }
1339
1340 ParentTable = DtPeekSubtable ();
1341 DtInsertSubtable (ParentTable, Subtable);
1342 DtPushSubtable (Subtable);
1343
1344 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1345
1346 switch (GtdtHeader->Type)
1347 {
1348 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1349
1350 InfoTable = AcpiDmTableInfoGtdt0;
1351 break;
1352
1353 case ACPI_GTDT_TYPE_WATCHDOG:
1354
1355 InfoTable = AcpiDmTableInfoGtdt1;
1356 break;
1357
1358 default:
1359
1360 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1361 return (AE_ERROR);
1362 }
1363
1364 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1365 if (ACPI_FAILURE (Status))
1366 {
1367 return (Status);
1368 }
1369
1370 ParentTable = DtPeekSubtable ();
1371 DtInsertSubtable (ParentTable, Subtable);
1372
1373 /*
1374 * Additional GT block subtable data
1375 */
1376
1377 switch (GtdtHeader->Type)
1378 {
1379 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1380
1381 DtPushSubtable (Subtable);
1382 ParentTable = DtPeekSubtable ();
1383
1384 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1385 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1386
1387 while (GtCount)
1388 {
1389 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1390 &Subtable);
1391 if (ACPI_FAILURE (Status))
1392 {
1393 return (Status);
1394 }
1395
1396 DtInsertSubtable (ParentTable, Subtable);
1397 GtCount--;
1398 }
1399
1400 DtPopSubtable ();
1401 break;
1402
1403 default:
1404
1405 break;
1406 }
1407
1408 DtPopSubtable ();
1409 }
1410
1411 return (AE_OK);
1412 }
1413
1414
1415 /******************************************************************************
1416 *
1417 * FUNCTION: DtCompileFpdt
1418 *
1419 * PARAMETERS: List - Current field list pointer
1420 *
1421 * RETURN: Status
1422 *
1423 * DESCRIPTION: Compile FPDT.
1424 *
1425 *****************************************************************************/
1426
1427 ACPI_STATUS
DtCompileFpdt(void ** List)1428 DtCompileFpdt (
1429 void **List)
1430 {
1431 ACPI_STATUS Status;
1432 ACPI_FPDT_HEADER *FpdtHeader;
1433 DT_SUBTABLE *Subtable;
1434 DT_SUBTABLE *ParentTable;
1435 ACPI_DMTABLE_INFO *InfoTable;
1436 DT_FIELD **PFieldList = (DT_FIELD **) List;
1437 DT_FIELD *SubtableStart;
1438
1439
1440 while (*PFieldList)
1441 {
1442 SubtableStart = *PFieldList;
1443 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1444 &Subtable);
1445 if (ACPI_FAILURE (Status))
1446 {
1447 return (Status);
1448 }
1449
1450 ParentTable = DtPeekSubtable ();
1451 DtInsertSubtable (ParentTable, Subtable);
1452 DtPushSubtable (Subtable);
1453
1454 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1455
1456 switch (FpdtHeader->Type)
1457 {
1458 case ACPI_FPDT_TYPE_BOOT:
1459
1460 InfoTable = AcpiDmTableInfoFpdt0;
1461 break;
1462
1463 case ACPI_FPDT_TYPE_S3PERF:
1464
1465 InfoTable = AcpiDmTableInfoFpdt1;
1466 break;
1467
1468 default:
1469
1470 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1471 return (AE_ERROR);
1472 break;
1473 }
1474
1475 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1476 if (ACPI_FAILURE (Status))
1477 {
1478 return (Status);
1479 }
1480
1481 ParentTable = DtPeekSubtable ();
1482 DtInsertSubtable (ParentTable, Subtable);
1483 DtPopSubtable ();
1484 }
1485
1486 return (AE_OK);
1487 }
1488
1489
1490 /******************************************************************************
1491 *
1492 * FUNCTION: DtCompileHest
1493 *
1494 * PARAMETERS: List - Current field list pointer
1495 *
1496 * RETURN: Status
1497 *
1498 * DESCRIPTION: Compile HEST.
1499 *
1500 *****************************************************************************/
1501
1502 ACPI_STATUS
DtCompileHest(void ** List)1503 DtCompileHest (
1504 void **List)
1505 {
1506 ACPI_STATUS Status;
1507 DT_SUBTABLE *Subtable;
1508 DT_SUBTABLE *ParentTable;
1509 DT_FIELD **PFieldList = (DT_FIELD **) List;
1510 DT_FIELD *SubtableStart;
1511 ACPI_DMTABLE_INFO *InfoTable;
1512 UINT16 Type;
1513 UINT32 BankCount;
1514
1515
1516 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1517 &Subtable);
1518 if (ACPI_FAILURE (Status))
1519 {
1520 return (Status);
1521 }
1522
1523 ParentTable = DtPeekSubtable ();
1524 DtInsertSubtable (ParentTable, Subtable);
1525
1526 while (*PFieldList)
1527 {
1528 /* Get subtable type */
1529
1530 SubtableStart = *PFieldList;
1531 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1532
1533 switch (Type)
1534 {
1535 case ACPI_HEST_TYPE_IA32_CHECK:
1536
1537 InfoTable = AcpiDmTableInfoHest0;
1538 break;
1539
1540 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1541
1542 InfoTable = AcpiDmTableInfoHest1;
1543 break;
1544
1545 case ACPI_HEST_TYPE_IA32_NMI:
1546
1547 InfoTable = AcpiDmTableInfoHest2;
1548 break;
1549
1550 case ACPI_HEST_TYPE_AER_ROOT_PORT:
1551
1552 InfoTable = AcpiDmTableInfoHest6;
1553 break;
1554
1555 case ACPI_HEST_TYPE_AER_ENDPOINT:
1556
1557 InfoTable = AcpiDmTableInfoHest7;
1558 break;
1559
1560 case ACPI_HEST_TYPE_AER_BRIDGE:
1561
1562 InfoTable = AcpiDmTableInfoHest8;
1563 break;
1564
1565 case ACPI_HEST_TYPE_GENERIC_ERROR:
1566
1567 InfoTable = AcpiDmTableInfoHest9;
1568 break;
1569
1570 case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1571
1572 InfoTable = AcpiDmTableInfoHest10;
1573 break;
1574
1575 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1576
1577 InfoTable = AcpiDmTableInfoHest11;
1578 break;
1579
1580 default:
1581
1582 /* Cannot continue on unknown type */
1583
1584 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1585 return (AE_ERROR);
1586 }
1587
1588 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1589 if (ACPI_FAILURE (Status))
1590 {
1591 return (Status);
1592 }
1593
1594 DtInsertSubtable (ParentTable, Subtable);
1595
1596 /*
1597 * Additional subtable data - IA32 Error Bank(s)
1598 */
1599 BankCount = 0;
1600 switch (Type)
1601 {
1602 case ACPI_HEST_TYPE_IA32_CHECK:
1603
1604 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1605 Subtable->Buffer))->NumHardwareBanks;
1606 break;
1607
1608 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1609
1610 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1611 Subtable->Buffer))->NumHardwareBanks;
1612 break;
1613
1614 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1615
1616 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1617 Subtable->Buffer))->NumHardwareBanks;
1618 break;
1619
1620 default:
1621
1622 break;
1623 }
1624
1625 while (BankCount)
1626 {
1627 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1628 &Subtable);
1629 if (ACPI_FAILURE (Status))
1630 {
1631 return (Status);
1632 }
1633
1634 DtInsertSubtable (ParentTable, Subtable);
1635 BankCount--;
1636 }
1637 }
1638
1639 return (AE_OK);
1640 }
1641
1642
1643 /******************************************************************************
1644 *
1645 * FUNCTION: DtCompileHmat
1646 *
1647 * PARAMETERS: List - Current field list pointer
1648 *
1649 * RETURN: Status
1650 *
1651 * DESCRIPTION: Compile HMAT.
1652 *
1653 *****************************************************************************/
1654
1655 ACPI_STATUS
DtCompileHmat(void ** List)1656 DtCompileHmat (
1657 void **List)
1658 {
1659 ACPI_STATUS Status;
1660 DT_SUBTABLE *Subtable;
1661 DT_SUBTABLE *ParentTable;
1662 DT_FIELD **PFieldList = (DT_FIELD **) List;
1663 DT_FIELD *SubtableStart;
1664 DT_FIELD *EntryStart;
1665 ACPI_HMAT_STRUCTURE *HmatStruct;
1666 ACPI_HMAT_LOCALITY *HmatLocality;
1667 ACPI_HMAT_CACHE *HmatCache;
1668 ACPI_DMTABLE_INFO *InfoTable;
1669 UINT32 IntPDNumber;
1670 UINT32 TgtPDNumber;
1671 UINT64 EntryNumber;
1672 UINT16 SMBIOSHandleNumber;
1673
1674
1675 ParentTable = DtPeekSubtable ();
1676
1677 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
1678 &Subtable);
1679 if (ACPI_FAILURE (Status))
1680 {
1681 return (Status);
1682 }
1683 DtInsertSubtable (ParentTable, Subtable);
1684
1685 while (*PFieldList)
1686 {
1687 /* Compile HMAT structure header */
1688
1689 SubtableStart = *PFieldList;
1690 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
1691 &Subtable);
1692 if (ACPI_FAILURE (Status))
1693 {
1694 return (Status);
1695 }
1696 DtInsertSubtable (ParentTable, Subtable);
1697
1698 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
1699 HmatStruct->Length = Subtable->Length;
1700
1701 /* Compile HMAT structure body */
1702
1703 switch (HmatStruct->Type)
1704 {
1705 case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1706
1707 InfoTable = AcpiDmTableInfoHmat0;
1708 break;
1709
1710 case ACPI_HMAT_TYPE_LOCALITY:
1711
1712 InfoTable = AcpiDmTableInfoHmat1;
1713 break;
1714
1715 case ACPI_HMAT_TYPE_CACHE:
1716
1717 InfoTable = AcpiDmTableInfoHmat2;
1718 break;
1719
1720 default:
1721
1722 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
1723 return (AE_ERROR);
1724 }
1725
1726 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1727 if (ACPI_FAILURE (Status))
1728 {
1729 return (Status);
1730 }
1731 DtInsertSubtable (ParentTable, Subtable);
1732 HmatStruct->Length += Subtable->Length;
1733
1734 /* Compile HMAT structure additionals */
1735
1736 switch (HmatStruct->Type)
1737 {
1738 case ACPI_HMAT_TYPE_LOCALITY:
1739
1740 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
1741 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
1742
1743 /* Compile initiator proximity domain list */
1744
1745 IntPDNumber = 0;
1746 while (*PFieldList)
1747 {
1748 Status = DtCompileTable (PFieldList,
1749 AcpiDmTableInfoHmat1a, &Subtable);
1750 if (ACPI_FAILURE (Status))
1751 {
1752 return (Status);
1753 }
1754 if (!Subtable)
1755 {
1756 break;
1757 }
1758 DtInsertSubtable (ParentTable, Subtable);
1759 HmatStruct->Length += Subtable->Length;
1760 IntPDNumber++;
1761 }
1762 HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
1763
1764 /* Compile target proximity domain list */
1765
1766 TgtPDNumber = 0;
1767 while (*PFieldList)
1768 {
1769 Status = DtCompileTable (PFieldList,
1770 AcpiDmTableInfoHmat1b, &Subtable);
1771 if (ACPI_FAILURE (Status))
1772 {
1773 return (Status);
1774 }
1775 if (!Subtable)
1776 {
1777 break;
1778 }
1779 DtInsertSubtable (ParentTable, Subtable);
1780 HmatStruct->Length += Subtable->Length;
1781 TgtPDNumber++;
1782 }
1783 HmatLocality->NumberOfTargetPDs = TgtPDNumber;
1784
1785 /* Save start of the entries for reporting errors */
1786
1787 EntryStart = *PFieldList;
1788
1789 /* Compile latency/bandwidth entries */
1790
1791 EntryNumber = 0;
1792 while (*PFieldList)
1793 {
1794 Status = DtCompileTable (PFieldList,
1795 AcpiDmTableInfoHmat1c, &Subtable);
1796 if (ACPI_FAILURE (Status))
1797 {
1798 return (Status);
1799 }
1800 if (!Subtable)
1801 {
1802 break;
1803 }
1804 DtInsertSubtable (ParentTable, Subtable);
1805 HmatStruct->Length += Subtable->Length;
1806 EntryNumber++;
1807 }
1808
1809 /* Validate number of entries */
1810
1811 if (EntryNumber !=
1812 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
1813 {
1814 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
1815 return (AE_ERROR);
1816 }
1817 break;
1818
1819 case ACPI_HMAT_TYPE_CACHE:
1820
1821 /* Compile SMBIOS handles */
1822
1823 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
1824 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
1825 SMBIOSHandleNumber = 0;
1826 while (*PFieldList)
1827 {
1828 Status = DtCompileTable (PFieldList,
1829 AcpiDmTableInfoHmat2a, &Subtable);
1830 if (ACPI_FAILURE (Status))
1831 {
1832 return (Status);
1833 }
1834 if (!Subtable)
1835 {
1836 break;
1837 }
1838 DtInsertSubtable (ParentTable, Subtable);
1839 HmatStruct->Length += Subtable->Length;
1840 SMBIOSHandleNumber++;
1841 }
1842 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
1843 break;
1844
1845 default:
1846
1847 break;
1848 }
1849 }
1850
1851 return (AE_OK);
1852 }
1853
1854
1855 /******************************************************************************
1856 *
1857 * FUNCTION: DtCompileIort
1858 *
1859 * PARAMETERS: List - Current field list pointer
1860 *
1861 * RETURN: Status
1862 *
1863 * DESCRIPTION: Compile IORT.
1864 *
1865 *****************************************************************************/
1866
1867 ACPI_STATUS
DtCompileIort(void ** List)1868 DtCompileIort (
1869 void **List)
1870 {
1871 ACPI_STATUS Status;
1872 DT_SUBTABLE *Subtable;
1873 DT_SUBTABLE *ParentTable;
1874 DT_FIELD **PFieldList = (DT_FIELD **) List;
1875 DT_FIELD *SubtableStart;
1876 ACPI_TABLE_HEADER *Table;
1877 ACPI_TABLE_IORT *Iort;
1878 ACPI_IORT_NODE *IortNode;
1879 ACPI_IORT_ITS_GROUP *IortItsGroup;
1880 ACPI_IORT_SMMU *IortSmmu;
1881 ACPI_IORT_RMR *IortRmr;
1882 UINT32 NodeNumber;
1883 UINT32 NodeLength;
1884 UINT32 IdMappingNumber;
1885 UINT32 ItsNumber;
1886 UINT32 ContextIrptNumber;
1887 UINT32 PmuIrptNumber;
1888 UINT32 PaddingLength;
1889 UINT8 Revision;
1890 UINT32 RmrCount;
1891
1892
1893 ParentTable = DtPeekSubtable ();
1894
1895 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1896 &Subtable);
1897 if (ACPI_FAILURE (Status))
1898 {
1899 return (Status);
1900 }
1901 DtInsertSubtable (ParentTable, Subtable);
1902
1903 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1904 Revision = Table->Revision;
1905
1906 /* Both IORT Rev E and E.a have known issues and are not supported */
1907
1908 if (Revision == 1 || Revision == 2)
1909 {
1910 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
1911 return (AE_ERROR);
1912 }
1913
1914 /*
1915 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1916 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
1917 */
1918 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1919 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1920
1921 /*
1922 * OptionalPadding - Variable-length data
1923 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1924 * Optionally allows the generic data types to be used for filling
1925 * this field.
1926 */
1927 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1928 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1929 &Subtable);
1930 if (ACPI_FAILURE (Status))
1931 {
1932 return (Status);
1933 }
1934 if (Subtable)
1935 {
1936 DtInsertSubtable (ParentTable, Subtable);
1937 Iort->NodeOffset += Subtable->Length;
1938 }
1939 else
1940 {
1941 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1942 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1943 if (ACPI_FAILURE (Status))
1944 {
1945 return (Status);
1946 }
1947 Iort->NodeOffset += PaddingLength;
1948 }
1949
1950 NodeNumber = 0;
1951 while (*PFieldList)
1952 {
1953 SubtableStart = *PFieldList;
1954 if (Revision == 0)
1955 {
1956 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1957 &Subtable);
1958 }
1959 else if (Revision >= 3)
1960 {
1961 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
1962 &Subtable);
1963 }
1964
1965 if (ACPI_FAILURE (Status))
1966 {
1967 return (Status);
1968 }
1969
1970 DtInsertSubtable (ParentTable, Subtable);
1971 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1972 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1973
1974 DtPushSubtable (Subtable);
1975 ParentTable = DtPeekSubtable ();
1976
1977 switch (IortNode->Type)
1978 {
1979 case ACPI_IORT_NODE_ITS_GROUP:
1980
1981 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1982 &Subtable);
1983 if (ACPI_FAILURE (Status))
1984 {
1985 return (Status);
1986 }
1987
1988 DtInsertSubtable (ParentTable, Subtable);
1989 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1990 NodeLength += Subtable->Length;
1991
1992 ItsNumber = 0;
1993 while (*PFieldList)
1994 {
1995 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1996 &Subtable);
1997 if (ACPI_FAILURE (Status))
1998 {
1999 return (Status);
2000 }
2001 if (!Subtable)
2002 {
2003 break;
2004 }
2005
2006 DtInsertSubtable (ParentTable, Subtable);
2007 NodeLength += Subtable->Length;
2008 ItsNumber++;
2009 }
2010
2011 IortItsGroup->ItsCount = ItsNumber;
2012 break;
2013
2014 case ACPI_IORT_NODE_NAMED_COMPONENT:
2015
2016 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
2017 &Subtable);
2018 if (ACPI_FAILURE (Status))
2019 {
2020 return (Status);
2021 }
2022
2023 DtInsertSubtable (ParentTable, Subtable);
2024 NodeLength += Subtable->Length;
2025
2026 /*
2027 * Padding - Variable-length data
2028 * Optionally allows the offset of the ID mappings to be used
2029 * for filling this field.
2030 */
2031 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
2032 &Subtable);
2033 if (ACPI_FAILURE (Status))
2034 {
2035 return (Status);
2036 }
2037
2038 if (Subtable)
2039 {
2040 DtInsertSubtable (ParentTable, Subtable);
2041 NodeLength += Subtable->Length;
2042 }
2043 else
2044 {
2045 if (NodeLength > IortNode->MappingOffset)
2046 {
2047 return (AE_BAD_DATA);
2048 }
2049
2050 if (NodeLength < IortNode->MappingOffset)
2051 {
2052 Status = DtCompilePadding (
2053 IortNode->MappingOffset - NodeLength,
2054 &Subtable);
2055 if (ACPI_FAILURE (Status))
2056 {
2057 return (Status);
2058 }
2059
2060 DtInsertSubtable (ParentTable, Subtable);
2061 NodeLength = IortNode->MappingOffset;
2062 }
2063 }
2064 break;
2065
2066 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
2067
2068 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
2069 &Subtable);
2070 if (ACPI_FAILURE (Status))
2071 {
2072 return (Status);
2073 }
2074
2075 DtInsertSubtable (ParentTable, Subtable);
2076 NodeLength += Subtable->Length;
2077 break;
2078
2079 case ACPI_IORT_NODE_SMMU:
2080
2081 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
2082 &Subtable);
2083 if (ACPI_FAILURE (Status))
2084 {
2085 return (Status);
2086 }
2087
2088 DtInsertSubtable (ParentTable, Subtable);
2089 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
2090 NodeLength += Subtable->Length;
2091
2092 /* Compile global interrupt array */
2093
2094 IortSmmu->GlobalInterruptOffset = NodeLength;
2095 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
2096 &Subtable);
2097 if (ACPI_FAILURE (Status))
2098 {
2099 return (Status);
2100 }
2101
2102 DtInsertSubtable (ParentTable, Subtable);
2103 NodeLength += Subtable->Length;
2104
2105 /* Compile context interrupt array */
2106
2107 ContextIrptNumber = 0;
2108 IortSmmu->ContextInterruptOffset = NodeLength;
2109 while (*PFieldList)
2110 {
2111 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
2112 &Subtable);
2113 if (ACPI_FAILURE (Status))
2114 {
2115 return (Status);
2116 }
2117
2118 if (!Subtable)
2119 {
2120 break;
2121 }
2122
2123 DtInsertSubtable (ParentTable, Subtable);
2124 NodeLength += Subtable->Length;
2125 ContextIrptNumber++;
2126 }
2127
2128 IortSmmu->ContextInterruptCount = ContextIrptNumber;
2129
2130 /* Compile PMU interrupt array */
2131
2132 PmuIrptNumber = 0;
2133 IortSmmu->PmuInterruptOffset = NodeLength;
2134 while (*PFieldList)
2135 {
2136 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
2137 &Subtable);
2138 if (ACPI_FAILURE (Status))
2139 {
2140 return (Status);
2141 }
2142
2143 if (!Subtable)
2144 {
2145 break;
2146 }
2147
2148 DtInsertSubtable (ParentTable, Subtable);
2149 NodeLength += Subtable->Length;
2150 PmuIrptNumber++;
2151 }
2152
2153 IortSmmu->PmuInterruptCount = PmuIrptNumber;
2154 break;
2155
2156 case ACPI_IORT_NODE_SMMU_V3:
2157
2158 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
2159 &Subtable);
2160 if (ACPI_FAILURE (Status))
2161 {
2162 return (Status);
2163 }
2164
2165 DtInsertSubtable (ParentTable, Subtable);
2166 NodeLength += Subtable->Length;
2167 break;
2168
2169 case ACPI_IORT_NODE_PMCG:
2170
2171 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
2172 &Subtable);
2173 if (ACPI_FAILURE (Status))
2174 {
2175 return (Status);
2176 }
2177
2178 DtInsertSubtable (ParentTable, Subtable);
2179 NodeLength += Subtable->Length;
2180 break;
2181
2182 case ACPI_IORT_NODE_RMR:
2183
2184 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
2185 &Subtable);
2186 if (ACPI_FAILURE (Status))
2187 {
2188 return (Status);
2189 }
2190
2191 DtInsertSubtable (ParentTable, Subtable);
2192 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
2193 NodeLength += Subtable->Length;
2194
2195 /* Compile RMR Descriptors */
2196
2197 RmrCount = 0;
2198 IortRmr->RmrOffset = NodeLength;
2199 while (*PFieldList)
2200 {
2201 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
2202 &Subtable);
2203 if (ACPI_FAILURE (Status))
2204 {
2205 return (Status);
2206 }
2207
2208 if (!Subtable)
2209 {
2210 break;
2211 }
2212
2213 DtInsertSubtable (ParentTable, Subtable);
2214 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
2215 RmrCount++;
2216 }
2217
2218 IortRmr->RmrCount = RmrCount;
2219 break;
2220
2221 default:
2222
2223 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
2224 return (AE_ERROR);
2225 }
2226
2227 /* Compile Array of ID mappings */
2228
2229 IortNode->MappingOffset = NodeLength;
2230 IdMappingNumber = 0;
2231 while (*PFieldList)
2232 {
2233 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
2234 &Subtable);
2235 if (ACPI_FAILURE (Status))
2236 {
2237 return (Status);
2238 }
2239
2240 if (!Subtable)
2241 {
2242 break;
2243 }
2244
2245 DtInsertSubtable (ParentTable, Subtable);
2246 NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
2247 IdMappingNumber++;
2248 }
2249
2250 IortNode->MappingCount = IdMappingNumber;
2251 if (!IdMappingNumber)
2252 {
2253 IortNode->MappingOffset = 0;
2254 }
2255
2256 /*
2257 * Node length can be determined by DT_LENGTH option
2258 * IortNode->Length = NodeLength;
2259 */
2260 DtPopSubtable ();
2261 ParentTable = DtPeekSubtable ();
2262 NodeNumber++;
2263 }
2264
2265 Iort->NodeCount = NodeNumber;
2266 return (AE_OK);
2267 }
2268
2269
2270 /******************************************************************************
2271 *
2272 * FUNCTION: DtCompileIvrs
2273 *
2274 * PARAMETERS: List - Current field list pointer
2275 *
2276 * RETURN: Status
2277 *
2278 * DESCRIPTION: Compile IVRS. Notes:
2279 * The IVRS is essentially a flat table, with the following
2280 * structure:
2281 * <Main ACPI Table Header>
2282 * <Main subtable - virtualization info>
2283 * <IVHD>
2284 * <Device Entries>
2285 * ...
2286 * <IVHD>
2287 * <Device Entries>
2288 * <IVMD>
2289 * ...
2290 *
2291 *****************************************************************************/
2292
2293 ACPI_STATUS
DtCompileIvrs(void ** List)2294 DtCompileIvrs (
2295 void **List)
2296 {
2297 ACPI_STATUS Status;
2298 DT_SUBTABLE *Subtable;
2299 DT_SUBTABLE *ParentTable;
2300 DT_SUBTABLE *MainSubtable;
2301 DT_FIELD **PFieldList = (DT_FIELD **) List;
2302 DT_FIELD *SubtableStart;
2303 ACPI_DMTABLE_INFO *InfoTable = NULL;
2304 UINT8 SubtableType;
2305 UINT8 Temp64[16];
2306 UINT8 Temp8;
2307
2308
2309 /* Main table */
2310
2311 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
2312 &Subtable);
2313 if (ACPI_FAILURE (Status))
2314 {
2315 return (Status);
2316 }
2317
2318 ParentTable = DtPeekSubtable ();
2319 DtInsertSubtable (ParentTable, Subtable);
2320 DtPushSubtable (Subtable);
2321
2322 /* Save a pointer to the main subtable */
2323
2324 MainSubtable = Subtable;
2325
2326 while (*PFieldList)
2327 {
2328 SubtableStart = *PFieldList;
2329
2330 /* Compile the SubtableType integer */
2331
2332 DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
2333
2334 switch (SubtableType)
2335 {
2336
2337 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
2338
2339 case ACPI_IVRS_TYPE_HARDWARE1:
2340
2341 InfoTable = AcpiDmTableInfoIvrsHware1;
2342 break;
2343
2344 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
2345
2346 case ACPI_IVRS_TYPE_HARDWARE2:
2347 case ACPI_IVRS_TYPE_HARDWARE3:
2348
2349 InfoTable = AcpiDmTableInfoIvrsHware23;
2350 break;
2351
2352 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
2353
2354 case ACPI_IVRS_TYPE_MEMORY1:
2355 case ACPI_IVRS_TYPE_MEMORY2:
2356 case ACPI_IVRS_TYPE_MEMORY3:
2357
2358 InfoTable = AcpiDmTableInfoIvrsMemory;
2359 break;
2360
2361 /* 4-byte device entries */
2362
2363 case ACPI_IVRS_TYPE_PAD4:
2364 case ACPI_IVRS_TYPE_ALL:
2365 case ACPI_IVRS_TYPE_SELECT:
2366 case ACPI_IVRS_TYPE_START:
2367 case ACPI_IVRS_TYPE_END:
2368
2369 InfoTable = AcpiDmTableInfoIvrs4;
2370 break;
2371
2372 /* 8-byte device entries, type A */
2373
2374 case ACPI_IVRS_TYPE_ALIAS_SELECT:
2375 case ACPI_IVRS_TYPE_ALIAS_START:
2376
2377 InfoTable = AcpiDmTableInfoIvrs8a;
2378 break;
2379
2380 /* 8-byte device entries, type B */
2381
2382 case ACPI_IVRS_TYPE_EXT_SELECT:
2383 case ACPI_IVRS_TYPE_EXT_START:
2384
2385 InfoTable = AcpiDmTableInfoIvrs8b;
2386 break;
2387
2388 /* 8-byte device entries, type C */
2389
2390 case ACPI_IVRS_TYPE_SPECIAL:
2391
2392 InfoTable = AcpiDmTableInfoIvrs8c;
2393 break;
2394
2395 /* Variable device entries, type F0h */
2396
2397 case ACPI_IVRS_TYPE_HID:
2398
2399 InfoTable = AcpiDmTableInfoIvrsHid;
2400 break;
2401
2402 default:
2403
2404 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
2405 "IVRS Device Entry");
2406 return (AE_ERROR);
2407 }
2408
2409 /* Compile the InfoTable from above */
2410
2411 Status = DtCompileTable (PFieldList, InfoTable,
2412 &Subtable);
2413 if (ACPI_FAILURE (Status))
2414 {
2415 return (Status);
2416 }
2417
2418 ParentTable = DtPeekSubtable ();
2419 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
2420 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
2421 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
2422 SubtableType != ACPI_IVRS_TYPE_HID &&
2423 SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
2424 SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
2425 SubtableType != ACPI_IVRS_TYPE_MEMORY3)
2426 {
2427 if (ParentTable)
2428 DtInsertSubtable (ParentTable, Subtable);
2429 }
2430
2431 switch (SubtableType)
2432 {
2433 case ACPI_IVRS_TYPE_HARDWARE1:
2434 case ACPI_IVRS_TYPE_HARDWARE2:
2435 case ACPI_IVRS_TYPE_HARDWARE3:
2436 case ACPI_IVRS_TYPE_MEMORY1:
2437 case ACPI_IVRS_TYPE_MEMORY2:
2438 case ACPI_IVRS_TYPE_MEMORY3:
2439
2440 /* Insert these IVHDs/IVMDs at the root subtable */
2441
2442 DtInsertSubtable (MainSubtable, Subtable);
2443 DtPushSubtable (Subtable);
2444 ParentTable = MainSubtable;
2445 break;
2446
2447 case ACPI_IVRS_TYPE_HID:
2448
2449 /* Special handling for the HID named device entry (0xF0) */
2450
2451 if (ParentTable)
2452 {
2453 DtInsertSubtable (ParentTable, Subtable);
2454 }
2455
2456 /*
2457 * Process the HID value. First, get the HID value as a string.
2458 */
2459 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2460
2461 /*
2462 * Determine if the HID is an integer or a string.
2463 * An integer is defined to be 32 bits, with the upper 32 bits
2464 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
2465 * integer or a character string. If an integer, the lower
2466 * 4 bytes of the field contain the integer and the upper
2467 * 4 bytes are padded with 0".
2468 */
2469 if (UtIsIdInteger ((UINT8 *) &Temp64))
2470 {
2471 /* Compile the HID value as an integer */
2472
2473 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2474
2475 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
2476 &Subtable);
2477 if (ACPI_FAILURE (Status))
2478 {
2479 return (Status);
2480 }
2481 }
2482 else
2483 {
2484 /* Compile the HID value as a string */
2485
2486 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
2487 &Subtable);
2488 if (ACPI_FAILURE (Status))
2489 {
2490 return (Status);
2491 }
2492 }
2493
2494 DtInsertSubtable (ParentTable, Subtable);
2495
2496 /*
2497 * Process the CID value. First, get the CID value as a string.
2498 */
2499 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2500
2501 if (UtIsIdInteger ((UINT8 *) &Temp64))
2502 {
2503 /* Compile the CID value as an integer */
2504
2505 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2506
2507 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
2508 &Subtable);
2509 if (ACPI_FAILURE (Status))
2510 {
2511 return (Status);
2512 }
2513 }
2514 else
2515 {
2516 /* Compile the CID value as a string */
2517
2518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
2519 &Subtable);
2520 if (ACPI_FAILURE (Status))
2521 {
2522 return (Status);
2523 }
2524 }
2525
2526 DtInsertSubtable (ParentTable, Subtable);
2527
2528 /*
2529 * Process the UID value. First, get and decode the "UID Format" field (Integer).
2530 */
2531 if (!*PFieldList)
2532 {
2533 return (AE_OK);
2534 }
2535
2536 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
2537
2538 switch (Temp8)
2539 {
2540 case ACPI_IVRS_UID_NOT_PRESENT:
2541 break;
2542
2543 case ACPI_IVRS_UID_IS_INTEGER:
2544
2545 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
2546 &Subtable);
2547 if (ACPI_FAILURE (Status))
2548 {
2549 return (Status);
2550 }
2551 DtInsertSubtable (ParentTable, Subtable);
2552 break;
2553
2554 case ACPI_IVRS_UID_IS_STRING:
2555
2556 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
2557 &Subtable);
2558 if (ACPI_FAILURE (Status))
2559 {
2560 return (Status);
2561 }
2562 DtInsertSubtable (ParentTable, Subtable);
2563 break;
2564
2565 default:
2566
2567 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
2568 "IVRS Device Entry");
2569 return (AE_ERROR);
2570 }
2571
2572 default:
2573
2574 /* All other subtable types come through here */
2575 break;
2576 }
2577 }
2578
2579 return (AE_OK);
2580 }
2581