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