dttable.c revision 1.5 1 /******************************************************************************
2 *
3 * Module Name: dttable.c - handling for specific ACPI tables
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2015, 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 */
45
46 #include "aslcompiler.h"
47 #include "dtcompiler.h"
48
49 #define _COMPONENT DT_COMPILER
50 ACPI_MODULE_NAME ("dttable")
51
52
53 /* TBD: merge these into dmtbinfo.c? */
54
55 static ACPI_DMTABLE_INFO TableInfoAsfAddress[] =
56 {
57 {ACPI_DMT_BUFFER, 0, "Addresses", 0},
58 {ACPI_DMT_EXIT, 0, NULL, 0}
59 };
60
61 static ACPI_DMTABLE_INFO TableInfoDmarPciPath[] =
62 {
63 {ACPI_DMT_PCI_PATH, 0, "PCI Path", 0},
64 {ACPI_DMT_EXIT, 0, NULL, 0}
65 };
66
67
68 /* Local prototypes */
69
70 static ACPI_STATUS
71 DtCompileTwoSubtables (
72 void **List,
73 ACPI_DMTABLE_INFO *TableInfo1,
74 ACPI_DMTABLE_INFO *TableInfo2);
75
76
77 /******************************************************************************
78 *
79 * FUNCTION: DtCompileTwoSubtables
80 *
81 * PARAMETERS: List - Current field list pointer
82 * TableInfo1 - Info table 1
83 * TableInfo1 - Info table 2
84 *
85 * RETURN: Status
86 *
87 * DESCRIPTION: Compile tables with a header and one or more same subtables.
88 * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
89 *
90 *****************************************************************************/
91
92 static ACPI_STATUS
93 DtCompileTwoSubtables (
94 void **List,
95 ACPI_DMTABLE_INFO *TableInfo1,
96 ACPI_DMTABLE_INFO *TableInfo2)
97 {
98 ACPI_STATUS Status;
99 DT_SUBTABLE *Subtable;
100 DT_SUBTABLE *ParentTable;
101 DT_FIELD **PFieldList = (DT_FIELD **) List;
102
103
104 Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
105 if (ACPI_FAILURE (Status))
106 {
107 return (Status);
108 }
109
110 ParentTable = DtPeekSubtable ();
111 DtInsertSubtable (ParentTable, Subtable);
112
113 while (*PFieldList)
114 {
115 Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
116 if (ACPI_FAILURE (Status))
117 {
118 return (Status);
119 }
120
121 DtInsertSubtable (ParentTable, Subtable);
122 }
123
124 return (AE_OK);
125 }
126
127
128 /******************************************************************************
129 *
130 * FUNCTION: DtCompileFacs
131 *
132 * PARAMETERS: PFieldList - Current field list pointer
133 *
134 * RETURN: Status
135 *
136 * DESCRIPTION: Compile FACS.
137 *
138 *****************************************************************************/
139
140 ACPI_STATUS
141 DtCompileFacs (
142 DT_FIELD **PFieldList)
143 {
144 DT_SUBTABLE *Subtable;
145 UINT8 *ReservedBuffer;
146 ACPI_STATUS Status;
147 UINT32 ReservedSize;
148
149
150 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
151 &Gbl_RootTable, TRUE);
152 if (ACPI_FAILURE (Status))
153 {
154 return (Status);
155 }
156
157 /* Large FACS reserved area at the end of the table */
158
159 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
160 ReservedBuffer = UtLocalCalloc (ReservedSize);
161
162 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
163
164 ACPI_FREE (ReservedBuffer);
165 DtInsertSubtable (Gbl_RootTable, Subtable);
166 return (AE_OK);
167 }
168
169
170 /******************************************************************************
171 *
172 * FUNCTION: DtCompileRsdp
173 *
174 * PARAMETERS: PFieldList - Current field list pointer
175 *
176 * RETURN: Status
177 *
178 * DESCRIPTION: Compile RSDP.
179 *
180 *****************************************************************************/
181
182 ACPI_STATUS
183 DtCompileRsdp (
184 DT_FIELD **PFieldList)
185 {
186 DT_SUBTABLE *Subtable;
187 ACPI_TABLE_RSDP *Rsdp;
188 ACPI_RSDP_EXTENSION *RsdpExtension;
189 ACPI_STATUS Status;
190
191
192 /* Compile the "common" RSDP (ACPI 1.0) */
193
194 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
195 &Gbl_RootTable, TRUE);
196 if (ACPI_FAILURE (Status))
197 {
198 return (Status);
199 }
200
201 Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
202 DtSetTableChecksum (&Rsdp->Checksum);
203
204 if (Rsdp->Revision > 0)
205 {
206 /* Compile the "extended" part of the RSDP as a subtable */
207
208 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
209 &Subtable, TRUE);
210 if (ACPI_FAILURE (Status))
211 {
212 return (Status);
213 }
214
215 DtInsertSubtable (Gbl_RootTable, Subtable);
216
217 /* Set length and extended checksum for entire RSDP */
218
219 RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
220 RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
221 DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
222 }
223
224 return (AE_OK);
225 }
226
227
228 /******************************************************************************
229 *
230 * FUNCTION: DtCompileAsf
231 *
232 * PARAMETERS: List - Current field list pointer
233 *
234 * RETURN: Status
235 *
236 * DESCRIPTION: Compile ASF!.
237 *
238 *****************************************************************************/
239
240 ACPI_STATUS
241 DtCompileAsf (
242 void **List)
243 {
244 ACPI_ASF_INFO *AsfTable;
245 DT_SUBTABLE *Subtable;
246 DT_SUBTABLE *ParentTable;
247 ACPI_DMTABLE_INFO *InfoTable;
248 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
249 UINT32 DataCount = 0;
250 ACPI_STATUS Status;
251 UINT32 i;
252 DT_FIELD **PFieldList = (DT_FIELD **) List;
253 DT_FIELD *SubtableStart;
254
255
256 while (*PFieldList)
257 {
258 SubtableStart = *PFieldList;
259 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
260 &Subtable, TRUE);
261 if (ACPI_FAILURE (Status))
262 {
263 return (Status);
264 }
265
266 ParentTable = DtPeekSubtable ();
267 DtInsertSubtable (ParentTable, Subtable);
268 DtPushSubtable (Subtable);
269
270 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
271
272 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
273 {
274 case ACPI_ASF_TYPE_INFO:
275
276 InfoTable = AcpiDmTableInfoAsf0;
277 break;
278
279 case ACPI_ASF_TYPE_ALERT:
280
281 InfoTable = AcpiDmTableInfoAsf1;
282 break;
283
284 case ACPI_ASF_TYPE_CONTROL:
285
286 InfoTable = AcpiDmTableInfoAsf2;
287 break;
288
289 case ACPI_ASF_TYPE_BOOT:
290
291 InfoTable = AcpiDmTableInfoAsf3;
292 break;
293
294 case ACPI_ASF_TYPE_ADDRESS:
295
296 InfoTable = AcpiDmTableInfoAsf4;
297 break;
298
299 default:
300
301 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
302 return (AE_ERROR);
303 }
304
305 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
306 if (ACPI_FAILURE (Status))
307 {
308 return (Status);
309 }
310
311 ParentTable = DtPeekSubtable ();
312 DtInsertSubtable (ParentTable, Subtable);
313
314 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
315 {
316 case ACPI_ASF_TYPE_INFO:
317
318 DataInfoTable = NULL;
319 break;
320
321 case ACPI_ASF_TYPE_ALERT:
322
323 DataInfoTable = AcpiDmTableInfoAsf1a;
324 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
325 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
326 sizeof (ACPI_ASF_HEADER)))->Alerts;
327 break;
328
329 case ACPI_ASF_TYPE_CONTROL:
330
331 DataInfoTable = AcpiDmTableInfoAsf2a;
332 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
333 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
334 sizeof (ACPI_ASF_HEADER)))->Controls;
335 break;
336
337 case ACPI_ASF_TYPE_BOOT:
338
339 DataInfoTable = NULL;
340 break;
341
342 case ACPI_ASF_TYPE_ADDRESS:
343
344 DataInfoTable = TableInfoAsfAddress;
345 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
346 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
347 sizeof (ACPI_ASF_HEADER)))->Devices;
348 break;
349
350 default:
351
352 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
353 return (AE_ERROR);
354 }
355
356 if (DataInfoTable)
357 {
358 switch (AsfTable->Header.Type & 0x7F)
359 {
360 case ACPI_ASF_TYPE_ADDRESS:
361
362 while (DataCount > 0)
363 {
364 Status = DtCompileTable (PFieldList, DataInfoTable,
365 &Subtable, TRUE);
366 if (ACPI_FAILURE (Status))
367 {
368 return (Status);
369 }
370
371 DtInsertSubtable (ParentTable, Subtable);
372 DataCount = DataCount - Subtable->Length;
373 }
374 break;
375
376 default:
377
378 for (i = 0; i < DataCount; i++)
379 {
380 Status = DtCompileTable (PFieldList, DataInfoTable,
381 &Subtable, TRUE);
382 if (ACPI_FAILURE (Status))
383 {
384 return (Status);
385 }
386
387 DtInsertSubtable (ParentTable, Subtable);
388 }
389 break;
390 }
391 }
392
393 DtPopSubtable ();
394 }
395
396 return (AE_OK);
397 }
398
399
400 /******************************************************************************
401 *
402 * FUNCTION: DtCompileCpep
403 *
404 * PARAMETERS: List - Current field list pointer
405 *
406 * RETURN: Status
407 *
408 * DESCRIPTION: Compile CPEP.
409 *
410 *****************************************************************************/
411
412 ACPI_STATUS
413 DtCompileCpep (
414 void **List)
415 {
416 ACPI_STATUS Status;
417
418
419 Status = DtCompileTwoSubtables (List,
420 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
421 return (Status);
422 }
423
424
425 /******************************************************************************
426 *
427 * FUNCTION: DtCompileCsrt
428 *
429 * PARAMETERS: List - Current field list pointer
430 *
431 * RETURN: Status
432 *
433 * DESCRIPTION: Compile CSRT.
434 *
435 *****************************************************************************/
436
437 ACPI_STATUS
438 DtCompileCsrt (
439 void **List)
440 {
441 ACPI_STATUS Status = AE_OK;
442 DT_SUBTABLE *Subtable;
443 DT_SUBTABLE *ParentTable;
444 DT_FIELD **PFieldList = (DT_FIELD **) List;
445 UINT32 DescriptorCount;
446 UINT32 GroupLength;
447
448
449 /* Subtables (Resource Groups) */
450
451 ParentTable = DtPeekSubtable ();
452 while (*PFieldList)
453 {
454 /* Resource group subtable */
455
456 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
457 &Subtable, TRUE);
458 if (ACPI_FAILURE (Status))
459 {
460 return (Status);
461 }
462
463 /* Compute the number of resource descriptors */
464
465 GroupLength =
466 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
467 Subtable->Buffer))->Length -
468 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
469 Subtable->Buffer))->SharedInfoLength -
470 sizeof (ACPI_CSRT_GROUP);
471
472 DescriptorCount = (GroupLength /
473 sizeof (ACPI_CSRT_DESCRIPTOR));
474
475 DtInsertSubtable (ParentTable, Subtable);
476 DtPushSubtable (Subtable);
477 ParentTable = DtPeekSubtable ();
478
479 /* Shared info subtable (One per resource group) */
480
481 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
482 &Subtable, TRUE);
483 if (ACPI_FAILURE (Status))
484 {
485 return (Status);
486 }
487
488 DtInsertSubtable (ParentTable, Subtable);
489
490 /* Sub-Subtables (Resource Descriptors) */
491
492 while (*PFieldList && DescriptorCount)
493 {
494
495 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
496 &Subtable, TRUE);
497 if (ACPI_FAILURE (Status))
498 {
499 return (Status);
500 }
501 DtInsertSubtable (ParentTable, Subtable);
502
503 DtPushSubtable (Subtable);
504 ParentTable = DtPeekSubtable ();
505 if (*PFieldList)
506 {
507 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
508 &Subtable, TRUE);
509 if (ACPI_FAILURE (Status))
510 {
511 return (Status);
512 }
513 if (Subtable)
514 {
515 DtInsertSubtable (ParentTable, Subtable);
516 }
517 }
518 DtPopSubtable ();
519 ParentTable = DtPeekSubtable ();
520
521 DescriptorCount--;
522 }
523
524 DtPopSubtable ();
525 ParentTable = DtPeekSubtable ();
526 }
527
528 return (Status);
529 }
530
531
532 /******************************************************************************
533 *
534 * FUNCTION: DtCompileDbg2
535 *
536 * PARAMETERS: List - Current field list pointer
537 *
538 * RETURN: Status
539 *
540 * DESCRIPTION: Compile DBG2.
541 *
542 *****************************************************************************/
543
544 ACPI_STATUS
545 DtCompileDbg2 (
546 void **List)
547 {
548 ACPI_STATUS Status;
549 DT_SUBTABLE *Subtable;
550 DT_SUBTABLE *ParentTable;
551 DT_FIELD **PFieldList = (DT_FIELD **) List;
552 UINT32 SubtableCount;
553 ACPI_DBG2_HEADER *Dbg2Header;
554 ACPI_DBG2_DEVICE *DeviceInfo;
555 UINT16 CurrentOffset;
556 UINT32 i;
557
558
559 /* Main table */
560
561 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
562 if (ACPI_FAILURE (Status))
563 {
564 return (Status);
565 }
566
567 ParentTable = DtPeekSubtable ();
568 DtInsertSubtable (ParentTable, Subtable);
569
570 /* Main table fields */
571
572 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
573 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
574 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
575
576 SubtableCount = Dbg2Header->InfoCount;
577 DtPushSubtable (Subtable);
578
579 /* Process all Device Information subtables (Count = InfoCount) */
580
581 while (*PFieldList && SubtableCount)
582 {
583 /* Subtable: Debug Device Information */
584
585 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
586 &Subtable, TRUE);
587 if (ACPI_FAILURE (Status))
588 {
589 return (Status);
590 }
591
592 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
593 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
594
595 ParentTable = DtPeekSubtable ();
596 DtInsertSubtable (ParentTable, Subtable);
597 DtPushSubtable (Subtable);
598
599 ParentTable = DtPeekSubtable ();
600
601 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
602
603 DeviceInfo->BaseAddressOffset = CurrentOffset;
604 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
605 {
606 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
607 &Subtable, TRUE);
608 if (ACPI_FAILURE (Status))
609 {
610 return (Status);
611 }
612
613 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
614 DtInsertSubtable (ParentTable, Subtable);
615 }
616
617 /* AddressSize array (Required, size = RegisterCount) */
618
619 DeviceInfo->AddressSizeOffset = CurrentOffset;
620 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
621 {
622 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
623 &Subtable, TRUE);
624 if (ACPI_FAILURE (Status))
625 {
626 return (Status);
627 }
628
629 CurrentOffset += (UINT16) sizeof (UINT32);
630 DtInsertSubtable (ParentTable, Subtable);
631 }
632
633 /* NamespaceString device identifier (Required, size = NamePathLength) */
634
635 DeviceInfo->NamepathOffset = CurrentOffset;
636 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
637 &Subtable, TRUE);
638 if (ACPI_FAILURE (Status))
639 {
640 return (Status);
641 }
642
643 /* Update the device info header */
644
645 DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
646 CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
647 DtInsertSubtable (ParentTable, Subtable);
648
649 /* OemData - Variable-length data (Optional, size = OemDataLength) */
650
651 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
652 &Subtable, TRUE);
653 if (ACPI_FAILURE (Status))
654 {
655 return (Status);
656 }
657
658 /* Update the device info header (zeros if no OEM data present) */
659
660 DeviceInfo->OemDataOffset = 0;
661 DeviceInfo->OemDataLength = 0;
662
663 /* Optional subtable (OemData) */
664
665 if (Subtable && Subtable->Length)
666 {
667 DeviceInfo->OemDataOffset = CurrentOffset;
668 DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
669
670 DtInsertSubtable (ParentTable, Subtable);
671 }
672
673 SubtableCount--;
674 DtPopSubtable (); /* Get next Device Information subtable */
675 }
676
677 DtPopSubtable ();
678 return (AE_OK);
679 }
680
681
682 /******************************************************************************
683 *
684 * FUNCTION: DtCompileDmar
685 *
686 * PARAMETERS: List - Current field list pointer
687 *
688 * RETURN: Status
689 *
690 * DESCRIPTION: Compile DMAR.
691 *
692 *****************************************************************************/
693
694 ACPI_STATUS
695 DtCompileDmar (
696 void **List)
697 {
698 ACPI_STATUS Status;
699 DT_SUBTABLE *Subtable;
700 DT_SUBTABLE *ParentTable;
701 DT_FIELD **PFieldList = (DT_FIELD **) List;
702 DT_FIELD *SubtableStart;
703 ACPI_DMTABLE_INFO *InfoTable;
704 ACPI_DMAR_HEADER *DmarHeader;
705 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
706 UINT32 DeviceScopeLength;
707 UINT32 PciPathLength;
708
709
710 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
711 if (ACPI_FAILURE (Status))
712 {
713 return (Status);
714 }
715
716 ParentTable = DtPeekSubtable ();
717 DtInsertSubtable (ParentTable, Subtable);
718 DtPushSubtable (Subtable);
719
720 while (*PFieldList)
721 {
722 /* DMAR Header */
723
724 SubtableStart = *PFieldList;
725 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
726 &Subtable, TRUE);
727 if (ACPI_FAILURE (Status))
728 {
729 return (Status);
730 }
731
732 ParentTable = DtPeekSubtable ();
733 DtInsertSubtable (ParentTable, Subtable);
734 DtPushSubtable (Subtable);
735
736 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
737
738 switch (DmarHeader->Type)
739 {
740 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
741
742 InfoTable = AcpiDmTableInfoDmar0;
743 break;
744
745 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
746
747 InfoTable = AcpiDmTableInfoDmar1;
748 break;
749
750 case ACPI_DMAR_TYPE_ROOT_ATS:
751
752 InfoTable = AcpiDmTableInfoDmar2;
753 break;
754
755 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
756
757 InfoTable = AcpiDmTableInfoDmar3;
758 break;
759
760 case ACPI_DMAR_TYPE_NAMESPACE:
761
762 InfoTable = AcpiDmTableInfoDmar4;
763 break;
764
765 default:
766
767 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
768 return (AE_ERROR);
769 }
770
771 /* DMAR Subtable */
772
773 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
774 if (ACPI_FAILURE (Status))
775 {
776 return (Status);
777 }
778
779 ParentTable = DtPeekSubtable ();
780 DtInsertSubtable (ParentTable, Subtable);
781
782 /*
783 * Optional Device Scope subtables
784 */
785 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
786 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
787 {
788 /* These types do not support device scopes */
789
790 DtPopSubtable ();
791 continue;
792 }
793
794 DtPushSubtable (Subtable);
795 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
796 ParentTable->Length;
797 while (DeviceScopeLength)
798 {
799 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
800 &Subtable, FALSE);
801 if (Status == AE_NOT_FOUND)
802 {
803 break;
804 }
805
806 ParentTable = DtPeekSubtable ();
807 DtInsertSubtable (ParentTable, Subtable);
808 DtPushSubtable (Subtable);
809
810 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
811
812 /* Optional PCI Paths */
813
814 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
815 while (PciPathLength)
816 {
817 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
818 &Subtable, FALSE);
819 if (Status == AE_NOT_FOUND)
820 {
821 DtPopSubtable ();
822 break;
823 }
824
825 ParentTable = DtPeekSubtable ();
826 DtInsertSubtable (ParentTable, Subtable);
827 PciPathLength -= Subtable->Length;
828 }
829
830 DtPopSubtable ();
831 DeviceScopeLength -= DmarDeviceScope->Length;
832 }
833
834 DtPopSubtable ();
835 DtPopSubtable ();
836 }
837
838 return (AE_OK);
839 }
840
841
842 /******************************************************************************
843 *
844 * FUNCTION: DtCompileDrtm
845 *
846 * PARAMETERS: List - Current field list pointer
847 *
848 * RETURN: Status
849 *
850 * DESCRIPTION: Compile DRTM.
851 *
852 *****************************************************************************/
853
854 ACPI_STATUS
855 DtCompileDrtm (
856 void **List)
857 {
858 ACPI_STATUS Status;
859 DT_SUBTABLE *Subtable;
860 DT_SUBTABLE *ParentTable;
861 DT_FIELD **PFieldList = (DT_FIELD **) List;
862 UINT32 Count;
863 /* ACPI_TABLE_DRTM *Drtm; */
864 ACPI_DRTM_VTABLE_LIST *DrtmVtl;
865 ACPI_DRTM_RESOURCE_LIST *DrtmRl;
866 /* ACPI_DRTM_DPS_ID *DrtmDps; */
867
868
869 ParentTable = DtPeekSubtable ();
870
871 /* Compile DRTM header */
872
873 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
874 &Subtable, TRUE);
875 if (ACPI_FAILURE (Status))
876 {
877 return (Status);
878 }
879 DtInsertSubtable (ParentTable, Subtable);
880
881 /*
882 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
883 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
884 */
885 #if 0
886 Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
887 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
888 #endif
889 /* Compile VTL */
890
891 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
892 &Subtable, TRUE);
893 if (ACPI_FAILURE (Status))
894 {
895 return (Status);
896 }
897 DtInsertSubtable (ParentTable, Subtable);
898 DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
899
900 DtPushSubtable (Subtable);
901 ParentTable = DtPeekSubtable ();
902 Count = 0;
903 while (*PFieldList)
904 {
905 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
906 &Subtable, TRUE);
907 if (ACPI_FAILURE (Status))
908 {
909 return (Status);
910 }
911 if (!Subtable)
912 {
913 break;
914 }
915 DtInsertSubtable (ParentTable, Subtable);
916 Count++;
917 }
918 DrtmVtl->ValidatedTableCount = Count;
919 DtPopSubtable ();
920 ParentTable = DtPeekSubtable ();
921
922 /* Compile RL */
923
924 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
925 &Subtable, TRUE);
926 if (ACPI_FAILURE (Status))
927 {
928 return (Status);
929 }
930 DtInsertSubtable (ParentTable, Subtable);
931 DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
932
933 DtPushSubtable (Subtable);
934 ParentTable = DtPeekSubtable ();
935 Count = 0;
936 while (*PFieldList)
937 {
938 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
939 &Subtable, TRUE);
940 if (ACPI_FAILURE (Status))
941 {
942 return (Status);
943 }
944 if (!Subtable)
945 {
946 break;
947 }
948 DtInsertSubtable (ParentTable, Subtable);
949 Count++;
950 }
951 DrtmRl->ResourceCount = Count;
952 DtPopSubtable ();
953 ParentTable = DtPeekSubtable ();
954
955 /* Compile DPS */
956
957 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
958 &Subtable, TRUE);
959 if (ACPI_FAILURE (Status))
960 {
961 return (Status);
962 }
963 DtInsertSubtable (ParentTable, Subtable);
964 /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
965
966
967 return (AE_OK);
968 }
969
970
971 /******************************************************************************
972 *
973 * FUNCTION: DtCompileEinj
974 *
975 * PARAMETERS: List - Current field list pointer
976 *
977 * RETURN: Status
978 *
979 * DESCRIPTION: Compile EINJ.
980 *
981 *****************************************************************************/
982
983 ACPI_STATUS
984 DtCompileEinj (
985 void **List)
986 {
987 ACPI_STATUS Status;
988
989
990 Status = DtCompileTwoSubtables (List,
991 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
992 return (Status);
993 }
994
995
996 /******************************************************************************
997 *
998 * FUNCTION: DtCompileErst
999 *
1000 * PARAMETERS: List - Current field list pointer
1001 *
1002 * RETURN: Status
1003 *
1004 * DESCRIPTION: Compile ERST.
1005 *
1006 *****************************************************************************/
1007
1008 ACPI_STATUS
1009 DtCompileErst (
1010 void **List)
1011 {
1012 ACPI_STATUS Status;
1013
1014
1015 Status = DtCompileTwoSubtables (List,
1016 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
1017 return (Status);
1018 }
1019
1020
1021 /******************************************************************************
1022 *
1023 * FUNCTION: DtCompileFadt
1024 *
1025 * PARAMETERS: List - Current field list pointer
1026 *
1027 * RETURN: Status
1028 *
1029 * DESCRIPTION: Compile FADT.
1030 *
1031 *****************************************************************************/
1032
1033 ACPI_STATUS
1034 DtCompileFadt (
1035 void **List)
1036 {
1037 ACPI_STATUS Status;
1038 DT_SUBTABLE *Subtable;
1039 DT_SUBTABLE *ParentTable;
1040 DT_FIELD **PFieldList = (DT_FIELD **) List;
1041 ACPI_TABLE_HEADER *Table;
1042 UINT8 Revision;
1043
1044
1045 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
1046 &Subtable, TRUE);
1047 if (ACPI_FAILURE (Status))
1048 {
1049 return (Status);
1050 }
1051
1052 ParentTable = DtPeekSubtable ();
1053 DtInsertSubtable (ParentTable, Subtable);
1054
1055 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
1056 Revision = Table->Revision;
1057
1058 if (Revision == 2)
1059 {
1060 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
1061 &Subtable, TRUE);
1062 if (ACPI_FAILURE (Status))
1063 {
1064 return (Status);
1065 }
1066
1067 DtInsertSubtable (ParentTable, Subtable);
1068 }
1069 else if (Revision >= 2)
1070 {
1071 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
1072 &Subtable, TRUE);
1073 if (ACPI_FAILURE (Status))
1074 {
1075 return (Status);
1076 }
1077
1078 DtInsertSubtable (ParentTable, Subtable);
1079
1080 if (Revision >= 5)
1081 {
1082 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
1083 &Subtable, TRUE);
1084 if (ACPI_FAILURE (Status))
1085 {
1086 return (Status);
1087 }
1088
1089 DtInsertSubtable (ParentTable, Subtable);
1090 }
1091
1092 if (Revision >= 6)
1093 {
1094 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt6,
1095 &Subtable, TRUE);
1096 if (ACPI_FAILURE (Status))
1097 {
1098 return (Status);
1099 }
1100
1101 DtInsertSubtable (ParentTable, Subtable);
1102 }
1103 }
1104
1105 return (AE_OK);
1106 }
1107
1108 /******************************************************************************
1109 *
1110 * FUNCTION: DtCompileGtdt
1111 *
1112 * PARAMETERS: List - Current field list pointer
1113 *
1114 * RETURN: Status
1115 *
1116 * DESCRIPTION: Compile GTDT.
1117 *
1118 *****************************************************************************/
1119
1120 ACPI_STATUS
1121 DtCompileGtdt (
1122 void **List)
1123 {
1124 ACPI_STATUS Status;
1125 DT_SUBTABLE *Subtable;
1126 DT_SUBTABLE *ParentTable;
1127 DT_FIELD **PFieldList = (DT_FIELD **) List;
1128 DT_FIELD *SubtableStart;
1129 ACPI_SUBTABLE_HEADER *GtdtHeader;
1130 ACPI_DMTABLE_INFO *InfoTable;
1131 UINT32 GtCount;
1132
1133
1134 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
1135 &Subtable, TRUE);
1136 if (ACPI_FAILURE (Status))
1137 {
1138 return (Status);
1139 }
1140
1141 ParentTable = DtPeekSubtable ();
1142 DtInsertSubtable (ParentTable, Subtable);
1143
1144 while (*PFieldList)
1145 {
1146 SubtableStart = *PFieldList;
1147 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
1148 &Subtable, TRUE);
1149 if (ACPI_FAILURE (Status))
1150 {
1151 return (Status);
1152 }
1153
1154 ParentTable = DtPeekSubtable ();
1155 DtInsertSubtable (ParentTable, Subtable);
1156 DtPushSubtable (Subtable);
1157
1158 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1159
1160 switch (GtdtHeader->Type)
1161 {
1162 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1163
1164 InfoTable = AcpiDmTableInfoGtdt0;
1165 break;
1166
1167 case ACPI_GTDT_TYPE_WATCHDOG:
1168
1169 InfoTable = AcpiDmTableInfoGtdt1;
1170 break;
1171
1172 default:
1173
1174 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1175 return (AE_ERROR);
1176 }
1177
1178 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1179 if (ACPI_FAILURE (Status))
1180 {
1181 return (Status);
1182 }
1183
1184 ParentTable = DtPeekSubtable ();
1185 DtInsertSubtable (ParentTable, Subtable);
1186
1187 /*
1188 * Additional GT block subtable data
1189 */
1190
1191 switch (GtdtHeader->Type)
1192 {
1193 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1194
1195 DtPushSubtable (Subtable);
1196 ParentTable = DtPeekSubtable ();
1197
1198 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1199 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1200 while (GtCount)
1201 {
1202 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1203 &Subtable, TRUE);
1204 if (ACPI_FAILURE (Status))
1205 {
1206 return (Status);
1207 }
1208
1209
1210 DtInsertSubtable (ParentTable, Subtable);
1211 GtCount--;
1212 }
1213 DtPopSubtable ();
1214 break;
1215
1216 default:
1217
1218 break;
1219 }
1220
1221 DtPopSubtable ();
1222 }
1223
1224 return (AE_OK);
1225 }
1226
1227
1228 /******************************************************************************
1229 *
1230 * FUNCTION: DtCompileFpdt
1231 *
1232 * PARAMETERS: List - Current field list pointer
1233 *
1234 * RETURN: Status
1235 *
1236 * DESCRIPTION: Compile FPDT.
1237 *
1238 *****************************************************************************/
1239
1240 ACPI_STATUS
1241 DtCompileFpdt (
1242 void **List)
1243 {
1244 ACPI_STATUS Status;
1245 ACPI_FPDT_HEADER *FpdtHeader;
1246 DT_SUBTABLE *Subtable;
1247 DT_SUBTABLE *ParentTable;
1248 ACPI_DMTABLE_INFO *InfoTable;
1249 DT_FIELD **PFieldList = (DT_FIELD **) List;
1250 DT_FIELD *SubtableStart;
1251
1252
1253 while (*PFieldList)
1254 {
1255 SubtableStart = *PFieldList;
1256 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1257 &Subtable, TRUE);
1258 if (ACPI_FAILURE (Status))
1259 {
1260 return (Status);
1261 }
1262
1263 ParentTable = DtPeekSubtable ();
1264 DtInsertSubtable (ParentTable, Subtable);
1265 DtPushSubtable (Subtable);
1266
1267 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1268
1269 switch (FpdtHeader->Type)
1270 {
1271 case ACPI_FPDT_TYPE_BOOT:
1272
1273 InfoTable = AcpiDmTableInfoFpdt0;
1274 break;
1275
1276 case ACPI_FPDT_TYPE_S3PERF:
1277
1278 InfoTable = AcpiDmTableInfoFpdt1;
1279 break;
1280
1281 default:
1282
1283 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1284 return (AE_ERROR);
1285 break;
1286 }
1287
1288 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1289 if (ACPI_FAILURE (Status))
1290 {
1291 return (Status);
1292 }
1293
1294 ParentTable = DtPeekSubtable ();
1295 DtInsertSubtable (ParentTable, Subtable);
1296 DtPopSubtable ();
1297 }
1298
1299 return (AE_OK);
1300 }
1301
1302
1303 /******************************************************************************
1304 *
1305 * FUNCTION: DtCompileHest
1306 *
1307 * PARAMETERS: List - Current field list pointer
1308 *
1309 * RETURN: Status
1310 *
1311 * DESCRIPTION: Compile HEST.
1312 *
1313 *****************************************************************************/
1314
1315 ACPI_STATUS
1316 DtCompileHest (
1317 void **List)
1318 {
1319 ACPI_STATUS Status;
1320 DT_SUBTABLE *Subtable;
1321 DT_SUBTABLE *ParentTable;
1322 DT_FIELD **PFieldList = (DT_FIELD **) List;
1323 DT_FIELD *SubtableStart;
1324 ACPI_DMTABLE_INFO *InfoTable;
1325 UINT16 Type;
1326 UINT32 BankCount;
1327
1328
1329 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1330 &Subtable, TRUE);
1331 if (ACPI_FAILURE (Status))
1332 {
1333 return (Status);
1334 }
1335
1336 ParentTable = DtPeekSubtable ();
1337 DtInsertSubtable (ParentTable, Subtable);
1338
1339 while (*PFieldList)
1340 {
1341 /* Get subtable type */
1342
1343 SubtableStart = *PFieldList;
1344 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1345
1346 switch (Type)
1347 {
1348 case ACPI_HEST_TYPE_IA32_CHECK:
1349
1350 InfoTable = AcpiDmTableInfoHest0;
1351 break;
1352
1353 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1354
1355 InfoTable = AcpiDmTableInfoHest1;
1356 break;
1357
1358 case ACPI_HEST_TYPE_IA32_NMI:
1359
1360 InfoTable = AcpiDmTableInfoHest2;
1361 break;
1362
1363 case ACPI_HEST_TYPE_AER_ROOT_PORT:
1364
1365 InfoTable = AcpiDmTableInfoHest6;
1366 break;
1367
1368 case ACPI_HEST_TYPE_AER_ENDPOINT:
1369
1370 InfoTable = AcpiDmTableInfoHest7;
1371 break;
1372
1373 case ACPI_HEST_TYPE_AER_BRIDGE:
1374
1375 InfoTable = AcpiDmTableInfoHest8;
1376 break;
1377
1378 case ACPI_HEST_TYPE_GENERIC_ERROR:
1379
1380 InfoTable = AcpiDmTableInfoHest9;
1381 break;
1382
1383 default:
1384
1385 /* Cannot continue on unknown type */
1386
1387 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1388 return (AE_ERROR);
1389 }
1390
1391 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1392 if (ACPI_FAILURE (Status))
1393 {
1394 return (Status);
1395 }
1396
1397 DtInsertSubtable (ParentTable, Subtable);
1398
1399 /*
1400 * Additional subtable data - IA32 Error Bank(s)
1401 */
1402 BankCount = 0;
1403 switch (Type)
1404 {
1405 case ACPI_HEST_TYPE_IA32_CHECK:
1406
1407 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1408 Subtable->Buffer))->NumHardwareBanks;
1409 break;
1410
1411 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1412
1413 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1414 Subtable->Buffer))->NumHardwareBanks;
1415 break;
1416
1417 default:
1418
1419 break;
1420 }
1421
1422 while (BankCount)
1423 {
1424 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1425 &Subtable, TRUE);
1426 if (ACPI_FAILURE (Status))
1427 {
1428 return (Status);
1429 }
1430
1431 DtInsertSubtable (ParentTable, Subtable);
1432 BankCount--;
1433 }
1434 }
1435
1436 return (AE_OK);
1437 }
1438
1439
1440 /******************************************************************************
1441 *
1442 * FUNCTION: DtCompileIort
1443 *
1444 * PARAMETERS: List - Current field list pointer
1445 *
1446 * RETURN: Status
1447 *
1448 * DESCRIPTION: Compile IORT.
1449 *
1450 *****************************************************************************/
1451
1452 ACPI_STATUS
1453 DtCompileIort (
1454 void **List)
1455 {
1456 ACPI_STATUS Status;
1457 DT_SUBTABLE *Subtable;
1458 DT_SUBTABLE *ParentTable;
1459 DT_FIELD **PFieldList = (DT_FIELD **) List;
1460 DT_FIELD *SubtableStart;
1461 ACPI_TABLE_IORT *Iort;
1462 ACPI_IORT_NODE *IortNode;
1463 ACPI_IORT_ITS_GROUP *IortItsGroup;
1464 ACPI_IORT_SMMU *IortSmmu;
1465 UINT32 NodeNumber;
1466 UINT32 NodeLength;
1467 UINT32 IdMappingNumber;
1468 UINT32 ItsNumber;
1469 UINT32 ContextIrptNumber;
1470 UINT32 PmuIrptNumber;
1471 UINT32 PaddingLength;
1472
1473
1474 ParentTable = DtPeekSubtable ();
1475
1476 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
1477 &Subtable, TRUE);
1478 if (ACPI_FAILURE (Status))
1479 {
1480 return (Status);
1481 }
1482 DtInsertSubtable (ParentTable, Subtable);
1483
1484 /*
1485 * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
1486 * should be taken to avoid accessing ACPI_TABLE_HADER fields.
1487 */
1488 Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
1489 Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
1490
1491 /*
1492 * OptionalPadding - Variable-length data
1493 * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
1494 * Optionally allows the generic data types to be used for filling
1495 * this field.
1496 */
1497 Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
1498 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
1499 &Subtable, TRUE);
1500 if (ACPI_FAILURE (Status))
1501 {
1502 return (Status);
1503 }
1504 if (Subtable)
1505 {
1506 DtInsertSubtable (ParentTable, Subtable);
1507 Iort->NodeOffset += Subtable->Length;
1508 }
1509 else
1510 {
1511 Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
1512 AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
1513 if (ACPI_FAILURE (Status))
1514 {
1515 return (Status);
1516 }
1517 Iort->NodeOffset += PaddingLength;
1518 }
1519
1520 NodeNumber = 0;
1521 while (*PFieldList)
1522 {
1523 SubtableStart = *PFieldList;
1524 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
1525 &Subtable, TRUE);
1526 if (ACPI_FAILURE (Status))
1527 {
1528 return (Status);
1529 }
1530 DtInsertSubtable (ParentTable, Subtable);
1531 IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
1532 NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
1533
1534 DtPushSubtable (Subtable);
1535 ParentTable = DtPeekSubtable ();
1536
1537 switch (IortNode->Type)
1538 {
1539 case ACPI_IORT_NODE_ITS_GROUP:
1540
1541 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
1542 &Subtable, TRUE);
1543 if (ACPI_FAILURE (Status))
1544 {
1545 return (Status);
1546 }
1547 DtInsertSubtable (ParentTable, Subtable);
1548 IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
1549 NodeLength += Subtable->Length;
1550
1551 ItsNumber = 0;
1552 while (*PFieldList)
1553 {
1554 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
1555 &Subtable, TRUE);
1556 if (ACPI_FAILURE (Status))
1557 {
1558 return (Status);
1559 }
1560 if (!Subtable)
1561 {
1562 break;
1563 }
1564 DtInsertSubtable (ParentTable, Subtable);
1565 NodeLength += Subtable->Length;
1566 ItsNumber++;
1567 }
1568
1569 IortItsGroup->ItsCount = ItsNumber;
1570 break;
1571
1572 case ACPI_IORT_NODE_NAMED_COMPONENT:
1573
1574 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
1575 &Subtable, TRUE);
1576 if (ACPI_FAILURE (Status))
1577 {
1578 return (Status);
1579 }
1580 DtInsertSubtable (ParentTable, Subtable);
1581 NodeLength += Subtable->Length;
1582
1583 /*
1584 * Padding - Variable-length data
1585 * Optionally allows the offset of the ID mappings to be used
1586 * for filling this field.
1587 */
1588 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
1589 &Subtable, TRUE);
1590 if (ACPI_FAILURE (Status))
1591 {
1592 return (Status);
1593 }
1594 if (Subtable)
1595 {
1596 DtInsertSubtable (ParentTable, Subtable);
1597 NodeLength += Subtable->Length;
1598 }
1599 else
1600 {
1601 if (NodeLength > IortNode->MappingOffset)
1602 {
1603 return (AE_BAD_DATA);
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 DtInsertSubtable (ParentTable, Subtable);
1615 NodeLength = IortNode->MappingOffset;
1616 }
1617 }
1618 break;
1619
1620 case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
1621
1622 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
1623 &Subtable, TRUE);
1624 if (ACPI_FAILURE (Status))
1625 {
1626 return (Status);
1627 }
1628 DtInsertSubtable (ParentTable, Subtable);
1629 NodeLength += Subtable->Length;
1630 break;
1631
1632 case ACPI_IORT_NODE_SMMU:
1633
1634 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
1635 &Subtable, TRUE);
1636 if (ACPI_FAILURE (Status))
1637 {
1638 return (Status);
1639 }
1640 DtInsertSubtable (ParentTable, Subtable);
1641 IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
1642 NodeLength += Subtable->Length;
1643
1644 /* Compile global interrupt array */
1645
1646 IortSmmu->GlobalInterruptOffset = NodeLength;
1647 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
1648 &Subtable, TRUE);
1649 if (ACPI_FAILURE (Status))
1650 {
1651 return (Status);
1652 }
1653 DtInsertSubtable (ParentTable, Subtable);
1654 NodeLength += Subtable->Length;
1655
1656 /* Compile context interrupt array */
1657
1658 ContextIrptNumber = 0;
1659 IortSmmu->ContextInterruptOffset = NodeLength;
1660 while (*PFieldList)
1661 {
1662 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
1663 &Subtable, TRUE);
1664 if (ACPI_FAILURE (Status))
1665 {
1666 return (Status);
1667 }
1668 if (!Subtable)
1669 {
1670 break;
1671 }
1672 DtInsertSubtable (ParentTable, Subtable);
1673 NodeLength += Subtable->Length;
1674 ContextIrptNumber++;
1675 }
1676 IortSmmu->ContextInterruptCount = ContextIrptNumber;
1677
1678 /* Compile PMU interrupt array */
1679
1680 PmuIrptNumber = 0;
1681 IortSmmu->PmuInterruptOffset = NodeLength;
1682 while (*PFieldList)
1683 {
1684 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
1685 &Subtable, TRUE);
1686 if (ACPI_FAILURE (Status))
1687 {
1688 return (Status);
1689 }
1690 if (!Subtable)
1691 {
1692 break;
1693 }
1694 DtInsertSubtable (ParentTable, Subtable);
1695 NodeLength += Subtable->Length;
1696 PmuIrptNumber++;
1697 }
1698 IortSmmu->PmuInterruptCount = PmuIrptNumber;
1699 break;
1700
1701 default:
1702
1703 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
1704 return (AE_ERROR);
1705 }
1706
1707 /* Compile Array of ID mappings */
1708
1709 IortNode->MappingOffset = NodeLength;
1710 IdMappingNumber = 0;
1711 while (*PFieldList)
1712 {
1713 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
1714 &Subtable, TRUE);
1715 if (ACPI_FAILURE (Status))
1716 {
1717 return (Status);
1718 }
1719 if (!Subtable)
1720 {
1721 break;
1722 }
1723 DtInsertSubtable (ParentTable, Subtable);
1724 NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
1725 IdMappingNumber++;
1726 }
1727 IortNode->MappingCount = IdMappingNumber;
1728
1729 /*
1730 * Node length can be determined by DT_LENGTH option
1731 * IortNode->Length = NodeLength;
1732 */
1733 DtPopSubtable ();
1734 ParentTable = DtPeekSubtable ();
1735 NodeNumber++;
1736 }
1737 Iort->NodeCount = NodeNumber;
1738
1739 return (AE_OK);
1740 }
1741
1742
1743 /******************************************************************************
1744 *
1745 * FUNCTION: DtCompileIvrs
1746 *
1747 * PARAMETERS: List - Current field list pointer
1748 *
1749 * RETURN: Status
1750 *
1751 * DESCRIPTION: Compile IVRS.
1752 *
1753 *****************************************************************************/
1754
1755 ACPI_STATUS
1756 DtCompileIvrs (
1757 void **List)
1758 {
1759 ACPI_STATUS Status;
1760 DT_SUBTABLE *Subtable;
1761 DT_SUBTABLE *ParentTable;
1762 DT_FIELD **PFieldList = (DT_FIELD **) List;
1763 DT_FIELD *SubtableStart;
1764 ACPI_DMTABLE_INFO *InfoTable;
1765 ACPI_IVRS_HEADER *IvrsHeader;
1766 UINT8 EntryType;
1767
1768
1769 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1770 &Subtable, TRUE);
1771 if (ACPI_FAILURE (Status))
1772 {
1773 return (Status);
1774 }
1775
1776 ParentTable = DtPeekSubtable ();
1777 DtInsertSubtable (ParentTable, Subtable);
1778
1779 while (*PFieldList)
1780 {
1781 SubtableStart = *PFieldList;
1782 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1783 &Subtable, TRUE);
1784 if (ACPI_FAILURE (Status))
1785 {
1786 return (Status);
1787 }
1788
1789 ParentTable = DtPeekSubtable ();
1790 DtInsertSubtable (ParentTable, Subtable);
1791 DtPushSubtable (Subtable);
1792
1793 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1794
1795 switch (IvrsHeader->Type)
1796 {
1797 case ACPI_IVRS_TYPE_HARDWARE:
1798
1799 InfoTable = AcpiDmTableInfoIvrs0;
1800 break;
1801
1802 case ACPI_IVRS_TYPE_MEMORY1:
1803 case ACPI_IVRS_TYPE_MEMORY2:
1804 case ACPI_IVRS_TYPE_MEMORY3:
1805
1806 InfoTable = AcpiDmTableInfoIvrs1;
1807 break;
1808
1809 default:
1810
1811 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1812 return (AE_ERROR);
1813 }
1814
1815 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1816 if (ACPI_FAILURE (Status))
1817 {
1818 return (Status);
1819 }
1820
1821 ParentTable = DtPeekSubtable ();
1822 DtInsertSubtable (ParentTable, Subtable);
1823
1824 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1825 {
1826 while (*PFieldList &&
1827 !strcmp ((*PFieldList)->Name, "Entry Type"))
1828 {
1829 SubtableStart = *PFieldList;
1830 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1831
1832 switch (EntryType)
1833 {
1834 /* 4-byte device entries */
1835
1836 case ACPI_IVRS_TYPE_PAD4:
1837 case ACPI_IVRS_TYPE_ALL:
1838 case ACPI_IVRS_TYPE_SELECT:
1839 case ACPI_IVRS_TYPE_START:
1840 case ACPI_IVRS_TYPE_END:
1841
1842 InfoTable = AcpiDmTableInfoIvrs4;
1843 break;
1844
1845 /* 8-byte entries, type A */
1846
1847 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1848 case ACPI_IVRS_TYPE_ALIAS_START:
1849
1850 InfoTable = AcpiDmTableInfoIvrs8a;
1851 break;
1852
1853 /* 8-byte entries, type B */
1854
1855 case ACPI_IVRS_TYPE_PAD8:
1856 case ACPI_IVRS_TYPE_EXT_SELECT:
1857 case ACPI_IVRS_TYPE_EXT_START:
1858
1859 InfoTable = AcpiDmTableInfoIvrs8b;
1860 break;
1861
1862 /* 8-byte entries, type C */
1863
1864 case ACPI_IVRS_TYPE_SPECIAL:
1865
1866 InfoTable = AcpiDmTableInfoIvrs8c;
1867 break;
1868
1869 default:
1870
1871 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1872 "IVRS Device Entry");
1873 return (AE_ERROR);
1874 }
1875
1876 Status = DtCompileTable (PFieldList, InfoTable,
1877 &Subtable, TRUE);
1878 if (ACPI_FAILURE (Status))
1879 {
1880 return (Status);
1881 }
1882
1883 DtInsertSubtable (ParentTable, Subtable);
1884 }
1885 }
1886
1887 DtPopSubtable ();
1888 }
1889
1890 return (AE_OK);
1891 }
1892
1893
1894 /******************************************************************************
1895 *
1896 * FUNCTION: DtCompileLpit
1897 *
1898 * PARAMETERS: List - Current field list pointer
1899 *
1900 * RETURN: Status
1901 *
1902 * DESCRIPTION: Compile LPIT.
1903 *
1904 *****************************************************************************/
1905
1906 ACPI_STATUS
1907 DtCompileLpit (
1908 void **List)
1909 {
1910 ACPI_STATUS Status;
1911 DT_SUBTABLE *Subtable;
1912 DT_SUBTABLE *ParentTable;
1913 DT_FIELD **PFieldList = (DT_FIELD **) List;
1914 DT_FIELD *SubtableStart;
1915 ACPI_DMTABLE_INFO *InfoTable;
1916 ACPI_LPIT_HEADER *LpitHeader;
1917
1918
1919 /* Note: Main table consists only of the standard ACPI table header */
1920
1921 while (*PFieldList)
1922 {
1923 SubtableStart = *PFieldList;
1924
1925 /* LPIT Subtable header */
1926
1927 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1928 &Subtable, TRUE);
1929 if (ACPI_FAILURE (Status))
1930 {
1931 return (Status);
1932 }
1933
1934 ParentTable = DtPeekSubtable ();
1935 DtInsertSubtable (ParentTable, Subtable);
1936 DtPushSubtable (Subtable);
1937
1938 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1939
1940 switch (LpitHeader->Type)
1941 {
1942 case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1943
1944 InfoTable = AcpiDmTableInfoLpit0;
1945 break;
1946
1947 default:
1948
1949 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1950 return (AE_ERROR);
1951 }
1952
1953 /* LPIT Subtable */
1954
1955 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1956 if (ACPI_FAILURE (Status))
1957 {
1958 return (Status);
1959 }
1960
1961 ParentTable = DtPeekSubtable ();
1962 DtInsertSubtable (ParentTable, Subtable);
1963 DtPopSubtable ();
1964 }
1965
1966 return (AE_OK);
1967 }
1968
1969
1970 /******************************************************************************
1971 *
1972 * FUNCTION: DtCompileMadt
1973 *
1974 * PARAMETERS: List - Current field list pointer
1975 *
1976 * RETURN: Status
1977 *
1978 * DESCRIPTION: Compile MADT.
1979 *
1980 *****************************************************************************/
1981
1982 ACPI_STATUS
1983 DtCompileMadt (
1984 void **List)
1985 {
1986 ACPI_STATUS Status;
1987 DT_SUBTABLE *Subtable;
1988 DT_SUBTABLE *ParentTable;
1989 DT_FIELD **PFieldList = (DT_FIELD **) List;
1990 DT_FIELD *SubtableStart;
1991 ACPI_SUBTABLE_HEADER *MadtHeader;
1992 ACPI_DMTABLE_INFO *InfoTable;
1993
1994
1995 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1996 &Subtable, TRUE);
1997 if (ACPI_FAILURE (Status))
1998 {
1999 return (Status);
2000 }
2001
2002 ParentTable = DtPeekSubtable ();
2003 DtInsertSubtable (ParentTable, Subtable);
2004
2005 while (*PFieldList)
2006 {
2007 SubtableStart = *PFieldList;
2008 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
2009 &Subtable, TRUE);
2010 if (ACPI_FAILURE (Status))
2011 {
2012 return (Status);
2013 }
2014
2015 ParentTable = DtPeekSubtable ();
2016 DtInsertSubtable (ParentTable, Subtable);
2017 DtPushSubtable (Subtable);
2018
2019 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2020
2021 switch (MadtHeader->Type)
2022 {
2023 case ACPI_MADT_TYPE_LOCAL_APIC:
2024
2025 InfoTable = AcpiDmTableInfoMadt0;
2026 break;
2027
2028 case ACPI_MADT_TYPE_IO_APIC:
2029
2030 InfoTable = AcpiDmTableInfoMadt1;
2031 break;
2032
2033 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
2034
2035 InfoTable = AcpiDmTableInfoMadt2;
2036 break;
2037
2038 case ACPI_MADT_TYPE_NMI_SOURCE:
2039
2040 InfoTable = AcpiDmTableInfoMadt3;
2041 break;
2042
2043 case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
2044
2045 InfoTable = AcpiDmTableInfoMadt4;
2046 break;
2047
2048 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
2049
2050 InfoTable = AcpiDmTableInfoMadt5;
2051 break;
2052
2053 case ACPI_MADT_TYPE_IO_SAPIC:
2054
2055 InfoTable = AcpiDmTableInfoMadt6;
2056 break;
2057
2058 case ACPI_MADT_TYPE_LOCAL_SAPIC:
2059
2060 InfoTable = AcpiDmTableInfoMadt7;
2061 break;
2062
2063 case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
2064
2065 InfoTable = AcpiDmTableInfoMadt8;
2066 break;
2067
2068 case ACPI_MADT_TYPE_LOCAL_X2APIC:
2069
2070 InfoTable = AcpiDmTableInfoMadt9;
2071 break;
2072
2073 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
2074
2075 InfoTable = AcpiDmTableInfoMadt10;
2076 break;
2077
2078 case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
2079
2080 InfoTable = AcpiDmTableInfoMadt11;
2081 break;
2082
2083 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
2084
2085 InfoTable = AcpiDmTableInfoMadt12;
2086 break;
2087
2088 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
2089
2090 InfoTable = AcpiDmTableInfoMadt13;
2091 break;
2092
2093 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
2094
2095 InfoTable = AcpiDmTableInfoMadt14;
2096 break;
2097
2098 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
2099
2100 InfoTable = AcpiDmTableInfoMadt15;
2101 break;
2102
2103 default:
2104
2105 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
2106 return (AE_ERROR);
2107 }
2108
2109 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2110 if (ACPI_FAILURE (Status))
2111 {
2112 return (Status);
2113 }
2114
2115 ParentTable = DtPeekSubtable ();
2116 DtInsertSubtable (ParentTable, Subtable);
2117 DtPopSubtable ();
2118 }
2119
2120 return (AE_OK);
2121 }
2122
2123
2124 /******************************************************************************
2125 *
2126 * FUNCTION: DtCompileMcfg
2127 *
2128 * PARAMETERS: List - Current field list pointer
2129 *
2130 * RETURN: Status
2131 *
2132 * DESCRIPTION: Compile MCFG.
2133 *
2134 *****************************************************************************/
2135
2136 ACPI_STATUS
2137 DtCompileMcfg (
2138 void **List)
2139 {
2140 ACPI_STATUS Status;
2141
2142
2143 Status = DtCompileTwoSubtables (List,
2144 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
2145 return (Status);
2146 }
2147
2148
2149 /******************************************************************************
2150 *
2151 * FUNCTION: DtCompileMpst
2152 *
2153 * PARAMETERS: List - Current field list pointer
2154 *
2155 * RETURN: Status
2156 *
2157 * DESCRIPTION: Compile MPST.
2158 *
2159 *****************************************************************************/
2160
2161 ACPI_STATUS
2162 DtCompileMpst (
2163 void **List)
2164 {
2165 ACPI_STATUS Status;
2166 DT_SUBTABLE *Subtable;
2167 DT_SUBTABLE *ParentTable;
2168 DT_FIELD **PFieldList = (DT_FIELD **) List;
2169 ACPI_MPST_CHANNEL *MpstChannelInfo;
2170 ACPI_MPST_POWER_NODE *MpstPowerNode;
2171 ACPI_MPST_DATA_HDR *MpstDataHeader;
2172 UINT16 SubtableCount;
2173 UINT32 PowerStateCount;
2174 UINT32 ComponentCount;
2175
2176
2177 /* Main table */
2178
2179 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
2180 if (ACPI_FAILURE (Status))
2181 {
2182 return (Status);
2183 }
2184
2185 ParentTable = DtPeekSubtable ();
2186 DtInsertSubtable (ParentTable, Subtable);
2187 DtPushSubtable (Subtable);
2188
2189 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
2190 SubtableCount = MpstChannelInfo->PowerNodeCount;
2191
2192 while (*PFieldList && SubtableCount)
2193 {
2194 /* Subtable: Memory Power Node(s) */
2195
2196 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
2197 &Subtable, TRUE);
2198 if (ACPI_FAILURE (Status))
2199 {
2200 return (Status);
2201 }
2202
2203 ParentTable = DtPeekSubtable ();
2204 DtInsertSubtable (ParentTable, Subtable);
2205 DtPushSubtable (Subtable);
2206
2207 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
2208 PowerStateCount = MpstPowerNode->NumPowerStates;
2209 ComponentCount = MpstPowerNode->NumPhysicalComponents;
2210
2211 ParentTable = DtPeekSubtable ();
2212
2213 /* Sub-subtables - Memory Power State Structure(s) */
2214
2215 while (*PFieldList && PowerStateCount)
2216 {
2217 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
2218 &Subtable, TRUE);
2219 if (ACPI_FAILURE (Status))
2220 {
2221 return (Status);
2222 }
2223
2224 DtInsertSubtable (ParentTable, Subtable);
2225 PowerStateCount--;
2226 }
2227
2228 /* Sub-subtables - Physical Component ID Structure(s) */
2229
2230 while (*PFieldList && ComponentCount)
2231 {
2232 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
2233 &Subtable, TRUE);
2234 if (ACPI_FAILURE (Status))
2235 {
2236 return (Status);
2237 }
2238
2239 DtInsertSubtable (ParentTable, Subtable);
2240 ComponentCount--;
2241 }
2242
2243 SubtableCount--;
2244 DtPopSubtable ();
2245 }
2246
2247 /* Subtable: Count of Memory Power State Characteristic structures */
2248
2249 DtPopSubtable ();
2250
2251 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
2252 if (ACPI_FAILURE (Status))
2253 {
2254 return (Status);
2255 }
2256
2257 ParentTable = DtPeekSubtable ();
2258 DtInsertSubtable (ParentTable, Subtable);
2259 DtPushSubtable (Subtable);
2260
2261 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
2262 SubtableCount = MpstDataHeader->CharacteristicsCount;
2263
2264 ParentTable = DtPeekSubtable ();
2265
2266 /* Subtable: Memory Power State Characteristics structure(s) */
2267
2268 while (*PFieldList && SubtableCount)
2269 {
2270 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
2271 &Subtable, TRUE);
2272 if (ACPI_FAILURE (Status))
2273 {
2274 return (Status);
2275 }
2276
2277 DtInsertSubtable (ParentTable, Subtable);
2278 SubtableCount--;
2279 }
2280
2281 DtPopSubtable ();
2282 return (AE_OK);
2283 }
2284
2285
2286 /******************************************************************************
2287 *
2288 * FUNCTION: DtCompileMsct
2289 *
2290 * PARAMETERS: List - Current field list pointer
2291 *
2292 * RETURN: Status
2293 *
2294 * DESCRIPTION: Compile MSCT.
2295 *
2296 *****************************************************************************/
2297
2298 ACPI_STATUS
2299 DtCompileMsct (
2300 void **List)
2301 {
2302 ACPI_STATUS Status;
2303
2304
2305 Status = DtCompileTwoSubtables (List,
2306 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
2307 return (Status);
2308 }
2309
2310
2311 /******************************************************************************
2312 *
2313 * FUNCTION: DtCompileMtmr
2314 *
2315 * PARAMETERS: List - Current field list pointer
2316 *
2317 * RETURN: Status
2318 *
2319 * DESCRIPTION: Compile MTMR.
2320 *
2321 *****************************************************************************/
2322
2323 ACPI_STATUS
2324 DtCompileMtmr (
2325 void **List)
2326 {
2327 ACPI_STATUS Status;
2328
2329
2330 Status = DtCompileTwoSubtables (List,
2331 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
2332 return (Status);
2333 }
2334
2335
2336 /******************************************************************************
2337 *
2338 * FUNCTION: DtCompileNfit
2339 *
2340 * PARAMETERS: List - Current field list pointer
2341 *
2342 * RETURN: Status
2343 *
2344 * DESCRIPTION: Compile NFIT.
2345 *
2346 *****************************************************************************/
2347
2348 ACPI_STATUS
2349 DtCompileNfit (
2350 void **List)
2351 {
2352 ACPI_STATUS Status;
2353 DT_SUBTABLE *Subtable;
2354 DT_SUBTABLE *ParentTable;
2355 DT_FIELD **PFieldList = (DT_FIELD **) List;
2356 DT_FIELD *SubtableStart;
2357 ACPI_NFIT_HEADER *NfitHeader;
2358 ACPI_DMTABLE_INFO *InfoTable;
2359 UINT32 Count;
2360 ACPI_NFIT_INTERLEAVE *Interleave = NULL;
2361 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
2362
2363 /* Main table */
2364
2365 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
2366 &Subtable, TRUE);
2367 if (ACPI_FAILURE (Status))
2368 {
2369 return (Status);
2370 }
2371
2372 ParentTable = DtPeekSubtable ();
2373 DtInsertSubtable (ParentTable, Subtable);
2374 DtPushSubtable (Subtable);
2375
2376 /* Subtables */
2377
2378 while (*PFieldList)
2379 {
2380 SubtableStart = *PFieldList;
2381 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
2382 &Subtable, TRUE);
2383 if (ACPI_FAILURE (Status))
2384 {
2385 return (Status);
2386 }
2387
2388 ParentTable = DtPeekSubtable ();
2389 DtInsertSubtable (ParentTable, Subtable);
2390 DtPushSubtable (Subtable);
2391
2392 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
2393
2394 switch (NfitHeader->Type)
2395 {
2396 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2397
2398 InfoTable = AcpiDmTableInfoNfit0;
2399 break;
2400
2401 case ACPI_NFIT_TYPE_MEMORY_MAP:
2402
2403 InfoTable = AcpiDmTableInfoNfit1;
2404 break;
2405
2406 case ACPI_NFIT_TYPE_INTERLEAVE:
2407
2408 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
2409 InfoTable = AcpiDmTableInfoNfit2;
2410 break;
2411
2412 case ACPI_NFIT_TYPE_SMBIOS:
2413
2414 InfoTable = AcpiDmTableInfoNfit3;
2415 break;
2416
2417 case ACPI_NFIT_TYPE_CONTROL_REGION:
2418
2419 InfoTable = AcpiDmTableInfoNfit4;
2420 break;
2421
2422 case ACPI_NFIT_TYPE_DATA_REGION:
2423
2424 InfoTable = AcpiDmTableInfoNfit5;
2425 break;
2426
2427 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2428
2429 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
2430 InfoTable = AcpiDmTableInfoNfit6;
2431 break;
2432
2433 default:
2434
2435 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
2436 return (AE_ERROR);
2437 }
2438
2439 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2440 if (ACPI_FAILURE (Status))
2441 {
2442 return (Status);
2443 }
2444
2445 ParentTable = DtPeekSubtable ();
2446 DtInsertSubtable (ParentTable, Subtable);
2447 DtPopSubtable ();
2448
2449 switch (NfitHeader->Type)
2450 {
2451 case ACPI_NFIT_TYPE_INTERLEAVE:
2452
2453 Count = 0;
2454 DtPushSubtable (Subtable);
2455 while (*PFieldList)
2456 {
2457 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
2458 &Subtable, FALSE);
2459 if (ACPI_FAILURE (Status))
2460 {
2461 return (Status);
2462 }
2463 if (!Subtable)
2464 {
2465 DtPopSubtable ();
2466 break;
2467 }
2468
2469 ParentTable = DtPeekSubtable ();
2470 DtInsertSubtable (ParentTable, Subtable);
2471 Count++;
2472 }
2473
2474 Interleave->LineCount = Count;
2475 DtPopSubtable ();
2476 break;
2477
2478 case ACPI_NFIT_TYPE_SMBIOS:
2479
2480 if (*PFieldList)
2481 {
2482 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
2483 &Subtable, TRUE);
2484 if (ACPI_FAILURE (Status))
2485 {
2486 return (Status);
2487 }
2488 if (Subtable)
2489 {
2490 DtInsertSubtable (ParentTable, Subtable);
2491 }
2492 }
2493 break;
2494
2495 case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2496
2497 Count = 0;
2498 DtPushSubtable (Subtable);
2499 while (*PFieldList)
2500 {
2501 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
2502 &Subtable, FALSE);
2503 if (ACPI_FAILURE (Status))
2504 {
2505 return (Status);
2506 }
2507 if (!Subtable)
2508 {
2509 DtPopSubtable ();
2510 break;
2511 }
2512
2513 ParentTable = DtPeekSubtable ();
2514 DtInsertSubtable (ParentTable, Subtable);
2515 Count++;
2516 }
2517
2518 Hint->HintCount = (UINT16) Count;
2519 DtPopSubtable ();
2520 break;
2521
2522 default:
2523 break;
2524 }
2525 }
2526
2527 return (AE_OK);
2528 }
2529
2530
2531 /******************************************************************************
2532 *
2533 * FUNCTION: DtCompilePcct
2534 *
2535 * PARAMETERS: List - Current field list pointer
2536 *
2537 * RETURN: Status
2538 *
2539 * DESCRIPTION: Compile PCCT.
2540 *
2541 *****************************************************************************/
2542
2543 ACPI_STATUS
2544 DtCompilePcct (
2545 void **List)
2546 {
2547 ACPI_STATUS Status;
2548 DT_SUBTABLE *Subtable;
2549 DT_SUBTABLE *ParentTable;
2550 DT_FIELD **PFieldList = (DT_FIELD **) List;
2551 DT_FIELD *SubtableStart;
2552 ACPI_SUBTABLE_HEADER *PcctHeader;
2553 ACPI_DMTABLE_INFO *InfoTable;
2554
2555
2556 /* Main table */
2557
2558 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
2559 &Subtable, TRUE);
2560 if (ACPI_FAILURE (Status))
2561 {
2562 return (Status);
2563 }
2564
2565 ParentTable = DtPeekSubtable ();
2566 DtInsertSubtable (ParentTable, Subtable);
2567
2568 /* Subtables */
2569
2570 while (*PFieldList)
2571 {
2572 SubtableStart = *PFieldList;
2573 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
2574 &Subtable, TRUE);
2575 if (ACPI_FAILURE (Status))
2576 {
2577 return (Status);
2578 }
2579
2580 ParentTable = DtPeekSubtable ();
2581 DtInsertSubtable (ParentTable, Subtable);
2582 DtPushSubtable (Subtable);
2583
2584 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2585
2586 switch (PcctHeader->Type)
2587 {
2588 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
2589
2590 InfoTable = AcpiDmTableInfoPcct0;
2591 break;
2592
2593 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
2594
2595 InfoTable = AcpiDmTableInfoPcct1;
2596 break;
2597
2598 default:
2599
2600 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
2601 return (AE_ERROR);
2602 }
2603
2604 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2605 if (ACPI_FAILURE (Status))
2606 {
2607 return (Status);
2608 }
2609
2610 ParentTable = DtPeekSubtable ();
2611 DtInsertSubtable (ParentTable, Subtable);
2612 DtPopSubtable ();
2613 }
2614
2615 return (AE_OK);
2616 }
2617
2618
2619 /******************************************************************************
2620 *
2621 * FUNCTION: DtCompilePmtt
2622 *
2623 * PARAMETERS: List - Current field list pointer
2624 *
2625 * RETURN: Status
2626 *
2627 * DESCRIPTION: Compile PMTT.
2628 *
2629 *****************************************************************************/
2630
2631 ACPI_STATUS
2632 DtCompilePmtt (
2633 void **List)
2634 {
2635 ACPI_STATUS Status;
2636 DT_SUBTABLE *Subtable;
2637 DT_SUBTABLE *ParentTable;
2638 DT_FIELD **PFieldList = (DT_FIELD **) List;
2639 DT_FIELD *SubtableStart;
2640 ACPI_PMTT_HEADER *PmttHeader;
2641 ACPI_PMTT_CONTROLLER *PmttController;
2642 UINT16 DomainCount;
2643 UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET;
2644
2645
2646 /* Main table */
2647
2648 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
2649 if (ACPI_FAILURE (Status))
2650 {
2651 return (Status);
2652 }
2653
2654 ParentTable = DtPeekSubtable ();
2655 DtInsertSubtable (ParentTable, Subtable);
2656 DtPushSubtable (Subtable);
2657
2658 while (*PFieldList)
2659 {
2660 SubtableStart = *PFieldList;
2661 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
2662 &Subtable, TRUE);
2663 if (ACPI_FAILURE (Status))
2664 {
2665 return (Status);
2666 }
2667
2668 PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
2669 while (PrevType >= PmttHeader->Type)
2670 {
2671 DtPopSubtable ();
2672
2673 if (PrevType == ACPI_PMTT_TYPE_SOCKET)
2674 {
2675 break;
2676 }
2677 PrevType--;
2678 }
2679 PrevType = PmttHeader->Type;
2680
2681 ParentTable = DtPeekSubtable ();
2682 DtInsertSubtable (ParentTable, Subtable);
2683 DtPushSubtable (Subtable);
2684
2685 switch (PmttHeader->Type)
2686 {
2687 case ACPI_PMTT_TYPE_SOCKET:
2688
2689 /* Subtable: Socket Structure */
2690
2691 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
2692 &Subtable, TRUE);
2693 if (ACPI_FAILURE (Status))
2694 {
2695 return (Status);
2696 }
2697
2698 ParentTable = DtPeekSubtable ();
2699 DtInsertSubtable (ParentTable, Subtable);
2700 break;
2701
2702 case ACPI_PMTT_TYPE_CONTROLLER:
2703
2704 /* Subtable: Memory Controller Structure */
2705
2706 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
2707 &Subtable, TRUE);
2708 if (ACPI_FAILURE (Status))
2709 {
2710 return (Status);
2711 }
2712
2713 ParentTable = DtPeekSubtable ();
2714 DtInsertSubtable (ParentTable, Subtable);
2715
2716 PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
2717 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
2718 DomainCount = PmttController->DomainCount;
2719
2720 while (DomainCount)
2721 {
2722 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
2723 &Subtable, TRUE);
2724 if (ACPI_FAILURE (Status))
2725 {
2726 return (Status);
2727 }
2728
2729 DtInsertSubtable (ParentTable, Subtable);
2730 DomainCount--;
2731 }
2732 break;
2733
2734 case ACPI_PMTT_TYPE_DIMM:
2735
2736 /* Subtable: Physical Component Structure */
2737
2738 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
2739 &Subtable, TRUE);
2740 if (ACPI_FAILURE (Status))
2741 {
2742 return (Status);
2743 }
2744
2745 ParentTable = DtPeekSubtable ();
2746 DtInsertSubtable (ParentTable, Subtable);
2747 break;
2748
2749 default:
2750
2751 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
2752 return (AE_ERROR);
2753 }
2754 }
2755
2756 return (Status);
2757 }
2758
2759
2760 /******************************************************************************
2761 *
2762 * FUNCTION: DtCompileRsdt
2763 *
2764 * PARAMETERS: List - Current field list pointer
2765 *
2766 * RETURN: Status
2767 *
2768 * DESCRIPTION: Compile RSDT.
2769 *
2770 *****************************************************************************/
2771
2772 ACPI_STATUS
2773 DtCompileRsdt (
2774 void **List)
2775 {
2776 DT_SUBTABLE *Subtable;
2777 DT_SUBTABLE *ParentTable;
2778 DT_FIELD *FieldList = *(DT_FIELD **) List;
2779 UINT32 Address;
2780
2781
2782 ParentTable = DtPeekSubtable ();
2783
2784 while (FieldList)
2785 {
2786 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2787
2788 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2789 DtInsertSubtable (ParentTable, Subtable);
2790 FieldList = FieldList->Next;
2791 }
2792
2793 return (AE_OK);
2794 }
2795
2796
2797 /******************************************************************************
2798 *
2799 * FUNCTION: DtCompileS3pt
2800 *
2801 * PARAMETERS: PFieldList - Current field list pointer
2802 *
2803 * RETURN: Status
2804 *
2805 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2806 *
2807 *****************************************************************************/
2808
2809 ACPI_STATUS
2810 DtCompileS3pt (
2811 DT_FIELD **PFieldList)
2812 {
2813 ACPI_STATUS Status;
2814 ACPI_S3PT_HEADER *S3ptHeader;
2815 DT_SUBTABLE *Subtable;
2816 DT_SUBTABLE *ParentTable;
2817 ACPI_DMTABLE_INFO *InfoTable;
2818 DT_FIELD *SubtableStart;
2819
2820
2821 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2822 &Gbl_RootTable, TRUE);
2823 if (ACPI_FAILURE (Status))
2824 {
2825 return (Status);
2826 }
2827
2828 DtPushSubtable (Gbl_RootTable);
2829
2830 while (*PFieldList)
2831 {
2832 SubtableStart = *PFieldList;
2833 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2834 &Subtable, TRUE);
2835 if (ACPI_FAILURE (Status))
2836 {
2837 return (Status);
2838 }
2839
2840 ParentTable = DtPeekSubtable ();
2841 DtInsertSubtable (ParentTable, Subtable);
2842 DtPushSubtable (Subtable);
2843
2844 S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2845
2846 switch (S3ptHeader->Type)
2847 {
2848 case ACPI_S3PT_TYPE_RESUME:
2849
2850 InfoTable = AcpiDmTableInfoS3pt0;
2851 break;
2852
2853 case ACPI_S3PT_TYPE_SUSPEND:
2854
2855 InfoTable = AcpiDmTableInfoS3pt1;
2856 break;
2857
2858 default:
2859
2860 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2861 return (AE_ERROR);
2862 }
2863
2864 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2865 if (ACPI_FAILURE (Status))
2866 {
2867 return (Status);
2868 }
2869
2870 ParentTable = DtPeekSubtable ();
2871 DtInsertSubtable (ParentTable, Subtable);
2872 DtPopSubtable ();
2873 }
2874
2875 return (AE_OK);
2876 }
2877
2878
2879 /******************************************************************************
2880 *
2881 * FUNCTION: DtCompileSlic
2882 *
2883 * PARAMETERS: List - Current field list pointer
2884 *
2885 * RETURN: Status
2886 *
2887 * DESCRIPTION: Compile SLIC.
2888 *
2889 *****************************************************************************/
2890
2891 ACPI_STATUS
2892 DtCompileSlic (
2893 void **List)
2894 {
2895 ACPI_STATUS Status;
2896 DT_SUBTABLE *Subtable;
2897 DT_SUBTABLE *ParentTable;
2898 DT_FIELD **PFieldList = (DT_FIELD **) List;
2899
2900
2901 while (*PFieldList)
2902 {
2903 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2904 &Subtable, TRUE);
2905 if (ACPI_FAILURE (Status))
2906 {
2907 return (Status);
2908 }
2909
2910 ParentTable = DtPeekSubtable ();
2911 DtInsertSubtable (ParentTable, Subtable);
2912 DtPushSubtable (Subtable);
2913 DtPopSubtable ();
2914 }
2915
2916 return (AE_OK);
2917 }
2918
2919
2920 /******************************************************************************
2921 *
2922 * FUNCTION: DtCompileSlit
2923 *
2924 * PARAMETERS: List - Current field list pointer
2925 *
2926 * RETURN: Status
2927 *
2928 * DESCRIPTION: Compile SLIT.
2929 *
2930 *****************************************************************************/
2931
2932 ACPI_STATUS
2933 DtCompileSlit (
2934 void **List)
2935 {
2936 ACPI_STATUS Status;
2937 DT_SUBTABLE *Subtable;
2938 DT_SUBTABLE *ParentTable;
2939 DT_FIELD **PFieldList = (DT_FIELD **) List;
2940 DT_FIELD *FieldList;
2941 UINT32 Localities;
2942 UINT8 *LocalityBuffer;
2943
2944
2945 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2946 &Subtable, TRUE);
2947 if (ACPI_FAILURE (Status))
2948 {
2949 return (Status);
2950 }
2951
2952 ParentTable = DtPeekSubtable ();
2953 DtInsertSubtable (ParentTable, Subtable);
2954
2955 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2956 LocalityBuffer = UtLocalCalloc (Localities);
2957
2958 /* Compile each locality buffer */
2959
2960 FieldList = *PFieldList;
2961 while (FieldList)
2962 {
2963 DtCompileBuffer (LocalityBuffer,
2964 FieldList->Value, FieldList, Localities);
2965
2966 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2967 DtInsertSubtable (ParentTable, Subtable);
2968 FieldList = FieldList->Next;
2969 }
2970
2971 ACPI_FREE (LocalityBuffer);
2972 return (AE_OK);
2973 }
2974
2975
2976 /******************************************************************************
2977 *
2978 * FUNCTION: DtCompileSrat
2979 *
2980 * PARAMETERS: List - Current field list pointer
2981 *
2982 * RETURN: Status
2983 *
2984 * DESCRIPTION: Compile SRAT.
2985 *
2986 *****************************************************************************/
2987
2988 ACPI_STATUS
2989 DtCompileSrat (
2990 void **List)
2991 {
2992 ACPI_STATUS Status;
2993 DT_SUBTABLE *Subtable;
2994 DT_SUBTABLE *ParentTable;
2995 DT_FIELD **PFieldList = (DT_FIELD **) List;
2996 DT_FIELD *SubtableStart;
2997 ACPI_SUBTABLE_HEADER *SratHeader;
2998 ACPI_DMTABLE_INFO *InfoTable;
2999
3000
3001 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
3002 &Subtable, TRUE);
3003 if (ACPI_FAILURE (Status))
3004 {
3005 return (Status);
3006 }
3007
3008 ParentTable = DtPeekSubtable ();
3009 DtInsertSubtable (ParentTable, Subtable);
3010
3011 while (*PFieldList)
3012 {
3013 SubtableStart = *PFieldList;
3014 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
3015 &Subtable, TRUE);
3016 if (ACPI_FAILURE (Status))
3017 {
3018 return (Status);
3019 }
3020
3021 ParentTable = DtPeekSubtable ();
3022 DtInsertSubtable (ParentTable, Subtable);
3023 DtPushSubtable (Subtable);
3024
3025 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
3026
3027 switch (SratHeader->Type)
3028 {
3029 case ACPI_SRAT_TYPE_CPU_AFFINITY:
3030
3031 InfoTable = AcpiDmTableInfoSrat0;
3032 break;
3033
3034 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
3035
3036 InfoTable = AcpiDmTableInfoSrat1;
3037 break;
3038
3039 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
3040
3041 InfoTable = AcpiDmTableInfoSrat2;
3042 break;
3043
3044 case ACPI_SRAT_TYPE_GICC_AFFINITY:
3045
3046 InfoTable = AcpiDmTableInfoSrat3;
3047 break;
3048
3049 default:
3050
3051 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
3052 return (AE_ERROR);
3053 }
3054
3055 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
3056 if (ACPI_FAILURE (Status))
3057 {
3058 return (Status);
3059 }
3060
3061 ParentTable = DtPeekSubtable ();
3062 DtInsertSubtable (ParentTable, Subtable);
3063 DtPopSubtable ();
3064 }
3065
3066 return (AE_OK);
3067 }
3068
3069
3070 /******************************************************************************
3071 *
3072 * FUNCTION: DtCompileStao
3073 *
3074 * PARAMETERS: PFieldList - Current field list pointer
3075 *
3076 * RETURN: Status
3077 *
3078 * DESCRIPTION: Compile STAO.
3079 *
3080 *****************************************************************************/
3081
3082 ACPI_STATUS
3083 DtCompileStao (
3084 void **List)
3085 {
3086 DT_FIELD **PFieldList = (DT_FIELD **) List;
3087 DT_SUBTABLE *Subtable;
3088 DT_SUBTABLE *ParentTable;
3089 ACPI_STATUS Status;
3090
3091
3092 /* Compile the main table */
3093
3094 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
3095 &Subtable, TRUE);
3096 if (ACPI_FAILURE (Status))
3097 {
3098 return (Status);
3099 }
3100
3101 ParentTable = DtPeekSubtable ();
3102 DtInsertSubtable (ParentTable, Subtable);
3103
3104 /* Compile each ASCII namestring as a subtable */
3105
3106 while (*PFieldList)
3107 {
3108 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
3109 &Subtable, TRUE);
3110 if (ACPI_FAILURE (Status))
3111 {
3112 return (Status);
3113 }
3114
3115 ParentTable = DtPeekSubtable ();
3116 DtInsertSubtable (ParentTable, Subtable);
3117 }
3118
3119 return (AE_OK);
3120 }
3121
3122
3123 /******************************************************************************
3124 *
3125 * FUNCTION: DtCompileTcpa
3126 *
3127 * PARAMETERS: PFieldList - Current field list pointer
3128 *
3129 * RETURN: Status
3130 *
3131 * DESCRIPTION: Compile TCPA.
3132 *
3133 *****************************************************************************/
3134
3135 ACPI_STATUS
3136 DtCompileTcpa (
3137 void **List)
3138 {
3139 DT_FIELD **PFieldList = (DT_FIELD **) List;
3140 DT_SUBTABLE *Subtable;
3141 ACPI_TABLE_TCPA_HDR *TcpaHeader;
3142 DT_SUBTABLE *ParentTable;
3143 ACPI_STATUS Status;
3144
3145
3146 /* Compile the main table */
3147
3148 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
3149 &Subtable, TRUE);
3150 if (ACPI_FAILURE (Status))
3151 {
3152 return (Status);
3153 }
3154
3155 ParentTable = DtPeekSubtable ();
3156 DtInsertSubtable (ParentTable, Subtable);
3157
3158 /*
3159 * Examine the PlatformClass field to determine the table type.
3160 * Either a client or server table. Only one.
3161 */
3162 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
3163
3164 switch (TcpaHeader->PlatformClass)
3165 {
3166 case ACPI_TCPA_CLIENT_TABLE:
3167
3168 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
3169 &Subtable, TRUE);
3170 break;
3171
3172 case ACPI_TCPA_SERVER_TABLE:
3173
3174 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
3175 &Subtable, TRUE);
3176 break;
3177
3178 default:
3179
3180 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
3181 TcpaHeader->PlatformClass);
3182 Status = AE_ERROR;
3183 break;
3184 }
3185
3186
3187 ParentTable = DtPeekSubtable ();
3188 DtInsertSubtable (ParentTable, Subtable);
3189
3190 return (Status);
3191 }
3192
3193
3194 /******************************************************************************
3195 *
3196 * FUNCTION: DtGetGenericTableInfo
3197 *
3198 * PARAMETERS: Name - Generic type name
3199 *
3200 * RETURN: Info entry
3201 *
3202 * DESCRIPTION: Obtain table info for a generic name entry
3203 *
3204 *****************************************************************************/
3205
3206 ACPI_DMTABLE_INFO *
3207 DtGetGenericTableInfo (
3208 char *Name)
3209 {
3210 ACPI_DMTABLE_INFO *Info;
3211 UINT32 i;
3212
3213
3214 if (!Name)
3215 {
3216 return (NULL);
3217 }
3218
3219 /* Search info table for name match */
3220
3221 for (i = 0; ; i++)
3222 {
3223 Info = AcpiDmTableInfoGeneric[i];
3224 if (Info->Opcode == ACPI_DMT_EXIT)
3225 {
3226 Info = NULL;
3227 break;
3228 }
3229
3230 /* Use caseless compare for generic keywords */
3231
3232 if (!AcpiUtStricmp (Name, Info->Name))
3233 {
3234 break;
3235 }
3236 }
3237
3238 return (Info);
3239 }
3240
3241
3242 /******************************************************************************
3243 *
3244 * FUNCTION: DtCompileUefi
3245 *
3246 * PARAMETERS: List - Current field list pointer
3247 *
3248 * RETURN: Status
3249 *
3250 * DESCRIPTION: Compile UEFI.
3251 *
3252 *****************************************************************************/
3253
3254 ACPI_STATUS
3255 DtCompileUefi (
3256 void **List)
3257 {
3258 ACPI_STATUS Status;
3259 DT_SUBTABLE *Subtable;
3260 DT_SUBTABLE *ParentTable;
3261 DT_FIELD **PFieldList = (DT_FIELD **) List;
3262 UINT16 *DataOffset;
3263
3264
3265 /* Compile the predefined portion of the UEFI table */
3266
3267 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
3268 &Subtable, TRUE);
3269 if (ACPI_FAILURE (Status))
3270 {
3271 return (Status);
3272 }
3273
3274 DataOffset = (UINT16 *) (Subtable->Buffer + 16);
3275 *DataOffset = sizeof (ACPI_TABLE_UEFI);
3276
3277 ParentTable = DtPeekSubtable ();
3278 DtInsertSubtable (ParentTable, Subtable);
3279
3280 /*
3281 * Compile the "generic" portion of the UEFI table. This
3282 * part of the table is not predefined and any of the generic
3283 * operators may be used.
3284 */
3285
3286 DtCompileGeneric ((void **) PFieldList, NULL, NULL);
3287
3288 return (AE_OK);
3289 }
3290
3291
3292 /******************************************************************************
3293 *
3294 * FUNCTION: DtCompileVrtc
3295 *
3296 * PARAMETERS: List - Current field list pointer
3297 *
3298 * RETURN: Status
3299 *
3300 * DESCRIPTION: Compile VRTC.
3301 *
3302 *****************************************************************************/
3303
3304 ACPI_STATUS
3305 DtCompileVrtc (
3306 void **List)
3307 {
3308 ACPI_STATUS Status;
3309
3310
3311 Status = DtCompileTwoSubtables (List,
3312 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
3313 return (Status);
3314 }
3315
3316
3317 /******************************************************************************
3318 *
3319 * FUNCTION: DtCompileWdat
3320 *
3321 * PARAMETERS: List - Current field list pointer
3322 *
3323 * RETURN: Status
3324 *
3325 * DESCRIPTION: Compile WDAT.
3326 *
3327 *****************************************************************************/
3328
3329 ACPI_STATUS
3330 DtCompileWdat (
3331 void **List)
3332 {
3333 ACPI_STATUS Status;
3334
3335
3336 Status = DtCompileTwoSubtables (List,
3337 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
3338 return (Status);
3339 }
3340
3341
3342 /******************************************************************************
3343 *
3344 * FUNCTION: DtCompileWpbt
3345 *
3346 * PARAMETERS: List - Current field list pointer
3347 *
3348 * RETURN: Status
3349 *
3350 * DESCRIPTION: Compile WPBT.
3351 *
3352 *****************************************************************************/
3353
3354 ACPI_STATUS
3355 DtCompileWpbt (
3356 void **List)
3357 {
3358 DT_FIELD **PFieldList = (DT_FIELD **) List;
3359 DT_SUBTABLE *Subtable;
3360 DT_SUBTABLE *ParentTable;
3361 ACPI_TABLE_WPBT *Table;
3362 ACPI_STATUS Status;
3363 UINT16 Length;
3364
3365
3366 /* Compile the main table */
3367
3368 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt,
3369 &Subtable, TRUE);
3370 if (ACPI_FAILURE (Status))
3371 {
3372 return (Status);
3373 }
3374
3375 ParentTable = DtPeekSubtable ();
3376 DtInsertSubtable (ParentTable, Subtable);
3377
3378 /* Compile the argument list subtable */
3379
3380 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0,
3381 &Subtable, TRUE);
3382 if (ACPI_FAILURE (Status))
3383 {
3384 return (Status);
3385 }
3386
3387 /* Extract the length of the Arguments buffer, insert into main table */
3388
3389 Length = (UINT16) Subtable->TotalLength;
3390 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
3391 Table->ArgumentsLength = Length;
3392
3393 ParentTable = DtPeekSubtable ();
3394 DtInsertSubtable (ParentTable, Subtable);
3395 return (AE_OK);
3396 }
3397
3398
3399 /******************************************************************************
3400 *
3401 * FUNCTION: DtCompileXsdt
3402 *
3403 * PARAMETERS: List - Current field list pointer
3404 *
3405 * RETURN: Status
3406 *
3407 * DESCRIPTION: Compile XSDT.
3408 *
3409 *****************************************************************************/
3410
3411 ACPI_STATUS
3412 DtCompileXsdt (
3413 void **List)
3414 {
3415 DT_SUBTABLE *Subtable;
3416 DT_SUBTABLE *ParentTable;
3417 DT_FIELD *FieldList = *(DT_FIELD **) List;
3418 UINT64 Address;
3419
3420
3421 ParentTable = DtPeekSubtable ();
3422
3423 while (FieldList)
3424 {
3425 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
3426
3427 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
3428 DtInsertSubtable (ParentTable, Subtable);
3429 FieldList = FieldList->Next;
3430 }
3431
3432 return (AE_OK);
3433 }
3434
3435
3436 /******************************************************************************
3437 *
3438 * FUNCTION: DtCompileGeneric
3439 *
3440 * PARAMETERS: List - Current field list pointer
3441 * Name - Field name to end generic compiling
3442 * Length - Compiled table length to return
3443 *
3444 * RETURN: Status
3445 *
3446 * DESCRIPTION: Compile generic unknown table.
3447 *
3448 *****************************************************************************/
3449
3450 ACPI_STATUS
3451 DtCompileGeneric (
3452 void **List,
3453 char *Name,
3454 UINT32 *Length)
3455 {
3456 ACPI_STATUS Status;
3457 DT_SUBTABLE *Subtable;
3458 DT_SUBTABLE *ParentTable;
3459 DT_FIELD **PFieldList = (DT_FIELD **) List;
3460 ACPI_DMTABLE_INFO *Info;
3461
3462
3463 ParentTable = DtPeekSubtable ();
3464
3465 /*
3466 * Compile the "generic" portion of the table. This
3467 * part of the table is not predefined and any of the generic
3468 * operators may be used.
3469 */
3470
3471 /* Find any and all labels in the entire generic portion */
3472
3473 DtDetectAllLabels (*PFieldList);
3474
3475 /* Now we can actually compile the parse tree */
3476
3477 if (Length && *Length)
3478 {
3479 *Length = 0;
3480 }
3481 while (*PFieldList)
3482 {
3483 if (Name && !strcmp ((*PFieldList)->Name, Name))
3484 {
3485 break;
3486 }
3487 Info = DtGetGenericTableInfo ((*PFieldList)->Name);
3488 if (!Info)
3489 {
3490 snprintf (MsgBuffer, sizeof(MsgBuffer), "Generic data type \"%s\" not found",
3491 (*PFieldList)->Name);
3492 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3493 (*PFieldList), MsgBuffer);
3494
3495 *PFieldList = (*PFieldList)->Next;
3496 continue;
3497 }
3498
3499 Status = DtCompileTable (PFieldList, Info,
3500 &Subtable, TRUE);
3501 if (ACPI_SUCCESS (Status))
3502 {
3503 DtInsertSubtable (ParentTable, Subtable);
3504 if (Length)
3505 {
3506 *Length += Subtable->Length;
3507 }
3508 }
3509 else
3510 {
3511 *PFieldList = (*PFieldList)->Next;
3512
3513 if (Status == AE_NOT_FOUND)
3514 {
3515 snprintf (MsgBuffer, sizeof(MsgBuffer), "Generic data type \"%s\" not found",
3516 (*PFieldList)->Name);
3517 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
3518 (*PFieldList), MsgBuffer);
3519 }
3520 }
3521 }
3522
3523 return (AE_OK);
3524 }
3525