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 - 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 A-I */
153
154 #include <contrib/dev/acpica/compiler/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: DtCompileApmt
393 *
394 * PARAMETERS: List - Current field list pointer
395 *
396 * RETURN: Status
397 *
398 * DESCRIPTION: Compile APMT.
399 *
400 *****************************************************************************/
401
402 ACPI_STATUS
DtCompileApmt(void ** List)403 DtCompileApmt (
404 void **List)
405 {
406 ACPI_STATUS Status;
407 ACPI_TABLE_HEADER *Header;
408 ACPI_APMT_NODE *ApmtNode;
409 ACPI_APMT_NODE *PeerApmtNode;
410 DT_SUBTABLE *Subtable;
411 DT_SUBTABLE *PeerSubtable;
412 DT_SUBTABLE *ParentTable;
413 DT_FIELD **PFieldList = (DT_FIELD**)List;
414 DT_FIELD *SubtableStart;
415 UINT32 CurLength;
416 char MsgBuffer[64] = "";
417
418 ParentTable = DtPeekSubtable();
419
420 Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer);
421
422 CurLength = sizeof(ACPI_TABLE_HEADER);
423
424 /* Walk the parse tree */
425
426 while (*PFieldList)
427 {
428 /* APMT Node Subtable */
429
430 SubtableStart = *PFieldList;
431
432 Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable);
433
434 if (ACPI_FAILURE(Status))
435 {
436 return (Status);
437 }
438
439 ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer);
440
441 if (ApmtNode->Length != sizeof(ACPI_APMT_NODE))
442 {
443 DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT");
444 return (AE_ERROR);
445 }
446
447 if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT)
448 {
449 snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type);
450 DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer);
451 return (AE_ERROR);
452 }
453
454 PeerSubtable = DtGetNextSubtable(ParentTable, NULL);
455
456 /* Validate the node id needs to be unique. */
457 while(PeerSubtable)
458 {
459 PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer);
460 if (PeerApmtNode->Id == ApmtNode->Id)
461 {
462 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id);
463 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer);
464 return (AE_ERROR);
465 }
466
467 PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable);
468 }
469
470 CurLength += ApmtNode->Length;
471
472 DtInsertSubtable(ParentTable, Subtable);
473 }
474
475 if (Header->Length != CurLength)
476 {
477 snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)",
478 Header->Length, CurLength);
479 DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer);
480 return (AE_ERROR);
481 }
482
483 return (AE_OK);
484 }
485
486 /******************************************************************************
487 *
488 * FUNCTION: DtCompileAsf
489 *
490 * PARAMETERS: List - Current field list pointer
491 *
492 * RETURN: Status
493 *
494 * DESCRIPTION: Compile ASF!.
495 *
496 *****************************************************************************/
497
498 ACPI_STATUS
DtCompileAsf(void ** List)499 DtCompileAsf (
500 void **List)
501 {
502 ACPI_ASF_INFO *AsfTable;
503 DT_SUBTABLE *Subtable;
504 DT_SUBTABLE *ParentTable;
505 ACPI_DMTABLE_INFO *InfoTable;
506 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
507 UINT32 DataCount = 0;
508 ACPI_STATUS Status;
509 UINT32 i;
510 DT_FIELD **PFieldList = (DT_FIELD **) List;
511 DT_FIELD *SubtableStart;
512
513
514 while (*PFieldList)
515 {
516 SubtableStart = *PFieldList;
517 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
518 &Subtable);
519 if (ACPI_FAILURE (Status))
520 {
521 return (Status);
522 }
523
524 ParentTable = DtPeekSubtable ();
525 DtInsertSubtable (ParentTable, Subtable);
526 DtPushSubtable (Subtable);
527
528 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
529
530 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
531 {
532 case ACPI_ASF_TYPE_INFO:
533
534 InfoTable = AcpiDmTableInfoAsf0;
535 break;
536
537 case ACPI_ASF_TYPE_ALERT:
538
539 InfoTable = AcpiDmTableInfoAsf1;
540 break;
541
542 case ACPI_ASF_TYPE_CONTROL:
543
544 InfoTable = AcpiDmTableInfoAsf2;
545 break;
546
547 case ACPI_ASF_TYPE_BOOT:
548
549 InfoTable = AcpiDmTableInfoAsf3;
550 break;
551
552 case ACPI_ASF_TYPE_ADDRESS:
553
554 InfoTable = AcpiDmTableInfoAsf4;
555 break;
556
557 default:
558
559 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
560 return (AE_ERROR);
561 }
562
563 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
564 if (ACPI_FAILURE (Status))
565 {
566 return (Status);
567 }
568
569 ParentTable = DtPeekSubtable ();
570 DtInsertSubtable (ParentTable, Subtable);
571
572 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
573 {
574 case ACPI_ASF_TYPE_INFO:
575
576 DataInfoTable = NULL;
577 break;
578
579 case ACPI_ASF_TYPE_ALERT:
580
581 DataInfoTable = AcpiDmTableInfoAsf1a;
582 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
583 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
584 sizeof (ACPI_ASF_HEADER)))->Alerts;
585 break;
586
587 case ACPI_ASF_TYPE_CONTROL:
588
589 DataInfoTable = AcpiDmTableInfoAsf2a;
590 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
591 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
592 sizeof (ACPI_ASF_HEADER)))->Controls;
593 break;
594
595 case ACPI_ASF_TYPE_BOOT:
596
597 DataInfoTable = NULL;
598 break;
599
600 case ACPI_ASF_TYPE_ADDRESS:
601
602 DataInfoTable = TableInfoAsfAddress;
603 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
604 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
605 sizeof (ACPI_ASF_HEADER)))->Devices;
606 break;
607
608 default:
609
610 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
611 return (AE_ERROR);
612 }
613
614 if (DataInfoTable)
615 {
616 switch (AsfTable->Header.Type & 0x7F)
617 {
618 case ACPI_ASF_TYPE_ADDRESS:
619
620 while (DataCount > 0)
621 {
622 Status = DtCompileTable (PFieldList, DataInfoTable,
623 &Subtable);
624 if (ACPI_FAILURE (Status))
625 {
626 return (Status);
627 }
628
629 DtInsertSubtable (ParentTable, Subtable);
630 DataCount = DataCount - Subtable->Length;
631 }
632 break;
633
634 default:
635
636 for (i = 0; i < DataCount; i++)
637 {
638 Status = DtCompileTable (PFieldList, DataInfoTable,
639 &Subtable);
640 if (ACPI_FAILURE (Status))
641 {
642 return (Status);
643 }
644
645 DtInsertSubtable (ParentTable, Subtable);
646 }
647 break;
648 }
649 }
650
651 DtPopSubtable ();
652 }
653
654 return (AE_OK);
655 }
656
657 /******************************************************************************
658 *
659 * FUNCTION: DtCompileAspt
660 *
661 * PARAMETERS: List - Current field list pointer
662 *
663 * RETURN: Status
664 *
665 * DESCRIPTION: Compile ASPT.
666 *
667 *****************************************************************************/
668
669 ACPI_STATUS
DtCompileAspt(void ** List)670 DtCompileAspt (
671 void **List)
672 {
673 ACPI_ASPT_HEADER *AsptTable;
674 DT_SUBTABLE *Subtable;
675 DT_SUBTABLE *ParentTable;
676 ACPI_DMTABLE_INFO *InfoTable;
677 ACPI_STATUS Status;
678 DT_FIELD **PFieldList = (DT_FIELD **) List;
679 DT_FIELD *SubtableStart;
680
681 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAspt, &Subtable);
682 if (ACPI_FAILURE (Status))
683 {
684 return (Status);
685 }
686
687 ParentTable = DtPeekSubtable ();
688 DtInsertSubtable (ParentTable, Subtable);
689
690 while (*PFieldList)
691 {
692 SubtableStart = *PFieldList;
693 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsptHdr,
694 &Subtable);
695 if (ACPI_FAILURE (Status))
696 {
697 return (Status);
698 }
699
700 ParentTable = DtPeekSubtable ();
701 DtInsertSubtable (ParentTable, Subtable);
702 DtPushSubtable (Subtable);
703
704 AsptTable = ACPI_CAST_PTR (ACPI_ASPT_HEADER, Subtable->Buffer);
705
706 switch (AsptTable->Type) /* Mask off top bit */
707 {
708 case ACPI_ASPT_TYPE_GLOBAL_REGS:
709
710 InfoTable = AcpiDmTableInfoAspt0;
711 break;
712
713 case ACPI_ASPT_TYPE_SEV_MBOX_REGS:
714
715 InfoTable = AcpiDmTableInfoAspt1;
716 break;
717
718 case ACPI_ASPT_TYPE_ACPI_MBOX_REGS:
719
720 InfoTable = AcpiDmTableInfoAspt2;
721 break;
722
723 default:
724
725 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASPT");
726 return (AE_ERROR);
727 }
728
729 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
730 if (ACPI_FAILURE (Status))
731 {
732 return (Status);
733 }
734 ParentTable = DtPeekSubtable ();
735 DtInsertSubtable (ParentTable, Subtable);
736 DtPopSubtable ();
737 }
738
739 return (AE_OK);
740 }
741
742
743 /******************************************************************************
744 *
745 * FUNCTION: DtCompileCdat
746 *
747 * PARAMETERS: List - Current field list pointer
748 *
749 * RETURN: Status
750 *
751 * DESCRIPTION: Compile CDAT.
752 *
753 *****************************************************************************/
754
755 ACPI_STATUS
DtCompileCdat(void ** List)756 DtCompileCdat (
757 void **List)
758 {
759 ACPI_STATUS Status = AE_OK;
760 DT_SUBTABLE *Subtable;
761 DT_SUBTABLE *ParentTable;
762 DT_FIELD **PFieldList = (DT_FIELD **) List;
763 ACPI_CDAT_HEADER *CdatHeader;
764 ACPI_DMTABLE_INFO *InfoTable = NULL;
765 DT_FIELD *SubtableStart;
766
767
768 /* Walk the parse tree.
769 *
770 * Note: Main table consists of only the CDAT table header
771 * (This is not the standard ACPI table header, however)--
772 * Followed by some number of subtables.
773 */
774 while (*PFieldList)
775 {
776 SubtableStart = *PFieldList;
777
778 /* Compile the expected CDAT Subtable header */
779
780 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader,
781 &Subtable);
782 if (ACPI_FAILURE (Status))
783 {
784 return (Status);
785 }
786
787 ParentTable = DtPeekSubtable ();
788 DtInsertSubtable (ParentTable, Subtable);
789 DtPushSubtable (Subtable);
790
791 CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer);
792
793 /* Decode the subtable by type */
794
795 switch (CdatHeader->Type)
796 {
797 case ACPI_CDAT_TYPE_DSMAS:
798 InfoTable = AcpiDmTableInfoCdat0;
799 break;
800
801 case ACPI_CDAT_TYPE_DSLBIS:
802 InfoTable = AcpiDmTableInfoCdat1;
803 break;
804
805 case ACPI_CDAT_TYPE_DSMSCIS:
806 InfoTable = AcpiDmTableInfoCdat2;
807 break;
808
809 case ACPI_CDAT_TYPE_DSIS:
810 InfoTable = AcpiDmTableInfoCdat3;
811 break;
812
813 case ACPI_CDAT_TYPE_DSEMTS:
814 InfoTable = AcpiDmTableInfoCdat4;
815 break;
816
817 case ACPI_CDAT_TYPE_SSLBIS:
818 InfoTable = AcpiDmTableInfoCdat5;
819 break;
820
821 default:
822 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT");
823 }
824
825 /* Compile the CDAT subtable */
826
827 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
828 if (ACPI_FAILURE (Status))
829 {
830 return (Status);
831 }
832
833 ParentTable = DtPeekSubtable ();
834 DtInsertSubtable (ParentTable, Subtable);
835
836 switch (CdatHeader->Type)
837 {
838 /* Multiple entries supported for this type */
839
840 case ACPI_CDAT_TYPE_SSLBIS:
841
842 /*
843 * Check for multiple SSLBEs
844 */
845 while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID"))
846 {
847 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable);
848 if (ACPI_FAILURE (Status))
849 {
850 return (Status);
851 }
852 ParentTable = DtPeekSubtable ();
853 DtInsertSubtable (ParentTable, Subtable);
854 }
855 break;
856
857 default:
858 break;
859 }
860
861 /* Pop off the CDAT Subtable header subtree */
862
863 DtPopSubtable ();
864 }
865
866 return (AE_OK);
867 }
868
869
870 /******************************************************************************
871 *
872 * FUNCTION: DtCompileCedt
873 *
874 * PARAMETERS: List - Current field list pointer
875 *
876 * RETURN: Status
877 *
878 * DESCRIPTION: Compile CEDT.
879 *
880 *****************************************************************************/
881
882 ACPI_STATUS
DtCompileCedt(void ** List)883 DtCompileCedt (
884 void **List)
885 {
886 ACPI_STATUS Status;
887 DT_SUBTABLE *Subtable;
888 DT_SUBTABLE *ParentTable;
889 DT_FIELD **PFieldList = (DT_FIELD **) List;
890 ACPI_CEDT_HEADER *CedtHeader;
891 DT_FIELD *SubtableStart;
892
893
894 /* Walk the parse tree */
895
896 while (*PFieldList)
897 {
898 /* if CFMWS and has more than one target, then set to zero later */
899
900 int InsertFlag = 1;
901 SubtableStart = *PFieldList;
902
903 /* CEDT Header */
904
905 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
906 &Subtable);
907 if (ACPI_FAILURE (Status))
908 {
909 return (Status);
910 }
911
912 ParentTable = DtPeekSubtable ();
913 DtInsertSubtable (ParentTable, Subtable);
914 DtPushSubtable (Subtable);
915
916 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
917
918 switch (CedtHeader->Type)
919 {
920 case ACPI_CEDT_TYPE_CHBS:
921 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
922 if (ACPI_FAILURE (Status))
923 {
924 return (Status);
925 }
926 break;
927 case ACPI_CEDT_TYPE_CFMWS: {
928 unsigned char *dump;
929 unsigned int idx, offset, max = 0;
930
931 /* Compile table with first "Interleave target" */
932
933 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable);
934 if (ACPI_FAILURE (Status))
935 {
936 return (Status);
937 }
938
939 /* Look in buffer for the number of targets */
940 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays);
941 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt1 */
942 max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */
943 if (max > 8) max=1; /* Error in encoding Interleaving Ways. */
944 if (max == 1) /* if only one target, then break here. */
945 break; /* break if only one target. */
946
947 /* We need to add more interleave targets, so write the current Subtable. */
948
949 ParentTable = DtPeekSubtable ();
950 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt1 table so we can put in */
951 DtPushSubtable (Subtable); /* the targets > the first. */
952
953 /* Now, find out all interleave targets beyond the first. */
954
955 for (idx = 1; idx < max; idx++) {
956 ParentTable = DtPeekSubtable ();
957
958 if (*PFieldList)
959 {
960 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable);
961 if (ACPI_FAILURE (Status))
962 {
963 return (Status);
964 }
965 if (Subtable)
966 {
967 DtInsertSubtable (ParentTable, Subtable); /* got a target, so insert table. */
968 InsertFlag = 0;
969 }
970 }
971 }
972
973 DtPopSubtable ();
974 ParentTable = DtPeekSubtable ();
975 break;
976 }
977
978 default:
979 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
980 return (AE_ERROR);
981 }
982
983 ParentTable = DtPeekSubtable ();
984 if (InsertFlag == 1) {
985 DtInsertSubtable (ParentTable, Subtable);
986 }
987 DtPopSubtable ();
988 }
989
990 return (AE_OK);
991 }
992
993
994 /******************************************************************************
995 *
996 * FUNCTION: DtCompileCpep
997 *
998 * PARAMETERS: List - Current field list pointer
999 *
1000 * RETURN: Status
1001 *
1002 * DESCRIPTION: Compile CPEP.
1003 *
1004 *****************************************************************************/
1005
1006 ACPI_STATUS
DtCompileCpep(void ** List)1007 DtCompileCpep (
1008 void **List)
1009 {
1010 ACPI_STATUS Status;
1011
1012
1013 Status = DtCompileTwoSubtables (List,
1014 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
1015 return (Status);
1016 }
1017
1018
1019 /******************************************************************************
1020 *
1021 * FUNCTION: DtCompileCsrt
1022 *
1023 * PARAMETERS: List - Current field list pointer
1024 *
1025 * RETURN: Status
1026 *
1027 * DESCRIPTION: Compile CSRT.
1028 *
1029 *****************************************************************************/
1030
1031 ACPI_STATUS
DtCompileCsrt(void ** List)1032 DtCompileCsrt (
1033 void **List)
1034 {
1035 ACPI_STATUS Status = AE_OK;
1036 DT_SUBTABLE *Subtable;
1037 DT_SUBTABLE *ParentTable;
1038 DT_FIELD **PFieldList = (DT_FIELD **) List;
1039 UINT32 DescriptorCount;
1040 UINT32 GroupLength;
1041
1042
1043 /* Subtables (Resource Groups) */
1044
1045 ParentTable = DtPeekSubtable ();
1046 while (*PFieldList)
1047 {
1048 /* Resource group subtable */
1049
1050 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
1051 &Subtable);
1052 if (ACPI_FAILURE (Status))
1053 {
1054 return (Status);
1055 }
1056
1057 /* Compute the number of resource descriptors */
1058
1059 GroupLength =
1060 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
1061 Subtable->Buffer))->Length -
1062 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
1063 Subtable->Buffer))->SharedInfoLength -
1064 sizeof (ACPI_CSRT_GROUP);
1065
1066 DescriptorCount = (GroupLength /
1067 sizeof (ACPI_CSRT_DESCRIPTOR));
1068
1069 DtInsertSubtable (ParentTable, Subtable);
1070 DtPushSubtable (Subtable);
1071 ParentTable = DtPeekSubtable ();
1072
1073 /* Shared info subtable (One per resource group) */
1074
1075 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
1076 &Subtable);
1077 if (ACPI_FAILURE (Status))
1078 {
1079 return (Status);
1080 }
1081
1082 DtInsertSubtable (ParentTable, Subtable);
1083
1084 /* Sub-Subtables (Resource Descriptors) */
1085
1086 while (*PFieldList && DescriptorCount)
1087 {
1088
1089 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
1090 &Subtable);
1091 if (ACPI_FAILURE (Status))
1092 {
1093 return (Status);
1094 }
1095
1096 DtInsertSubtable (ParentTable, Subtable);
1097
1098 DtPushSubtable (Subtable);
1099 ParentTable = DtPeekSubtable ();
1100 if (*PFieldList)
1101 {
1102 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
1103 &Subtable);
1104 if (ACPI_FAILURE (Status))
1105 {
1106 return (Status);
1107 }
1108 if (Subtable)
1109 {
1110 DtInsertSubtable (ParentTable, Subtable);
1111 }
1112 }
1113
1114 DtPopSubtable ();
1115 ParentTable = DtPeekSubtable ();
1116 DescriptorCount--;
1117 }
1118
1119 DtPopSubtable ();
1120 ParentTable = DtPeekSubtable ();
1121 }
1122
1123 return (Status);
1124 }
1125
1126
1127 /******************************************************************************
1128 *
1129 * FUNCTION: DtCompileDbg2
1130 *
1131 * PARAMETERS: List - Current field list pointer
1132 *
1133 * RETURN: Status
1134 *
1135 * DESCRIPTION: Compile DBG2.
1136 *
1137 *****************************************************************************/
1138
1139 ACPI_STATUS
DtCompileDbg2(void ** List)1140 DtCompileDbg2 (
1141 void **List)
1142 {
1143 ACPI_STATUS Status;
1144 DT_SUBTABLE *Subtable;
1145 DT_SUBTABLE *ParentTable;
1146 DT_FIELD **PFieldList = (DT_FIELD **) List;
1147 UINT32 SubtableCount;
1148 ACPI_DBG2_HEADER *Dbg2Header;
1149 ACPI_DBG2_DEVICE *DeviceInfo;
1150 UINT16 CurrentOffset;
1151 UINT32 i;
1152
1153
1154 /* Main table */
1155
1156 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
1157 if (ACPI_FAILURE (Status))
1158 {
1159 return (Status);
1160 }
1161
1162 ParentTable = DtPeekSubtable ();
1163 DtInsertSubtable (ParentTable, Subtable);
1164
1165 /* Main table fields */
1166
1167 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
1168 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
1169 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
1170
1171 SubtableCount = Dbg2Header->InfoCount;
1172 DtPushSubtable (Subtable);
1173
1174 /* Process all Device Information subtables (Count = InfoCount) */
1175
1176 while (*PFieldList && SubtableCount)
1177 {
1178 /* Subtable: Debug Device Information */
1179
1180 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
1181 &Subtable);
1182 if (ACPI_FAILURE (Status))
1183 {
1184 return (Status);
1185 }
1186
1187 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
1188 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
1189
1190 ParentTable = DtPeekSubtable ();
1191 DtInsertSubtable (ParentTable, Subtable);
1192 DtPushSubtable (Subtable);
1193
1194 ParentTable = DtPeekSubtable ();
1195
1196 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
1197
1198 DeviceInfo->BaseAddressOffset = CurrentOffset;
1199 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
1200 {
1201 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
1202 &Subtable);
1203 if (ACPI_FAILURE (Status))
1204 {
1205 return (Status);
1206 }
1207
1208 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
1209 DtInsertSubtable (ParentTable, Subtable);
1210 }
1211
1212 /* AddressSize array (Required, size = RegisterCount) */
1213
1214 DeviceInfo->AddressSizeOffset = CurrentOffset;
1215 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
1216 {
1217 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
1218 &Subtable);
1219 if (ACPI_FAILURE (Status))
1220 {
1221 return (Status);
1222 }
1223
1224 CurrentOffset += (UINT16) sizeof (UINT32);
1225 DtInsertSubtable (ParentTable, Subtable);
1226 }
1227
1228 /* NamespaceString device identifier (Required, size = NamePathLength) */
1229
1230 DeviceInfo->NamepathOffset = CurrentOffset;
1231 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
1232 &Subtable);
1233 if (ACPI_FAILURE (Status))
1234 {
1235 return (Status);
1236 }
1237
1238 /* Update the device info header */
1239
1240 DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
1241 CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
1242 DtInsertSubtable (ParentTable, Subtable);
1243
1244 /* OemData - Variable-length data (Optional, size = OemDataLength) */
1245
1246 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
1247 &Subtable);
1248 if (Status == AE_END_OF_TABLE)
1249 {
1250 /* optional field was not found and we're at the end of the file */
1251
1252 goto subtableDone;
1253 }
1254 else if (ACPI_FAILURE (Status))
1255 {
1256 return (Status);
1257 }
1258
1259 /* Update the device info header (zeros if no OEM data present) */
1260
1261 DeviceInfo->OemDataOffset = 0;
1262 DeviceInfo->OemDataLength = 0;
1263
1264 /* Optional subtable (OemData) */
1265
1266 if (Subtable && Subtable->Length)
1267 {
1268 DeviceInfo->OemDataOffset = CurrentOffset;
1269 DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
1270
1271 DtInsertSubtable (ParentTable, Subtable);
1272 }
1273 subtableDone:
1274 SubtableCount--;
1275 DtPopSubtable (); /* Get next Device Information subtable */
1276 }
1277
1278 DtPopSubtable ();
1279 return (AE_OK);
1280 }
1281
1282
1283 /******************************************************************************
1284 *
1285 * FUNCTION: DtCompileDmar
1286 *
1287 * PARAMETERS: List - Current field list pointer
1288 *
1289 * RETURN: Status
1290 *
1291 * DESCRIPTION: Compile DMAR.
1292 *
1293 *****************************************************************************/
1294
1295 ACPI_STATUS
DtCompileDmar(void ** List)1296 DtCompileDmar (
1297 void **List)
1298 {
1299 ACPI_STATUS Status;
1300 DT_SUBTABLE *Subtable;
1301 DT_SUBTABLE *ParentTable;
1302 DT_FIELD **PFieldList = (DT_FIELD **) List;
1303 DT_FIELD *SubtableStart;
1304 ACPI_DMTABLE_INFO *InfoTable;
1305 ACPI_DMAR_HEADER *DmarHeader;
1306 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
1307 UINT32 DeviceScopeLength;
1308 UINT32 PciPathLength;
1309
1310
1311 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
1312 if (ACPI_FAILURE (Status))
1313 {
1314 return (Status);
1315 }
1316
1317 ParentTable = DtPeekSubtable ();
1318 DtInsertSubtable (ParentTable, Subtable);
1319 DtPushSubtable (Subtable);
1320
1321 while (*PFieldList)
1322 {
1323 /* DMAR Header */
1324
1325 SubtableStart = *PFieldList;
1326 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
1327 &Subtable);
1328 if (ACPI_FAILURE (Status))
1329 {
1330 return (Status);
1331 }
1332
1333 ParentTable = DtPeekSubtable ();
1334 DtInsertSubtable (ParentTable, Subtable);
1335 DtPushSubtable (Subtable);
1336
1337 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
1338
1339 switch (DmarHeader->Type)
1340 {
1341 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1342
1343 InfoTable = AcpiDmTableInfoDmar0;
1344 break;
1345
1346 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1347
1348 InfoTable = AcpiDmTableInfoDmar1;
1349 break;
1350
1351 case ACPI_DMAR_TYPE_ROOT_ATS:
1352
1353 InfoTable = AcpiDmTableInfoDmar2;
1354 break;
1355
1356 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1357
1358 InfoTable = AcpiDmTableInfoDmar3;
1359 break;
1360
1361 case ACPI_DMAR_TYPE_NAMESPACE:
1362
1363 InfoTable = AcpiDmTableInfoDmar4;
1364 break;
1365
1366 case ACPI_DMAR_TYPE_SATC:
1367
1368 InfoTable = AcpiDmTableInfoDmar5;
1369 break;
1370
1371 default:
1372
1373 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
1374 return (AE_ERROR);
1375 }
1376
1377 /* DMAR Subtable */
1378
1379 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1380 if (ACPI_FAILURE (Status))
1381 {
1382 return (Status);
1383 }
1384
1385 ParentTable = DtPeekSubtable ();
1386 DtInsertSubtable (ParentTable, Subtable);
1387
1388 /*
1389 * Optional Device Scope subtables
1390 */
1391 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1392 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
1393 {
1394 /* These types do not support device scopes */
1395
1396 DtPopSubtable ();
1397 continue;
1398 }
1399
1400 DtPushSubtable (Subtable);
1401 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
1402 ParentTable->Length;
1403 while (DeviceScopeLength)
1404 {
1405 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
1406 &Subtable);
1407 if (Status == AE_NOT_FOUND)
1408 {
1409 break;
1410 }
1411
1412 ParentTable = DtPeekSubtable ();
1413 DtInsertSubtable (ParentTable, Subtable);
1414 DtPushSubtable (Subtable);
1415
1416 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
1417
1418 /* Optional PCI Paths */
1419
1420 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
1421 while (PciPathLength)
1422 {
1423 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
1424 &Subtable);
1425 if (Status == AE_NOT_FOUND)
1426 {
1427 DtPopSubtable ();
1428 break;
1429 }
1430
1431 ParentTable = DtPeekSubtable ();
1432 DtInsertSubtable (ParentTable, Subtable);
1433 PciPathLength -= Subtable->Length;
1434 }
1435
1436 DtPopSubtable ();
1437 DeviceScopeLength -= DmarDeviceScope->Length;
1438 }
1439
1440 DtPopSubtable ();
1441 DtPopSubtable ();
1442 }
1443
1444 return (AE_OK);
1445 }
1446
1447
1448 /******************************************************************************
1449 *
1450 * FUNCTION: DtCompileDrtm
1451 *
1452 * PARAMETERS: List - Current field list pointer
1453 *
1454 * RETURN: Status
1455 *
1456 * DESCRIPTION: Compile DRTM.
1457 *
1458 *****************************************************************************/
1459
1460 ACPI_STATUS
DtCompileDrtm(void ** List)1461 DtCompileDrtm (
1462 void **List)
1463 {
1464 ACPI_STATUS Status;
1465 DT_SUBTABLE *Subtable;
1466 DT_SUBTABLE *ParentTable;
1467 DT_FIELD **PFieldList = (DT_FIELD **) List;
1468 UINT32 Count;
1469 /* ACPI_TABLE_DRTM *Drtm; */
1470 ACPI_DRTM_VTABLE_LIST *DrtmVtl;
1471 ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1472 /* ACPI_DRTM_DPS_ID *DrtmDps; */
1473
1474
1475 ParentTable = DtPeekSubtable ();
1476
1477 /* Compile DRTM header */
1478
1479 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
1480 &Subtable);
1481 if (ACPI_FAILURE (Status))
1482 {
1483 return (Status);
1484 }
1485 DtInsertSubtable (ParentTable, Subtable);
1486
1487 /*
1488 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1489 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1490 */
1491 #if 0
1492 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
1493 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1494 #endif
1495 /* Compile VTL */
1496
1497 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
1498 &Subtable);
1499 if (ACPI_FAILURE (Status))
1500 {
1501 return (Status);
1502 }
1503
1504 DtInsertSubtable (ParentTable, Subtable);
1505 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
1506
1507 DtPushSubtable (Subtable);
1508 ParentTable = DtPeekSubtable ();
1509 Count = 0;
1510
1511 while (*PFieldList)
1512 {
1513 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
1514 &Subtable);
1515 if (ACPI_FAILURE (Status))
1516 {
1517 return (Status);
1518 }
1519 if (!Subtable)
1520 {
1521 break;
1522 }
1523 DtInsertSubtable (ParentTable, Subtable);
1524 Count++;
1525 }
1526
1527 DrtmVtl->ValidatedTableCount = Count;
1528 DtPopSubtable ();
1529 ParentTable = DtPeekSubtable ();
1530
1531 /* Compile RL */
1532
1533 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
1534 &Subtable);
1535 if (ACPI_FAILURE (Status))
1536 {
1537 return (Status);
1538 }
1539
1540 DtInsertSubtable (ParentTable, Subtable);
1541 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
1542
1543 DtPushSubtable (Subtable);
1544 ParentTable = DtPeekSubtable ();
1545 Count = 0;
1546
1547 while (*PFieldList)
1548 {
1549 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
1550 &Subtable);
1551 if (ACPI_FAILURE (Status))
1552 {
1553 return (Status);
1554 }
1555
1556 if (!Subtable)
1557 {
1558 break;
1559 }
1560
1561 DtInsertSubtable (ParentTable, Subtable);
1562 Count++;
1563 }
1564
1565 DrtmRl->ResourceCount = Count;
1566 DtPopSubtable ();
1567 ParentTable = DtPeekSubtable ();
1568
1569 /* Compile DPS */
1570
1571 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
1572 &Subtable);
1573 if (ACPI_FAILURE (Status))
1574 {
1575 return (Status);
1576 }
1577 DtInsertSubtable (ParentTable, Subtable);
1578 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
1579
1580
1581 return (AE_OK);
1582 }
1583
1584
1585 /******************************************************************************
1586 *
1587 * FUNCTION: DtCompileEinj
1588 *
1589 * PARAMETERS: List - Current field list pointer
1590 *
1591 * RETURN: Status
1592 *
1593 * DESCRIPTION: Compile EINJ.
1594 *
1595 *****************************************************************************/
1596
1597 ACPI_STATUS
DtCompileEinj(void ** List)1598 DtCompileEinj (
1599 void **List)
1600 {
1601 ACPI_STATUS Status;
1602
1603
1604 Status = DtCompileTwoSubtables (List,
1605 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
1606 return (Status);
1607 }
1608
1609
1610 /******************************************************************************
1611 *
1612 * FUNCTION: DtCompileErst
1613 *
1614 * PARAMETERS: List - Current field list pointer
1615 *
1616 * RETURN: Status
1617 *
1618 * DESCRIPTION: Compile ERST.
1619 *
1620 *****************************************************************************/
1621
1622 ACPI_STATUS
DtCompileErst(void ** List)1623 DtCompileErst (
1624 void **List)
1625 {
1626 ACPI_STATUS Status;
1627
1628
1629 Status = DtCompileTwoSubtables (List,
1630 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1631 return (Status);
1632 }
1633
1634
1635 /******************************************************************************
1636 *
1637 * FUNCTION: DtCompileGtdt
1638 *
1639 * PARAMETERS: List - Current field list pointer
1640 *
1641 * RETURN: Status
1642 *
1643 * DESCRIPTION: Compile GTDT.
1644 *
1645 *****************************************************************************/
1646
1647 ACPI_STATUS
DtCompileGtdt(void ** List)1648 DtCompileGtdt (
1649 void **List)
1650 {
1651 ACPI_STATUS Status;
1652 DT_SUBTABLE *Subtable;
1653 DT_SUBTABLE *ParentTable;
1654 DT_FIELD **PFieldList = (DT_FIELD **) List;
1655 DT_FIELD *SubtableStart;
1656 ACPI_SUBTABLE_HEADER *GtdtHeader;
1657 ACPI_DMTABLE_INFO *InfoTable;
1658 UINT32 GtCount;
1659 ACPI_TABLE_HEADER *Header;
1660
1661
1662 ParentTable = DtPeekSubtable ();
1663
1664 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1665
1666 /* Compile the main table */
1667
1668 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1669 &Subtable);
1670 if (ACPI_FAILURE (Status))
1671 {
1672 return (Status);
1673 }
1674
1675 /* GTDT revision 3 later contains 2 extra fields before subtables */
1676
1677 if (Header->Revision > 2)
1678 {
1679 ParentTable = DtPeekSubtable ();
1680 DtInsertSubtable (ParentTable, Subtable);
1681
1682 Status = DtCompileTable (PFieldList,
1683 AcpiDmTableInfoGtdtEl2, &Subtable);
1684 if (ACPI_FAILURE (Status))
1685 {
1686 return (Status);
1687 }
1688 }
1689
1690 ParentTable = DtPeekSubtable ();
1691 DtInsertSubtable (ParentTable, Subtable);
1692
1693 while (*PFieldList)
1694 {
1695 SubtableStart = *PFieldList;
1696 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1697 &Subtable);
1698 if (ACPI_FAILURE (Status))
1699 {
1700 return (Status);
1701 }
1702
1703 ParentTable = DtPeekSubtable ();
1704 DtInsertSubtable (ParentTable, Subtable);
1705 DtPushSubtable (Subtable);
1706
1707 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1708
1709 switch (GtdtHeader->Type)
1710 {
1711 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1712
1713 InfoTable = AcpiDmTableInfoGtdt0;
1714 break;
1715
1716 case ACPI_GTDT_TYPE_WATCHDOG:
1717
1718 InfoTable = AcpiDmTableInfoGtdt1;
1719 break;
1720
1721 default:
1722
1723 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1724 return (AE_ERROR);
1725 }
1726
1727 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1728 if (ACPI_FAILURE (Status))
1729 {
1730 return (Status);
1731 }
1732
1733 ParentTable = DtPeekSubtable ();
1734 DtInsertSubtable (ParentTable, Subtable);
1735
1736 /*
1737 * Additional GT block subtable data
1738 */
1739
1740 switch (GtdtHeader->Type)
1741 {
1742 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1743
1744 DtPushSubtable (Subtable);
1745 ParentTable = DtPeekSubtable ();
1746
1747 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1748 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1749
1750 while (GtCount)
1751 {
1752 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1753 &Subtable);
1754 if (ACPI_FAILURE (Status))
1755 {
1756 return (Status);
1757 }
1758
1759 DtInsertSubtable (ParentTable, Subtable);
1760 GtCount--;
1761 }
1762
1763 DtPopSubtable ();
1764 break;
1765
1766 default:
1767
1768 break;
1769 }
1770
1771 DtPopSubtable ();
1772 }
1773
1774 return (AE_OK);
1775 }
1776
1777
1778 /******************************************************************************
1779 *
1780 * FUNCTION: DtCompileFpdt
1781 *
1782 * PARAMETERS: List - Current field list pointer
1783 *
1784 * RETURN: Status
1785 *
1786 * DESCRIPTION: Compile FPDT.
1787 *
1788 *****************************************************************************/
1789
1790 ACPI_STATUS
DtCompileFpdt(void ** List)1791 DtCompileFpdt (
1792 void **List)
1793 {
1794 ACPI_STATUS Status;
1795 ACPI_FPDT_HEADER *FpdtHeader;
1796 DT_SUBTABLE *Subtable;
1797 DT_SUBTABLE *ParentTable;
1798 ACPI_DMTABLE_INFO *InfoTable;
1799 DT_FIELD **PFieldList = (DT_FIELD **) List;
1800 DT_FIELD *SubtableStart;
1801
1802
1803 while (*PFieldList)
1804 {
1805 SubtableStart = *PFieldList;
1806 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1807 &Subtable);
1808 if (ACPI_FAILURE (Status))
1809 {
1810 return (Status);
1811 }
1812
1813 ParentTable = DtPeekSubtable ();
1814 DtInsertSubtable (ParentTable, Subtable);
1815 DtPushSubtable (Subtable);
1816
1817 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1818
1819 switch (FpdtHeader->Type)
1820 {
1821 case ACPI_FPDT_TYPE_BOOT:
1822
1823 InfoTable = AcpiDmTableInfoFpdt0;
1824 break;
1825
1826 case ACPI_FPDT_TYPE_S3PERF:
1827
1828 InfoTable = AcpiDmTableInfoFpdt1;
1829 break;
1830
1831 default:
1832
1833 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1834 return (AE_ERROR);
1835 break;
1836 }
1837
1838 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1839 if (ACPI_FAILURE (Status))
1840 {
1841 return (Status);
1842 }
1843
1844 ParentTable = DtPeekSubtable ();
1845 DtInsertSubtable (ParentTable, Subtable);
1846 DtPopSubtable ();
1847 }
1848
1849 return (AE_OK);
1850 }
1851
1852
1853 /******************************************************************************
1854 *
1855 * FUNCTION: DtCompileHest
1856 *
1857 * PARAMETERS: List - Current field list pointer
1858 *
1859 * RETURN: Status
1860 *
1861 * DESCRIPTION: Compile HEST.
1862 *
1863 *****************************************************************************/
1864
1865 ACPI_STATUS
DtCompileHest(void ** List)1866 DtCompileHest (
1867 void **List)
1868 {
1869 ACPI_STATUS Status;
1870 DT_SUBTABLE *Subtable;
1871 DT_SUBTABLE *ParentTable;
1872 DT_FIELD **PFieldList = (DT_FIELD **) List;
1873 DT_FIELD *SubtableStart;
1874 ACPI_DMTABLE_INFO *InfoTable;
1875 UINT16 Type;
1876 UINT32 BankCount;
1877
1878
1879 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1880 &Subtable);
1881 if (ACPI_FAILURE (Status))
1882 {
1883 return (Status);
1884 }
1885
1886 ParentTable = DtPeekSubtable ();
1887 DtInsertSubtable (ParentTable, Subtable);
1888
1889 while (*PFieldList)
1890 {
1891 /* Get subtable type */
1892
1893 SubtableStart = *PFieldList;
1894 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1895
1896 switch (Type)
1897 {
1898 case ACPI_HEST_TYPE_IA32_CHECK:
1899
1900 InfoTable = AcpiDmTableInfoHest0;
1901 break;
1902
1903 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1904
1905 InfoTable = AcpiDmTableInfoHest1;
1906 break;
1907
1908 case ACPI_HEST_TYPE_IA32_NMI:
1909
1910 InfoTable = AcpiDmTableInfoHest2;
1911 break;
1912
1913 case ACPI_HEST_TYPE_AER_ROOT_PORT:
1914
1915 InfoTable = AcpiDmTableInfoHest6;
1916 break;
1917
1918 case ACPI_HEST_TYPE_AER_ENDPOINT:
1919
1920 InfoTable = AcpiDmTableInfoHest7;
1921 break;
1922
1923 case ACPI_HEST_TYPE_AER_BRIDGE:
1924
1925 InfoTable = AcpiDmTableInfoHest8;
1926 break;
1927
1928 case ACPI_HEST_TYPE_GENERIC_ERROR:
1929
1930 InfoTable = AcpiDmTableInfoHest9;
1931 break;
1932
1933 case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1934
1935 InfoTable = AcpiDmTableInfoHest10;
1936 break;
1937
1938 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1939
1940 InfoTable = AcpiDmTableInfoHest11;
1941 break;
1942
1943 default:
1944
1945 /* Cannot continue on unknown type */
1946
1947 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1948 return (AE_ERROR);
1949 }
1950
1951 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1952 if (ACPI_FAILURE (Status))
1953 {
1954 return (Status);
1955 }
1956
1957 DtInsertSubtable (ParentTable, Subtable);
1958
1959 /*
1960 * Additional subtable data - IA32 Error Bank(s)
1961 */
1962 BankCount = 0;
1963 switch (Type)
1964 {
1965 case ACPI_HEST_TYPE_IA32_CHECK:
1966
1967 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1968 Subtable->Buffer))->NumHardwareBanks;
1969 break;
1970
1971 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1972
1973 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1974 Subtable->Buffer))->NumHardwareBanks;
1975 break;
1976
1977 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1978
1979 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1980 Subtable->Buffer))->NumHardwareBanks;
1981 break;
1982
1983 default:
1984
1985 break;
1986 }
1987
1988 while (BankCount)
1989 {
1990 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1991 &Subtable);
1992 if (ACPI_FAILURE (Status))
1993 {
1994 return (Status);
1995 }
1996
1997 DtInsertSubtable (ParentTable, Subtable);
1998 BankCount--;
1999 }
2000 }
2001
2002 return (AE_OK);
2003 }
2004
2005
2006 /******************************************************************************
2007 *
2008 * FUNCTION: DtCompileHmat
2009 *
2010 * PARAMETERS: List - Current field list pointer
2011 *
2012 * RETURN: Status
2013 *
2014 * DESCRIPTION: Compile HMAT.
2015 *
2016 *****************************************************************************/
2017
2018 ACPI_STATUS
DtCompileHmat(void ** List)2019 DtCompileHmat (
2020 void **List)
2021 {
2022 ACPI_STATUS Status;
2023 DT_SUBTABLE *Subtable;
2024 DT_SUBTABLE *ParentTable;
2025 DT_FIELD **PFieldList = (DT_FIELD **) List;
2026 DT_FIELD *SubtableStart;
2027 DT_FIELD *EntryStart;
2028 ACPI_HMAT_STRUCTURE *HmatStruct;
2029 ACPI_HMAT_LOCALITY *HmatLocality;
2030 ACPI_HMAT_CACHE *HmatCache;
2031 ACPI_DMTABLE_INFO *InfoTable;
2032 UINT32 IntPDNumber;
2033 UINT32 TgtPDNumber;
2034 UINT64 EntryNumber;
2035 UINT16 SMBIOSHandleNumber;
2036
2037
2038 ParentTable = DtPeekSubtable ();
2039
2040 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
2041 &Subtable);
2042 if (ACPI_FAILURE (Status))
2043 {
2044 return (Status);
2045 }
2046 DtInsertSubtable (ParentTable, Subtable);
2047
2048 while (*PFieldList)
2049 {
2050 /* Compile HMAT structure header */
2051
2052 SubtableStart = *PFieldList;
2053 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
2054 &Subtable);
2055 if (ACPI_FAILURE (Status))
2056 {
2057 return (Status);
2058 }
2059 DtInsertSubtable (ParentTable, Subtable);
2060
2061 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
2062 HmatStruct->Length = Subtable->Length;
2063
2064 /* Compile HMAT structure body */
2065
2066 switch (HmatStruct->Type)
2067 {
2068 case ACPI_HMAT_TYPE_ADDRESS_RANGE:
2069
2070 InfoTable = AcpiDmTableInfoHmat0;
2071 break;
2072
2073 case ACPI_HMAT_TYPE_LOCALITY:
2074
2075 InfoTable = AcpiDmTableInfoHmat1;
2076 break;
2077
2078 case ACPI_HMAT_TYPE_CACHE:
2079
2080 InfoTable = AcpiDmTableInfoHmat2;
2081 break;
2082
2083 default:
2084
2085 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
2086 return (AE_ERROR);
2087 }
2088
2089 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2090 if (ACPI_FAILURE (Status))
2091 {
2092 return (Status);
2093 }
2094 DtInsertSubtable (ParentTable, Subtable);
2095 HmatStruct->Length += Subtable->Length;
2096
2097 /* Compile HMAT structure additional */
2098
2099 switch (HmatStruct->Type)
2100 {
2101 case ACPI_HMAT_TYPE_LOCALITY:
2102
2103 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
2104 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2105
2106 /* Compile initiator proximity domain list */
2107
2108 IntPDNumber = 0;
2109 while (*PFieldList)
2110 {
2111 Status = DtCompileTable (PFieldList,
2112 AcpiDmTableInfoHmat1a, &Subtable);
2113 if (ACPI_FAILURE (Status))
2114 {
2115 return (Status);
2116 }
2117 if (!Subtable)
2118 {
2119 break;
2120 }
2121 DtInsertSubtable (ParentTable, Subtable);
2122 HmatStruct->Length += Subtable->Length;
2123 IntPDNumber++;
2124 }
2125 HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
2126
2127 /* Compile target proximity domain list */
2128
2129 TgtPDNumber = 0;
2130 while (*PFieldList)
2131 {
2132 Status = DtCompileTable (PFieldList,
2133 AcpiDmTableInfoHmat1b, &Subtable);
2134 if (ACPI_FAILURE (Status))
2135 {
2136 return (Status);
2137 }
2138 if (!Subtable)
2139 {
2140 break;
2141 }
2142 DtInsertSubtable (ParentTable, Subtable);
2143 HmatStruct->Length += Subtable->Length;
2144 TgtPDNumber++;
2145 }
2146 HmatLocality->NumberOfTargetPDs = TgtPDNumber;
2147
2148 /* Save start of the entries for reporting errors */
2149
2150 EntryStart = *PFieldList;
2151
2152 /* Compile latency/bandwidth entries */
2153
2154 EntryNumber = 0;
2155 while (*PFieldList)
2156 {
2157 Status = DtCompileTable (PFieldList,
2158 AcpiDmTableInfoHmat1c, &Subtable);
2159 if (ACPI_FAILURE (Status))
2160 {
2161 return (Status);
2162 }
2163 if (!Subtable)
2164 {
2165 break;
2166 }
2167 DtInsertSubtable (ParentTable, Subtable);
2168 HmatStruct->Length += Subtable->Length;
2169 EntryNumber++;
2170 }
2171
2172 /* Validate number of entries */
2173
2174 if (EntryNumber !=
2175 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
2176 {
2177 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
2178 return (AE_ERROR);
2179 }
2180 break;
2181
2182 case ACPI_HMAT_TYPE_CACHE:
2183
2184 /* Compile SMBIOS handles */
2185
2186 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
2187 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2188 SMBIOSHandleNumber = 0;
2189 while (*PFieldList)
2190 {
2191 Status = DtCompileTable (PFieldList,
2192 AcpiDmTableInfoHmat2a, &Subtable);
2193 if (ACPI_FAILURE (Status))
2194 {
2195 return (Status);
2196 }
2197 if (!Subtable)
2198 {
2199 break;
2200 }
2201 DtInsertSubtable (ParentTable, Subtable);
2202 HmatStruct->Length += Subtable->Length;
2203 SMBIOSHandleNumber++;
2204 }
2205 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
2206 break;
2207
2208 default:
2209
2210 break;
2211 }
2212 }
2213
2214 return (AE_OK);
2215 }
2216
2217
2218 /******************************************************************************
2219 *
2220 * FUNCTION: DtCompileIort
2221 *
2222 * PARAMETERS: List - Current field list pointer
2223 *
2224 * RETURN: Status
2225 *
2226 * DESCRIPTION: Compile IORT.
2227 *
2228 *****************************************************************************/
2229
2230 ACPI_STATUS
DtCompileIort(void ** List)2231 DtCompileIort (
2232 void **List)
2233 {
2234 ACPI_STATUS Status;
2235 DT_SUBTABLE *Subtable;
2236 DT_SUBTABLE *ParentTable;
2237 DT_FIELD **PFieldList = (DT_FIELD **) List;
2238 DT_FIELD *SubtableStart;
2239 ACPI_TABLE_HEADER *Table;
2240 ACPI_TABLE_IORT *Iort;
2241 ACPI_IORT_NODE *IortNode;
2242 ACPI_IORT_ITS_GROUP *IortItsGroup;
2243 ACPI_IORT_SMMU *IortSmmu;
2244 ACPI_IORT_RMR *IortRmr;
2245 UINT32 NodeNumber;
2246 UINT32 NodeLength;
2247 UINT32 IdMappingNumber;
2248 UINT32 ItsNumber;
2249 UINT32 ContextIrptNumber;
2250 UINT32 PmuIrptNumber;
2251 UINT32 PaddingLength;
2252 UINT8 Revision;
2253 UINT32 RmrCount;
2254
2255
2256 ParentTable = DtPeekSubtable ();
2257
2258 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
2259 &Subtable);
2260 if (ACPI_FAILURE (Status))
2261 {
2262 return (Status);
2263 }
2264 DtInsertSubtable (ParentTable, Subtable);
2265
2266 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2267 Revision = Table->Revision;
2268
2269 /* IORT Revisions E, E.a & E.c have known issues and are not supported */
2270
2271 if (Revision == 1 || Revision == 2 || Revision == 4)
2272 {
2273 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
2274 return (AE_ERROR);
2275 }
2276
2277 /*
2278 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2279 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2280 */
2281 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
2282 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
2283
2284 /*
2285 * OptionalPadding - Variable-length data
2286 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
2287 * Optionally allows the generic data types to be used for filling
2288 * this field.
2289 */
2290 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
2291 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
2292 &Subtable);
2293 if (ACPI_FAILURE (Status))
2294 {
2295 return (Status);
2296 }
2297 if (Subtable)
2298 {
2299 DtInsertSubtable (ParentTable, Subtable);
2300 Iort->NodeOffset += Subtable->Length;
2301 }
2302 else
2303 {
2304 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
2305 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
2306 if (ACPI_FAILURE (Status))
2307 {
2308 return (Status);
2309 }
2310 Iort->NodeOffset += PaddingLength;
2311 }
2312
2313 NodeNumber = 0;
2314 while (*PFieldList)
2315 {
2316 SubtableStart = *PFieldList;
2317 if (Revision == 0)
2318 {
2319 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
2320 &Subtable);
2321 }
2322 else if (Revision >= 3)
2323 {
2324 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
2325 &Subtable);
2326 }
2327
2328 if (ACPI_FAILURE (Status))
2329 {
2330 return (Status);
2331 }
2332
2333 DtInsertSubtable (ParentTable, Subtable);
2334 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
2335 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
2336
2337 DtPushSubtable (Subtable);
2338 ParentTable = DtPeekSubtable ();
2339
2340 switch (IortNode->Type)
2341 {
2342 case ACPI_IORT_NODE_ITS_GROUP:
2343
2344 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
2345 &Subtable);
2346 if (ACPI_FAILURE (Status))
2347 {
2348 return (Status);
2349 }
2350
2351 DtInsertSubtable (ParentTable, Subtable);
2352 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
2353 NodeLength += Subtable->Length;
2354
2355 ItsNumber = 0;
2356 while (*PFieldList)
2357 {
2358 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
2359 &Subtable);
2360 if (ACPI_FAILURE (Status))
2361 {
2362 return (Status);
2363 }
2364 if (!Subtable)
2365 {
2366 break;
2367 }
2368
2369 DtInsertSubtable (ParentTable, Subtable);
2370 NodeLength += Subtable->Length;
2371 ItsNumber++;
2372 }
2373
2374 IortItsGroup->ItsCount = ItsNumber;
2375 break;
2376
2377 case ACPI_IORT_NODE_NAMED_COMPONENT:
2378
2379 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
2380 &Subtable);
2381 if (ACPI_FAILURE (Status))
2382 {
2383 return (Status);
2384 }
2385
2386 DtInsertSubtable (ParentTable, Subtable);
2387 NodeLength += Subtable->Length;
2388
2389 /*
2390 * Padding - Variable-length data
2391 * Optionally allows the offset of the ID mappings to be used
2392 * for filling this field.
2393 */
2394 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
2395 &Subtable);
2396 if (ACPI_FAILURE (Status))
2397 {
2398 return (Status);
2399 }
2400
2401 if (Subtable)
2402 {
2403 DtInsertSubtable (ParentTable, Subtable);
2404 NodeLength += Subtable->Length;
2405 }
2406 else
2407 {
2408 if (NodeLength > IortNode->MappingOffset)
2409 {
2410 return (AE_BAD_DATA);
2411 }
2412
2413 if (NodeLength < IortNode->MappingOffset)
2414 {
2415 Status = DtCompilePadding (
2416 IortNode->MappingOffset - NodeLength,
2417 &Subtable);
2418 if (ACPI_FAILURE (Status))
2419 {
2420 return (Status);
2421 }
2422
2423 DtInsertSubtable (ParentTable, Subtable);
2424 NodeLength = IortNode->MappingOffset;
2425 }
2426 }
2427 break;
2428
2429 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
2430
2431 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
2432 &Subtable);
2433 if (ACPI_FAILURE (Status))
2434 {
2435 return (Status);
2436 }
2437
2438 DtInsertSubtable (ParentTable, Subtable);
2439 NodeLength += Subtable->Length;
2440 break;
2441
2442 case ACPI_IORT_NODE_SMMU:
2443
2444 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
2445 &Subtable);
2446 if (ACPI_FAILURE (Status))
2447 {
2448 return (Status);
2449 }
2450
2451 DtInsertSubtable (ParentTable, Subtable);
2452 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
2453 NodeLength += Subtable->Length;
2454
2455 /* Compile global interrupt array */
2456
2457 IortSmmu->GlobalInterruptOffset = NodeLength;
2458 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
2459 &Subtable);
2460 if (ACPI_FAILURE (Status))
2461 {
2462 return (Status);
2463 }
2464
2465 DtInsertSubtable (ParentTable, Subtable);
2466 NodeLength += Subtable->Length;
2467
2468 /* Compile context interrupt array */
2469
2470 ContextIrptNumber = 0;
2471 IortSmmu->ContextInterruptOffset = NodeLength;
2472 while (*PFieldList)
2473 {
2474 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
2475 &Subtable);
2476 if (ACPI_FAILURE (Status))
2477 {
2478 return (Status);
2479 }
2480
2481 if (!Subtable)
2482 {
2483 break;
2484 }
2485
2486 DtInsertSubtable (ParentTable, Subtable);
2487 NodeLength += Subtable->Length;
2488 ContextIrptNumber++;
2489 }
2490
2491 IortSmmu->ContextInterruptCount = ContextIrptNumber;
2492
2493 /* Compile PMU interrupt array */
2494
2495 PmuIrptNumber = 0;
2496 IortSmmu->PmuInterruptOffset = NodeLength;
2497 while (*PFieldList)
2498 {
2499 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
2500 &Subtable);
2501 if (ACPI_FAILURE (Status))
2502 {
2503 return (Status);
2504 }
2505
2506 if (!Subtable)
2507 {
2508 break;
2509 }
2510
2511 DtInsertSubtable (ParentTable, Subtable);
2512 NodeLength += Subtable->Length;
2513 PmuIrptNumber++;
2514 }
2515
2516 IortSmmu->PmuInterruptCount = PmuIrptNumber;
2517 break;
2518
2519 case ACPI_IORT_NODE_SMMU_V3:
2520
2521 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
2522 &Subtable);
2523 if (ACPI_FAILURE (Status))
2524 {
2525 return (Status);
2526 }
2527
2528 DtInsertSubtable (ParentTable, Subtable);
2529 NodeLength += Subtable->Length;
2530 break;
2531
2532 case ACPI_IORT_NODE_PMCG:
2533
2534 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
2535 &Subtable);
2536 if (ACPI_FAILURE (Status))
2537 {
2538 return (Status);
2539 }
2540
2541 DtInsertSubtable (ParentTable, Subtable);
2542 NodeLength += Subtable->Length;
2543 break;
2544
2545 case ACPI_IORT_NODE_RMR:
2546
2547 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
2548 &Subtable);
2549 if (ACPI_FAILURE (Status))
2550 {
2551 return (Status);
2552 }
2553
2554 DtInsertSubtable (ParentTable, Subtable);
2555 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
2556 NodeLength += Subtable->Length;
2557
2558 /* Compile RMR Descriptors */
2559
2560 RmrCount = 0;
2561 IortRmr->RmrOffset = NodeLength;
2562 while (*PFieldList)
2563 {
2564 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
2565 &Subtable);
2566 if (ACPI_FAILURE (Status))
2567 {
2568 return (Status);
2569 }
2570
2571 if (!Subtable)
2572 {
2573 break;
2574 }
2575
2576 DtInsertSubtable (ParentTable, Subtable);
2577 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
2578 RmrCount++;
2579 }
2580
2581 IortRmr->RmrCount = RmrCount;
2582 break;
2583
2584 default:
2585
2586 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
2587 return (AE_ERROR);
2588 }
2589
2590 /* Compile Array of ID mappings */
2591
2592 IortNode->MappingOffset = NodeLength;
2593 IdMappingNumber = 0;
2594 while (*PFieldList)
2595 {
2596 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
2597 &Subtable);
2598 if (ACPI_FAILURE (Status))
2599 {
2600 return (Status);
2601 }
2602
2603 if (!Subtable)
2604 {
2605 break;
2606 }
2607
2608 DtInsertSubtable (ParentTable, Subtable);
2609 NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
2610 IdMappingNumber++;
2611 }
2612
2613 IortNode->MappingCount = IdMappingNumber;
2614 if (!IdMappingNumber)
2615 {
2616 IortNode->MappingOffset = 0;
2617 }
2618
2619 /*
2620 * Node length can be determined by DT_LENGTH option
2621 * IortNode->Length = NodeLength;
2622 */
2623 DtPopSubtable ();
2624 ParentTable = DtPeekSubtable ();
2625 NodeNumber++;
2626 }
2627
2628 Iort->NodeCount = NodeNumber;
2629 return (AE_OK);
2630 }
2631
2632
2633 /******************************************************************************
2634 *
2635 * FUNCTION: DtCompileIvrs
2636 *
2637 * PARAMETERS: List - Current field list pointer
2638 *
2639 * RETURN: Status
2640 *
2641 * DESCRIPTION: Compile IVRS. Notes:
2642 * The IVRS is essentially a flat table, with the following
2643 * structure:
2644 * <Main ACPI Table Header>
2645 * <Main subtable - virtualization info>
2646 * <IVHD>
2647 * <Device Entries>
2648 * ...
2649 * <IVHD>
2650 * <Device Entries>
2651 * <IVMD>
2652 * ...
2653 *
2654 *****************************************************************************/
2655
2656 ACPI_STATUS
DtCompileIvrs(void ** List)2657 DtCompileIvrs (
2658 void **List)
2659 {
2660 ACPI_STATUS Status;
2661 DT_SUBTABLE *Subtable;
2662 DT_SUBTABLE *ParentTable;
2663 DT_SUBTABLE *MainSubtable;
2664 DT_FIELD **PFieldList = (DT_FIELD **) List;
2665 DT_FIELD *SubtableStart;
2666 ACPI_DMTABLE_INFO *InfoTable = NULL;
2667 UINT8 SubtableType;
2668 UINT8 Temp64[16];
2669 UINT8 Temp8;
2670
2671
2672 /* Main table */
2673
2674 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
2675 &Subtable);
2676 if (ACPI_FAILURE (Status))
2677 {
2678 return (Status);
2679 }
2680
2681 ParentTable = DtPeekSubtable ();
2682 DtInsertSubtable (ParentTable, Subtable);
2683 DtPushSubtable (Subtable);
2684
2685 /* Save a pointer to the main subtable */
2686
2687 MainSubtable = Subtable;
2688
2689 while (*PFieldList)
2690 {
2691 SubtableStart = *PFieldList;
2692
2693 /* Compile the SubtableType integer */
2694
2695 DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
2696
2697 switch (SubtableType)
2698 {
2699
2700 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
2701
2702 case ACPI_IVRS_TYPE_HARDWARE1:
2703
2704 InfoTable = AcpiDmTableInfoIvrsHware1;
2705 break;
2706
2707 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
2708
2709 case ACPI_IVRS_TYPE_HARDWARE2:
2710 case ACPI_IVRS_TYPE_HARDWARE3:
2711
2712 InfoTable = AcpiDmTableInfoIvrsHware23;
2713 break;
2714
2715 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
2716
2717 case ACPI_IVRS_TYPE_MEMORY1:
2718 case ACPI_IVRS_TYPE_MEMORY2:
2719 case ACPI_IVRS_TYPE_MEMORY3:
2720
2721 InfoTable = AcpiDmTableInfoIvrsMemory;
2722 break;
2723
2724 /* 4-byte device entries */
2725
2726 case ACPI_IVRS_TYPE_PAD4:
2727 case ACPI_IVRS_TYPE_ALL:
2728 case ACPI_IVRS_TYPE_SELECT:
2729 case ACPI_IVRS_TYPE_START:
2730 case ACPI_IVRS_TYPE_END:
2731
2732 InfoTable = AcpiDmTableInfoIvrs4;
2733 break;
2734
2735 /* 8-byte device entries, type A */
2736
2737 case ACPI_IVRS_TYPE_ALIAS_SELECT:
2738 case ACPI_IVRS_TYPE_ALIAS_START:
2739
2740 InfoTable = AcpiDmTableInfoIvrs8a;
2741 break;
2742
2743 /* 8-byte device entries, type B */
2744
2745 case ACPI_IVRS_TYPE_EXT_SELECT:
2746 case ACPI_IVRS_TYPE_EXT_START:
2747
2748 InfoTable = AcpiDmTableInfoIvrs8b;
2749 break;
2750
2751 /* 8-byte device entries, type C */
2752
2753 case ACPI_IVRS_TYPE_SPECIAL:
2754
2755 InfoTable = AcpiDmTableInfoIvrs8c;
2756 break;
2757
2758 /* Variable device entries, type F0h */
2759
2760 case ACPI_IVRS_TYPE_HID:
2761
2762 InfoTable = AcpiDmTableInfoIvrsHid;
2763 break;
2764
2765 default:
2766
2767 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
2768 "IVRS Device Entry");
2769 return (AE_ERROR);
2770 }
2771
2772 /* Compile the InfoTable from above */
2773
2774 Status = DtCompileTable (PFieldList, InfoTable,
2775 &Subtable);
2776 if (ACPI_FAILURE (Status))
2777 {
2778 return (Status);
2779 }
2780
2781 ParentTable = DtPeekSubtable ();
2782 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
2783 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
2784 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
2785 SubtableType != ACPI_IVRS_TYPE_HID &&
2786 SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
2787 SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
2788 SubtableType != ACPI_IVRS_TYPE_MEMORY3)
2789 {
2790 if (ParentTable)
2791 DtInsertSubtable (ParentTable, Subtable);
2792 }
2793
2794 switch (SubtableType)
2795 {
2796 case ACPI_IVRS_TYPE_HARDWARE1:
2797 case ACPI_IVRS_TYPE_HARDWARE2:
2798 case ACPI_IVRS_TYPE_HARDWARE3:
2799 case ACPI_IVRS_TYPE_MEMORY1:
2800 case ACPI_IVRS_TYPE_MEMORY2:
2801 case ACPI_IVRS_TYPE_MEMORY3:
2802
2803 /* Insert these IVHDs/IVMDs at the root subtable */
2804
2805 DtInsertSubtable (MainSubtable, Subtable);
2806 DtPushSubtable (Subtable);
2807 break;
2808
2809 case ACPI_IVRS_TYPE_HID:
2810
2811 /* Special handling for the HID named device entry (0xF0) */
2812
2813 if (ParentTable)
2814 {
2815 DtInsertSubtable (ParentTable, Subtable);
2816 }
2817
2818 /*
2819 * Process the HID value. First, get the HID value as a string.
2820 */
2821 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2822
2823 /*
2824 * Determine if the HID is an integer or a string.
2825 * An integer is defined to be 32 bits, with the upper 32 bits
2826 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
2827 * integer or a character string. If an integer, the lower
2828 * 4 bytes of the field contain the integer and the upper
2829 * 4 bytes are padded with 0".
2830 */
2831 if (UtIsIdInteger ((UINT8 *) &Temp64))
2832 {
2833 /* Compile the HID value as an integer */
2834
2835 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2836
2837 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
2838 &Subtable);
2839 if (ACPI_FAILURE (Status))
2840 {
2841 return (Status);
2842 }
2843 }
2844 else
2845 {
2846 /* Compile the HID value as a string */
2847
2848 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
2849 &Subtable);
2850 if (ACPI_FAILURE (Status))
2851 {
2852 return (Status);
2853 }
2854 }
2855
2856 DtInsertSubtable (ParentTable, Subtable);
2857
2858 /*
2859 * Process the CID value. First, get the CID value as a string.
2860 */
2861 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2862
2863 if (UtIsIdInteger ((UINT8 *) &Temp64))
2864 {
2865 /* Compile the CID value as an integer */
2866
2867 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2868
2869 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
2870 &Subtable);
2871 if (ACPI_FAILURE (Status))
2872 {
2873 return (Status);
2874 }
2875 }
2876 else
2877 {
2878 /* Compile the CID value as a string */
2879
2880 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
2881 &Subtable);
2882 if (ACPI_FAILURE (Status))
2883 {
2884 return (Status);
2885 }
2886 }
2887
2888 DtInsertSubtable (ParentTable, Subtable);
2889
2890 /*
2891 * Process the UID value. First, get and decode the "UID Format" field (Integer).
2892 */
2893 if (!*PFieldList)
2894 {
2895 return (AE_OK);
2896 }
2897
2898 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
2899
2900 switch (Temp8)
2901 {
2902 case ACPI_IVRS_UID_NOT_PRESENT:
2903 break;
2904
2905 case ACPI_IVRS_UID_IS_INTEGER:
2906
2907 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
2908 &Subtable);
2909 if (ACPI_FAILURE (Status))
2910 {
2911 return (Status);
2912 }
2913 DtInsertSubtable (ParentTable, Subtable);
2914 break;
2915
2916 case ACPI_IVRS_UID_IS_STRING:
2917
2918 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
2919 &Subtable);
2920 if (ACPI_FAILURE (Status))
2921 {
2922 return (Status);
2923 }
2924 DtInsertSubtable (ParentTable, Subtable);
2925 break;
2926
2927 default:
2928
2929 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
2930 "IVRS Device Entry");
2931 return (AE_ERROR);
2932 }
2933
2934 default:
2935
2936 /* All other subtable types come through here */
2937 break;
2938 }
2939 }
2940
2941 return (AE_OK);
2942 }
2943