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