dttable.c revision 1.3.2.1 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 /* TBD: move to acmacros.h */
69
70 #define ACPI_SUB_PTR(t, a, b) \
71 ACPI_CAST_PTR (t, (ACPI_CAST_PTR (UINT8, (a)) - (ACPI_SIZE)(b)))
72
73
74 /* Local prototypes */
75
76 static ACPI_STATUS
77 DtCompileTwoSubtables (
78 void **List,
79 ACPI_DMTABLE_INFO *TableInfo1,
80 ACPI_DMTABLE_INFO *TableInfo2);
81
82
83 /******************************************************************************
84 *
85 * FUNCTION: DtCompileTwoSubtables
86 *
87 * PARAMETERS: List - Current field list pointer
88 * TableInfo1 - Info table 1
89 * TableInfo1 - Info table 2
90 *
91 * RETURN: Status
92 *
93 * DESCRIPTION: Compile tables with a header and one or more same subtables.
94 * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
95 *
96 *****************************************************************************/
97
98 static ACPI_STATUS
99 DtCompileTwoSubtables (
100 void **List,
101 ACPI_DMTABLE_INFO *TableInfo1,
102 ACPI_DMTABLE_INFO *TableInfo2)
103 {
104 ACPI_STATUS Status;
105 DT_SUBTABLE *Subtable;
106 DT_SUBTABLE *ParentTable;
107 DT_FIELD **PFieldList = (DT_FIELD **) List;
108
109
110 Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
111 if (ACPI_FAILURE (Status))
112 {
113 return (Status);
114 }
115
116 ParentTable = DtPeekSubtable ();
117 DtInsertSubtable (ParentTable, Subtable);
118
119 while (*PFieldList)
120 {
121 Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
122 if (ACPI_FAILURE (Status))
123 {
124 return (Status);
125 }
126
127 DtInsertSubtable (ParentTable, Subtable);
128 }
129
130 return (AE_OK);
131 }
132
133
134 /******************************************************************************
135 *
136 * FUNCTION: DtCompileFacs
137 *
138 * PARAMETERS: PFieldList - Current field list pointer
139 *
140 * RETURN: Status
141 *
142 * DESCRIPTION: Compile FACS.
143 *
144 *****************************************************************************/
145
146 ACPI_STATUS
147 DtCompileFacs (
148 DT_FIELD **PFieldList)
149 {
150 DT_SUBTABLE *Subtable;
151 UINT8 *ReservedBuffer;
152 ACPI_STATUS Status;
153 UINT32 ReservedSize;
154
155
156 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
157 &Gbl_RootTable, TRUE);
158 if (ACPI_FAILURE (Status))
159 {
160 return (Status);
161 }
162
163 /* Large FACS reserved area at the end of the table */
164
165 ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
166 ReservedBuffer = UtLocalCalloc (ReservedSize);
167
168 DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
169
170 ACPI_FREE (ReservedBuffer);
171 DtInsertSubtable (Gbl_RootTable, Subtable);
172 return (AE_OK);
173 }
174
175
176 /******************************************************************************
177 *
178 * FUNCTION: DtCompileRsdp
179 *
180 * PARAMETERS: PFieldList - Current field list pointer
181 *
182 * RETURN: Status
183 *
184 * DESCRIPTION: Compile RSDP.
185 *
186 *****************************************************************************/
187
188 ACPI_STATUS
189 DtCompileRsdp (
190 DT_FIELD **PFieldList)
191 {
192 DT_SUBTABLE *Subtable;
193 ACPI_TABLE_RSDP *Rsdp;
194 ACPI_RSDP_EXTENSION *RsdpExtension;
195 ACPI_STATUS Status;
196
197
198 /* Compile the "common" RSDP (ACPI 1.0) */
199
200 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
201 &Gbl_RootTable, TRUE);
202 if (ACPI_FAILURE (Status))
203 {
204 return (Status);
205 }
206
207 Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Gbl_RootTable->Buffer);
208 DtSetTableChecksum (&Rsdp->Checksum);
209
210 if (Rsdp->Revision > 0)
211 {
212 /* Compile the "extended" part of the RSDP as a subtable */
213
214 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
215 &Subtable, TRUE);
216 if (ACPI_FAILURE (Status))
217 {
218 return (Status);
219 }
220
221 DtInsertSubtable (Gbl_RootTable, Subtable);
222
223 /* Set length and extended checksum for entire RSDP */
224
225 RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
226 RsdpExtension->Length = Gbl_RootTable->Length + Subtable->Length;
227 DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
228 }
229
230 return (AE_OK);
231 }
232
233
234 /******************************************************************************
235 *
236 * FUNCTION: DtCompileAsf
237 *
238 * PARAMETERS: List - Current field list pointer
239 *
240 * RETURN: Status
241 *
242 * DESCRIPTION: Compile ASF!.
243 *
244 *****************************************************************************/
245
246 ACPI_STATUS
247 DtCompileAsf (
248 void **List)
249 {
250 ACPI_ASF_INFO *AsfTable;
251 DT_SUBTABLE *Subtable;
252 DT_SUBTABLE *ParentTable;
253 ACPI_DMTABLE_INFO *InfoTable;
254 ACPI_DMTABLE_INFO *DataInfoTable = NULL;
255 UINT32 DataCount = 0;
256 ACPI_STATUS Status;
257 UINT32 i;
258 DT_FIELD **PFieldList = (DT_FIELD **) List;
259 DT_FIELD *SubtableStart;
260
261
262 while (*PFieldList)
263 {
264 SubtableStart = *PFieldList;
265 Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
266 &Subtable, TRUE);
267 if (ACPI_FAILURE (Status))
268 {
269 return (Status);
270 }
271
272 ParentTable = DtPeekSubtable ();
273 DtInsertSubtable (ParentTable, Subtable);
274 DtPushSubtable (Subtable);
275
276 AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
277
278 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
279 {
280 case ACPI_ASF_TYPE_INFO:
281
282 InfoTable = AcpiDmTableInfoAsf0;
283 break;
284
285 case ACPI_ASF_TYPE_ALERT:
286
287 InfoTable = AcpiDmTableInfoAsf1;
288 break;
289
290 case ACPI_ASF_TYPE_CONTROL:
291
292 InfoTable = AcpiDmTableInfoAsf2;
293 break;
294
295 case ACPI_ASF_TYPE_BOOT:
296
297 InfoTable = AcpiDmTableInfoAsf3;
298 break;
299
300 case ACPI_ASF_TYPE_ADDRESS:
301
302 InfoTable = AcpiDmTableInfoAsf4;
303 break;
304
305 default:
306
307 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
308 return (AE_ERROR);
309 }
310
311 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
312 if (ACPI_FAILURE (Status))
313 {
314 return (Status);
315 }
316
317 ParentTable = DtPeekSubtable ();
318 DtInsertSubtable (ParentTable, Subtable);
319
320 switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
321 {
322 case ACPI_ASF_TYPE_INFO:
323
324 DataInfoTable = NULL;
325 break;
326
327 case ACPI_ASF_TYPE_ALERT:
328
329 DataInfoTable = AcpiDmTableInfoAsf1a;
330 DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
331 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
332 sizeof (ACPI_ASF_HEADER)))->Alerts;
333 break;
334
335 case ACPI_ASF_TYPE_CONTROL:
336
337 DataInfoTable = AcpiDmTableInfoAsf2a;
338 DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
339 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
340 sizeof (ACPI_ASF_HEADER)))->Controls;
341 break;
342
343 case ACPI_ASF_TYPE_BOOT:
344
345 DataInfoTable = NULL;
346 break;
347
348 case ACPI_ASF_TYPE_ADDRESS:
349
350 DataInfoTable = TableInfoAsfAddress;
351 DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
352 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
353 sizeof (ACPI_ASF_HEADER)))->Devices;
354 break;
355
356 default:
357
358 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
359 return (AE_ERROR);
360 }
361
362 if (DataInfoTable)
363 {
364 switch (AsfTable->Header.Type & 0x7F)
365 {
366 case ACPI_ASF_TYPE_ADDRESS:
367
368 while (DataCount > 0)
369 {
370 Status = DtCompileTable (PFieldList, DataInfoTable,
371 &Subtable, TRUE);
372 if (ACPI_FAILURE (Status))
373 {
374 return (Status);
375 }
376
377 DtInsertSubtable (ParentTable, Subtable);
378 DataCount = DataCount - Subtable->Length;
379 }
380 break;
381
382 default:
383
384 for (i = 0; i < DataCount; i++)
385 {
386 Status = DtCompileTable (PFieldList, DataInfoTable,
387 &Subtable, TRUE);
388 if (ACPI_FAILURE (Status))
389 {
390 return (Status);
391 }
392
393 DtInsertSubtable (ParentTable, Subtable);
394 }
395 break;
396 }
397 }
398
399 DtPopSubtable ();
400 }
401
402 return (AE_OK);
403 }
404
405
406 /******************************************************************************
407 *
408 * FUNCTION: DtCompileCpep
409 *
410 * PARAMETERS: List - Current field list pointer
411 *
412 * RETURN: Status
413 *
414 * DESCRIPTION: Compile CPEP.
415 *
416 *****************************************************************************/
417
418 ACPI_STATUS
419 DtCompileCpep (
420 void **List)
421 {
422 ACPI_STATUS Status;
423
424
425 Status = DtCompileTwoSubtables (List,
426 AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
427 return (Status);
428 }
429
430
431 /******************************************************************************
432 *
433 * FUNCTION: DtCompileCsrt
434 *
435 * PARAMETERS: List - Current field list pointer
436 *
437 * RETURN: Status
438 *
439 * DESCRIPTION: Compile CSRT.
440 *
441 *****************************************************************************/
442
443 ACPI_STATUS
444 DtCompileCsrt (
445 void **List)
446 {
447 ACPI_STATUS Status = AE_OK;
448 DT_SUBTABLE *Subtable;
449 DT_SUBTABLE *ParentTable;
450 DT_FIELD **PFieldList = (DT_FIELD **) List;
451 UINT32 DescriptorCount;
452 UINT32 GroupLength;
453
454
455 /* Subtables (Resource Groups) */
456
457 while (*PFieldList)
458 {
459 /* Resource group subtable */
460
461 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
462 &Subtable, TRUE);
463 if (ACPI_FAILURE (Status))
464 {
465 return (Status);
466 }
467
468 /* Compute the number of resource descriptors */
469
470 GroupLength =
471 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
472 Subtable->Buffer))->Length -
473 (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
474 Subtable->Buffer))->SharedInfoLength -
475 sizeof (ACPI_CSRT_GROUP);
476
477 DescriptorCount = (GroupLength /
478 sizeof (ACPI_CSRT_DESCRIPTOR));
479
480 ParentTable = DtPeekSubtable ();
481 DtInsertSubtable (ParentTable, Subtable);
482 DtPushSubtable (Subtable);
483
484 /* Shared info subtable (One per resource group) */
485
486 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
487 &Subtable, TRUE);
488 if (ACPI_FAILURE (Status))
489 {
490 return (Status);
491 }
492
493 ParentTable = DtPeekSubtable ();
494 DtInsertSubtable (ParentTable, Subtable);
495
496 /* Sub-Subtables (Resource Descriptors) */
497
498 while (*PFieldList && DescriptorCount)
499 {
500 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
501 &Subtable, TRUE);
502 if (ACPI_FAILURE (Status))
503 {
504 return (Status);
505 }
506
507 ParentTable = DtPeekSubtable ();
508 DtInsertSubtable (ParentTable, Subtable);
509 DescriptorCount--;
510 }
511
512 DtPopSubtable ();
513 }
514
515 return (Status);
516 }
517
518
519 /******************************************************************************
520 *
521 * FUNCTION: DtCompileDbg2
522 *
523 * PARAMETERS: List - Current field list pointer
524 *
525 * RETURN: Status
526 *
527 * DESCRIPTION: Compile DBG2.
528 *
529 *****************************************************************************/
530
531 ACPI_STATUS
532 DtCompileDbg2 (
533 void **List)
534 {
535 ACPI_STATUS Status;
536 DT_SUBTABLE *Subtable;
537 DT_SUBTABLE *ParentTable;
538 DT_FIELD **PFieldList = (DT_FIELD **) List;
539 UINT32 SubtableCount;
540 ACPI_DBG2_HEADER *Dbg2Header;
541 ACPI_DBG2_DEVICE *DeviceInfo;
542 UINT16 CurrentOffset;
543 UINT32 i;
544
545
546 /* Main table */
547
548 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE);
549 if (ACPI_FAILURE (Status))
550 {
551 return (Status);
552 }
553
554 ParentTable = DtPeekSubtable ();
555 DtInsertSubtable (ParentTable, Subtable);
556
557 /* Main table fields */
558
559 Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
560 Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
561 ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
562
563 SubtableCount = Dbg2Header->InfoCount;
564 DtPushSubtable (Subtable);
565
566 /* Process all Device Information subtables (Count = InfoCount) */
567
568 while (*PFieldList && SubtableCount)
569 {
570 /* Subtable: Debug Device Information */
571
572 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
573 &Subtable, TRUE);
574 if (ACPI_FAILURE (Status))
575 {
576 return (Status);
577 }
578
579 DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
580 CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
581
582 ParentTable = DtPeekSubtable ();
583 DtInsertSubtable (ParentTable, Subtable);
584 DtPushSubtable (Subtable);
585
586 ParentTable = DtPeekSubtable ();
587
588 /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
589
590 DeviceInfo->BaseAddressOffset = CurrentOffset;
591 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
592 {
593 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
594 &Subtable, TRUE);
595 if (ACPI_FAILURE (Status))
596 {
597 return (Status);
598 }
599
600 CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
601 DtInsertSubtable (ParentTable, Subtable);
602 }
603
604 /* AddressSize array (Required, size = RegisterCount) */
605
606 DeviceInfo->AddressSizeOffset = CurrentOffset;
607 for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
608 {
609 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
610 &Subtable, TRUE);
611 if (ACPI_FAILURE (Status))
612 {
613 return (Status);
614 }
615
616 CurrentOffset += (UINT16) sizeof (UINT32);
617 DtInsertSubtable (ParentTable, Subtable);
618 }
619
620 /* NamespaceString device identifier (Required, size = NamePathLength) */
621
622 DeviceInfo->NamepathOffset = CurrentOffset;
623 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
624 &Subtable, TRUE);
625 if (ACPI_FAILURE (Status))
626 {
627 return (Status);
628 }
629
630 /* Update the device info header */
631
632 DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
633 CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
634 DtInsertSubtable (ParentTable, Subtable);
635
636 /* OemData - Variable-length data (Optional, size = OemDataLength) */
637
638 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
639 &Subtable, TRUE);
640 if (ACPI_FAILURE (Status))
641 {
642 return (Status);
643 }
644
645 /* Update the device info header (zeros if no OEM data present) */
646
647 DeviceInfo->OemDataOffset = 0;
648 DeviceInfo->OemDataLength = 0;
649
650 /* Optional subtable (OemData) */
651
652 if (Subtable && Subtable->Length)
653 {
654 DeviceInfo->OemDataOffset = CurrentOffset;
655 DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
656
657 DtInsertSubtable (ParentTable, Subtable);
658 }
659
660 SubtableCount--;
661 DtPopSubtable (); /* Get next Device Information subtable */
662 }
663
664 DtPopSubtable ();
665 return (AE_OK);
666 }
667
668
669 /******************************************************************************
670 *
671 * FUNCTION: DtCompileDmar
672 *
673 * PARAMETERS: List - Current field list pointer
674 *
675 * RETURN: Status
676 *
677 * DESCRIPTION: Compile DMAR.
678 *
679 *****************************************************************************/
680
681 ACPI_STATUS
682 DtCompileDmar (
683 void **List)
684 {
685 ACPI_STATUS Status;
686 DT_SUBTABLE *Subtable;
687 DT_SUBTABLE *ParentTable;
688 DT_FIELD **PFieldList = (DT_FIELD **) List;
689 DT_FIELD *SubtableStart;
690 ACPI_DMTABLE_INFO *InfoTable;
691 ACPI_DMAR_HEADER *DmarHeader;
692 ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope;
693 UINT32 DeviceScopeLength;
694 UINT32 PciPathLength;
695
696
697 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
698 if (ACPI_FAILURE (Status))
699 {
700 return (Status);
701 }
702
703 ParentTable = DtPeekSubtable ();
704 DtInsertSubtable (ParentTable, Subtable);
705 DtPushSubtable (Subtable);
706
707 while (*PFieldList)
708 {
709 /* DMAR Header */
710
711 SubtableStart = *PFieldList;
712 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
713 &Subtable, TRUE);
714 if (ACPI_FAILURE (Status))
715 {
716 return (Status);
717 }
718
719 ParentTable = DtPeekSubtable ();
720 DtInsertSubtable (ParentTable, Subtable);
721 DtPushSubtable (Subtable);
722
723 DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
724
725 switch (DmarHeader->Type)
726 {
727 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
728
729 InfoTable = AcpiDmTableInfoDmar0;
730 break;
731
732 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
733
734 InfoTable = AcpiDmTableInfoDmar1;
735 break;
736
737 case ACPI_DMAR_TYPE_ROOT_ATS:
738
739 InfoTable = AcpiDmTableInfoDmar2;
740 break;
741
742 case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
743
744 InfoTable = AcpiDmTableInfoDmar3;
745 break;
746
747 case ACPI_DMAR_TYPE_NAMESPACE:
748
749 InfoTable = AcpiDmTableInfoDmar4;
750 break;
751
752 default:
753
754 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
755 return (AE_ERROR);
756 }
757
758 /* DMAR Subtable */
759
760 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
761 if (ACPI_FAILURE (Status))
762 {
763 return (Status);
764 }
765
766 ParentTable = DtPeekSubtable ();
767 DtInsertSubtable (ParentTable, Subtable);
768
769 /*
770 * Optional Device Scope subtables
771 */
772 if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
773 (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
774 {
775 /* These types do not support device scopes */
776
777 DtPopSubtable ();
778 continue;
779 }
780
781 DtPushSubtable (Subtable);
782 DeviceScopeLength = DmarHeader->Length - Subtable->Length -
783 ParentTable->Length;
784 while (DeviceScopeLength)
785 {
786 Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
787 &Subtable, FALSE);
788 if (Status == AE_NOT_FOUND)
789 {
790 break;
791 }
792
793 ParentTable = DtPeekSubtable ();
794 DtInsertSubtable (ParentTable, Subtable);
795 DtPushSubtable (Subtable);
796
797 DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
798
799 /* Optional PCI Paths */
800
801 PciPathLength = DmarDeviceScope->Length - Subtable->Length;
802 while (PciPathLength)
803 {
804 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
805 &Subtable, FALSE);
806 if (Status == AE_NOT_FOUND)
807 {
808 DtPopSubtable ();
809 break;
810 }
811
812 ParentTable = DtPeekSubtable ();
813 DtInsertSubtable (ParentTable, Subtable);
814 PciPathLength -= Subtable->Length;
815 }
816
817 DtPopSubtable ();
818 DeviceScopeLength -= DmarDeviceScope->Length;
819 }
820
821 DtPopSubtable ();
822 DtPopSubtable ();
823 }
824
825 return (AE_OK);
826 }
827
828
829 /******************************************************************************
830 *
831 * FUNCTION: DtCompileEinj
832 *
833 * PARAMETERS: List - Current field list pointer
834 *
835 * RETURN: Status
836 *
837 * DESCRIPTION: Compile EINJ.
838 *
839 *****************************************************************************/
840
841 ACPI_STATUS
842 DtCompileEinj (
843 void **List)
844 {
845 ACPI_STATUS Status;
846
847
848 Status = DtCompileTwoSubtables (List,
849 AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
850 return (Status);
851 }
852
853
854 /******************************************************************************
855 *
856 * FUNCTION: DtCompileErst
857 *
858 * PARAMETERS: List - Current field list pointer
859 *
860 * RETURN: Status
861 *
862 * DESCRIPTION: Compile ERST.
863 *
864 *****************************************************************************/
865
866 ACPI_STATUS
867 DtCompileErst (
868 void **List)
869 {
870 ACPI_STATUS Status;
871
872
873 Status = DtCompileTwoSubtables (List,
874 AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
875 return (Status);
876 }
877
878
879 /******************************************************************************
880 *
881 * FUNCTION: DtCompileFadt
882 *
883 * PARAMETERS: List - Current field list pointer
884 *
885 * RETURN: Status
886 *
887 * DESCRIPTION: Compile FADT.
888 *
889 *****************************************************************************/
890
891 ACPI_STATUS
892 DtCompileFadt (
893 void **List)
894 {
895 ACPI_STATUS Status;
896 DT_SUBTABLE *Subtable;
897 DT_SUBTABLE *ParentTable;
898 DT_FIELD **PFieldList = (DT_FIELD **) List;
899 ACPI_TABLE_HEADER *Table;
900 UINT8 Revision;
901
902
903 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
904 &Subtable, TRUE);
905 if (ACPI_FAILURE (Status))
906 {
907 return (Status);
908 }
909
910 ParentTable = DtPeekSubtable ();
911 DtInsertSubtable (ParentTable, Subtable);
912
913 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
914 Revision = Table->Revision;
915
916 if (Revision == 2)
917 {
918 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
919 &Subtable, TRUE);
920 if (ACPI_FAILURE (Status))
921 {
922 return (Status);
923 }
924
925 DtInsertSubtable (ParentTable, Subtable);
926 }
927 else if (Revision >= 2)
928 {
929 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
930 &Subtable, TRUE);
931 if (ACPI_FAILURE (Status))
932 {
933 return (Status);
934 }
935
936 DtInsertSubtable (ParentTable, Subtable);
937
938 if (Revision >= 5)
939 {
940 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
941 &Subtable, TRUE);
942 if (ACPI_FAILURE (Status))
943 {
944 return (Status);
945 }
946
947 DtInsertSubtable (ParentTable, Subtable);
948 }
949 }
950
951 return (AE_OK);
952 }
953
954 /******************************************************************************
955 *
956 * FUNCTION: DtCompileGtdt
957 *
958 * PARAMETERS: List - Current field list pointer
959 *
960 * RETURN: Status
961 *
962 * DESCRIPTION: Compile GTDT.
963 *
964 *****************************************************************************/
965
966 ACPI_STATUS
967 DtCompileGtdt (
968 void **List)
969 {
970 ACPI_STATUS Status;
971 DT_SUBTABLE *Subtable;
972 DT_SUBTABLE *ParentTable;
973 DT_FIELD **PFieldList = (DT_FIELD **) List;
974 DT_FIELD *SubtableStart;
975 ACPI_SUBTABLE_HEADER *GtdtHeader;
976 ACPI_DMTABLE_INFO *InfoTable;
977 UINT32 GtCount;
978
979
980 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
981 &Subtable, TRUE);
982 if (ACPI_FAILURE (Status))
983 {
984 return (Status);
985 }
986
987 ParentTable = DtPeekSubtable ();
988 DtInsertSubtable (ParentTable, Subtable);
989
990 while (*PFieldList)
991 {
992 SubtableStart = *PFieldList;
993 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
994 &Subtable, TRUE);
995 if (ACPI_FAILURE (Status))
996 {
997 return (Status);
998 }
999
1000 ParentTable = DtPeekSubtable ();
1001 DtInsertSubtable (ParentTable, Subtable);
1002 DtPushSubtable (Subtable);
1003
1004 GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1005
1006 switch (GtdtHeader->Type)
1007 {
1008 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1009
1010 InfoTable = AcpiDmTableInfoGtdt0;
1011 break;
1012
1013 case ACPI_GTDT_TYPE_WATCHDOG:
1014
1015 InfoTable = AcpiDmTableInfoGtdt1;
1016 break;
1017
1018 default:
1019
1020 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
1021 return (AE_ERROR);
1022 }
1023
1024 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1025 if (ACPI_FAILURE (Status))
1026 {
1027 return (Status);
1028 }
1029
1030 ParentTable = DtPeekSubtable ();
1031 DtInsertSubtable (ParentTable, Subtable);
1032
1033 /*
1034 * Additional GT block subtable data
1035 */
1036
1037 switch (GtdtHeader->Type)
1038 {
1039 case ACPI_GTDT_TYPE_TIMER_BLOCK:
1040
1041 DtPushSubtable (Subtable);
1042 ParentTable = DtPeekSubtable ();
1043
1044 GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1045 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
1046 while (GtCount)
1047 {
1048 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
1049 &Subtable, TRUE);
1050 if (ACPI_FAILURE (Status))
1051 {
1052 return (Status);
1053 }
1054
1055
1056 DtInsertSubtable (ParentTable, Subtable);
1057 GtCount--;
1058 }
1059 DtPopSubtable ();
1060 break;
1061
1062 default:
1063
1064 break;
1065 }
1066
1067 DtPopSubtable ();
1068 }
1069
1070 return (AE_OK);
1071 }
1072
1073
1074 /******************************************************************************
1075 *
1076 * FUNCTION: DtCompileFpdt
1077 *
1078 * PARAMETERS: List - Current field list pointer
1079 *
1080 * RETURN: Status
1081 *
1082 * DESCRIPTION: Compile FPDT.
1083 *
1084 *****************************************************************************/
1085
1086 ACPI_STATUS
1087 DtCompileFpdt (
1088 void **List)
1089 {
1090 ACPI_STATUS Status;
1091 ACPI_FPDT_HEADER *FpdtHeader;
1092 DT_SUBTABLE *Subtable;
1093 DT_SUBTABLE *ParentTable;
1094 ACPI_DMTABLE_INFO *InfoTable;
1095 DT_FIELD **PFieldList = (DT_FIELD **) List;
1096 DT_FIELD *SubtableStart;
1097
1098
1099 while (*PFieldList)
1100 {
1101 SubtableStart = *PFieldList;
1102 Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
1103 &Subtable, TRUE);
1104 if (ACPI_FAILURE (Status))
1105 {
1106 return (Status);
1107 }
1108
1109 ParentTable = DtPeekSubtable ();
1110 DtInsertSubtable (ParentTable, Subtable);
1111 DtPushSubtable (Subtable);
1112
1113 FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
1114
1115 switch (FpdtHeader->Type)
1116 {
1117 case ACPI_FPDT_TYPE_BOOT:
1118
1119 InfoTable = AcpiDmTableInfoFpdt0;
1120 break;
1121
1122 case ACPI_FPDT_TYPE_S3PERF:
1123
1124 InfoTable = AcpiDmTableInfoFpdt1;
1125 break;
1126
1127 default:
1128
1129 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
1130 return (AE_ERROR);
1131 break;
1132 }
1133
1134 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1135 if (ACPI_FAILURE (Status))
1136 {
1137 return (Status);
1138 }
1139
1140 ParentTable = DtPeekSubtable ();
1141 DtInsertSubtable (ParentTable, Subtable);
1142 DtPopSubtable ();
1143 }
1144
1145 return (AE_OK);
1146 }
1147
1148
1149 /******************************************************************************
1150 *
1151 * FUNCTION: DtCompileHest
1152 *
1153 * PARAMETERS: List - Current field list pointer
1154 *
1155 * RETURN: Status
1156 *
1157 * DESCRIPTION: Compile HEST.
1158 *
1159 *****************************************************************************/
1160
1161 ACPI_STATUS
1162 DtCompileHest (
1163 void **List)
1164 {
1165 ACPI_STATUS Status;
1166 DT_SUBTABLE *Subtable;
1167 DT_SUBTABLE *ParentTable;
1168 DT_FIELD **PFieldList = (DT_FIELD **) List;
1169 DT_FIELD *SubtableStart;
1170 ACPI_DMTABLE_INFO *InfoTable;
1171 UINT16 Type;
1172 UINT32 BankCount;
1173
1174
1175 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
1176 &Subtable, TRUE);
1177 if (ACPI_FAILURE (Status))
1178 {
1179 return (Status);
1180 }
1181
1182 ParentTable = DtPeekSubtable ();
1183 DtInsertSubtable (ParentTable, Subtable);
1184
1185 while (*PFieldList)
1186 {
1187 /* Get subtable type */
1188
1189 SubtableStart = *PFieldList;
1190 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
1191
1192 switch (Type)
1193 {
1194 case ACPI_HEST_TYPE_IA32_CHECK:
1195
1196 InfoTable = AcpiDmTableInfoHest0;
1197 break;
1198
1199 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1200
1201 InfoTable = AcpiDmTableInfoHest1;
1202 break;
1203
1204 case ACPI_HEST_TYPE_IA32_NMI:
1205
1206 InfoTable = AcpiDmTableInfoHest2;
1207 break;
1208
1209 case ACPI_HEST_TYPE_AER_ROOT_PORT:
1210
1211 InfoTable = AcpiDmTableInfoHest6;
1212 break;
1213
1214 case ACPI_HEST_TYPE_AER_ENDPOINT:
1215
1216 InfoTable = AcpiDmTableInfoHest7;
1217 break;
1218
1219 case ACPI_HEST_TYPE_AER_BRIDGE:
1220
1221 InfoTable = AcpiDmTableInfoHest8;
1222 break;
1223
1224 case ACPI_HEST_TYPE_GENERIC_ERROR:
1225
1226 InfoTable = AcpiDmTableInfoHest9;
1227 break;
1228
1229 default:
1230
1231 /* Cannot continue on unknown type */
1232
1233 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
1234 return (AE_ERROR);
1235 }
1236
1237 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1238 if (ACPI_FAILURE (Status))
1239 {
1240 return (Status);
1241 }
1242
1243 DtInsertSubtable (ParentTable, Subtable);
1244
1245 /*
1246 * Additional subtable data - IA32 Error Bank(s)
1247 */
1248 BankCount = 0;
1249 switch (Type)
1250 {
1251 case ACPI_HEST_TYPE_IA32_CHECK:
1252
1253 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1254 Subtable->Buffer))->NumHardwareBanks;
1255 break;
1256
1257 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1258
1259 BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1260 Subtable->Buffer))->NumHardwareBanks;
1261 break;
1262
1263 default:
1264
1265 break;
1266 }
1267
1268 while (BankCount)
1269 {
1270 Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
1271 &Subtable, TRUE);
1272 if (ACPI_FAILURE (Status))
1273 {
1274 return (Status);
1275 }
1276
1277 DtInsertSubtable (ParentTable, Subtable);
1278 BankCount--;
1279 }
1280 }
1281
1282 return (AE_OK);
1283 }
1284
1285
1286 /******************************************************************************
1287 *
1288 * FUNCTION: DtCompileIvrs
1289 *
1290 * PARAMETERS: List - Current field list pointer
1291 *
1292 * RETURN: Status
1293 *
1294 * DESCRIPTION: Compile IVRS.
1295 *
1296 *****************************************************************************/
1297
1298 ACPI_STATUS
1299 DtCompileIvrs (
1300 void **List)
1301 {
1302 ACPI_STATUS Status;
1303 DT_SUBTABLE *Subtable;
1304 DT_SUBTABLE *ParentTable;
1305 DT_FIELD **PFieldList = (DT_FIELD **) List;
1306 DT_FIELD *SubtableStart;
1307 ACPI_DMTABLE_INFO *InfoTable;
1308 ACPI_IVRS_HEADER *IvrsHeader;
1309 UINT8 EntryType;
1310
1311
1312 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
1313 &Subtable, TRUE);
1314 if (ACPI_FAILURE (Status))
1315 {
1316 return (Status);
1317 }
1318
1319 ParentTable = DtPeekSubtable ();
1320 DtInsertSubtable (ParentTable, Subtable);
1321
1322 while (*PFieldList)
1323 {
1324 SubtableStart = *PFieldList;
1325 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
1326 &Subtable, TRUE);
1327 if (ACPI_FAILURE (Status))
1328 {
1329 return (Status);
1330 }
1331
1332 ParentTable = DtPeekSubtable ();
1333 DtInsertSubtable (ParentTable, Subtable);
1334 DtPushSubtable (Subtable);
1335
1336 IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
1337
1338 switch (IvrsHeader->Type)
1339 {
1340 case ACPI_IVRS_TYPE_HARDWARE:
1341
1342 InfoTable = AcpiDmTableInfoIvrs0;
1343 break;
1344
1345 case ACPI_IVRS_TYPE_MEMORY1:
1346 case ACPI_IVRS_TYPE_MEMORY2:
1347 case ACPI_IVRS_TYPE_MEMORY3:
1348
1349 InfoTable = AcpiDmTableInfoIvrs1;
1350 break;
1351
1352 default:
1353
1354 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
1355 return (AE_ERROR);
1356 }
1357
1358 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1359 if (ACPI_FAILURE (Status))
1360 {
1361 return (Status);
1362 }
1363
1364 ParentTable = DtPeekSubtable ();
1365 DtInsertSubtable (ParentTable, Subtable);
1366
1367 if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
1368 {
1369 while (*PFieldList &&
1370 !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
1371 {
1372 SubtableStart = *PFieldList;
1373 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
1374
1375 switch (EntryType)
1376 {
1377 /* 4-byte device entries */
1378
1379 case ACPI_IVRS_TYPE_PAD4:
1380 case ACPI_IVRS_TYPE_ALL:
1381 case ACPI_IVRS_TYPE_SELECT:
1382 case ACPI_IVRS_TYPE_START:
1383 case ACPI_IVRS_TYPE_END:
1384
1385 InfoTable = AcpiDmTableInfoIvrs4;
1386 break;
1387
1388 /* 8-byte entries, type A */
1389
1390 case ACPI_IVRS_TYPE_ALIAS_SELECT:
1391 case ACPI_IVRS_TYPE_ALIAS_START:
1392
1393 InfoTable = AcpiDmTableInfoIvrs8a;
1394 break;
1395
1396 /* 8-byte entries, type B */
1397
1398 case ACPI_IVRS_TYPE_PAD8:
1399 case ACPI_IVRS_TYPE_EXT_SELECT:
1400 case ACPI_IVRS_TYPE_EXT_START:
1401
1402 InfoTable = AcpiDmTableInfoIvrs8b;
1403 break;
1404
1405 /* 8-byte entries, type C */
1406
1407 case ACPI_IVRS_TYPE_SPECIAL:
1408
1409 InfoTable = AcpiDmTableInfoIvrs8c;
1410 break;
1411
1412 default:
1413
1414 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
1415 "IVRS Device Entry");
1416 return (AE_ERROR);
1417 }
1418
1419 Status = DtCompileTable (PFieldList, InfoTable,
1420 &Subtable, TRUE);
1421 if (ACPI_FAILURE (Status))
1422 {
1423 return (Status);
1424 }
1425
1426 DtInsertSubtable (ParentTable, Subtable);
1427 }
1428 }
1429
1430 DtPopSubtable ();
1431 }
1432
1433 return (AE_OK);
1434 }
1435
1436
1437 /******************************************************************************
1438 *
1439 * FUNCTION: DtCompileLpit
1440 *
1441 * PARAMETERS: List - Current field list pointer
1442 *
1443 * RETURN: Status
1444 *
1445 * DESCRIPTION: Compile LPIT.
1446 *
1447 *****************************************************************************/
1448
1449 ACPI_STATUS
1450 DtCompileLpit (
1451 void **List)
1452 {
1453 ACPI_STATUS Status;
1454 DT_SUBTABLE *Subtable;
1455 DT_SUBTABLE *ParentTable;
1456 DT_FIELD **PFieldList = (DT_FIELD **) List;
1457 DT_FIELD *SubtableStart;
1458 ACPI_DMTABLE_INFO *InfoTable;
1459 ACPI_LPIT_HEADER *LpitHeader;
1460
1461
1462 /* Note: Main table consists only of the standard ACPI table header */
1463
1464 while (*PFieldList)
1465 {
1466 SubtableStart = *PFieldList;
1467
1468 /* LPIT Subtable header */
1469
1470 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
1471 &Subtable, TRUE);
1472 if (ACPI_FAILURE (Status))
1473 {
1474 return (Status);
1475 }
1476
1477 ParentTable = DtPeekSubtable ();
1478 DtInsertSubtable (ParentTable, Subtable);
1479 DtPushSubtable (Subtable);
1480
1481 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
1482
1483 switch (LpitHeader->Type)
1484 {
1485 case ACPI_LPIT_TYPE_NATIVE_CSTATE:
1486
1487 InfoTable = AcpiDmTableInfoLpit0;
1488 break;
1489
1490 case ACPI_LPIT_TYPE_SIMPLE_IO:
1491
1492 InfoTable = AcpiDmTableInfoLpit1;
1493 break;
1494
1495 default:
1496
1497 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
1498 return (AE_ERROR);
1499 }
1500
1501 /* LPIT Subtable */
1502
1503 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1504 if (ACPI_FAILURE (Status))
1505 {
1506 return (Status);
1507 }
1508
1509 ParentTable = DtPeekSubtable ();
1510 DtInsertSubtable (ParentTable, Subtable);
1511 DtPopSubtable ();
1512 }
1513
1514 return (AE_OK);
1515 }
1516
1517
1518 /******************************************************************************
1519 *
1520 * FUNCTION: DtCompileMadt
1521 *
1522 * PARAMETERS: List - Current field list pointer
1523 *
1524 * RETURN: Status
1525 *
1526 * DESCRIPTION: Compile MADT.
1527 *
1528 *****************************************************************************/
1529
1530 ACPI_STATUS
1531 DtCompileMadt (
1532 void **List)
1533 {
1534 ACPI_STATUS Status;
1535 DT_SUBTABLE *Subtable;
1536 DT_SUBTABLE *ParentTable;
1537 DT_FIELD **PFieldList = (DT_FIELD **) List;
1538 DT_FIELD *SubtableStart;
1539 ACPI_SUBTABLE_HEADER *MadtHeader;
1540 ACPI_DMTABLE_INFO *InfoTable;
1541
1542
1543 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
1544 &Subtable, TRUE);
1545 if (ACPI_FAILURE (Status))
1546 {
1547 return (Status);
1548 }
1549
1550 ParentTable = DtPeekSubtable ();
1551 DtInsertSubtable (ParentTable, Subtable);
1552
1553 while (*PFieldList)
1554 {
1555 SubtableStart = *PFieldList;
1556 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
1557 &Subtable, TRUE);
1558 if (ACPI_FAILURE (Status))
1559 {
1560 return (Status);
1561 }
1562
1563 ParentTable = DtPeekSubtable ();
1564 DtInsertSubtable (ParentTable, Subtable);
1565 DtPushSubtable (Subtable);
1566
1567 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1568
1569 switch (MadtHeader->Type)
1570 {
1571 case ACPI_MADT_TYPE_LOCAL_APIC:
1572
1573 InfoTable = AcpiDmTableInfoMadt0;
1574 break;
1575
1576 case ACPI_MADT_TYPE_IO_APIC:
1577
1578 InfoTable = AcpiDmTableInfoMadt1;
1579 break;
1580
1581 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1582
1583 InfoTable = AcpiDmTableInfoMadt2;
1584 break;
1585
1586 case ACPI_MADT_TYPE_NMI_SOURCE:
1587
1588 InfoTable = AcpiDmTableInfoMadt3;
1589 break;
1590
1591 case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1592
1593 InfoTable = AcpiDmTableInfoMadt4;
1594 break;
1595
1596 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1597
1598 InfoTable = AcpiDmTableInfoMadt5;
1599 break;
1600
1601 case ACPI_MADT_TYPE_IO_SAPIC:
1602
1603 InfoTable = AcpiDmTableInfoMadt6;
1604 break;
1605
1606 case ACPI_MADT_TYPE_LOCAL_SAPIC:
1607
1608 InfoTable = AcpiDmTableInfoMadt7;
1609 break;
1610
1611 case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1612
1613 InfoTable = AcpiDmTableInfoMadt8;
1614 break;
1615
1616 case ACPI_MADT_TYPE_LOCAL_X2APIC:
1617
1618 InfoTable = AcpiDmTableInfoMadt9;
1619 break;
1620
1621 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1622
1623 InfoTable = AcpiDmTableInfoMadt10;
1624 break;
1625
1626 case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1627
1628 InfoTable = AcpiDmTableInfoMadt11;
1629 break;
1630
1631 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1632
1633 InfoTable = AcpiDmTableInfoMadt12;
1634 break;
1635
1636 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1637
1638 InfoTable = AcpiDmTableInfoMadt13;
1639 break;
1640
1641 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1642
1643 InfoTable = AcpiDmTableInfoMadt14;
1644 break;
1645
1646 default:
1647
1648 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
1649 return (AE_ERROR);
1650 }
1651
1652 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1653 if (ACPI_FAILURE (Status))
1654 {
1655 return (Status);
1656 }
1657
1658 ParentTable = DtPeekSubtable ();
1659 DtInsertSubtable (ParentTable, Subtable);
1660 DtPopSubtable ();
1661 }
1662
1663 return (AE_OK);
1664 }
1665
1666
1667 /******************************************************************************
1668 *
1669 * FUNCTION: DtCompileMcfg
1670 *
1671 * PARAMETERS: List - Current field list pointer
1672 *
1673 * RETURN: Status
1674 *
1675 * DESCRIPTION: Compile MCFG.
1676 *
1677 *****************************************************************************/
1678
1679 ACPI_STATUS
1680 DtCompileMcfg (
1681 void **List)
1682 {
1683 ACPI_STATUS Status;
1684
1685
1686 Status = DtCompileTwoSubtables (List,
1687 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
1688 return (Status);
1689 }
1690
1691
1692 /******************************************************************************
1693 *
1694 * FUNCTION: DtCompileMpst
1695 *
1696 * PARAMETERS: List - Current field list pointer
1697 *
1698 * RETURN: Status
1699 *
1700 * DESCRIPTION: Compile MPST.
1701 *
1702 *****************************************************************************/
1703
1704 ACPI_STATUS
1705 DtCompileMpst (
1706 void **List)
1707 {
1708 ACPI_STATUS Status;
1709 DT_SUBTABLE *Subtable;
1710 DT_SUBTABLE *ParentTable;
1711 DT_FIELD **PFieldList = (DT_FIELD **) List;
1712 ACPI_MPST_CHANNEL *MpstChannelInfo;
1713 ACPI_MPST_POWER_NODE *MpstPowerNode;
1714 ACPI_MPST_DATA_HDR *MpstDataHeader;
1715 UINT16 SubtableCount;
1716 UINT32 PowerStateCount;
1717 UINT32 ComponentCount;
1718
1719
1720 /* Main table */
1721
1722 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE);
1723 if (ACPI_FAILURE (Status))
1724 {
1725 return (Status);
1726 }
1727
1728 ParentTable = DtPeekSubtable ();
1729 DtInsertSubtable (ParentTable, Subtable);
1730 DtPushSubtable (Subtable);
1731
1732 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
1733 SubtableCount = MpstChannelInfo->PowerNodeCount;
1734
1735 while (*PFieldList && SubtableCount)
1736 {
1737 /* Subtable: Memory Power Node(s) */
1738
1739 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
1740 &Subtable, TRUE);
1741 if (ACPI_FAILURE (Status))
1742 {
1743 return (Status);
1744 }
1745
1746 ParentTable = DtPeekSubtable ();
1747 DtInsertSubtable (ParentTable, Subtable);
1748 DtPushSubtable (Subtable);
1749
1750 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
1751 PowerStateCount = MpstPowerNode->NumPowerStates;
1752 ComponentCount = MpstPowerNode->NumPhysicalComponents;
1753
1754 ParentTable = DtPeekSubtable ();
1755
1756 /* Sub-subtables - Memory Power State Structure(s) */
1757
1758 while (*PFieldList && PowerStateCount)
1759 {
1760 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
1761 &Subtable, TRUE);
1762 if (ACPI_FAILURE (Status))
1763 {
1764 return (Status);
1765 }
1766
1767 DtInsertSubtable (ParentTable, Subtable);
1768 PowerStateCount--;
1769 }
1770
1771 /* Sub-subtables - Physical Component ID Structure(s) */
1772
1773 while (*PFieldList && ComponentCount)
1774 {
1775 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
1776 &Subtable, TRUE);
1777 if (ACPI_FAILURE (Status))
1778 {
1779 return (Status);
1780 }
1781
1782 DtInsertSubtable (ParentTable, Subtable);
1783 ComponentCount--;
1784 }
1785
1786 SubtableCount--;
1787 DtPopSubtable ();
1788 }
1789
1790 /* Subtable: Count of Memory Power State Characteristic structures */
1791
1792 DtPopSubtable ();
1793
1794 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE);
1795 if (ACPI_FAILURE (Status))
1796 {
1797 return (Status);
1798 }
1799
1800 ParentTable = DtPeekSubtable ();
1801 DtInsertSubtable (ParentTable, Subtable);
1802 DtPushSubtable (Subtable);
1803
1804 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
1805 SubtableCount = MpstDataHeader->CharacteristicsCount;
1806
1807 ParentTable = DtPeekSubtable ();
1808
1809 /* Subtable: Memory Power State Characteristics structure(s) */
1810
1811 while (*PFieldList && SubtableCount)
1812 {
1813 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
1814 &Subtable, TRUE);
1815 if (ACPI_FAILURE (Status))
1816 {
1817 return (Status);
1818 }
1819
1820 DtInsertSubtable (ParentTable, Subtable);
1821 SubtableCount--;
1822 }
1823
1824 DtPopSubtable ();
1825 return (AE_OK);
1826 }
1827
1828
1829 /******************************************************************************
1830 *
1831 * FUNCTION: DtCompileMsct
1832 *
1833 * PARAMETERS: List - Current field list pointer
1834 *
1835 * RETURN: Status
1836 *
1837 * DESCRIPTION: Compile MSCT.
1838 *
1839 *****************************************************************************/
1840
1841 ACPI_STATUS
1842 DtCompileMsct (
1843 void **List)
1844 {
1845 ACPI_STATUS Status;
1846
1847
1848 Status = DtCompileTwoSubtables (List,
1849 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
1850 return (Status);
1851 }
1852
1853
1854 /******************************************************************************
1855 *
1856 * FUNCTION: DtCompileMtmr
1857 *
1858 * PARAMETERS: List - Current field list pointer
1859 *
1860 * RETURN: Status
1861 *
1862 * DESCRIPTION: Compile MTMR.
1863 *
1864 *****************************************************************************/
1865
1866 ACPI_STATUS
1867 DtCompileMtmr (
1868 void **List)
1869 {
1870 ACPI_STATUS Status;
1871
1872
1873 Status = DtCompileTwoSubtables (List,
1874 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0);
1875 return (Status);
1876 }
1877
1878
1879 /******************************************************************************
1880 *
1881 * FUNCTION: DtCompilePcct
1882 *
1883 * PARAMETERS: List - Current field list pointer
1884 *
1885 * RETURN: Status
1886 *
1887 * DESCRIPTION: Compile PCCT.
1888 *
1889 *****************************************************************************/
1890
1891 ACPI_STATUS
1892 DtCompilePcct (
1893 void **List)
1894 {
1895 ACPI_STATUS Status;
1896 DT_SUBTABLE *Subtable;
1897 DT_SUBTABLE *ParentTable;
1898 DT_FIELD **PFieldList = (DT_FIELD **) List;
1899 DT_FIELD *SubtableStart;
1900 ACPI_SUBTABLE_HEADER *PcctHeader;
1901 ACPI_DMTABLE_INFO *InfoTable;
1902
1903
1904 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
1905 &Subtable, TRUE);
1906 if (ACPI_FAILURE (Status))
1907 {
1908 return (Status);
1909 }
1910
1911 ParentTable = DtPeekSubtable ();
1912 DtInsertSubtable (ParentTable, Subtable);
1913
1914 while (*PFieldList)
1915 {
1916 SubtableStart = *PFieldList;
1917 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
1918 &Subtable, TRUE);
1919 if (ACPI_FAILURE (Status))
1920 {
1921 return (Status);
1922 }
1923
1924 ParentTable = DtPeekSubtable ();
1925 DtInsertSubtable (ParentTable, Subtable);
1926 DtPushSubtable (Subtable);
1927
1928 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
1929
1930 switch (PcctHeader->Type)
1931 {
1932 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1933
1934 InfoTable = AcpiDmTableInfoPcct0;
1935 break;
1936
1937 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1938
1939 InfoTable = AcpiDmTableInfoPcct1;
1940 break;
1941
1942 default:
1943
1944 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
1945 return (AE_ERROR);
1946 }
1947
1948 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
1949 if (ACPI_FAILURE (Status))
1950 {
1951 return (Status);
1952 }
1953
1954 ParentTable = DtPeekSubtable ();
1955 DtInsertSubtable (ParentTable, Subtable);
1956 DtPopSubtable ();
1957 }
1958
1959 return (AE_OK);
1960 }
1961
1962
1963 /******************************************************************************
1964 *
1965 * FUNCTION: DtCompilePmtt
1966 *
1967 * PARAMETERS: List - Current field list pointer
1968 *
1969 * RETURN: Status
1970 *
1971 * DESCRIPTION: Compile PMTT.
1972 *
1973 *****************************************************************************/
1974
1975 ACPI_STATUS
1976 DtCompilePmtt (
1977 void **List)
1978 {
1979 ACPI_STATUS Status;
1980 DT_SUBTABLE *Subtable;
1981 DT_SUBTABLE *ParentTable;
1982 DT_FIELD **PFieldList = (DT_FIELD **) List;
1983 DT_FIELD *SubtableStart;
1984 ACPI_PMTT_HEADER *PmttHeader;
1985 ACPI_PMTT_CONTROLLER *PmttController;
1986 UINT16 DomainCount;
1987 UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET;
1988
1989
1990 /* Main table */
1991
1992 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE);
1993 if (ACPI_FAILURE (Status))
1994 {
1995 return (Status);
1996 }
1997
1998 ParentTable = DtPeekSubtable ();
1999 DtInsertSubtable (ParentTable, Subtable);
2000 DtPushSubtable (Subtable);
2001
2002 while (*PFieldList)
2003 {
2004 SubtableStart = *PFieldList;
2005 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr,
2006 &Subtable, TRUE);
2007 if (ACPI_FAILURE (Status))
2008 {
2009 return (Status);
2010 }
2011
2012 PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer);
2013 while (PrevType >= PmttHeader->Type)
2014 {
2015 DtPopSubtable ();
2016
2017 if (PrevType == ACPI_PMTT_TYPE_SOCKET)
2018 {
2019 break;
2020 }
2021 PrevType--;
2022 }
2023 PrevType = PmttHeader->Type;
2024
2025 ParentTable = DtPeekSubtable ();
2026 DtInsertSubtable (ParentTable, Subtable);
2027 DtPushSubtable (Subtable);
2028
2029 switch (PmttHeader->Type)
2030 {
2031 case ACPI_PMTT_TYPE_SOCKET:
2032
2033 /* Subtable: Socket Structure */
2034
2035 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
2036 &Subtable, TRUE);
2037 if (ACPI_FAILURE (Status))
2038 {
2039 return (Status);
2040 }
2041
2042 ParentTable = DtPeekSubtable ();
2043 DtInsertSubtable (ParentTable, Subtable);
2044 break;
2045
2046 case ACPI_PMTT_TYPE_CONTROLLER:
2047
2048 /* Subtable: Memory Controller Structure */
2049
2050 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
2051 &Subtable, TRUE);
2052 if (ACPI_FAILURE (Status))
2053 {
2054 return (Status);
2055 }
2056
2057 ParentTable = DtPeekSubtable ();
2058 DtInsertSubtable (ParentTable, Subtable);
2059
2060 PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER,
2061 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER)));
2062 DomainCount = PmttController->DomainCount;
2063
2064 while (DomainCount)
2065 {
2066 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a,
2067 &Subtable, TRUE);
2068 if (ACPI_FAILURE (Status))
2069 {
2070 return (Status);
2071 }
2072
2073 DtInsertSubtable (ParentTable, Subtable);
2074 DomainCount--;
2075 }
2076 break;
2077
2078 case ACPI_PMTT_TYPE_DIMM:
2079
2080 /* Subtable: Physical Component Structure */
2081
2082 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
2083 &Subtable, TRUE);
2084 if (ACPI_FAILURE (Status))
2085 {
2086 return (Status);
2087 }
2088
2089 ParentTable = DtPeekSubtable ();
2090 DtInsertSubtable (ParentTable, Subtable);
2091 break;
2092
2093 default:
2094
2095 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
2096 return (AE_ERROR);
2097 }
2098 }
2099
2100 return (Status);
2101 }
2102
2103
2104 /******************************************************************************
2105 *
2106 * FUNCTION: DtCompileRsdt
2107 *
2108 * PARAMETERS: List - Current field list pointer
2109 *
2110 * RETURN: Status
2111 *
2112 * DESCRIPTION: Compile RSDT.
2113 *
2114 *****************************************************************************/
2115
2116 ACPI_STATUS
2117 DtCompileRsdt (
2118 void **List)
2119 {
2120 DT_SUBTABLE *Subtable;
2121 DT_SUBTABLE *ParentTable;
2122 DT_FIELD *FieldList = *(DT_FIELD **) List;
2123 UINT32 Address;
2124
2125
2126 ParentTable = DtPeekSubtable ();
2127
2128 while (FieldList)
2129 {
2130 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
2131
2132 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
2133 DtInsertSubtable (ParentTable, Subtable);
2134 FieldList = FieldList->Next;
2135 }
2136
2137 return (AE_OK);
2138 }
2139
2140
2141 /******************************************************************************
2142 *
2143 * FUNCTION: DtCompileS3pt
2144 *
2145 * PARAMETERS: PFieldList - Current field list pointer
2146 *
2147 * RETURN: Status
2148 *
2149 * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
2150 *
2151 *****************************************************************************/
2152
2153 ACPI_STATUS
2154 DtCompileS3pt (
2155 DT_FIELD **PFieldList)
2156 {
2157 ACPI_STATUS Status;
2158 ACPI_S3PT_HEADER *S3ptHeader;
2159 DT_SUBTABLE *Subtable;
2160 DT_SUBTABLE *ParentTable;
2161 ACPI_DMTABLE_INFO *InfoTable;
2162 DT_FIELD *SubtableStart;
2163
2164
2165 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
2166 &Gbl_RootTable, TRUE);
2167 if (ACPI_FAILURE (Status))
2168 {
2169 return (Status);
2170 }
2171
2172 DtPushSubtable (Gbl_RootTable);
2173
2174 while (*PFieldList)
2175 {
2176 SubtableStart = *PFieldList;
2177 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
2178 &Subtable, TRUE);
2179 if (ACPI_FAILURE (Status))
2180 {
2181 return (Status);
2182 }
2183
2184 ParentTable = DtPeekSubtable ();
2185 DtInsertSubtable (ParentTable, Subtable);
2186 DtPushSubtable (Subtable);
2187
2188 S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer);
2189
2190 switch (S3ptHeader->Type)
2191 {
2192 case ACPI_S3PT_TYPE_RESUME:
2193
2194 InfoTable = AcpiDmTableInfoS3pt0;
2195 break;
2196
2197 case ACPI_S3PT_TYPE_SUSPEND:
2198
2199 InfoTable = AcpiDmTableInfoS3pt1;
2200 break;
2201
2202 default:
2203
2204 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
2205 return (AE_ERROR);
2206 }
2207
2208 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2209 if (ACPI_FAILURE (Status))
2210 {
2211 return (Status);
2212 }
2213
2214 ParentTable = DtPeekSubtable ();
2215 DtInsertSubtable (ParentTable, Subtable);
2216 DtPopSubtable ();
2217 }
2218
2219 return (AE_OK);
2220 }
2221
2222
2223 /******************************************************************************
2224 *
2225 * FUNCTION: DtCompileSlic
2226 *
2227 * PARAMETERS: List - Current field list pointer
2228 *
2229 * RETURN: Status
2230 *
2231 * DESCRIPTION: Compile SLIC.
2232 *
2233 *****************************************************************************/
2234
2235 ACPI_STATUS
2236 DtCompileSlic (
2237 void **List)
2238 {
2239 ACPI_STATUS Status;
2240 DT_SUBTABLE *Subtable;
2241 DT_SUBTABLE *ParentTable;
2242 DT_FIELD **PFieldList = (DT_FIELD **) List;
2243
2244
2245 while (*PFieldList)
2246 {
2247 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
2248 &Subtable, TRUE);
2249 if (ACPI_FAILURE (Status))
2250 {
2251 return (Status);
2252 }
2253
2254 ParentTable = DtPeekSubtable ();
2255 DtInsertSubtable (ParentTable, Subtable);
2256 DtPushSubtable (Subtable);
2257 DtPopSubtable ();
2258 }
2259
2260 return (AE_OK);
2261 }
2262
2263
2264 /******************************************************************************
2265 *
2266 * FUNCTION: DtCompileSlit
2267 *
2268 * PARAMETERS: List - Current field list pointer
2269 *
2270 * RETURN: Status
2271 *
2272 * DESCRIPTION: Compile SLIT.
2273 *
2274 *****************************************************************************/
2275
2276 ACPI_STATUS
2277 DtCompileSlit (
2278 void **List)
2279 {
2280 ACPI_STATUS Status;
2281 DT_SUBTABLE *Subtable;
2282 DT_SUBTABLE *ParentTable;
2283 DT_FIELD **PFieldList = (DT_FIELD **) List;
2284 DT_FIELD *FieldList;
2285 UINT32 Localities;
2286 UINT8 *LocalityBuffer;
2287
2288
2289 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
2290 &Subtable, TRUE);
2291 if (ACPI_FAILURE (Status))
2292 {
2293 return (Status);
2294 }
2295
2296 ParentTable = DtPeekSubtable ();
2297 DtInsertSubtable (ParentTable, Subtable);
2298
2299 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
2300 LocalityBuffer = UtLocalCalloc (Localities);
2301
2302 /* Compile each locality buffer */
2303
2304 FieldList = *PFieldList;
2305 while (FieldList)
2306 {
2307 DtCompileBuffer (LocalityBuffer,
2308 FieldList->Value, FieldList, Localities);
2309
2310 DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
2311 DtInsertSubtable (ParentTable, Subtable);
2312 FieldList = FieldList->Next;
2313 }
2314
2315 ACPI_FREE (LocalityBuffer);
2316 return (AE_OK);
2317 }
2318
2319
2320 /******************************************************************************
2321 *
2322 * FUNCTION: DtCompileSrat
2323 *
2324 * PARAMETERS: List - Current field list pointer
2325 *
2326 * RETURN: Status
2327 *
2328 * DESCRIPTION: Compile SRAT.
2329 *
2330 *****************************************************************************/
2331
2332 ACPI_STATUS
2333 DtCompileSrat (
2334 void **List)
2335 {
2336 ACPI_STATUS Status;
2337 DT_SUBTABLE *Subtable;
2338 DT_SUBTABLE *ParentTable;
2339 DT_FIELD **PFieldList = (DT_FIELD **) List;
2340 DT_FIELD *SubtableStart;
2341 ACPI_SUBTABLE_HEADER *SratHeader;
2342 ACPI_DMTABLE_INFO *InfoTable;
2343
2344
2345 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
2346 &Subtable, TRUE);
2347 if (ACPI_FAILURE (Status))
2348 {
2349 return (Status);
2350 }
2351
2352 ParentTable = DtPeekSubtable ();
2353 DtInsertSubtable (ParentTable, Subtable);
2354
2355 while (*PFieldList)
2356 {
2357 SubtableStart = *PFieldList;
2358 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
2359 &Subtable, TRUE);
2360 if (ACPI_FAILURE (Status))
2361 {
2362 return (Status);
2363 }
2364
2365 ParentTable = DtPeekSubtable ();
2366 DtInsertSubtable (ParentTable, Subtable);
2367 DtPushSubtable (Subtable);
2368
2369 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
2370
2371 switch (SratHeader->Type)
2372 {
2373 case ACPI_SRAT_TYPE_CPU_AFFINITY:
2374
2375 InfoTable = AcpiDmTableInfoSrat0;
2376 break;
2377
2378 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2379
2380 InfoTable = AcpiDmTableInfoSrat1;
2381 break;
2382
2383 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2384
2385 InfoTable = AcpiDmTableInfoSrat2;
2386 break;
2387
2388 case ACPI_SRAT_TYPE_GICC_AFFINITY:
2389
2390 InfoTable = AcpiDmTableInfoSrat3;
2391 break;
2392
2393 default:
2394
2395 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
2396 return (AE_ERROR);
2397 }
2398
2399 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
2400 if (ACPI_FAILURE (Status))
2401 {
2402 return (Status);
2403 }
2404
2405 ParentTable = DtPeekSubtable ();
2406 DtInsertSubtable (ParentTable, Subtable);
2407 DtPopSubtable ();
2408 }
2409
2410 return (AE_OK);
2411 }
2412
2413
2414 /******************************************************************************
2415 *
2416 * FUNCTION: DtGetGenericTableInfo
2417 *
2418 * PARAMETERS: Name - Generic type name
2419 *
2420 * RETURN: Info entry
2421 *
2422 * DESCRIPTION: Obtain table info for a generic name entry
2423 *
2424 *****************************************************************************/
2425
2426 ACPI_DMTABLE_INFO *
2427 DtGetGenericTableInfo (
2428 char *Name)
2429 {
2430 ACPI_DMTABLE_INFO *Info;
2431 UINT32 i;
2432
2433
2434 if (!Name)
2435 {
2436 return (NULL);
2437 }
2438
2439 /* Search info table for name match */
2440
2441 for (i = 0; ; i++)
2442 {
2443 Info = AcpiDmTableInfoGeneric[i];
2444 if (Info->Opcode == ACPI_DMT_EXIT)
2445 {
2446 Info = NULL;
2447 break;
2448 }
2449
2450 /* Use caseless compare for generic keywords */
2451
2452 if (!AcpiUtStricmp (Name, Info->Name))
2453 {
2454 break;
2455 }
2456 }
2457
2458 return (Info);
2459 }
2460
2461
2462 /******************************************************************************
2463 *
2464 * FUNCTION: DtCompileUefi
2465 *
2466 * PARAMETERS: List - Current field list pointer
2467 *
2468 * RETURN: Status
2469 *
2470 * DESCRIPTION: Compile UEFI.
2471 *
2472 *****************************************************************************/
2473
2474 ACPI_STATUS
2475 DtCompileUefi (
2476 void **List)
2477 {
2478 ACPI_STATUS Status;
2479 DT_SUBTABLE *Subtable;
2480 DT_SUBTABLE *ParentTable;
2481 DT_FIELD **PFieldList = (DT_FIELD **) List;
2482 UINT16 *DataOffset;
2483
2484
2485 /* Compile the predefined portion of the UEFI table */
2486
2487 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
2488 &Subtable, TRUE);
2489 if (ACPI_FAILURE (Status))
2490 {
2491 return (Status);
2492 }
2493
2494 DataOffset = (UINT16 *) (Subtable->Buffer + 16);
2495 *DataOffset = sizeof (ACPI_TABLE_UEFI);
2496
2497 ParentTable = DtPeekSubtable ();
2498 DtInsertSubtable (ParentTable, Subtable);
2499
2500 /*
2501 * Compile the "generic" portion of the UEFI table. This
2502 * part of the table is not predefined and any of the generic
2503 * operators may be used.
2504 */
2505
2506 DtCompileGeneric ((void **) PFieldList);
2507
2508 return (AE_OK);
2509 }
2510
2511
2512 /******************************************************************************
2513 *
2514 * FUNCTION: DtCompileVrtc
2515 *
2516 * PARAMETERS: List - Current field list pointer
2517 *
2518 * RETURN: Status
2519 *
2520 * DESCRIPTION: Compile VRTC.
2521 *
2522 *****************************************************************************/
2523
2524 ACPI_STATUS
2525 DtCompileVrtc (
2526 void **List)
2527 {
2528 ACPI_STATUS Status;
2529
2530
2531 Status = DtCompileTwoSubtables (List,
2532 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0);
2533 return (Status);
2534 }
2535
2536
2537 /******************************************************************************
2538 *
2539 * FUNCTION: DtCompileWdat
2540 *
2541 * PARAMETERS: List - Current field list pointer
2542 *
2543 * RETURN: Status
2544 *
2545 * DESCRIPTION: Compile WDAT.
2546 *
2547 *****************************************************************************/
2548
2549 ACPI_STATUS
2550 DtCompileWdat (
2551 void **List)
2552 {
2553 ACPI_STATUS Status;
2554
2555
2556 Status = DtCompileTwoSubtables (List,
2557 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
2558 return (Status);
2559 }
2560
2561
2562 /******************************************************************************
2563 *
2564 * FUNCTION: DtCompileXsdt
2565 *
2566 * PARAMETERS: List - Current field list pointer
2567 *
2568 * RETURN: Status
2569 *
2570 * DESCRIPTION: Compile XSDT.
2571 *
2572 *****************************************************************************/
2573
2574 ACPI_STATUS
2575 DtCompileXsdt (
2576 void **List)
2577 {
2578 DT_SUBTABLE *Subtable;
2579 DT_SUBTABLE *ParentTable;
2580 DT_FIELD *FieldList = *(DT_FIELD **) List;
2581 UINT64 Address;
2582
2583 ParentTable = DtPeekSubtable ();
2584
2585 while (FieldList)
2586 {
2587 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
2588
2589 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
2590 DtInsertSubtable (ParentTable, Subtable);
2591 FieldList = FieldList->Next;
2592 }
2593
2594 return (AE_OK);
2595 }
2596
2597
2598 /******************************************************************************
2599 *
2600 * FUNCTION: DtCompileGeneric
2601 *
2602 * PARAMETERS: List - Current field list pointer
2603 *
2604 * RETURN: Status
2605 *
2606 * DESCRIPTION: Compile generic unknown table.
2607 *
2608 *****************************************************************************/
2609
2610 ACPI_STATUS
2611 DtCompileGeneric (
2612 void **List)
2613 {
2614 ACPI_STATUS Status;
2615 DT_SUBTABLE *Subtable;
2616 DT_SUBTABLE *ParentTable;
2617 DT_FIELD **PFieldList = (DT_FIELD **) List;
2618 ACPI_DMTABLE_INFO *Info;
2619
2620
2621 ParentTable = DtPeekSubtable ();
2622
2623 /*
2624 * Compile the "generic" portion of the table. This
2625 * part of the table is not predefined and any of the generic
2626 * operators may be used.
2627 */
2628
2629 /* Find any and all labels in the entire generic portion */
2630
2631 DtDetectAllLabels (*PFieldList);
2632
2633 /* Now we can actually compile the parse tree */
2634
2635 while (*PFieldList)
2636 {
2637 Info = DtGetGenericTableInfo ((*PFieldList)->Name);
2638 if (!Info)
2639 {
2640 snprintf (MsgBuffer, sizeof(MsgBuffer), "Generic data type \"%s\" not found",
2641 (*PFieldList)->Name);
2642 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2643 (*PFieldList), MsgBuffer);
2644
2645 *PFieldList = (*PFieldList)->Next;
2646 continue;
2647 }
2648
2649 Status = DtCompileTable (PFieldList, Info,
2650 &Subtable, TRUE);
2651 if (ACPI_SUCCESS (Status))
2652 {
2653 DtInsertSubtable (ParentTable, Subtable);
2654 }
2655 else
2656 {
2657 *PFieldList = (*PFieldList)->Next;
2658
2659 if (Status == AE_NOT_FOUND)
2660 {
2661 snprintf (MsgBuffer, sizeof(MsgBuffer), "Generic data type \"%s\" not found",
2662 (*PFieldList)->Name);
2663 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
2664 (*PFieldList), MsgBuffer);
2665 }
2666 }
2667 }
2668
2669 return (AE_OK);
2670 }
2671