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