dttable1.c revision 1.1.1.11 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: DtCompileAsf
68 *
69 * PARAMETERS: List - Current field list pointer
70 *
71 * RETURN: Status
72 *
73 * DESCRIPTION: Compile ASF!.
74 *
75 *****************************************************************************/
76
77 ACPI_STATUS
78 DtCompileAsf (
79 void **List)
80 {
81 ACPI_ASF_INFO *AsfTable;
82 DT_SUBTABLE *Subtable;
83 DT_SUBTABLE *ParentTable;
84 ACPI_DMTABLE_INFO *InfoTable;
85 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
86 UINT32 DataCount = 0;
87 ACPI_STATUS Status;
88 UINT32 i;
89 DT_FIELD **PFieldList = (DT_FIELD **) List;
90 DT_FIELD *SubtableStart;
91
92
93 while (*PFieldList)
94 {
95 SubtableStart = *PFieldList;
96 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
97 &Subtable);
98 if (ACPI_FAILURE (Status))
99 {
100 return (Status);
101 }
102
103 ParentTable = DtPeekSubtable ();
104 DtInsertSubtable (ParentTable, Subtable);
105 DtPushSubtable (Subtable);
106
107 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
108
109 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
110 {
111 case ACPI_ASF_TYPE_INFO:
112
113 InfoTable = AcpiDmTableInfoAsf0;
114 break;
115
116 case ACPI_ASF_TYPE_ALERT:
117
118 InfoTable = AcpiDmTableInfoAsf1;
119 break;
120
121 case ACPI_ASF_TYPE_CONTROL:
122
123 InfoTable = AcpiDmTableInfoAsf2;
124 break;
125
126 case ACPI_ASF_TYPE_BOOT:
127
128 InfoTable = AcpiDmTableInfoAsf3;
129 break;
130
131 case ACPI_ASF_TYPE_ADDRESS:
132
133 InfoTable = AcpiDmTableInfoAsf4;
134 break;
135
136 default:
137
138 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
139 return (AE_ERROR);
140 }
141
142 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
143 if (ACPI_FAILURE (Status))
144 {
145 return (Status);
146 }
147
148 ParentTable = DtPeekSubtable ();
149 DtInsertSubtable (ParentTable, Subtable);
150
151 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
152 {
153 case ACPI_ASF_TYPE_INFO:
154
155 DataInfoTable = NULL;
156 break;
157
158 case ACPI_ASF_TYPE_ALERT:
159
160 DataInfoTable = AcpiDmTableInfoAsf1a;
161 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
162 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
163 sizeof (ACPI_ASF_HEADER)))->Alerts;
164 break;
165
166 case ACPI_ASF_TYPE_CONTROL:
167
168 DataInfoTable = AcpiDmTableInfoAsf2a;
169 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
170 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
171 sizeof (ACPI_ASF_HEADER)))->Controls;
172 break;
173
174 case ACPI_ASF_TYPE_BOOT:
175
176 DataInfoTable = NULL;
177 break;
178
179 case ACPI_ASF_TYPE_ADDRESS:
180
181 DataInfoTable = TableInfoAsfAddress;
182 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
183 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
184 sizeof (ACPI_ASF_HEADER)))->Devices;
185 break;
186
187 default:
188
189 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
190 return (AE_ERROR);
191 }
192
193 if (DataInfoTable)
194 {
195 switch (AsfTable->Header.Type & 0x7F)
196 {
197 case ACPI_ASF_TYPE_ADDRESS:
198
199 while (DataCount > 0)
200 {
201 Status = DtCompileTable (PFieldList, DataInfoTable,
202 &Subtable);
203 if (ACPI_FAILURE (Status))
204 {
205 return (Status);
206 }
207
208 DtInsertSubtable (ParentTable, Subtable);
209 DataCount = DataCount - Subtable->Length;
210 }
211 break;
212
213 default:
214
215 for (i = 0; i < DataCount; i++)
216 {
217 Status = DtCompileTable (PFieldList, DataInfoTable,
218 &Subtable);
219 if (ACPI_FAILURE (Status))
220 {
221 return (Status);
222 }
223
224 DtInsertSubtable (ParentTable, Subtable);
225 }
226 break;
227 }
228 }
229
230 DtPopSubtable ();
231 }
232
233 return (AE_OK);
234 }
235
236
237 /******************************************************************************
238 *
239 * FUNCTION: DtCompileCedt
240 *
241 * PARAMETERS: List - Current field list pointer
242 *
243 * RETURN: Status
244 *
245 * DESCRIPTION: Compile CEDT.
246 *
247 *****************************************************************************/
248
249 ACPI_STATUS
250 DtCompileCedt (
251 void **List)
252 {
253 ACPI_STATUS Status;
254 DT_SUBTABLE *Subtable;
255 DT_SUBTABLE *ParentTable;
256 DT_FIELD **PFieldList = (DT_FIELD **) List;
257 ACPI_CEDT_HEADER *CedtHeader;
258 DT_FIELD *SubtableStart;
259
260
261 /* Walk the parse tree */
262
263 while (*PFieldList)
264 {
265 SubtableStart = *PFieldList;
266
267 /* CEDT Header */
268
269 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
270 &Subtable);
271 if (ACPI_FAILURE (Status))
272 {
273 return (Status);
274 }
275
276 ParentTable = DtPeekSubtable ();
277 DtInsertSubtable (ParentTable, Subtable);
278 DtPushSubtable (Subtable);
279
280 CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
281
282 switch (CedtHeader->Type)
283 {
284 case ACPI_CEDT_TYPE_CHBS:
285
286 break;
287
288 default:
289
290 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
291 return (AE_ERROR);
292 }
293
294 /* CEDT Subtable */
295
296 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
297 if (ACPI_FAILURE (Status))
298 {
299 return (Status);
300 }
301
302 ParentTable = DtPeekSubtable ();
303 DtInsertSubtable (ParentTable, Subtable);
304 DtPopSubtable ();
305 }
306
307 return (AE_OK);
308 }
309
310
311 /******************************************************************************
312 *
313 * FUNCTION: DtCompileCpep
314 *
315 * PARAMETERS: List - Current field list pointer
316 *
317 * RETURN: Status
318 *
319 * DESCRIPTION: Compile CPEP.
320 *
321 *****************************************************************************/
322
323 ACPI_STATUS
324 DtCompileCpep (
325 void **List)
326 {
327 ACPI_STATUS Status;
328
329
330 Status = DtCompileTwoSubtables (List,
331 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
332 return (Status);
333 }
334
335
336 /******************************************************************************
337 *
338 * FUNCTION: DtCompileCsrt
339 *
340 * PARAMETERS: List - Current field list pointer
341 *
342 * RETURN: Status
343 *
344 * DESCRIPTION: Compile CSRT.
345 *
346 *****************************************************************************/
347
348 ACPI_STATUS
349 DtCompileCsrt (
350 void **List)
351 {
352 ACPI_STATUS Status = AE_OK;
353 DT_SUBTABLE *Subtable;
354 DT_SUBTABLE *ParentTable;
355 DT_FIELD **PFieldList = (DT_FIELD **) List;
356 UINT32 DescriptorCount;
357 UINT32 GroupLength;
358
359
360 /* Subtables (Resource Groups) */
361
362 ParentTable = DtPeekSubtable ();
363 while (*PFieldList)
364 {
365 /* Resource group subtable */
366
367 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
368 &Subtable);
369 if (ACPI_FAILURE (Status))
370 {
371 return (Status);
372 }
373
374 /* Compute the number of resource descriptors */
375
376 GroupLength =
377 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
378 Subtable->Buffer))->Length -
379 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
380 Subtable->Buffer))->SharedInfoLength -
381 sizeof (ACPI_CSRT_GROUP);
382
383 DescriptorCount = (GroupLength /
384 sizeof (ACPI_CSRT_DESCRIPTOR));
385
386 DtInsertSubtable (ParentTable, Subtable);
387 DtPushSubtable (Subtable);
388 ParentTable = DtPeekSubtable ();
389
390 /* Shared info subtable (One per resource group) */
391
392 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
393 &Subtable);
394 if (ACPI_FAILURE (Status))
395 {
396 return (Status);
397 }
398
399 DtInsertSubtable (ParentTable, Subtable);
400
401 /* Sub-Subtables (Resource Descriptors) */
402
403 while (*PFieldList && DescriptorCount)
404 {
405
406 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
407 &Subtable);
408 if (ACPI_FAILURE (Status))
409 {
410 return (Status);
411 }
412
413 DtInsertSubtable (ParentTable, Subtable);
414
415 DtPushSubtable (Subtable);
416 ParentTable = DtPeekSubtable ();
417 if (*PFieldList)
418 {
419 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
420 &Subtable);
421 if (ACPI_FAILURE (Status))
422 {
423 return (Status);
424 }
425 if (Subtable)
426 {
427 DtInsertSubtable (ParentTable, Subtable);
428 }
429 }
430
431 DtPopSubtable ();
432 ParentTable = DtPeekSubtable ();
433 DescriptorCount--;
434 }
435
436 DtPopSubtable ();
437 ParentTable = DtPeekSubtable ();
438 }
439
440 return (Status);
441 }
442
443
444 /******************************************************************************
445 *
446 * FUNCTION: DtCompileDbg2
447 *
448 * PARAMETERS: List - Current field list pointer
449 *
450 * RETURN: Status
451 *
452 * DESCRIPTION: Compile DBG2.
453 *
454 *****************************************************************************/
455
456 ACPI_STATUS
457 DtCompileDbg2 (
458 void **List)
459 {
460 ACPI_STATUS Status;
461 DT_SUBTABLE *Subtable;
462 DT_SUBTABLE *ParentTable;
463 DT_FIELD **PFieldList = (DT_FIELD **) List;
464 UINT32 SubtableCount;
465 ACPI_DBG2_HEADER *Dbg2Header;
466 ACPI_DBG2_DEVICE *DeviceInfo;
467 UINT16 CurrentOffset;
468 UINT32 i;
469
470
471 /* Main table */
472
473 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
474 if (ACPI_FAILURE (Status))
475 {
476 return (Status);
477 }
478
479 ParentTable = DtPeekSubtable ();
480 DtInsertSubtable (ParentTable, Subtable);
481
482 /* Main table fields */
483
484 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
485 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
486 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
487
488 SubtableCount = Dbg2Header->InfoCount;
489 DtPushSubtable (Subtable);
490
491 /* Process all Device Information subtables (Count = InfoCount) */
492
493 while (*PFieldList && SubtableCount)
494 {
495 /* Subtable: Debug Device Information */
496
497 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
498 &Subtable);
499 if (ACPI_FAILURE (Status))
500 {
501 return (Status);
502 }
503
504 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
505 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
506
507 ParentTable = DtPeekSubtable ();
508 DtInsertSubtable (ParentTable, Subtable);
509 DtPushSubtable (Subtable);
510
511 ParentTable = DtPeekSubtable ();
512
513 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
514
515 DeviceInfo->BaseAddressOffset = CurrentOffset;
516 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
517 {
518 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
519 &Subtable);
520 if (ACPI_FAILURE (Status))
521 {
522 return (Status);
523 }
524
525 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
526 DtInsertSubtable (ParentTable, Subtable);
527 }
528
529 /* AddressSize array (Required, size = RegisterCount) */
530
531 DeviceInfo->AddressSizeOffset = CurrentOffset;
532 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
533 {
534 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
535 &Subtable);
536 if (ACPI_FAILURE (Status))
537 {
538 return (Status);
539 }
540
541 CurrentOffset += (UINT16) sizeof (UINT32);
542 DtInsertSubtable (ParentTable, Subtable);
543 }
544
545 /* NamespaceString device identifier (Required, size = NamePathLength) */
546
547 DeviceInfo->NamepathOffset = CurrentOffset;
548 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
549 &Subtable);
550 if (ACPI_FAILURE (Status))
551 {
552 return (Status);
553 }
554
555 /* Update the device info header */
556
557 DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
558 CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
559 DtInsertSubtable (ParentTable, Subtable);
560
561 /* OemData - Variable-length data (Optional, size = OemDataLength) */
562
563 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
564 &Subtable);
565 if (Status == AE_END_OF_TABLE)
566 {
567 /* optional field was not found and we're at the end of the file */
568
569 goto subtableDone;
570 }
571 else if (ACPI_FAILURE (Status))
572 {
573 return (Status);
574 }
575
576 /* Update the device info header (zeros if no OEM data present) */
577
578 DeviceInfo->OemDataOffset = 0;
579 DeviceInfo->OemDataLength = 0;
580
581 /* Optional subtable (OemData) */
582
583 if (Subtable && Subtable->Length)
584 {
585 DeviceInfo->OemDataOffset = CurrentOffset;
586 DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
587
588 DtInsertSubtable (ParentTable, Subtable);
589 }
590 subtableDone:
591 SubtableCount--;
592 DtPopSubtable (); /* Get next Device Information subtable */
593 }
594
595 DtPopSubtable ();
596 return (AE_OK);
597 }
598
599
600 /******************************************************************************
601 *
602 * FUNCTION: DtCompileDmar
603 *
604 * PARAMETERS: List - Current field list pointer
605 *
606 * RETURN: Status
607 *
608 * DESCRIPTION: Compile DMAR.
609 *
610 *****************************************************************************/
611
612 ACPI_STATUS
613 DtCompileDmar (
614 void **List)
615 {
616 ACPI_STATUS Status;
617 DT_SUBTABLE *Subtable;
618 DT_SUBTABLE *ParentTable;
619 DT_FIELD **PFieldList = (DT_FIELD **) List;
620 DT_FIELD *SubtableStart;
621 ACPI_DMTABLE_INFO *InfoTable;
622 ACPI_DMAR_HEADER *DmarHeader;
623 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
624 UINT32 DeviceScopeLength;
625 UINT32 PciPathLength;
626
627
628 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
629 if (ACPI_FAILURE (Status))
630 {
631 return (Status);
632 }
633
634 ParentTable = DtPeekSubtable ();
635 DtInsertSubtable (ParentTable, Subtable);
636 DtPushSubtable (Subtable);
637
638 while (*PFieldList)
639 {
640 /* DMAR Header */
641
642 SubtableStart = *PFieldList;
643 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
644 &Subtable);
645 if (ACPI_FAILURE (Status))
646 {
647 return (Status);
648 }
649
650 ParentTable = DtPeekSubtable ();
651 DtInsertSubtable (ParentTable, Subtable);
652 DtPushSubtable (Subtable);
653
654 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
655
656 switch (DmarHeader->Type)
657 {
658 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
659
660 InfoTable = AcpiDmTableInfoDmar0;
661 break;
662
663 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
664
665 InfoTable = AcpiDmTableInfoDmar1;
666 break;
667
668 case ACPI_DMAR_TYPE_ROOT_ATS:
669
670 InfoTable = AcpiDmTableInfoDmar2;
671 break;
672
673 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
674
675 InfoTable = AcpiDmTableInfoDmar3;
676 break;
677
678 case ACPI_DMAR_TYPE_NAMESPACE:
679
680 InfoTable = AcpiDmTableInfoDmar4;
681 break;
682
683 default:
684
685 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
686 return (AE_ERROR);
687 }
688
689 /* DMAR Subtable */
690
691 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
692 if (ACPI_FAILURE (Status))
693 {
694 return (Status);
695 }
696
697 ParentTable = DtPeekSubtable ();
698 DtInsertSubtable (ParentTable, Subtable);
699
700 /*
701 * Optional Device Scope subtables
702 */
703 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
704 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
705 {
706 /* These types do not support device scopes */
707
708 DtPopSubtable ();
709 continue;
710 }
711
712 DtPushSubtable (Subtable);
713 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
714 ParentTable->Length;
715 while (DeviceScopeLength)
716 {
717 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
718 &Subtable);
719 if (Status == AE_NOT_FOUND)
720 {
721 break;
722 }
723
724 ParentTable = DtPeekSubtable ();
725 DtInsertSubtable (ParentTable, Subtable);
726 DtPushSubtable (Subtable);
727
728 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
729
730 /* Optional PCI Paths */
731
732 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
733 while (PciPathLength)
734 {
735 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
736 &Subtable);
737 if (Status == AE_NOT_FOUND)
738 {
739 DtPopSubtable ();
740 break;
741 }
742
743 ParentTable = DtPeekSubtable ();
744 DtInsertSubtable (ParentTable, Subtable);
745 PciPathLength -= Subtable->Length;
746 }
747
748 DtPopSubtable ();
749 DeviceScopeLength -= DmarDeviceScope->Length;
750 }
751
752 DtPopSubtable ();
753 DtPopSubtable ();
754 }
755
756 return (AE_OK);
757 }
758
759
760 /******************************************************************************
761 *
762 * FUNCTION: DtCompileDrtm
763 *
764 * PARAMETERS: List - Current field list pointer
765 *
766 * RETURN: Status
767 *
768 * DESCRIPTION: Compile DRTM.
769 *
770 *****************************************************************************/
771
772 ACPI_STATUS
773 DtCompileDrtm (
774 void **List)
775 {
776 ACPI_STATUS Status;
777 DT_SUBTABLE *Subtable;
778 DT_SUBTABLE *ParentTable;
779 DT_FIELD **PFieldList = (DT_FIELD **) List;
780 UINT32 Count;
781 /* ACPI_TABLE_DRTM *Drtm; */
782 ACPI_DRTM_VTABLE_LIST *DrtmVtl;
783 ACPI_DRTM_RESOURCE_LIST *DrtmRl;
784 /* ACPI_DRTM_DPS_ID *DrtmDps; */
785
786
787 ParentTable = DtPeekSubtable ();
788
789 /* Compile DRTM header */
790
791 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
792 &Subtable);
793 if (ACPI_FAILURE (Status))
794 {
795 return (Status);
796 }
797 DtInsertSubtable (ParentTable, Subtable);
798
799 /*
800 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
801 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
802 */
803 #if 0
804 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
805 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
806 #endif
807 /* Compile VTL */
808
809 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
810 &Subtable);
811 if (ACPI_FAILURE (Status))
812 {
813 return (Status);
814 }
815
816 DtInsertSubtable (ParentTable, Subtable);
817 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
818
819 DtPushSubtable (Subtable);
820 ParentTable = DtPeekSubtable ();
821 Count = 0;
822
823 while (*PFieldList)
824 {
825 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
826 &Subtable);
827 if (ACPI_FAILURE (Status))
828 {
829 return (Status);
830 }
831 if (!Subtable)
832 {
833 break;
834 }
835 DtInsertSubtable (ParentTable, Subtable);
836 Count++;
837 }
838
839 DrtmVtl->ValidatedTableCount = Count;
840 DtPopSubtable ();
841 ParentTable = DtPeekSubtable ();
842
843 /* Compile RL */
844
845 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
846 &Subtable);
847 if (ACPI_FAILURE (Status))
848 {
849 return (Status);
850 }
851
852 DtInsertSubtable (ParentTable, Subtable);
853 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
854
855 DtPushSubtable (Subtable);
856 ParentTable = DtPeekSubtable ();
857 Count = 0;
858
859 while (*PFieldList)
860 {
861 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
862 &Subtable);
863 if (ACPI_FAILURE (Status))
864 {
865 return (Status);
866 }
867
868 if (!Subtable)
869 {
870 break;
871 }
872
873 DtInsertSubtable (ParentTable, Subtable);
874 Count++;
875 }
876
877 DrtmRl->ResourceCount = Count;
878 DtPopSubtable ();
879 ParentTable = DtPeekSubtable ();
880
881 /* Compile DPS */
882
883 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
884 &Subtable);
885 if (ACPI_FAILURE (Status))
886 {
887 return (Status);
888 }
889 DtInsertSubtable (ParentTable, Subtable);
890 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
891
892
893 return (AE_OK);
894 }
895
896
897 /******************************************************************************
898 *
899 * FUNCTION: DtCompileEinj
900 *
901 * PARAMETERS: List - Current field list pointer
902 *
903 * RETURN: Status
904 *
905 * DESCRIPTION: Compile EINJ.
906 *
907 *****************************************************************************/
908
909 ACPI_STATUS
910 DtCompileEinj (
911 void **List)
912 {
913 ACPI_STATUS Status;
914
915
916 Status = DtCompileTwoSubtables (List,
917 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
918 return (Status);
919 }
920
921
922 /******************************************************************************
923 *
924 * FUNCTION: DtCompileErst
925 *
926 * PARAMETERS: List - Current field list pointer
927 *
928 * RETURN: Status
929 *
930 * DESCRIPTION: Compile ERST.
931 *
932 *****************************************************************************/
933
934 ACPI_STATUS
935 DtCompileErst (
936 void **List)
937 {
938 ACPI_STATUS Status;
939
940
941 Status = DtCompileTwoSubtables (List,
942 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
943 return (Status);
944 }
945
946
947 /******************************************************************************
948 *
949 * FUNCTION: DtCompileGtdt
950 *
951 * PARAMETERS: List - Current field list pointer
952 *
953 * RETURN: Status
954 *
955 * DESCRIPTION: Compile GTDT.
956 *
957 *****************************************************************************/
958
959 ACPI_STATUS
960 DtCompileGtdt (
961 void **List)
962 {
963 ACPI_STATUS Status;
964 DT_SUBTABLE *Subtable;
965 DT_SUBTABLE *ParentTable;
966 DT_FIELD **PFieldList = (DT_FIELD **) List;
967 DT_FIELD *SubtableStart;
968 ACPI_SUBTABLE_HEADER *GtdtHeader;
969 ACPI_DMTABLE_INFO *InfoTable;
970 UINT32 GtCount;
971 ACPI_TABLE_HEADER *Header;
972
973
974 ParentTable = DtPeekSubtable ();
975
976 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
977
978 /* Compile the main table */
979
980 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
981 &Subtable);
982 if (ACPI_FAILURE (Status))
983 {
984 return (Status);
985 }
986
987 /* GTDT revision 3 later contains 2 extra fields before subtables */
988
989 if (Header->Revision > 2)
990 {
991 ParentTable = DtPeekSubtable ();
992 DtInsertSubtable (ParentTable, Subtable);
993
994 Status = DtCompileTable (PFieldList,
995 AcpiDmTableInfoGtdtEl2, &Subtable);
996 if (ACPI_FAILURE (Status))
997 {
998 return (Status);
999 }
1000 }
1001
1002 ParentTable = DtPeekSubtable ();
1003 DtInsertSubtable (ParentTable, Subtable);
1004
1005 while (*PFieldList)
1006 {
1007 SubtableStart = *PFieldList;
1008 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1009 &Subtable);
1010 if (ACPI_FAILURE (Status))
1011 {
1012 return (Status);
1013 }
1014
1015 ParentTable = DtPeekSubtable ();
1016 DtInsertSubtable (ParentTable, Subtable);
1017 DtPushSubtable (Subtable);
1018
1019 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1020
1021 switch (GtdtHeader->Type)
1022 {
1023 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1024
1025 InfoTable = AcpiDmTableInfoGtdt0;
1026 break;
1027
1028 case ACPI_GTDT_TYPE_WATCHDOG:
1029
1030 InfoTable = AcpiDmTableInfoGtdt1;
1031 break;
1032
1033 default:
1034
1035 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1036 return (AE_ERROR);
1037 }
1038
1039 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1040 if (ACPI_FAILURE (Status))
1041 {
1042 return (Status);
1043 }
1044
1045 ParentTable = DtPeekSubtable ();
1046 DtInsertSubtable (ParentTable, Subtable);
1047
1048 /*
1049 * Additional GT block subtable data
1050 */
1051
1052 switch (GtdtHeader->Type)
1053 {
1054 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1055
1056 DtPushSubtable (Subtable);
1057 ParentTable = DtPeekSubtable ();
1058
1059 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1060 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1061
1062 while (GtCount)
1063 {
1064 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1065 &Subtable);
1066 if (ACPI_FAILURE (Status))
1067 {
1068 return (Status);
1069 }
1070
1071 DtInsertSubtable (ParentTable, Subtable);
1072 GtCount--;
1073 }
1074
1075 DtPopSubtable ();
1076 break;
1077
1078 default:
1079
1080 break;
1081 }
1082
1083 DtPopSubtable ();
1084 }
1085
1086 return (AE_OK);
1087 }
1088
1089
1090 /******************************************************************************
1091 *
1092 * FUNCTION: DtCompileFpdt
1093 *
1094 * PARAMETERS: List - Current field list pointer
1095 *
1096 * RETURN: Status
1097 *
1098 * DESCRIPTION: Compile FPDT.
1099 *
1100 *****************************************************************************/
1101
1102 ACPI_STATUS
1103 DtCompileFpdt (
1104 void **List)
1105 {
1106 ACPI_STATUS Status;
1107 ACPI_FPDT_HEADER *FpdtHeader;
1108 DT_SUBTABLE *Subtable;
1109 DT_SUBTABLE *ParentTable;
1110 ACPI_DMTABLE_INFO *InfoTable;
1111 DT_FIELD **PFieldList = (DT_FIELD **) List;
1112 DT_FIELD *SubtableStart;
1113
1114
1115 while (*PFieldList)
1116 {
1117 SubtableStart = *PFieldList;
1118 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1119 &Subtable);
1120 if (ACPI_FAILURE (Status))
1121 {
1122 return (Status);
1123 }
1124
1125 ParentTable = DtPeekSubtable ();
1126 DtInsertSubtable (ParentTable, Subtable);
1127 DtPushSubtable (Subtable);
1128
1129 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1130
1131 switch (FpdtHeader->Type)
1132 {
1133 case ACPI_FPDT_TYPE_BOOT:
1134
1135 InfoTable = AcpiDmTableInfoFpdt0;
1136 break;
1137
1138 case ACPI_FPDT_TYPE_S3PERF:
1139
1140 InfoTable = AcpiDmTableInfoFpdt1;
1141 break;
1142
1143 default:
1144
1145 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1146 return (AE_ERROR);
1147 break;
1148 }
1149
1150 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1151 if (ACPI_FAILURE (Status))
1152 {
1153 return (Status);
1154 }
1155
1156 ParentTable = DtPeekSubtable ();
1157 DtInsertSubtable (ParentTable, Subtable);
1158 DtPopSubtable ();
1159 }
1160
1161 return (AE_OK);
1162 }
1163
1164
1165 /******************************************************************************
1166 *
1167 * FUNCTION: DtCompileHest
1168 *
1169 * PARAMETERS: List - Current field list pointer
1170 *
1171 * RETURN: Status
1172 *
1173 * DESCRIPTION: Compile HEST.
1174 *
1175 *****************************************************************************/
1176
1177 ACPI_STATUS
1178 DtCompileHest (
1179 void **List)
1180 {
1181 ACPI_STATUS Status;
1182 DT_SUBTABLE *Subtable;
1183 DT_SUBTABLE *ParentTable;
1184 DT_FIELD **PFieldList = (DT_FIELD **) List;
1185 DT_FIELD *SubtableStart;
1186 ACPI_DMTABLE_INFO *InfoTable;
1187 UINT16 Type;
1188 UINT32 BankCount;
1189
1190
1191 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1192 &Subtable);
1193 if (ACPI_FAILURE (Status))
1194 {
1195 return (Status);
1196 }
1197
1198 ParentTable = DtPeekSubtable ();
1199 DtInsertSubtable (ParentTable, Subtable);
1200
1201 while (*PFieldList)
1202 {
1203 /* Get subtable type */
1204
1205 SubtableStart = *PFieldList;
1206 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1207
1208 switch (Type)
1209 {
1210 case ACPI_HEST_TYPE_IA32_CHECK:
1211
1212 InfoTable = AcpiDmTableInfoHest0;
1213 break;
1214
1215 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1216
1217 InfoTable = AcpiDmTableInfoHest1;
1218 break;
1219
1220 case ACPI_HEST_TYPE_IA32_NMI:
1221
1222 InfoTable = AcpiDmTableInfoHest2;
1223 break;
1224
1225 case ACPI_HEST_TYPE_AER_ROOT_PORT:
1226
1227 InfoTable = AcpiDmTableInfoHest6;
1228 break;
1229
1230 case ACPI_HEST_TYPE_AER_ENDPOINT:
1231
1232 InfoTable = AcpiDmTableInfoHest7;
1233 break;
1234
1235 case ACPI_HEST_TYPE_AER_BRIDGE:
1236
1237 InfoTable = AcpiDmTableInfoHest8;
1238 break;
1239
1240 case ACPI_HEST_TYPE_GENERIC_ERROR:
1241
1242 InfoTable = AcpiDmTableInfoHest9;
1243 break;
1244
1245 case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1246
1247 InfoTable = AcpiDmTableInfoHest10;
1248 break;
1249
1250 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1251
1252 InfoTable = AcpiDmTableInfoHest11;
1253 break;
1254
1255 default:
1256
1257 /* Cannot continue on unknown type */
1258
1259 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1260 return (AE_ERROR);
1261 }
1262
1263 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1264 if (ACPI_FAILURE (Status))
1265 {
1266 return (Status);
1267 }
1268
1269 DtInsertSubtable (ParentTable, Subtable);
1270
1271 /*
1272 * Additional subtable data - IA32 Error Bank(s)
1273 */
1274 BankCount = 0;
1275 switch (Type)
1276 {
1277 case ACPI_HEST_TYPE_IA32_CHECK:
1278
1279 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1280 Subtable->Buffer))->NumHardwareBanks;
1281 break;
1282
1283 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1284
1285 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1286 Subtable->Buffer))->NumHardwareBanks;
1287 break;
1288
1289 case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1290
1291 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1292 Subtable->Buffer))->NumHardwareBanks;
1293 break;
1294
1295 default:
1296
1297 break;
1298 }
1299
1300 while (BankCount)
1301 {
1302 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1303 &Subtable);
1304 if (ACPI_FAILURE (Status))
1305 {
1306 return (Status);
1307 }
1308
1309 DtInsertSubtable (ParentTable, Subtable);
1310 BankCount--;
1311 }
1312 }
1313
1314 return (AE_OK);
1315 }
1316
1317
1318 /******************************************************************************
1319 *
1320 * FUNCTION: DtCompileHmat
1321 *
1322 * PARAMETERS: List - Current field list pointer
1323 *
1324 * RETURN: Status
1325 *
1326 * DESCRIPTION: Compile HMAT.
1327 *
1328 *****************************************************************************/
1329
1330 ACPI_STATUS
1331 DtCompileHmat (
1332 void **List)
1333 {
1334 ACPI_STATUS Status;
1335 DT_SUBTABLE *Subtable;
1336 DT_SUBTABLE *ParentTable;
1337 DT_FIELD **PFieldList = (DT_FIELD **) List;
1338 DT_FIELD *SubtableStart;
1339 DT_FIELD *EntryStart;
1340 ACPI_HMAT_STRUCTURE *HmatStruct;
1341 ACPI_HMAT_LOCALITY *HmatLocality;
1342 ACPI_HMAT_CACHE *HmatCache;
1343 ACPI_DMTABLE_INFO *InfoTable;
1344 UINT32 IntPDNumber;
1345 UINT32 TgtPDNumber;
1346 UINT64 EntryNumber;
1347 UINT16 SMBIOSHandleNumber;
1348
1349
1350 ParentTable = DtPeekSubtable ();
1351
1352 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
1353 &Subtable);
1354 if (ACPI_FAILURE (Status))
1355 {
1356 return (Status);
1357 }
1358 DtInsertSubtable (ParentTable, Subtable);
1359
1360 while (*PFieldList)
1361 {
1362 /* Compile HMAT structure header */
1363
1364 SubtableStart = *PFieldList;
1365 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
1366 &Subtable);
1367 if (ACPI_FAILURE (Status))
1368 {
1369 return (Status);
1370 }
1371 DtInsertSubtable (ParentTable, Subtable);
1372
1373 HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
1374 HmatStruct->Length = Subtable->Length;
1375
1376 /* Compile HMAT structure body */
1377
1378 switch (HmatStruct->Type)
1379 {
1380 case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1381
1382 InfoTable = AcpiDmTableInfoHmat0;
1383 break;
1384
1385 case ACPI_HMAT_TYPE_LOCALITY:
1386
1387 InfoTable = AcpiDmTableInfoHmat1;
1388 break;
1389
1390 case ACPI_HMAT_TYPE_CACHE:
1391
1392 InfoTable = AcpiDmTableInfoHmat2;
1393 break;
1394
1395 default:
1396
1397 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
1398 return (AE_ERROR);
1399 }
1400
1401 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
1402 if (ACPI_FAILURE (Status))
1403 {
1404 return (Status);
1405 }
1406 DtInsertSubtable (ParentTable, Subtable);
1407 HmatStruct->Length += Subtable->Length;
1408
1409 /* Compile HMAT structure additionals */
1410
1411 switch (HmatStruct->Type)
1412 {
1413 case ACPI_HMAT_TYPE_LOCALITY:
1414
1415 HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
1416 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
1417
1418 /* Compile initiator proximity domain list */
1419
1420 IntPDNumber = 0;
1421 while (*PFieldList)
1422 {
1423 Status = DtCompileTable (PFieldList,
1424 AcpiDmTableInfoHmat1a, &Subtable);
1425 if (ACPI_FAILURE (Status))
1426 {
1427 return (Status);
1428 }
1429 if (!Subtable)
1430 {
1431 break;
1432 }
1433 DtInsertSubtable (ParentTable, Subtable);
1434 HmatStruct->Length += Subtable->Length;
1435 IntPDNumber++;
1436 }
1437 HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
1438
1439 /* Compile target proximity domain list */
1440
1441 TgtPDNumber = 0;
1442 while (*PFieldList)
1443 {
1444 Status = DtCompileTable (PFieldList,
1445 AcpiDmTableInfoHmat1b, &Subtable);
1446 if (ACPI_FAILURE (Status))
1447 {
1448 return (Status);
1449 }
1450 if (!Subtable)
1451 {
1452 break;
1453 }
1454 DtInsertSubtable (ParentTable, Subtable);
1455 HmatStruct->Length += Subtable->Length;
1456 TgtPDNumber++;
1457 }
1458 HmatLocality->NumberOfTargetPDs = TgtPDNumber;
1459
1460 /* Save start of the entries for reporting errors */
1461
1462 EntryStart = *PFieldList;
1463
1464 /* Compile latency/bandwidth entries */
1465
1466 EntryNumber = 0;
1467 while (*PFieldList)
1468 {
1469 Status = DtCompileTable (PFieldList,
1470 AcpiDmTableInfoHmat1c, &Subtable);
1471 if (ACPI_FAILURE (Status))
1472 {
1473 return (Status);
1474 }
1475 if (!Subtable)
1476 {
1477 break;
1478 }
1479 DtInsertSubtable (ParentTable, Subtable);
1480 HmatStruct->Length += Subtable->Length;
1481 EntryNumber++;
1482 }
1483
1484 /* Validate number of entries */
1485
1486 if (EntryNumber !=
1487 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
1488 {
1489 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
1490 return (AE_ERROR);
1491 }
1492 break;
1493
1494 case ACPI_HMAT_TYPE_CACHE:
1495
1496 /* Compile SMBIOS handles */
1497
1498 HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
1499 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
1500 SMBIOSHandleNumber = 0;
1501 while (*PFieldList)
1502 {
1503 Status = DtCompileTable (PFieldList,
1504 AcpiDmTableInfoHmat2a, &Subtable);
1505 if (ACPI_FAILURE (Status))
1506 {
1507 return (Status);
1508 }
1509 if (!Subtable)
1510 {
1511 break;
1512 }
1513 DtInsertSubtable (ParentTable, Subtable);
1514 HmatStruct->Length += Subtable->Length;
1515 SMBIOSHandleNumber++;
1516 }
1517 HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
1518 break;
1519
1520 default:
1521
1522 break;
1523 }
1524 }
1525
1526 return (AE_OK);
1527 }
1528
1529
1530 /******************************************************************************
1531 *
1532 * FUNCTION: DtCompileIort
1533 *
1534 * PARAMETERS: List - Current field list pointer
1535 *
1536 * RETURN: Status
1537 *
1538 * DESCRIPTION: Compile IORT.
1539 *
1540 *****************************************************************************/
1541
1542 ACPI_STATUS
1543 DtCompileIort (
1544 void **List)
1545 {
1546 ACPI_STATUS Status;
1547 DT_SUBTABLE *Subtable;
1548 DT_SUBTABLE *ParentTable;
1549 DT_FIELD **PFieldList = (DT_FIELD **) List;
1550 DT_FIELD *SubtableStart;
1551 ACPI_TABLE_HEADER *Table;
1552 ACPI_TABLE_IORT *Iort;
1553 ACPI_IORT_NODE *IortNode;
1554 ACPI_IORT_ITS_GROUP *IortItsGroup;
1555 ACPI_IORT_SMMU *IortSmmu;
1556 ACPI_IORT_RMR *IortRmr;
1557 UINT32 NodeNumber;
1558 UINT32 NodeLength;
1559 UINT32 IdMappingNumber;
1560 UINT32 ItsNumber;
1561 UINT32 ContextIrptNumber;
1562 UINT32 PmuIrptNumber;
1563 UINT32 PaddingLength;
1564 UINT8 Revision;
1565 UINT32 RmrCount;
1566
1567
1568 ParentTable = DtPeekSubtable ();
1569
1570 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1571 &Subtable);
1572 if (ACPI_FAILURE (Status))
1573 {
1574 return (Status);
1575 }
1576 DtInsertSubtable (ParentTable, Subtable);
1577
1578 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1579 Revision = Table->Revision;
1580
1581 /* Both IORT Rev E and E.a have known issues and are not supported */
1582
1583 if (Revision == 1 || Revision == 2)
1584 {
1585 DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
1586 return (AE_ERROR);
1587 }
1588
1589 /*
1590 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1591 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
1592 */
1593 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1594 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1595
1596 /*
1597 * OptionalPadding - Variable-length data
1598 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1599 * Optionally allows the generic data types to be used for filling
1600 * this field.
1601 */
1602 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1603 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1604 &Subtable);
1605 if (ACPI_FAILURE (Status))
1606 {
1607 return (Status);
1608 }
1609 if (Subtable)
1610 {
1611 DtInsertSubtable (ParentTable, Subtable);
1612 Iort->NodeOffset += Subtable->Length;
1613 }
1614 else
1615 {
1616 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1617 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1618 if (ACPI_FAILURE (Status))
1619 {
1620 return (Status);
1621 }
1622 Iort->NodeOffset += PaddingLength;
1623 }
1624
1625 NodeNumber = 0;
1626 while (*PFieldList)
1627 {
1628 SubtableStart = *PFieldList;
1629 if (Revision == 0)
1630 {
1631 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1632 &Subtable);
1633 }
1634 else if (Revision >= 3)
1635 {
1636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
1637 &Subtable);
1638 }
1639
1640 if (ACPI_FAILURE (Status))
1641 {
1642 return (Status);
1643 }
1644
1645 DtInsertSubtable (ParentTable, Subtable);
1646 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1647 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1648
1649 DtPushSubtable (Subtable);
1650 ParentTable = DtPeekSubtable ();
1651
1652 switch (IortNode->Type)
1653 {
1654 case ACPI_IORT_NODE_ITS_GROUP:
1655
1656 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1657 &Subtable);
1658 if (ACPI_FAILURE (Status))
1659 {
1660 return (Status);
1661 }
1662
1663 DtInsertSubtable (ParentTable, Subtable);
1664 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1665 NodeLength += Subtable->Length;
1666
1667 ItsNumber = 0;
1668 while (*PFieldList)
1669 {
1670 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1671 &Subtable);
1672 if (ACPI_FAILURE (Status))
1673 {
1674 return (Status);
1675 }
1676 if (!Subtable)
1677 {
1678 break;
1679 }
1680
1681 DtInsertSubtable (ParentTable, Subtable);
1682 NodeLength += Subtable->Length;
1683 ItsNumber++;
1684 }
1685
1686 IortItsGroup->ItsCount = ItsNumber;
1687 break;
1688
1689 case ACPI_IORT_NODE_NAMED_COMPONENT:
1690
1691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1692 &Subtable);
1693 if (ACPI_FAILURE (Status))
1694 {
1695 return (Status);
1696 }
1697
1698 DtInsertSubtable (ParentTable, Subtable);
1699 NodeLength += Subtable->Length;
1700
1701 /*
1702 * Padding - Variable-length data
1703 * Optionally allows the offset of the ID mappings to be used
1704 * for filling this field.
1705 */
1706 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1707 &Subtable);
1708 if (ACPI_FAILURE (Status))
1709 {
1710 return (Status);
1711 }
1712
1713 if (Subtable)
1714 {
1715 DtInsertSubtable (ParentTable, Subtable);
1716 NodeLength += Subtable->Length;
1717 }
1718 else
1719 {
1720 if (NodeLength > IortNode->MappingOffset)
1721 {
1722 return (AE_BAD_DATA);
1723 }
1724
1725 if (NodeLength < IortNode->MappingOffset)
1726 {
1727 Status = DtCompilePadding (
1728 IortNode->MappingOffset - NodeLength,
1729 &Subtable);
1730 if (ACPI_FAILURE (Status))
1731 {
1732 return (Status);
1733 }
1734
1735 DtInsertSubtable (ParentTable, Subtable);
1736 NodeLength = IortNode->MappingOffset;
1737 }
1738 }
1739 break;
1740
1741 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1742
1743 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1744 &Subtable);
1745 if (ACPI_FAILURE (Status))
1746 {
1747 return (Status);
1748 }
1749
1750 DtInsertSubtable (ParentTable, Subtable);
1751 NodeLength += Subtable->Length;
1752 break;
1753
1754 case ACPI_IORT_NODE_SMMU:
1755
1756 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1757 &Subtable);
1758 if (ACPI_FAILURE (Status))
1759 {
1760 return (Status);
1761 }
1762
1763 DtInsertSubtable (ParentTable, Subtable);
1764 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1765 NodeLength += Subtable->Length;
1766
1767 /* Compile global interrupt array */
1768
1769 IortSmmu->GlobalInterruptOffset = NodeLength;
1770 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1771 &Subtable);
1772 if (ACPI_FAILURE (Status))
1773 {
1774 return (Status);
1775 }
1776
1777 DtInsertSubtable (ParentTable, Subtable);
1778 NodeLength += Subtable->Length;
1779
1780 /* Compile context interrupt array */
1781
1782 ContextIrptNumber = 0;
1783 IortSmmu->ContextInterruptOffset = NodeLength;
1784 while (*PFieldList)
1785 {
1786 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1787 &Subtable);
1788 if (ACPI_FAILURE (Status))
1789 {
1790 return (Status);
1791 }
1792
1793 if (!Subtable)
1794 {
1795 break;
1796 }
1797
1798 DtInsertSubtable (ParentTable, Subtable);
1799 NodeLength += Subtable->Length;
1800 ContextIrptNumber++;
1801 }
1802
1803 IortSmmu->ContextInterruptCount = ContextIrptNumber;
1804
1805 /* Compile PMU interrupt array */
1806
1807 PmuIrptNumber = 0;
1808 IortSmmu->PmuInterruptOffset = NodeLength;
1809 while (*PFieldList)
1810 {
1811 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1812 &Subtable);
1813 if (ACPI_FAILURE (Status))
1814 {
1815 return (Status);
1816 }
1817
1818 if (!Subtable)
1819 {
1820 break;
1821 }
1822
1823 DtInsertSubtable (ParentTable, Subtable);
1824 NodeLength += Subtable->Length;
1825 PmuIrptNumber++;
1826 }
1827
1828 IortSmmu->PmuInterruptCount = PmuIrptNumber;
1829 break;
1830
1831 case ACPI_IORT_NODE_SMMU_V3:
1832
1833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
1834 &Subtable);
1835 if (ACPI_FAILURE (Status))
1836 {
1837 return (Status);
1838 }
1839
1840 DtInsertSubtable (ParentTable, Subtable);
1841 NodeLength += Subtable->Length;
1842 break;
1843
1844 case ACPI_IORT_NODE_PMCG:
1845
1846 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
1847 &Subtable);
1848 if (ACPI_FAILURE (Status))
1849 {
1850 return (Status);
1851 }
1852
1853 DtInsertSubtable (ParentTable, Subtable);
1854 NodeLength += Subtable->Length;
1855 break;
1856
1857 case ACPI_IORT_NODE_RMR:
1858
1859 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
1860 &Subtable);
1861 if (ACPI_FAILURE (Status))
1862 {
1863 return (Status);
1864 }
1865
1866 DtInsertSubtable (ParentTable, Subtable);
1867 IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
1868 NodeLength += Subtable->Length;
1869
1870 /* Compile RMR Descriptors */
1871
1872 RmrCount = 0;
1873 IortRmr->RmrOffset = NodeLength;
1874 while (*PFieldList)
1875 {
1876 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
1877 &Subtable);
1878 if (ACPI_FAILURE (Status))
1879 {
1880 return (Status);
1881 }
1882
1883 if (!Subtable)
1884 {
1885 break;
1886 }
1887
1888 DtInsertSubtable (ParentTable, Subtable);
1889 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
1890 RmrCount++;
1891 }
1892
1893 IortRmr->RmrCount = RmrCount;
1894 break;
1895
1896 default:
1897
1898 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1899 return (AE_ERROR);
1900 }
1901
1902 /* Compile Array of ID mappings */
1903
1904 IortNode->MappingOffset = NodeLength;
1905 IdMappingNumber = 0;
1906 while (*PFieldList)
1907 {
1908 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1909 &Subtable);
1910 if (ACPI_FAILURE (Status))
1911 {
1912 return (Status);
1913 }
1914
1915 if (!Subtable)
1916 {
1917 break;
1918 }
1919
1920 DtInsertSubtable (ParentTable, Subtable);
1921 NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1922 IdMappingNumber++;
1923 }
1924
1925 IortNode->MappingCount = IdMappingNumber;
1926 if (!IdMappingNumber)
1927 {
1928 IortNode->MappingOffset = 0;
1929 }
1930
1931 /*
1932 * Node length can be determined by DT_LENGTH option
1933 * IortNode->Length = NodeLength;
1934 */
1935 DtPopSubtable ();
1936 ParentTable = DtPeekSubtable ();
1937 NodeNumber++;
1938 }
1939
1940 Iort->NodeCount = NodeNumber;
1941 return (AE_OK);
1942 }
1943
1944
1945 /******************************************************************************
1946 *
1947 * FUNCTION: DtCompileIvrs
1948 *
1949 * PARAMETERS: List - Current field list pointer
1950 *
1951 * RETURN: Status
1952 *
1953 * DESCRIPTION: Compile IVRS.
1954 *
1955 *****************************************************************************/
1956
1957 ACPI_STATUS
1958 DtCompileIvrs (
1959 void **List)
1960 {
1961 ACPI_STATUS Status;
1962 DT_SUBTABLE *Subtable;
1963 DT_SUBTABLE *ParentTable;
1964 DT_FIELD **PFieldList = (DT_FIELD **) List;
1965 DT_FIELD *SubtableStart;
1966 ACPI_DMTABLE_INFO *InfoTable;
1967 ACPI_IVRS_HEADER *IvrsHeader;
1968 UINT8 EntryType;
1969
1970
1971 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1972 &Subtable);
1973 if (ACPI_FAILURE (Status))
1974 {
1975 return (Status);
1976 }
1977
1978 ParentTable = DtPeekSubtable ();
1979 DtInsertSubtable (ParentTable, Subtable);
1980
1981 while (*PFieldList)
1982 {
1983 SubtableStart = *PFieldList;
1984 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1985 &Subtable);
1986 if (ACPI_FAILURE (Status))
1987 {
1988 return (Status);
1989 }
1990
1991 ParentTable = DtPeekSubtable ();
1992 DtInsertSubtable (ParentTable, Subtable);
1993 DtPushSubtable (Subtable);
1994
1995 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1996
1997 switch (IvrsHeader->Type)
1998 {
1999 case ACPI_IVRS_TYPE_HARDWARE1:
2000
2001 InfoTable = AcpiDmTableInfoIvrs0;
2002 break;
2003
2004 case ACPI_IVRS_TYPE_HARDWARE2:
2005
2006 InfoTable = AcpiDmTableInfoIvrs01;
2007 break;
2008
2009 case ACPI_IVRS_TYPE_MEMORY1:
2010 case ACPI_IVRS_TYPE_MEMORY2:
2011 case ACPI_IVRS_TYPE_MEMORY3:
2012
2013 InfoTable = AcpiDmTableInfoIvrs1;
2014 break;
2015
2016 default:
2017
2018 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
2019 return (AE_ERROR);
2020 }
2021
2022 Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
2023 if (ACPI_FAILURE (Status))
2024 {
2025 return (Status);
2026 }
2027
2028 ParentTable = DtPeekSubtable ();
2029 DtInsertSubtable (ParentTable, Subtable);
2030
2031 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE1 ||
2032 IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE2)
2033 {
2034 while (*PFieldList &&
2035 !strcmp ((*PFieldList)->Name, "Entry Type"))
2036 {
2037 SubtableStart = *PFieldList;
2038 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
2039
2040 switch (EntryType)
2041 {
2042 /* 4-byte device entries */
2043
2044 case ACPI_IVRS_TYPE_PAD4:
2045 case ACPI_IVRS_TYPE_ALL:
2046 case ACPI_IVRS_TYPE_SELECT:
2047 case ACPI_IVRS_TYPE_START:
2048 case ACPI_IVRS_TYPE_END:
2049
2050 InfoTable = AcpiDmTableInfoIvrs4;
2051 break;
2052
2053 /* 8-byte entries, type A */
2054
2055 case ACPI_IVRS_TYPE_ALIAS_SELECT:
2056 case ACPI_IVRS_TYPE_ALIAS_START:
2057
2058 InfoTable = AcpiDmTableInfoIvrs8a;
2059 break;
2060
2061 /* 8-byte entries, type B */
2062
2063 case ACPI_IVRS_TYPE_PAD8:
2064 case ACPI_IVRS_TYPE_EXT_SELECT:
2065 case ACPI_IVRS_TYPE_EXT_START:
2066
2067 InfoTable = AcpiDmTableInfoIvrs8b;
2068 break;
2069
2070 /* 8-byte entries, type C */
2071
2072 case ACPI_IVRS_TYPE_SPECIAL:
2073
2074 InfoTable = AcpiDmTableInfoIvrs8c;
2075 break;
2076
2077 default:
2078
2079 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
2080 "IVRS Device Entry");
2081 return (AE_ERROR);
2082 }
2083
2084 Status = DtCompileTable (PFieldList, InfoTable,
2085 &Subtable);
2086 if (ACPI_FAILURE (Status))
2087 {
2088 return (Status);
2089 }
2090
2091 DtInsertSubtable (ParentTable, Subtable);
2092 }
2093 }
2094
2095 DtPopSubtable ();
2096 }
2097
2098 return (AE_OK);
2099 }
2100