dttable1.c revision 1.1.1.2 1 /******************************************************************************
2 *
3 * Module Name: dttable1.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2016, 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 #include "dtcompiler.h"
48
49 #define _COMPONENT DT_COMPILER
50 ACPI_MODULE_NAME ("dttable1")
51
52
53 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] =
54 {
55 {ACPI_DMT_BUFFER, 0, "Addresses", 0},
56 {ACPI_DMT_EXIT, 0, NULL, 0}
57 };
58
59 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] =
60 {
61 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0},
62 {ACPI_DMT_EXIT, 0, NULL, 0}
63 };
64
65
66 /******************************************************************************
67 *
68 * FUNCTION: DtCompileAsf
69 *
70 * PARAMETERS: List - Current field list pointer
71 *
72 * RETURN: Status
73 *
74 * DESCRIPTION: Compile ASF!.
75 *
76 *****************************************************************************/
77
78 ACPI_STATUS
79 DtCompileAsf (
80 void **List)
81 {
82 ACPI_ASF_INFO *AsfTable;
83 DT_SUBTABLE *Subtable;
84 DT_SUBTABLE *ParentTable;
85 ACPI_DMTABLE_INFO *InfoTable;
86 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
87 UINT32 DataCount = 0;
88 ACPI_STATUS Status;
89 UINT32 i;
90 DT_FIELD **PFieldList = (DT_FIELD **) List;
91 DT_FIELD *SubtableStart;
92
93
94 while (*PFieldList)
95 {
96 SubtableStart = *PFieldList;
97 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
98 &Subtable, TRUE);
99 if (ACPI_FAILURE (Status))
100 {
101 return (Status);
102 }
103
104 ParentTable = DtPeekSubtable ();
105 DtInsertSubtable (ParentTable, Subtable);
106 DtPushSubtable (Subtable);
107
108 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
109
110 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
111 {
112 case ACPI_ASF_TYPE_INFO:
113
114 InfoTable = AcpiDmTableInfoAsf0;
115 break;
116
117 case ACPI_ASF_TYPE_ALERT:
118
119 InfoTable = AcpiDmTableInfoAsf1;
120 break;
121
122 case ACPI_ASF_TYPE_CONTROL:
123
124 InfoTable = AcpiDmTableInfoAsf2;
125 break;
126
127 case ACPI_ASF_TYPE_BOOT:
128
129 InfoTable = AcpiDmTableInfoAsf3;
130 break;
131
132 case ACPI_ASF_TYPE_ADDRESS:
133
134 InfoTable = AcpiDmTableInfoAsf4;
135 break;
136
137 default:
138
139 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
140 return (AE_ERROR);
141 }
142
143 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
144 if (ACPI_FAILURE (Status))
145 {
146 return (Status);
147 }
148
149 ParentTable = DtPeekSubtable ();
150 DtInsertSubtable (ParentTable, Subtable);
151
152 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
153 {
154 case ACPI_ASF_TYPE_INFO:
155
156 DataInfoTable = NULL;
157 break;
158
159 case ACPI_ASF_TYPE_ALERT:
160
161 DataInfoTable = AcpiDmTableInfoAsf1a;
162 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
163 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
164 sizeof (ACPI_ASF_HEADER)))->Alerts;
165 break;
166
167 case ACPI_ASF_TYPE_CONTROL:
168
169 DataInfoTable = AcpiDmTableInfoAsf2a;
170 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
171 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
172 sizeof (ACPI_ASF_HEADER)))->Controls;
173 break;
174
175 case ACPI_ASF_TYPE_BOOT:
176
177 DataInfoTable = NULL;
178 break;
179
180 case ACPI_ASF_TYPE_ADDRESS:
181
182 DataInfoTable = TableInfoAsfAddress;
183 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
184 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
185 sizeof (ACPI_ASF_HEADER)))->Devices;
186 break;
187
188 default:
189
190 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
191 return (AE_ERROR);
192 }
193
194 if (DataInfoTable)
195 {
196 switch (AsfTable->Header.Type & 0x7F)
197 {
198 case ACPI_ASF_TYPE_ADDRESS:
199
200 while (DataCount > 0)
201 {
202 Status = DtCompileTable (PFieldList, DataInfoTable,
203 &Subtable, TRUE);
204 if (ACPI_FAILURE (Status))
205 {
206 return (Status);
207 }
208
209 DtInsertSubtable (ParentTable, Subtable);
210 DataCount = DataCount - Subtable->Length;
211 }
212 break;
213
214 default:
215
216 for (i = 0; i < DataCount; i++)
217 {
218 Status = DtCompileTable (PFieldList, DataInfoTable,
219 &Subtable, TRUE);
220 if (ACPI_FAILURE (Status))
221 {
222 return (Status);
223 }
224
225 DtInsertSubtable (ParentTable, Subtable);
226 }
227 break;
228 }
229 }
230
231 DtPopSubtable ();
232 }
233
234 return (AE_OK);
235 }
236
237
238 /******************************************************************************
239 *
240 * FUNCTION: DtCompileCpep
241 *
242 * PARAMETERS: List - Current field list pointer
243 *
244 * RETURN: Status
245 *
246 * DESCRIPTION: Compile CPEP.
247 *
248 *****************************************************************************/
249
250 ACPI_STATUS
251 DtCompileCpep (
252 void **List)
253 {
254 ACPI_STATUS Status;
255
256
257 Status = DtCompileTwoSubtables (List,
258 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
259 return (Status);
260 }
261
262
263 /******************************************************************************
264 *
265 * FUNCTION: DtCompileCsrt
266 *
267 * PARAMETERS: List - Current field list pointer
268 *
269 * RETURN: Status
270 *
271 * DESCRIPTION: Compile CSRT.
272 *
273 *****************************************************************************/
274
275 ACPI_STATUS
276 DtCompileCsrt (
277 void **List)
278 {
279 ACPI_STATUS Status = AE_OK;
280 DT_SUBTABLE *Subtable;
281 DT_SUBTABLE *ParentTable;
282 DT_FIELD **PFieldList = (DT_FIELD **) List;
283 UINT32 DescriptorCount;
284 UINT32 GroupLength;
285
286
287 /* Subtables (Resource Groups) */
288
289 ParentTable = DtPeekSubtable ();
290 while (*PFieldList)
291 {
292 /* Resource group subtable */
293
294 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
295 &Subtable, TRUE);
296 if (ACPI_FAILURE (Status))
297 {
298 return (Status);
299 }
300
301 /* Compute the number of resource descriptors */
302
303 GroupLength =
304 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
305 Subtable->Buffer))->Length -
306 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
307 Subtable->Buffer))->SharedInfoLength -
308 sizeof (ACPI_CSRT_GROUP);
309
310 DescriptorCount = (GroupLength /
311 sizeof (ACPI_CSRT_DESCRIPTOR));
312
313 DtInsertSubtable (ParentTable, Subtable);
314 DtPushSubtable (Subtable);
315 ParentTable = DtPeekSubtable ();
316
317 /* Shared info subtable (One per resource group) */
318
319 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
320 &Subtable, TRUE);
321 if (ACPI_FAILURE (Status))
322 {
323 return (Status);
324 }
325
326 DtInsertSubtable (ParentTable, Subtable);
327
328 /* Sub-Subtables (Resource Descriptors) */
329
330 while (*PFieldList && DescriptorCount)
331 {
332
333 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
334 &Subtable, TRUE);
335 if (ACPI_FAILURE (Status))
336 {
337 return (Status);
338 }
339
340 DtInsertSubtable (ParentTable, Subtable);
341
342 DtPushSubtable (Subtable);
343 ParentTable = DtPeekSubtable ();
344 if (*PFieldList)
345 {
346 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
347 &Subtable, TRUE);
348 if (ACPI_FAILURE (Status))
349 {
350 return (Status);
351 }
352 if (Subtable)
353 {
354 DtInsertSubtable (ParentTable, Subtable);
355 }
356 }
357
358 DtPopSubtable ();
359 ParentTable = DtPeekSubtable ();
360 DescriptorCount--;
361 }
362
363 DtPopSubtable ();
364 ParentTable = DtPeekSubtable ();
365 }
366
367 return (Status);
368 }
369
370
371 /******************************************************************************
372 *
373 * FUNCTION: DtCompileDbg2
374 *
375 * PARAMETERS: List - Current field list pointer
376 *
377 * RETURN: Status
378 *
379 * DESCRIPTION: Compile DBG2.
380 *
381 *****************************************************************************/
382
383 ACPI_STATUS
384 DtCompileDbg2 (
385 void **List)
386 {
387 ACPI_STATUS Status;
388 DT_SUBTABLE *Subtable;
389 DT_SUBTABLE *ParentTable;
390 DT_FIELD **PFieldList = (DT_FIELD **) List;
391 UINT32 SubtableCount;
392 ACPI_DBG2_HEADER *Dbg2Header;
393 ACPI_DBG2_DEVICE *DeviceInfo;
394 UINT16 CurrentOffset;
395 UINT32 i;
396
397
398 /* Main table */
399
400 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
401 if (ACPI_FAILURE (Status))
402 {
403 return (Status);
404 }
405
406 ParentTable = DtPeekSubtable ();
407 DtInsertSubtable (ParentTable, Subtable);
408
409 /* Main table fields */
410
411 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
412 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
413 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
414
415 SubtableCount = Dbg2Header->InfoCount;
416 DtPushSubtable (Subtable);
417
418 /* Process all Device Information subtables (Count = InfoCount) */
419
420 while (*PFieldList && SubtableCount)
421 {
422 /* Subtable: Debug Device Information */
423
424 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
425 &Subtable, TRUE);
426 if (ACPI_FAILURE (Status))
427 {
428 return (Status);
429 }
430
431 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
432 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
433
434 ParentTable = DtPeekSubtable ();
435 DtInsertSubtable (ParentTable, Subtable);
436 DtPushSubtable (Subtable);
437
438 ParentTable = DtPeekSubtable ();
439
440 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
441
442 DeviceInfo->BaseAddressOffset = CurrentOffset;
443 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
444 {
445 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
446 &Subtable, TRUE);
447 if (ACPI_FAILURE (Status))
448 {
449 return (Status);
450 }
451
452 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
453 DtInsertSubtable (ParentTable, Subtable);
454 }
455
456 /* AddressSize array (Required, size = RegisterCount) */
457
458 DeviceInfo->AddressSizeOffset = CurrentOffset;
459 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
460 {
461 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
462 &Subtable, TRUE);
463 if (ACPI_FAILURE (Status))
464 {
465 return (Status);
466 }
467
468 CurrentOffset += (UINT16) sizeof (UINT32);
469 DtInsertSubtable (ParentTable, Subtable);
470 }
471
472 /* NamespaceString device identifier (Required, size = NamePathLength) */
473
474 DeviceInfo->NamepathOffset = CurrentOffset;
475 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
476 &Subtable, TRUE);
477 if (ACPI_FAILURE (Status))
478 {
479 return (Status);
480 }
481
482 /* Update the device info header */
483
484 DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
485 CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
486 DtInsertSubtable (ParentTable, Subtable);
487
488 /* OemData - Variable-length data (Optional, size = OemDataLength) */
489
490 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
491 &Subtable, TRUE);
492 if (ACPI_FAILURE (Status))
493 {
494 return (Status);
495 }
496
497 /* Update the device info header (zeros if no OEM data present) */
498
499 DeviceInfo->OemDataOffset = 0;
500 DeviceInfo->OemDataLength = 0;
501
502 /* Optional subtable (OemData) */
503
504 if (Subtable && Subtable->Length)
505 {
506 DeviceInfo->OemDataOffset = CurrentOffset;
507 DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
508
509 DtInsertSubtable (ParentTable, Subtable);
510 }
511
512 SubtableCount--;
513 DtPopSubtable (); /* Get next Device Information subtable */
514 }
515
516 DtPopSubtable ();
517 return (AE_OK);
518 }
519
520
521 /******************************************************************************
522 *
523 * FUNCTION: DtCompileDmar
524 *
525 * PARAMETERS: List - Current field list pointer
526 *
527 * RETURN: Status
528 *
529 * DESCRIPTION: Compile DMAR.
530 *
531 *****************************************************************************/
532
533 ACPI_STATUS
534 DtCompileDmar (
535 void **List)
536 {
537 ACPI_STATUS Status;
538 DT_SUBTABLE *Subtable;
539 DT_SUBTABLE *ParentTable;
540 DT_FIELD **PFieldList = (DT_FIELD **) List;
541 DT_FIELD *SubtableStart;
542 ACPI_DMTABLE_INFO *InfoTable;
543 ACPI_DMAR_HEADER *DmarHeader;
544 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
545 UINT32 DeviceScopeLength;
546 UINT32 PciPathLength;
547
548
549 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
550 if (ACPI_FAILURE (Status))
551 {
552 return (Status);
553 }
554
555 ParentTable = DtPeekSubtable ();
556 DtInsertSubtable (ParentTable, Subtable);
557 DtPushSubtable (Subtable);
558
559 while (*PFieldList)
560 {
561 /* DMAR Header */
562
563 SubtableStart = *PFieldList;
564 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
565 &Subtable, TRUE);
566 if (ACPI_FAILURE (Status))
567 {
568 return (Status);
569 }
570
571 ParentTable = DtPeekSubtable ();
572 DtInsertSubtable (ParentTable, Subtable);
573 DtPushSubtable (Subtable);
574
575 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
576
577 switch (DmarHeader->Type)
578 {
579 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
580
581 InfoTable = AcpiDmTableInfoDmar0;
582 break;
583
584 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
585
586 InfoTable = AcpiDmTableInfoDmar1;
587 break;
588
589 case ACPI_DMAR_TYPE_ROOT_ATS:
590
591 InfoTable = AcpiDmTableInfoDmar2;
592 break;
593
594 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
595
596 InfoTable = AcpiDmTableInfoDmar3;
597 break;
598
599 case ACPI_DMAR_TYPE_NAMESPACE:
600
601 InfoTable = AcpiDmTableInfoDmar4;
602 break;
603
604 default:
605
606 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
607 return (AE_ERROR);
608 }
609
610 /* DMAR Subtable */
611
612 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
613 if (ACPI_FAILURE (Status))
614 {
615 return (Status);
616 }
617
618 ParentTable = DtPeekSubtable ();
619 DtInsertSubtable (ParentTable, Subtable);
620
621 /*
622 * Optional Device Scope subtables
623 */
624 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
625 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
626 {
627 /* These types do not support device scopes */
628
629 DtPopSubtable ();
630 continue;
631 }
632
633 DtPushSubtable (Subtable);
634 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
635 ParentTable->Length;
636 while (DeviceScopeLength)
637 {
638 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
639 &Subtable, FALSE);
640 if (Status == AE_NOT_FOUND)
641 {
642 break;
643 }
644
645 ParentTable = DtPeekSubtable ();
646 DtInsertSubtable (ParentTable, Subtable);
647 DtPushSubtable (Subtable);
648
649 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
650
651 /* Optional PCI Paths */
652
653 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
654 while (PciPathLength)
655 {
656 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
657 &Subtable, FALSE);
658 if (Status == AE_NOT_FOUND)
659 {
660 DtPopSubtable ();
661 break;
662 }
663
664 ParentTable = DtPeekSubtable ();
665 DtInsertSubtable (ParentTable, Subtable);
666 PciPathLength -= Subtable->Length;
667 }
668
669 DtPopSubtable ();
670 DeviceScopeLength -= DmarDeviceScope->Length;
671 }
672
673 DtPopSubtable ();
674 DtPopSubtable ();
675 }
676
677 return (AE_OK);
678 }
679
680
681 /******************************************************************************
682 *
683 * FUNCTION: DtCompileDrtm
684 *
685 * PARAMETERS: List - Current field list pointer
686 *
687 * RETURN: Status
688 *
689 * DESCRIPTION: Compile DRTM.
690 *
691 *****************************************************************************/
692
693 ACPI_STATUS
694 DtCompileDrtm (
695 void **List)
696 {
697 ACPI_STATUS Status;
698 DT_SUBTABLE *Subtable;
699 DT_SUBTABLE *ParentTable;
700 DT_FIELD **PFieldList = (DT_FIELD **) List;
701 UINT32 Count;
702 /* ACPI_TABLE_DRTM *Drtm; */
703 ACPI_DRTM_VTABLE_LIST *DrtmVtl;
704 ACPI_DRTM_RESOURCE_LIST *DrtmRl;
705 /* ACPI_DRTM_DPS_ID *DrtmDps; */
706
707
708 ParentTable = DtPeekSubtable ();
709
710 /* Compile DRTM header */
711
712 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
713 &Subtable, TRUE);
714 if (ACPI_FAILURE (Status))
715 {
716 return (Status);
717 }
718 DtInsertSubtable (ParentTable, Subtable);
719
720 /*
721 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
722 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
723 */
724 #if 0
725 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
726 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
727 #endif
728 /* Compile VTL */
729
730 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
731 &Subtable, TRUE);
732 if (ACPI_FAILURE (Status))
733 {
734 return (Status);
735 }
736
737 DtInsertSubtable (ParentTable, Subtable);
738 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
739
740 DtPushSubtable (Subtable);
741 ParentTable = DtPeekSubtable ();
742 Count = 0;
743
744 while (*PFieldList)
745 {
746 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
747 &Subtable, TRUE);
748 if (ACPI_FAILURE (Status))
749 {
750 return (Status);
751 }
752 if (!Subtable)
753 {
754 break;
755 }
756 DtInsertSubtable (ParentTable, Subtable);
757 Count++;
758 }
759
760 DrtmVtl->ValidatedTableCount = Count;
761 DtPopSubtable ();
762 ParentTable = DtPeekSubtable ();
763
764 /* Compile RL */
765
766 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
767 &Subtable, TRUE);
768 if (ACPI_FAILURE (Status))
769 {
770 return (Status);
771 }
772
773 DtInsertSubtable (ParentTable, Subtable);
774 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
775
776 DtPushSubtable (Subtable);
777 ParentTable = DtPeekSubtable ();
778 Count = 0;
779
780 while (*PFieldList)
781 {
782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
783 &Subtable, TRUE);
784 if (ACPI_FAILURE (Status))
785 {
786 return (Status);
787 }
788
789 if (!Subtable)
790 {
791 break;
792 }
793
794 DtInsertSubtable (ParentTable, Subtable);
795 Count++;
796 }
797
798 DrtmRl->ResourceCount = Count;
799 DtPopSubtable ();
800 ParentTable = DtPeekSubtable ();
801
802 /* Compile DPS */
803
804 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
805 &Subtable, TRUE);
806 if (ACPI_FAILURE (Status))
807 {
808 return (Status);
809 }
810 DtInsertSubtable (ParentTable, Subtable);
811 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
812
813
814 return (AE_OK);
815 }
816
817
818 /******************************************************************************
819 *
820 * FUNCTION: DtCompileEinj
821 *
822 * PARAMETERS: List - Current field list pointer
823 *
824 * RETURN: Status
825 *
826 * DESCRIPTION: Compile EINJ.
827 *
828 *****************************************************************************/
829
830 ACPI_STATUS
831 DtCompileEinj (
832 void **List)
833 {
834 ACPI_STATUS Status;
835
836
837 Status = DtCompileTwoSubtables (List,
838 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
839 return (Status);
840 }
841
842
843 /******************************************************************************
844 *
845 * FUNCTION: DtCompileErst
846 *
847 * PARAMETERS: List - Current field list pointer
848 *
849 * RETURN: Status
850 *
851 * DESCRIPTION: Compile ERST.
852 *
853 *****************************************************************************/
854
855 ACPI_STATUS
856 DtCompileErst (
857 void **List)
858 {
859 ACPI_STATUS Status;
860
861
862 Status = DtCompileTwoSubtables (List,
863 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
864 return (Status);
865 }
866
867
868 /******************************************************************************
869 *
870 * FUNCTION: DtCompileGtdt
871 *
872 * PARAMETERS: List - Current field list pointer
873 *
874 * RETURN: Status
875 *
876 * DESCRIPTION: Compile GTDT.
877 *
878 *****************************************************************************/
879
880 ACPI_STATUS
881 DtCompileGtdt (
882 void **List)
883 {
884 ACPI_STATUS Status;
885 DT_SUBTABLE *Subtable;
886 DT_SUBTABLE *ParentTable;
887 DT_FIELD **PFieldList = (DT_FIELD **) List;
888 DT_FIELD *SubtableStart;
889 ACPI_SUBTABLE_HEADER *GtdtHeader;
890 ACPI_DMTABLE_INFO *InfoTable;
891 UINT32 GtCount;
892
893
894 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
895 &Subtable, TRUE);
896 if (ACPI_FAILURE (Status))
897 {
898 return (Status);
899 }
900
901 ParentTable = DtPeekSubtable ();
902 DtInsertSubtable (ParentTable, Subtable);
903
904 while (*PFieldList)
905 {
906 SubtableStart = *PFieldList;
907 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
908 &Subtable, TRUE);
909 if (ACPI_FAILURE (Status))
910 {
911 return (Status);
912 }
913
914 ParentTable = DtPeekSubtable ();
915 DtInsertSubtable (ParentTable, Subtable);
916 DtPushSubtable (Subtable);
917
918 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
919
920 switch (GtdtHeader->Type)
921 {
922 case ACPI_GTDT_TYPE_TIMER_BLOCK:
923
924 InfoTable = AcpiDmTableInfoGtdt0;
925 break;
926
927 case ACPI_GTDT_TYPE_WATCHDOG:
928
929 InfoTable = AcpiDmTableInfoGtdt1;
930 break;
931
932 default:
933
934 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
935 return (AE_ERROR);
936 }
937
938 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
939 if (ACPI_FAILURE (Status))
940 {
941 return (Status);
942 }
943
944 ParentTable = DtPeekSubtable ();
945 DtInsertSubtable (ParentTable, Subtable);
946
947 /*
948 * Additional GT block subtable data
949 */
950
951 switch (GtdtHeader->Type)
952 {
953 case ACPI_GTDT_TYPE_TIMER_BLOCK:
954
955 DtPushSubtable (Subtable);
956 ParentTable = DtPeekSubtable ();
957
958 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
959 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
960
961 while (GtCount)
962 {
963 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
964 &Subtable, TRUE);
965 if (ACPI_FAILURE (Status))
966 {
967 return (Status);
968 }
969
970 DtInsertSubtable (ParentTable, Subtable);
971 GtCount--;
972 }
973
974 DtPopSubtable ();
975 break;
976
977 default:
978
979 break;
980 }
981
982 DtPopSubtable ();
983 }
984
985 return (AE_OK);
986 }
987
988
989 /******************************************************************************
990 *
991 * FUNCTION: DtCompileFpdt
992 *
993 * PARAMETERS: List - Current field list pointer
994 *
995 * RETURN: Status
996 *
997 * DESCRIPTION: Compile FPDT.
998 *
999 *****************************************************************************/
1000
1001 ACPI_STATUS
1002 DtCompileFpdt (
1003 void **List)
1004 {
1005 ACPI_STATUS Status;
1006 ACPI_FPDT_HEADER *FpdtHeader;
1007 DT_SUBTABLE *Subtable;
1008 DT_SUBTABLE *ParentTable;
1009 ACPI_DMTABLE_INFO *InfoTable;
1010 DT_FIELD **PFieldList = (DT_FIELD **) List;
1011 DT_FIELD *SubtableStart;
1012
1013
1014 while (*PFieldList)
1015 {
1016 SubtableStart = *PFieldList;
1017 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1018 &Subtable, TRUE);
1019 if (ACPI_FAILURE (Status))
1020 {
1021 return (Status);
1022 }
1023
1024 ParentTable = DtPeekSubtable ();
1025 DtInsertSubtable (ParentTable, Subtable);
1026 DtPushSubtable (Subtable);
1027
1028 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1029
1030 switch (FpdtHeader->Type)
1031 {
1032 case ACPI_FPDT_TYPE_BOOT:
1033
1034 InfoTable = AcpiDmTableInfoFpdt0;
1035 break;
1036
1037 case ACPI_FPDT_TYPE_S3PERF:
1038
1039 InfoTable = AcpiDmTableInfoFpdt1;
1040 break;
1041
1042 default:
1043
1044 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1045 return (AE_ERROR);
1046 break;
1047 }
1048
1049 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1050 if (ACPI_FAILURE (Status))
1051 {
1052 return (Status);
1053 }
1054
1055 ParentTable = DtPeekSubtable ();
1056 DtInsertSubtable (ParentTable, Subtable);
1057 DtPopSubtable ();
1058 }
1059
1060 return (AE_OK);
1061 }
1062
1063
1064 /******************************************************************************
1065 *
1066 * FUNCTION: DtCompileHest
1067 *
1068 * PARAMETERS: List - Current field list pointer
1069 *
1070 * RETURN: Status
1071 *
1072 * DESCRIPTION: Compile HEST.
1073 *
1074 *****************************************************************************/
1075
1076 ACPI_STATUS
1077 DtCompileHest (
1078 void **List)
1079 {
1080 ACPI_STATUS Status;
1081 DT_SUBTABLE *Subtable;
1082 DT_SUBTABLE *ParentTable;
1083 DT_FIELD **PFieldList = (DT_FIELD **) List;
1084 DT_FIELD *SubtableStart;
1085 ACPI_DMTABLE_INFO *InfoTable;
1086 UINT16 Type;
1087 UINT32 BankCount;
1088
1089
1090 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1091 &Subtable, TRUE);
1092 if (ACPI_FAILURE (Status))
1093 {
1094 return (Status);
1095 }
1096
1097 ParentTable = DtPeekSubtable ();
1098 DtInsertSubtable (ParentTable, Subtable);
1099
1100 while (*PFieldList)
1101 {
1102 /* Get subtable type */
1103
1104 SubtableStart = *PFieldList;
1105 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1106
1107 switch (Type)
1108 {
1109 case ACPI_HEST_TYPE_IA32_CHECK:
1110
1111 InfoTable = AcpiDmTableInfoHest0;
1112 break;
1113
1114 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1115
1116 InfoTable = AcpiDmTableInfoHest1;
1117 break;
1118
1119 case ACPI_HEST_TYPE_IA32_NMI:
1120
1121 InfoTable = AcpiDmTableInfoHest2;
1122 break;
1123
1124 case ACPI_HEST_TYPE_AER_ROOT_PORT:
1125
1126 InfoTable = AcpiDmTableInfoHest6;
1127 break;
1128
1129 case ACPI_HEST_TYPE_AER_ENDPOINT:
1130
1131 InfoTable = AcpiDmTableInfoHest7;
1132 break;
1133
1134 case ACPI_HEST_TYPE_AER_BRIDGE:
1135
1136 InfoTable = AcpiDmTableInfoHest8;
1137 break;
1138
1139 case ACPI_HEST_TYPE_GENERIC_ERROR:
1140
1141 InfoTable = AcpiDmTableInfoHest9;
1142 break;
1143
1144 default:
1145
1146 /* Cannot continue on unknown type */
1147
1148 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1149 return (AE_ERROR);
1150 }
1151
1152 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1153 if (ACPI_FAILURE (Status))
1154 {
1155 return (Status);
1156 }
1157
1158 DtInsertSubtable (ParentTable, Subtable);
1159
1160 /*
1161 * Additional subtable data - IA32 Error Bank(s)
1162 */
1163 BankCount = 0;
1164 switch (Type)
1165 {
1166 case ACPI_HEST_TYPE_IA32_CHECK:
1167
1168 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1169 Subtable->Buffer))->NumHardwareBanks;
1170 break;
1171
1172 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1173
1174 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1175 Subtable->Buffer))->NumHardwareBanks;
1176 break;
1177
1178 default:
1179
1180 break;
1181 }
1182
1183 while (BankCount)
1184 {
1185 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1186 &Subtable, TRUE);
1187 if (ACPI_FAILURE (Status))
1188 {
1189 return (Status);
1190 }
1191
1192 DtInsertSubtable (ParentTable, Subtable);
1193 BankCount--;
1194 }
1195 }
1196
1197 return (AE_OK);
1198 }
1199
1200
1201 /******************************************************************************
1202 *
1203 * FUNCTION: DtCompileIort
1204 *
1205 * PARAMETERS: List - Current field list pointer
1206 *
1207 * RETURN: Status
1208 *
1209 * DESCRIPTION: Compile IORT.
1210 *
1211 *****************************************************************************/
1212
1213 ACPI_STATUS
1214 DtCompileIort (
1215 void **List)
1216 {
1217 ACPI_STATUS Status;
1218 DT_SUBTABLE *Subtable;
1219 DT_SUBTABLE *ParentTable;
1220 DT_FIELD **PFieldList = (DT_FIELD **) List;
1221 DT_FIELD *SubtableStart;
1222 ACPI_TABLE_IORT *Iort;
1223 ACPI_IORT_NODE *IortNode;
1224 ACPI_IORT_ITS_GROUP *IortItsGroup;
1225 ACPI_IORT_SMMU *IortSmmu;
1226 UINT32 NodeNumber;
1227 UINT32 NodeLength;
1228 UINT32 IdMappingNumber;
1229 UINT32 ItsNumber;
1230 UINT32 ContextIrptNumber;
1231 UINT32 PmuIrptNumber;
1232 UINT32 PaddingLength;
1233
1234
1235 ParentTable = DtPeekSubtable ();
1236
1237 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1238 &Subtable, TRUE);
1239 if (ACPI_FAILURE (Status))
1240 {
1241 return (Status);
1242 }
1243 DtInsertSubtable (ParentTable, Subtable);
1244
1245 /*
1246 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
1247 * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
1248 */
1249 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1250 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1251
1252 /*
1253 * OptionalPadding - Variable-length data
1254 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1255 * Optionally allows the generic data types to be used for filling
1256 * this field.
1257 */
1258 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1259 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1260 &Subtable, TRUE);
1261 if (ACPI_FAILURE (Status))
1262 {
1263 return (Status);
1264 }
1265 if (Subtable)
1266 {
1267 DtInsertSubtable (ParentTable, Subtable);
1268 Iort->NodeOffset += Subtable->Length;
1269 }
1270 else
1271 {
1272 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1273 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1274 if (ACPI_FAILURE (Status))
1275 {
1276 return (Status);
1277 }
1278 Iort->NodeOffset += PaddingLength;
1279 }
1280
1281 NodeNumber = 0;
1282 while (*PFieldList)
1283 {
1284 SubtableStart = *PFieldList;
1285 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1286 &Subtable, TRUE);
1287 if (ACPI_FAILURE (Status))
1288 {
1289 return (Status);
1290 }
1291
1292 DtInsertSubtable (ParentTable, Subtable);
1293 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1294 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1295
1296 DtPushSubtable (Subtable);
1297 ParentTable = DtPeekSubtable ();
1298
1299 switch (IortNode->Type)
1300 {
1301 case ACPI_IORT_NODE_ITS_GROUP:
1302
1303 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1304 &Subtable, TRUE);
1305 if (ACPI_FAILURE (Status))
1306 {
1307 return (Status);
1308 }
1309
1310 DtInsertSubtable (ParentTable, Subtable);
1311 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1312 NodeLength += Subtable->Length;
1313
1314 ItsNumber = 0;
1315 while (*PFieldList)
1316 {
1317 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1318 &Subtable, TRUE);
1319 if (ACPI_FAILURE (Status))
1320 {
1321 return (Status);
1322 }
1323 if (!Subtable)
1324 {
1325 break;
1326 }
1327
1328 DtInsertSubtable (ParentTable, Subtable);
1329 NodeLength += Subtable->Length;
1330 ItsNumber++;
1331 }
1332
1333 IortItsGroup->ItsCount = ItsNumber;
1334 break;
1335
1336 case ACPI_IORT_NODE_NAMED_COMPONENT:
1337
1338 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1339 &Subtable, TRUE);
1340 if (ACPI_FAILURE (Status))
1341 {
1342 return (Status);
1343 }
1344
1345 DtInsertSubtable (ParentTable, Subtable);
1346 NodeLength += Subtable->Length;
1347
1348 /*
1349 * Padding - Variable-length data
1350 * Optionally allows the offset of the ID mappings to be used
1351 * for filling this field.
1352 */
1353 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1354 &Subtable, TRUE);
1355 if (ACPI_FAILURE (Status))
1356 {
1357 return (Status);
1358 }
1359
1360 if (Subtable)
1361 {
1362 DtInsertSubtable (ParentTable, Subtable);
1363 NodeLength += Subtable->Length;
1364 }
1365 else
1366 {
1367 if (NodeLength > IortNode->MappingOffset)
1368 {
1369 return (AE_BAD_DATA);
1370 }
1371
1372 if (NodeLength < IortNode->MappingOffset)
1373 {
1374 Status = DtCompilePadding (
1375 IortNode->MappingOffset - NodeLength,
1376 &Subtable);
1377 if (ACPI_FAILURE (Status))
1378 {
1379 return (Status);
1380 }
1381
1382 DtInsertSubtable (ParentTable, Subtable);
1383 NodeLength = IortNode->MappingOffset;
1384 }
1385 }
1386 break;
1387
1388 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1389
1390 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1391 &Subtable, TRUE);
1392 if (ACPI_FAILURE (Status))
1393 {
1394 return (Status);
1395 }
1396
1397 DtInsertSubtable (ParentTable, Subtable);
1398 NodeLength += Subtable->Length;
1399 break;
1400
1401 case ACPI_IORT_NODE_SMMU:
1402
1403 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1404 &Subtable, TRUE);
1405 if (ACPI_FAILURE (Status))
1406 {
1407 return (Status);
1408 }
1409
1410 DtInsertSubtable (ParentTable, Subtable);
1411 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1412 NodeLength += Subtable->Length;
1413
1414 /* Compile global interrupt array */
1415
1416 IortSmmu->GlobalInterruptOffset = NodeLength;
1417 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1418 &Subtable, TRUE);
1419 if (ACPI_FAILURE (Status))
1420 {
1421 return (Status);
1422 }
1423
1424 DtInsertSubtable (ParentTable, Subtable);
1425 NodeLength += Subtable->Length;
1426
1427 /* Compile context interrupt array */
1428
1429 ContextIrptNumber = 0;
1430 IortSmmu->ContextInterruptOffset = NodeLength;
1431 while (*PFieldList)
1432 {
1433 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1434 &Subtable, TRUE);
1435 if (ACPI_FAILURE (Status))
1436 {
1437 return (Status);
1438 }
1439
1440 if (!Subtable)
1441 {
1442 break;
1443 }
1444
1445 DtInsertSubtable (ParentTable, Subtable);
1446 NodeLength += Subtable->Length;
1447 ContextIrptNumber++;
1448 }
1449
1450 IortSmmu->ContextInterruptCount = ContextIrptNumber;
1451
1452 /* Compile PMU interrupt array */
1453
1454 PmuIrptNumber = 0;
1455 IortSmmu->PmuInterruptOffset = NodeLength;
1456 while (*PFieldList)
1457 {
1458 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1459 &Subtable, TRUE);
1460 if (ACPI_FAILURE (Status))
1461 {
1462 return (Status);
1463 }
1464
1465 if (!Subtable)
1466 {
1467 break;
1468 }
1469
1470 DtInsertSubtable (ParentTable, Subtable);
1471 NodeLength += Subtable->Length;
1472 PmuIrptNumber++;
1473 }
1474
1475 IortSmmu->PmuInterruptCount = PmuIrptNumber;
1476 break;
1477
1478 case ACPI_IORT_NODE_SMMU_V3:
1479
1480 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
1481 &Subtable, TRUE);
1482 if (ACPI_FAILURE (Status))
1483 {
1484 return (Status);
1485 }
1486
1487 DtInsertSubtable (ParentTable, Subtable);
1488 NodeLength += Subtable->Length;
1489 break;
1490
1491 default:
1492
1493 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1494 return (AE_ERROR);
1495 }
1496
1497 /* Compile Array of ID mappings */
1498
1499 IortNode->MappingOffset = NodeLength;
1500 IdMappingNumber = 0;
1501 while (*PFieldList)
1502 {
1503 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1504 &Subtable, TRUE);
1505 if (ACPI_FAILURE (Status))
1506 {
1507 return (Status);
1508 }
1509
1510 if (!Subtable)
1511 {
1512 break;
1513 }
1514
1515 DtInsertSubtable (ParentTable, Subtable);
1516 NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1517 IdMappingNumber++;
1518 }
1519
1520 IortNode->MappingCount = IdMappingNumber;
1521
1522 /*
1523 * Node length can be determined by DT_LENGTH option
1524 * IortNode->Length = NodeLength;
1525 */
1526 DtPopSubtable ();
1527 ParentTable = DtPeekSubtable ();
1528 NodeNumber++;
1529 }
1530
1531 Iort->NodeCount = NodeNumber;
1532 return (AE_OK);
1533 }
1534
1535
1536 /******************************************************************************
1537 *
1538 * FUNCTION: DtCompileIvrs
1539 *
1540 * PARAMETERS: List - Current field list pointer
1541 *
1542 * RETURN: Status
1543 *
1544 * DESCRIPTION: Compile IVRS.
1545 *
1546 *****************************************************************************/
1547
1548 ACPI_STATUS
1549 DtCompileIvrs (
1550 void **List)
1551 {
1552 ACPI_STATUS Status;
1553 DT_SUBTABLE *Subtable;
1554 DT_SUBTABLE *ParentTable;
1555 DT_FIELD **PFieldList = (DT_FIELD **) List;
1556 DT_FIELD *SubtableStart;
1557 ACPI_DMTABLE_INFO *InfoTable;
1558 ACPI_IVRS_HEADER *IvrsHeader;
1559 UINT8 EntryType;
1560
1561
1562 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1563 &Subtable, TRUE);
1564 if (ACPI_FAILURE (Status))
1565 {
1566 return (Status);
1567 }
1568
1569 ParentTable = DtPeekSubtable ();
1570 DtInsertSubtable (ParentTable, Subtable);
1571
1572 while (*PFieldList)
1573 {
1574 SubtableStart = *PFieldList;
1575 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1576 &Subtable, TRUE);
1577 if (ACPI_FAILURE (Status))
1578 {
1579 return (Status);
1580 }
1581
1582 ParentTable = DtPeekSubtable ();
1583 DtInsertSubtable (ParentTable, Subtable);
1584 DtPushSubtable (Subtable);
1585
1586 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1587
1588 switch (IvrsHeader->Type)
1589 {
1590 case ACPI_IVRS_TYPE_HARDWARE:
1591
1592 InfoTable = AcpiDmTableInfoIvrs0;
1593 break;
1594
1595 case ACPI_IVRS_TYPE_MEMORY1:
1596 case ACPI_IVRS_TYPE_MEMORY2:
1597 case ACPI_IVRS_TYPE_MEMORY3:
1598
1599 InfoTable = AcpiDmTableInfoIvrs1;
1600 break;
1601
1602 default:
1603
1604 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1605 return (AE_ERROR);
1606 }
1607
1608 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1609 if (ACPI_FAILURE (Status))
1610 {
1611 return (Status);
1612 }
1613
1614 ParentTable = DtPeekSubtable ();
1615 DtInsertSubtable (ParentTable, Subtable);
1616
1617 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1618 {
1619 while (*PFieldList &&
1620 !strcmp ((*PFieldList)->Name, "Entry Type"))
1621 {
1622 SubtableStart = *PFieldList;
1623 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1624
1625 switch (EntryType)
1626 {
1627 /* 4-byte device entries */
1628
1629 case ACPI_IVRS_TYPE_PAD4:
1630 case ACPI_IVRS_TYPE_ALL:
1631 case ACPI_IVRS_TYPE_SELECT:
1632 case ACPI_IVRS_TYPE_START:
1633 case ACPI_IVRS_TYPE_END:
1634
1635 InfoTable = AcpiDmTableInfoIvrs4;
1636 break;
1637
1638 /* 8-byte entries, type A */
1639
1640 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1641 case ACPI_IVRS_TYPE_ALIAS_START:
1642
1643 InfoTable = AcpiDmTableInfoIvrs8a;
1644 break;
1645
1646 /* 8-byte entries, type B */
1647
1648 case ACPI_IVRS_TYPE_PAD8:
1649 case ACPI_IVRS_TYPE_EXT_SELECT:
1650 case ACPI_IVRS_TYPE_EXT_START:
1651
1652 InfoTable = AcpiDmTableInfoIvrs8b;
1653 break;
1654
1655 /* 8-byte entries, type C */
1656
1657 case ACPI_IVRS_TYPE_SPECIAL:
1658
1659 InfoTable = AcpiDmTableInfoIvrs8c;
1660 break;
1661
1662 default:
1663
1664 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1665 "IVRS Device Entry");
1666 return (AE_ERROR);
1667 }
1668
1669 Status = DtCompileTable (PFieldList, InfoTable,
1670 &Subtable, TRUE);
1671 if (ACPI_FAILURE (Status))
1672 {
1673 return (Status);
1674 }
1675
1676 DtInsertSubtable (ParentTable, Subtable);
1677 }
1678 }
1679
1680 DtPopSubtable ();
1681 }
1682
1683 return (AE_OK);
1684 }
1685