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 - 2026, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152 /* Compile all complex data tables, signatures starting with 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 ACPI_AEST_NODE_INTERFACE_HEADER *AestNodeHeader;
210 UINT8 Revision;
211 ACPI_TABLE_HEADER *Header;
212
213 ParentTable = DtPeekSubtable ();
214
215 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
216 Revision = Header->Revision;
217
218 while (*PFieldList)
219 {
220 /* Compile the common error node header */
221
222 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr,
223 &Subtable);
224 if (ACPI_FAILURE (Status))
225 {
226 return (Status);
227 }
228
229 ParentTable = DtPeekSubtable ();
230 DtInsertSubtable (ParentTable, Subtable);
231
232 /* Everything past the error node header will be a subtable */
233
234 DtPushSubtable (Subtable);
235
236 /*
237 * Compile the node-specific structure (Based on the error
238 * node header Type field)
239 */
240 ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer);
241
242 /* Point past the common error node header */
243
244 Offset = sizeof (ACPI_AEST_HEADER);
245 ErrorNodeHeader->NodeSpecificOffset = Offset;
246
247 /* Decode the error node type */
248
249 switch (ErrorNodeHeader->Type)
250 {
251 case ACPI_AEST_PROCESSOR_ERROR_NODE:
252
253 InfoTable = AcpiDmTableInfoAestProcError;
254 break;
255
256 case ACPI_AEST_MEMORY_ERROR_NODE:
257
258 InfoTable = AcpiDmTableInfoAestMemError;
259 break;
260
261 case ACPI_AEST_SMMU_ERROR_NODE:
262
263 InfoTable = AcpiDmTableInfoAestSmmuError;
264 break;
265
266 case ACPI_AEST_VENDOR_ERROR_NODE:
267 switch (Revision)
268 {
269 case 1:
270 InfoTable = AcpiDmTableInfoAestVendorError;
271 break;
272
273 case 2:
274 InfoTable = AcpiDmTableInfoAestVendorV2Error;
275 break;
276
277 default:
278 AcpiOsPrintf ("Unknown AEST Vendor Error Revision: %X\n",
279 Revision);
280 return (AE_ERROR);
281 }
282 break;
283
284 case ACPI_AEST_GIC_ERROR_NODE:
285
286 InfoTable = AcpiDmTableInfoAestGicError;
287 break;
288
289 case ACPI_AEST_PCIE_ERROR_NODE:
290
291 InfoTable = AcpiDmTableInfoAestPCIeError;
292 break;
293
294 case ACPI_AEST_PROXY_ERROR_NODE:
295
296 InfoTable = AcpiDmTableInfoAestProxyError;
297 break;
298
299 /* Error case below */
300 default:
301 AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n",
302 ErrorNodeHeader->Type);
303 return (AE_ERROR);
304 }
305
306 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
307 if (ACPI_FAILURE (Status))
308 {
309 return (Status);
310 }
311
312 /* Point past the node-specific structure */
313
314 Offset += Subtable->Length;
315 ErrorNodeHeader->NodeInterfaceOffset = Offset;
316
317 ParentTable = DtPeekSubtable ();
318 DtInsertSubtable (ParentTable, Subtable);
319
320 /* Compile any additional node-specific substructures */
321
322 if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
323 {
324 /*
325 * Special handling for PROCESSOR_ERROR_NODE subtables
326 * (to handle the Resource Substructure via the ResourceType
327 * field).
328 */
329 AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR,
330 Subtable->Buffer);
331
332 switch (AestProcessor->ResourceType)
333 {
334 case ACPI_AEST_CACHE_RESOURCE:
335
336 InfoTable = AcpiDmTableInfoAestCacheRsrc;
337 break;
338
339 case ACPI_AEST_TLB_RESOURCE:
340
341 InfoTable = AcpiDmTableInfoAestTlbRsrc;
342 break;
343
344 case ACPI_AEST_GENERIC_RESOURCE:
345
346 InfoTable = AcpiDmTableInfoAestGenRsrc;
347 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n",
348 AestProcessor->ResourceType);
349 return (AE_ERROR);
350
351 /* Error case below */
352 default:
353 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n",
354 AestProcessor->ResourceType);
355 return (AE_ERROR);
356 }
357
358 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
359 if (ACPI_FAILURE (Status))
360 {
361 return (Status);
362 }
363
364 /* Point past the resource substructure subtable */
365
366 Offset += Subtable->Length;
367 ErrorNodeHeader->NodeInterfaceOffset = Offset;
368
369 ParentTable = DtPeekSubtable ();
370 DtInsertSubtable (ParentTable, Subtable);
371 }
372
373 /* Compile the (required) node interface structure */
374 if (Revision == 1)
375 {
376 InfoTable = AcpiDmTableInfoAestXface;
377 }
378 else if (Revision == 2)
379 {
380 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXfaceHeader,
381 &Subtable);
382 if (ACPI_FAILURE (Status))
383 {
384 return (Status);
385 }
386
387 ParentTable = DtPeekSubtable ();
388 DtInsertSubtable (ParentTable, Subtable);
389
390 Offset += Subtable->Length;
391
392 AestNodeHeader = ACPI_CAST_PTR (ACPI_AEST_NODE_INTERFACE_HEADER,
393 Subtable->Buffer);
394
395 switch (AestNodeHeader->GroupFormat)
396 {
397 case ACPI_AEST_NODE_GROUP_FORMAT_4K:
398
399 InfoTable = AcpiDmTableInfoAestXface4k;
400 break;
401
402 case ACPI_AEST_NODE_GROUP_FORMAT_16K:
403
404 InfoTable = AcpiDmTableInfoAestXface16k;
405 break;
406
407 case ACPI_AEST_NODE_GROUP_FORMAT_64K:
408
409 InfoTable = AcpiDmTableInfoAestXface64k;
410 break;
411
412 /* Error case below */
413 default:
414 AcpiOsPrintf ("Unknown AEST Interface Group Format: %X\n",
415 AestNodeHeader->GroupFormat);
416 return (AE_ERROR);
417 }
418 }
419 else
420 {
421 AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision);
422 }
423
424 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
425 if (ACPI_FAILURE (Status))
426 {
427 return (Status);
428 }
429
430 ErrorNodeHeader->NodeInterruptOffset = 0;
431 ParentTable = DtPeekSubtable ();
432 DtInsertSubtable (ParentTable, Subtable);
433
434 /* Compile each of the node interrupt structures */
435
436 if (ErrorNodeHeader->NodeInterruptCount)
437 {
438 /* Point to the first interrupt structure */
439
440 Offset += Subtable->Length;
441 ErrorNodeHeader->NodeInterruptOffset = Offset;
442 }
443
444 /* Compile each of the interrupt structures */
445
446 for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++)
447 {
448 switch (Revision) {
449 case 1:
450
451 InfoTable = AcpiDmTableInfoAestXrupt;
452 break;
453
454 case 2:
455
456 InfoTable = AcpiDmTableInfoAestXruptV2;
457 break;
458
459 default:
460 AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision);
461 return (AE_ERROR);
462 }
463 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
464 if (ACPI_FAILURE (Status))
465 {
466 return (Status);
467 }
468
469 ParentTable = DtPeekSubtable ();
470 DtInsertSubtable (ParentTable, Subtable);
471 }
472
473 /* Prepare for the next AEST Error node */
474
475 DtPopSubtable ();
476 }
477
478 return (AE_OK);
479 }
480
481
482 /******************************************************************************
483 *
484 * FUNCTION: DtCompileApmt
485 *
486 * PARAMETERS: List - Current field list pointer
487 *
488 * RETURN: Status
489 *
490 * DESCRIPTION: Compile APMT.
491 *
492 *****************************************************************************/
493
494 ACPI_STATUS
DtCompileApmt(void ** List)495 DtCompileApmt (
496 void **List)
497 {
498 ACPI_STATUS Status;
499 ACPI_TABLE_HEADER *Header;
500 ACPI_APMT_NODE *ApmtNode;
501 ACPI_APMT_NODE *PeerApmtNode;
502 DT_SUBTABLE *Subtable;
503 DT_SUBTABLE *PeerSubtable;
504 DT_SUBTABLE *ParentTable;
505 DT_FIELD **PFieldList = (DT_FIELD**)List;
506 DT_FIELD *SubtableStart;
507 UINT32 CurLength;
508 char MsgBuffer[64] = "";
509
510 ParentTable = DtPeekSubtable();
511
512 Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer);
513
514 CurLength = sizeof(ACPI_TABLE_HEADER);
515
516 /* Walk the parse tree */
517
518 while (*PFieldList)
519 {
520 /* APMT Node Subtable */
521
522 SubtableStart = *PFieldList;
523
524 Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable);
525
526 if (ACPI_FAILURE(Status))
527 {
528 return (Status);
529 }
530
531 ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer);
532
533 if (ApmtNode->Length != sizeof(ACPI_APMT_NODE))
534 {
535 DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT");
536 return (AE_ERROR);
537 }
538
539 if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT)
540 {
541 snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type);
542 DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer);
543 return (AE_ERROR);
544 }
545
546 PeerSubtable = DtGetNextSubtable(ParentTable, NULL);
547
548 /* Validate the node id needs to be unique. */
549 while(PeerSubtable)
550 {
551 PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer);
552 if (PeerApmtNode->Id == ApmtNode->Id)
553 {
554 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id);
555 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer);
556 return (AE_ERROR);
557 }
558
559 PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable);
560 }
561
562 CurLength += ApmtNode->Length;
563
564 DtInsertSubtable(ParentTable, Subtable);
565 }
566
567 if (Header->Length != CurLength)
568 {
569 snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)",
570 Header->Length, CurLength);
571 DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer);
572 return (AE_ERROR);
573 }
574
575 return (AE_OK);
576 }
577
578 /******************************************************************************
579 *
580 * FUNCTION: DtCompileAsf
581 *
582 * PARAMETERS: List - Current field list pointer
583 *
584 * RETURN: Status
585 *
586 * DESCRIPTION: Compile ASF!.
587 *
588 *****************************************************************************/
589
590 ACPI_STATUS
DtCompileAsf(void ** List)591 DtCompileAsf (
592 void **List)
593 {
594 ACPI_ASF_INFO *AsfTable;
595 DT_SUBTABLE *Subtable;
596 DT_SUBTABLE *ParentTable;
597 ACPI_DMTABLE_INFO *InfoTable;
598 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
599 UINT32 DataCount = 0;
600 ACPI_STATUS Status;
601 UINT32 i;
602 DT_FIELD **PFieldList = (DT_FIELD **) List;
603 DT_FIELD *SubtableStart;
604
605
606 while (*PFieldList)
607 {
608 SubtableStart = *PFieldList;
609 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
610 &Subtable);
611 if (ACPI_FAILURE (Status))
612 {
613 return (Status);
614 }
615
616 ParentTable = DtPeekSubtable ();
617 DtInsertSubtable (ParentTable, Subtable);
618 DtPushSubtable (Subtable);
619
620 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
621
622 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
623 {
624 case ACPI_ASF_TYPE_INFO:
625
626 InfoTable = AcpiDmTableInfoAsf0;
627 break;
628
629 case ACPI_ASF_TYPE_ALERT:
630
631 InfoTable = AcpiDmTableInfoAsf1;
632 break;
633
634 case ACPI_ASF_TYPE_CONTROL:
635
636 InfoTable = AcpiDmTableInfoAsf2;
637 break;
638
639 case ACPI_ASF_TYPE_BOOT:
640
641 InfoTable = AcpiDmTableInfoAsf3;
642 break;
643
644 case ACPI_ASF_TYPE_ADDRESS:
645
646 InfoTable = AcpiDmTableInfoAsf4;
647 break;
648
649 default:
650
651 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
652 return (AE_ERROR);
653 }
654
655 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
656 if (ACPI_FAILURE (Status))
657 {
658 return (Status);
659 }
660
661 ParentTable = DtPeekSubtable ();
662 DtInsertSubtable (ParentTable, Subtable);
663
664 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
665 {
666 case ACPI_ASF_TYPE_INFO:
667
668 DataInfoTable = NULL;
669 break;
670
671 case ACPI_ASF_TYPE_ALERT:
672
673 DataInfoTable = AcpiDmTableInfoAsf1a;
674 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
675 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
676 sizeof (ACPI_ASF_HEADER)))->Alerts;
677 break;
678
679 case ACPI_ASF_TYPE_CONTROL:
680
681 DataInfoTable = AcpiDmTableInfoAsf2a;
682 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
683 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
684 sizeof (ACPI_ASF_HEADER)))->Controls;
685 break;
686
687 case ACPI_ASF_TYPE_BOOT:
688
689 DataInfoTable = NULL;
690 break;
691
692 case ACPI_ASF_TYPE_ADDRESS:
693
694 DataInfoTable = TableInfoAsfAddress;
695 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
696 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
697 sizeof (ACPI_ASF_HEADER)))->Devices;
698 break;
699
700 default:
701
702 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
703 return (AE_ERROR);
704 }
705
706 if (DataInfoTable)
707 {
708 switch (AsfTable->Header.Type & 0x7F)
709 {
710 case ACPI_ASF_TYPE_ADDRESS:
711
712 while (DataCount > 0)
713 {
714 Status = DtCompileTable (PFieldList, DataInfoTable,
715 &Subtable);
716 if (ACPI_FAILURE (Status))
717 {
718 return (Status);
719 }
720
721 DtInsertSubtable (ParentTable, Subtable);
722 DataCount = DataCount - Subtable->Length;
723 }
724 break;
725
726 default:
727
728 for (i = 0; i < DataCount; i++)
729 {
730 Status = DtCompileTable (PFieldList, DataInfoTable,
731 &Subtable);
732 if (ACPI_FAILURE (Status))
733 {
734 return (Status);
735 }
736
737 DtInsertSubtable (ParentTable, Subtable);
738 }
739 break;
740 }
741 }
742
743 DtPopSubtable ();
744 }
745
746 return (AE_OK);
747 }
748
749 /******************************************************************************
750 *
751 * FUNCTION: DtCompileAspt
752 *
753 * PARAMETERS: List - Current field list pointer
754 *
755 * RETURN: Status
756 *
757 * DESCRIPTION: Compile ASPT.
758 *
759 *****************************************************************************/
760
761 ACPI_STATUS
DtCompileAspt(void ** List)762 DtCompileAspt (
763 void **List)
764 {
765 ACPI_ASPT_HEADER *AsptTable;
766 DT_SUBTABLE *Subtable;
767 DT_SUBTABLE *ParentTable;
768 ACPI_DMTABLE_INFO *InfoTable;
769 ACPI_STATUS Status;
770 DT_FIELD **PFieldList = (DT_FIELD **) List;
771 DT_FIELD *SubtableStart;
772
773 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAspt, &Subtable);
774 if (ACPI_FAILURE (Status))
775 {
776 return (Status);
777 }
778
779 ParentTable = DtPeekSubtable ();
780 DtInsertSubtable (ParentTable, Subtable);
781
782 while (*PFieldList)
783 {
784 SubtableStart = *PFieldList;
785 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsptHdr,
786 &Subtable);
787 if (ACPI_FAILURE (Status))
788 {
789 return (Status);
790 }
791
792 ParentTable = DtPeekSubtable ();
793 DtInsertSubtable (ParentTable, Subtable);
794 DtPushSubtable (Subtable);
795
796 AsptTable = ACPI_CAST_PTR (ACPI_ASPT_HEADER, Subtable->Buffer);
797
798 switch (AsptTable->Type) /* Mask off top bit */
799 {
800 case ACPI_ASPT_TYPE_GLOBAL_REGS:
801
802 InfoTable = AcpiDmTableInfoAspt0;
803 break;
804
805 case ACPI_ASPT_TYPE_SEV_MBOX_REGS:
806
807 InfoTable = AcpiDmTableInfoAspt1;
808 break;
809
810 case ACPI_ASPT_TYPE_ACPI_MBOX_REGS:
811
812 InfoTable = AcpiDmTableInfoAspt2;
813 break;
814
815 default:
816
817 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASPT");
818 return (AE_ERROR);
819 }
820
821 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
822 if (ACPI_FAILURE (Status))
823 {
824 return (Status);
825 }
826 ParentTable = DtPeekSubtable ();
827 DtInsertSubtable (ParentTable, Subtable);
828 DtPopSubtable ();
829 }
830
831 return (AE_OK);
832 }
833
834
835 /******************************************************************************
836 *
837 * FUNCTION: DtCompileCdat
838 *
839 * PARAMETERS: List - Current field list pointer
840 *
841 * RETURN: Status
842 *
843 * DESCRIPTION: Compile CDAT.
844 *
845 *****************************************************************************/
846
847 ACPI_STATUS
DtCompileCdat(void ** List)848 DtCompileCdat (
849 void **List)
850 {
851 ACPI_STATUS Status = AE_OK;
852 DT_SUBTABLE *Subtable;
853 DT_SUBTABLE *ParentTable;
854 DT_FIELD **PFieldList = (DT_FIELD **) List;
855 ACPI_CDAT_HEADER *CdatHeader;
856 ACPI_DMTABLE_INFO *InfoTable = NULL;
857 DT_FIELD *SubtableStart;
858
859
860 /* Walk the parse tree.
861 *
862 * Note: Main table consists of only the CDAT table header
863 * (This is not the standard ACPI table header, however)--
864 * Followed by some number of subtables.
865 */
866 while (*PFieldList)
867 {
868 SubtableStart = *PFieldList;
869
870 /* Compile the expected CDAT Subtable header */
871
872 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader,
873 &Subtable);
874 if (ACPI_FAILURE (Status))
875 {
876 return (Status);
877 }
878
879 ParentTable = DtPeekSubtable ();
880 DtInsertSubtable (ParentTable, Subtable);
881 DtPushSubtable (Subtable);
882
883 CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer);
884
885 /* Decode the subtable by type */
886
887 switch (CdatHeader->Type)
888 {
889 case ACPI_CDAT_TYPE_DSMAS:
890 InfoTable = AcpiDmTableInfoCdat0;
891 break;
892
893 case ACPI_CDAT_TYPE_DSLBIS:
894 InfoTable = AcpiDmTableInfoCdat1;
895 break;
896
897 case ACPI_CDAT_TYPE_DSMSCIS:
898 InfoTable = AcpiDmTableInfoCdat2;
899 break;
900
901 case ACPI_CDAT_TYPE_DSIS:
902 InfoTable = AcpiDmTableInfoCdat3;
903 break;
904
905 case ACPI_CDAT_TYPE_DSEMTS:
906 InfoTable = AcpiDmTableInfoCdat4;
907 break;
908
909 case ACPI_CDAT_TYPE_SSLBIS:
910 InfoTable = AcpiDmTableInfoCdat5;
911 break;
912
913 default:
914 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT");
915 }
916
917 /* Compile the CDAT subtable */
918
919 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
920 if (ACPI_FAILURE (Status))
921 {
922 return (Status);
923 }
924
925 ParentTable = DtPeekSubtable ();
926 DtInsertSubtable (ParentTable, Subtable);
927
928 switch (CdatHeader->Type)
929 {
930 /* Multiple entries supported for this type */
931
932 case ACPI_CDAT_TYPE_SSLBIS:
933
934 /*
935 * Check for multiple SSLBEs
936 */
937 while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID"))
938 {
939 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable);
940 if (ACPI_FAILURE (Status))
941 {
942 return (Status);
943 }
944 ParentTable = DtPeekSubtable ();
945 DtInsertSubtable (ParentTable, Subtable);
946 }
947 break;
948
949 default:
950 break;
951 }
952
953 /* Pop off the CDAT Subtable header subtree */
954
955 DtPopSubtable ();
956 }
957
958 return (AE_OK);
959 }
960
961
962 /******************************************************************************
963 *
964 * FUNCTION: DtCompileCedt
965 *
966 * PARAMETERS: List - Current field list pointer
967 *
968 * RETURN: Status
969 *
970 * DESCRIPTION: Compile CEDT.
971 *
972 *****************************************************************************/
973
974 ACPI_STATUS
DtCompileCedt(void ** List)975 DtCompileCedt (
976 void **List)
977 {
978 ACPI_STATUS Status;
979 DT_SUBTABLE *Subtable;
980 DT_SUBTABLE *ParentTable;
981 DT_FIELD **PFieldList = (DT_FIELD **) List;
982 ACPI_CEDT_HEADER *CedtHeader;
983 DT_FIELD *SubtableStart;
984
985
986 /* Walk the parse tree */
987
988 while (*PFieldList)
989 {
990 /* if CFMWS and has more than one target, then set to zero later */
991
992 int InsertFlag = 1;
993 SubtableStart = *PFieldList;
994
995 /* CEDT Header */
996
997 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
998 &Subtable);
999 if (ACPI_FAILURE (Status))
1000 {
1001 return (Status);
1002 }
1003
1004 ParentTable = DtPeekSubtable ();
1005 DtInsertSubtable (ParentTable, Subtable);
1006 DtPushSubtable (Subtable);
1007
1008 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
1009
1010 switch (CedtHeader->Type)
1011 {
1012 case ACPI_CEDT_TYPE_CHBS:
1013 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
1014 if (ACPI_FAILURE (Status))
1015 {
1016 return (Status);
1017 }
1018 break;
1019 case ACPI_CEDT_TYPE_CFMWS: {
1020 unsigned char *dump;
1021 unsigned int idx, offset, max = 0;
1022
1023 /* Compile table with first "Interleave target" */
1024
1025 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable);
1026 if (ACPI_FAILURE (Status))
1027 {
1028 return (Status);
1029 }
1030
1031 /* Look in buffer for the number of targets */
1032 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays);
1033 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt1 */
1034 max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */
1035 if (max > 8) max=1; /* Error in encoding Interleaving Ways. */
1036 if (max == 1) /* if only one target, then break here. */
1037 break; /* break if only one target. */
1038
1039 /* We need to add more interleave targets, so write the current Subtable. */
1040
1041 ParentTable = DtPeekSubtable ();
1042 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt1 table so we can put in */
1043 DtPushSubtable (Subtable); /* the targets > the first. */
1044
1045 /* Now, find out all interleave targets beyond the first. */
1046
1047 for (idx = 1; idx < max; idx++) {
1048 ParentTable = DtPeekSubtable ();
1049
1050 if (*PFieldList)
1051 {
1052 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable);
1053 if (ACPI_FAILURE (Status))
1054 {
1055 return (Status);
1056 }
1057 if (Subtable)
1058 {
1059 DtInsertSubtable (ParentTable, Subtable); /* got a target, so insert table. */
1060 InsertFlag = 0;
1061 }
1062 }
1063 }
1064
1065 DtPopSubtable ();
1066 ParentTable = DtPeekSubtable ();
1067 break;
1068 }
1069 case ACPI_CEDT_TYPE_CXIMS: {
1070 unsigned char *dump;
1071 unsigned int idx, offset, max = 0;
1072
1073 /* Compile table with first "Xor map" */
1074
1075 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2, &Subtable);
1076 if (ACPI_FAILURE (Status))
1077 {
1078 return (Status);
1079 }
1080
1081 /* Look in buffer for the number of Xor maps */
1082 offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CXIMS, NrXormaps);
1083 dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt2 */
1084 max = dump[offset];
1085
1086 /* We need to add more XOR maps, so write the current Subtable. */
1087
1088 ParentTable = DtPeekSubtable ();
1089 DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt2 table so we can put in */
1090 DtPushSubtable (Subtable);
1091
1092 /* Now, find out all Xor maps beyond the first. */
1093
1094 for (idx = 1; idx < max; idx++) {
1095 ParentTable = DtPeekSubtable ();
1096
1097 if (*PFieldList)
1098 {
1099 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2_te, &Subtable);
1100 if (ACPI_FAILURE (Status))
1101 {
1102 return (Status);
1103 }
1104 if (Subtable)
1105 {
1106 DtInsertSubtable (ParentTable, Subtable); /* got an Xor map, so insert table. */
1107 InsertFlag = 0;
1108 }
1109 }
1110 }
1111
1112 DtPopSubtable ();
1113 ParentTable = DtPeekSubtable ();
1114 break;
1115 }
1116
1117 default:
1118 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
1119 return (AE_ERROR);
1120 }
1121
1122 ParentTable = DtPeekSubtable ();
1123 if (InsertFlag == 1) {
1124 DtInsertSubtable (ParentTable, Subtable);
1125 }
1126 DtPopSubtable ();
1127 }
1128
1129 return (AE_OK);
1130 }
1131
1132
1133 /******************************************************************************
1134 *
1135 * FUNCTION: DtCompileCpep
1136 *
1137 * PARAMETERS: List - Current field list pointer
1138 *
1139 * RETURN: Status
1140 *
1141 * DESCRIPTION: Compile CPEP.
1142 *
1143 *****************************************************************************/
1144
1145 ACPI_STATUS
DtCompileCpep(void ** List)1146 DtCompileCpep (
1147 void **List)
1148 {
1149 ACPI_STATUS Status;
1150
1151
1152 Status = DtCompileTwoSubtables (List,
1153 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
1154 return (Status);
1155 }
1156
1157
1158 /******************************************************************************
1159 *
1160 * FUNCTION: DtCompileCsrt
1161 *
1162 * PARAMETERS: List - Current field list pointer
1163 *
1164 * RETURN: Status
1165 *
1166 * DESCRIPTION: Compile CSRT.
1167 *
1168 *****************************************************************************/
1169
1170 ACPI_STATUS
DtCompileCsrt(void ** List)1171 DtCompileCsrt (
1172 void **List)
1173 {
1174 ACPI_STATUS Status = AE_OK;
1175 DT_SUBTABLE *Subtable;
1176 DT_SUBTABLE *ParentTable;
1177 DT_FIELD **PFieldList = (DT_FIELD **) List;
1178 UINT32 DescriptorCount;
1179 UINT32 GroupLength;
1180
1181
1182 /* Subtables (Resource Groups) */
1183
1184 ParentTable = DtPeekSubtable ();
1185 while (*PFieldList)
1186 {
1187 /* Resource group subtable */
1188
1189 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
1190 &Subtable);
1191 if (ACPI_FAILURE (Status))
1192 {
1193 return (Status);
1194 }
1195
1196 /* Compute the number of resource descriptors */
1197
1198 GroupLength =
1199 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
1200 Subtable->Buffer))->Length -
1201 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
1202 Subtable->Buffer))->SharedInfoLength -
1203 sizeof (ACPI_CSRT_GROUP);
1204
1205 DescriptorCount = (GroupLength /
1206 sizeof (ACPI_CSRT_DESCRIPTOR));
1207
1208 DtInsertSubtable (ParentTable, Subtable);
1209 DtPushSubtable (Subtable);
1210 ParentTable = DtPeekSubtable ();
1211
1212 /* Shared info subtable (One per resource group) */
1213
1214 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
1215 &Subtable);
1216 if (ACPI_FAILURE (Status))
1217 {
1218 return (Status);
1219 }
1220
1221 DtInsertSubtable (ParentTable, Subtable);
1222
1223 /* Sub-Subtables (Resource Descriptors) */
1224
1225 while (*PFieldList && DescriptorCount)
1226 {
1227
1228 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
1229 &Subtable);
1230 if (ACPI_FAILURE (Status))
1231 {
1232 return (Status);
1233 }
1234
1235 DtInsertSubtable (ParentTable, Subtable);
1236
1237 DtPushSubtable (Subtable);
1238 ParentTable = DtPeekSubtable ();
1239 if (*PFieldList)
1240 {
1241 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
1242 &Subtable);
1243 if (ACPI_FAILURE (Status))
1244 {
1245 return (Status);
1246 }
1247 if (Subtable)
1248 {
1249 DtInsertSubtable (ParentTable, Subtable);
1250 }
1251 }
1252
1253 DtPopSubtable ();
1254 ParentTable = DtPeekSubtable ();
1255 DescriptorCount--;
1256 }
1257
1258 DtPopSubtable ();
1259 ParentTable = DtPeekSubtable ();
1260 }
1261
1262 return (Status);
1263 }
1264
1265
1266 /******************************************************************************
1267 *
1268 * FUNCTION: DtCompileDbg2
1269 *
1270 * PARAMETERS: List - Current field list pointer
1271 *
1272 * RETURN: Status
1273 *
1274 * DESCRIPTION: Compile DBG2.
1275 *
1276 *****************************************************************************/
1277
1278 ACPI_STATUS
DtCompileDbg2(void ** List)1279 DtCompileDbg2 (
1280 void **List)
1281 {
1282 ACPI_STATUS Status;
1283 DT_SUBTABLE *Subtable;
1284 DT_SUBTABLE *ParentTable;
1285 DT_FIELD **PFieldList = (DT_FIELD **) List;
1286 UINT32 SubtableCount;
1287 ACPI_DBG2_HEADER *Dbg2Header;
1288 ACPI_DBG2_DEVICE *DeviceInfo;
1289 UINT16 CurrentOffset;
1290 UINT32 i;
1291
1292
1293 /* Main table */
1294
1295 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
1296 if (ACPI_FAILURE (Status))
1297 {
1298 return (Status);
1299 }
1300
1301 ParentTable = DtPeekSubtable ();
1302 DtInsertSubtable (ParentTable, Subtable);
1303
1304 /* Main table fields */
1305
1306 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
1307 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
1308 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
1309
1310 SubtableCount = Dbg2Header->InfoCount;
1311 DtPushSubtable (Subtable);
1312
1313 /* Process all Device Information subtables (Count = InfoCount) */
1314
1315 while (*PFieldList && SubtableCount)
1316 {
1317 /* Subtable: Debug Device Information */
1318
1319 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
1320 &Subtable);
1321 if (ACPI_FAILURE (Status))
1322 {
1323 return (Status);
1324 }
1325
1326 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
1327 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
1328
1329 ParentTable = DtPeekSubtable ();
1330 DtInsertSubtable (ParentTable, Subtable);
1331 DtPushSubtable (Subtable);
1332
1333 ParentTable = DtPeekSubtable ();
1334
1335 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
1336
1337 DeviceInfo->BaseAddressOffset = CurrentOffset;
1338 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
1339 {
1340 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
1341 &Subtable);
1342 if (ACPI_FAILURE (Status))
1343 {
1344 return (Status);
1345 }
1346
1347 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
1348 DtInsertSubtable (ParentTable, Subtable);
1349 }
1350
1351 /* AddressSize array (Required, size = RegisterCount) */
1352
1353 DeviceInfo->AddressSizeOffset = CurrentOffset;
1354 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
1355 {
1356 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
1357 &Subtable);
1358 if (ACPI_FAILURE (Status))
1359 {
1360 return (Status);
1361 }
1362
1363 CurrentOffset += (UINT16) sizeof (UINT32);
1364 DtInsertSubtable (ParentTable, Subtable);
1365 }
1366
1367 /* NamespaceString device identifier (Required, size = NamePathLength) */
1368
1369 DeviceInfo->NamepathOffset = CurrentOffset;
1370 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
1371 &Subtable);
1372 if (ACPI_FAILURE (Status))
1373 {
1374 return (Status);
1375 }
1376
1377 /* Update the device info header */
1378
1379 DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
1380 CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
1381 DtInsertSubtable (ParentTable, Subtable);
1382
1383 /* OemData - Variable-length data (Optional, size = OemDataLength) */
1384
1385 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
1386 &Subtable);
1387 if (Status == AE_END_OF_TABLE)
1388 {
1389 /* optional field was not found and we're at the end of the file */
1390
1391 goto subtableDone;
1392 }
1393 else if (ACPI_FAILURE (Status))
1394 {
1395 return (Status);
1396 }
1397
1398 /* Update the device info header (zeros if no OEM data present) */
1399
1400 DeviceInfo->OemDataOffset = 0;
1401 DeviceInfo->OemDataLength = 0;
1402
1403 /* Optional subtable (OemData) */
1404
1405 if (Subtable && Subtable->Length)
1406 {
1407 DeviceInfo->OemDataOffset = CurrentOffset;
1408 DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
1409
1410 DtInsertSubtable (ParentTable, Subtable);
1411 }
1412 subtableDone:
1413 SubtableCount--;
1414 DtPopSubtable (); /* Get next Device Information subtable */
1415 }
1416
1417 DtPopSubtable ();
1418 return (AE_OK);
1419 }
1420
1421
1422 /******************************************************************************
1423 *
1424 * FUNCTION: DtCompileDmar
1425 *
1426 * PARAMETERS: List - Current field list pointer
1427 *
1428 * RETURN: Status
1429 *
1430 * DESCRIPTION: Compile DMAR.
1431 *
1432 *****************************************************************************/
1433
1434 ACPI_STATUS
DtCompileDmar(void ** List)1435 DtCompileDmar (
1436 void **List)
1437 {
1438 ACPI_STATUS Status;
1439 DT_SUBTABLE *Subtable;
1440 DT_SUBTABLE *ParentTable;
1441 DT_FIELD **PFieldList = (DT_FIELD **) List;
1442 DT_FIELD *SubtableStart;
1443 ACPI_DMTABLE_INFO *InfoTable;
1444 ACPI_DMAR_HEADER *DmarHeader;
1445 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
1446 UINT32 DeviceScopeLength;
1447 UINT32 PciPathLength;
1448
1449
1450 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
1451 if (ACPI_FAILURE (Status))
1452 {
1453 return (Status);
1454 }
1455
1456 ParentTable = DtPeekSubtable ();
1457 DtInsertSubtable (ParentTable, Subtable);
1458 DtPushSubtable (Subtable);
1459
1460 while (*PFieldList)
1461 {
1462 /* DMAR Header */
1463
1464 SubtableStart = *PFieldList;
1465 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
1466 &Subtable);
1467 if (ACPI_FAILURE (Status))
1468 {
1469 return (Status);
1470 }
1471
1472 ParentTable = DtPeekSubtable ();
1473 DtInsertSubtable (ParentTable, Subtable);
1474 DtPushSubtable (Subtable);
1475
1476 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
1477
1478 switch (DmarHeader->Type)
1479 {
1480 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1481
1482 InfoTable = AcpiDmTableInfoDmar0;
1483 break;
1484
1485 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1486
1487 InfoTable = AcpiDmTableInfoDmar1;
1488 break;
1489
1490 case ACPI_DMAR_TYPE_ROOT_ATS:
1491
1492 InfoTable = AcpiDmTableInfoDmar2;
1493 break;
1494
1495 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1496
1497 InfoTable = AcpiDmTableInfoDmar3;
1498 break;
1499
1500 case ACPI_DMAR_TYPE_NAMESPACE:
1501
1502 InfoTable = AcpiDmTableInfoDmar4;
1503 break;
1504
1505 case ACPI_DMAR_TYPE_SATC:
1506
1507 InfoTable = AcpiDmTableInfoDmar5;
1508 break;
1509
1510 case ACPI_DMAR_TYPE_SIDP:
1511
1512 InfoTable = AcpiDmTableInfoDmar6;
1513 break;
1514
1515 default:
1516
1517 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
1518 return (AE_ERROR);
1519 }
1520
1521 /* DMAR Subtable */
1522
1523 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1524 if (ACPI_FAILURE (Status))
1525 {
1526 return (Status);
1527 }
1528
1529 ParentTable = DtPeekSubtable ();
1530 DtInsertSubtable (ParentTable, Subtable);
1531
1532 /*
1533 * Optional Device Scope subtables
1534 */
1535 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1536 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
1537 {
1538 /* These types do not support device scopes */
1539
1540 DtPopSubtable ();
1541 continue;
1542 }
1543
1544 DtPushSubtable (Subtable);
1545 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
1546 ParentTable->Length;
1547 while (DeviceScopeLength)
1548 {
1549 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
1550 &Subtable);
1551 if (Status == AE_NOT_FOUND)
1552 {
1553 break;
1554 }
1555
1556 ParentTable = DtPeekSubtable ();
1557 DtInsertSubtable (ParentTable, Subtable);
1558 DtPushSubtable (Subtable);
1559
1560 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
1561
1562 /* Optional PCI Paths */
1563
1564 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
1565 while (PciPathLength)
1566 {
1567 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
1568 &Subtable);
1569 if (Status == AE_NOT_FOUND)
1570 {
1571 DtPopSubtable ();
1572 break;
1573 }
1574
1575 ParentTable = DtPeekSubtable ();
1576 DtInsertSubtable (ParentTable, Subtable);
1577 PciPathLength -= Subtable->Length;
1578 }
1579
1580 DtPopSubtable ();
1581 DeviceScopeLength -= DmarDeviceScope->Length;
1582 }
1583
1584 DtPopSubtable ();
1585 DtPopSubtable ();
1586 }
1587
1588 return (AE_OK);
1589 }
1590
1591
1592 /******************************************************************************
1593 *
1594 * FUNCTION: DtCompileDrtm
1595 *
1596 * PARAMETERS: List - Current field list pointer
1597 *
1598 * RETURN: Status
1599 *
1600 * DESCRIPTION: Compile DRTM.
1601 *
1602 *****************************************************************************/
1603
1604 ACPI_STATUS
DtCompileDrtm(void ** List)1605 DtCompileDrtm (
1606 void **List)
1607 {
1608 ACPI_STATUS Status;
1609 DT_SUBTABLE *Subtable;
1610 DT_SUBTABLE *ParentTable;
1611 DT_FIELD **PFieldList = (DT_FIELD **) List;
1612 UINT32 Count;
1613 /* ACPI_TABLE_DRTM *Drtm; */
1614 ACPI_DRTM_VTABLE_LIST *DrtmVtl;
1615 ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1616 /* ACPI_DRTM_DPS_ID *DrtmDps; */
1617
1618
1619 ParentTable = DtPeekSubtable ();
1620
1621 /* Compile DRTM header */
1622
1623 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
1624 &Subtable);
1625 if (ACPI_FAILURE (Status))
1626 {
1627 return (Status);
1628 }
1629 DtInsertSubtable (ParentTable, Subtable);
1630
1631 /*
1632 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1633 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1634 */
1635 #if 0
1636 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
1637 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1638 #endif
1639 /* Compile VTL */
1640
1641 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
1642 &Subtable);
1643 if (ACPI_FAILURE (Status))
1644 {
1645 return (Status);
1646 }
1647
1648 DtInsertSubtable (ParentTable, Subtable);
1649 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
1650
1651 DtPushSubtable (Subtable);
1652 ParentTable = DtPeekSubtable ();
1653 Count = 0;
1654
1655 while (*PFieldList)
1656 {
1657 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
1658 &Subtable);
1659 if (ACPI_FAILURE (Status))
1660 {
1661 return (Status);
1662 }
1663 if (!Subtable)
1664 {
1665 break;
1666 }
1667 DtInsertSubtable (ParentTable, Subtable);
1668 Count++;
1669 }
1670
1671 DrtmVtl->ValidatedTableCount = Count;
1672 DtPopSubtable ();
1673 ParentTable = DtPeekSubtable ();
1674
1675 /* Compile RL */
1676
1677 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
1678 &Subtable);
1679 if (ACPI_FAILURE (Status))
1680 {
1681 return (Status);
1682 }
1683
1684 DtInsertSubtable (ParentTable, Subtable);
1685 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
1686
1687 DtPushSubtable (Subtable);
1688 ParentTable = DtPeekSubtable ();
1689 Count = 0;
1690
1691 while (*PFieldList)
1692 {
1693 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
1694 &Subtable);
1695 if (ACPI_FAILURE (Status))
1696 {
1697 return (Status);
1698 }
1699
1700 if (!Subtable)
1701 {
1702 break;
1703 }
1704
1705 DtInsertSubtable (ParentTable, Subtable);
1706 Count++;
1707 }
1708
1709 DrtmRl->ResourceCount = Count;
1710 DtPopSubtable ();
1711 ParentTable = DtPeekSubtable ();
1712
1713 /* Compile DPS */
1714
1715 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
1716 &Subtable);
1717 if (ACPI_FAILURE (Status))
1718 {
1719 return (Status);
1720 }
1721 DtInsertSubtable (ParentTable, Subtable);
1722 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
1723
1724
1725 return (AE_OK);
1726 }
1727
1728
1729 /******************************************************************************
1730 *
1731 * FUNCTION: DtCompileDtpr
1732 *
1733 * PARAMETERS: List - Current field list pointer
1734 *
1735 * RETURN: Status
1736 *
1737 * DESCRIPTION: Compile DTPR.
1738 *
1739 *****************************************************************************/
1740
1741 ACPI_STATUS
DtCompileDtpr(void ** List)1742 DtCompileDtpr (
1743 void **List)
1744 {
1745 ACPI_STATUS Status;
1746 DT_SUBTABLE *Subtable;
1747 DT_SUBTABLE *ParentTable;
1748 DT_FIELD **PFieldList = (DT_FIELD **) List;
1749 ACPI_TABLE_DTPR *Dtpr;
1750 ACPI_TPR_INSTANCE *TprInst;
1751 UINT32 i, InsCnt, SrlCnt, TprCnt;
1752
1753
1754 ParentTable = DtPeekSubtable ();
1755
1756 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtpr, &Subtable);
1757 if (ACPI_FAILURE (Status))
1758 {
1759 return (Status);
1760 }
1761
1762 DtInsertSubtable (ParentTable, Subtable);
1763
1764 Dtpr = ACPI_SUB_PTR (ACPI_TABLE_DTPR, Subtable->Buffer,
1765 sizeof (ACPI_TABLE_HEADER));
1766 if (!Dtpr)
1767 {
1768 AcpiOsPrintf ("DTPR buffer pointer is NULL\n");
1769 return (AE_NULL_OBJECT);
1770 }
1771
1772 InsCnt = Dtpr->InsCnt;
1773
1774 while (*PFieldList)
1775 {
1776 for (i = 0; i < InsCnt; i++)
1777 {
1778 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprInstance,
1779 &Subtable);
1780 if (ACPI_FAILURE (Status))
1781 {
1782 return (Status);
1783 }
1784
1785 TprInst = ACPI_CAST_PTR (ACPI_TPR_INSTANCE, Subtable->Buffer);
1786 if (!TprInst)
1787 {
1788 AcpiOsPrintf ("Tpr Instance buffer pointer is NULL\n");
1789 return (AE_NULL_OBJECT);
1790 }
1791
1792 TprCnt = TprInst->TprCnt;
1793 DtInsertSubtable (ParentTable, Subtable);
1794 DtPushSubtable (Subtable);
1795 ParentTable = DtPeekSubtable ();
1796
1797 while (*PFieldList && TprCnt)
1798 {
1799 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprArr,
1800 &Subtable);
1801 if (ACPI_FAILURE (Status))
1802 {
1803 return (Status);
1804 }
1805
1806 DtInsertSubtable (ParentTable, Subtable);
1807 TprCnt--;
1808 }
1809
1810 DtPopSubtable();
1811 ParentTable = DtPeekSubtable ();
1812 }
1813
1814 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprSerializeReq0,
1815 &Subtable);
1816 if (ACPI_FAILURE (Status))
1817 {
1818 return (Status);
1819 }
1820
1821 SrlCnt = *ACPI_CAST_PTR(UINT32, Subtable->Buffer);
1822 DtInsertSubtable (ParentTable, Subtable);
1823 DtPushSubtable (Subtable);
1824 ParentTable = DtPeekSubtable ();
1825
1826 while (*PFieldList && SrlCnt)
1827 {
1828 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDtprSerializeReq1,
1829 &Subtable);
1830 if (ACPI_FAILURE (Status))
1831 {
1832 return (Status);
1833 }
1834
1835 DtInsertSubtable (ParentTable, Subtable);
1836 SrlCnt--;
1837 }
1838
1839
1840 DtPopSubtable();
1841 ParentTable = DtPeekSubtable ();
1842 }
1843
1844 return Status;
1845 }
1846
1847 /******************************************************************************
1848 *
1849 * FUNCTION: DtCompileEinj
1850 *
1851 * PARAMETERS: List - Current field list pointer
1852 *
1853 * RETURN: Status
1854 *
1855 * DESCRIPTION: Compile EINJ.
1856 *
1857 *****************************************************************************/
1858
1859 ACPI_STATUS
DtCompileEinj(void ** List)1860 DtCompileEinj (
1861 void **List)
1862 {
1863 ACPI_STATUS Status;
1864
1865
1866 Status = DtCompileTwoSubtables (List,
1867 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
1868 return (Status);
1869 }
1870
1871
1872 /******************************************************************************
1873 *
1874 * FUNCTION: DtCompileErdt
1875 *
1876 * PARAMETERS: List - Current field list pointer
1877 *
1878 * RETURN: Status
1879 *
1880 * DESCRIPTION: Compile ERST. Complex table with subtables and subsubtables.
1881 *
1882 *****************************************************************************/
1883
1884 ACPI_STATUS
DtCompileErdt(void ** List)1885 DtCompileErdt (
1886 void **List)
1887 {
1888 ACPI_STATUS Status;
1889 DT_SUBTABLE *Subtable, *RmddSubtable = NULL, *Subsubtable;
1890 DT_SUBTABLE *ParentTable;
1891 DT_FIELD **PFieldList = (DT_FIELD **) List;
1892 DT_FIELD *SubtableStart;
1893 ACPI_SUBTBL_HDR_16 *ErdtHeader;
1894 ACPI_DMTABLE_INFO *InfoTable;
1895 ACPI_ERDT_MMRC *Mmrc;
1896 ACPI_ERDT_IBRD *Ibrd;
1897 UINT32 NumEntries;
1898 BOOLEAN SeenRmdd = FALSE;
1899 BOOLEAN SeenSubtable = FALSE;
1900
1901 Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdt,
1902 &Subtable);
1903 if (ACPI_FAILURE (Status))
1904 {
1905 return (Status);
1906 }
1907
1908 ParentTable = DtPeekSubtable ();
1909 DtInsertSubtable (ParentTable, Subtable);
1910
1911 while (*PFieldList)
1912 {
1913 SubtableStart = *PFieldList;
1914 Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdtHdr,
1915 &Subtable);
1916 if (ACPI_FAILURE (Status))
1917 {
1918 return (Status);
1919 }
1920
1921 ErdtHeader = ACPI_CAST_PTR (ACPI_SUBTBL_HDR_16, Subtable->Buffer);
1922
1923 /* RMDD tables at top level. All others are subtables of preceeding RMDD */
1924 if (ErdtHeader->Type == ACPI_ERDT_TYPE_RMDD)
1925 {
1926 if (SeenRmdd && SeenSubtable)
1927 DtPopSubtable ();
1928 SeenRmdd = TRUE;
1929 SeenSubtable = FALSE;
1930 RmddSubtable = Subtable;
1931 }
1932 else
1933 {
1934 if (!SeenSubtable)
1935 {
1936 DtPushSubtable (RmddSubtable);
1937 SeenSubtable = TRUE;
1938 }
1939 }
1940
1941 ParentTable = DtPeekSubtable ();
1942 DtInsertSubtable (ParentTable, Subtable);
1943 DtPushSubtable (Subtable);
1944
1945 switch (ErdtHeader->Type)
1946 {
1947 case ACPI_ERDT_TYPE_RMDD:
1948 InfoTable = AcpiDmTableInfoErdtRmdd;
1949 break;
1950
1951 case ACPI_ERDT_TYPE_CACD:
1952 InfoTable = AcpiDmTableInfoErdtCacd;
1953 break;
1954
1955 case ACPI_ERDT_TYPE_DACD:
1956 InfoTable = AcpiDmTableInfoErdtDacd;
1957 break;
1958
1959 case ACPI_ERDT_TYPE_CMRC:
1960 InfoTable = AcpiDmTableInfoErdtCmrc;
1961 break;
1962
1963 case ACPI_ERDT_TYPE_MMRC:
1964 InfoTable = AcpiDmTableInfoErdtMmrc;
1965 break;
1966
1967 case ACPI_ERDT_TYPE_MARC:
1968 InfoTable = AcpiDmTableInfoErdtMarc;
1969 break;
1970
1971 case ACPI_ERDT_TYPE_CARC:
1972 InfoTable = AcpiDmTableInfoErdtCarc;
1973 break;
1974
1975 case ACPI_ERDT_TYPE_CMRD:
1976 InfoTable = AcpiDmTableInfoErdtCmrd;
1977 break;
1978
1979 case ACPI_ERDT_TYPE_IBRD:
1980 InfoTable = AcpiDmTableInfoErdtIbrd;
1981 break;
1982
1983 case ACPI_ERDT_TYPE_IBAD:
1984 InfoTable = AcpiDmTableInfoErdtIbad;
1985 break;
1986
1987 case ACPI_ERDT_TYPE_CARD:
1988 InfoTable = AcpiDmTableInfoErdtCard;
1989 break;
1990
1991 default:
1992 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ERDT");
1993 return (AE_ERROR);
1994 }
1995
1996 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1997 if (ACPI_FAILURE (Status))
1998 {
1999 return (Status);
2000 }
2001
2002 ParentTable = DtPeekSubtable ();
2003 DtInsertSubtable (ParentTable, Subtable);
2004
2005 /* Some subtable types end with flex arrays */
2006
2007 switch (ErdtHeader->Type)
2008 {
2009 case ACPI_ERDT_TYPE_CACD:
2010 while (*PFieldList)
2011 {
2012 Status = DtCompileTable (PFieldList,
2013 AcpiDmTableInfoErdtCacdX2apic, &Subtable);
2014 if (ACPI_FAILURE (Status))
2015 {
2016 return (Status);
2017 }
2018 if (!Subtable)
2019 {
2020 break;
2021 }
2022
2023 ParentTable = DtPeekSubtable ();
2024 DtInsertSubtable (ParentTable, Subtable);
2025 }
2026 break;
2027
2028 case ACPI_ERDT_TYPE_DACD:
2029 while (*PFieldList)
2030 {
2031 Status = DtCompileTable (PFieldList,
2032 AcpiDmTableInfoErdtDacdScope, &Subtable);
2033 if (ACPI_FAILURE (Status))
2034 {
2035 return (Status);
2036 }
2037 if (!Subtable)
2038 {
2039 break;
2040 }
2041
2042 DtPushSubtable (Subtable);
2043 while (*PFieldList)
2044 {
2045 Status = DtCompileTable (PFieldList,
2046 AcpiDmTableInfoErdtDacdPath, &Subsubtable);
2047 if (ACPI_FAILURE (Status))
2048 {
2049 return (Status);
2050 }
2051 if (!Subsubtable)
2052 {
2053 break;
2054 }
2055
2056 ParentTable = DtPeekSubtable ();
2057 DtInsertSubtable (ParentTable, Subsubtable);
2058 }
2059 DtPopSubtable ();
2060
2061 ParentTable = DtPeekSubtable ();
2062 DtInsertSubtable (ParentTable, Subtable);
2063 }
2064 break;
2065
2066 case ACPI_ERDT_TYPE_MMRC:
2067 Mmrc = ACPI_SUB_PTR (ACPI_ERDT_MMRC, Subtable->Buffer,
2068 sizeof(ACPI_SUBTBL_HDR_16));
2069 NumEntries = 0;
2070 while (*PFieldList)
2071 {
2072 Status = DtCompileTable (PFieldList,
2073 AcpiDmTableInfoErdtMmrcCorrFactor, &Subtable);
2074 if (ACPI_FAILURE (Status))
2075 {
2076 return (Status);
2077 }
2078 if (!Subtable)
2079 {
2080 break;
2081 }
2082
2083 ParentTable = DtPeekSubtable ();
2084 DtInsertSubtable (ParentTable, Subtable);
2085 NumEntries++;
2086 }
2087 Mmrc->CorrFactorListLen = NumEntries;
2088 break;
2089
2090 case ACPI_ERDT_TYPE_IBRD:
2091 Ibrd = ACPI_SUB_PTR (ACPI_ERDT_IBRD, Subtable->Buffer,
2092 sizeof(ACPI_SUBTBL_HDR_16));
2093 NumEntries = 0;
2094 while (*PFieldList)
2095 {
2096 Status = DtCompileTable (PFieldList,
2097 AcpiDmTableInfoErdtIbrdCorrFactor, &Subtable);
2098 if (ACPI_FAILURE (Status))
2099 {
2100 return (Status);
2101 }
2102 if (!Subtable)
2103 {
2104 break;
2105 }
2106
2107 ParentTable = DtPeekSubtable ();
2108 DtInsertSubtable (ParentTable, Subtable);
2109 NumEntries++;
2110 }
2111 Ibrd->CorrFactorListLen = NumEntries;
2112 break;
2113
2114 default:
2115 /* Already checked for valid subtable type above */
2116
2117 break;
2118 }
2119 DtPopSubtable ();
2120 }
2121
2122 if (SeenSubtable)
2123 {
2124 DtPopSubtable ();
2125 }
2126
2127 return (AE_OK);
2128 }
2129
2130
2131 /******************************************************************************
2132 *
2133 * FUNCTION: DtCompileErst
2134 *
2135 * PARAMETERS: List - Current field list pointer
2136 *
2137 * RETURN: Status
2138 *
2139 * DESCRIPTION: Compile ERST.
2140 *
2141 *****************************************************************************/
2142
2143 ACPI_STATUS
DtCompileErst(void ** List)2144 DtCompileErst (
2145 void **List)
2146 {
2147 ACPI_STATUS Status;
2148
2149
2150 Status = DtCompileTwoSubtables (List,
2151 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
2152 return (Status);
2153 }
2154
2155
2156 /******************************************************************************
2157 *
2158 * FUNCTION: DtCompileGtdt
2159 *
2160 * PARAMETERS: List - Current field list pointer
2161 *
2162 * RETURN: Status
2163 *
2164 * DESCRIPTION: Compile GTDT.
2165 *
2166 *****************************************************************************/
2167
2168 ACPI_STATUS
DtCompileGtdt(void ** List)2169 DtCompileGtdt (
2170 void **List)
2171 {
2172 ACPI_STATUS Status;
2173 DT_SUBTABLE *Subtable;
2174 DT_SUBTABLE *ParentTable;
2175 DT_FIELD **PFieldList = (DT_FIELD **) List;
2176 DT_FIELD *SubtableStart;
2177 ACPI_SUBTABLE_HEADER *GtdtHeader;
2178 ACPI_DMTABLE_INFO *InfoTable;
2179 UINT32 GtCount;
2180 ACPI_TABLE_HEADER *Header;
2181
2182
2183 ParentTable = DtPeekSubtable ();
2184
2185 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2186
2187 /* Compile the main table */
2188
2189 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
2190 &Subtable);
2191 if (ACPI_FAILURE (Status))
2192 {
2193 return (Status);
2194 }
2195
2196 /* GTDT revision 3 later contains 2 extra fields before subtables */
2197
2198 if (Header->Revision > 2)
2199 {
2200 ParentTable = DtPeekSubtable ();
2201 DtInsertSubtable (ParentTable, Subtable);
2202
2203 Status = DtCompileTable (PFieldList,
2204 AcpiDmTableInfoGtdtEl2, &Subtable);
2205 if (ACPI_FAILURE (Status))
2206 {
2207 return (Status);
2208 }
2209 }
2210
2211 ParentTable = DtPeekSubtable ();
2212 DtInsertSubtable (ParentTable, Subtable);
2213
2214 while (*PFieldList)
2215 {
2216 SubtableStart = *PFieldList;
2217 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
2218 &Subtable);
2219 if (ACPI_FAILURE (Status))
2220 {
2221 return (Status);
2222 }
2223
2224 ParentTable = DtPeekSubtable ();
2225 DtInsertSubtable (ParentTable, Subtable);
2226 DtPushSubtable (Subtable);
2227
2228 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2229
2230 switch (GtdtHeader->Type)
2231 {
2232 case ACPI_GTDT_TYPE_TIMER_BLOCK:
2233
2234 InfoTable = AcpiDmTableInfoGtdt0;
2235 break;
2236
2237 case ACPI_GTDT_TYPE_WATCHDOG:
2238
2239 InfoTable = AcpiDmTableInfoGtdt1;
2240 break;
2241
2242 default:
2243
2244 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
2245 return (AE_ERROR);
2246 }
2247
2248 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2249 if (ACPI_FAILURE (Status))
2250 {
2251 return (Status);
2252 }
2253
2254 ParentTable = DtPeekSubtable ();
2255 DtInsertSubtable (ParentTable, Subtable);
2256
2257 /*
2258 * Additional GT block subtable data
2259 */
2260
2261 switch (GtdtHeader->Type)
2262 {
2263 case ACPI_GTDT_TYPE_TIMER_BLOCK:
2264
2265 DtPushSubtable (Subtable);
2266 ParentTable = DtPeekSubtable ();
2267
2268 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
2269 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
2270
2271 while (GtCount)
2272 {
2273 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
2274 &Subtable);
2275 if (ACPI_FAILURE (Status))
2276 {
2277 return (Status);
2278 }
2279
2280 DtInsertSubtable (ParentTable, Subtable);
2281 GtCount--;
2282 }
2283
2284 DtPopSubtable ();
2285 break;
2286
2287 default:
2288
2289 break;
2290 }
2291
2292 DtPopSubtable ();
2293 }
2294
2295 return (AE_OK);
2296 }
2297
2298
2299 /******************************************************************************
2300 *
2301 * FUNCTION: DtCompileFpdt
2302 *
2303 * PARAMETERS: List - Current field list pointer
2304 *
2305 * RETURN: Status
2306 *
2307 * DESCRIPTION: Compile FPDT.
2308 *
2309 *****************************************************************************/
2310
2311 ACPI_STATUS
DtCompileFpdt(void ** List)2312 DtCompileFpdt (
2313 void **List)
2314 {
2315 ACPI_STATUS Status;
2316 ACPI_FPDT_HEADER *FpdtHeader;
2317 DT_SUBTABLE *Subtable;
2318 DT_SUBTABLE *ParentTable;
2319 ACPI_DMTABLE_INFO *InfoTable;
2320 DT_FIELD **PFieldList = (DT_FIELD **) List;
2321 DT_FIELD *SubtableStart;
2322
2323
2324 while (*PFieldList)
2325 {
2326 SubtableStart = *PFieldList;
2327 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
2328 &Subtable);
2329 if (ACPI_FAILURE (Status))
2330 {
2331 return (Status);
2332 }
2333
2334 ParentTable = DtPeekSubtable ();
2335 DtInsertSubtable (ParentTable, Subtable);
2336 DtPushSubtable (Subtable);
2337
2338 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
2339
2340 switch (FpdtHeader->Type)
2341 {
2342 case ACPI_FPDT_TYPE_BOOT:
2343
2344 InfoTable = AcpiDmTableInfoFpdt0;
2345 break;
2346
2347 case ACPI_FPDT_TYPE_S3PERF:
2348
2349 InfoTable = AcpiDmTableInfoFpdt1;
2350 break;
2351
2352 default:
2353
2354 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
2355 return (AE_ERROR);
2356 break;
2357 }
2358
2359 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2360 if (ACPI_FAILURE (Status))
2361 {
2362 return (Status);
2363 }
2364
2365 ParentTable = DtPeekSubtable ();
2366 DtInsertSubtable (ParentTable, Subtable);
2367 DtPopSubtable ();
2368 }
2369
2370 return (AE_OK);
2371 }
2372
2373
2374 /******************************************************************************
2375 *
2376 * FUNCTION: DtCompileHest
2377 *
2378 * PARAMETERS: List - Current field list pointer
2379 *
2380 * RETURN: Status
2381 *
2382 * DESCRIPTION: Compile HEST.
2383 *
2384 *****************************************************************************/
2385
2386 ACPI_STATUS
DtCompileHest(void ** List)2387 DtCompileHest (
2388 void **List)
2389 {
2390 ACPI_STATUS Status;
2391 DT_SUBTABLE *Subtable;
2392 DT_SUBTABLE *ParentTable;
2393 DT_FIELD **PFieldList = (DT_FIELD **) List;
2394 DT_FIELD *SubtableStart;
2395 ACPI_DMTABLE_INFO *InfoTable;
2396 UINT16 Type;
2397 UINT32 BankCount;
2398
2399
2400 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
2401 &Subtable);
2402 if (ACPI_FAILURE (Status))
2403 {
2404 return (Status);
2405 }
2406
2407 ParentTable = DtPeekSubtable ();
2408 DtInsertSubtable (ParentTable, Subtable);
2409
2410 while (*PFieldList)
2411 {
2412 /* Get subtable type */
2413
2414 SubtableStart = *PFieldList;
2415 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
2416
2417 switch (Type)
2418 {
2419 case ACPI_HEST_TYPE_IA32_CHECK:
2420
2421 InfoTable = AcpiDmTableInfoHest0;
2422 break;
2423
2424 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
2425
2426 InfoTable = AcpiDmTableInfoHest1;
2427 break;
2428
2429 case ACPI_HEST_TYPE_IA32_NMI:
2430
2431 InfoTable = AcpiDmTableInfoHest2;
2432 break;
2433
2434 case ACPI_HEST_TYPE_AER_ROOT_PORT:
2435
2436 InfoTable = AcpiDmTableInfoHest6;
2437 break;
2438
2439 case ACPI_HEST_TYPE_AER_ENDPOINT:
2440
2441 InfoTable = AcpiDmTableInfoHest7;
2442 break;
2443
2444 case ACPI_HEST_TYPE_AER_BRIDGE:
2445
2446 InfoTable = AcpiDmTableInfoHest8;
2447 break;
2448
2449 case ACPI_HEST_TYPE_GENERIC_ERROR:
2450
2451 InfoTable = AcpiDmTableInfoHest9;
2452 break;
2453
2454 case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
2455
2456 InfoTable = AcpiDmTableInfoHest10;
2457 break;
2458
2459 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
2460
2461 InfoTable = AcpiDmTableInfoHest11;
2462 break;
2463
2464 default:
2465
2466 /* Cannot continue on unknown type */
2467
2468 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
2469 return (AE_ERROR);
2470 }
2471
2472 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2473 if (ACPI_FAILURE (Status))
2474 {
2475 return (Status);
2476 }
2477
2478 DtInsertSubtable (ParentTable, Subtable);
2479
2480 /*
2481 * Additional subtable data - IA32 Error Bank(s)
2482 */
2483 BankCount = 0;
2484 switch (Type)
2485 {
2486 case ACPI_HEST_TYPE_IA32_CHECK:
2487
2488 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
2489 Subtable->Buffer))->NumHardwareBanks;
2490 break;
2491
2492 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
2493
2494 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
2495 Subtable->Buffer))->NumHardwareBanks;
2496 break;
2497
2498 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
2499
2500 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
2501 Subtable->Buffer))->NumHardwareBanks;
2502 break;
2503
2504 default:
2505
2506 break;
2507 }
2508
2509 while (BankCount)
2510 {
2511 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
2512 &Subtable);
2513 if (ACPI_FAILURE (Status))
2514 {
2515 return (Status);
2516 }
2517
2518 DtInsertSubtable (ParentTable, Subtable);
2519 BankCount--;
2520 }
2521 }
2522
2523 return (AE_OK);
2524 }
2525
2526
2527 /******************************************************************************
2528 *
2529 * FUNCTION: DtCompileHmat
2530 *
2531 * PARAMETERS: List - Current field list pointer
2532 *
2533 * RETURN: Status
2534 *
2535 * DESCRIPTION: Compile HMAT.
2536 *
2537 *****************************************************************************/
2538
2539 ACPI_STATUS
DtCompileHmat(void ** List)2540 DtCompileHmat (
2541 void **List)
2542 {
2543 ACPI_STATUS Status;
2544 DT_SUBTABLE *Subtable;
2545 DT_SUBTABLE *ParentTable;
2546 DT_FIELD **PFieldList = (DT_FIELD **) List;
2547 DT_FIELD *SubtableStart;
2548 DT_FIELD *EntryStart;
2549 ACPI_HMAT_STRUCTURE *HmatStruct;
2550 ACPI_HMAT_LOCALITY *HmatLocality;
2551 ACPI_HMAT_CACHE *HmatCache;
2552 ACPI_DMTABLE_INFO *InfoTable;
2553 UINT32 IntPDNumber;
2554 UINT32 TgtPDNumber;
2555 UINT64 EntryNumber;
2556 UINT16 SMBIOSHandleNumber;
2557
2558
2559 ParentTable = DtPeekSubtable ();
2560
2561 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
2562 &Subtable);
2563 if (ACPI_FAILURE (Status))
2564 {
2565 return (Status);
2566 }
2567 DtInsertSubtable (ParentTable, Subtable);
2568
2569 while (*PFieldList)
2570 {
2571 /* Compile HMAT structure header */
2572
2573 SubtableStart = *PFieldList;
2574 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
2575 &Subtable);
2576 if (ACPI_FAILURE (Status))
2577 {
2578 return (Status);
2579 }
2580 DtInsertSubtable (ParentTable, Subtable);
2581
2582 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
2583 HmatStruct->Length = Subtable->Length;
2584
2585 /* Compile HMAT structure body */
2586
2587 switch (HmatStruct->Type)
2588 {
2589 case ACPI_HMAT_TYPE_ADDRESS_RANGE:
2590
2591 InfoTable = AcpiDmTableInfoHmat0;
2592 break;
2593
2594 case ACPI_HMAT_TYPE_LOCALITY:
2595
2596 InfoTable = AcpiDmTableInfoHmat1;
2597 break;
2598
2599 case ACPI_HMAT_TYPE_CACHE:
2600
2601 InfoTable = AcpiDmTableInfoHmat2;
2602 break;
2603
2604 default:
2605
2606 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
2607 return (AE_ERROR);
2608 }
2609
2610 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2611 if (ACPI_FAILURE (Status))
2612 {
2613 return (Status);
2614 }
2615 DtInsertSubtable (ParentTable, Subtable);
2616 HmatStruct->Length += Subtable->Length;
2617
2618 /* Compile HMAT structure additional */
2619
2620 switch (HmatStruct->Type)
2621 {
2622 case ACPI_HMAT_TYPE_LOCALITY:
2623
2624 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
2625 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2626
2627 /* Compile initiator proximity domain list */
2628
2629 IntPDNumber = 0;
2630 while (*PFieldList)
2631 {
2632 Status = DtCompileTable (PFieldList,
2633 AcpiDmTableInfoHmat1a, &Subtable);
2634 if (ACPI_FAILURE (Status))
2635 {
2636 return (Status);
2637 }
2638 if (!Subtable)
2639 {
2640 break;
2641 }
2642 DtInsertSubtable (ParentTable, Subtable);
2643 HmatStruct->Length += Subtable->Length;
2644 IntPDNumber++;
2645 }
2646 HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
2647
2648 /* Compile target proximity domain list */
2649
2650 TgtPDNumber = 0;
2651 while (*PFieldList)
2652 {
2653 Status = DtCompileTable (PFieldList,
2654 AcpiDmTableInfoHmat1b, &Subtable);
2655 if (ACPI_FAILURE (Status))
2656 {
2657 return (Status);
2658 }
2659 if (!Subtable)
2660 {
2661 break;
2662 }
2663 DtInsertSubtable (ParentTable, Subtable);
2664 HmatStruct->Length += Subtable->Length;
2665 TgtPDNumber++;
2666 }
2667 HmatLocality->NumberOfTargetPDs = TgtPDNumber;
2668
2669 /* Save start of the entries for reporting errors */
2670
2671 EntryStart = *PFieldList;
2672
2673 /* Compile latency/bandwidth entries */
2674
2675 EntryNumber = 0;
2676 while (*PFieldList)
2677 {
2678 Status = DtCompileTable (PFieldList,
2679 AcpiDmTableInfoHmat1c, &Subtable);
2680 if (ACPI_FAILURE (Status))
2681 {
2682 return (Status);
2683 }
2684 if (!Subtable)
2685 {
2686 break;
2687 }
2688 DtInsertSubtable (ParentTable, Subtable);
2689 HmatStruct->Length += Subtable->Length;
2690 EntryNumber++;
2691 }
2692
2693 /* Validate number of entries */
2694
2695 if (EntryNumber !=
2696 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
2697 {
2698 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
2699 return (AE_ERROR);
2700 }
2701 break;
2702
2703 case ACPI_HMAT_TYPE_CACHE:
2704
2705 /* Compile SMBIOS handles */
2706
2707 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
2708 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2709 SMBIOSHandleNumber = 0;
2710 while (*PFieldList)
2711 {
2712 Status = DtCompileTable (PFieldList,
2713 AcpiDmTableInfoHmat2a, &Subtable);
2714 if (ACPI_FAILURE (Status))
2715 {
2716 return (Status);
2717 }
2718 if (!Subtable)
2719 {
2720 break;
2721 }
2722 DtInsertSubtable (ParentTable, Subtable);
2723 HmatStruct->Length += Subtable->Length;
2724 SMBIOSHandleNumber++;
2725 }
2726 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
2727 break;
2728
2729 default:
2730
2731 break;
2732 }
2733 }
2734
2735 return (AE_OK);
2736 }
2737
2738
2739 /******************************************************************************
2740 *
2741 * FUNCTION: DtCompileIort
2742 *
2743 * PARAMETERS: List - Current field list pointer
2744 *
2745 * RETURN: Status
2746 *
2747 * DESCRIPTION: Compile IORT.
2748 *
2749 *****************************************************************************/
2750
2751 ACPI_STATUS
DtCompileIort(void ** List)2752 DtCompileIort (
2753 void **List)
2754 {
2755 ACPI_STATUS Status;
2756 DT_SUBTABLE *Subtable;
2757 DT_SUBTABLE *ParentTable;
2758 DT_FIELD **PFieldList = (DT_FIELD **) List;
2759 DT_FIELD *SubtableStart;
2760 ACPI_TABLE_HEADER *Table;
2761 ACPI_TABLE_IORT *Iort;
2762 ACPI_IORT_NODE *IortNode;
2763 ACPI_IORT_ITS_GROUP *IortItsGroup;
2764 ACPI_IORT_SMMU *IortSmmu;
2765 ACPI_IORT_RMR *IortRmr;
2766 UINT32 NodeNumber;
2767 UINT32 NodeLength;
2768 UINT32 IdMappingNumber;
2769 UINT32 ItsNumber;
2770 UINT32 ContextIrptNumber;
2771 UINT32 PmuIrptNumber;
2772 UINT32 PaddingLength;
2773 UINT8 Revision;
2774 UINT32 RmrCount;
2775
2776
2777 ParentTable = DtPeekSubtable ();
2778
2779 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
2780 &Subtable);
2781 if (ACPI_FAILURE (Status))
2782 {
2783 return (Status);
2784 }
2785 DtInsertSubtable (ParentTable, Subtable);
2786
2787 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2788 Revision = Table->Revision;
2789
2790 /* IORT Revisions E, E.a & E.c have known issues and are not supported */
2791
2792 if (Revision == 1 || Revision == 2 || Revision == 4)
2793 {
2794 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
2795 return (AE_ERROR);
2796 }
2797
2798 /*
2799 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2800 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2801 */
2802 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
2803 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
2804
2805 /*
2806 * OptionalPadding - Variable-length data
2807 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
2808 * Optionally allows the generic data types to be used for filling
2809 * this field.
2810 */
2811 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
2812 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
2813 &Subtable);
2814 if (ACPI_FAILURE (Status))
2815 {
2816 return (Status);
2817 }
2818 if (Subtable)
2819 {
2820 DtInsertSubtable (ParentTable, Subtable);
2821 Iort->NodeOffset += Subtable->Length;
2822 }
2823 else
2824 {
2825 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
2826 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
2827 if (ACPI_FAILURE (Status))
2828 {
2829 return (Status);
2830 }
2831 Iort->NodeOffset += PaddingLength;
2832 }
2833
2834 NodeNumber = 0;
2835 while (*PFieldList)
2836 {
2837 SubtableStart = *PFieldList;
2838 if (Revision == 0)
2839 {
2840 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
2841 &Subtable);
2842 }
2843 else if (Revision >= 3)
2844 {
2845 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
2846 &Subtable);
2847 }
2848
2849 if (ACPI_FAILURE (Status))
2850 {
2851 return (Status);
2852 }
2853
2854 DtInsertSubtable (ParentTable, Subtable);
2855 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
2856 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
2857
2858 DtPushSubtable (Subtable);
2859 ParentTable = DtPeekSubtable ();
2860
2861 switch (IortNode->Type)
2862 {
2863 case ACPI_IORT_NODE_ITS_GROUP:
2864
2865 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
2866 &Subtable);
2867 if (ACPI_FAILURE (Status))
2868 {
2869 return (Status);
2870 }
2871
2872 DtInsertSubtable (ParentTable, Subtable);
2873 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
2874 NodeLength += Subtable->Length;
2875
2876 ItsNumber = 0;
2877 while (*PFieldList)
2878 {
2879 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
2880 &Subtable);
2881 if (ACPI_FAILURE (Status))
2882 {
2883 return (Status);
2884 }
2885 if (!Subtable)
2886 {
2887 break;
2888 }
2889
2890 DtInsertSubtable (ParentTable, Subtable);
2891 NodeLength += Subtable->Length;
2892 ItsNumber++;
2893 }
2894
2895 IortItsGroup->ItsCount = ItsNumber;
2896 break;
2897
2898 case ACPI_IORT_NODE_NAMED_COMPONENT:
2899
2900 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
2901 &Subtable);
2902 if (ACPI_FAILURE (Status))
2903 {
2904 return (Status);
2905 }
2906
2907 DtInsertSubtable (ParentTable, Subtable);
2908 NodeLength += Subtable->Length;
2909
2910 /*
2911 * Padding - Variable-length data
2912 * Optionally allows the offset of the ID mappings to be used
2913 * for filling this field.
2914 */
2915 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
2916 &Subtable);
2917 if (ACPI_FAILURE (Status))
2918 {
2919 return (Status);
2920 }
2921
2922 if (Subtable)
2923 {
2924 DtInsertSubtable (ParentTable, Subtable);
2925 NodeLength += Subtable->Length;
2926 }
2927 else
2928 {
2929 if (NodeLength > IortNode->MappingOffset)
2930 {
2931 return (AE_BAD_DATA);
2932 }
2933
2934 if (NodeLength < IortNode->MappingOffset)
2935 {
2936 Status = DtCompilePadding (
2937 IortNode->MappingOffset - NodeLength,
2938 &Subtable);
2939 if (ACPI_FAILURE (Status))
2940 {
2941 return (Status);
2942 }
2943
2944 DtInsertSubtable (ParentTable, Subtable);
2945 NodeLength = IortNode->MappingOffset;
2946 }
2947 }
2948 break;
2949
2950 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
2951
2952 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
2953 &Subtable);
2954 if (ACPI_FAILURE (Status))
2955 {
2956 return (Status);
2957 }
2958
2959 DtInsertSubtable (ParentTable, Subtable);
2960 NodeLength += Subtable->Length;
2961 break;
2962
2963 case ACPI_IORT_NODE_SMMU:
2964
2965 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
2966 &Subtable);
2967 if (ACPI_FAILURE (Status))
2968 {
2969 return (Status);
2970 }
2971
2972 DtInsertSubtable (ParentTable, Subtable);
2973 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
2974 NodeLength += Subtable->Length;
2975
2976 /* Compile global interrupt array */
2977
2978 IortSmmu->GlobalInterruptOffset = NodeLength;
2979 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
2980 &Subtable);
2981 if (ACPI_FAILURE (Status))
2982 {
2983 return (Status);
2984 }
2985
2986 DtInsertSubtable (ParentTable, Subtable);
2987 NodeLength += Subtable->Length;
2988
2989 /* Compile context interrupt array */
2990
2991 ContextIrptNumber = 0;
2992 IortSmmu->ContextInterruptOffset = NodeLength;
2993 while (*PFieldList)
2994 {
2995 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
2996 &Subtable);
2997 if (ACPI_FAILURE (Status))
2998 {
2999 return (Status);
3000 }
3001
3002 if (!Subtable)
3003 {
3004 break;
3005 }
3006
3007 DtInsertSubtable (ParentTable, Subtable);
3008 NodeLength += Subtable->Length;
3009 ContextIrptNumber++;
3010 }
3011
3012 IortSmmu->ContextInterruptCount = ContextIrptNumber;
3013
3014 /* Compile PMU interrupt array */
3015
3016 PmuIrptNumber = 0;
3017 IortSmmu->PmuInterruptOffset = NodeLength;
3018 while (*PFieldList)
3019 {
3020 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
3021 &Subtable);
3022 if (ACPI_FAILURE (Status))
3023 {
3024 return (Status);
3025 }
3026
3027 if (!Subtable)
3028 {
3029 break;
3030 }
3031
3032 DtInsertSubtable (ParentTable, Subtable);
3033 NodeLength += Subtable->Length;
3034 PmuIrptNumber++;
3035 }
3036
3037 IortSmmu->PmuInterruptCount = PmuIrptNumber;
3038 break;
3039
3040 case ACPI_IORT_NODE_SMMU_V3:
3041
3042 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
3043 &Subtable);
3044 if (ACPI_FAILURE (Status))
3045 {
3046 return (Status);
3047 }
3048
3049 DtInsertSubtable (ParentTable, Subtable);
3050 NodeLength += Subtable->Length;
3051 break;
3052
3053 case ACPI_IORT_NODE_PMCG:
3054
3055 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
3056 &Subtable);
3057 if (ACPI_FAILURE (Status))
3058 {
3059 return (Status);
3060 }
3061
3062 DtInsertSubtable (ParentTable, Subtable);
3063 NodeLength += Subtable->Length;
3064 break;
3065
3066 case ACPI_IORT_NODE_RMR:
3067
3068 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
3069 &Subtable);
3070 if (ACPI_FAILURE (Status))
3071 {
3072 return (Status);
3073 }
3074
3075 DtInsertSubtable (ParentTable, Subtable);
3076 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
3077 NodeLength += Subtable->Length;
3078
3079 /* Compile RMR Descriptors */
3080
3081 RmrCount = 0;
3082 IortRmr->RmrOffset = NodeLength;
3083 while (*PFieldList)
3084 {
3085 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
3086 &Subtable);
3087 if (ACPI_FAILURE (Status))
3088 {
3089 return (Status);
3090 }
3091
3092 if (!Subtable)
3093 {
3094 break;
3095 }
3096
3097 DtInsertSubtable (ParentTable, Subtable);
3098 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
3099 RmrCount++;
3100 }
3101
3102 IortRmr->RmrCount = RmrCount;
3103 break;
3104
3105 case ACPI_IORT_NODE_IWB:
3106
3107 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort7,
3108 &Subtable);
3109 if (ACPI_FAILURE (Status))
3110 {
3111 return (Status);
3112 }
3113
3114 DtInsertSubtable (ParentTable, Subtable);
3115 NodeLength += Subtable->Length;
3116 break;
3117
3118 default:
3119
3120 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
3121 return (AE_ERROR);
3122 }
3123
3124 /* Compile Array of ID mappings */
3125
3126 IortNode->MappingOffset = NodeLength;
3127 IdMappingNumber = 0;
3128 while (*PFieldList)
3129 {
3130 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
3131 &Subtable);
3132 if (ACPI_FAILURE (Status))
3133 {
3134 return (Status);
3135 }
3136
3137 if (!Subtable)
3138 {
3139 break;
3140 }
3141
3142 DtInsertSubtable (ParentTable, Subtable);
3143 NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
3144 IdMappingNumber++;
3145 }
3146
3147 IortNode->MappingCount = IdMappingNumber;
3148 if (!IdMappingNumber)
3149 {
3150 IortNode->MappingOffset = 0;
3151 }
3152
3153 /*
3154 * Node length can be determined by DT_LENGTH option
3155 * IortNode->Length = NodeLength;
3156 */
3157 DtPopSubtable ();
3158 ParentTable = DtPeekSubtable ();
3159 NodeNumber++;
3160 }
3161
3162 Iort->NodeCount = NodeNumber;
3163 return (AE_OK);
3164 }
3165
3166
3167 /******************************************************************************
3168 *
3169 * FUNCTION: DtCompileIovt
3170 *
3171 * PARAMETERS: List - Current field list pointer
3172 *
3173 * RETURN: Status
3174 *
3175 * DESCRIPTION: Compile Iovt. Notes:
3176 * The IOVT is essentially a flat table, with the following
3177 * structure:
3178 * <Main ACPI Table Header>
3179 * <Main subtable - virtualization info>
3180 * <IOVT>
3181 * <Device Entries>
3182 * ...
3183 * <IOVT>
3184 * <IOVT>
3185 * ...
3186 *
3187 *****************************************************************************/
3188
3189 ACPI_STATUS
DtCompileIovt(void ** List)3190 DtCompileIovt (
3191 void **List)
3192 {
3193 ACPI_STATUS Status;
3194 DT_SUBTABLE *Subtable;
3195 DT_SUBTABLE *ParentTable;
3196 DT_FIELD **PFieldList = (DT_FIELD **) List;
3197 ACPI_TABLE_IOVT *Iovt;
3198 UINT16 IommuCount;
3199 ACPI_IOVT_IOMMU *Iommu;
3200 UINT32 DeviceEntryNum;
3201
3202
3203 ParentTable = DtPeekSubtable ();
3204 /* Main table */
3205
3206 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIovt,
3207 &Subtable);
3208 if (ACPI_FAILURE (Status))
3209 {
3210 return (Status);
3211 }
3212
3213 DtInsertSubtable (ParentTable, Subtable);
3214 DtPushSubtable (Subtable);
3215
3216 Iovt = ACPI_SUB_PTR (ACPI_TABLE_IOVT, Subtable->Buffer,
3217 sizeof (ACPI_TABLE_HEADER));
3218
3219 for (IommuCount = 0; IommuCount < Iovt->IommuCount; IommuCount++)
3220 {
3221 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIovt0,
3222 &Subtable);
3223 if (ACPI_FAILURE (Status))
3224 {
3225 return (Status);
3226 }
3227
3228 ParentTable = DtPeekSubtable ();
3229 DtInsertSubtable (ParentTable, Subtable);
3230 DtPushSubtable (Subtable);
3231
3232 Iommu = ACPI_CAST_PTR(ACPI_IOVT_IOMMU, Subtable->Buffer);
3233 for (DeviceEntryNum = 0; DeviceEntryNum < Iommu->DeviceEntryNum; DeviceEntryNum++)
3234 {
3235 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIovtdev,
3236 &Subtable);
3237 if (ACPI_FAILURE (Status))
3238 {
3239 return (Status);
3240 }
3241
3242 ParentTable = DtPeekSubtable ();
3243 DtInsertSubtable (ParentTable, Subtable);
3244 }
3245 DtPopSubtable();
3246 }
3247
3248 return (AE_OK);
3249 }
3250
3251
3252 /******************************************************************************
3253 *
3254 * FUNCTION: DtCompileIvrs
3255 *
3256 * PARAMETERS: List - Current field list pointer
3257 *
3258 * RETURN: Status
3259 *
3260 * DESCRIPTION: Compile IVRS. Notes:
3261 * The IVRS is essentially a flat table, with the following
3262 * structure:
3263 * <Main ACPI Table Header>
3264 * <Main subtable - virtualization info>
3265 * <IVHD>
3266 * <Device Entries>
3267 * ...
3268 * <IVHD>
3269 * <Device Entries>
3270 * <IVMD>
3271 * ...
3272 *
3273 *****************************************************************************/
3274
3275 ACPI_STATUS
DtCompileIvrs(void ** List)3276 DtCompileIvrs (
3277 void **List)
3278 {
3279 ACPI_STATUS Status;
3280 DT_SUBTABLE *Subtable;
3281 DT_SUBTABLE *ParentTable;
3282 DT_SUBTABLE *MainSubtable;
3283 DT_FIELD **PFieldList = (DT_FIELD **) List;
3284 DT_FIELD *SubtableStart;
3285 ACPI_DMTABLE_INFO *InfoTable = NULL;
3286 UINT8 SubtableType;
3287 UINT8 Temp64[16];
3288 UINT8 Temp8;
3289
3290
3291 /* Main table */
3292
3293 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
3294 &Subtable);
3295 if (ACPI_FAILURE (Status))
3296 {
3297 return (Status);
3298 }
3299
3300 ParentTable = DtPeekSubtable ();
3301 DtInsertSubtable (ParentTable, Subtable);
3302 DtPushSubtable (Subtable);
3303
3304 /* Save a pointer to the main subtable */
3305
3306 MainSubtable = Subtable;
3307
3308 while (*PFieldList)
3309 {
3310 SubtableStart = *PFieldList;
3311
3312 /* Compile the SubtableType integer */
3313
3314 DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
3315
3316 switch (SubtableType)
3317 {
3318
3319 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
3320
3321 case ACPI_IVRS_TYPE_HARDWARE1:
3322
3323 InfoTable = AcpiDmTableInfoIvrsHware1;
3324 break;
3325
3326 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
3327
3328 case ACPI_IVRS_TYPE_HARDWARE2:
3329 case ACPI_IVRS_TYPE_HARDWARE3:
3330
3331 InfoTable = AcpiDmTableInfoIvrsHware23;
3332 break;
3333
3334 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
3335
3336 case ACPI_IVRS_TYPE_MEMORY1:
3337 case ACPI_IVRS_TYPE_MEMORY2:
3338 case ACPI_IVRS_TYPE_MEMORY3:
3339
3340 InfoTable = AcpiDmTableInfoIvrsMemory;
3341 break;
3342
3343 /* 4-byte device entries */
3344
3345 case ACPI_IVRS_TYPE_PAD4:
3346 case ACPI_IVRS_TYPE_ALL:
3347 case ACPI_IVRS_TYPE_SELECT:
3348 case ACPI_IVRS_TYPE_START:
3349 case ACPI_IVRS_TYPE_END:
3350
3351 InfoTable = AcpiDmTableInfoIvrs4;
3352 break;
3353
3354 /* 8-byte device entries, type A */
3355
3356 case ACPI_IVRS_TYPE_ALIAS_SELECT:
3357 case ACPI_IVRS_TYPE_ALIAS_START:
3358
3359 InfoTable = AcpiDmTableInfoIvrs8a;
3360 break;
3361
3362 /* 8-byte device entries, type B */
3363
3364 case ACPI_IVRS_TYPE_EXT_SELECT:
3365 case ACPI_IVRS_TYPE_EXT_START:
3366
3367 InfoTable = AcpiDmTableInfoIvrs8b;
3368 break;
3369
3370 /* 8-byte device entries, type C */
3371
3372 case ACPI_IVRS_TYPE_SPECIAL:
3373
3374 InfoTable = AcpiDmTableInfoIvrs8c;
3375 break;
3376
3377 /* Variable device entries, type F0h */
3378
3379 case ACPI_IVRS_TYPE_HID:
3380
3381 InfoTable = AcpiDmTableInfoIvrsHid;
3382 break;
3383
3384 default:
3385
3386 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
3387 "IVRS Device Entry");
3388 return (AE_ERROR);
3389 }
3390
3391 /* Compile the InfoTable from above */
3392
3393 Status = DtCompileTable (PFieldList, InfoTable,
3394 &Subtable);
3395 if (ACPI_FAILURE (Status))
3396 {
3397 return (Status);
3398 }
3399
3400 ParentTable = DtPeekSubtable ();
3401 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
3402 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
3403 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
3404 SubtableType != ACPI_IVRS_TYPE_HID &&
3405 SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
3406 SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
3407 SubtableType != ACPI_IVRS_TYPE_MEMORY3)
3408 {
3409 if (ParentTable)
3410 DtInsertSubtable (ParentTable, Subtable);
3411 }
3412
3413 switch (SubtableType)
3414 {
3415 case ACPI_IVRS_TYPE_HARDWARE1:
3416 case ACPI_IVRS_TYPE_HARDWARE2:
3417 case ACPI_IVRS_TYPE_HARDWARE3:
3418 case ACPI_IVRS_TYPE_MEMORY1:
3419 case ACPI_IVRS_TYPE_MEMORY2:
3420 case ACPI_IVRS_TYPE_MEMORY3:
3421
3422 /* Insert these IVHDs/IVMDs at the root subtable */
3423
3424 DtInsertSubtable (MainSubtable, Subtable);
3425 DtPushSubtable (Subtable);
3426 break;
3427
3428 case ACPI_IVRS_TYPE_HID:
3429
3430 /* Special handling for the HID named device entry (0xF0) */
3431
3432 if (ParentTable)
3433 {
3434 DtInsertSubtable (ParentTable, Subtable);
3435 }
3436
3437 /*
3438 * Process the HID value. First, get the HID value as a string.
3439 */
3440 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
3441
3442 /*
3443 * Determine if the HID is an integer or a string.
3444 * An integer is defined to be 32 bits, with the upper 32 bits
3445 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
3446 * integer or a character string. If an integer, the lower
3447 * 4 bytes of the field contain the integer and the upper
3448 * 4 bytes are padded with 0".
3449 */
3450 if (UtIsIdInteger ((UINT8 *) &Temp64))
3451 {
3452 /* Compile the HID value as an integer */
3453
3454 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
3455
3456 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
3457 &Subtable);
3458 if (ACPI_FAILURE (Status))
3459 {
3460 return (Status);
3461 }
3462 }
3463 else
3464 {
3465 /* Compile the HID value as a string */
3466
3467 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
3468 &Subtable);
3469 if (ACPI_FAILURE (Status))
3470 {
3471 return (Status);
3472 }
3473 }
3474
3475 DtInsertSubtable (ParentTable, Subtable);
3476
3477 /*
3478 * Process the CID value. First, get the CID value as a string.
3479 */
3480 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
3481
3482 if (UtIsIdInteger ((UINT8 *) &Temp64))
3483 {
3484 /* Compile the CID value as an integer */
3485
3486 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
3487
3488 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
3489 &Subtable);
3490 if (ACPI_FAILURE (Status))
3491 {
3492 return (Status);
3493 }
3494 }
3495 else
3496 {
3497 /* Compile the CID value as a string */
3498
3499 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
3500 &Subtable);
3501 if (ACPI_FAILURE (Status))
3502 {
3503 return (Status);
3504 }
3505 }
3506
3507 DtInsertSubtable (ParentTable, Subtable);
3508
3509 /*
3510 * Process the UID value. First, get and decode the "UID Format" field (Integer).
3511 */
3512 if (!*PFieldList)
3513 {
3514 return (AE_OK);
3515 }
3516
3517 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
3518
3519 switch (Temp8)
3520 {
3521 case ACPI_IVRS_UID_NOT_PRESENT:
3522 break;
3523
3524 case ACPI_IVRS_UID_IS_INTEGER:
3525
3526 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
3527 &Subtable);
3528 if (ACPI_FAILURE (Status))
3529 {
3530 return (Status);
3531 }
3532 DtInsertSubtable (ParentTable, Subtable);
3533 break;
3534
3535 case ACPI_IVRS_UID_IS_STRING:
3536
3537 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
3538 &Subtable);
3539 if (ACPI_FAILURE (Status))
3540 {
3541 return (Status);
3542 }
3543 DtInsertSubtable (ParentTable, Subtable);
3544 break;
3545
3546 default:
3547
3548 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
3549 "IVRS Device Entry");
3550 return (AE_ERROR);
3551 }
3552
3553 default:
3554
3555 /* All other subtable types come through here */
3556 break;
3557 }
3558 }
3559
3560 return (AE_OK);
3561 }
3562
3563
3564 /******************************************************************************
3565 *
3566 * FUNCTION: DtCompileRimt
3567 *
3568 * PARAMETERS: List - Current field list pointer
3569 *
3570 * RETURN: Status
3571 *
3572 * DESCRIPTION: Compile RIMT.
3573 *
3574 *****************************************************************************/
3575
3576 ACPI_STATUS
DtCompileRimt(void ** List)3577 DtCompileRimt (
3578 void **List)
3579 {
3580 ACPI_RIMT_PLATFORM_DEVICE *PlatDevNode;
3581 ACPI_RIMT_PCIE_RC *PcieRcNode;
3582 ACPI_TABLE_RIMT *Rimt;
3583 ACPI_RIMT_IOMMU *IommuNode;
3584 ACPI_RIMT_NODE *RimtNode;
3585 ACPI_STATUS Status;
3586 DT_SUBTABLE *Subtable;
3587 DT_SUBTABLE *ParentTable;
3588 DT_FIELD **PFieldList = (DT_FIELD **) List;
3589 DT_FIELD *SubtableStart;
3590 UINT32 NodeNumber;
3591 UINT32 NodeLength;
3592 UINT16 IdMappingNumber;
3593 UINT32 i;
3594
3595
3596 ParentTable = DtPeekSubtable ();
3597
3598 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimt, &Subtable);
3599 if (ACPI_FAILURE (Status))
3600 {
3601 return (Status);
3602 }
3603
3604 DtInsertSubtable (ParentTable, Subtable);
3605
3606 /*
3607 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
3608 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
3609 */
3610 Rimt = ACPI_SUB_PTR (ACPI_TABLE_RIMT, Subtable->Buffer,
3611 sizeof (ACPI_TABLE_HEADER));
3612
3613 NodeNumber = 0;
3614 while (*PFieldList)
3615 {
3616 SubtableStart = *PFieldList;
3617 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtNodeHdr, &Subtable);
3618
3619 if (ACPI_FAILURE (Status))
3620 {
3621 return (Status);
3622 }
3623
3624 DtInsertSubtable (ParentTable, Subtable);
3625 RimtNode = ACPI_CAST_PTR (ACPI_RIMT_NODE, Subtable->Buffer);
3626 NodeLength = ACPI_OFFSET (ACPI_RIMT_NODE, NodeData);
3627
3628 DtPushSubtable (Subtable);
3629 ParentTable = DtPeekSubtable ();
3630
3631 switch (RimtNode->Type)
3632 {
3633 case ACPI_RIMT_NODE_TYPE_IOMMU:
3634
3635 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtIommu,
3636 &Subtable);
3637 if (ACPI_FAILURE (Status))
3638 {
3639 return (Status);
3640 }
3641
3642 IommuNode = ACPI_CAST_PTR (ACPI_RIMT_IOMMU, Subtable->Buffer);
3643 DtInsertSubtable (ParentTable, Subtable);
3644 NodeLength += Subtable->Length;
3645
3646 for (i = 0; i < IommuNode->NumInterruptWires; i++)
3647 {
3648 while (*PFieldList)
3649 {
3650 Status = DtCompileTable (PFieldList,
3651 AcpiDmTableInfoRimtIommuWire,
3652 &Subtable);
3653 if (ACPI_FAILURE (Status))
3654 {
3655 return (Status);
3656 }
3657 if (!Subtable)
3658 {
3659 break;
3660 }
3661
3662 DtInsertSubtable (ParentTable, Subtable);
3663 NodeLength += Subtable->Length;
3664 }
3665 }
3666
3667 break;
3668
3669 case ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX:
3670
3671 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPcieRc,
3672 &Subtable);
3673 if (ACPI_FAILURE (Status))
3674 {
3675 return (Status);
3676 }
3677
3678 DtInsertSubtable (ParentTable, Subtable);
3679 PcieRcNode = ACPI_CAST_PTR (ACPI_RIMT_PCIE_RC, Subtable->Buffer);
3680 NodeLength += Subtable->Length;
3681
3682 /* Compile Array of ID mappings */
3683
3684 PcieRcNode->IdMappingOffset = (UINT16) NodeLength;
3685 IdMappingNumber = 0;
3686 while (*PFieldList)
3687 {
3688 Status = DtCompileTable (PFieldList,
3689 AcpiDmTableInfoRimtIdMapping,
3690 &Subtable);
3691 if (ACPI_FAILURE (Status))
3692 {
3693 return (Status);
3694 }
3695
3696 if (!Subtable)
3697 {
3698 break;
3699 }
3700
3701 DtInsertSubtable (ParentTable, Subtable);
3702 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING);
3703 IdMappingNumber++;
3704 }
3705
3706 PcieRcNode->NumIdMappings = IdMappingNumber;
3707 if (!IdMappingNumber)
3708 {
3709 PcieRcNode->IdMappingOffset = 0;
3710 }
3711
3712 break;
3713
3714 case ACPI_RIMT_NODE_TYPE_PLAT_DEVICE:
3715
3716 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDev,
3717 &Subtable);
3718 if (ACPI_FAILURE (Status))
3719 {
3720 return (Status);
3721 }
3722
3723 DtInsertSubtable (ParentTable, Subtable);
3724 PlatDevNode = ACPI_CAST_PTR (ACPI_RIMT_PLATFORM_DEVICE, Subtable->Buffer);
3725 NodeLength += Subtable->Length;
3726
3727 /*
3728 * Padding - Variable-length data
3729 * Optionally allows the offset of the ID mappings to be used
3730 * for filling this field.
3731 */
3732 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDevPad,
3733 &Subtable);
3734 if (ACPI_FAILURE (Status))
3735 {
3736 return (Status);
3737 }
3738
3739 if (Subtable)
3740 {
3741 DtInsertSubtable (ParentTable, Subtable);
3742 NodeLength += Subtable->Length;
3743 }
3744 else
3745 {
3746 if (NodeLength > PlatDevNode->IdMappingOffset)
3747 {
3748 return (AE_BAD_DATA);
3749 }
3750
3751 if (NodeLength < PlatDevNode->IdMappingOffset)
3752 {
3753 Status = DtCompilePadding (
3754 PlatDevNode->IdMappingOffset - (UINT16) NodeLength,
3755 &Subtable);
3756 if (ACPI_FAILURE (Status))
3757 {
3758 return (Status);
3759 }
3760
3761 DtInsertSubtable (ParentTable, Subtable);
3762 NodeLength = PlatDevNode->IdMappingOffset;
3763 }
3764 }
3765
3766 /* Compile Array of ID mappings */
3767
3768 PlatDevNode->IdMappingOffset = (UINT16) NodeLength;
3769 IdMappingNumber = 0;
3770 while (*PFieldList)
3771 {
3772 Status = DtCompileTable (PFieldList,
3773 AcpiDmTableInfoRimtIdMapping,
3774 &Subtable);
3775 if (ACPI_FAILURE (Status))
3776 {
3777 return (Status);
3778 }
3779
3780 if (!Subtable)
3781 {
3782 break;
3783 }
3784
3785 DtInsertSubtable (ParentTable, Subtable);
3786 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING);
3787 IdMappingNumber++;
3788 }
3789
3790 PlatDevNode->NumIdMappings = IdMappingNumber;
3791 if (!IdMappingNumber)
3792 {
3793 PlatDevNode->IdMappingOffset = 0;
3794 }
3795
3796 break;
3797
3798
3799 default:
3800
3801 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RIMT");
3802 return (AE_ERROR);
3803 }
3804
3805 DtPopSubtable ();
3806 ParentTable = DtPeekSubtable ();
3807 NodeNumber++;
3808 }
3809
3810 Rimt->NumNodes = NodeNumber;
3811 return (AE_OK);
3812 }
3813