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 - 2024, 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 default:
1511
1512 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
1513 return (AE_ERROR);
1514 }
1515
1516 /* DMAR Subtable */
1517
1518 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1519 if (ACPI_FAILURE (Status))
1520 {
1521 return (Status);
1522 }
1523
1524 ParentTable = DtPeekSubtable ();
1525 DtInsertSubtable (ParentTable, Subtable);
1526
1527 /*
1528 * Optional Device Scope subtables
1529 */
1530 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
1531 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
1532 {
1533 /* These types do not support device scopes */
1534
1535 DtPopSubtable ();
1536 continue;
1537 }
1538
1539 DtPushSubtable (Subtable);
1540 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
1541 ParentTable->Length;
1542 while (DeviceScopeLength)
1543 {
1544 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
1545 &Subtable);
1546 if (Status == AE_NOT_FOUND)
1547 {
1548 break;
1549 }
1550
1551 ParentTable = DtPeekSubtable ();
1552 DtInsertSubtable (ParentTable, Subtable);
1553 DtPushSubtable (Subtable);
1554
1555 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
1556
1557 /* Optional PCI Paths */
1558
1559 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
1560 while (PciPathLength)
1561 {
1562 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
1563 &Subtable);
1564 if (Status == AE_NOT_FOUND)
1565 {
1566 DtPopSubtable ();
1567 break;
1568 }
1569
1570 ParentTable = DtPeekSubtable ();
1571 DtInsertSubtable (ParentTable, Subtable);
1572 PciPathLength -= Subtable->Length;
1573 }
1574
1575 DtPopSubtable ();
1576 DeviceScopeLength -= DmarDeviceScope->Length;
1577 }
1578
1579 DtPopSubtable ();
1580 DtPopSubtable ();
1581 }
1582
1583 return (AE_OK);
1584 }
1585
1586
1587 /******************************************************************************
1588 *
1589 * FUNCTION: DtCompileDrtm
1590 *
1591 * PARAMETERS: List - Current field list pointer
1592 *
1593 * RETURN: Status
1594 *
1595 * DESCRIPTION: Compile DRTM.
1596 *
1597 *****************************************************************************/
1598
1599 ACPI_STATUS
DtCompileDrtm(void ** List)1600 DtCompileDrtm (
1601 void **List)
1602 {
1603 ACPI_STATUS Status;
1604 DT_SUBTABLE *Subtable;
1605 DT_SUBTABLE *ParentTable;
1606 DT_FIELD **PFieldList = (DT_FIELD **) List;
1607 UINT32 Count;
1608 /* ACPI_TABLE_DRTM *Drtm; */
1609 ACPI_DRTM_VTABLE_LIST *DrtmVtl;
1610 ACPI_DRTM_RESOURCE_LIST *DrtmRl;
1611 /* ACPI_DRTM_DPS_ID *DrtmDps; */
1612
1613
1614 ParentTable = DtPeekSubtable ();
1615
1616 /* Compile DRTM header */
1617
1618 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
1619 &Subtable);
1620 if (ACPI_FAILURE (Status))
1621 {
1622 return (Status);
1623 }
1624 DtInsertSubtable (ParentTable, Subtable);
1625
1626 /*
1627 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1628 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1629 */
1630 #if 0
1631 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
1632 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1633 #endif
1634 /* Compile VTL */
1635
1636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
1637 &Subtable);
1638 if (ACPI_FAILURE (Status))
1639 {
1640 return (Status);
1641 }
1642
1643 DtInsertSubtable (ParentTable, Subtable);
1644 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
1645
1646 DtPushSubtable (Subtable);
1647 ParentTable = DtPeekSubtable ();
1648 Count = 0;
1649
1650 while (*PFieldList)
1651 {
1652 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
1653 &Subtable);
1654 if (ACPI_FAILURE (Status))
1655 {
1656 return (Status);
1657 }
1658 if (!Subtable)
1659 {
1660 break;
1661 }
1662 DtInsertSubtable (ParentTable, Subtable);
1663 Count++;
1664 }
1665
1666 DrtmVtl->ValidatedTableCount = Count;
1667 DtPopSubtable ();
1668 ParentTable = DtPeekSubtable ();
1669
1670 /* Compile RL */
1671
1672 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
1673 &Subtable);
1674 if (ACPI_FAILURE (Status))
1675 {
1676 return (Status);
1677 }
1678
1679 DtInsertSubtable (ParentTable, Subtable);
1680 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
1681
1682 DtPushSubtable (Subtable);
1683 ParentTable = DtPeekSubtable ();
1684 Count = 0;
1685
1686 while (*PFieldList)
1687 {
1688 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
1689 &Subtable);
1690 if (ACPI_FAILURE (Status))
1691 {
1692 return (Status);
1693 }
1694
1695 if (!Subtable)
1696 {
1697 break;
1698 }
1699
1700 DtInsertSubtable (ParentTable, Subtable);
1701 Count++;
1702 }
1703
1704 DrtmRl->ResourceCount = Count;
1705 DtPopSubtable ();
1706 ParentTable = DtPeekSubtable ();
1707
1708 /* Compile DPS */
1709
1710 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
1711 &Subtable);
1712 if (ACPI_FAILURE (Status))
1713 {
1714 return (Status);
1715 }
1716 DtInsertSubtable (ParentTable, Subtable);
1717 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
1718
1719
1720 return (AE_OK);
1721 }
1722
1723
1724 /******************************************************************************
1725 *
1726 * FUNCTION: DtCompileEinj
1727 *
1728 * PARAMETERS: List - Current field list pointer
1729 *
1730 * RETURN: Status
1731 *
1732 * DESCRIPTION: Compile EINJ.
1733 *
1734 *****************************************************************************/
1735
1736 ACPI_STATUS
DtCompileEinj(void ** List)1737 DtCompileEinj (
1738 void **List)
1739 {
1740 ACPI_STATUS Status;
1741
1742
1743 Status = DtCompileTwoSubtables (List,
1744 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
1745 return (Status);
1746 }
1747
1748
1749 /******************************************************************************
1750 *
1751 * FUNCTION: DtCompileErst
1752 *
1753 * PARAMETERS: List - Current field list pointer
1754 *
1755 * RETURN: Status
1756 *
1757 * DESCRIPTION: Compile ERST.
1758 *
1759 *****************************************************************************/
1760
1761 ACPI_STATUS
DtCompileErst(void ** List)1762 DtCompileErst (
1763 void **List)
1764 {
1765 ACPI_STATUS Status;
1766
1767
1768 Status = DtCompileTwoSubtables (List,
1769 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1770 return (Status);
1771 }
1772
1773
1774 /******************************************************************************
1775 *
1776 * FUNCTION: DtCompileGtdt
1777 *
1778 * PARAMETERS: List - Current field list pointer
1779 *
1780 * RETURN: Status
1781 *
1782 * DESCRIPTION: Compile GTDT.
1783 *
1784 *****************************************************************************/
1785
1786 ACPI_STATUS
DtCompileGtdt(void ** List)1787 DtCompileGtdt (
1788 void **List)
1789 {
1790 ACPI_STATUS Status;
1791 DT_SUBTABLE *Subtable;
1792 DT_SUBTABLE *ParentTable;
1793 DT_FIELD **PFieldList = (DT_FIELD **) List;
1794 DT_FIELD *SubtableStart;
1795 ACPI_SUBTABLE_HEADER *GtdtHeader;
1796 ACPI_DMTABLE_INFO *InfoTable;
1797 UINT32 GtCount;
1798 ACPI_TABLE_HEADER *Header;
1799
1800
1801 ParentTable = DtPeekSubtable ();
1802
1803 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1804
1805 /* Compile the main table */
1806
1807 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1808 &Subtable);
1809 if (ACPI_FAILURE (Status))
1810 {
1811 return (Status);
1812 }
1813
1814 /* GTDT revision 3 later contains 2 extra fields before subtables */
1815
1816 if (Header->Revision > 2)
1817 {
1818 ParentTable = DtPeekSubtable ();
1819 DtInsertSubtable (ParentTable, Subtable);
1820
1821 Status = DtCompileTable (PFieldList,
1822 AcpiDmTableInfoGtdtEl2, &Subtable);
1823 if (ACPI_FAILURE (Status))
1824 {
1825 return (Status);
1826 }
1827 }
1828
1829 ParentTable = DtPeekSubtable ();
1830 DtInsertSubtable (ParentTable, Subtable);
1831
1832 while (*PFieldList)
1833 {
1834 SubtableStart = *PFieldList;
1835 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1836 &Subtable);
1837 if (ACPI_FAILURE (Status))
1838 {
1839 return (Status);
1840 }
1841
1842 ParentTable = DtPeekSubtable ();
1843 DtInsertSubtable (ParentTable, Subtable);
1844 DtPushSubtable (Subtable);
1845
1846 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1847
1848 switch (GtdtHeader->Type)
1849 {
1850 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1851
1852 InfoTable = AcpiDmTableInfoGtdt0;
1853 break;
1854
1855 case ACPI_GTDT_TYPE_WATCHDOG:
1856
1857 InfoTable = AcpiDmTableInfoGtdt1;
1858 break;
1859
1860 default:
1861
1862 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1863 return (AE_ERROR);
1864 }
1865
1866 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1867 if (ACPI_FAILURE (Status))
1868 {
1869 return (Status);
1870 }
1871
1872 ParentTable = DtPeekSubtable ();
1873 DtInsertSubtable (ParentTable, Subtable);
1874
1875 /*
1876 * Additional GT block subtable data
1877 */
1878
1879 switch (GtdtHeader->Type)
1880 {
1881 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1882
1883 DtPushSubtable (Subtable);
1884 ParentTable = DtPeekSubtable ();
1885
1886 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1887 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1888
1889 while (GtCount)
1890 {
1891 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1892 &Subtable);
1893 if (ACPI_FAILURE (Status))
1894 {
1895 return (Status);
1896 }
1897
1898 DtInsertSubtable (ParentTable, Subtable);
1899 GtCount--;
1900 }
1901
1902 DtPopSubtable ();
1903 break;
1904
1905 default:
1906
1907 break;
1908 }
1909
1910 DtPopSubtable ();
1911 }
1912
1913 return (AE_OK);
1914 }
1915
1916
1917 /******************************************************************************
1918 *
1919 * FUNCTION: DtCompileFpdt
1920 *
1921 * PARAMETERS: List - Current field list pointer
1922 *
1923 * RETURN: Status
1924 *
1925 * DESCRIPTION: Compile FPDT.
1926 *
1927 *****************************************************************************/
1928
1929 ACPI_STATUS
DtCompileFpdt(void ** List)1930 DtCompileFpdt (
1931 void **List)
1932 {
1933 ACPI_STATUS Status;
1934 ACPI_FPDT_HEADER *FpdtHeader;
1935 DT_SUBTABLE *Subtable;
1936 DT_SUBTABLE *ParentTable;
1937 ACPI_DMTABLE_INFO *InfoTable;
1938 DT_FIELD **PFieldList = (DT_FIELD **) List;
1939 DT_FIELD *SubtableStart;
1940
1941
1942 while (*PFieldList)
1943 {
1944 SubtableStart = *PFieldList;
1945 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1946 &Subtable);
1947 if (ACPI_FAILURE (Status))
1948 {
1949 return (Status);
1950 }
1951
1952 ParentTable = DtPeekSubtable ();
1953 DtInsertSubtable (ParentTable, Subtable);
1954 DtPushSubtable (Subtable);
1955
1956 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1957
1958 switch (FpdtHeader->Type)
1959 {
1960 case ACPI_FPDT_TYPE_BOOT:
1961
1962 InfoTable = AcpiDmTableInfoFpdt0;
1963 break;
1964
1965 case ACPI_FPDT_TYPE_S3PERF:
1966
1967 InfoTable = AcpiDmTableInfoFpdt1;
1968 break;
1969
1970 default:
1971
1972 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1973 return (AE_ERROR);
1974 break;
1975 }
1976
1977 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1978 if (ACPI_FAILURE (Status))
1979 {
1980 return (Status);
1981 }
1982
1983 ParentTable = DtPeekSubtable ();
1984 DtInsertSubtable (ParentTable, Subtable);
1985 DtPopSubtable ();
1986 }
1987
1988 return (AE_OK);
1989 }
1990
1991
1992 /******************************************************************************
1993 *
1994 * FUNCTION: DtCompileHest
1995 *
1996 * PARAMETERS: List - Current field list pointer
1997 *
1998 * RETURN: Status
1999 *
2000 * DESCRIPTION: Compile HEST.
2001 *
2002 *****************************************************************************/
2003
2004 ACPI_STATUS
DtCompileHest(void ** List)2005 DtCompileHest (
2006 void **List)
2007 {
2008 ACPI_STATUS Status;
2009 DT_SUBTABLE *Subtable;
2010 DT_SUBTABLE *ParentTable;
2011 DT_FIELD **PFieldList = (DT_FIELD **) List;
2012 DT_FIELD *SubtableStart;
2013 ACPI_DMTABLE_INFO *InfoTable;
2014 UINT16 Type;
2015 UINT32 BankCount;
2016
2017
2018 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
2019 &Subtable);
2020 if (ACPI_FAILURE (Status))
2021 {
2022 return (Status);
2023 }
2024
2025 ParentTable = DtPeekSubtable ();
2026 DtInsertSubtable (ParentTable, Subtable);
2027
2028 while (*PFieldList)
2029 {
2030 /* Get subtable type */
2031
2032 SubtableStart = *PFieldList;
2033 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
2034
2035 switch (Type)
2036 {
2037 case ACPI_HEST_TYPE_IA32_CHECK:
2038
2039 InfoTable = AcpiDmTableInfoHest0;
2040 break;
2041
2042 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
2043
2044 InfoTable = AcpiDmTableInfoHest1;
2045 break;
2046
2047 case ACPI_HEST_TYPE_IA32_NMI:
2048
2049 InfoTable = AcpiDmTableInfoHest2;
2050 break;
2051
2052 case ACPI_HEST_TYPE_AER_ROOT_PORT:
2053
2054 InfoTable = AcpiDmTableInfoHest6;
2055 break;
2056
2057 case ACPI_HEST_TYPE_AER_ENDPOINT:
2058
2059 InfoTable = AcpiDmTableInfoHest7;
2060 break;
2061
2062 case ACPI_HEST_TYPE_AER_BRIDGE:
2063
2064 InfoTable = AcpiDmTableInfoHest8;
2065 break;
2066
2067 case ACPI_HEST_TYPE_GENERIC_ERROR:
2068
2069 InfoTable = AcpiDmTableInfoHest9;
2070 break;
2071
2072 case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
2073
2074 InfoTable = AcpiDmTableInfoHest10;
2075 break;
2076
2077 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
2078
2079 InfoTable = AcpiDmTableInfoHest11;
2080 break;
2081
2082 default:
2083
2084 /* Cannot continue on unknown type */
2085
2086 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
2087 return (AE_ERROR);
2088 }
2089
2090 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2091 if (ACPI_FAILURE (Status))
2092 {
2093 return (Status);
2094 }
2095
2096 DtInsertSubtable (ParentTable, Subtable);
2097
2098 /*
2099 * Additional subtable data - IA32 Error Bank(s)
2100 */
2101 BankCount = 0;
2102 switch (Type)
2103 {
2104 case ACPI_HEST_TYPE_IA32_CHECK:
2105
2106 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
2107 Subtable->Buffer))->NumHardwareBanks;
2108 break;
2109
2110 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
2111
2112 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
2113 Subtable->Buffer))->NumHardwareBanks;
2114 break;
2115
2116 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
2117
2118 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
2119 Subtable->Buffer))->NumHardwareBanks;
2120 break;
2121
2122 default:
2123
2124 break;
2125 }
2126
2127 while (BankCount)
2128 {
2129 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
2130 &Subtable);
2131 if (ACPI_FAILURE (Status))
2132 {
2133 return (Status);
2134 }
2135
2136 DtInsertSubtable (ParentTable, Subtable);
2137 BankCount--;
2138 }
2139 }
2140
2141 return (AE_OK);
2142 }
2143
2144
2145 /******************************************************************************
2146 *
2147 * FUNCTION: DtCompileHmat
2148 *
2149 * PARAMETERS: List - Current field list pointer
2150 *
2151 * RETURN: Status
2152 *
2153 * DESCRIPTION: Compile HMAT.
2154 *
2155 *****************************************************************************/
2156
2157 ACPI_STATUS
DtCompileHmat(void ** List)2158 DtCompileHmat (
2159 void **List)
2160 {
2161 ACPI_STATUS Status;
2162 DT_SUBTABLE *Subtable;
2163 DT_SUBTABLE *ParentTable;
2164 DT_FIELD **PFieldList = (DT_FIELD **) List;
2165 DT_FIELD *SubtableStart;
2166 DT_FIELD *EntryStart;
2167 ACPI_HMAT_STRUCTURE *HmatStruct;
2168 ACPI_HMAT_LOCALITY *HmatLocality;
2169 ACPI_HMAT_CACHE *HmatCache;
2170 ACPI_DMTABLE_INFO *InfoTable;
2171 UINT32 IntPDNumber;
2172 UINT32 TgtPDNumber;
2173 UINT64 EntryNumber;
2174 UINT16 SMBIOSHandleNumber;
2175
2176
2177 ParentTable = DtPeekSubtable ();
2178
2179 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
2180 &Subtable);
2181 if (ACPI_FAILURE (Status))
2182 {
2183 return (Status);
2184 }
2185 DtInsertSubtable (ParentTable, Subtable);
2186
2187 while (*PFieldList)
2188 {
2189 /* Compile HMAT structure header */
2190
2191 SubtableStart = *PFieldList;
2192 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
2193 &Subtable);
2194 if (ACPI_FAILURE (Status))
2195 {
2196 return (Status);
2197 }
2198 DtInsertSubtable (ParentTable, Subtable);
2199
2200 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
2201 HmatStruct->Length = Subtable->Length;
2202
2203 /* Compile HMAT structure body */
2204
2205 switch (HmatStruct->Type)
2206 {
2207 case ACPI_HMAT_TYPE_ADDRESS_RANGE:
2208
2209 InfoTable = AcpiDmTableInfoHmat0;
2210 break;
2211
2212 case ACPI_HMAT_TYPE_LOCALITY:
2213
2214 InfoTable = AcpiDmTableInfoHmat1;
2215 break;
2216
2217 case ACPI_HMAT_TYPE_CACHE:
2218
2219 InfoTable = AcpiDmTableInfoHmat2;
2220 break;
2221
2222 default:
2223
2224 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
2225 return (AE_ERROR);
2226 }
2227
2228 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2229 if (ACPI_FAILURE (Status))
2230 {
2231 return (Status);
2232 }
2233 DtInsertSubtable (ParentTable, Subtable);
2234 HmatStruct->Length += Subtable->Length;
2235
2236 /* Compile HMAT structure additional */
2237
2238 switch (HmatStruct->Type)
2239 {
2240 case ACPI_HMAT_TYPE_LOCALITY:
2241
2242 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
2243 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2244
2245 /* Compile initiator proximity domain list */
2246
2247 IntPDNumber = 0;
2248 while (*PFieldList)
2249 {
2250 Status = DtCompileTable (PFieldList,
2251 AcpiDmTableInfoHmat1a, &Subtable);
2252 if (ACPI_FAILURE (Status))
2253 {
2254 return (Status);
2255 }
2256 if (!Subtable)
2257 {
2258 break;
2259 }
2260 DtInsertSubtable (ParentTable, Subtable);
2261 HmatStruct->Length += Subtable->Length;
2262 IntPDNumber++;
2263 }
2264 HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
2265
2266 /* Compile target proximity domain list */
2267
2268 TgtPDNumber = 0;
2269 while (*PFieldList)
2270 {
2271 Status = DtCompileTable (PFieldList,
2272 AcpiDmTableInfoHmat1b, &Subtable);
2273 if (ACPI_FAILURE (Status))
2274 {
2275 return (Status);
2276 }
2277 if (!Subtable)
2278 {
2279 break;
2280 }
2281 DtInsertSubtable (ParentTable, Subtable);
2282 HmatStruct->Length += Subtable->Length;
2283 TgtPDNumber++;
2284 }
2285 HmatLocality->NumberOfTargetPDs = TgtPDNumber;
2286
2287 /* Save start of the entries for reporting errors */
2288
2289 EntryStart = *PFieldList;
2290
2291 /* Compile latency/bandwidth entries */
2292
2293 EntryNumber = 0;
2294 while (*PFieldList)
2295 {
2296 Status = DtCompileTable (PFieldList,
2297 AcpiDmTableInfoHmat1c, &Subtable);
2298 if (ACPI_FAILURE (Status))
2299 {
2300 return (Status);
2301 }
2302 if (!Subtable)
2303 {
2304 break;
2305 }
2306 DtInsertSubtable (ParentTable, Subtable);
2307 HmatStruct->Length += Subtable->Length;
2308 EntryNumber++;
2309 }
2310
2311 /* Validate number of entries */
2312
2313 if (EntryNumber !=
2314 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
2315 {
2316 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
2317 return (AE_ERROR);
2318 }
2319 break;
2320
2321 case ACPI_HMAT_TYPE_CACHE:
2322
2323 /* Compile SMBIOS handles */
2324
2325 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
2326 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
2327 SMBIOSHandleNumber = 0;
2328 while (*PFieldList)
2329 {
2330 Status = DtCompileTable (PFieldList,
2331 AcpiDmTableInfoHmat2a, &Subtable);
2332 if (ACPI_FAILURE (Status))
2333 {
2334 return (Status);
2335 }
2336 if (!Subtable)
2337 {
2338 break;
2339 }
2340 DtInsertSubtable (ParentTable, Subtable);
2341 HmatStruct->Length += Subtable->Length;
2342 SMBIOSHandleNumber++;
2343 }
2344 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
2345 break;
2346
2347 default:
2348
2349 break;
2350 }
2351 }
2352
2353 return (AE_OK);
2354 }
2355
2356
2357 /******************************************************************************
2358 *
2359 * FUNCTION: DtCompileIort
2360 *
2361 * PARAMETERS: List - Current field list pointer
2362 *
2363 * RETURN: Status
2364 *
2365 * DESCRIPTION: Compile IORT.
2366 *
2367 *****************************************************************************/
2368
2369 ACPI_STATUS
DtCompileIort(void ** List)2370 DtCompileIort (
2371 void **List)
2372 {
2373 ACPI_STATUS Status;
2374 DT_SUBTABLE *Subtable;
2375 DT_SUBTABLE *ParentTable;
2376 DT_FIELD **PFieldList = (DT_FIELD **) List;
2377 DT_FIELD *SubtableStart;
2378 ACPI_TABLE_HEADER *Table;
2379 ACPI_TABLE_IORT *Iort;
2380 ACPI_IORT_NODE *IortNode;
2381 ACPI_IORT_ITS_GROUP *IortItsGroup;
2382 ACPI_IORT_SMMU *IortSmmu;
2383 ACPI_IORT_RMR *IortRmr;
2384 UINT32 NodeNumber;
2385 UINT32 NodeLength;
2386 UINT32 IdMappingNumber;
2387 UINT32 ItsNumber;
2388 UINT32 ContextIrptNumber;
2389 UINT32 PmuIrptNumber;
2390 UINT32 PaddingLength;
2391 UINT8 Revision;
2392 UINT32 RmrCount;
2393
2394
2395 ParentTable = DtPeekSubtable ();
2396
2397 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
2398 &Subtable);
2399 if (ACPI_FAILURE (Status))
2400 {
2401 return (Status);
2402 }
2403 DtInsertSubtable (ParentTable, Subtable);
2404
2405 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
2406 Revision = Table->Revision;
2407
2408 /* IORT Revisions E, E.a & E.c have known issues and are not supported */
2409
2410 if (Revision == 1 || Revision == 2 || Revision == 4)
2411 {
2412 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
2413 return (AE_ERROR);
2414 }
2415
2416 /*
2417 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
2418 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
2419 */
2420 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
2421 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
2422
2423 /*
2424 * OptionalPadding - Variable-length data
2425 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
2426 * Optionally allows the generic data types to be used for filling
2427 * this field.
2428 */
2429 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
2430 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
2431 &Subtable);
2432 if (ACPI_FAILURE (Status))
2433 {
2434 return (Status);
2435 }
2436 if (Subtable)
2437 {
2438 DtInsertSubtable (ParentTable, Subtable);
2439 Iort->NodeOffset += Subtable->Length;
2440 }
2441 else
2442 {
2443 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
2444 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
2445 if (ACPI_FAILURE (Status))
2446 {
2447 return (Status);
2448 }
2449 Iort->NodeOffset += PaddingLength;
2450 }
2451
2452 NodeNumber = 0;
2453 while (*PFieldList)
2454 {
2455 SubtableStart = *PFieldList;
2456 if (Revision == 0)
2457 {
2458 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
2459 &Subtable);
2460 }
2461 else if (Revision >= 3)
2462 {
2463 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
2464 &Subtable);
2465 }
2466
2467 if (ACPI_FAILURE (Status))
2468 {
2469 return (Status);
2470 }
2471
2472 DtInsertSubtable (ParentTable, Subtable);
2473 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
2474 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
2475
2476 DtPushSubtable (Subtable);
2477 ParentTable = DtPeekSubtable ();
2478
2479 switch (IortNode->Type)
2480 {
2481 case ACPI_IORT_NODE_ITS_GROUP:
2482
2483 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
2484 &Subtable);
2485 if (ACPI_FAILURE (Status))
2486 {
2487 return (Status);
2488 }
2489
2490 DtInsertSubtable (ParentTable, Subtable);
2491 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
2492 NodeLength += Subtable->Length;
2493
2494 ItsNumber = 0;
2495 while (*PFieldList)
2496 {
2497 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
2498 &Subtable);
2499 if (ACPI_FAILURE (Status))
2500 {
2501 return (Status);
2502 }
2503 if (!Subtable)
2504 {
2505 break;
2506 }
2507
2508 DtInsertSubtable (ParentTable, Subtable);
2509 NodeLength += Subtable->Length;
2510 ItsNumber++;
2511 }
2512
2513 IortItsGroup->ItsCount = ItsNumber;
2514 break;
2515
2516 case ACPI_IORT_NODE_NAMED_COMPONENT:
2517
2518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
2519 &Subtable);
2520 if (ACPI_FAILURE (Status))
2521 {
2522 return (Status);
2523 }
2524
2525 DtInsertSubtable (ParentTable, Subtable);
2526 NodeLength += Subtable->Length;
2527
2528 /*
2529 * Padding - Variable-length data
2530 * Optionally allows the offset of the ID mappings to be used
2531 * for filling this field.
2532 */
2533 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
2534 &Subtable);
2535 if (ACPI_FAILURE (Status))
2536 {
2537 return (Status);
2538 }
2539
2540 if (Subtable)
2541 {
2542 DtInsertSubtable (ParentTable, Subtable);
2543 NodeLength += Subtable->Length;
2544 }
2545 else
2546 {
2547 if (NodeLength > IortNode->MappingOffset)
2548 {
2549 return (AE_BAD_DATA);
2550 }
2551
2552 if (NodeLength < IortNode->MappingOffset)
2553 {
2554 Status = DtCompilePadding (
2555 IortNode->MappingOffset - NodeLength,
2556 &Subtable);
2557 if (ACPI_FAILURE (Status))
2558 {
2559 return (Status);
2560 }
2561
2562 DtInsertSubtable (ParentTable, Subtable);
2563 NodeLength = IortNode->MappingOffset;
2564 }
2565 }
2566 break;
2567
2568 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
2569
2570 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
2571 &Subtable);
2572 if (ACPI_FAILURE (Status))
2573 {
2574 return (Status);
2575 }
2576
2577 DtInsertSubtable (ParentTable, Subtable);
2578 NodeLength += Subtable->Length;
2579 break;
2580
2581 case ACPI_IORT_NODE_SMMU:
2582
2583 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
2584 &Subtable);
2585 if (ACPI_FAILURE (Status))
2586 {
2587 return (Status);
2588 }
2589
2590 DtInsertSubtable (ParentTable, Subtable);
2591 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
2592 NodeLength += Subtable->Length;
2593
2594 /* Compile global interrupt array */
2595
2596 IortSmmu->GlobalInterruptOffset = NodeLength;
2597 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
2598 &Subtable);
2599 if (ACPI_FAILURE (Status))
2600 {
2601 return (Status);
2602 }
2603
2604 DtInsertSubtable (ParentTable, Subtable);
2605 NodeLength += Subtable->Length;
2606
2607 /* Compile context interrupt array */
2608
2609 ContextIrptNumber = 0;
2610 IortSmmu->ContextInterruptOffset = NodeLength;
2611 while (*PFieldList)
2612 {
2613 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
2614 &Subtable);
2615 if (ACPI_FAILURE (Status))
2616 {
2617 return (Status);
2618 }
2619
2620 if (!Subtable)
2621 {
2622 break;
2623 }
2624
2625 DtInsertSubtable (ParentTable, Subtable);
2626 NodeLength += Subtable->Length;
2627 ContextIrptNumber++;
2628 }
2629
2630 IortSmmu->ContextInterruptCount = ContextIrptNumber;
2631
2632 /* Compile PMU interrupt array */
2633
2634 PmuIrptNumber = 0;
2635 IortSmmu->PmuInterruptOffset = NodeLength;
2636 while (*PFieldList)
2637 {
2638 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
2639 &Subtable);
2640 if (ACPI_FAILURE (Status))
2641 {
2642 return (Status);
2643 }
2644
2645 if (!Subtable)
2646 {
2647 break;
2648 }
2649
2650 DtInsertSubtable (ParentTable, Subtable);
2651 NodeLength += Subtable->Length;
2652 PmuIrptNumber++;
2653 }
2654
2655 IortSmmu->PmuInterruptCount = PmuIrptNumber;
2656 break;
2657
2658 case ACPI_IORT_NODE_SMMU_V3:
2659
2660 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
2661 &Subtable);
2662 if (ACPI_FAILURE (Status))
2663 {
2664 return (Status);
2665 }
2666
2667 DtInsertSubtable (ParentTable, Subtable);
2668 NodeLength += Subtable->Length;
2669 break;
2670
2671 case ACPI_IORT_NODE_PMCG:
2672
2673 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
2674 &Subtable);
2675 if (ACPI_FAILURE (Status))
2676 {
2677 return (Status);
2678 }
2679
2680 DtInsertSubtable (ParentTable, Subtable);
2681 NodeLength += Subtable->Length;
2682 break;
2683
2684 case ACPI_IORT_NODE_RMR:
2685
2686 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
2687 &Subtable);
2688 if (ACPI_FAILURE (Status))
2689 {
2690 return (Status);
2691 }
2692
2693 DtInsertSubtable (ParentTable, Subtable);
2694 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
2695 NodeLength += Subtable->Length;
2696
2697 /* Compile RMR Descriptors */
2698
2699 RmrCount = 0;
2700 IortRmr->RmrOffset = NodeLength;
2701 while (*PFieldList)
2702 {
2703 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
2704 &Subtable);
2705 if (ACPI_FAILURE (Status))
2706 {
2707 return (Status);
2708 }
2709
2710 if (!Subtable)
2711 {
2712 break;
2713 }
2714
2715 DtInsertSubtable (ParentTable, Subtable);
2716 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
2717 RmrCount++;
2718 }
2719
2720 IortRmr->RmrCount = RmrCount;
2721 break;
2722
2723 default:
2724
2725 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
2726 return (AE_ERROR);
2727 }
2728
2729 /* Compile Array of ID mappings */
2730
2731 IortNode->MappingOffset = NodeLength;
2732 IdMappingNumber = 0;
2733 while (*PFieldList)
2734 {
2735 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
2736 &Subtable);
2737 if (ACPI_FAILURE (Status))
2738 {
2739 return (Status);
2740 }
2741
2742 if (!Subtable)
2743 {
2744 break;
2745 }
2746
2747 DtInsertSubtable (ParentTable, Subtable);
2748 NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
2749 IdMappingNumber++;
2750 }
2751
2752 IortNode->MappingCount = IdMappingNumber;
2753 if (!IdMappingNumber)
2754 {
2755 IortNode->MappingOffset = 0;
2756 }
2757
2758 /*
2759 * Node length can be determined by DT_LENGTH option
2760 * IortNode->Length = NodeLength;
2761 */
2762 DtPopSubtable ();
2763 ParentTable = DtPeekSubtable ();
2764 NodeNumber++;
2765 }
2766
2767 Iort->NodeCount = NodeNumber;
2768 return (AE_OK);
2769 }
2770
2771
2772 /******************************************************************************
2773 *
2774 * FUNCTION: DtCompileIvrs
2775 *
2776 * PARAMETERS: List - Current field list pointer
2777 *
2778 * RETURN: Status
2779 *
2780 * DESCRIPTION: Compile IVRS. Notes:
2781 * The IVRS is essentially a flat table, with the following
2782 * structure:
2783 * <Main ACPI Table Header>
2784 * <Main subtable - virtualization info>
2785 * <IVHD>
2786 * <Device Entries>
2787 * ...
2788 * <IVHD>
2789 * <Device Entries>
2790 * <IVMD>
2791 * ...
2792 *
2793 *****************************************************************************/
2794
2795 ACPI_STATUS
DtCompileIvrs(void ** List)2796 DtCompileIvrs (
2797 void **List)
2798 {
2799 ACPI_STATUS Status;
2800 DT_SUBTABLE *Subtable;
2801 DT_SUBTABLE *ParentTable;
2802 DT_SUBTABLE *MainSubtable;
2803 DT_FIELD **PFieldList = (DT_FIELD **) List;
2804 DT_FIELD *SubtableStart;
2805 ACPI_DMTABLE_INFO *InfoTable = NULL;
2806 UINT8 SubtableType;
2807 UINT8 Temp64[16];
2808 UINT8 Temp8;
2809
2810
2811 /* Main table */
2812
2813 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
2814 &Subtable);
2815 if (ACPI_FAILURE (Status))
2816 {
2817 return (Status);
2818 }
2819
2820 ParentTable = DtPeekSubtable ();
2821 DtInsertSubtable (ParentTable, Subtable);
2822 DtPushSubtable (Subtable);
2823
2824 /* Save a pointer to the main subtable */
2825
2826 MainSubtable = Subtable;
2827
2828 while (*PFieldList)
2829 {
2830 SubtableStart = *PFieldList;
2831
2832 /* Compile the SubtableType integer */
2833
2834 DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
2835
2836 switch (SubtableType)
2837 {
2838
2839 /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
2840
2841 case ACPI_IVRS_TYPE_HARDWARE1:
2842
2843 InfoTable = AcpiDmTableInfoIvrsHware1;
2844 break;
2845
2846 /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
2847
2848 case ACPI_IVRS_TYPE_HARDWARE2:
2849 case ACPI_IVRS_TYPE_HARDWARE3:
2850
2851 InfoTable = AcpiDmTableInfoIvrsHware23;
2852 break;
2853
2854 /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
2855
2856 case ACPI_IVRS_TYPE_MEMORY1:
2857 case ACPI_IVRS_TYPE_MEMORY2:
2858 case ACPI_IVRS_TYPE_MEMORY3:
2859
2860 InfoTable = AcpiDmTableInfoIvrsMemory;
2861 break;
2862
2863 /* 4-byte device entries */
2864
2865 case ACPI_IVRS_TYPE_PAD4:
2866 case ACPI_IVRS_TYPE_ALL:
2867 case ACPI_IVRS_TYPE_SELECT:
2868 case ACPI_IVRS_TYPE_START:
2869 case ACPI_IVRS_TYPE_END:
2870
2871 InfoTable = AcpiDmTableInfoIvrs4;
2872 break;
2873
2874 /* 8-byte device entries, type A */
2875
2876 case ACPI_IVRS_TYPE_ALIAS_SELECT:
2877 case ACPI_IVRS_TYPE_ALIAS_START:
2878
2879 InfoTable = AcpiDmTableInfoIvrs8a;
2880 break;
2881
2882 /* 8-byte device entries, type B */
2883
2884 case ACPI_IVRS_TYPE_EXT_SELECT:
2885 case ACPI_IVRS_TYPE_EXT_START:
2886
2887 InfoTable = AcpiDmTableInfoIvrs8b;
2888 break;
2889
2890 /* 8-byte device entries, type C */
2891
2892 case ACPI_IVRS_TYPE_SPECIAL:
2893
2894 InfoTable = AcpiDmTableInfoIvrs8c;
2895 break;
2896
2897 /* Variable device entries, type F0h */
2898
2899 case ACPI_IVRS_TYPE_HID:
2900
2901 InfoTable = AcpiDmTableInfoIvrsHid;
2902 break;
2903
2904 default:
2905
2906 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
2907 "IVRS Device Entry");
2908 return (AE_ERROR);
2909 }
2910
2911 /* Compile the InfoTable from above */
2912
2913 Status = DtCompileTable (PFieldList, InfoTable,
2914 &Subtable);
2915 if (ACPI_FAILURE (Status))
2916 {
2917 return (Status);
2918 }
2919
2920 ParentTable = DtPeekSubtable ();
2921 if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
2922 SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
2923 SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
2924 SubtableType != ACPI_IVRS_TYPE_HID &&
2925 SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
2926 SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
2927 SubtableType != ACPI_IVRS_TYPE_MEMORY3)
2928 {
2929 if (ParentTable)
2930 DtInsertSubtable (ParentTable, Subtable);
2931 }
2932
2933 switch (SubtableType)
2934 {
2935 case ACPI_IVRS_TYPE_HARDWARE1:
2936 case ACPI_IVRS_TYPE_HARDWARE2:
2937 case ACPI_IVRS_TYPE_HARDWARE3:
2938 case ACPI_IVRS_TYPE_MEMORY1:
2939 case ACPI_IVRS_TYPE_MEMORY2:
2940 case ACPI_IVRS_TYPE_MEMORY3:
2941
2942 /* Insert these IVHDs/IVMDs at the root subtable */
2943
2944 DtInsertSubtable (MainSubtable, Subtable);
2945 DtPushSubtable (Subtable);
2946 break;
2947
2948 case ACPI_IVRS_TYPE_HID:
2949
2950 /* Special handling for the HID named device entry (0xF0) */
2951
2952 if (ParentTable)
2953 {
2954 DtInsertSubtable (ParentTable, Subtable);
2955 }
2956
2957 /*
2958 * Process the HID value. First, get the HID value as a string.
2959 */
2960 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
2961
2962 /*
2963 * Determine if the HID is an integer or a string.
2964 * An integer is defined to be 32 bits, with the upper 32 bits
2965 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
2966 * integer or a character string. If an integer, the lower
2967 * 4 bytes of the field contain the integer and the upper
2968 * 4 bytes are padded with 0".
2969 */
2970 if (UtIsIdInteger ((UINT8 *) &Temp64))
2971 {
2972 /* Compile the HID value as an integer */
2973
2974 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
2975
2976 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
2977 &Subtable);
2978 if (ACPI_FAILURE (Status))
2979 {
2980 return (Status);
2981 }
2982 }
2983 else
2984 {
2985 /* Compile the HID value as a string */
2986
2987 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
2988 &Subtable);
2989 if (ACPI_FAILURE (Status))
2990 {
2991 return (Status);
2992 }
2993 }
2994
2995 DtInsertSubtable (ParentTable, Subtable);
2996
2997 /*
2998 * Process the CID value. First, get the CID value as a string.
2999 */
3000 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
3001
3002 if (UtIsIdInteger ((UINT8 *) &Temp64))
3003 {
3004 /* Compile the CID value as an integer */
3005
3006 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
3007
3008 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
3009 &Subtable);
3010 if (ACPI_FAILURE (Status))
3011 {
3012 return (Status);
3013 }
3014 }
3015 else
3016 {
3017 /* Compile the CID value as a string */
3018
3019 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
3020 &Subtable);
3021 if (ACPI_FAILURE (Status))
3022 {
3023 return (Status);
3024 }
3025 }
3026
3027 DtInsertSubtable (ParentTable, Subtable);
3028
3029 /*
3030 * Process the UID value. First, get and decode the "UID Format" field (Integer).
3031 */
3032 if (!*PFieldList)
3033 {
3034 return (AE_OK);
3035 }
3036
3037 DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
3038
3039 switch (Temp8)
3040 {
3041 case ACPI_IVRS_UID_NOT_PRESENT:
3042 break;
3043
3044 case ACPI_IVRS_UID_IS_INTEGER:
3045
3046 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
3047 &Subtable);
3048 if (ACPI_FAILURE (Status))
3049 {
3050 return (Status);
3051 }
3052 DtInsertSubtable (ParentTable, Subtable);
3053 break;
3054
3055 case ACPI_IVRS_UID_IS_STRING:
3056
3057 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
3058 &Subtable);
3059 if (ACPI_FAILURE (Status))
3060 {
3061 return (Status);
3062 }
3063 DtInsertSubtable (ParentTable, Subtable);
3064 break;
3065
3066 default:
3067
3068 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
3069 "IVRS Device Entry");
3070 return (AE_ERROR);
3071 }
3072
3073 default:
3074
3075 /* All other subtable types come through here */
3076 break;
3077 }
3078 }
3079
3080 return (AE_OK);
3081 }
3082